@@ -33,6 +33,25 @@ func (z *scalar64) toScalar(x *Scalar) {
33
33
binary .LittleEndian .PutUint64 (x [6 * 8 :7 * 8 ], z [6 ])
34
34
}
35
35
36
+ // isZero returns 1 if z=0.
37
+ func (z * scalar64 ) isZero () uint {
38
+ z .modOrder ()
39
+ var z64 uint64
40
+ for i := range z {
41
+ z64 |= z [i ]
42
+ }
43
+ z32 := uint32 (z64 & 0xFFFFFFFF ) | (uint32 (z64 >> 32 ) & 0xFFFFFFF )
44
+ return uint ((uint64 (z32 ) - 1 ) >> 63 )
45
+ }
46
+
47
+ // cmov moves x into z if b=1.
48
+ func (z * scalar64 ) cmov (x * scalar64 , b uint64 ) {
49
+ m := - (b & 1 )
50
+ for i := range z {
51
+ z [i ] = (z [i ] &^ m ) | (x [i ] & m )
52
+ }
53
+ }
54
+
36
55
// add calculates z = x + y. Assumes len(z) > max(len(x),len(y)).
37
56
func add (z , x , y []uint64 ) uint64 {
38
57
l , L , zz := len (x ), len (y ), y
@@ -81,14 +100,6 @@ func mulWord(z, x []uint64, y uint64) {
81
100
z [len (x )] = carry
82
101
}
83
102
84
- // Cmov moves x into z if b=1.
85
- func (z * scalar64 ) Cmov (b uint64 , x * scalar64 ) {
86
- m := uint64 (0 ) - b
87
- for i := range z {
88
- z [i ] = (z [i ] &^ m ) | (x [i ] & m )
89
- }
90
- }
91
-
92
103
// leftShift shifts to the left the words of z returning the more significant word.
93
104
func (z * scalar64 ) leftShift (low uint64 ) uint64 {
94
105
high := z [_N - 1 ]
@@ -108,6 +119,15 @@ func (z *scalar64) reduceOneWord(x uint64) {
108
119
add (z [:], z [:], prod )
109
120
}
110
121
122
+ // Sub calculates z = x-y mod order.
123
+ func (z * scalar64 ) sub (x , y * scalar64 ) {
124
+ var t scalar64
125
+ c := sub (z [:], x [:], y [:])
126
+ sub (t [:], z [:], residue448 [:])
127
+ z .cmov (& t , c )
128
+ z .modOrder ()
129
+ }
130
+
111
131
// modOrder reduces z mod order.
112
132
func (z * scalar64 ) modOrder () {
113
133
var o64 , x scalar64
@@ -116,7 +136,7 @@ func (z *scalar64) modOrder() {
116
136
// At most 8 (eight) iterations reduce 3 bits by subtracting.
117
137
for i := 0 ; i < 8 ; i ++ {
118
138
c := sub (x [:], z [:], o64 [:]) // (c || x) = z-order
119
- z .Cmov ( 1 - c , & x ) // if c != 0 { z = x }
139
+ z .cmov ( & x , 1 - c ) // if c != 0 { z = x }
120
140
}
121
141
}
122
142
@@ -159,20 +179,17 @@ func (z *Scalar) Add(x, y *Scalar) {
159
179
y64 .fromScalar (y )
160
180
c := add (z64 [:], x64 [:], y64 [:])
161
181
add (t [:], z64 [:], residue448 [:])
162
- z64 .Cmov ( c , & t )
182
+ z64 .cmov ( & t , c )
163
183
z64 .modOrder ()
164
184
z64 .toScalar (z )
165
185
}
166
186
167
187
// Sub calculates z = x-y mod order.
168
188
func (z * Scalar ) Sub (x , y * Scalar ) {
169
- var z64 , x64 , y64 , t scalar64
189
+ var z64 , x64 , y64 scalar64
170
190
x64 .fromScalar (x )
171
191
y64 .fromScalar (y )
172
- c := sub (z64 [:], x64 [:], y64 [:])
173
- sub (t [:], z64 [:], residue448 [:])
174
- z64 .Cmov (c , & t )
175
- z64 .modOrder ()
192
+ z64 .sub (& x64 , & y64 )
176
193
z64 .toScalar (z )
177
194
}
178
195
@@ -195,6 +212,3 @@ func (z *Scalar) Mul(x, y *Scalar) {
195
212
z64 .modOrder ()
196
213
z64 .toScalar (z )
197
214
}
198
-
199
- // IsZero returns true if z=0.
200
- func (z * Scalar ) IsZero () bool { z .Red (); return * z == Scalar {} }
0 commit comments