@@ -33,6 +33,25 @@ func (z *scalar64) toScalar(x *Scalar) {
3333 binary .LittleEndian .PutUint64 (x [6 * 8 :7 * 8 ], z [6 ])
3434}
3535
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+
3655// add calculates z = x + y. Assumes len(z) > max(len(x),len(y)).
3756func add (z , x , y []uint64 ) uint64 {
3857 l , L , zz := len (x ), len (y ), y
@@ -81,14 +100,6 @@ func mulWord(z, x []uint64, y uint64) {
81100 z [len (x )] = carry
82101}
83102
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-
92103// leftShift shifts to the left the words of z returning the more significant word.
93104func (z * scalar64 ) leftShift (low uint64 ) uint64 {
94105 high := z [_N - 1 ]
@@ -108,6 +119,15 @@ func (z *scalar64) reduceOneWord(x uint64) {
108119 add (z [:], z [:], prod )
109120}
110121
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+
111131// modOrder reduces z mod order.
112132func (z * scalar64 ) modOrder () {
113133 var o64 , x scalar64
@@ -116,7 +136,7 @@ func (z *scalar64) modOrder() {
116136 // At most 8 (eight) iterations reduce 3 bits by subtracting.
117137 for i := 0 ; i < 8 ; i ++ {
118138 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 }
120140 }
121141}
122142
@@ -159,20 +179,17 @@ func (z *Scalar) Add(x, y *Scalar) {
159179 y64 .fromScalar (y )
160180 c := add (z64 [:], x64 [:], y64 [:])
161181 add (t [:], z64 [:], residue448 [:])
162- z64 .Cmov ( c , & t )
182+ z64 .cmov ( & t , c )
163183 z64 .modOrder ()
164184 z64 .toScalar (z )
165185}
166186
167187// Sub calculates z = x-y mod order.
168188func (z * Scalar ) Sub (x , y * Scalar ) {
169- var z64 , x64 , y64 , t scalar64
189+ var z64 , x64 , y64 scalar64
170190 x64 .fromScalar (x )
171191 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 )
176193 z64 .toScalar (z )
177194}
178195
@@ -195,6 +212,3 @@ func (z *Scalar) Mul(x, y *Scalar) {
195212 z64 .modOrder ()
196213 z64 .toScalar (z )
197214}
198-
199- // IsZero returns true if z=0.
200- func (z * Scalar ) IsZero () bool { z .Red (); return * z == Scalar {} }
0 commit comments