Add constant-time multiply secp256k1_ecmult_const for ECDH
Designed with clear separation of the wNAF conversion, precomputation and exponentiation (since the precomp at least we will probably want to separate in the API for users who reuse points a lot. Future work: - actually separate precomp in the API - do multiexp rather than single exponentiation
This commit is contained in:
@@ -234,6 +234,31 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) {
|
||||
return yes;
|
||||
}
|
||||
|
||||
static int secp256k1_scalar_cond_negate(secp256k1_scalar_t *r, int flag) {
|
||||
/* If we are flag = 0, mask = 00...00 and this is a no-op;
|
||||
* if we are flag = 1, mask = 11...11 and this is identical to secp256k1_scalar_negate */
|
||||
uint32_t mask = !flag - 1;
|
||||
uint32_t nonzero = 0xFFFFFFFFUL * (secp256k1_scalar_is_zero(r) == 0);
|
||||
uint64_t t = (uint64_t)(r->d[0] ^ mask) + ((SECP256K1_N_0 + 1) & mask);
|
||||
r->d[0] = t & nonzero; t >>= 32;
|
||||
t += (uint64_t)(r->d[1] ^ mask) + (SECP256K1_N_1 & mask);
|
||||
r->d[1] = t & nonzero; t >>= 32;
|
||||
t += (uint64_t)(r->d[2] ^ mask) + (SECP256K1_N_2 & mask);
|
||||
r->d[2] = t & nonzero; t >>= 32;
|
||||
t += (uint64_t)(r->d[3] ^ mask) + (SECP256K1_N_3 & mask);
|
||||
r->d[3] = t & nonzero; t >>= 32;
|
||||
t += (uint64_t)(r->d[4] ^ mask) + (SECP256K1_N_4 & mask);
|
||||
r->d[4] = t & nonzero; t >>= 32;
|
||||
t += (uint64_t)(r->d[5] ^ mask) + (SECP256K1_N_5 & mask);
|
||||
r->d[5] = t & nonzero; t >>= 32;
|
||||
t += (uint64_t)(r->d[6] ^ mask) + (SECP256K1_N_6 & mask);
|
||||
r->d[6] = t & nonzero; t >>= 32;
|
||||
t += (uint64_t)(r->d[7] ^ mask) + (SECP256K1_N_7 & mask);
|
||||
r->d[7] = t & nonzero;
|
||||
return 2 * (mask == 0) - 1;
|
||||
}
|
||||
|
||||
|
||||
/* Inspired by the macros in OpenSSL's crypto/bn/asm/x86_64-gcc.c. */
|
||||
|
||||
/** Add a*b to the number defined by (c0,c1,c2). c2 must never overflow. */
|
||||
@@ -624,6 +649,22 @@ static void secp256k1_scalar_mul(secp256k1_scalar_t *r, const secp256k1_scalar_t
|
||||
secp256k1_scalar_reduce_512(r, l);
|
||||
}
|
||||
|
||||
static int secp256k1_scalar_shr_int(secp256k1_scalar_t *r, int n) {
|
||||
int ret;
|
||||
VERIFY_CHECK(n > 0);
|
||||
VERIFY_CHECK(n < 16);
|
||||
ret = r->d[0] & ((1 << n) - 1);
|
||||
r->d[0] = (r->d[0] >> n) + (r->d[1] << (32 - n));
|
||||
r->d[1] = (r->d[1] >> n) + (r->d[2] << (32 - n));
|
||||
r->d[2] = (r->d[2] >> n) + (r->d[3] << (32 - n));
|
||||
r->d[3] = (r->d[3] >> n) + (r->d[4] << (32 - n));
|
||||
r->d[4] = (r->d[4] >> n) + (r->d[5] << (32 - n));
|
||||
r->d[5] = (r->d[5] >> n) + (r->d[6] << (32 - n));
|
||||
r->d[6] = (r->d[6] >> n) + (r->d[7] << (32 - n));
|
||||
r->d[7] = (r->d[7] >> n);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void secp256k1_scalar_sqr(secp256k1_scalar_t *r, const secp256k1_scalar_t *a) {
|
||||
uint32_t l[16];
|
||||
secp256k1_scalar_sqr_512(l, a);
|
||||
|
||||
Reference in New Issue
Block a user