Get rid of precomputed H tables

This commit is contained in:
Pieter Wuille 2016-07-01 14:38:00 +02:00
parent 8de58308d8
commit dc05520096
13 changed files with 144 additions and 352 deletions

View File

@ -251,7 +251,7 @@ void bench_wnaf_const(void* arg) {
bench_inv_t *data = (bench_inv_t*)arg; bench_inv_t *data = (bench_inv_t*)arg;
for (i = 0; i < 20000; i++) { for (i = 0; i < 20000; i++) {
secp256k1_wnaf_const(data->wnaf, data->scalar_x, WINDOW_A); secp256k1_wnaf_const(data->wnaf, data->scalar_x, WINDOW_A, 256, 1);
secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
} }
} }

View File

@ -53,8 +53,6 @@ int main(void) {
bench_rangeproof_t data; bench_rangeproof_t data;
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
secp256k1_pedersen_context_initialize(data.ctx);
secp256k1_rangeproof_context_initialize(data.ctx);
data.min_bits = 32; data.min_bits = 32;

View File

@ -10,6 +10,6 @@
#include "scalar.h" #include "scalar.h"
#include "group.h" #include "group.h"
static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *q); static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *q, int bits);
#endif #endif

View File

@ -12,12 +12,7 @@
#include "ecmult_const.h" #include "ecmult_const.h"
#include "ecmult_impl.h" #include "ecmult_impl.h"
#ifdef USE_ENDOMORPHISM #define WNAF_SIZE(bits, w) (((bits) + (w) - 1) / (w))
#define WNAF_BITS 128
#else
#define WNAF_BITS 256
#endif
#define WNAF_SIZE(w) ((WNAF_BITS + (w) - 1) / (w))
/* This is like `ECMULT_TABLE_GET_GE` but is constant time */ /* This is like `ECMULT_TABLE_GET_GE` but is constant time */
#define ECMULT_CONST_TABLE_GET_GE(r,pre,n,w) do { \ #define ECMULT_CONST_TABLE_GET_GE(r,pre,n,w) do { \
@ -54,7 +49,7 @@
* *
* Numbers reference steps of `Algorithm SPA-resistant Width-w NAF with Odd Scalar` on pp. 335 * Numbers reference steps of `Algorithm SPA-resistant Width-w NAF with Odd Scalar` on pp. 335
*/ */
static int secp256k1_wnaf_const(int *wnaf, secp256k1_scalar s, int w) { static int secp256k1_wnaf_const(int *wnaf, secp256k1_scalar s, int w, int size, int maybe_negative) {
int global_sign; int global_sign;
int skew = 0; int skew = 0;
int word = 0; int word = 0;
@ -75,8 +70,9 @@ static int secp256k1_wnaf_const(int *wnaf, secp256k1_scalar s, int w) {
* or 2 (for odd) to the number we are encoding, returning a skew value indicating * or 2 (for odd) to the number we are encoding, returning a skew value indicating
* this, and having the caller compensate after doing the multiplication. */ * this, and having the caller compensate after doing the multiplication. */
if (maybe_negative) {
/* Negative numbers will be negated to keep their bit representation below the maximum width */ /* Negative numbers will be negated to keep their bit representation below the maximum width */
flip = secp256k1_scalar_is_high(&s); flip = maybe_negative ? secp256k1_scalar_is_high(&s) : 0;
/* We add 1 to even numbers, 2 to odd ones, noting that negation flips parity */ /* We add 1 to even numbers, 2 to odd ones, noting that negation flips parity */
bit = flip ^ !secp256k1_scalar_is_even(&s); bit = flip ^ !secp256k1_scalar_is_even(&s);
/* We check for negative one, since adding 2 to it will cause an overflow */ /* We check for negative one, since adding 2 to it will cause an overflow */
@ -91,10 +87,17 @@ static int secp256k1_wnaf_const(int *wnaf, secp256k1_scalar s, int w) {
global_sign = secp256k1_scalar_cond_negate(&s, flip); global_sign = secp256k1_scalar_cond_negate(&s, flip);
global_sign *= not_neg_one * 2 - 1; global_sign *= not_neg_one * 2 - 1;
skew = 1 << bit; skew = 1 << bit;
} else {
VERIFY_CHECK(!secp256k1_scalar_is_high(&s));
bit = !secp256k1_scalar_is_even(&s);
skew = 1 << bit;
secp256k1_scalar_cadd_bit(&s, bit, 1);
global_sign = 1;
}
/* 4 */ /* 4 */
u_last = secp256k1_scalar_shr_int(&s, w); u_last = secp256k1_scalar_shr_int(&s, w);
while (word * w < WNAF_BITS) { do {
int sign; int sign;
int even; int even;
@ -110,41 +113,50 @@ static int secp256k1_wnaf_const(int *wnaf, secp256k1_scalar s, int w) {
wnaf[word++] = u_last * global_sign; wnaf[word++] = u_last * global_sign;
u_last = u; u_last = u;
} } while(word * w < size);
wnaf[word] = u * global_sign; wnaf[word] = u * global_sign;
VERIFY_CHECK(secp256k1_scalar_is_zero(&s)); VERIFY_CHECK(secp256k1_scalar_is_zero(&s));
VERIFY_CHECK(word == WNAF_SIZE(w)); VERIFY_CHECK(word == WNAF_SIZE(size, w));
return skew; return skew;
} }
static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *scalar, int size) {
static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *scalar) {
secp256k1_ge pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; secp256k1_ge pre_a[ECMULT_TABLE_SIZE(WINDOW_A)];
secp256k1_ge tmpa; secp256k1_ge tmpa;
secp256k1_fe Z; secp256k1_fe Z;
int skew_1; int skew_1;
int wnaf_1[1 + WNAF_SIZE(WINDOW_A - 1)];
#ifdef USE_ENDOMORPHISM #ifdef USE_ENDOMORPHISM
secp256k1_ge pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; secp256k1_ge pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)];
int wnaf_lam[1 + WNAF_SIZE(WINDOW_A - 1)]; int wnaf_1[1 + WNAF_SIZE(128, WINDOW_A - 1)];
int wnaf_lam[1 + WNAF_SIZE(128, WINDOW_A - 1)];
int skew_lam; int skew_lam;
secp256k1_scalar q_1, q_lam; secp256k1_scalar q_1, q_lam;
#else
int wnaf_1[1 + WNAF_SIZE(256, WINDOW_A - 1)];
#endif #endif
int i; int i;
secp256k1_scalar sc = *scalar; secp256k1_scalar sc = *scalar;
/* build wnaf representation for q. */ /* build wnaf representation for q. */
int rsize = size;
#ifdef USE_ENDOMORPHISM #ifdef USE_ENDOMORPHISM
if (size > 128) {
rsize = 128;
/* split q into q_1 and q_lam (where q = q_1 + q_lam*lambda, and q_1 and q_lam are ~128 bit) */ /* split q into q_1 and q_lam (where q = q_1 + q_lam*lambda, and q_1 and q_lam are ~128 bit) */
secp256k1_scalar_split_lambda(&q_1, &q_lam, &sc); secp256k1_scalar_split_lambda(&q_1, &q_lam, &sc);
skew_1 = secp256k1_wnaf_const(wnaf_1, q_1, WINDOW_A - 1); skew_1 = secp256k1_wnaf_const(wnaf_1, q_1, WINDOW_A - 1, 128, 1);
skew_lam = secp256k1_wnaf_const(wnaf_lam, q_lam, WINDOW_A - 1); skew_lam = secp256k1_wnaf_const(wnaf_lam, q_lam, WINDOW_A - 1, 128, 1);
#else } else
skew_1 = secp256k1_wnaf_const(wnaf_1, sc, WINDOW_A - 1);
#endif #endif
{
skew_1 = secp256k1_wnaf_const(wnaf_1, sc, WINDOW_A - 1, size, size == 256);
#ifdef USE_ENDOMORPHISM
skew_lam = 0;
#endif
}
/* Calculate odd multiples of a. /* Calculate odd multiples of a.
* All multiples are brought to the same Z 'denominator', which is stored * All multiples are brought to the same Z 'denominator', which is stored
@ -158,26 +170,30 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons
secp256k1_fe_normalize_weak(&pre_a[i].y); secp256k1_fe_normalize_weak(&pre_a[i].y);
} }
#ifdef USE_ENDOMORPHISM #ifdef USE_ENDOMORPHISM
if (size > 128) {
for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) {
secp256k1_ge_mul_lambda(&pre_a_lam[i], &pre_a[i]); secp256k1_ge_mul_lambda(&pre_a_lam[i], &pre_a[i]);
} }
}
#endif #endif
/* first loop iteration (separated out so we can directly set r, rather /* first loop iteration (separated out so we can directly set r, rather
* than having it start at infinity, get doubled several times, then have * than having it start at infinity, get doubled several times, then have
* its new value added to it) */ * its new value added to it) */
i = wnaf_1[WNAF_SIZE(WINDOW_A - 1)]; i = wnaf_1[WNAF_SIZE(rsize, WINDOW_A - 1)];
VERIFY_CHECK(i != 0); VERIFY_CHECK(i != 0);
ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, i, WINDOW_A); ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, i, WINDOW_A);
secp256k1_gej_set_ge(r, &tmpa); secp256k1_gej_set_ge(r, &tmpa);
#ifdef USE_ENDOMORPHISM #ifdef USE_ENDOMORPHISM
i = wnaf_lam[WNAF_SIZE(WINDOW_A - 1)]; if (size > 128) {
i = wnaf_lam[WNAF_SIZE(rsize, WINDOW_A - 1)];
VERIFY_CHECK(i != 0); VERIFY_CHECK(i != 0);
ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, i, WINDOW_A); ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, i, WINDOW_A);
secp256k1_gej_add_ge(r, r, &tmpa); secp256k1_gej_add_ge(r, r, &tmpa);
}
#endif #endif
/* remaining loop iterations */ /* remaining loop iterations */
for (i = WNAF_SIZE(WINDOW_A - 1) - 1; i >= 0; i--) { for (i = WNAF_SIZE(rsize, WINDOW_A - 1) - 1; i >= 0; i--) {
int n; int n;
int j; int j;
for (j = 0; j < WINDOW_A - 1; ++j) { for (j = 0; j < WINDOW_A - 1; ++j) {
@ -189,10 +205,12 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons
VERIFY_CHECK(n != 0); VERIFY_CHECK(n != 0);
secp256k1_gej_add_ge(r, r, &tmpa); secp256k1_gej_add_ge(r, r, &tmpa);
#ifdef USE_ENDOMORPHISM #ifdef USE_ENDOMORPHISM
if (size > 128) {
n = wnaf_lam[i]; n = wnaf_lam[i];
ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, n, WINDOW_A); ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, n, WINDOW_A);
VERIFY_CHECK(n != 0); VERIFY_CHECK(n != 0);
secp256k1_gej_add_ge(r, r, &tmpa); secp256k1_gej_add_ge(r, r, &tmpa);
}
#endif #endif
} }
@ -212,14 +230,18 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons
secp256k1_ge_set_gej(&correction, &tmpj); secp256k1_ge_set_gej(&correction, &tmpj);
secp256k1_ge_to_storage(&correction_1_stor, a); secp256k1_ge_to_storage(&correction_1_stor, a);
#ifdef USE_ENDOMORPHISM #ifdef USE_ENDOMORPHISM
if (size > 128) {
secp256k1_ge_to_storage(&correction_lam_stor, a); secp256k1_ge_to_storage(&correction_lam_stor, a);
}
#endif #endif
secp256k1_ge_to_storage(&a2_stor, &correction); secp256k1_ge_to_storage(&a2_stor, &correction);
/* For odd numbers this is 2a (so replace it), for even ones a (so no-op) */ /* For odd numbers this is 2a (so replace it), for even ones a (so no-op) */
secp256k1_ge_storage_cmov(&correction_1_stor, &a2_stor, skew_1 == 2); secp256k1_ge_storage_cmov(&correction_1_stor, &a2_stor, skew_1 == 2);
#ifdef USE_ENDOMORPHISM #ifdef USE_ENDOMORPHISM
if (size > 128) {
secp256k1_ge_storage_cmov(&correction_lam_stor, &a2_stor, skew_lam == 2); secp256k1_ge_storage_cmov(&correction_lam_stor, &a2_stor, skew_lam == 2);
}
#endif #endif
/* Apply the correction */ /* Apply the correction */
@ -228,10 +250,12 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons
secp256k1_gej_add_ge(r, r, &correction); secp256k1_gej_add_ge(r, r, &correction);
#ifdef USE_ENDOMORPHISM #ifdef USE_ENDOMORPHISM
if (size > 128) {
secp256k1_ge_from_storage(&correction, &correction_lam_stor); secp256k1_ge_from_storage(&correction, &correction_lam_stor);
secp256k1_ge_neg(&correction, &correction); secp256k1_ge_neg(&correction, &correction);
secp256k1_ge_mul_lambda(&correction, &correction); secp256k1_ge_mul_lambda(&correction, &correction);
secp256k1_gej_add_ge(r, r, &correction); secp256k1_gej_add_ge(r, r, &correction);
}
#endif #endif
} }
} }

View File

@ -30,7 +30,7 @@ int secp256k1_ecdh(const secp256k1_context* ctx, unsigned char *result, const se
unsigned char y[1]; unsigned char y[1];
secp256k1_sha256_t sha; secp256k1_sha256_t sha;
secp256k1_ecmult_const(&res, &pt, &s); secp256k1_ecmult_const(&res, &pt, &s, 256);
secp256k1_ge_set_gej(&pt, &res); secp256k1_ge_set_gej(&pt, &res);
/* Compute a hash of the point in compressed form /* Compute a hash of the point in compressed form
* Note we cannot use secp256k1_eckey_pubkey_serialize here since it does not * Note we cannot use secp256k1_eckey_pubkey_serialize here since it does not

View File

@ -11,10 +11,6 @@
#include "modules/rangeproof/borromean_impl.h" #include "modules/rangeproof/borromean_impl.h"
#include "modules/rangeproof/rangeproof_impl.h" #include "modules/rangeproof/rangeproof_impl.h"
void secp256k1_pedersen_context_initialize(secp256k1_context* ctx) {
secp256k1_pedersen_context_build(&ctx->pedersen_ctx, &ctx->error_callback);
}
/* Generates a pedersen commitment: *commit = blind * G + value * G2. The commitment is 33 bytes, the blinding factor is 32 bytes.*/ /* Generates a pedersen commitment: *commit = blind * G + value * G2. The commitment is 33 bytes, the blinding factor is 32 bytes.*/
int secp256k1_pedersen_commit(const secp256k1_context* ctx, unsigned char *commit, unsigned char *blind, uint64_t value) { int secp256k1_pedersen_commit(const secp256k1_context* ctx, unsigned char *commit, unsigned char *blind, uint64_t value) {
secp256k1_gej rj; secp256k1_gej rj;
@ -25,12 +21,11 @@ int secp256k1_pedersen_commit(const secp256k1_context* ctx, unsigned char *commi
int ret = 0; int ret = 0;
ARG_CHECK(ctx != NULL); ARG_CHECK(ctx != NULL);
ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
ARG_CHECK(secp256k1_pedersen_context_is_built(&ctx->pedersen_ctx));
ARG_CHECK(commit != NULL); ARG_CHECK(commit != NULL);
ARG_CHECK(blind != NULL); ARG_CHECK(blind != NULL);
secp256k1_scalar_set_b32(&sec, blind, &overflow); secp256k1_scalar_set_b32(&sec, blind, &overflow);
if (!overflow) { if (!overflow) {
secp256k1_pedersen_ecmult(&ctx->ecmult_gen_ctx, &ctx->pedersen_ctx, &rj, &sec, value); secp256k1_pedersen_ecmult(&ctx->ecmult_gen_ctx, &rj, &sec, value);
if (!secp256k1_gej_is_infinity(&rj)) { if (!secp256k1_gej_is_infinity(&rj)) {
secp256k1_ge_set_gej(&r, &rj); secp256k1_ge_set_gej(&r, &rj);
sz = 33; sz = 33;
@ -80,14 +75,13 @@ int secp256k1_pedersen_verify_tally(const secp256k1_context* ctx, const unsigned
ARG_CHECK(ctx != NULL); ARG_CHECK(ctx != NULL);
ARG_CHECK(!pcnt || (commits != NULL)); ARG_CHECK(!pcnt || (commits != NULL));
ARG_CHECK(!ncnt || (ncommits != NULL)); ARG_CHECK(!ncnt || (ncommits != NULL));
ARG_CHECK(secp256k1_pedersen_context_is_built(&ctx->pedersen_ctx));
secp256k1_gej_set_infinity(&accj); secp256k1_gej_set_infinity(&accj);
if (excess) { if (excess) {
uint64_t ex; uint64_t ex;
int neg; int neg;
/* Take the absolute value, and negate the result if the input was negative. */ /* Take the absolute value, and negate the result if the input was negative. */
neg = secp256k1_sign_and_abs64(&ex, excess); neg = secp256k1_sign_and_abs64(&ex, excess);
secp256k1_pedersen_ecmult_small(&ctx->pedersen_ctx, &accj, ex); secp256k1_pedersen_ecmult_small(&accj, ex);
if (neg) { if (neg) {
secp256k1_gej_neg(&accj, &accj); secp256k1_gej_neg(&accj, &accj);
} }
@ -108,10 +102,6 @@ int secp256k1_pedersen_verify_tally(const secp256k1_context* ctx, const unsigned
return secp256k1_gej_is_infinity(&accj); return secp256k1_gej_is_infinity(&accj);
} }
void secp256k1_rangeproof_context_initialize(secp256k1_context* ctx) {
secp256k1_rangeproof_context_build(&ctx->rangeproof_ctx, &ctx->error_callback);
}
int secp256k1_rangeproof_info(const secp256k1_context* ctx, int *exp, int *mantissa, int secp256k1_rangeproof_info(const secp256k1_context* ctx, int *exp, int *mantissa,
uint64_t *min_value, uint64_t *max_value, const unsigned char *proof, int plen) { uint64_t *min_value, uint64_t *max_value, const unsigned char *proof, int plen) {
int offset; int offset;
@ -137,9 +127,7 @@ int secp256k1_rangeproof_rewind(const secp256k1_context* ctx,
ARG_CHECK(max_value != NULL); ARG_CHECK(max_value != NULL);
ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
ARG_CHECK(secp256k1_pedersen_context_is_built(&ctx->pedersen_ctx)); return secp256k1_rangeproof_verify_impl(&ctx->ecmult_ctx, &ctx->ecmult_gen_ctx,
ARG_CHECK(secp256k1_rangeproof_context_is_built(&ctx->rangeproof_ctx));
return secp256k1_rangeproof_verify_impl(&ctx->ecmult_ctx, &ctx->ecmult_gen_ctx, &ctx->pedersen_ctx, &ctx->rangeproof_ctx,
blind_out, value_out, message_out, outlen, nonce, min_value, max_value, commit, proof, plen); blind_out, value_out, message_out, outlen, nonce, min_value, max_value, commit, proof, plen);
} }
@ -151,9 +139,7 @@ int secp256k1_rangeproof_verify(const secp256k1_context* ctx, uint64_t *min_valu
ARG_CHECK(min_value != NULL); ARG_CHECK(min_value != NULL);
ARG_CHECK(max_value != NULL); ARG_CHECK(max_value != NULL);
ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
ARG_CHECK(secp256k1_pedersen_context_is_built(&ctx->pedersen_ctx)); return secp256k1_rangeproof_verify_impl(&ctx->ecmult_ctx, NULL,
ARG_CHECK(secp256k1_rangeproof_context_is_built(&ctx->rangeproof_ctx));
return secp256k1_rangeproof_verify_impl(&ctx->ecmult_ctx, NULL, &ctx->pedersen_ctx, &ctx->rangeproof_ctx,
NULL, NULL, NULL, NULL, NULL, min_value, max_value, commit, proof, plen); NULL, NULL, NULL, NULL, NULL, min_value, max_value, commit, proof, plen);
} }
@ -167,9 +153,7 @@ int secp256k1_rangeproof_sign(const secp256k1_context* ctx, unsigned char *proof
ARG_CHECK(nonce != NULL); ARG_CHECK(nonce != NULL);
ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
ARG_CHECK(secp256k1_pedersen_context_is_built(&ctx->pedersen_ctx)); return secp256k1_rangeproof_sign_impl(&ctx->ecmult_ctx, &ctx->ecmult_gen_ctx,
ARG_CHECK(secp256k1_rangeproof_context_is_built(&ctx->rangeproof_ctx));
return secp256k1_rangeproof_sign_impl(&ctx->ecmult_ctx, &ctx->ecmult_gen_ctx, &ctx->pedersen_ctx, &ctx->rangeproof_ctx,
proof, plen, min_value, commit, blind, nonce, exp, min_bits, value); proof, plen, min_value, commit, blind, nonce, exp, min_bits, value);
} }

View File

@ -12,23 +12,10 @@
#include <stdint.h> #include <stdint.h>
typedef struct {
secp256k1_ge_storage (*prec)[16][16]; /* prec[j][i] = 16^j * i * G + U_i */
} secp256k1_pedersen_context;
static void secp256k1_pedersen_context_init(secp256k1_pedersen_context* ctx);
static void secp256k1_pedersen_context_build(secp256k1_pedersen_context* ctx, const secp256k1_callback* cb);
static void secp256k1_pedersen_context_clone(secp256k1_pedersen_context *dst,
const secp256k1_pedersen_context* src, const secp256k1_callback* cb);
static void secp256k1_pedersen_context_clear(secp256k1_pedersen_context* ctx);
static int secp256k1_pedersen_context_is_built(const secp256k1_pedersen_context* ctx);
/** Multiply a small number with the generator: r = gn*G2 */ /** Multiply a small number with the generator: r = gn*G2 */
static void secp256k1_pedersen_ecmult_small(const secp256k1_pedersen_context *ctx, secp256k1_gej *r, uint64_t gn); static void secp256k1_pedersen_ecmult_small(secp256k1_gej *r, uint64_t gn);
/* sec * G + value * G2. */ /* sec * G + value * G2. */
static void secp256k1_pedersen_ecmult(const secp256k1_ecmult_gen_context *ecmult_gen_ctx, static void secp256k1_pedersen_ecmult(const secp256k1_ecmult_gen_context *ecmult_gen_ctx, secp256k1_gej *rj, const secp256k1_scalar *sec, uint64_t value);
const secp256k1_pedersen_context *pedersen_ctx, secp256k1_gej *rj, const secp256k1_scalar *sec, uint64_t value);
#endif #endif

View File

@ -20,117 +20,32 @@ static const secp256k1_ge secp256k1_ge_const_g2 = SECP256K1_GE_CONST(
0x36dac28aUL, 0xf1766968UL, 0xc30c2313UL, 0xf3a38904UL 0x36dac28aUL, 0xf1766968UL, 0xc30c2313UL, 0xf3a38904UL
); );
static void secp256k1_pedersen_context_init(secp256k1_pedersen_context *ctx) { static void secp256k1_pedersen_scalar_set_u64(secp256k1_scalar *sec, uint64_t value) {
ctx->prec = NULL; unsigned char data[32];
int i;
for (i = 0; i < 24; i++) {
data[i] = 0;
}
for (; i < 32; i++) {
data[i] = value >> 56;
value <<= 8;
}
secp256k1_scalar_set_b32(sec, data, NULL);
memset(data, 0, 32);
} }
static void secp256k1_pedersen_context_build(secp256k1_pedersen_context *ctx, const secp256k1_callback *cb) { static void secp256k1_pedersen_ecmult_small(secp256k1_gej *r, uint64_t gn) {
secp256k1_ge prec[256]; secp256k1_scalar s;
secp256k1_gej gj; secp256k1_pedersen_scalar_set_u64(&s, gn);
secp256k1_gej nums_gej; secp256k1_ecmult_const(r, &secp256k1_ge_const_g2, &s, 64);
int i, j; secp256k1_scalar_clear(&s);
if (ctx->prec != NULL) {
return;
}
ctx->prec = (secp256k1_ge_storage (*)[16][16])checked_malloc(cb, sizeof(*ctx->prec));
/* get the generator */
secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g2);
/* Construct a group element with no known corresponding scalar (nothing up my sleeve). */
{
static const unsigned char nums_b32[33] = "The scalar for this x is unknown";
secp256k1_fe nums_x;
secp256k1_ge nums_ge;
VERIFY_CHECK(secp256k1_fe_set_b32(&nums_x, nums_b32));
VERIFY_CHECK(secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0));
secp256k1_gej_set_ge(&nums_gej, &nums_ge);
/* Add G to make the bits in x uniformly distributed. */
secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, &secp256k1_ge_const_g2, NULL);
}
/* compute prec. */
{
secp256k1_gej precj[256]; /* Jacobian versions of prec. */
secp256k1_gej gbase;
secp256k1_gej numsbase;
gbase = gj; /* 16^j * G */
numsbase = nums_gej; /* 2^j * nums. */
for (j = 0; j < 16; j++) {
/* Set precj[j*16 .. j*16+15] to (numsbase, numsbase + gbase, ..., numsbase + 15*gbase). */
precj[j*16] = numsbase;
for (i = 1; i < 16; i++) {
secp256k1_gej_add_var(&precj[j*16 + i], &precj[j*16 + i - 1], &gbase, NULL);
}
/* Multiply gbase by 16. */
for (i = 0; i < 4; i++) {
secp256k1_gej_double_var(&gbase, &gbase, NULL);
}
/* Multiply numbase by 2. */
secp256k1_gej_double_var(&numsbase, &numsbase, NULL);
if (j == 14) {
/* In the last iteration, numsbase is (1 - 2^j) * nums instead. */
secp256k1_gej_neg(&numsbase, &numsbase);
secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL);
}
}
secp256k1_ge_set_all_gej_var(prec, precj, 256, cb);
}
for (j = 0; j < 16; j++) {
for (i = 0; i < 16; i++) {
secp256k1_ge_to_storage(&(*ctx->prec)[j][i], &prec[j*16 + i]);
}
}
}
static int secp256k1_pedersen_context_is_built(const secp256k1_pedersen_context* ctx) {
return ctx->prec != NULL;
}
static void secp256k1_pedersen_context_clone(secp256k1_pedersen_context *dst,
const secp256k1_pedersen_context *src, const secp256k1_callback *cb) {
if (src->prec == NULL) {
dst->prec = NULL;
} else {
dst->prec = (secp256k1_ge_storage (*)[16][16])checked_malloc(cb, sizeof(*dst->prec));
memcpy(dst->prec, src->prec, sizeof(*dst->prec));
}
}
static void secp256k1_pedersen_context_clear(secp256k1_pedersen_context *ctx) {
free(ctx->prec);
ctx->prec = NULL;
}
/* Version of secp256k1_ecmult_gen using the second generator and working only on numbers in the range [0 .. 2^64). */
static void secp256k1_pedersen_ecmult_small(const secp256k1_pedersen_context *ctx, secp256k1_gej *r, uint64_t gn) {
secp256k1_ge add;
secp256k1_ge_storage adds;
int bits;
int i, j;
memset(&adds, 0, sizeof(adds));
secp256k1_gej_set_infinity(r);
add.infinity = 0;
for (j = 0; j < 16; j++) {
bits = (gn >> (j * 4)) & 15;
for (i = 0; i < 16; i++) {
secp256k1_ge_storage_cmov(&adds, &(*ctx->prec)[j][i], i == bits);
}
secp256k1_ge_from_storage(&add, &adds);
secp256k1_gej_add_ge(r, r, &add);
}
bits = 0;
secp256k1_ge_clear(&add);
} }
/* sec * G + value * G2. */ /* sec * G + value * G2. */
SECP256K1_INLINE static void secp256k1_pedersen_ecmult(const secp256k1_ecmult_gen_context *ecmult_gen_ctx, SECP256K1_INLINE static void secp256k1_pedersen_ecmult(const secp256k1_ecmult_gen_context *ecmult_gen_ctx, secp256k1_gej *rj, const secp256k1_scalar *sec, uint64_t value) {
const secp256k1_pedersen_context *pedersen_ctx, secp256k1_gej *rj, const secp256k1_scalar *sec, uint64_t value) {
secp256k1_gej vj; secp256k1_gej vj;
secp256k1_ecmult_gen(ecmult_gen_ctx, rj, sec); secp256k1_ecmult_gen(ecmult_gen_ctx, rj, sec);
secp256k1_pedersen_ecmult_small(pedersen_ctx, &vj, value); secp256k1_pedersen_ecmult_small(&vj, value);
/* FIXME: constant time. */ /* FIXME: constant time. */
secp256k1_gej_add_var(rj, rj, &vj, NULL); secp256k1_gej_add_var(rj, rj, &vj, NULL);
secp256k1_gej_clear(&vj); secp256k1_gej_clear(&vj);

View File

@ -10,21 +10,8 @@
#include "scalar.h" #include "scalar.h"
#include "group.h" #include "group.h"
typedef struct {
secp256k1_ge_storage (*prec)[1005];
} secp256k1_rangeproof_context;
static void secp256k1_rangeproof_context_init(secp256k1_rangeproof_context* ctx);
static void secp256k1_rangeproof_context_build(secp256k1_rangeproof_context* ctx, const secp256k1_callback* cb);
static void secp256k1_rangeproof_context_clone(secp256k1_rangeproof_context *dst,
const secp256k1_rangeproof_context* src, const secp256k1_callback* cb);
static void secp256k1_rangeproof_context_clear(secp256k1_rangeproof_context* ctx);
static int secp256k1_rangeproof_context_is_built(const secp256k1_rangeproof_context* ctx);
static int secp256k1_rangeproof_verify_impl(const secp256k1_ecmult_context* ecmult_ctx, static int secp256k1_rangeproof_verify_impl(const secp256k1_ecmult_context* ecmult_ctx,
const secp256k1_ecmult_gen_context* ecmult_gen_ctx, const secp256k1_ecmult_gen_context* ecmult_gen_ctx,
const secp256k1_pedersen_context* pedersen_ctx, const secp256k1_rangeproof_context* rangeproof_ctx,
unsigned char *blindout, uint64_t *value_out, unsigned char *message_out, int *outlen, const unsigned char *nonce, unsigned char *blindout, uint64_t *value_out, unsigned char *message_out, int *outlen, const unsigned char *nonce,
uint64_t *min_value, uint64_t *max_value, const unsigned char *commit, const unsigned char *proof, int plen); uint64_t *min_value, uint64_t *max_value, const unsigned char *commit, const unsigned char *proof, int plen);

View File

@ -15,107 +15,9 @@
#include "modules/rangeproof/pedersen.h" #include "modules/rangeproof/pedersen.h"
#include "modules/rangeproof/borromean.h" #include "modules/rangeproof/borromean.h"
static const int secp256k1_rangeproof_offsets[20] = { SECP256K1_INLINE static void secp256k1_rangeproof_pub_expand(secp256k1_gej *pubs,
0, 96, 189, 276, 360, 438, 510, 579, 642,
699, 753, 801, 843, 882, 915, 942, 966, 984,
996, 1005,
};
static void secp256k1_rangeproof_context_init(secp256k1_rangeproof_context *ctx) {
ctx->prec = NULL;
}
static void secp256k1_rangeproof_context_build(secp256k1_rangeproof_context *ctx, const secp256k1_callback* cb) {
secp256k1_ge *prec;
secp256k1_gej *precj;
secp256k1_gej gj;
secp256k1_gej one;
int i, pos;
if (ctx->prec != NULL) {
return;
}
precj = (secp256k1_gej (*))checked_malloc(cb, sizeof(*precj) * 1005);
if (precj == NULL) {
return;
}
prec = (secp256k1_ge (*))checked_malloc(cb, sizeof(*prec) * 1005);
if (prec == NULL) {
free(precj);
return;
}
/* get the generator */
secp256k1_gej_set_ge(&one, &secp256k1_ge_const_g2);
secp256k1_gej_neg(&one, &one);
/* compute prec. */
pos = 0;
for (i = 0; i < 19; i++) {
int pmax;
pmax = secp256k1_rangeproof_offsets[i + 1];
gj = one;
while (pos < pmax) {
precj[pos] = gj;
pos++;
secp256k1_gej_double_var(&precj[pos], &gj, NULL);
pos++;
secp256k1_gej_add_var(&precj[pos], &precj[pos - 1], &gj, NULL);
pos++;
if (pos < pmax - 1) {
secp256k1_gej_double_var(&gj, &precj[pos - 2], NULL);
}
}
if (i < 18) {
secp256k1_gej_double_var(&gj, &one, NULL);
one = gj;
secp256k1_gej_double_var(&gj, &gj, NULL);
secp256k1_gej_double_var(&gj, &gj, NULL);
secp256k1_gej_add_var(&one, &one, &gj, NULL);
}
}
VERIFY_CHECK(pos == 1005);
secp256k1_ge_set_all_gej_var(prec, precj, 1005, cb);
free(precj);
ctx->prec = (secp256k1_ge_storage (*)[1005])checked_malloc(cb, sizeof(*ctx->prec));
if (ctx->prec == NULL) {
free(prec);
return;
}
for (i = 0; i < 1005; i++) {
secp256k1_ge_to_storage(&(*ctx->prec)[i], &prec[i]);
}
free(prec);
}
static int secp256k1_rangeproof_context_is_built(const secp256k1_rangeproof_context* ctx) {
return ctx->prec != NULL;
}
static void secp256k1_rangeproof_context_clone(secp256k1_rangeproof_context *dst,
const secp256k1_rangeproof_context *src, const secp256k1_callback* cb) {
if (src->prec == NULL) {
dst->prec = NULL;
} else {
dst->prec = (secp256k1_ge_storage (*)[1005])checked_malloc(cb, sizeof(*dst->prec));
memcpy(dst->prec, src->prec, sizeof(*dst->prec));
}
}
static void secp256k1_rangeproof_context_clear(secp256k1_rangeproof_context *ctx) {
free(ctx->prec);
ctx->prec = NULL;
}
SECP256K1_INLINE static void secp256k1_rangeproof_pub_expand(const secp256k1_rangeproof_context *ctx, secp256k1_gej *pubs,
int exp, int *rsizes, int rings) { int exp, int *rsizes, int rings) {
secp256k1_ge ge; secp256k1_gej base;
secp256k1_ge_storage *basis;
int i; int i;
int j; int j;
int npub; int npub;
@ -123,12 +25,24 @@ SECP256K1_INLINE static void secp256k1_rangeproof_pub_expand(const secp256k1_ran
if (exp < 0) { if (exp < 0) {
exp = 0; exp = 0;
} }
basis = &(*ctx->prec)[secp256k1_rangeproof_offsets[exp]]; secp256k1_gej_set_ge(&base, &secp256k1_ge_const_g2);
secp256k1_gej_neg(&base, &base);
while (exp--) {
/* Multiplication by 10 */
secp256k1_gej tmp;
secp256k1_gej_double_var(&tmp, &base, NULL);
secp256k1_gej_double_var(&base, &tmp, NULL);
secp256k1_gej_double_var(&base, &base, NULL);
secp256k1_gej_add_var(&base, &base, &tmp, NULL);
}
npub = 0; npub = 0;
for (i = 0; i < rings; i++) { for (i = 0; i < rings; i++) {
for (j = 1; j < rsizes[i]; j++) { for (j = 1; j < rsizes[i]; j++) {
secp256k1_ge_from_storage(&ge, &basis[i * 3 + j - 1]); secp256k1_gej_add_var(&pubs[npub + j], &pubs[npub + j - 1], &base, NULL);
secp256k1_gej_add_ge_var(&pubs[npub + j], &pubs[npub], &ge, NULL); }
if (i < rings - 1) {
secp256k1_gej_double_var(&base, &base, NULL);
secp256k1_gej_double_var(&base, &base, NULL);
} }
npub += rsizes[i]; npub += rsizes[i];
} }
@ -264,8 +178,8 @@ SECP256K1_INLINE static int secp256k1_range_proveparams(uint64_t *v, int *rings,
/* strawman interface, writes proof in proof, a buffer of plen, proves with respect to min_value the range for commit which has the provided blinding factor and value. */ /* strawman interface, writes proof in proof, a buffer of plen, proves with respect to min_value the range for commit which has the provided blinding factor and value. */
SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmult_context* ecmult_ctx, SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmult_context* ecmult_ctx,
const secp256k1_ecmult_gen_context* ecmult_gen_ctx, const secp256k1_pedersen_context* pedersen_ctx, const secp256k1_ecmult_gen_context* ecmult_gen_ctx,
const secp256k1_rangeproof_context* rangeproof_ctx, unsigned char *proof, int *plen, uint64_t min_value, unsigned char *proof, int *plen, uint64_t min_value,
const unsigned char *commit, const unsigned char *blind, const unsigned char *nonce, int exp, int min_bits, uint64_t value){ const unsigned char *commit, const unsigned char *blind, const unsigned char *nonce, int exp, int min_bits, uint64_t value){
secp256k1_gej pubs[128]; /* Candidate digits for our proof, most inferred. */ secp256k1_gej pubs[128]; /* Candidate digits for our proof, most inferred. */
secp256k1_scalar s[128]; /* Signatures in our proof, most forged. */ secp256k1_scalar s[128]; /* Signatures in our proof, most forged. */
@ -357,7 +271,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
npub = 0; npub = 0;
for (i = 0; i < rings; i++) { for (i = 0; i < rings; i++) {
/*OPT: Use the precomputed gen2 basis?*/ /*OPT: Use the precomputed gen2 basis?*/
secp256k1_pedersen_ecmult(ecmult_gen_ctx, pedersen_ctx, &pubs[npub], &sec[i], ((uint64_t)secidx[i] * scale) << (i*2)); secp256k1_pedersen_ecmult(ecmult_gen_ctx, &pubs[npub], &sec[i], ((uint64_t)secidx[i] * scale) << (i*2));
if (secp256k1_gej_is_infinity(&pubs[npub])) { if (secp256k1_gej_is_infinity(&pubs[npub])) {
return 0; return 0;
} }
@ -376,7 +290,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
} }
npub += rsizes[i]; npub += rsizes[i];
} }
secp256k1_rangeproof_pub_expand(rangeproof_ctx, pubs, exp, rsizes, rings); secp256k1_rangeproof_pub_expand(pubs, exp, rsizes, rings);
secp256k1_sha256_finalize(&sha256_m, tmp); secp256k1_sha256_finalize(&sha256_m, tmp);
if (!secp256k1_borromean_sign(ecmult_ctx, ecmult_gen_ctx, &proof[len], s, pubs, k, sec, rsizes, secidx, rings, tmp, 32)) { if (!secp256k1_borromean_sign(ecmult_ctx, ecmult_gen_ctx, &proof[len], s, pubs, k, sec, rsizes, secidx, rings, tmp, 32)) {
return 0; return 0;
@ -596,7 +510,6 @@ SECP256K1_INLINE static int secp256k1_rangeproof_getheader_impl(int *offset, int
/* Verifies range proof (len plen) for 33-byte commit, the min/max values proven are put in the min/max arguments; returns 0 on failure 1 on success.*/ /* Verifies range proof (len plen) for 33-byte commit, the min/max values proven are put in the min/max arguments; returns 0 on failure 1 on success.*/
SECP256K1_INLINE static int secp256k1_rangeproof_verify_impl(const secp256k1_ecmult_context* ecmult_ctx, SECP256K1_INLINE static int secp256k1_rangeproof_verify_impl(const secp256k1_ecmult_context* ecmult_ctx,
const secp256k1_ecmult_gen_context* ecmult_gen_ctx, const secp256k1_ecmult_gen_context* ecmult_gen_ctx,
const secp256k1_pedersen_context* pedersen_ctx, const secp256k1_rangeproof_context* rangeproof_ctx,
unsigned char *blindout, uint64_t *value_out, unsigned char *message_out, int *outlen, const unsigned char *nonce, unsigned char *blindout, uint64_t *value_out, unsigned char *message_out, int *outlen, const unsigned char *nonce,
uint64_t *min_value, uint64_t *max_value, const unsigned char *commit, const unsigned char *proof, int plen) { uint64_t *min_value, uint64_t *max_value, const unsigned char *commit, const unsigned char *proof, int plen) {
secp256k1_gej accj; secp256k1_gej accj;
@ -660,7 +573,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_verify_impl(const secp256k1_ecm
npub = 0; npub = 0;
secp256k1_gej_set_infinity(&accj); secp256k1_gej_set_infinity(&accj);
if (*min_value) { if (*min_value) {
secp256k1_pedersen_ecmult_small(pedersen_ctx, &accj, *min_value); secp256k1_pedersen_ecmult_small(&accj, *min_value);
} }
for(i = 0; i < rings - 1; i++) { for(i = 0; i < rings - 1; i++) {
memcpy(&m[1], &proof[offset], 32); memcpy(&m[1], &proof[offset], 32);
@ -682,7 +595,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_verify_impl(const secp256k1_ecm
if (secp256k1_gej_is_infinity(&pubs[npub])) { if (secp256k1_gej_is_infinity(&pubs[npub])) {
return 0; return 0;
} }
secp256k1_rangeproof_pub_expand(rangeproof_ctx, pubs, exp, rsizes, rings); secp256k1_rangeproof_pub_expand(pubs, exp, rsizes, rings);
npub += rsizes[rings - 1]; npub += rsizes[rings - 1];
e0 = &proof[offset]; e0 = &proof[offset];
offset += 32; offset += 32;
@ -713,7 +626,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_verify_impl(const secp256k1_ecm
/* Unwind apparently successful, see if the commitment can be reconstructed. */ /* Unwind apparently successful, see if the commitment can be reconstructed. */
/* FIXME: should check vv is in the mantissa's range. */ /* FIXME: should check vv is in the mantissa's range. */
vv = (vv * scale) + *min_value; vv = (vv * scale) + *min_value;
secp256k1_pedersen_ecmult(ecmult_gen_ctx, pedersen_ctx, &accj, &blind, vv); secp256k1_pedersen_ecmult(ecmult_gen_ctx, &accj, &blind, vv);
if (secp256k1_gej_is_infinity(&accj)) { if (secp256k1_gej_is_infinity(&accj)) {
return 0; return 0;
} }

View File

@ -267,8 +267,6 @@ void test_rangeproof(void) {
void run_rangeproof_tests(void) { void run_rangeproof_tests(void) {
int i; int i;
secp256k1_pedersen_context_initialize(ctx);
secp256k1_rangeproof_context_initialize(ctx);
for (i = 0; i < 10*count; i++) { for (i = 0; i < 10*count; i++) {
test_pedersen(); test_pedersen();
} }

View File

@ -56,10 +56,6 @@ static const secp256k1_callback default_error_callback = {
struct secp256k1_context_struct { struct secp256k1_context_struct {
secp256k1_ecmult_context ecmult_ctx; secp256k1_ecmult_context ecmult_ctx;
secp256k1_ecmult_gen_context ecmult_gen_ctx; secp256k1_ecmult_gen_context ecmult_gen_ctx;
#ifdef ENABLE_MODULE_RANGEPROOF
secp256k1_pedersen_context pedersen_ctx;
secp256k1_rangeproof_context rangeproof_ctx;
#endif
secp256k1_callback illegal_callback; secp256k1_callback illegal_callback;
secp256k1_callback error_callback; secp256k1_callback error_callback;
}; };
@ -78,10 +74,6 @@ secp256k1_context* secp256k1_context_create(unsigned int flags) {
secp256k1_ecmult_context_init(&ret->ecmult_ctx); secp256k1_ecmult_context_init(&ret->ecmult_ctx);
secp256k1_ecmult_gen_context_init(&ret->ecmult_gen_ctx); secp256k1_ecmult_gen_context_init(&ret->ecmult_gen_ctx);
#ifdef ENABLE_MODULE_RANGEPROOF
secp256k1_pedersen_context_init(&ret->pedersen_ctx);
secp256k1_rangeproof_context_init(&ret->rangeproof_ctx);
#endif
if (flags & SECP256K1_FLAGS_BIT_CONTEXT_SIGN) { if (flags & SECP256K1_FLAGS_BIT_CONTEXT_SIGN) {
secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx, &ret->error_callback); secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx, &ret->error_callback);
@ -99,10 +91,6 @@ secp256k1_context* secp256k1_context_clone(const secp256k1_context* ctx) {
ret->error_callback = ctx->error_callback; ret->error_callback = ctx->error_callback;
secp256k1_ecmult_context_clone(&ret->ecmult_ctx, &ctx->ecmult_ctx, &ctx->error_callback); secp256k1_ecmult_context_clone(&ret->ecmult_ctx, &ctx->ecmult_ctx, &ctx->error_callback);
secp256k1_ecmult_gen_context_clone(&ret->ecmult_gen_ctx, &ctx->ecmult_gen_ctx, &ctx->error_callback); secp256k1_ecmult_gen_context_clone(&ret->ecmult_gen_ctx, &ctx->ecmult_gen_ctx, &ctx->error_callback);
#ifdef ENABLE_MODULE_RANGEPROOF
secp256k1_pedersen_context_clone(&ret->pedersen_ctx, &ctx->pedersen_ctx, &ctx->error_callback);
secp256k1_rangeproof_context_clone(&ret->rangeproof_ctx, &ctx->rangeproof_ctx, &ctx->error_callback);
#endif
return ret; return ret;
} }
@ -110,10 +98,6 @@ void secp256k1_context_destroy(secp256k1_context* ctx) {
if (ctx != NULL) { if (ctx != NULL) {
secp256k1_ecmult_context_clear(&ctx->ecmult_ctx); secp256k1_ecmult_context_clear(&ctx->ecmult_ctx);
secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx); secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx);
#ifdef ENABLE_MODULE_RANGEPROOF
secp256k1_pedersen_context_clear(&ctx->pedersen_ctx);
secp256k1_rangeproof_context_clear(&ctx->rangeproof_ctx);
#endif
free(ctx); free(ctx);
} }

View File

@ -2451,7 +2451,7 @@ void ecmult_const_random_mult(void) {
0xb84e4e1b, 0xfb77e21f, 0x96baae2a, 0x63dec956 0xb84e4e1b, 0xfb77e21f, 0x96baae2a, 0x63dec956
); );
secp256k1_gej b; secp256k1_gej b;
secp256k1_ecmult_const(&b, &a, &xn); secp256k1_ecmult_const(&b, &a, &xn, 256);
CHECK(secp256k1_ge_is_valid_var(&a)); CHECK(secp256k1_ge_is_valid_var(&a));
ge_equals_gej(&expected_b, &b); ge_equals_gej(&expected_b, &b);
@ -2467,12 +2467,12 @@ void ecmult_const_commutativity(void) {
random_scalar_order_test(&a); random_scalar_order_test(&a);
random_scalar_order_test(&b); random_scalar_order_test(&b);
secp256k1_ecmult_const(&res1, &secp256k1_ge_const_g, &a); secp256k1_ecmult_const(&res1, &secp256k1_ge_const_g, &a, 256);
secp256k1_ecmult_const(&res2, &secp256k1_ge_const_g, &b); secp256k1_ecmult_const(&res2, &secp256k1_ge_const_g, &b, 256);
secp256k1_ge_set_gej(&mid1, &res1); secp256k1_ge_set_gej(&mid1, &res1);
secp256k1_ge_set_gej(&mid2, &res2); secp256k1_ge_set_gej(&mid2, &res2);
secp256k1_ecmult_const(&res1, &mid1, &b); secp256k1_ecmult_const(&res1, &mid1, &b, 256);
secp256k1_ecmult_const(&res2, &mid2, &a); secp256k1_ecmult_const(&res2, &mid2, &a, 256);
secp256k1_ge_set_gej(&mid1, &res1); secp256k1_ge_set_gej(&mid1, &res1);
secp256k1_ge_set_gej(&mid2, &res2); secp256k1_ge_set_gej(&mid2, &res2);
ge_equals_ge(&mid1, &mid2); ge_equals_ge(&mid1, &mid2);
@ -2488,13 +2488,13 @@ void ecmult_const_mult_zero_one(void) {
secp256k1_scalar_negate(&negone, &one); secp256k1_scalar_negate(&negone, &one);
random_group_element_test(&point); random_group_element_test(&point);
secp256k1_ecmult_const(&res1, &point, &zero); secp256k1_ecmult_const(&res1, &point, &zero, 3);
secp256k1_ge_set_gej(&res2, &res1); secp256k1_ge_set_gej(&res2, &res1);
CHECK(secp256k1_ge_is_infinity(&res2)); CHECK(secp256k1_ge_is_infinity(&res2));
secp256k1_ecmult_const(&res1, &point, &one); secp256k1_ecmult_const(&res1, &point, &one, 2);
secp256k1_ge_set_gej(&res2, &res1); secp256k1_ge_set_gej(&res2, &res1);
ge_equals_ge(&res2, &point); ge_equals_ge(&res2, &point);
secp256k1_ecmult_const(&res1, &point, &negone); secp256k1_ecmult_const(&res1, &point, &negone, 256);
secp256k1_gej_neg(&res1, &res1); secp256k1_gej_neg(&res1, &res1);
secp256k1_ge_set_gej(&res2, &res1); secp256k1_ge_set_gej(&res2, &res1);
ge_equals_ge(&res2, &point); ge_equals_ge(&res2, &point);
@ -2520,7 +2520,7 @@ void ecmult_const_chain_multiply(void) {
for (i = 0; i < 100; ++i) { for (i = 0; i < 100; ++i) {
secp256k1_ge tmp; secp256k1_ge tmp;
secp256k1_ge_set_gej(&tmp, &point); secp256k1_ge_set_gej(&tmp, &point);
secp256k1_ecmult_const(&point, &tmp, &scalar); secp256k1_ecmult_const(&point, &tmp, &scalar, 256);
} }
secp256k1_ge_set_gej(&res, &point); secp256k1_ge_set_gej(&res, &point);
ge_equals_gej(&res, &expected_point); ge_equals_gej(&res, &expected_point);
@ -2587,6 +2587,7 @@ void test_constant_wnaf(const secp256k1_scalar *number, int w) {
int wnaf[256] = {0}; int wnaf[256] = {0};
int i; int i;
int skew; int skew;
int bits = 256;
secp256k1_scalar num = *number; secp256k1_scalar num = *number;
secp256k1_scalar_set_int(&x, 0); secp256k1_scalar_set_int(&x, 0);
@ -2596,10 +2597,11 @@ void test_constant_wnaf(const secp256k1_scalar *number, int w) {
for (i = 0; i < 16; ++i) { for (i = 0; i < 16; ++i) {
secp256k1_scalar_shr_int(&num, 8); secp256k1_scalar_shr_int(&num, 8);
} }
bits = 128;
#endif #endif
skew = secp256k1_wnaf_const(wnaf, num, w); skew = secp256k1_wnaf_const(wnaf, num, w, bits, 1);
for (i = WNAF_SIZE(w); i >= 0; --i) { for (i = WNAF_SIZE(bits, w); i >= 0; --i) {
secp256k1_scalar t; secp256k1_scalar t;
int v = wnaf[i]; int v = wnaf[i];
CHECK(v != 0); /* check nonzero */ CHECK(v != 0); /* check nonzero */