Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signed-digit multi-comb ecmult_gen algorithm #1058

Merged
merged 17 commits into from
Apr 22, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Rename scalar_get_bits -> scalar_get_bits_limb32; return uint32_t
sipa committed Apr 19, 2024
commit 5005abee60ad03d2967c9aadf4e25d208c90d98a
4 changes: 2 additions & 2 deletions src/ecmult_const_impl.h
Original file line number Diff line number Diff line change
@@ -214,8 +214,8 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons
#ifdef VERIFY
/* Verify that v1 and v2 are in range [0, 2^129-1]. */
for (i = 129; i < 256; ++i) {
VERIFY_CHECK(secp256k1_scalar_get_bits(&v1, i, 1) == 0);
VERIFY_CHECK(secp256k1_scalar_get_bits(&v2, i, 1) == 0);
VERIFY_CHECK(secp256k1_scalar_get_bits_limb32(&v1, i, 1) == 0);
VERIFY_CHECK(secp256k1_scalar_get_bits_limb32(&v2, i, 1) == 0);
}
#endif

2 changes: 1 addition & 1 deletion src/ecmult_gen_compute_table_impl.h
Original file line number Diff line number Diff line change
@@ -34,7 +34,7 @@ static void secp256k1_ecmult_gen_compute_table(secp256k1_ge_storage* table, cons
for (i = 255; i >= 0; --i) {
/* Use a very simple multiplication ladder to avoid dependency on ecmult. */
secp256k1_gej_double_var(&u, &u, NULL);
if (secp256k1_scalar_get_bits(&half, i, 1)) {
if (secp256k1_scalar_get_bits_limb32(&half, i, 1)) {
secp256k1_gej_add_ge_var(&u, &u, gen, NULL);
}
}
2 changes: 1 addition & 1 deletion src/ecmult_gen_impl.h
Original file line number Diff line number Diff line change
@@ -189,7 +189,7 @@ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp25
* bits[tooth] = d[(block*COMB_TEETH + tooth)*COMB_SPACING + comb_off]. */
uint32_t bits = 0, sign, abs, index, tooth;
for (tooth = 0; tooth < COMB_TEETH && bit_pos < 256; ++tooth) {
uint32_t bit = secp256k1_scalar_get_bits(&d, bit_pos, 1);
uint32_t bit = secp256k1_scalar_get_bits_limb32(&d, bit_pos, 1);
bits |= bit << tooth;
bit_pos += COMB_SPACING;
}
6 changes: 3 additions & 3 deletions src/ecmult_impl.h
Original file line number Diff line number Diff line change
@@ -174,15 +174,15 @@ static int secp256k1_ecmult_wnaf(int *wnaf, int len, const secp256k1_scalar *a,
memset(wnaf, 0, len * sizeof(wnaf[0]));

s = *a;
if (secp256k1_scalar_get_bits(&s, 255, 1)) {
if (secp256k1_scalar_get_bits_limb32(&s, 255, 1)) {
secp256k1_scalar_negate(&s, &s);
sign = -1;
}

while (bit < len) {
int now;
int word;
if (secp256k1_scalar_get_bits(&s, bit, 1) == (unsigned int)carry) {
if (secp256k1_scalar_get_bits_limb32(&s, bit, 1) == (unsigned int)carry) {
bit++;
continue;
}
@@ -209,7 +209,7 @@ static int secp256k1_ecmult_wnaf(int *wnaf, int len, const secp256k1_scalar *a,
VERIFY_CHECK(carry == 0);

while (verify_bit < 256) {
VERIFY_CHECK(secp256k1_scalar_get_bits(&s, verify_bit, 1) == 0);
VERIFY_CHECK(secp256k1_scalar_get_bits_limb32(&s, verify_bit, 1) == 0);
verify_bit++;
}
}
4 changes: 2 additions & 2 deletions src/scalar.h
Original file line number Diff line number Diff line change
@@ -23,10 +23,10 @@
static void secp256k1_scalar_clear(secp256k1_scalar *r);

/** Access bits from a scalar. All requested bits must belong to the same 32-bit limb. */
static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count);
static uint32_t secp256k1_scalar_get_bits_limb32(const secp256k1_scalar *a, unsigned int offset, unsigned int count);

/** Access bits from a scalar. Not constant time in offset and count. */
static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count);
static uint32_t secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count);

/** Set a scalar from a big endian byte array. The scalar will be reduced modulo group order `n`.
* In: bin: pointer to a 32-byte array.
6 changes: 3 additions & 3 deletions src/scalar_4x64_impl.h
Original file line number Diff line number Diff line change
@@ -45,20 +45,20 @@ SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsig
SECP256K1_SCALAR_VERIFY(r);
}

SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_limb32(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
SECP256K1_SCALAR_VERIFY(a);
VERIFY_CHECK((offset + count - 1) >> 6 == offset >> 6);

return (a->d[offset >> 6] >> (offset & 0x3F)) & ((((uint64_t)1) << count) - 1);
}

SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
SECP256K1_SCALAR_VERIFY(a);
VERIFY_CHECK(count < 32);
VERIFY_CHECK(offset + count <= 256);

if ((offset + count - 1) >> 6 == offset >> 6) {
return secp256k1_scalar_get_bits(a, offset, count);
return secp256k1_scalar_get_bits_limb32(a, offset, count);
} else {
VERIFY_CHECK((offset >> 6) + 1 < 4);
return ((a->d[offset >> 6] >> (offset & 0x3F)) | (a->d[(offset >> 6) + 1] << (64 - (offset & 0x3F)))) & ((((uint64_t)1) << count) - 1);
6 changes: 3 additions & 3 deletions src/scalar_8x32_impl.h
Original file line number Diff line number Diff line change
@@ -62,20 +62,20 @@ SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsig
SECP256K1_SCALAR_VERIFY(r);
}

SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_limb32(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
SECP256K1_SCALAR_VERIFY(a);
VERIFY_CHECK((offset + count - 1) >> 5 == offset >> 5);

return (a->d[offset >> 5] >> (offset & 0x1F)) & ((1 << count) - 1);
}

SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
SECP256K1_SCALAR_VERIFY(a);
VERIFY_CHECK(count < 32);
VERIFY_CHECK(offset + count <= 256);

if ((offset + count - 1) >> 5 == offset >> 5) {
return secp256k1_scalar_get_bits(a, offset, count);
return secp256k1_scalar_get_bits_limb32(a, offset, count);
} else {
VERIFY_CHECK((offset >> 5) + 1 < 8);
return ((a->d[offset >> 5] >> (offset & 0x1F)) | (a->d[(offset >> 5) + 1] << (32 - (offset & 0x1F)))) & ((((uint32_t)1) << count) - 1);
6 changes: 3 additions & 3 deletions src/scalar_low_impl.h
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsig
SECP256K1_SCALAR_VERIFY(r);
}

SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_limb32(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
SECP256K1_SCALAR_VERIFY(a);

if (offset < 32)
@@ -36,10 +36,10 @@ SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_s
return 0;
}

SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
SECP256K1_SCALAR_VERIFY(a);

return secp256k1_scalar_get_bits(a, offset, count);
return secp256k1_scalar_get_bits_limb32(a, offset, count);
}

SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { return *a >= EXHAUSTIVE_TEST_ORDER; }
2 changes: 1 addition & 1 deletion src/tests.c
Original file line number Diff line number Diff line change
@@ -2149,7 +2149,7 @@ static void scalar_test(void) {
for (i = 0; i < 256; i += 4) {
secp256k1_scalar t;
int j;
secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits(&s, 256 - 4 - i, 4));
secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits_limb32(&s, 256 - 4 - i, 4));
for (j = 0; j < 4; j++) {
secp256k1_scalar_add(&n, &n, &n);
}