12
12
#include "field.h"
13
13
#include "modinv32_impl.h"
14
14
15
+ #ifdef X86
16
+ # include <immintrin.h>
17
+ #endif
18
+
15
19
#ifdef VERIFY
16
20
static void secp256k1_fe_impl_verify (const secp256k1_fe * a ) {
17
21
const uint32_t * d = a -> n ;
@@ -38,16 +42,20 @@ static void secp256k1_fe_impl_verify(const secp256k1_fe *a) {
38
42
#endif
39
43
40
44
static void secp256k1_fe_impl_get_bounds (secp256k1_fe * r , int m ) {
41
- r -> n [0 ] = 0x3FFFFFFUL * 2 * m ;
42
- r -> n [1 ] = 0x3FFFFFFUL * 2 * m ;
43
- r -> n [2 ] = 0x3FFFFFFUL * 2 * m ;
44
- r -> n [3 ] = 0x3FFFFFFUL * 2 * m ;
45
- r -> n [4 ] = 0x3FFFFFFUL * 2 * m ;
46
- r -> n [5 ] = 0x3FFFFFFUL * 2 * m ;
47
- r -> n [6 ] = 0x3FFFFFFUL * 2 * m ;
48
- r -> n [7 ] = 0x3FFFFFFUL * 2 * m ;
49
- r -> n [8 ] = 0x3FFFFFFUL * 2 * m ;
50
- r -> n [9 ] = 0x03FFFFFUL * 2 * m ;
45
+ const uint64_t two_m = 2 * m ;
46
+ const uint64_t bound1 = 0x3FFFFFFUL * two_m ;
47
+ const uint64_t bound2 = 0x03FFFFFUL * two_m ;
48
+
49
+ r -> n [0 ] = bound1 ;
50
+ r -> n [1 ] = bound1 ;
51
+ r -> n [2 ] = bound1 ;
52
+ r -> n [3 ] = bound1 ;
53
+ r -> n [4 ] = bound1 ;
54
+ r -> n [5 ] = bound1 ;
55
+ r -> n [6 ] = bound1 ;
56
+ r -> n [7 ] = bound1 ;
57
+ r -> n [8 ] = bound1 ;
58
+ r -> n [9 ] = bound2 ;
51
59
}
52
60
53
61
static void secp256k1_fe_impl_normalize (secp256k1_fe * r ) {
@@ -257,8 +265,8 @@ static int secp256k1_fe_impl_normalizes_to_zero_var(const secp256k1_fe *r) {
257
265
}
258
266
259
267
SECP256K1_INLINE static void secp256k1_fe_impl_set_int (secp256k1_fe * r , int a ) {
268
+ memset (r -> n , 0 , sizeof (r -> n ));
260
269
r -> n [0 ] = a ;
261
- r -> n [1 ] = r -> n [2 ] = r -> n [3 ] = r -> n [4 ] = r -> n [5 ] = r -> n [6 ] = r -> n [7 ] = r -> n [8 ] = r -> n [9 ] = 0 ;
262
270
}
263
271
264
272
SECP256K1_INLINE static int secp256k1_fe_impl_is_zero (const secp256k1_fe * a ) {
@@ -272,12 +280,11 @@ SECP256K1_INLINE static int secp256k1_fe_impl_is_odd(const secp256k1_fe *a) {
272
280
273
281
static int secp256k1_fe_impl_cmp_var (const secp256k1_fe * a , const secp256k1_fe * b ) {
274
282
int i ;
283
+ int diff ;
275
284
for (i = 9 ; i >= 0 ; i -- ) {
276
- if (a -> n [i ] > b -> n [i ]) {
277
- return 1 ;
278
- }
279
- if (a -> n [i ] < b -> n [i ]) {
280
- return -1 ;
285
+ diff = (a -> n [i ] > b -> n [i ]) - (a -> n [i ] < b -> n [i ]);
286
+ if (diff != 0 ) {
287
+ return diff ;
281
288
}
282
289
}
283
290
return 0 ;
@@ -338,24 +345,32 @@ static void secp256k1_fe_impl_get_b32(unsigned char *r, const secp256k1_fe *a) {
338
345
}
339
346
340
347
SECP256K1_INLINE static void secp256k1_fe_impl_negate_unchecked (secp256k1_fe * r , const secp256k1_fe * a , int m ) {
348
+ const uint32_t two_m1 = 2 * (m + 1 );
349
+
350
+ const uint32_t bound1 = 0x3FFFC2FUL * two_m1 ;
351
+ const uint32_t bound2 = 0x3FFFFBFUL * two_m1 ;
352
+ const uint32_t bound3 = 0x3FFFFFFUL * two_m1 ;
353
+ const uint32_t bound4 = 0x03FFFFFUL * two_m1 ;
354
+
341
355
/* For all legal values of m (0..31), the following properties hold: */
342
- VERIFY_CHECK (0x3FFFC2FUL * 2 * ( m + 1 ) >= 0x3FFFFFFUL * 2 * m );
343
- VERIFY_CHECK (0x3FFFFBFUL * 2 * ( m + 1 ) >= 0x3FFFFFFUL * 2 * m );
344
- VERIFY_CHECK (0x3FFFFFFUL * 2 * ( m + 1 ) >= 0x3FFFFFFUL * 2 * m );
345
- VERIFY_CHECK (0x03FFFFFUL * 2 * ( m + 1 ) >= 0x03FFFFFUL * 2 * m );
356
+ VERIFY_CHECK (bound1 >= 0x3FFFFFFUL * 2 * m );
357
+ VERIFY_CHECK (bound2 >= 0x3FFFFFFUL * 2 * m );
358
+ VERIFY_CHECK (bound3 >= 0x3FFFFFFUL * 2 * m );
359
+ VERIFY_CHECK (bound4 >= 0x03FFFFFUL * 2 * m );
346
360
347
361
/* Due to the properties above, the left hand in the subtractions below is never less than
348
362
* the right hand. */
349
- r -> n [0 ] = 0x3FFFC2FUL * 2 * (m + 1 ) - a -> n [0 ];
350
- r -> n [1 ] = 0x3FFFFBFUL * 2 * (m + 1 ) - a -> n [1 ];
351
- r -> n [2 ] = 0x3FFFFFFUL * 2 * (m + 1 ) - a -> n [2 ];
352
- r -> n [3 ] = 0x3FFFFFFUL * 2 * (m + 1 ) - a -> n [3 ];
353
- r -> n [4 ] = 0x3FFFFFFUL * 2 * (m + 1 ) - a -> n [4 ];
354
- r -> n [5 ] = 0x3FFFFFFUL * 2 * (m + 1 ) - a -> n [5 ];
355
- r -> n [6 ] = 0x3FFFFFFUL * 2 * (m + 1 ) - a -> n [6 ];
356
- r -> n [7 ] = 0x3FFFFFFUL * 2 * (m + 1 ) - a -> n [7 ];
357
- r -> n [8 ] = 0x3FFFFFFUL * 2 * (m + 1 ) - a -> n [8 ];
358
- r -> n [9 ] = 0x03FFFFFUL * 2 * (m + 1 ) - a -> n [9 ];
363
+
364
+ r -> n [0 ] = bound1 - a -> n [0 ];
365
+ r -> n [1 ] = bound2 - a -> n [1 ];
366
+ r -> n [2 ] = bound3 - a -> n [2 ];
367
+ r -> n [3 ] = bound3 - a -> n [3 ];
368
+ r -> n [4 ] = bound3 - a -> n [4 ];
369
+ r -> n [5 ] = bound3 - a -> n [5 ];
370
+ r -> n [6 ] = bound3 - a -> n [6 ];
371
+ r -> n [7 ] = bound3 - a -> n [7 ];
372
+ r -> n [8 ] = bound3 - a -> n [8 ];
373
+ r -> n [9 ] = bound4 - a -> n [9 ];
359
374
}
360
375
361
376
SECP256K1_INLINE static void secp256k1_fe_impl_mul_int_unchecked (secp256k1_fe * r , int a ) {
@@ -1111,26 +1126,26 @@ static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r,
1111
1126
}
1112
1127
1113
1128
static void secp256k1_fe_impl_to_storage (secp256k1_fe_storage * r , const secp256k1_fe * a ) {
1114
- r -> n [0 ] = a -> n [0 ] | a -> n [1 ] << 26 ;
1115
- r -> n [1 ] = a -> n [1 ] >> 6 | a -> n [2 ] << 20 ;
1129
+ r -> n [0 ] = a -> n [0 ] | a -> n [1 ] << 26 ;
1130
+ r -> n [1 ] = a -> n [1 ] >> 6 | a -> n [2 ] << 20 ;
1116
1131
r -> n [2 ] = a -> n [2 ] >> 12 | a -> n [3 ] << 14 ;
1117
1132
r -> n [3 ] = a -> n [3 ] >> 18 | a -> n [4 ] << 8 ;
1118
1133
r -> n [4 ] = a -> n [4 ] >> 24 | a -> n [5 ] << 2 | a -> n [6 ] << 28 ;
1119
- r -> n [5 ] = a -> n [6 ] >> 4 | a -> n [7 ] << 22 ;
1134
+ r -> n [5 ] = a -> n [6 ] >> 4 | a -> n [7 ] << 22 ;
1120
1135
r -> n [6 ] = a -> n [7 ] >> 10 | a -> n [8 ] << 16 ;
1121
1136
r -> n [7 ] = a -> n [8 ] >> 16 | a -> n [9 ] << 10 ;
1122
1137
}
1123
1138
1124
1139
static SECP256K1_INLINE void secp256k1_fe_impl_from_storage (secp256k1_fe * r , const secp256k1_fe_storage * a ) {
1125
1140
r -> n [0 ] = a -> n [0 ] & 0x3FFFFFFUL ;
1126
- r -> n [1 ] = a -> n [0 ] >> 26 | ((a -> n [1 ] << 6 ) & 0x3FFFFFFUL );
1127
- r -> n [2 ] = a -> n [1 ] >> 20 | ((a -> n [2 ] << 12 ) & 0x3FFFFFFUL );
1128
- r -> n [3 ] = a -> n [2 ] >> 14 | ((a -> n [3 ] << 18 ) & 0x3FFFFFFUL );
1129
- r -> n [4 ] = a -> n [3 ] >> 8 | ((a -> n [4 ] << 24 ) & 0x3FFFFFFUL );
1141
+ r -> n [1 ] = a -> n [0 ] >> 26 | ((a -> n [1 ] << 6 ) & 0x3FFFFFFUL );
1142
+ r -> n [2 ] = a -> n [1 ] >> 20 | ((a -> n [2 ] << 12 ) & 0x3FFFFFFUL );
1143
+ r -> n [3 ] = a -> n [2 ] >> 14 | ((a -> n [3 ] << 18 ) & 0x3FFFFFFUL );
1144
+ r -> n [4 ] = a -> n [3 ] >> 8 | ((a -> n [4 ] << 24 ) & 0x3FFFFFFUL );
1130
1145
r -> n [5 ] = (a -> n [4 ] >> 2 ) & 0x3FFFFFFUL ;
1131
- r -> n [6 ] = a -> n [4 ] >> 28 | ((a -> n [5 ] << 4 ) & 0x3FFFFFFUL );
1132
- r -> n [7 ] = a -> n [5 ] >> 22 | ((a -> n [6 ] << 10 ) & 0x3FFFFFFUL );
1133
- r -> n [8 ] = a -> n [6 ] >> 16 | ((a -> n [7 ] << 16 ) & 0x3FFFFFFUL );
1146
+ r -> n [6 ] = a -> n [4 ] >> 28 | ((a -> n [5 ] << 4 ) & 0x3FFFFFFUL );
1147
+ r -> n [7 ] = a -> n [5 ] >> 22 | ((a -> n [6 ] << 10 ) & 0x3FFFFFFUL );
1148
+ r -> n [8 ] = a -> n [6 ] >> 16 | ((a -> n [7 ] << 16 ) & 0x3FFFFFFUL );
1134
1149
r -> n [9 ] = a -> n [7 ] >> 10 ;
1135
1150
}
1136
1151
0 commit comments