mirror of
https://github.com/status-im/secp256k1.git
synced 2025-02-22 10:48:21 +00:00
Make secp256k1_i128_check_pow2 support -(2^n)
This commit is contained in:
parent
cbd2555934
commit
5fffb2c7af
@ -80,10 +80,10 @@ static SECP256K1_INLINE void secp256k1_i128_from_i64(secp256k1_int128 *r, int64_
|
||||
/* Compare two 128-bit values for equality. */
|
||||
static SECP256K1_INLINE int secp256k1_i128_eq_var(const secp256k1_int128 *a, const secp256k1_int128 *b);
|
||||
|
||||
/* Tests if r is equal to 2^n.
|
||||
/* Tests if r is equal to sign*2^n (sign must be 1 or -1).
|
||||
* n must be strictly less than 127.
|
||||
*/
|
||||
static SECP256K1_INLINE int secp256k1_i128_check_pow2(const secp256k1_int128 *r, unsigned int n);
|
||||
static SECP256K1_INLINE int secp256k1_i128_check_pow2(const secp256k1_int128 *r, unsigned int n, int sign);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -84,9 +84,10 @@ static SECP256K1_INLINE int secp256k1_i128_eq_var(const secp256k1_int128 *a, con
|
||||
return *a == *b;
|
||||
}
|
||||
|
||||
static SECP256K1_INLINE int secp256k1_i128_check_pow2(const secp256k1_int128 *r, unsigned int n) {
|
||||
static SECP256K1_INLINE int secp256k1_i128_check_pow2(const secp256k1_int128 *r, unsigned int n, int sign) {
|
||||
VERIFY_CHECK(n < 127);
|
||||
return (*r == (int128_t)1 << n);
|
||||
VERIFY_CHECK(sign == 1 || sign == -1);
|
||||
return (*r == (int128_t)((uint128_t)sign << n));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -189,10 +189,11 @@ static SECP256K1_INLINE int secp256k1_i128_eq_var(const secp256k1_int128 *a, con
|
||||
return a->hi == b->hi && a->lo == b->lo;
|
||||
}
|
||||
|
||||
static SECP256K1_INLINE int secp256k1_i128_check_pow2(const secp256k1_int128 *r, unsigned int n) {
|
||||
VERIFY_CHECK(n < 127);
|
||||
return n >= 64 ? r->hi == (uint64_t)1 << (n - 64) && r->lo == 0
|
||||
: r->hi == 0 && r->lo == (uint64_t)1 << n;
|
||||
static SECP256K1_INLINE int secp256k1_i128_check_pow2(const secp256k1_int128 *r, unsigned int n, int sign) {
|
||||
VERIFY_CHECK(n < 127);
|
||||
VERIFY_CHECK(sign == 1 || sign == -1);
|
||||
return n >= 64 ? r->hi == (uint64_t)sign << (n - 64) && r->lo == 0
|
||||
: r->hi == (uint64_t)((sign - 1) >> 1) && r->lo == (uint64_t)sign << n;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -75,7 +75,7 @@ static int secp256k1_modinv64_mul_cmp_62(const secp256k1_modinv64_signed62 *a, i
|
||||
static int secp256k1_modinv64_det_check_pow2(const secp256k1_modinv64_trans2x2 *t, unsigned int n) {
|
||||
secp256k1_int128 a;
|
||||
secp256k1_i128_det(&a, t->u, t->v, t->q, t->r);
|
||||
return secp256k1_i128_check_pow2(&a, n);
|
||||
return secp256k1_i128_check_pow2(&a, n, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
38
src/tests.c
38
src/tests.c
@ -2022,30 +2022,56 @@ static void run_int128_test_case(void) {
|
||||
}
|
||||
CHECK(secp256k1_i128_eq_var(&swa, &swz) == expect);
|
||||
}
|
||||
/* test secp256k1_i128_check_pow2 */
|
||||
/* test secp256k1_i128_check_pow2 (sign == 1) */
|
||||
{
|
||||
int expect = (uc & 1);
|
||||
int pos = ub % 127;
|
||||
if (expect) {
|
||||
/* If expect==1, set swz to exactly (2 << pos). */
|
||||
/* If expect==1, set swz to exactly 2^pos. */
|
||||
uint64_t hi = 0;
|
||||
uint64_t lo = 0;
|
||||
if (pos & 64) {
|
||||
if (pos >= 64) {
|
||||
hi = (((uint64_t)1) << (pos & 63));
|
||||
} else {
|
||||
lo = (((uint64_t)1) << (pos & 63));
|
||||
}
|
||||
secp256k1_i128_load(&swz, hi, lo);
|
||||
} else {
|
||||
/* If expect==0, set swz = swa, but update expect=1 if swa happens to equal (2 << pos). */
|
||||
if (pos & 64) {
|
||||
/* If expect==0, set swz = swa, but update expect=1 if swa happens to equal 2^pos. */
|
||||
if (pos >= 64) {
|
||||
if ((v[1] == (((uint64_t)1) << (pos & 63))) && v[0] == 0) expect = 1;
|
||||
} else {
|
||||
if ((v[0] == (((uint64_t)1) << (pos & 63))) && v[1] == 0) expect = 1;
|
||||
}
|
||||
swz = swa;
|
||||
}
|
||||
CHECK(secp256k1_i128_check_pow2(&swz, pos) == expect);
|
||||
CHECK(secp256k1_i128_check_pow2(&swz, pos, 1) == expect);
|
||||
}
|
||||
/* test secp256k1_i128_check_pow2 (sign == -1) */
|
||||
{
|
||||
int expect = (uc & 1);
|
||||
int pos = ub % 127;
|
||||
if (expect) {
|
||||
/* If expect==1, set swz to exactly -2^pos. */
|
||||
uint64_t hi = ~(uint64_t)0;
|
||||
uint64_t lo = ~(uint64_t)0;
|
||||
if (pos >= 64) {
|
||||
hi <<= (pos & 63);
|
||||
lo = 0;
|
||||
} else {
|
||||
lo <<= (pos & 63);
|
||||
}
|
||||
secp256k1_i128_load(&swz, hi, lo);
|
||||
} else {
|
||||
/* If expect==0, set swz = swa, but update expect=1 if swa happens to equal -2^pos. */
|
||||
if (pos >= 64) {
|
||||
if ((v[1] == ((~(uint64_t)0) << (pos & 63))) && v[0] == 0) expect = 1;
|
||||
} else {
|
||||
if ((v[0] == ((~(uint64_t)0) << (pos & 63))) && v[1] == ~(uint64_t)0) expect = 1;
|
||||
}
|
||||
swz = swa;
|
||||
}
|
||||
CHECK(secp256k1_i128_check_pow2(&swz, pos, -1) == expect);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user