@@ -74,7 +74,190 @@ macro_rules! field_element_type {
74
74
$decode_uint: path,
75
75
$encode_uint: path
76
76
) => {
77
- $crate:: field_element_type_core!( $fe, $bytes, $uint, $modulus, $decode_uint, $encode_uint) ;
77
+ impl $fe {
78
+ /// Zero element.
79
+ pub const ZERO : Self = Self ( <$uint>:: ZERO ) ;
80
+
81
+ /// Multiplicative identity.
82
+ pub const ONE : Self = Self :: from_uint_unchecked( <$uint>:: ONE ) ;
83
+
84
+ /// Create a [`
85
+ #[ doc = stringify!( $fe) ]
86
+ /// `] from a canonical big-endian representation.
87
+ pub fn from_bytes( repr: & $bytes) -> $crate:: subtle:: CtOption <Self > {
88
+ Self :: from_uint( $decode_uint( repr) )
89
+ }
90
+
91
+ /// Decode [`
92
+ #[ doc = stringify!( $fe) ]
93
+ /// `] from a big endian byte slice.
94
+ pub fn from_slice( slice: & [ u8 ] ) -> Option <Self > {
95
+ let array = <$bytes>:: try_from( slice) . ok( ) ?;
96
+ Self :: from_bytes( & array) . into( )
97
+ }
98
+
99
+ /// Decode [`
100
+ #[ doc = stringify!( $fe) ]
101
+ /// `]
102
+ /// from [`
103
+ #[ doc = stringify!( $uint) ]
104
+ /// `] converting it into Montgomery form:
105
+ ///
106
+ /// ```text
107
+ /// w * R^2 * R^-1 mod p = wR mod p
108
+ /// ```
109
+ pub fn from_uint( uint: $uint) -> $crate:: subtle:: CtOption <Self > {
110
+ use $crate:: subtle:: ConstantTimeLess as _;
111
+ let is_some = uint. ct_lt( & $modulus) ;
112
+ $crate:: subtle:: CtOption :: new( Self :: from_uint_unchecked( uint) , is_some)
113
+ }
114
+
115
+ /// Parse a [`
116
+ #[ doc = stringify!( $fe) ]
117
+ /// `] from big endian hex-encoded bytes.
118
+ ///
119
+ /// Does *not* perform a check that the field element does not overflow the order.
120
+ ///
121
+ /// This method is primarily intended for defining internal constants.
122
+ #[ allow( dead_code) ]
123
+ pub ( crate ) const fn from_hex( hex: & str ) -> Self {
124
+ Self :: from_uint_unchecked( <$uint>:: from_be_hex( hex) )
125
+ }
126
+
127
+ /// Convert a `u64` into a [`
128
+ #[ doc = stringify!( $fe) ]
129
+ /// `].
130
+ pub const fn from_u64( w: u64 ) -> Self {
131
+ Self :: from_uint_unchecked( <$uint>:: from_u64( w) )
132
+ }
133
+
134
+ /// Returns the big-endian encoding of this [`
135
+ #[ doc = stringify!( $fe) ]
136
+ /// `].
137
+ pub fn to_bytes( self ) -> $bytes {
138
+ $encode_uint( & self . to_canonical( ) )
139
+ }
140
+
141
+ /// Determine if this [`
142
+ #[ doc = stringify!( $fe) ]
143
+ /// `] is odd in the SEC1 sense: `self mod 2 == 1`.
144
+ ///
145
+ /// # Returns
146
+ ///
147
+ /// If odd, return `Choice(1)`. Otherwise, return `Choice(0)`.
148
+ pub fn is_odd( & self ) -> $crate:: subtle:: Choice {
149
+ use $crate:: bigint:: Integer ;
150
+ self . to_canonical( ) . is_odd( )
151
+ }
152
+
153
+ /// Determine if this [`
154
+ #[ doc = stringify!( $fe) ]
155
+ /// `] is even in the SEC1 sense: `self mod 2 == 0`.
156
+ ///
157
+ /// # Returns
158
+ ///
159
+ /// If even, return `Choice(1)`. Otherwise, return `Choice(0)`.
160
+ pub fn is_even( & self ) -> $crate:: subtle:: Choice {
161
+ !self . is_odd( )
162
+ }
163
+
164
+ /// Determine if this [`
165
+ #[ doc = stringify!( $fe) ]
166
+ /// `] is zero.
167
+ ///
168
+ /// # Returns
169
+ ///
170
+ /// If zero, return `Choice(1)`. Otherwise, return `Choice(0)`.
171
+ pub fn is_zero( & self ) -> $crate:: subtle:: Choice {
172
+ self . ct_eq( & Self :: ZERO )
173
+ }
174
+
175
+ /// Returns `self^exp`, where `exp` is a little-endian integer exponent.
176
+ ///
177
+ /// **This operation is variable time with respect to the exponent.**
178
+ ///
179
+ /// If the exponent is fixed, this operation is constant time.
180
+ pub const fn pow_vartime( & self , exp: & [ u64 ] ) -> Self {
181
+ let mut res = Self :: ONE ;
182
+ let mut i = exp. len( ) ;
183
+
184
+ while i > 0 {
185
+ i -= 1 ;
186
+
187
+ let mut j = 64 ;
188
+ while j > 0 {
189
+ j -= 1 ;
190
+ res = res. square( ) ;
191
+
192
+ if ( ( exp[ i] >> j) & 1 ) == 1 {
193
+ res = res. multiply( self ) ;
194
+ }
195
+ }
196
+ }
197
+
198
+ res
199
+ }
200
+
201
+ /// Right shifts the [`
202
+ #[ doc = stringify!( $fe) ]
203
+ /// `].
204
+ pub const fn shr( & self , shift: u32 ) -> Self {
205
+ Self ( self . 0 . wrapping_shr( shift) )
206
+ }
207
+
208
+ /// Right shifts the [`
209
+ #[ doc = stringify!( $fe) ]
210
+ /// `].
211
+ ///
212
+ /// Note: not constant-time with respect to the `shift` parameter.
213
+ pub const fn shr_vartime( & self , shift: u32 ) -> Self {
214
+ Self ( self . 0 . wrapping_shr_vartime( shift) )
215
+ }
216
+ }
217
+
218
+ impl $crate:: ff:: Field for $fe {
219
+ const ZERO : Self = Self :: ZERO ;
220
+ const ONE : Self = Self :: ONE ;
221
+
222
+ fn try_from_rng<R : $crate:: rand_core:: TryRngCore + ?Sized >(
223
+ rng: & mut R ,
224
+ ) -> :: core:: result:: Result <Self , R :: Error > {
225
+ let mut bytes = <$bytes>:: default ( ) ;
226
+
227
+ loop {
228
+ rng. try_fill_bytes( & mut bytes) ?;
229
+ if let Some ( fe) = Self :: from_bytes( & bytes) . into( ) {
230
+ return Ok ( fe) ;
231
+ }
232
+ }
233
+ }
234
+
235
+ fn is_zero( & self ) -> Choice {
236
+ Self :: ZERO . ct_eq( self )
237
+ }
238
+
239
+ #[ must_use]
240
+ fn square( & self ) -> Self {
241
+ self . square( )
242
+ }
243
+
244
+ #[ must_use]
245
+ fn double( & self ) -> Self {
246
+ self . double( )
247
+ }
248
+
249
+ fn invert( & self ) -> CtOption <Self > {
250
+ self . invert( )
251
+ }
252
+
253
+ fn sqrt( & self ) -> CtOption <Self > {
254
+ self . sqrt( )
255
+ }
256
+
257
+ fn sqrt_ratio( num: & Self , div: & Self ) -> ( Choice , Self ) {
258
+ $crate:: ff:: helpers:: sqrt_ratio_generic( num, div)
259
+ }
260
+ }
78
261
79
262
$crate:: field_op!( $fe, Add , add, add) ;
80
263
$crate:: field_op!( $fe, Sub , sub, sub) ;
@@ -313,204 +496,6 @@ macro_rules! field_element_type {
313
496
} ;
314
497
}
315
498
316
- /// Core field element functionality
317
- #[ macro_export]
318
- macro_rules! field_element_type_core {
319
- (
320
- $fe: tt,
321
- $bytes: ty,
322
- $uint: ty,
323
- $modulus: expr,
324
- $decode_uint: path,
325
- $encode_uint: path
326
- ) => {
327
- impl $fe {
328
- /// Zero element.
329
- pub const ZERO : Self = Self ( <$uint>:: ZERO ) ;
330
-
331
- /// Multiplicative identity.
332
- pub const ONE : Self = Self :: from_uint_unchecked( <$uint>:: ONE ) ;
333
-
334
- /// Create a [`
335
- #[ doc = stringify!( $fe) ]
336
- /// `] from a canonical big-endian representation.
337
- pub fn from_bytes( repr: & $bytes) -> $crate:: subtle:: CtOption <Self > {
338
- Self :: from_uint( $decode_uint( repr) )
339
- }
340
-
341
- /// Decode [`
342
- #[ doc = stringify!( $fe) ]
343
- /// `] from a big endian byte slice.
344
- pub fn from_slice( slice: & [ u8 ] ) -> Option <Self > {
345
- let array = <$bytes>:: try_from( slice) . ok( ) ?;
346
- Self :: from_bytes( & array) . into( )
347
- }
348
-
349
- /// Decode [`
350
- #[ doc = stringify!( $fe) ]
351
- /// `]
352
- /// from [`
353
- #[ doc = stringify!( $uint) ]
354
- /// `] converting it into Montgomery form:
355
- ///
356
- /// ```text
357
- /// w * R^2 * R^-1 mod p = wR mod p
358
- /// ```
359
- pub fn from_uint( uint: $uint) -> $crate:: subtle:: CtOption <Self > {
360
- use $crate:: subtle:: ConstantTimeLess as _;
361
- let is_some = uint. ct_lt( & $modulus) ;
362
- $crate:: subtle:: CtOption :: new( Self :: from_uint_unchecked( uint) , is_some)
363
- }
364
-
365
- /// Parse a [`
366
- #[ doc = stringify!( $fe) ]
367
- /// `] from big endian hex-encoded bytes.
368
- ///
369
- /// Does *not* perform a check that the field element does not overflow the order.
370
- ///
371
- /// This method is primarily intended for defining internal constants.
372
- #[ allow( dead_code) ]
373
- pub ( crate ) const fn from_hex( hex: & str ) -> Self {
374
- Self :: from_uint_unchecked( <$uint>:: from_be_hex( hex) )
375
- }
376
-
377
- /// Convert a `u64` into a [`
378
- #[ doc = stringify!( $fe) ]
379
- /// `].
380
- pub const fn from_u64( w: u64 ) -> Self {
381
- Self :: from_uint_unchecked( <$uint>:: from_u64( w) )
382
- }
383
-
384
- /// Returns the big-endian encoding of this [`
385
- #[ doc = stringify!( $fe) ]
386
- /// `].
387
- pub fn to_bytes( self ) -> $bytes {
388
- $encode_uint( & self . to_canonical( ) )
389
- }
390
-
391
- /// Determine if this [`
392
- #[ doc = stringify!( $fe) ]
393
- /// `] is odd in the SEC1 sense: `self mod 2 == 1`.
394
- ///
395
- /// # Returns
396
- ///
397
- /// If odd, return `Choice(1)`. Otherwise, return `Choice(0)`.
398
- pub fn is_odd( & self ) -> $crate:: subtle:: Choice {
399
- use $crate:: bigint:: Integer ;
400
- self . to_canonical( ) . is_odd( )
401
- }
402
-
403
- /// Determine if this [`
404
- #[ doc = stringify!( $fe) ]
405
- /// `] is even in the SEC1 sense: `self mod 2 == 0`.
406
- ///
407
- /// # Returns
408
- ///
409
- /// If even, return `Choice(1)`. Otherwise, return `Choice(0)`.
410
- pub fn is_even( & self ) -> $crate:: subtle:: Choice {
411
- !self . is_odd( )
412
- }
413
-
414
- /// Determine if this [`
415
- #[ doc = stringify!( $fe) ]
416
- /// `] is zero.
417
- ///
418
- /// # Returns
419
- ///
420
- /// If zero, return `Choice(1)`. Otherwise, return `Choice(0)`.
421
- pub fn is_zero( & self ) -> $crate:: subtle:: Choice {
422
- self . ct_eq( & Self :: ZERO )
423
- }
424
-
425
- /// Returns `self^exp`, where `exp` is a little-endian integer exponent.
426
- ///
427
- /// **This operation is variable time with respect to the exponent.**
428
- ///
429
- /// If the exponent is fixed, this operation is constant time.
430
- pub const fn pow_vartime( & self , exp: & [ u64 ] ) -> Self {
431
- let mut res = Self :: ONE ;
432
- let mut i = exp. len( ) ;
433
-
434
- while i > 0 {
435
- i -= 1 ;
436
-
437
- let mut j = 64 ;
438
- while j > 0 {
439
- j -= 1 ;
440
- res = res. square( ) ;
441
-
442
- if ( ( exp[ i] >> j) & 1 ) == 1 {
443
- res = res. multiply( self ) ;
444
- }
445
- }
446
- }
447
-
448
- res
449
- }
450
-
451
- /// Right shifts the [`
452
- #[ doc = stringify!( $fe) ]
453
- /// `].
454
- pub const fn shr( & self , shift: u32 ) -> Self {
455
- Self ( self . 0 . wrapping_shr( shift) )
456
- }
457
-
458
- /// Right shifts the [`
459
- #[ doc = stringify!( $fe) ]
460
- /// `].
461
- ///
462
- /// Note: not constant-time with respect to the `shift` parameter.
463
- pub const fn shr_vartime( & self , shift: u32 ) -> Self {
464
- Self ( self . 0 . wrapping_shr_vartime( shift) )
465
- }
466
- }
467
-
468
- impl $crate:: ff:: Field for $fe {
469
- const ZERO : Self = Self :: ZERO ;
470
- const ONE : Self = Self :: ONE ;
471
-
472
- fn try_from_rng<R : $crate:: rand_core:: TryRngCore + ?Sized >(
473
- rng: & mut R ,
474
- ) -> :: core:: result:: Result <Self , R :: Error > {
475
- let mut bytes = <$bytes>:: default ( ) ;
476
-
477
- loop {
478
- rng. try_fill_bytes( & mut bytes) ?;
479
- if let Some ( fe) = Self :: from_bytes( & bytes) . into( ) {
480
- return Ok ( fe) ;
481
- }
482
- }
483
- }
484
-
485
- fn is_zero( & self ) -> Choice {
486
- Self :: ZERO . ct_eq( self )
487
- }
488
-
489
- #[ must_use]
490
- fn square( & self ) -> Self {
491
- self . square( )
492
- }
493
-
494
- #[ must_use]
495
- fn double( & self ) -> Self {
496
- self . double( )
497
- }
498
-
499
- fn invert( & self ) -> CtOption <Self > {
500
- self . invert( )
501
- }
502
-
503
- fn sqrt( & self ) -> CtOption <Self > {
504
- self . sqrt( )
505
- }
506
-
507
- fn sqrt_ratio( num: & Self , div: & Self ) -> ( Choice , Self ) {
508
- $crate:: ff:: helpers:: sqrt_ratio_generic( num, div)
509
- }
510
- }
511
- } ;
512
- }
513
-
514
499
/// Emit a `core::ops` trait wrapper for an inherent method which is expected to be provided by a
515
500
/// backend arithmetic implementation (e.g. `fiat-crypto`)
516
501
#[ macro_export]
0 commit comments