Squashed 'src/secp256k1/' changes from ad2028f..b0210a9

b0210a9 Merge pull request #135
ee3eb4b Fix a memory leak and add a number of small tests.
4d879a3 Merge pull request #134
d5e8362 Merge pull request #127
7b92cf6 Merge pull request #132
0bf70a5 Merge pull request #133
29ae131 Make scalar_add_bit test's overflow detection exact
9048def Avoid undefined shift behaviour
efb7d4b Use constant-time conditional moves instead of byte slicing
d220062 Merge pull request #131
82f9254 Fix typo
601ca04 Merge pull request #129
35399e0 Bugfix: b is restricted, not r
c35ff1e Convert lambda splitter to pure scalar code.
cc604e9 Avoid division when decomposing scalars
ff8746d Add secp256k1_scalar_mul_shift_var
bd313f7 Merge pull request #119
276f987 Merge pull request #124
25d125e Merge pull request #126
24b3c65 Add a test case for ECDSA recomputing infinity
32600e5 Add a test for r >= order signature handling
4d4eeea Make secp256k1_fe_mul_inner use the r != property
be82e92 Require that r and b are different for field multiplication.
597128d Make num optional
659b554 Make constant initializers independent from num
0af5b47 Merge pull request #120
e2e8a36 Merge pull request #117
c76be9e Remove unused num functions
4285a98 Move lambda-splitting code to scalar.
f24041d Switch all EC/ECDSA logic from num to scalar
6794be6 Add scalar splitting functions
d1502eb Add secp256k1_scalar_inverse_var which delegates to GMP
b5c9ee7 Make test_point_times_order test meaningful again
0b73059 Switch wnaf splitting from num-based to scalar-based
1e6c77c Generalize secp256k1_scalar_get_bits
5213207 Add secp256k1_scalar_add_bit
3c0ae43 Merge pull request #122
6e05287 Do signature recovery/verification with 4 possible recid case
e3d692f Explain why no y=0 check is necessary for doubling
f7dc1c6 Optimize doubling: secp256k1 has no y=0 point
666d3b5 Merge pull request #121
2a54f9b Correct typo in comment
9d64145 Merge pull request #114
99f0728 Fix secp256k1_num_set_bin handling of 0
d907ebc Add bounds checking to field element setters
bb2cd94 Merge pull request #116
665775b Don't split the g factor when not using endomorphism
9431d6b Merge pull request #115
e2274c5 build: osx: attempt to work with homebrew keg-only packages

git-subtree-dir: src/secp256k1
git-subtree-split: b0210a95da433e048a11d298efbcc14eb423c95f
This commit is contained in:
Pieter Wuille
2014-12-04 19:17:07 +01:00
parent d48555b36a
commit 87bddb7a3a
30 changed files with 1255 additions and 787 deletions

View File

@@ -15,7 +15,7 @@
#define VERIFY_BITS(x, n) do { } while(0)
#endif
SECP256K1_INLINE static void secp256k1_fe_mul_inner(const uint64_t *a, const uint64_t *b, uint64_t *r) {
SECP256K1_INLINE static void secp256k1_fe_mul_inner(const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b, uint64_t *r) {
VERIFY_BITS(a[0], 56);
VERIFY_BITS(a[1], 56);
VERIFY_BITS(a[2], 56);
@@ -26,6 +26,7 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(const uint64_t *a, const uin
VERIFY_BITS(b[2], 56);
VERIFY_BITS(b[3], 56);
VERIFY_BITS(b[4], 52);
VERIFY_CHECK(r != b);
const uint64_t M = 0xFFFFFFFFFFFFFULL, R = 0x1000003D10ULL;
/* [... a b c] is a shorthand for ... + a<<104 + b<<52 + c<<0 mod n.
@@ -33,15 +34,17 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(const uint64_t *a, const uin
* Note that [x 0 0 0 0 0] = [x*R].
*/
uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4];
__int128 c, d;
d = (__int128)a[0] * b[3]
+ (__int128)a[1] * b[2]
+ (__int128)a[2] * b[1]
+ (__int128)a[3] * b[0];
d = (__int128)a0 * b[3]
+ (__int128)a1 * b[2]
+ (__int128)a2 * b[1]
+ (__int128)a3 * b[0];
VERIFY_BITS(d, 114);
/* [d 0 0 0] = [p3 0 0 0] */
c = (__int128)a[4] * b[4];
c = (__int128)a4 * b[4];
VERIFY_BITS(c, 112);
/* [c 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */
d += (c & M) * R; c >>= 52;
@@ -53,11 +56,11 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(const uint64_t *a, const uin
VERIFY_BITS(d, 63);
/* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */
d += (__int128)a[0] * b[4]
+ (__int128)a[1] * b[3]
+ (__int128)a[2] * b[2]
+ (__int128)a[3] * b[1]
+ (__int128)a[4] * b[0];
d += (__int128)a0 * b[4]
+ (__int128)a1 * b[3]
+ (__int128)a2 * b[2]
+ (__int128)a3 * b[1]
+ (__int128)a4 * b[0];
VERIFY_BITS(d, 115);
/* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */
d += c * R;
@@ -72,13 +75,13 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(const uint64_t *a, const uin
VERIFY_BITS(t4, 48);
/* [d t4+(tx<<48) t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */
c = (__int128)a[0] * b[0];
c = (__int128)a0 * b[0];
VERIFY_BITS(c, 112);
/* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 0 p4 p3 0 0 p0] */
d += (__int128)a[1] * b[4]
+ (__int128)a[2] * b[3]
+ (__int128)a[3] * b[2]
+ (__int128)a[4] * b[1];
d += (__int128)a1 * b[4]
+ (__int128)a2 * b[3]
+ (__int128)a3 * b[2]
+ (__int128)a4 * b[1];
VERIFY_BITS(d, 115);
/* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */
uint64_t u0 = d & M; d >>= 52;
@@ -92,48 +95,43 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(const uint64_t *a, const uin
c += (__int128)u0 * (R >> 4);
VERIFY_BITS(c, 115);
/* [d 0 t4 t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */
uint64_t t0 = c & M; c >>= 52;
VERIFY_BITS(t0, 52);
VERIFY_BITS(c, 61);
/* [d 0 t4 t3 0 c t0] = [p8 0 0 p5 p4 p3 0 0 p0] */
c += (__int128)a[0] * b[1]
+ (__int128)a[1] * b[0];
VERIFY_BITS(c, 114);
/* [d 0 t4 t3 0 c t0] = [p8 0 0 p5 p4 p3 0 p1 p0] */
d += (__int128)a[2] * b[4]
+ (__int128)a[3] * b[3]
+ (__int128)a[4] * b[2];
VERIFY_BITS(d, 114);
/* [d 0 t4 t3 0 c t0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */
c += (d & M) * R; d >>= 52;
VERIFY_BITS(c, 115);
VERIFY_BITS(d, 62);
/* [d 0 0 t4 t3 0 c t0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */
uint64_t t1 = c & M; c >>= 52;
VERIFY_BITS(t1, 52);
VERIFY_BITS(c, 63);
/* [d 0 0 t4 t3 c t1 t0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */
c += (__int128)a[0] * b[2]
+ (__int128)a[1] * b[1]
+ (__int128)a[2] * b[0];
VERIFY_BITS(c, 114);
/* [d 0 0 t4 t3 c t1 t0] = [p8 0 p6 p5 p4 p3 p2 p1 p0] */
d += (__int128)a[3] * b[4]
+ (__int128)a[4] * b[3];
VERIFY_BITS(d, 114);
/* [d 0 0 t4 t3 c t1 t0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
c += (d & M) * R; d >>= 52;
VERIFY_BITS(c, 115);
VERIFY_BITS(d, 62);
/* [d 0 0 0 t4 t3 c t1 t0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
r[0] = t0;
r[0] = c & M; c >>= 52;
VERIFY_BITS(r[0], 52);
/* [d 0 0 0 t4 t3 c t1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
r[1] = t1;
VERIFY_BITS(c, 61);
/* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 0 p0] */
c += (__int128)a0 * b[1]
+ (__int128)a1 * b[0];
VERIFY_BITS(c, 114);
/* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 p1 p0] */
d += (__int128)a2 * b[4]
+ (__int128)a3 * b[3]
+ (__int128)a4 * b[2];
VERIFY_BITS(d, 114);
/* [d 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */
c += (d & M) * R; d >>= 52;
VERIFY_BITS(c, 115);
VERIFY_BITS(d, 62);
/* [d 0 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */
r[1] = c & M; c >>= 52;
VERIFY_BITS(r[1], 52);
VERIFY_BITS(c, 63);
/* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */
c += (__int128)a0 * b[2]
+ (__int128)a1 * b[1]
+ (__int128)a2 * b[0];
VERIFY_BITS(c, 114);
/* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 p2 p1 p0] */
d += (__int128)a3 * b[4]
+ (__int128)a4 * b[3];
VERIFY_BITS(d, 114);
/* [d 0 0 t4 t3 c t1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
c += (d & M) * R; d >>= 52;
VERIFY_BITS(c, 115);
VERIFY_BITS(d, 62);
/* [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
/* [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
r[2] = c & M; c >>= 52;
VERIFY_BITS(r[2], 52);