1
1
package goldilocks
2
2
3
- import fp "github.com/cloudflare/circl/math/fp448"
3
+ import (
4
+ fp "github.com/cloudflare/circl/math/fp448"
5
+ )
4
6
5
7
// Decaf provides a prime-order group.
6
8
// Internally, the implementation uses the twist of goldilocks curve.
@@ -29,6 +31,9 @@ func (d Decaf) Order() Scalar { return order }
29
31
// Add is
30
32
func (d Decaf ) Add (c , a , b * Elt ) { c .p = a .p ; c .p .Add (& b .p ) }
31
33
34
+ // Double is
35
+ func (d Decaf ) Double (c , a * Elt ) { c .p = a .p ; c .p .Double () }
36
+
32
37
// Neg is
33
38
func (d Decaf ) Neg (c , a * Elt ) { c .p = a .p ; c .p .cneg (1 ) }
34
39
@@ -49,85 +54,82 @@ func (d Decaf) AreEqual(a, b *Elt) bool {
49
54
50
55
// Marshal is
51
56
func (e * Elt ) Marshal () []byte {
52
- r , u := & fp.Elt {}, & fp.Elt {}
53
- one , s := & fp.Elt {}, & fp.Elt {}
54
- x , y , ta , tb , z := e .p .x , e .p .y , e .p .ta , e .p .tb , e .p .z
55
- t0 , t1 := z , y
57
+ x , ta , tb , z := e .p .x , e .p .ta , e .p .tb , e .p .z
58
+ one , t , t2 , s := & fp.Elt {}, & fp.Elt {}, & fp.Elt {}, & fp.Elt {}
56
59
fp .SetOne (one )
57
- fp .AddSub (& t0 , & t1 ) // (t0,t1) = (z+y,z-y)
58
- fp .Mul (& t0 , & t0 , & t1 ) // t0 = (z+y)*(z-y)
59
- fp .Mul (& t0 , & t0 , & aMinusDTwist ) // t0 = (a-d)*(z+y)*(z-y)
60
- fp .InvSqrt (r , one , & t0 ) // r = 1/sqrt( (a-d)*(z+y)*(z-y) )
61
- fp .Mul (u , r , & aMinusDTwist ) // u = (a-d)*r
62
- fp .Mul (& t0 , u , & z ) // t0 = u*Z
63
- fp .Add (& t0 , & t0 , & t0 ) // t0 = 2*u*Z
64
- fp .Neg (& t0 , & t0 ) // t0 = -2*u*Z
65
- isNeg := fp .Parity (& t0 ) // isNeg = sgn(t0)
66
- fp .Neg (& t1 , r ) // t1 = -r
67
- fp .Cmov (r , & t1 , uint (isNeg )) // if -2*u*Z is negative then r = -r
68
- fp .Mul (& t1 , & ta , & tb ) // t1 = Ta*Tb = T
69
- fp .Mul (& t1 , & t1 , & y ) // t1 = Y*T
70
- fp .Mul (& t1 , & t1 , & paramDTwist ) // t1 = d*Y*T
71
- fp .Mul (& t0 , & z , & x ) // t0 = Z*X
72
- fp .Neg (& t0 , & t0 ) // t0 = a*Z*X
73
- fp .Sub (& t0 , & t0 , & t1 ) // t0 = a*Z*X - d*Y*T
74
- fp .Mul (& t0 , & t0 , r ) // t0 = r*(a*Z*X - d*Y*T)
75
- fp .Add (& t0 , & t0 , & y ) // t0 = r*(a*Z*X - d*Y*T) + Y
76
- fp .Mul (s , & t0 , u ) // s = (u)*(r*(a*Z*X - d*Y*T) + Y)
77
- fp .Neg (s , s ) // s = (u/a)*(r*(a*Z*X - d*Y*T) + Y)
78
- isNeg = fp .Parity (s ) // isNeg = sgn(s)
79
- fp .Neg (& t1 , s ) // t1 = -s
80
- fp .Cmov (s , & t1 , uint (isNeg )) // if s is negative then s = -s
60
+ fp .Mul (t , & ta , & tb ) // t = ta*tb
61
+ t0 , t1 := x , * t // (t0,t1) = (x,t)
62
+ fp .Sqr (t2 , & x ) // t2 = x^2
63
+ fp .AddSub (& t0 , & t1 ) // (t0,t1) = (x+t,x-t)
64
+ fp .Mul (& t1 , & t0 , & t1 ) // t1 = (x+t)*(x-t)
65
+ fp .Mul (& t0 , & t1 , & aMinusDTwist ) // t0 = (a-d)*(x+t)*(x-t)
66
+ fp .Mul (& t0 , & t0 , t2 ) // t0 = x^2*(a-d)*(x+t)*(x-t)
67
+ fp .InvSqrt (& t0 , one , & t0 ) // t0 = 1/sqrt( x^2*(a-d)*(z+y)*(z-y) )
68
+ fp .Mul (& t1 , & t1 , & t0 ) // t1 = (z+y)*(z-y)/sqrt( x^2*(a-d)*(z+y)*(z-y) )
69
+ fp .Mul (t2 , & t1 , & sqrtAMinusDTwist ) // t2 = sqrt( (z+y)*(z-y) )/z
70
+ isNeg := fp .Parity (t2 ) // isNeg = sgn(t2)
71
+ fp .Neg (t2 , & t1 ) // t2 = -t1
72
+ fp .Cmov (& t1 , t2 , uint (isNeg )) // if t2 is negative then t1 = -t1
73
+ fp .Mul (s , & t1 , & z ) // s = t1*z
74
+ fp .Sub (s , s , t ) // s = t1*z - t
75
+ fp .Mul (s , s , & x ) // s = x*(t1*z - t)
76
+ fp .Mul (s , s , & t0 ) // s = isr*x*(t1*z - t)
77
+ fp .Mul (s , s , & aMinusDTwist ) // s = (a-d)*isr*x*(t1*z - t)
78
+ isNeg = fp .Parity (s ) // isNeg = sgn(s)
79
+ fp .Neg (& t0 , s ) // t0 = -s
80
+ fp .Cmov (s , & t0 , uint (isNeg )) // if s is negative then s = -s
81
81
82
82
var encS [fp .Size ]byte
83
83
_ = fp .ToBytes (encS [:], s )
84
84
return encS [:]
85
85
}
86
86
87
87
// Unmarshal is
88
- func (d Decaf ) Unmarshal (b []byte ) ( * Elt , error ) {
88
+ func (e * Elt ) Unmarshal (b []byte ) error {
89
89
if len (b ) < fp .Size {
90
- return nil , errInvalidDecoding
90
+ return errInvalidDecoding
91
91
}
92
92
93
93
s := & fp.Elt {}
94
94
copy (s [:], b [:fp .Size ])
95
95
isNeg := fp .Parity (s )
96
96
p := fp .P ()
97
97
if isNeg == 1 || ! isLessThan (b [:fp .Size ], p [:]) {
98
- return nil , errInvalidDecoding
98
+ return errInvalidDecoding
99
99
}
100
100
101
- one , u , v , w := & fp.Elt {}, & fp.Elt {}, & fp.Elt {}, & fp.Elt {}
101
+ one , s2 , den , num := & fp.Elt {}, & fp.Elt {}, & fp.Elt {}, & fp.Elt {}
102
+ isr , altx := & fp.Elt {}, & fp.Elt {}
102
103
t0 , t1 := & fp.Elt {}, & fp.Elt {}
103
- e := & Elt {}
104
104
fp .SetOne (one )
105
- fp .Add (& e .p .x , s , s ) // X = 2*s
106
- fp .Sqr (t0 , s ) // t0 = s^2
107
- fp .Sub (& e .p .z , one , t0 ) // Z = 1 + a*s^2
108
- fp .Mul (t1 , t0 , & paramDTwist ) // t1 = d*s^2
109
- fp .Add (t1 , t1 , t1 ) // t1 = 2*d*s^2
110
- fp .Add (t1 , t1 , t1 ) // t1 = 4*d*s^2
111
- fp .Sqr (u , & e .p .z ) // u = Z^2
112
- fp .Sub (u , u , t1 ) // u = Z^2 - 4*d*s^2
113
- fp .Mul (t0 , t0 , u ) // t0 = u*s^2
114
- isQR := fp .InvSqrt (v , one , t0 ) // v = 1/sqrt(u*s^2)
115
- var isZero byte
105
+ fp .Sqr (s2 , s ) // s2 = s^2
106
+ fp .Sub (den , one , s2 ) // den = 1 + a*s^2
107
+ fp .Mul (t1 , s2 , & paramDTwist ) // t1 = d*s^2
108
+ fp .Add (t1 , t1 , t1 ) // t1 = 2*d*s^2
109
+ fp .Add (t1 , t1 , t1 ) // t1 = 4*d*s^2
110
+ fp .Sqr (t0 , den ) // num = (1 + a*s^2)^2
111
+ fp .Sub (num , t0 , t1 ) // num = (1 + a*s^2)^2 - 4*d*s^2
112
+ fp .Mul (t0 , t0 , num ) // t0 = num*den^2
113
+ isQR := fp .InvSqrt (isr , one , t0 ) // v = 1/sqrt(num*den^2)
116
114
if ! isQR {
117
- if ! fp .IsZero (t0 ) {
118
- return nil , errInvalidDecoding
119
- }
120
- isZero = 1
115
+ return errInvalidDecoding
121
116
}
122
- fp .Mul (t0 , u , v ) // t0 = u*v
123
- isNeg = fp .Parity (t0 ) // isNeg = sgn(u*v)
124
- fp .Neg (t1 , v ) // t1 = -v
125
- fp .Cmov (v , t1 , uint (isNeg )) // if u*v is negative then v = -v
126
- fp .Sub (w , & fp.Elt {2 }, & e .p .z ) // w = 2-Z
127
- fp .Mul (w , w , s ) // w = s*(2-Z)
128
- fp .Mul (w , w , v ) // w = v*s*(2-Z)
129
- fp .Add (w , w , & fp.Elt {isZero }) // if s=0 then w = w+1
130
- fp .Mul (& e .p .y , & e .p .z , w ) // Y = w*Z
131
- e .p .ta , e .p .tb = e .p .x , * w // T = Ta*Tb = w*X
132
- return e , nil
117
+ fp .Mul (t1 , den , isr ) // altx = isr*den
118
+ fp .Mul (t1 , t1 , s ) // altx = s*isr*den
119
+ fp .Add (t1 , t1 , t1 ) // t1 = 2*s*isr*den
120
+ fp .Mul (altx , t1 , & sqrtAMinusDTwist ) // altx = 2*s*isr*den*sqrt(A-D)
121
+ isNeg = fp .Parity (altx ) // isNeg = sgn(altx)
122
+ fp .Neg (t0 , isr ) // t0 = -isr
123
+ fp .Cmov (isr , t0 , uint (isNeg )) // if altx is negative then isr = -isr
124
+ fp .Sqr (& e .p .x , isr ) // x = isr^2
125
+ fp .Mul (& e .p .x , & e .p .x , den ) // x = isr^2*den
126
+ fp .Mul (& e .p .x , & e .p .x , num ) // x = isr^2*den*num
127
+ fp .Mul (& e .p .x , & e .p .x , s ) // x = s*isr^2*den*num
128
+ fp .Add (& e .p .x , & e .p .x , & e .p .x ) // x = 2*s*isr^2*den*num
129
+ fp .Mul (& e .p .y , isr , den ) // y = isr*den
130
+ fp .Add (t0 , one , s2 ) // t0 = 1 - a*s^2
131
+ fp .Mul (& e .p .y , & e .p .y , t0 ) // y = (1 - a*s^2)*isr*den
132
+ e .p .ta , e .p .tb = e .p .x , e .p .y // T = Ta*Tb = x*y
133
+ fp .SetOne (& e .p .z )
134
+ return nil
133
135
}
0 commit comments