Skip to content

Commit

Permalink
Add ecdsa_adaptor_sig_verify
Browse files Browse the repository at this point in the history
  • Loading branch information
jonasnick committed Apr 4, 2020
1 parent cf0ae97 commit d4f796b
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 10 deletions.
21 changes: 20 additions & 1 deletion src/modules/ecdsa_adaptor/dleq_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,19 @@ static void secp256k1_dleq_serialize_point(unsigned char *buf33, const secp256k1
secp256k1_fe_get_b32(&buf33[1], &x);
}

static int secp256k1_dleq_deserialize_point(secp256k1_ge *p, const unsigned char *buf33) {
secp256k1_fe x;

if (!secp256k1_fe_set_b32(&x, &buf33[1])) {
return 0;
}
if (buf33[0] > 1) {
return 0;
}
secp256k1_ge_set_xo_var(p, &x, buf33[0]);
return 1;
}

/* TODO: remove */
static void print_buf(const unsigned char *buf, size_t n) {
size_t i;
Expand Down Expand Up @@ -92,7 +105,12 @@ static void secp256k1_dleq_pair(const secp256k1_ecmult_gen_context *ecmult_gen_c
secp256k1_ge_set_gej(p2, &p2j);
}

static int secp256k1_dleq_proof(const secp256k1_ecmult_gen_context *ecmult_gen_ctx, secp256k1_scalar *s, secp256k1_scalar *e, const unsigned char *algo16, const secp256k1_scalar *sk, const secp256k1_ge *gen2) {
static int secp256k1_dleq_proof(const secp256k1_ecmult_gen_context *ecmult_gen_ctx,
secp256k1_scalar *s,
secp256k1_scalar *e,
const unsigned char *algo16,
const secp256k1_scalar *sk,
const secp256k1_ge *gen2) {
unsigned char nonce32[32];
unsigned char key32[32];
secp256k1_ge p1, p2;
Expand All @@ -109,6 +127,7 @@ static int secp256k1_dleq_proof(const secp256k1_ecmult_gen_context *ecmult_gen_c
secp256k1_dleq_hash_point(&sha, &p2);
secp256k1_sha256_finalize(&sha, buf32);

secp256k1_scalar_get_b32(key32, sk);
/* everything that goes into the challenge hash must go into the nonce as well... */
if (!nonce_function_bip340(nonce32, buf32, key32, buf32, algo16, NULL, 0)) {
return 0;
Expand Down
98 changes: 93 additions & 5 deletions src/modules/ecdsa_adaptor/main_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ int secp256k1_ecdsa_adaptor_sign_helper(secp256k1_scalar *sigs, secp256k1_scalar
secp256k1_scalar sigr;
secp256k1_scalar n;
int overflow;
int high;
/* int high; */

secp256k1_fe_normalize(&r->x);
secp256k1_fe_get_b32(b, &r->x);
Expand All @@ -31,15 +31,21 @@ int secp256k1_ecdsa_adaptor_sign_helper(secp256k1_scalar *sigs, secp256k1_scalar

secp256k1_scalar_clear(&n);

high = secp256k1_scalar_is_high(sigs);
secp256k1_scalar_cond_negate(sigs, high);

/* high = secp256k1_scalar_is_high(sigs); */
/* TODO: deal with lows */
/* this may result in wrong r in adaptor verify */
/* secp256k1_scalar_cond_negate(sigs, high); */


return !secp256k1_scalar_is_zero(sigs);
}

int secp256k1_ecdsa_adaptor_sign(const secp256k1_context* ctx, unsigned char *adaptor_sig65, unsigned char *adaptor_proof97, unsigned char *seckey32, const secp256k1_pubkey *adaptor, const unsigned char *msg32) {
int secp256k1_ecdsa_adaptor_sign(const secp256k1_context* ctx,
unsigned char *adaptor_sig65,
unsigned char *adaptor_proof97,
unsigned char *seckey32,
const secp256k1_pubkey *adaptor,
const unsigned char *msg32) {
unsigned char nonce32[32];
secp256k1_scalar k;
secp256k1_gej rj, rpj;
Expand Down Expand Up @@ -91,6 +97,7 @@ int secp256k1_ecdsa_adaptor_sign(const secp256k1_context* ctx, unsigned char *ad
}

/* 6. return (R, R', s', proof) */
secp256k1_ge_set_gej(&rp, &rpj);
secp256k1_dleq_serialize_point(adaptor_proof97, &rp);
secp256k1_scalar_get_b32(&adaptor_proof97[33], &dleq_proof_s);
secp256k1_scalar_get_b32(&adaptor_proof97[33+32], &dleq_proof_e);
Expand All @@ -103,4 +110,85 @@ int secp256k1_ecdsa_adaptor_sign(const secp256k1_context* ctx, unsigned char *ad
return 1;
}

/* TODO: does x_coord have to be a scalar? */
SECP256K1_API int secp256k1_ecdsa_adaptor_sig_verify_helper(const secp256k1_context* ctx, secp256k1_fe *x_coord, secp256k1_scalar *sigr, secp256k1_scalar *sigs, const secp256k1_ge *pubkey, const secp256k1_scalar *message) {
secp256k1_scalar sn, u1, u2;
secp256k1_gej pubkeyj;
secp256k1_gej pr;
secp256k1_ge p;

if (secp256k1_scalar_is_zero(sigr) || secp256k1_scalar_is_zero(sigs)) {
return 0;
}

secp256k1_scalar_inverse_var(&sn, sigs);
secp256k1_scalar_mul(&u1, &sn, message);
secp256k1_scalar_mul(&u2, &sn, sigr);

secp256k1_gej_set_ge(&pubkeyj, pubkey);
secp256k1_ecmult(&ctx->ecmult_ctx, &pr, &pubkeyj, &u2, &u1);
if (secp256k1_gej_is_infinity(&pr)) {
return 0;
}
secp256k1_ge_set_gej(&p, &pr);
secp256k1_fe_normalize(&p.x);
*x_coord = p.x;
return 1;
}


int secp256k1_ecdsa_adaptor_sig_verify(const secp256k1_context* ctx, const unsigned char *adaptor_sig65, const secp256k1_pubkey *pubkey, const unsigned char *msg32, const secp256k1_pubkey *adaptor, const unsigned char *adaptor_proof97) {
secp256k1_scalar dleq_proof_s, dleq_proof_e;
secp256k1_scalar msg;
secp256k1_ge q;
secp256k1_ge r, rp;
secp256k1_fe rhs;
secp256k1_scalar sp;
secp256k1_scalar sigr;
secp256k1_ge adaptor_ge;
int overflow;

VERIFY_CHECK(ctx != NULL);
ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
ARG_CHECK(adaptor_sig65 != NULL);
ARG_CHECK(pubkey != NULL);
ARG_CHECK(msg32 != NULL);
ARG_CHECK(adaptor != NULL);
ARG_CHECK(adaptor_proof97 != NULL);

/* 1. DLEQ_verify((G,R'),(Y, R)) */
if (!secp256k1_dleq_deserialize_point(&rp, &adaptor_proof97[0])) {
return 0;
}
secp256k1_scalar_set_b32(&dleq_proof_s, &adaptor_proof97[33], &overflow);
if (overflow) {
return 0;
}
secp256k1_scalar_set_b32(&dleq_proof_e, &adaptor_proof97[33 + 32], &overflow);
if (overflow) {
return 0;
}
secp256k1_dleq_deserialize_point(&r, &adaptor_sig65[0]);
if (!secp256k1_pubkey_load(ctx, &adaptor_ge, adaptor)) {
return 0;
}
if(!secp256k1_dleq_verify(&ctx->ecmult_ctx, (unsigned char *)"ecdsaadaptorsig", &dleq_proof_s, &dleq_proof_e, &rp, &adaptor_ge, &r)) {
return 0;
}

/* 2. return x_coord(R') == x_coord(s'⁻¹(H(m) * G + x_coord(R) * X)) */
secp256k1_scalar_set_b32(&msg, msg32, NULL);
secp256k1_scalar_set_b32(&sp, &adaptor_sig65[33], NULL);
secp256k1_scalar_set_b32(&sigr, &adaptor_sig65[1], NULL);
if (!secp256k1_pubkey_load(ctx, &q, pubkey)) {
return 0;
}

if (!secp256k1_ecdsa_adaptor_sig_verify_helper(ctx, &rhs, &sigr, &sp, &q, &msg)) {
return 0;
}

return secp256k1_fe_equal(&rp.x, &rhs);
}

#endif /* SECP256K1_MODULE_ECDSA_ADAPTOR_MAIN_H */
32 changes: 28 additions & 4 deletions src/modules/ecdsa_adaptor/tests_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,21 +69,47 @@ void dleq_tests(void) {
}
}

void rand_flip_bit(unsigned char *array, size_t n) {
array[secp256k1_rand_int(n)] ^= 1 << secp256k1_rand_int(8);
}

void adaptor_tests(void) {
unsigned char adaptor_sig[65];
unsigned char adaptor_proof[97];
unsigned char seckey[32];
secp256k1_pubkey pubkey;
unsigned char msg[32];
unsigned char adaptor_secret[32];
secp256k1_pubkey adaptor;
unsigned char adaptor_sig[65];
unsigned char adaptor_proof[97];

secp256k1_rand256(seckey);
secp256k1_rand256(msg);
secp256k1_rand256(adaptor_secret);

CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, seckey) == 1);
CHECK(secp256k1_ec_pubkey_create(ctx, &adaptor, adaptor_secret) == 1);
CHECK(secp256k1_ecdsa_adaptor_sign(ctx, adaptor_sig, adaptor_proof, seckey, &adaptor, msg) == 1);
CHECK(secp256k1_ecdsa_adaptor_sig_verify(ctx, adaptor_sig, &pubkey, msg, &adaptor, adaptor_proof) == 1);
{
unsigned char adaptor_sig_tmp[65];
memcpy(adaptor_sig_tmp, adaptor_sig, sizeof(adaptor_sig_tmp));
rand_flip_bit(&adaptor_sig_tmp[1], sizeof(adaptor_sig_tmp) - 1);
CHECK(secp256k1_ecdsa_adaptor_sig_verify(ctx, adaptor_sig_tmp, &pubkey, msg, &adaptor, adaptor_proof) == 0);
}
CHECK(secp256k1_ecdsa_adaptor_sig_verify(ctx, adaptor_sig, &adaptor, msg, &adaptor, adaptor_proof) == 0);
{
unsigned char msg_tmp[32];
memcpy(msg_tmp, msg, sizeof(msg_tmp));
rand_flip_bit(msg_tmp, sizeof(msg_tmp));
CHECK(secp256k1_ecdsa_adaptor_sig_verify(ctx, adaptor_sig, &pubkey, msg_tmp, &adaptor, adaptor_proof) == 0);
}
CHECK(secp256k1_ecdsa_adaptor_sig_verify(ctx, adaptor_sig, &pubkey, msg, &pubkey, adaptor_proof) == 0);
{
unsigned char adaptor_proof_tmp[97];
memcpy(adaptor_proof_tmp, adaptor_proof, sizeof(adaptor_proof_tmp));
rand_flip_bit(adaptor_proof_tmp, sizeof(adaptor_proof_tmp));
CHECK(secp256k1_ecdsa_adaptor_sig_verify(ctx, adaptor_sig, &pubkey, msg, &adaptor, adaptor_proof_tmp) == 0);
}
}

void run_ecdsa_adaptor_tests(void) {
Expand All @@ -97,5 +123,3 @@ void run_ecdsa_adaptor_tests(void) {
}

#endif /* SECP256K1_MODULE_ECDSA_ADAPTOR_TESTS_H */


0 comments on commit d4f796b

Please sign in to comment.