@@ -77,141 +77,6 @@ const FRAC_MODULUS_2: U256 = ORDER.shr_vartime(1);
7777#[ cfg_attr( docsrs, doc( cfg( feature = "arithmetic" ) ) ) ]
7878pub struct Scalar ( U256 ) ;
7979
80- impl Field for Scalar {
81- fn random ( rng : impl RngCore ) -> Self {
82- // Uses rejection sampling as the default random generation method,
83- // which produces a uniformly random distribution of scalars.
84- //
85- // This method is not constant time, but should be secure so long as
86- // rejected RNG outputs are unrelated to future ones (which is a
87- // necessary property of a `CryptoRng`).
88- //
89- // With an unbiased RNG, the probability of failing to complete after 4
90- // iterations is vanishingly small.
91- Self :: generate_vartime ( rng)
92- }
93-
94- fn zero ( ) -> Self {
95- Self :: ZERO
96- }
97-
98- fn one ( ) -> Self {
99- Self :: ONE
100- }
101-
102- #[ must_use]
103- fn square ( & self ) -> Self {
104- Scalar :: square ( self )
105- }
106-
107- #[ must_use]
108- fn double ( & self ) -> Self {
109- self . add ( self )
110- }
111-
112- fn invert ( & self ) -> CtOption < Self > {
113- Scalar :: invert ( self )
114- }
115-
116- /// Tonelli-Shank's algorithm for q mod 16 = 1
117- /// <https://eprint.iacr.org/2012/685.pdf> (page 12, algorithm 5)
118- #[ allow( clippy:: many_single_char_names) ]
119- fn sqrt ( & self ) -> CtOption < Self > {
120- // Note: `pow_vartime` is constant-time with respect to `self`
121- let w = self . pow_vartime ( & [
122- 0x777fa4bd19a06c82 ,
123- 0xfd755db9cd5e9140 ,
124- 0xffffffffffffffff ,
125- 0x1ffffffffffffff ,
126- ] ) ;
127-
128- let mut v = Self :: S ;
129- let mut x = * self * w;
130- let mut b = x * w;
131- let mut z = Self :: root_of_unity ( ) ;
132-
133- for max_v in ( 1 ..=Self :: S ) . rev ( ) {
134- let mut k = 1 ;
135- let mut tmp = b. square ( ) ;
136- let mut j_less_than_v = Choice :: from ( 1 ) ;
137-
138- for j in 2 ..max_v {
139- let tmp_is_one = tmp. ct_eq ( & Self :: one ( ) ) ;
140- let squared = Self :: conditional_select ( & tmp, & z, tmp_is_one) . square ( ) ;
141- tmp = Self :: conditional_select ( & squared, & tmp, tmp_is_one) ;
142- let new_z = Self :: conditional_select ( & z, & squared, tmp_is_one) ;
143- j_less_than_v &= !j. ct_eq ( & v) ;
144- k = u32:: conditional_select ( & j, & k, tmp_is_one) ;
145- z = Self :: conditional_select ( & z, & new_z, j_less_than_v) ;
146- }
147-
148- let result = x * z;
149- x = Self :: conditional_select ( & result, & x, b. ct_eq ( & Self :: one ( ) ) ) ;
150- z = z. square ( ) ;
151- b *= z;
152- v = k;
153- }
154-
155- CtOption :: new ( x, x. square ( ) . ct_eq ( self ) )
156- }
157- }
158-
159- impl PrimeField for Scalar {
160- type Repr = FieldBytes ;
161-
162- const NUM_BITS : u32 = 256 ;
163- const CAPACITY : u32 = 255 ;
164- const S : u32 = 6 ;
165-
166- /// Attempts to parse the given byte array as an SEC1-encoded scalar.
167- ///
168- /// Returns None if the byte array does not contain a big-endian integer in the range
169- /// [0, p).
170- fn from_repr ( bytes : FieldBytes ) -> CtOption < Self > {
171- let inner = U256 :: from_be_byte_array ( bytes) ;
172- CtOption :: new ( Self ( inner) , inner. ct_lt ( & Secp256k1 :: ORDER ) )
173- }
174-
175- fn to_repr ( & self ) -> FieldBytes {
176- self . to_bytes ( )
177- }
178-
179- fn is_odd ( & self ) -> Choice {
180- self . 0 . is_odd ( )
181- }
182-
183- fn multiplicative_generator ( ) -> Self {
184- 7u64 . into ( )
185- }
186-
187- fn root_of_unity ( ) -> Self {
188- Scalar :: from_repr ( arr ! [ u8 ;
189- 0x0c , 0x1d , 0xc0 , 0x60 , 0xe7 , 0xa9 , 0x19 , 0x86 , 0xdf , 0x98 , 0x79 , 0xa3 , 0xfb , 0xc4 ,
190- 0x83 , 0xa8 , 0x98 , 0xbd , 0xea , 0xb6 , 0x80 , 0x75 , 0x60 , 0x45 , 0x99 , 0x2f , 0x4b , 0x54 ,
191- 0x02 , 0xb0 , 0x52 , 0xf2
192- ] )
193- . unwrap ( )
194- }
195- }
196-
197- #[ cfg( feature = "bits" ) ]
198- #[ cfg_attr( docsrs, doc( cfg( feature = "bits" ) ) ) ]
199- impl PrimeFieldBits for Scalar {
200- #[ cfg( target_pointer_width = "32" ) ]
201- type ReprBits = [ u32 ; 8 ] ;
202-
203- #[ cfg( target_pointer_width = "64" ) ]
204- type ReprBits = [ u64 ; 4 ] ;
205-
206- fn to_le_bits ( & self ) -> ScalarBits {
207- self . into ( )
208- }
209-
210- fn char_le_bits ( ) -> ScalarBits {
211- ORDER . to_uint_array ( ) . into ( )
212- }
213- }
214-
21580impl Scalar {
21681 /// Zero scalar.
21782 pub const ZERO : Self = Self ( U256 :: ZERO ) ;
@@ -281,7 +146,7 @@ impl Scalar {
281146 let x56 = x28. pow2k ( 28 ) . mul ( & x28) ;
282147
283148 #[ rustfmt:: skip]
284- let res = x56
149+ let res = x56
285150 . pow2k ( 56 ) . mul ( & x56)
286151 . pow2k ( 14 ) . mul ( & x14)
287152 . pow2k ( 3 ) . mul ( & x_101)
@@ -357,6 +222,141 @@ impl Scalar {
357222 }
358223}
359224
225+ impl Field for Scalar {
226+ fn random ( rng : impl RngCore ) -> Self {
227+ // Uses rejection sampling as the default random generation method,
228+ // which produces a uniformly random distribution of scalars.
229+ //
230+ // This method is not constant time, but should be secure so long as
231+ // rejected RNG outputs are unrelated to future ones (which is a
232+ // necessary property of a `CryptoRng`).
233+ //
234+ // With an unbiased RNG, the probability of failing to complete after 4
235+ // iterations is vanishingly small.
236+ Self :: generate_vartime ( rng)
237+ }
238+
239+ fn zero ( ) -> Self {
240+ Self :: ZERO
241+ }
242+
243+ fn one ( ) -> Self {
244+ Self :: ONE
245+ }
246+
247+ #[ must_use]
248+ fn square ( & self ) -> Self {
249+ Scalar :: square ( self )
250+ }
251+
252+ #[ must_use]
253+ fn double ( & self ) -> Self {
254+ self . add ( self )
255+ }
256+
257+ fn invert ( & self ) -> CtOption < Self > {
258+ Scalar :: invert ( self )
259+ }
260+
261+ /// Tonelli-Shank's algorithm for q mod 16 = 1
262+ /// <https://eprint.iacr.org/2012/685.pdf> (page 12, algorithm 5)
263+ #[ allow( clippy:: many_single_char_names) ]
264+ fn sqrt ( & self ) -> CtOption < Self > {
265+ // Note: `pow_vartime` is constant-time with respect to `self`
266+ let w = self . pow_vartime ( & [
267+ 0x777fa4bd19a06c82 ,
268+ 0xfd755db9cd5e9140 ,
269+ 0xffffffffffffffff ,
270+ 0x1ffffffffffffff ,
271+ ] ) ;
272+
273+ let mut v = Self :: S ;
274+ let mut x = * self * w;
275+ let mut b = x * w;
276+ let mut z = Self :: root_of_unity ( ) ;
277+
278+ for max_v in ( 1 ..=Self :: S ) . rev ( ) {
279+ let mut k = 1 ;
280+ let mut tmp = b. square ( ) ;
281+ let mut j_less_than_v = Choice :: from ( 1 ) ;
282+
283+ for j in 2 ..max_v {
284+ let tmp_is_one = tmp. ct_eq ( & Self :: one ( ) ) ;
285+ let squared = Self :: conditional_select ( & tmp, & z, tmp_is_one) . square ( ) ;
286+ tmp = Self :: conditional_select ( & squared, & tmp, tmp_is_one) ;
287+ let new_z = Self :: conditional_select ( & z, & squared, tmp_is_one) ;
288+ j_less_than_v &= !j. ct_eq ( & v) ;
289+ k = u32:: conditional_select ( & j, & k, tmp_is_one) ;
290+ z = Self :: conditional_select ( & z, & new_z, j_less_than_v) ;
291+ }
292+
293+ let result = x * z;
294+ x = Self :: conditional_select ( & result, & x, b. ct_eq ( & Self :: one ( ) ) ) ;
295+ z = z. square ( ) ;
296+ b *= z;
297+ v = k;
298+ }
299+
300+ CtOption :: new ( x, x. square ( ) . ct_eq ( self ) )
301+ }
302+ }
303+
304+ impl PrimeField for Scalar {
305+ type Repr = FieldBytes ;
306+
307+ const NUM_BITS : u32 = 256 ;
308+ const CAPACITY : u32 = 255 ;
309+ const S : u32 = 6 ;
310+
311+ /// Attempts to parse the given byte array as an SEC1-encoded scalar.
312+ ///
313+ /// Returns None if the byte array does not contain a big-endian integer in the range
314+ /// [0, p).
315+ fn from_repr ( bytes : FieldBytes ) -> CtOption < Self > {
316+ let inner = U256 :: from_be_byte_array ( bytes) ;
317+ CtOption :: new ( Self ( inner) , inner. ct_lt ( & Secp256k1 :: ORDER ) )
318+ }
319+
320+ fn to_repr ( & self ) -> FieldBytes {
321+ self . to_bytes ( )
322+ }
323+
324+ fn is_odd ( & self ) -> Choice {
325+ self . 0 . is_odd ( )
326+ }
327+
328+ fn multiplicative_generator ( ) -> Self {
329+ 7u64 . into ( )
330+ }
331+
332+ fn root_of_unity ( ) -> Self {
333+ Scalar :: from_repr ( arr ! [ u8 ;
334+ 0x0c , 0x1d , 0xc0 , 0x60 , 0xe7 , 0xa9 , 0x19 , 0x86 , 0xdf , 0x98 , 0x79 , 0xa3 , 0xfb , 0xc4 ,
335+ 0x83 , 0xa8 , 0x98 , 0xbd , 0xea , 0xb6 , 0x80 , 0x75 , 0x60 , 0x45 , 0x99 , 0x2f , 0x4b , 0x54 ,
336+ 0x02 , 0xb0 , 0x52 , 0xf2
337+ ] )
338+ . unwrap ( )
339+ }
340+ }
341+
342+ #[ cfg( feature = "bits" ) ]
343+ #[ cfg_attr( docsrs, doc( cfg( feature = "bits" ) ) ) ]
344+ impl PrimeFieldBits for Scalar {
345+ #[ cfg( target_pointer_width = "32" ) ]
346+ type ReprBits = [ u32 ; 8 ] ;
347+
348+ #[ cfg( target_pointer_width = "64" ) ]
349+ type ReprBits = [ u64 ; 4 ] ;
350+
351+ fn to_le_bits ( & self ) -> ScalarBits {
352+ self . into ( )
353+ }
354+
355+ fn char_le_bits ( ) -> ScalarBits {
356+ ORDER . to_uint_array ( ) . into ( )
357+ }
358+ }
359+
360360impl DefaultIsZeroes for Scalar { }
361361
362362impl From < u32 > for Scalar {
0 commit comments