1212#include "field.h"
1313#include "modinv32_impl.h"
1414
15+ #ifdef X86
16+ # include <immintrin.h>
17+ #endif
18+
1519#ifdef VERIFY
1620static void secp256k1_fe_impl_verify (const secp256k1_fe * a ) {
1721 const uint32_t * d = a -> n ;
@@ -38,16 +42,20 @@ static void secp256k1_fe_impl_verify(const secp256k1_fe *a) {
3842#endif
3943
4044static 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 ;
5159}
5260
5361static 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) {
257265}
258266
259267SECP256K1_INLINE static void secp256k1_fe_impl_set_int (secp256k1_fe * r , int a ) {
268+ memset (r -> n , 0 , sizeof (r -> n ));
260269 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 ;
262270}
263271
264272SECP256K1_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) {
272280
273281static int secp256k1_fe_impl_cmp_var (const secp256k1_fe * a , const secp256k1_fe * b ) {
274282 int i ;
283+ int diff ;
275284 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 ;
281288 }
282289 }
283290 return 0 ;
@@ -338,24 +345,32 @@ static void secp256k1_fe_impl_get_b32(unsigned char *r, const secp256k1_fe *a) {
338345}
339346
340347SECP256K1_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+
341355 /* 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 );
346360
347361 /* Due to the properties above, the left hand in the subtractions below is never less than
348362 * 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 ];
359374}
360375
361376SECP256K1_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,
11111126}
11121127
11131128static 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 ;
11161131 r -> n [2 ] = a -> n [2 ] >> 12 | a -> n [3 ] << 14 ;
11171132 r -> n [3 ] = a -> n [3 ] >> 18 | a -> n [4 ] << 8 ;
11181133 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 ;
11201135 r -> n [6 ] = a -> n [7 ] >> 10 | a -> n [8 ] << 16 ;
11211136 r -> n [7 ] = a -> n [8 ] >> 16 | a -> n [9 ] << 10 ;
11221137}
11231138
11241139static SECP256K1_INLINE void secp256k1_fe_impl_from_storage (secp256k1_fe * r , const secp256k1_fe_storage * a ) {
11251140 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 );
11301145 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 );
11341149 r -> n [9 ] = a -> n [7 ] >> 10 ;
11351150}
11361151
0 commit comments