@@ -2,9 +2,6 @@ package goldilocks
2
2
3
3
import fp "github.com/cloudflare/circl/math/fp448"
4
4
5
- // DecafEncodingSize is the size (in bytes) for storing a decaf element.
6
- const DecafEncodingSize = fp .Size
7
-
8
5
// Decaf provides operations of a prime-order group from goldilocks curve.
9
6
// Its internal implementation uses the twist of the goldilocks curve.
10
7
// This uses version 1.1 of the encoding. Decaf is a zero-length datatype.
@@ -19,9 +16,6 @@ func (e Elt) String() string { return e.p.String() }
19
16
// IsValid returns True if a is a valid element of the group.
20
17
func (d Decaf ) IsValid (a * Elt ) bool { return d .c .IsOnCurve (& a .p ) }
21
18
22
- // IsIdentity returns True if a is the identity of the group.
23
- func (d Decaf ) IsIdentity (a * Elt ) bool { return fp .IsZero (& a .p .x ) }
24
-
25
19
// Identity returns the identity element of the group.
26
20
func (d Decaf ) Identity () * Elt { return & Elt {* d .c .Identity ()} }
27
21
@@ -32,7 +26,7 @@ func (d Decaf) Generator() *Elt { return &Elt{*d.c.pull(Curve{}.Generator())} }
32
26
func (d Decaf ) Order () Scalar { return order }
33
27
34
28
// Add calculates c=a+b, where + is the group operation.
35
- func (d Decaf ) Add (c , a , b * Elt ) { c . p = a .p ; c . p . Add (& b .p ) }
29
+ func (d Decaf ) Add (c , a , b * Elt ) { q : = a .p ; q . Add (& b .p ); c . p = q }
36
30
37
31
// Double calculates c=a+a, where + is the group operation.
38
32
func (d Decaf ) Double (c , a * Elt ) { c .p = a .p ; c .p .Double () }
@@ -41,65 +35,36 @@ func (d Decaf) Double(c, a *Elt) { c.p = a.p; c.p.Double() }
41
35
func (d Decaf ) Neg (c , a * Elt ) { c .p = a .p ; c .p .cneg (1 ) }
42
36
43
37
// Mul calculates c=n*a, where * is scalar multiplication on the group.
44
- func (d Decaf ) Mul (c * Elt , n * Scalar , a * Elt ) { c . p = * d .c .ScalarMult (n , & a .p ) }
38
+ func (d Decaf ) Mul (c * Elt , n * Scalar , a * Elt ) { d .c .ScalarMult (& c . p , n , & a .p ) }
45
39
46
40
// MulGen calculates c=n*g, where * is scalar multiplication on the group,
47
41
// and g is the generator of the group.
48
- func (d Decaf ) MulGen (c * Elt , n * Scalar ) { c . p = * d .c .ScalarBaseMult (n ) }
42
+ func (d Decaf ) MulGen (c * Elt , n * Scalar ) { d .c .ScalarBaseMult (& c . p , n ) }
49
43
50
- // AreEqual returns True if a=b, where = is an equivalence relation.
51
- func (d Decaf ) AreEqual (a , b * Elt ) bool {
44
+ // IsIdentity returns True if e is the identity of the group.
45
+ func (e * Elt ) IsIdentity () bool { return fp .IsZero (& e .p .x ) }
46
+
47
+ // IsEqual returns True if e=a, where = is an equivalence relation.
48
+ func (e * Elt ) IsEqual (a * Elt ) bool {
52
49
l , r := & fp.Elt {}, & fp.Elt {}
53
- fp .Mul (l , & a .p .x , & b .p .y )
54
- fp .Mul (r , & b .p .x , & a .p .y )
50
+ fp .Mul (l , & e .p .x , & a .p .y )
51
+ fp .Mul (r , & a .p .x , & e .p .y )
55
52
fp .Sub (l , l , r )
56
53
return fp .IsZero (l )
57
54
}
58
55
59
- // Marshal returns a unique encoding of the element e.
60
- func (e * Elt ) Marshal () []byte {
61
- x , ta , tb , z := e .p .x , e .p .ta , e .p .tb , e .p .z
62
- one , t , t2 , s := & fp.Elt {}, & fp.Elt {}, & fp.Elt {}, & fp.Elt {}
63
- fp .SetOne (one )
64
- fp .Mul (t , & ta , & tb ) // t = ta*tb
65
- t0 , t1 := x , * t // (t0,t1) = (x,t)
66
- fp .Sqr (t2 , & x ) // t2 = x^2
67
- fp .AddSub (& t0 , & t1 ) // (t0,t1) = (x+t,x-t)
68
- fp .Mul (& t1 , & t0 , & t1 ) // t1 = (x+t)*(x-t)
69
- fp .Mul (& t0 , & t1 , & aMinusDTwist ) // t0 = (a-d)*(x+t)*(x-t)
70
- fp .Mul (& t0 , & t0 , t2 ) // t0 = x^2*(a-d)*(x+t)*(x-t)
71
- fp .InvSqrt (& t0 , one , & t0 ) // t0 = 1/sqrt( x^2*(a-d)*(z+y)*(z-y) )
72
- fp .Mul (& t1 , & t1 , & t0 ) // t1 = (z+y)*(z-y)/sqrt( x^2*(a-d)*(z+y)*(z-y) )
73
- fp .Mul (t2 , & t1 , & sqrtAMinusDTwist ) // t2 = sqrt( (z+y)*(z-y) )/z
74
- isNeg := fp .Parity (t2 ) // isNeg = sgn(t2)
75
- fp .Neg (t2 , & t1 ) // t2 = -t1
76
- fp .Cmov (& t1 , t2 , uint (isNeg )) // if t2 is negative then t1 = -t1
77
- fp .Mul (s , & t1 , & z ) // s = t1*z
78
- fp .Sub (s , s , t ) // s = t1*z - t
79
- fp .Mul (s , s , & x ) // s = x*(t1*z - t)
80
- fp .Mul (s , s , & t0 ) // s = isr*x*(t1*z - t)
81
- fp .Mul (s , s , & aMinusDTwist ) // s = (a-d)*isr*x*(t1*z - t)
82
- isNeg = fp .Parity (s ) // isNeg = sgn(s)
83
- fp .Neg (& t0 , s ) // t0 = -s
84
- fp .Cmov (s , & t0 , uint (isNeg )) // if s is negative then s = -s
85
-
86
- var encS [fp .Size ]byte
87
- _ = fp .ToBytes (encS [:], s )
88
- return encS [:]
89
- }
90
-
91
- // Unmarshal if succeeds returns nil and constructs an element e from an
92
- // encoding stored in a slice b of DecafEncodingSize bytes.
93
- func (e * Elt ) Unmarshal (b []byte ) error {
56
+ // UnmarshalBinary if succeeds returns a Decaf element by decoding the first
57
+ // DecafEncodingSize bytes of b.
58
+ func (e * Elt ) UnmarshalBinary (b []byte ) error {
94
59
if len (b ) < DecafEncodingSize {
95
60
return errInvalidDecoding
96
61
}
97
62
98
63
s := & fp.Elt {}
99
64
copy (s [:], b [:DecafEncodingSize ])
100
65
isNeg := fp .Parity (s )
101
- p := fp .P ()
102
- if isNeg == 1 || ! isLessThan (b [:DecafEncodingSize ], p [:]) {
66
+ modulus := fp .P ()
67
+ if isNeg == 1 || ! isLessThan (b [:DecafEncodingSize ], modulus [:]) {
103
68
return errInvalidDecoding
104
69
}
105
70
@@ -138,3 +103,35 @@ func (e *Elt) Unmarshal(b []byte) error {
138
103
fp .SetOne (& e .p .z )
139
104
return nil
140
105
}
106
+
107
+ // MarshalBinary returns a unique encoding of the element e.
108
+ func (e * Elt ) MarshalBinary () ([]byte , error ) {
109
+ x , ta , tb , z := e .p .x , e .p .ta , e .p .tb , e .p .z
110
+ one , t , t2 , s := & fp.Elt {}, & fp.Elt {}, & fp.Elt {}, & fp.Elt {}
111
+ fp .SetOne (one )
112
+ fp .Mul (t , & ta , & tb ) // t = ta*tb
113
+ t0 , t1 := x , * t // (t0,t1) = (x,t)
114
+ fp .Sqr (t2 , & x ) // t2 = x^2
115
+ fp .AddSub (& t0 , & t1 ) // (t0,t1) = (x+t,x-t)
116
+ fp .Mul (& t1 , & t0 , & t1 ) // t1 = (x+t)*(x-t)
117
+ fp .Mul (& t0 , & t1 , & aMinusDTwist ) // t0 = (a-d)*(x+t)*(x-t)
118
+ fp .Mul (& t0 , & t0 , t2 ) // t0 = x^2*(a-d)*(x+t)*(x-t)
119
+ fp .InvSqrt (& t0 , one , & t0 ) // t0 = 1/sqrt( x^2*(a-d)*(z+y)*(z-y) )
120
+ fp .Mul (& t1 , & t1 , & t0 ) // t1 = (z+y)*(z-y)/sqrt( x^2*(a-d)*(z+y)*(z-y) )
121
+ fp .Mul (t2 , & t1 , & sqrtAMinusDTwist ) // t2 = sqrt( (z+y)*(z-y) )/z
122
+ isNeg := fp .Parity (t2 ) // isNeg = sgn(t2)
123
+ fp .Neg (t2 , & t1 ) // t2 = -t1
124
+ fp .Cmov (& t1 , t2 , uint (isNeg )) // if t2 is negative then t1 = -t1
125
+ fp .Mul (s , & t1 , & z ) // s = t1*z
126
+ fp .Sub (s , s , t ) // s = t1*z - t
127
+ fp .Mul (s , s , & x ) // s = x*(t1*z - t)
128
+ fp .Mul (s , s , & t0 ) // s = isr*x*(t1*z - t)
129
+ fp .Mul (s , s , & aMinusDTwist ) // s = (a-d)*isr*x*(t1*z - t)
130
+ isNeg = fp .Parity (s ) // isNeg = sgn(s)
131
+ fp .Neg (& t0 , s ) // t0 = -s
132
+ fp .Cmov (s , & t0 , uint (isNeg )) // if s is negative then s = -s
133
+
134
+ var encS [fp .Size ]byte
135
+ err := fp .ToBytes (encS [:], s )
136
+ return encS [:], err
137
+ }
0 commit comments