github.com/aquanetwork/aquachain@v1.7.8/crypto/secp256k1/libsecp256k1/src/field_10x26_impl.h (about) 1 /********************************************************************** 2 * Copyright (c) 2013, 2014 Pieter Wuille * 3 * Distributed under the MIT software license, see the accompanying * 4 * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 **********************************************************************/ 6 7 #ifndef SECP256K1_FIELD_REPR_IMPL_H 8 #define SECP256K1_FIELD_REPR_IMPL_H 9 10 #include "util.h" 11 #include "num.h" 12 #include "field.h" 13 14 #ifdef VERIFY 15 static void secp256k1_fe_verify(const secp256k1_fe *a) { 16 const uint32_t *d = a->n; 17 int m = a->normalized ? 1 : 2 * a->magnitude, r = 1; 18 r &= (d[0] <= 0x3FFFFFFUL * m); 19 r &= (d[1] <= 0x3FFFFFFUL * m); 20 r &= (d[2] <= 0x3FFFFFFUL * m); 21 r &= (d[3] <= 0x3FFFFFFUL * m); 22 r &= (d[4] <= 0x3FFFFFFUL * m); 23 r &= (d[5] <= 0x3FFFFFFUL * m); 24 r &= (d[6] <= 0x3FFFFFFUL * m); 25 r &= (d[7] <= 0x3FFFFFFUL * m); 26 r &= (d[8] <= 0x3FFFFFFUL * m); 27 r &= (d[9] <= 0x03FFFFFUL * m); 28 r &= (a->magnitude >= 0); 29 r &= (a->magnitude <= 32); 30 if (a->normalized) { 31 r &= (a->magnitude <= 1); 32 if (r && (d[9] == 0x03FFFFFUL)) { 33 uint32_t mid = d[8] & d[7] & d[6] & d[5] & d[4] & d[3] & d[2]; 34 if (mid == 0x3FFFFFFUL) { 35 r &= ((d[1] + 0x40UL + ((d[0] + 0x3D1UL) >> 26)) <= 0x3FFFFFFUL); 36 } 37 } 38 } 39 VERIFY_CHECK(r == 1); 40 } 41 #endif 42 43 static void secp256k1_fe_normalize(secp256k1_fe *r) { 44 uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], 45 t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; 46 47 /* Reduce t9 at the start so there will be at most a single carry from the first pass */ 48 uint32_t m; 49 uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; 50 51 /* The first pass ensures the magnitude is 1, ... */ 52 t0 += x * 0x3D1UL; t1 += (x << 6); 53 t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; 54 t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; 55 t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; m = t2; 56 t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; m &= t3; 57 t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; m &= t4; 58 t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; m &= t5; 59 t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; m &= t6; 60 t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; m &= t7; 61 t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; m &= t8; 62 63 /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ 64 VERIFY_CHECK(t9 >> 23 == 0); 65 66 /* At most a single final reduction is needed; check if the value is >= the field characteristic */ 67 x = (t9 >> 22) | ((t9 == 0x03FFFFFUL) & (m == 0x3FFFFFFUL) 68 & ((t1 + 0x40UL + ((t0 + 0x3D1UL) >> 26)) > 0x3FFFFFFUL)); 69 70 /* Apply the final reduction (for constant-time behaviour, we do it always) */ 71 t0 += x * 0x3D1UL; t1 += (x << 6); 72 t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; 73 t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; 74 t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; 75 t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; 76 t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; 77 t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; 78 t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; 79 t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; 80 t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; 81 82 /* If t9 didn't carry to bit 22 already, then it should have after any final reduction */ 83 VERIFY_CHECK(t9 >> 22 == x); 84 85 /* Mask off the possible multiple of 2^256 from the final reduction */ 86 t9 &= 0x03FFFFFUL; 87 88 r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; 89 r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9; 90 91 #ifdef VERIFY 92 r->magnitude = 1; 93 r->normalized = 1; 94 secp256k1_fe_verify(r); 95 #endif 96 } 97 98 static void secp256k1_fe_normalize_weak(secp256k1_fe *r) { 99 uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], 100 t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; 101 102 /* Reduce t9 at the start so there will be at most a single carry from the first pass */ 103 uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; 104 105 /* The first pass ensures the magnitude is 1, ... */ 106 t0 += x * 0x3D1UL; t1 += (x << 6); 107 t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; 108 t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; 109 t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; 110 t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; 111 t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; 112 t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; 113 t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; 114 t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; 115 t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; 116 117 /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ 118 VERIFY_CHECK(t9 >> 23 == 0); 119 120 r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; 121 r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9; 122 123 #ifdef VERIFY 124 r->magnitude = 1; 125 secp256k1_fe_verify(r); 126 #endif 127 } 128 129 static void secp256k1_fe_normalize_var(secp256k1_fe *r) { 130 uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], 131 t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; 132 133 /* Reduce t9 at the start so there will be at most a single carry from the first pass */ 134 uint32_t m; 135 uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; 136 137 /* The first pass ensures the magnitude is 1, ... */ 138 t0 += x * 0x3D1UL; t1 += (x << 6); 139 t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; 140 t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; 141 t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; m = t2; 142 t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; m &= t3; 143 t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; m &= t4; 144 t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; m &= t5; 145 t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; m &= t6; 146 t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; m &= t7; 147 t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; m &= t8; 148 149 /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ 150 VERIFY_CHECK(t9 >> 23 == 0); 151 152 /* At most a single final reduction is needed; check if the value is >= the field characteristic */ 153 x = (t9 >> 22) | ((t9 == 0x03FFFFFUL) & (m == 0x3FFFFFFUL) 154 & ((t1 + 0x40UL + ((t0 + 0x3D1UL) >> 26)) > 0x3FFFFFFUL)); 155 156 if (x) { 157 t0 += 0x3D1UL; t1 += (x << 6); 158 t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; 159 t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; 160 t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; 161 t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; 162 t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; 163 t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; 164 t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; 165 t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; 166 t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; 167 168 /* If t9 didn't carry to bit 22 already, then it should have after any final reduction */ 169 VERIFY_CHECK(t9 >> 22 == x); 170 171 /* Mask off the possible multiple of 2^256 from the final reduction */ 172 t9 &= 0x03FFFFFUL; 173 } 174 175 r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; 176 r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9; 177 178 #ifdef VERIFY 179 r->magnitude = 1; 180 r->normalized = 1; 181 secp256k1_fe_verify(r); 182 #endif 183 } 184 185 static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *r) { 186 uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], 187 t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; 188 189 /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ 190 uint32_t z0, z1; 191 192 /* Reduce t9 at the start so there will be at most a single carry from the first pass */ 193 uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; 194 195 /* The first pass ensures the magnitude is 1, ... */ 196 t0 += x * 0x3D1UL; t1 += (x << 6); 197 t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; z0 = t0; z1 = t0 ^ 0x3D0UL; 198 t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL; 199 t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2; 200 t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3; 201 t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; z0 |= t4; z1 &= t4; 202 t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; z0 |= t5; z1 &= t5; 203 t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; z0 |= t6; z1 &= t6; 204 t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; z0 |= t7; z1 &= t7; 205 t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; z0 |= t8; z1 &= t8; 206 z0 |= t9; z1 &= t9 ^ 0x3C00000UL; 207 208 /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ 209 VERIFY_CHECK(t9 >> 23 == 0); 210 211 return (z0 == 0) | (z1 == 0x3FFFFFFUL); 212 } 213 214 static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r) { 215 uint32_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9; 216 uint32_t z0, z1; 217 uint32_t x; 218 219 t0 = r->n[0]; 220 t9 = r->n[9]; 221 222 /* Reduce t9 at the start so there will be at most a single carry from the first pass */ 223 x = t9 >> 22; 224 225 /* The first pass ensures the magnitude is 1, ... */ 226 t0 += x * 0x3D1UL; 227 228 /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ 229 z0 = t0 & 0x3FFFFFFUL; 230 z1 = z0 ^ 0x3D0UL; 231 232 /* Fast return path should catch the majority of cases */ 233 if ((z0 != 0UL) & (z1 != 0x3FFFFFFUL)) { 234 return 0; 235 } 236 237 t1 = r->n[1]; 238 t2 = r->n[2]; 239 t3 = r->n[3]; 240 t4 = r->n[4]; 241 t5 = r->n[5]; 242 t6 = r->n[6]; 243 t7 = r->n[7]; 244 t8 = r->n[8]; 245 246 t9 &= 0x03FFFFFUL; 247 t1 += (x << 6); 248 249 t1 += (t0 >> 26); 250 t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL; 251 t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2; 252 t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3; 253 t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; z0 |= t4; z1 &= t4; 254 t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; z0 |= t5; z1 &= t5; 255 t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; z0 |= t6; z1 &= t6; 256 t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; z0 |= t7; z1 &= t7; 257 t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; z0 |= t8; z1 &= t8; 258 z0 |= t9; z1 &= t9 ^ 0x3C00000UL; 259 260 /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ 261 VERIFY_CHECK(t9 >> 23 == 0); 262 263 return (z0 == 0) | (z1 == 0x3FFFFFFUL); 264 } 265 266 SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe *r, int a) { 267 r->n[0] = a; 268 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; 269 #ifdef VERIFY 270 r->magnitude = 1; 271 r->normalized = 1; 272 secp256k1_fe_verify(r); 273 #endif 274 } 275 276 SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe *a) { 277 const uint32_t *t = a->n; 278 #ifdef VERIFY 279 VERIFY_CHECK(a->normalized); 280 secp256k1_fe_verify(a); 281 #endif 282 return (t[0] | t[1] | t[2] | t[3] | t[4] | t[5] | t[6] | t[7] | t[8] | t[9]) == 0; 283 } 284 285 SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe *a) { 286 #ifdef VERIFY 287 VERIFY_CHECK(a->normalized); 288 secp256k1_fe_verify(a); 289 #endif 290 return a->n[0] & 1; 291 } 292 293 SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe *a) { 294 int i; 295 #ifdef VERIFY 296 a->magnitude = 0; 297 a->normalized = 1; 298 #endif 299 for (i=0; i<10; i++) { 300 a->n[i] = 0; 301 } 302 } 303 304 static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) { 305 int i; 306 #ifdef VERIFY 307 VERIFY_CHECK(a->normalized); 308 VERIFY_CHECK(b->normalized); 309 secp256k1_fe_verify(a); 310 secp256k1_fe_verify(b); 311 #endif 312 for (i = 9; i >= 0; i--) { 313 if (a->n[i] > b->n[i]) { 314 return 1; 315 } 316 if (a->n[i] < b->n[i]) { 317 return -1; 318 } 319 } 320 return 0; 321 } 322 323 static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a) { 324 r->n[0] = (uint32_t)a[31] | ((uint32_t)a[30] << 8) | ((uint32_t)a[29] << 16) | ((uint32_t)(a[28] & 0x3) << 24); 325 r->n[1] = (uint32_t)((a[28] >> 2) & 0x3f) | ((uint32_t)a[27] << 6) | ((uint32_t)a[26] << 14) | ((uint32_t)(a[25] & 0xf) << 22); 326 r->n[2] = (uint32_t)((a[25] >> 4) & 0xf) | ((uint32_t)a[24] << 4) | ((uint32_t)a[23] << 12) | ((uint32_t)(a[22] & 0x3f) << 20); 327 r->n[3] = (uint32_t)((a[22] >> 6) & 0x3) | ((uint32_t)a[21] << 2) | ((uint32_t)a[20] << 10) | ((uint32_t)a[19] << 18); 328 r->n[4] = (uint32_t)a[18] | ((uint32_t)a[17] << 8) | ((uint32_t)a[16] << 16) | ((uint32_t)(a[15] & 0x3) << 24); 329 r->n[5] = (uint32_t)((a[15] >> 2) & 0x3f) | ((uint32_t)a[14] << 6) | ((uint32_t)a[13] << 14) | ((uint32_t)(a[12] & 0xf) << 22); 330 r->n[6] = (uint32_t)((a[12] >> 4) & 0xf) | ((uint32_t)a[11] << 4) | ((uint32_t)a[10] << 12) | ((uint32_t)(a[9] & 0x3f) << 20); 331 r->n[7] = (uint32_t)((a[9] >> 6) & 0x3) | ((uint32_t)a[8] << 2) | ((uint32_t)a[7] << 10) | ((uint32_t)a[6] << 18); 332 r->n[8] = (uint32_t)a[5] | ((uint32_t)a[4] << 8) | ((uint32_t)a[3] << 16) | ((uint32_t)(a[2] & 0x3) << 24); 333 r->n[9] = (uint32_t)((a[2] >> 2) & 0x3f) | ((uint32_t)a[1] << 6) | ((uint32_t)a[0] << 14); 334 335 if (r->n[9] == 0x3FFFFFUL && (r->n[8] & r->n[7] & r->n[6] & r->n[5] & r->n[4] & r->n[3] & r->n[2]) == 0x3FFFFFFUL && (r->n[1] + 0x40UL + ((r->n[0] + 0x3D1UL) >> 26)) > 0x3FFFFFFUL) { 336 return 0; 337 } 338 #ifdef VERIFY 339 r->magnitude = 1; 340 r->normalized = 1; 341 secp256k1_fe_verify(r); 342 #endif 343 return 1; 344 } 345 346 /** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ 347 static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a) { 348 #ifdef VERIFY 349 VERIFY_CHECK(a->normalized); 350 secp256k1_fe_verify(a); 351 #endif 352 r[0] = (a->n[9] >> 14) & 0xff; 353 r[1] = (a->n[9] >> 6) & 0xff; 354 r[2] = ((a->n[9] & 0x3F) << 2) | ((a->n[8] >> 24) & 0x3); 355 r[3] = (a->n[8] >> 16) & 0xff; 356 r[4] = (a->n[8] >> 8) & 0xff; 357 r[5] = a->n[8] & 0xff; 358 r[6] = (a->n[7] >> 18) & 0xff; 359 r[7] = (a->n[7] >> 10) & 0xff; 360 r[8] = (a->n[7] >> 2) & 0xff; 361 r[9] = ((a->n[7] & 0x3) << 6) | ((a->n[6] >> 20) & 0x3f); 362 r[10] = (a->n[6] >> 12) & 0xff; 363 r[11] = (a->n[6] >> 4) & 0xff; 364 r[12] = ((a->n[6] & 0xf) << 4) | ((a->n[5] >> 22) & 0xf); 365 r[13] = (a->n[5] >> 14) & 0xff; 366 r[14] = (a->n[5] >> 6) & 0xff; 367 r[15] = ((a->n[5] & 0x3f) << 2) | ((a->n[4] >> 24) & 0x3); 368 r[16] = (a->n[4] >> 16) & 0xff; 369 r[17] = (a->n[4] >> 8) & 0xff; 370 r[18] = a->n[4] & 0xff; 371 r[19] = (a->n[3] >> 18) & 0xff; 372 r[20] = (a->n[3] >> 10) & 0xff; 373 r[21] = (a->n[3] >> 2) & 0xff; 374 r[22] = ((a->n[3] & 0x3) << 6) | ((a->n[2] >> 20) & 0x3f); 375 r[23] = (a->n[2] >> 12) & 0xff; 376 r[24] = (a->n[2] >> 4) & 0xff; 377 r[25] = ((a->n[2] & 0xf) << 4) | ((a->n[1] >> 22) & 0xf); 378 r[26] = (a->n[1] >> 14) & 0xff; 379 r[27] = (a->n[1] >> 6) & 0xff; 380 r[28] = ((a->n[1] & 0x3f) << 2) | ((a->n[0] >> 24) & 0x3); 381 r[29] = (a->n[0] >> 16) & 0xff; 382 r[30] = (a->n[0] >> 8) & 0xff; 383 r[31] = a->n[0] & 0xff; 384 } 385 386 SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) { 387 #ifdef VERIFY 388 VERIFY_CHECK(a->magnitude <= m); 389 secp256k1_fe_verify(a); 390 #endif 391 r->n[0] = 0x3FFFC2FUL * 2 * (m + 1) - a->n[0]; 392 r->n[1] = 0x3FFFFBFUL * 2 * (m + 1) - a->n[1]; 393 r->n[2] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[2]; 394 r->n[3] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[3]; 395 r->n[4] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[4]; 396 r->n[5] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[5]; 397 r->n[6] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[6]; 398 r->n[7] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[7]; 399 r->n[8] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[8]; 400 r->n[9] = 0x03FFFFFUL * 2 * (m + 1) - a->n[9]; 401 #ifdef VERIFY 402 r->magnitude = m + 1; 403 r->normalized = 0; 404 secp256k1_fe_verify(r); 405 #endif 406 } 407 408 SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe *r, int a) { 409 r->n[0] *= a; 410 r->n[1] *= a; 411 r->n[2] *= a; 412 r->n[3] *= a; 413 r->n[4] *= a; 414 r->n[5] *= a; 415 r->n[6] *= a; 416 r->n[7] *= a; 417 r->n[8] *= a; 418 r->n[9] *= a; 419 #ifdef VERIFY 420 r->magnitude *= a; 421 r->normalized = 0; 422 secp256k1_fe_verify(r); 423 #endif 424 } 425 426 SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a) { 427 #ifdef VERIFY 428 secp256k1_fe_verify(a); 429 #endif 430 r->n[0] += a->n[0]; 431 r->n[1] += a->n[1]; 432 r->n[2] += a->n[2]; 433 r->n[3] += a->n[3]; 434 r->n[4] += a->n[4]; 435 r->n[5] += a->n[5]; 436 r->n[6] += a->n[6]; 437 r->n[7] += a->n[7]; 438 r->n[8] += a->n[8]; 439 r->n[9] += a->n[9]; 440 #ifdef VERIFY 441 r->magnitude += a->magnitude; 442 r->normalized = 0; 443 secp256k1_fe_verify(r); 444 #endif 445 } 446 447 #if defined(USE_EXTERNAL_ASM) 448 449 /* External assembler implementation */ 450 void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b); 451 void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a); 452 453 #else 454 455 #ifdef VERIFY 456 #define VERIFY_BITS(x, n) VERIFY_CHECK(((x) >> (n)) == 0) 457 #else 458 #define VERIFY_BITS(x, n) do { } while(0) 459 #endif 460 461 SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b) { 462 uint64_t c, d; 463 uint64_t u0, u1, u2, u3, u4, u5, u6, u7, u8; 464 uint32_t t9, t1, t0, t2, t3, t4, t5, t6, t7; 465 const uint32_t M = 0x3FFFFFFUL, R0 = 0x3D10UL, R1 = 0x400UL; 466 467 VERIFY_BITS(a[0], 30); 468 VERIFY_BITS(a[1], 30); 469 VERIFY_BITS(a[2], 30); 470 VERIFY_BITS(a[3], 30); 471 VERIFY_BITS(a[4], 30); 472 VERIFY_BITS(a[5], 30); 473 VERIFY_BITS(a[6], 30); 474 VERIFY_BITS(a[7], 30); 475 VERIFY_BITS(a[8], 30); 476 VERIFY_BITS(a[9], 26); 477 VERIFY_BITS(b[0], 30); 478 VERIFY_BITS(b[1], 30); 479 VERIFY_BITS(b[2], 30); 480 VERIFY_BITS(b[3], 30); 481 VERIFY_BITS(b[4], 30); 482 VERIFY_BITS(b[5], 30); 483 VERIFY_BITS(b[6], 30); 484 VERIFY_BITS(b[7], 30); 485 VERIFY_BITS(b[8], 30); 486 VERIFY_BITS(b[9], 26); 487 488 /** [... a b c] is a shorthand for ... + a<<52 + b<<26 + c<<0 mod n. 489 * px is a shorthand for sum(a[i]*b[x-i], i=0..x). 490 * Note that [x 0 0 0 0 0 0 0 0 0 0] = [x*R1 x*R0]. 491 */ 492 493 d = (uint64_t)a[0] * b[9] 494 + (uint64_t)a[1] * b[8] 495 + (uint64_t)a[2] * b[7] 496 + (uint64_t)a[3] * b[6] 497 + (uint64_t)a[4] * b[5] 498 + (uint64_t)a[5] * b[4] 499 + (uint64_t)a[6] * b[3] 500 + (uint64_t)a[7] * b[2] 501 + (uint64_t)a[8] * b[1] 502 + (uint64_t)a[9] * b[0]; 503 /* VERIFY_BITS(d, 64); */ 504 /* [d 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ 505 t9 = d & M; d >>= 26; 506 VERIFY_BITS(t9, 26); 507 VERIFY_BITS(d, 38); 508 /* [d t9 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ 509 510 c = (uint64_t)a[0] * b[0]; 511 VERIFY_BITS(c, 60); 512 /* [d t9 0 0 0 0 0 0 0 0 c] = [p9 0 0 0 0 0 0 0 0 p0] */ 513 d += (uint64_t)a[1] * b[9] 514 + (uint64_t)a[2] * b[8] 515 + (uint64_t)a[3] * b[7] 516 + (uint64_t)a[4] * b[6] 517 + (uint64_t)a[5] * b[5] 518 + (uint64_t)a[6] * b[4] 519 + (uint64_t)a[7] * b[3] 520 + (uint64_t)a[8] * b[2] 521 + (uint64_t)a[9] * b[1]; 522 VERIFY_BITS(d, 63); 523 /* [d t9 0 0 0 0 0 0 0 0 c] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ 524 u0 = d & M; d >>= 26; c += u0 * R0; 525 VERIFY_BITS(u0, 26); 526 VERIFY_BITS(d, 37); 527 VERIFY_BITS(c, 61); 528 /* [d u0 t9 0 0 0 0 0 0 0 0 c-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ 529 t0 = c & M; c >>= 26; c += u0 * R1; 530 VERIFY_BITS(t0, 26); 531 VERIFY_BITS(c, 37); 532 /* [d u0 t9 0 0 0 0 0 0 0 c-u0*R1 t0-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ 533 /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ 534 535 c += (uint64_t)a[0] * b[1] 536 + (uint64_t)a[1] * b[0]; 537 VERIFY_BITS(c, 62); 538 /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 p1 p0] */ 539 d += (uint64_t)a[2] * b[9] 540 + (uint64_t)a[3] * b[8] 541 + (uint64_t)a[4] * b[7] 542 + (uint64_t)a[5] * b[6] 543 + (uint64_t)a[6] * b[5] 544 + (uint64_t)a[7] * b[4] 545 + (uint64_t)a[8] * b[3] 546 + (uint64_t)a[9] * b[2]; 547 VERIFY_BITS(d, 63); 548 /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ 549 u1 = d & M; d >>= 26; c += u1 * R0; 550 VERIFY_BITS(u1, 26); 551 VERIFY_BITS(d, 37); 552 VERIFY_BITS(c, 63); 553 /* [d u1 0 t9 0 0 0 0 0 0 0 c-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ 554 t1 = c & M; c >>= 26; c += u1 * R1; 555 VERIFY_BITS(t1, 26); 556 VERIFY_BITS(c, 38); 557 /* [d u1 0 t9 0 0 0 0 0 0 c-u1*R1 t1-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ 558 /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ 559 560 c += (uint64_t)a[0] * b[2] 561 + (uint64_t)a[1] * b[1] 562 + (uint64_t)a[2] * b[0]; 563 VERIFY_BITS(c, 62); 564 /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ 565 d += (uint64_t)a[3] * b[9] 566 + (uint64_t)a[4] * b[8] 567 + (uint64_t)a[5] * b[7] 568 + (uint64_t)a[6] * b[6] 569 + (uint64_t)a[7] * b[5] 570 + (uint64_t)a[8] * b[4] 571 + (uint64_t)a[9] * b[3]; 572 VERIFY_BITS(d, 63); 573 /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ 574 u2 = d & M; d >>= 26; c += u2 * R0; 575 VERIFY_BITS(u2, 26); 576 VERIFY_BITS(d, 37); 577 VERIFY_BITS(c, 63); 578 /* [d u2 0 0 t9 0 0 0 0 0 0 c-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ 579 t2 = c & M; c >>= 26; c += u2 * R1; 580 VERIFY_BITS(t2, 26); 581 VERIFY_BITS(c, 38); 582 /* [d u2 0 0 t9 0 0 0 0 0 c-u2*R1 t2-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ 583 /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ 584 585 c += (uint64_t)a[0] * b[3] 586 + (uint64_t)a[1] * b[2] 587 + (uint64_t)a[2] * b[1] 588 + (uint64_t)a[3] * b[0]; 589 VERIFY_BITS(c, 63); 590 /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ 591 d += (uint64_t)a[4] * b[9] 592 + (uint64_t)a[5] * b[8] 593 + (uint64_t)a[6] * b[7] 594 + (uint64_t)a[7] * b[6] 595 + (uint64_t)a[8] * b[5] 596 + (uint64_t)a[9] * b[4]; 597 VERIFY_BITS(d, 63); 598 /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ 599 u3 = d & M; d >>= 26; c += u3 * R0; 600 VERIFY_BITS(u3, 26); 601 VERIFY_BITS(d, 37); 602 /* VERIFY_BITS(c, 64); */ 603 /* [d u3 0 0 0 t9 0 0 0 0 0 c-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ 604 t3 = c & M; c >>= 26; c += u3 * R1; 605 VERIFY_BITS(t3, 26); 606 VERIFY_BITS(c, 39); 607 /* [d u3 0 0 0 t9 0 0 0 0 c-u3*R1 t3-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ 608 /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ 609 610 c += (uint64_t)a[0] * b[4] 611 + (uint64_t)a[1] * b[3] 612 + (uint64_t)a[2] * b[2] 613 + (uint64_t)a[3] * b[1] 614 + (uint64_t)a[4] * b[0]; 615 VERIFY_BITS(c, 63); 616 /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ 617 d += (uint64_t)a[5] * b[9] 618 + (uint64_t)a[6] * b[8] 619 + (uint64_t)a[7] * b[7] 620 + (uint64_t)a[8] * b[6] 621 + (uint64_t)a[9] * b[5]; 622 VERIFY_BITS(d, 62); 623 /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ 624 u4 = d & M; d >>= 26; c += u4 * R0; 625 VERIFY_BITS(u4, 26); 626 VERIFY_BITS(d, 36); 627 /* VERIFY_BITS(c, 64); */ 628 /* [d u4 0 0 0 0 t9 0 0 0 0 c-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ 629 t4 = c & M; c >>= 26; c += u4 * R1; 630 VERIFY_BITS(t4, 26); 631 VERIFY_BITS(c, 39); 632 /* [d u4 0 0 0 0 t9 0 0 0 c-u4*R1 t4-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ 633 /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ 634 635 c += (uint64_t)a[0] * b[5] 636 + (uint64_t)a[1] * b[4] 637 + (uint64_t)a[2] * b[3] 638 + (uint64_t)a[3] * b[2] 639 + (uint64_t)a[4] * b[1] 640 + (uint64_t)a[5] * b[0]; 641 VERIFY_BITS(c, 63); 642 /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ 643 d += (uint64_t)a[6] * b[9] 644 + (uint64_t)a[7] * b[8] 645 + (uint64_t)a[8] * b[7] 646 + (uint64_t)a[9] * b[6]; 647 VERIFY_BITS(d, 62); 648 /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ 649 u5 = d & M; d >>= 26; c += u5 * R0; 650 VERIFY_BITS(u5, 26); 651 VERIFY_BITS(d, 36); 652 /* VERIFY_BITS(c, 64); */ 653 /* [d u5 0 0 0 0 0 t9 0 0 0 c-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ 654 t5 = c & M; c >>= 26; c += u5 * R1; 655 VERIFY_BITS(t5, 26); 656 VERIFY_BITS(c, 39); 657 /* [d u5 0 0 0 0 0 t9 0 0 c-u5*R1 t5-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ 658 /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ 659 660 c += (uint64_t)a[0] * b[6] 661 + (uint64_t)a[1] * b[5] 662 + (uint64_t)a[2] * b[4] 663 + (uint64_t)a[3] * b[3] 664 + (uint64_t)a[4] * b[2] 665 + (uint64_t)a[5] * b[1] 666 + (uint64_t)a[6] * b[0]; 667 VERIFY_BITS(c, 63); 668 /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ 669 d += (uint64_t)a[7] * b[9] 670 + (uint64_t)a[8] * b[8] 671 + (uint64_t)a[9] * b[7]; 672 VERIFY_BITS(d, 61); 673 /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ 674 u6 = d & M; d >>= 26; c += u6 * R0; 675 VERIFY_BITS(u6, 26); 676 VERIFY_BITS(d, 35); 677 /* VERIFY_BITS(c, 64); */ 678 /* [d u6 0 0 0 0 0 0 t9 0 0 c-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ 679 t6 = c & M; c >>= 26; c += u6 * R1; 680 VERIFY_BITS(t6, 26); 681 VERIFY_BITS(c, 39); 682 /* [d u6 0 0 0 0 0 0 t9 0 c-u6*R1 t6-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ 683 /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ 684 685 c += (uint64_t)a[0] * b[7] 686 + (uint64_t)a[1] * b[6] 687 + (uint64_t)a[2] * b[5] 688 + (uint64_t)a[3] * b[4] 689 + (uint64_t)a[4] * b[3] 690 + (uint64_t)a[5] * b[2] 691 + (uint64_t)a[6] * b[1] 692 + (uint64_t)a[7] * b[0]; 693 /* VERIFY_BITS(c, 64); */ 694 VERIFY_CHECK(c <= 0x8000007C00000007ULL); 695 /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ 696 d += (uint64_t)a[8] * b[9] 697 + (uint64_t)a[9] * b[8]; 698 VERIFY_BITS(d, 58); 699 /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ 700 u7 = d & M; d >>= 26; c += u7 * R0; 701 VERIFY_BITS(u7, 26); 702 VERIFY_BITS(d, 32); 703 /* VERIFY_BITS(c, 64); */ 704 VERIFY_CHECK(c <= 0x800001703FFFC2F7ULL); 705 /* [d u7 0 0 0 0 0 0 0 t9 0 c-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ 706 t7 = c & M; c >>= 26; c += u7 * R1; 707 VERIFY_BITS(t7, 26); 708 VERIFY_BITS(c, 38); 709 /* [d u7 0 0 0 0 0 0 0 t9 c-u7*R1 t7-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ 710 /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ 711 712 c += (uint64_t)a[0] * b[8] 713 + (uint64_t)a[1] * b[7] 714 + (uint64_t)a[2] * b[6] 715 + (uint64_t)a[3] * b[5] 716 + (uint64_t)a[4] * b[4] 717 + (uint64_t)a[5] * b[3] 718 + (uint64_t)a[6] * b[2] 719 + (uint64_t)a[7] * b[1] 720 + (uint64_t)a[8] * b[0]; 721 /* VERIFY_BITS(c, 64); */ 722 VERIFY_CHECK(c <= 0x9000007B80000008ULL); 723 /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 724 d += (uint64_t)a[9] * b[9]; 725 VERIFY_BITS(d, 57); 726 /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 727 u8 = d & M; d >>= 26; c += u8 * R0; 728 VERIFY_BITS(u8, 26); 729 VERIFY_BITS(d, 31); 730 /* VERIFY_BITS(c, 64); */ 731 VERIFY_CHECK(c <= 0x9000016FBFFFC2F8ULL); 732 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 733 734 r[3] = t3; 735 VERIFY_BITS(r[3], 26); 736 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 737 r[4] = t4; 738 VERIFY_BITS(r[4], 26); 739 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 740 r[5] = t5; 741 VERIFY_BITS(r[5], 26); 742 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 743 r[6] = t6; 744 VERIFY_BITS(r[6], 26); 745 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 746 r[7] = t7; 747 VERIFY_BITS(r[7], 26); 748 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 749 750 r[8] = c & M; c >>= 26; c += u8 * R1; 751 VERIFY_BITS(r[8], 26); 752 VERIFY_BITS(c, 39); 753 /* [d u8 0 0 0 0 0 0 0 0 t9+c-u8*R1 r8-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 754 /* [d 0 0 0 0 0 0 0 0 0 t9+c r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 755 c += d * R0 + t9; 756 VERIFY_BITS(c, 45); 757 /* [d 0 0 0 0 0 0 0 0 0 c-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 758 r[9] = c & (M >> 4); c >>= 22; c += d * (R1 << 4); 759 VERIFY_BITS(r[9], 22); 760 VERIFY_BITS(c, 46); 761 /* [d 0 0 0 0 0 0 0 0 r9+((c-d*R1<<4)<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 762 /* [d 0 0 0 0 0 0 0 -d*R1 r9+(c<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 763 /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 764 765 d = c * (R0 >> 4) + t0; 766 VERIFY_BITS(d, 56); 767 /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 d-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 768 r[0] = d & M; d >>= 26; 769 VERIFY_BITS(r[0], 26); 770 VERIFY_BITS(d, 30); 771 /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1+d r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 772 d += c * (R1 >> 4) + t1; 773 VERIFY_BITS(d, 53); 774 VERIFY_CHECK(d <= 0x10000003FFFFBFULL); 775 /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 d-c*R1>>4 r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 776 /* [r9 r8 r7 r6 r5 r4 r3 t2 d r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 777 r[1] = d & M; d >>= 26; 778 VERIFY_BITS(r[1], 26); 779 VERIFY_BITS(d, 27); 780 VERIFY_CHECK(d <= 0x4000000ULL); 781 /* [r9 r8 r7 r6 r5 r4 r3 t2+d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 782 d += t2; 783 VERIFY_BITS(d, 27); 784 /* [r9 r8 r7 r6 r5 r4 r3 d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 785 r[2] = d; 786 VERIFY_BITS(r[2], 27); 787 /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 788 } 789 790 SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a) { 791 uint64_t c, d; 792 uint64_t u0, u1, u2, u3, u4, u5, u6, u7, u8; 793 uint32_t t9, t0, t1, t2, t3, t4, t5, t6, t7; 794 const uint32_t M = 0x3FFFFFFUL, R0 = 0x3D10UL, R1 = 0x400UL; 795 796 VERIFY_BITS(a[0], 30); 797 VERIFY_BITS(a[1], 30); 798 VERIFY_BITS(a[2], 30); 799 VERIFY_BITS(a[3], 30); 800 VERIFY_BITS(a[4], 30); 801 VERIFY_BITS(a[5], 30); 802 VERIFY_BITS(a[6], 30); 803 VERIFY_BITS(a[7], 30); 804 VERIFY_BITS(a[8], 30); 805 VERIFY_BITS(a[9], 26); 806 807 /** [... a b c] is a shorthand for ... + a<<52 + b<<26 + c<<0 mod n. 808 * px is a shorthand for sum(a[i]*a[x-i], i=0..x). 809 * Note that [x 0 0 0 0 0 0 0 0 0 0] = [x*R1 x*R0]. 810 */ 811 812 d = (uint64_t)(a[0]*2) * a[9] 813 + (uint64_t)(a[1]*2) * a[8] 814 + (uint64_t)(a[2]*2) * a[7] 815 + (uint64_t)(a[3]*2) * a[6] 816 + (uint64_t)(a[4]*2) * a[5]; 817 /* VERIFY_BITS(d, 64); */ 818 /* [d 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ 819 t9 = d & M; d >>= 26; 820 VERIFY_BITS(t9, 26); 821 VERIFY_BITS(d, 38); 822 /* [d t9 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ 823 824 c = (uint64_t)a[0] * a[0]; 825 VERIFY_BITS(c, 60); 826 /* [d t9 0 0 0 0 0 0 0 0 c] = [p9 0 0 0 0 0 0 0 0 p0] */ 827 d += (uint64_t)(a[1]*2) * a[9] 828 + (uint64_t)(a[2]*2) * a[8] 829 + (uint64_t)(a[3]*2) * a[7] 830 + (uint64_t)(a[4]*2) * a[6] 831 + (uint64_t)a[5] * a[5]; 832 VERIFY_BITS(d, 63); 833 /* [d t9 0 0 0 0 0 0 0 0 c] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ 834 u0 = d & M; d >>= 26; c += u0 * R0; 835 VERIFY_BITS(u0, 26); 836 VERIFY_BITS(d, 37); 837 VERIFY_BITS(c, 61); 838 /* [d u0 t9 0 0 0 0 0 0 0 0 c-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ 839 t0 = c & M; c >>= 26; c += u0 * R1; 840 VERIFY_BITS(t0, 26); 841 VERIFY_BITS(c, 37); 842 /* [d u0 t9 0 0 0 0 0 0 0 c-u0*R1 t0-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ 843 /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ 844 845 c += (uint64_t)(a[0]*2) * a[1]; 846 VERIFY_BITS(c, 62); 847 /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 p1 p0] */ 848 d += (uint64_t)(a[2]*2) * a[9] 849 + (uint64_t)(a[3]*2) * a[8] 850 + (uint64_t)(a[4]*2) * a[7] 851 + (uint64_t)(a[5]*2) * a[6]; 852 VERIFY_BITS(d, 63); 853 /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ 854 u1 = d & M; d >>= 26; c += u1 * R0; 855 VERIFY_BITS(u1, 26); 856 VERIFY_BITS(d, 37); 857 VERIFY_BITS(c, 63); 858 /* [d u1 0 t9 0 0 0 0 0 0 0 c-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ 859 t1 = c & M; c >>= 26; c += u1 * R1; 860 VERIFY_BITS(t1, 26); 861 VERIFY_BITS(c, 38); 862 /* [d u1 0 t9 0 0 0 0 0 0 c-u1*R1 t1-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ 863 /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ 864 865 c += (uint64_t)(a[0]*2) * a[2] 866 + (uint64_t)a[1] * a[1]; 867 VERIFY_BITS(c, 62); 868 /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ 869 d += (uint64_t)(a[3]*2) * a[9] 870 + (uint64_t)(a[4]*2) * a[8] 871 + (uint64_t)(a[5]*2) * a[7] 872 + (uint64_t)a[6] * a[6]; 873 VERIFY_BITS(d, 63); 874 /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ 875 u2 = d & M; d >>= 26; c += u2 * R0; 876 VERIFY_BITS(u2, 26); 877 VERIFY_BITS(d, 37); 878 VERIFY_BITS(c, 63); 879 /* [d u2 0 0 t9 0 0 0 0 0 0 c-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ 880 t2 = c & M; c >>= 26; c += u2 * R1; 881 VERIFY_BITS(t2, 26); 882 VERIFY_BITS(c, 38); 883 /* [d u2 0 0 t9 0 0 0 0 0 c-u2*R1 t2-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ 884 /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ 885 886 c += (uint64_t)(a[0]*2) * a[3] 887 + (uint64_t)(a[1]*2) * a[2]; 888 VERIFY_BITS(c, 63); 889 /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ 890 d += (uint64_t)(a[4]*2) * a[9] 891 + (uint64_t)(a[5]*2) * a[8] 892 + (uint64_t)(a[6]*2) * a[7]; 893 VERIFY_BITS(d, 63); 894 /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ 895 u3 = d & M; d >>= 26; c += u3 * R0; 896 VERIFY_BITS(u3, 26); 897 VERIFY_BITS(d, 37); 898 /* VERIFY_BITS(c, 64); */ 899 /* [d u3 0 0 0 t9 0 0 0 0 0 c-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ 900 t3 = c & M; c >>= 26; c += u3 * R1; 901 VERIFY_BITS(t3, 26); 902 VERIFY_BITS(c, 39); 903 /* [d u3 0 0 0 t9 0 0 0 0 c-u3*R1 t3-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ 904 /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ 905 906 c += (uint64_t)(a[0]*2) * a[4] 907 + (uint64_t)(a[1]*2) * a[3] 908 + (uint64_t)a[2] * a[2]; 909 VERIFY_BITS(c, 63); 910 /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ 911 d += (uint64_t)(a[5]*2) * a[9] 912 + (uint64_t)(a[6]*2) * a[8] 913 + (uint64_t)a[7] * a[7]; 914 VERIFY_BITS(d, 62); 915 /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ 916 u4 = d & M; d >>= 26; c += u4 * R0; 917 VERIFY_BITS(u4, 26); 918 VERIFY_BITS(d, 36); 919 /* VERIFY_BITS(c, 64); */ 920 /* [d u4 0 0 0 0 t9 0 0 0 0 c-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ 921 t4 = c & M; c >>= 26; c += u4 * R1; 922 VERIFY_BITS(t4, 26); 923 VERIFY_BITS(c, 39); 924 /* [d u4 0 0 0 0 t9 0 0 0 c-u4*R1 t4-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ 925 /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ 926 927 c += (uint64_t)(a[0]*2) * a[5] 928 + (uint64_t)(a[1]*2) * a[4] 929 + (uint64_t)(a[2]*2) * a[3]; 930 VERIFY_BITS(c, 63); 931 /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ 932 d += (uint64_t)(a[6]*2) * a[9] 933 + (uint64_t)(a[7]*2) * a[8]; 934 VERIFY_BITS(d, 62); 935 /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ 936 u5 = d & M; d >>= 26; c += u5 * R0; 937 VERIFY_BITS(u5, 26); 938 VERIFY_BITS(d, 36); 939 /* VERIFY_BITS(c, 64); */ 940 /* [d u5 0 0 0 0 0 t9 0 0 0 c-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ 941 t5 = c & M; c >>= 26; c += u5 * R1; 942 VERIFY_BITS(t5, 26); 943 VERIFY_BITS(c, 39); 944 /* [d u5 0 0 0 0 0 t9 0 0 c-u5*R1 t5-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ 945 /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ 946 947 c += (uint64_t)(a[0]*2) * a[6] 948 + (uint64_t)(a[1]*2) * a[5] 949 + (uint64_t)(a[2]*2) * a[4] 950 + (uint64_t)a[3] * a[3]; 951 VERIFY_BITS(c, 63); 952 /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ 953 d += (uint64_t)(a[7]*2) * a[9] 954 + (uint64_t)a[8] * a[8]; 955 VERIFY_BITS(d, 61); 956 /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ 957 u6 = d & M; d >>= 26; c += u6 * R0; 958 VERIFY_BITS(u6, 26); 959 VERIFY_BITS(d, 35); 960 /* VERIFY_BITS(c, 64); */ 961 /* [d u6 0 0 0 0 0 0 t9 0 0 c-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ 962 t6 = c & M; c >>= 26; c += u6 * R1; 963 VERIFY_BITS(t6, 26); 964 VERIFY_BITS(c, 39); 965 /* [d u6 0 0 0 0 0 0 t9 0 c-u6*R1 t6-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ 966 /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ 967 968 c += (uint64_t)(a[0]*2) * a[7] 969 + (uint64_t)(a[1]*2) * a[6] 970 + (uint64_t)(a[2]*2) * a[5] 971 + (uint64_t)(a[3]*2) * a[4]; 972 /* VERIFY_BITS(c, 64); */ 973 VERIFY_CHECK(c <= 0x8000007C00000007ULL); 974 /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ 975 d += (uint64_t)(a[8]*2) * a[9]; 976 VERIFY_BITS(d, 58); 977 /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ 978 u7 = d & M; d >>= 26; c += u7 * R0; 979 VERIFY_BITS(u7, 26); 980 VERIFY_BITS(d, 32); 981 /* VERIFY_BITS(c, 64); */ 982 VERIFY_CHECK(c <= 0x800001703FFFC2F7ULL); 983 /* [d u7 0 0 0 0 0 0 0 t9 0 c-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ 984 t7 = c & M; c >>= 26; c += u7 * R1; 985 VERIFY_BITS(t7, 26); 986 VERIFY_BITS(c, 38); 987 /* [d u7 0 0 0 0 0 0 0 t9 c-u7*R1 t7-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ 988 /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ 989 990 c += (uint64_t)(a[0]*2) * a[8] 991 + (uint64_t)(a[1]*2) * a[7] 992 + (uint64_t)(a[2]*2) * a[6] 993 + (uint64_t)(a[3]*2) * a[5] 994 + (uint64_t)a[4] * a[4]; 995 /* VERIFY_BITS(c, 64); */ 996 VERIFY_CHECK(c <= 0x9000007B80000008ULL); 997 /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 998 d += (uint64_t)a[9] * a[9]; 999 VERIFY_BITS(d, 57); 1000 /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1001 u8 = d & M; d >>= 26; c += u8 * R0; 1002 VERIFY_BITS(u8, 26); 1003 VERIFY_BITS(d, 31); 1004 /* VERIFY_BITS(c, 64); */ 1005 VERIFY_CHECK(c <= 0x9000016FBFFFC2F8ULL); 1006 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1007 1008 r[3] = t3; 1009 VERIFY_BITS(r[3], 26); 1010 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1011 r[4] = t4; 1012 VERIFY_BITS(r[4], 26); 1013 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1014 r[5] = t5; 1015 VERIFY_BITS(r[5], 26); 1016 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1017 r[6] = t6; 1018 VERIFY_BITS(r[6], 26); 1019 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1020 r[7] = t7; 1021 VERIFY_BITS(r[7], 26); 1022 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1023 1024 r[8] = c & M; c >>= 26; c += u8 * R1; 1025 VERIFY_BITS(r[8], 26); 1026 VERIFY_BITS(c, 39); 1027 /* [d u8 0 0 0 0 0 0 0 0 t9+c-u8*R1 r8-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1028 /* [d 0 0 0 0 0 0 0 0 0 t9+c r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1029 c += d * R0 + t9; 1030 VERIFY_BITS(c, 45); 1031 /* [d 0 0 0 0 0 0 0 0 0 c-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1032 r[9] = c & (M >> 4); c >>= 22; c += d * (R1 << 4); 1033 VERIFY_BITS(r[9], 22); 1034 VERIFY_BITS(c, 46); 1035 /* [d 0 0 0 0 0 0 0 0 r9+((c-d*R1<<4)<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1036 /* [d 0 0 0 0 0 0 0 -d*R1 r9+(c<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1037 /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1038 1039 d = c * (R0 >> 4) + t0; 1040 VERIFY_BITS(d, 56); 1041 /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 d-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1042 r[0] = d & M; d >>= 26; 1043 VERIFY_BITS(r[0], 26); 1044 VERIFY_BITS(d, 30); 1045 /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1+d r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1046 d += c * (R1 >> 4) + t1; 1047 VERIFY_BITS(d, 53); 1048 VERIFY_CHECK(d <= 0x10000003FFFFBFULL); 1049 /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 d-c*R1>>4 r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1050 /* [r9 r8 r7 r6 r5 r4 r3 t2 d r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1051 r[1] = d & M; d >>= 26; 1052 VERIFY_BITS(r[1], 26); 1053 VERIFY_BITS(d, 27); 1054 VERIFY_CHECK(d <= 0x4000000ULL); 1055 /* [r9 r8 r7 r6 r5 r4 r3 t2+d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1056 d += t2; 1057 VERIFY_BITS(d, 27); 1058 /* [r9 r8 r7 r6 r5 r4 r3 d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1059 r[2] = d; 1060 VERIFY_BITS(r[2], 27); 1061 /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 1062 } 1063 #endif 1064 1065 static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) { 1066 #ifdef VERIFY 1067 VERIFY_CHECK(a->magnitude <= 8); 1068 VERIFY_CHECK(b->magnitude <= 8); 1069 secp256k1_fe_verify(a); 1070 secp256k1_fe_verify(b); 1071 VERIFY_CHECK(r != b); 1072 #endif 1073 secp256k1_fe_mul_inner(r->n, a->n, b->n); 1074 #ifdef VERIFY 1075 r->magnitude = 1; 1076 r->normalized = 0; 1077 secp256k1_fe_verify(r); 1078 #endif 1079 } 1080 1081 static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) { 1082 #ifdef VERIFY 1083 VERIFY_CHECK(a->magnitude <= 8); 1084 secp256k1_fe_verify(a); 1085 #endif 1086 secp256k1_fe_sqr_inner(r->n, a->n); 1087 #ifdef VERIFY 1088 r->magnitude = 1; 1089 r->normalized = 0; 1090 secp256k1_fe_verify(r); 1091 #endif 1092 } 1093 1094 static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { 1095 uint32_t mask0, mask1; 1096 mask0 = flag + ~((uint32_t)0); 1097 mask1 = ~mask0; 1098 r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); 1099 r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); 1100 r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1); 1101 r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); 1102 r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1); 1103 r->n[5] = (r->n[5] & mask0) | (a->n[5] & mask1); 1104 r->n[6] = (r->n[6] & mask0) | (a->n[6] & mask1); 1105 r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1); 1106 r->n[8] = (r->n[8] & mask0) | (a->n[8] & mask1); 1107 r->n[9] = (r->n[9] & mask0) | (a->n[9] & mask1); 1108 #ifdef VERIFY 1109 if (a->magnitude > r->magnitude) { 1110 r->magnitude = a->magnitude; 1111 } 1112 r->normalized &= a->normalized; 1113 #endif 1114 } 1115 1116 static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) { 1117 uint32_t mask0, mask1; 1118 mask0 = flag + ~((uint32_t)0); 1119 mask1 = ~mask0; 1120 r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); 1121 r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); 1122 r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1); 1123 r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); 1124 r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1); 1125 r->n[5] = (r->n[5] & mask0) | (a->n[5] & mask1); 1126 r->n[6] = (r->n[6] & mask0) | (a->n[6] & mask1); 1127 r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1); 1128 } 1129 1130 static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a) { 1131 #ifdef VERIFY 1132 VERIFY_CHECK(a->normalized); 1133 #endif 1134 r->n[0] = a->n[0] | a->n[1] << 26; 1135 r->n[1] = a->n[1] >> 6 | a->n[2] << 20; 1136 r->n[2] = a->n[2] >> 12 | a->n[3] << 14; 1137 r->n[3] = a->n[3] >> 18 | a->n[4] << 8; 1138 r->n[4] = a->n[4] >> 24 | a->n[5] << 2 | a->n[6] << 28; 1139 r->n[5] = a->n[6] >> 4 | a->n[7] << 22; 1140 r->n[6] = a->n[7] >> 10 | a->n[8] << 16; 1141 r->n[7] = a->n[8] >> 16 | a->n[9] << 10; 1142 } 1143 1144 static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a) { 1145 r->n[0] = a->n[0] & 0x3FFFFFFUL; 1146 r->n[1] = a->n[0] >> 26 | ((a->n[1] << 6) & 0x3FFFFFFUL); 1147 r->n[2] = a->n[1] >> 20 | ((a->n[2] << 12) & 0x3FFFFFFUL); 1148 r->n[3] = a->n[2] >> 14 | ((a->n[3] << 18) & 0x3FFFFFFUL); 1149 r->n[4] = a->n[3] >> 8 | ((a->n[4] << 24) & 0x3FFFFFFUL); 1150 r->n[5] = (a->n[4] >> 2) & 0x3FFFFFFUL; 1151 r->n[6] = a->n[4] >> 28 | ((a->n[5] << 4) & 0x3FFFFFFUL); 1152 r->n[7] = a->n[5] >> 22 | ((a->n[6] << 10) & 0x3FFFFFFUL); 1153 r->n[8] = a->n[6] >> 16 | ((a->n[7] << 16) & 0x3FFFFFFUL); 1154 r->n[9] = a->n[7] >> 10; 1155 #ifdef VERIFY 1156 r->magnitude = 1; 1157 r->normalized = 1; 1158 #endif 1159 } 1160 1161 #endif /* SECP256K1_FIELD_REPR_IMPL_H */