Skip to content

Commit 8c1c940

Browse files
committed
address Jonas' feedback
1 parent ba34c6e commit 8c1c940

File tree

2 files changed

+97
-28
lines changed

2 files changed

+97
-28
lines changed

include/secp256k1.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -534,10 +534,10 @@ SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_def
534534
* `secp256k1_ecdsa_anti_nonce_sidechan_client_commit`. The client sends the resulting commitment
535535
* `R1` to the host.
536536
* 3. The host replies with `k2` generated in step 1.
537-
* 4. The client checks that the host commitment from step 1 commits to `k2` from step 3 and signs
538-
* with `secp256k1_ecdsa_sign_nonce_tweak_add`, using the `k2` as the tweak and the host
539-
* commitment as additional noncedata and sends the signature to the host.
540-
* 5. The host reconstructs the curve point `R` from the signature and verifies that `R = R1 + k2*G`.
537+
* 4. The client signs with `secp256k1_ecdsa_sign_to_contract`, using the `k2` as `s2c_data` and
538+
* sends the signature to the host.
539+
* 5. The host reconstructs the curve point `R` from the signature and verifies that
540+
* `R = R1 + H(R1, k2)*G`.
541541
*
542542
* Returns 1 on success, 0 on failure.
543543
* Args: ctx: pointer to a context object (cannot be NULL)
@@ -553,9 +553,8 @@ SECP256K1_API int secp256k1_ecdsa_anti_nonce_sidechan_client_commit(
553553
secp256k1_pubkey *client_commit,
554554
const unsigned char *msg32,
555555
const unsigned char *seckey32,
556-
secp256k1_nonce_function noncefp,
557556
unsigned char *rand_commitment32
558-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(6);
557+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
559558

560559
/** Create an ECDSA signature.
561560
*
@@ -580,16 +579,17 @@ SECP256K1_API int secp256k1_ecdsa_sign(
580579
const void *ndata
581580
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
582581

583-
/** Same as secp256k1_ecdsa_sign, but nonce_tweak32 is added to the nonce generated by noncefp.
582+
/** Same as secp256k1_ecdsa_sign, but s2c_data32 is committed to by adding `hash(R1, s2c_data32)` to
583+
the nonce generated by noncefp, with `ndata=hash(s2c_data32, ndata)`.
584584
*/
585-
SECP256K1_API int secp256k1_ecdsa_sign_nonce_tweak_add(
585+
SECP256K1_API int secp256k1_ecdsa_sign_to_contract(
586586
const secp256k1_context* ctx,
587587
secp256k1_ecdsa_signature *sig,
588588
const unsigned char *msg32,
589589
const unsigned char *seckey,
590590
secp256k1_nonce_function noncefp,
591591
const void *ndata,
592-
const unsigned char* nonce_tweak32
592+
const unsigned char* s2c_data32
593593
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
594594

595595
/** Verify an ECDSA secret key.

src/secp256k1.c

Lines changed: 88 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,6 @@ int secp256k1_ecdsa_anti_nonce_sidechan_client_commit(
451451
secp256k1_pubkey *client_commit,
452452
const unsigned char *msg32,
453453
const unsigned char *seckey32,
454-
secp256k1_nonce_function noncefp,
455454
unsigned char *rand_commitment32
456455
) {
457456
unsigned char nonce32[32];
@@ -464,13 +463,10 @@ int secp256k1_ecdsa_anti_nonce_sidechan_client_commit(
464463
ARG_CHECK(client_commit != NULL);
465464
ARG_CHECK(msg32 != NULL);
466465
ARG_CHECK(seckey32 != NULL);
467-
if (noncefp == NULL) {
468-
noncefp = secp256k1_nonce_function_default;
469-
}
470466
ARG_CHECK(rand_commitment32 != NULL);
471467

472468

473-
if (!noncefp(nonce32, msg32, seckey32, NULL, rand_commitment32, 0)) {
469+
if (!secp256k1_nonce_function_default(nonce32, msg32, seckey32, NULL, rand_commitment32, 0)) {
474470
return 0;
475471
}
476472

@@ -486,14 +482,56 @@ int secp256k1_ecdsa_anti_nonce_sidechan_client_commit(
486482
}
487483

488484
int secp256k1_ecdsa_sign(const secp256k1_context* ctx, secp256k1_ecdsa_signature *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) {
489-
return secp256k1_ecdsa_sign_nonce_tweak_add(ctx, signature, msg32, seckey, noncefp, noncedata, NULL);
485+
return secp256k1_ecdsa_sign_to_contract(ctx, signature, msg32, seckey, noncefp, noncedata, NULL);
490486
}
491487

492-
int secp256k1_ecdsa_sign_nonce_tweak_add(const secp256k1_context* ctx, secp256k1_ecdsa_signature *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata, const unsigned char* nonce_tweak32) {
488+
/* Compute an ec commitment tweak as hash(pubkey, data). */
489+
static int secp256k1_ec_commit_tweak(const secp256k1_context *ctx, unsigned char *tweak32, const secp256k1_pubkey *pubkey, const unsigned char *data, size_t data_size) {
490+
secp256k1_ge p;
491+
unsigned char rbuf[33];
492+
size_t rbuf_size = sizeof(rbuf);
493+
secp256k1_sha256 sha;
494+
495+
if (data_size == 0) {
496+
/* That's probably not what the caller wanted */
497+
return 0;
498+
}
499+
if(!secp256k1_pubkey_load(ctx, &p, pubkey)) {
500+
return 0;
501+
}
502+
secp256k1_eckey_pubkey_serialize(&p, rbuf, &rbuf_size, 1);
503+
504+
secp256k1_sha256_initialize(&sha);
505+
secp256k1_sha256_write(&sha, rbuf, rbuf_size);
506+
secp256k1_sha256_write(&sha, data, data_size);
507+
secp256k1_sha256_finalize(&sha, tweak32);
508+
return 1;
509+
}
510+
511+
/* Compute an ec commitment tweak as hash(pubkey, data). */
512+
static int secp256k1_ec_commit_tweak_from_seckey(
513+
const secp256k1_context *ctx,
514+
unsigned char *tweak32,
515+
const secp256k1_scalar *seckey,
516+
const unsigned char *data,
517+
size_t data_size) {
518+
secp256k1_gej rp;
519+
secp256k1_ge r;
520+
secp256k1_pubkey pubkey_tmp;
521+
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &rp, seckey);
522+
secp256k1_ge_set_gej(&r, &rp);
523+
secp256k1_pubkey_save(&pubkey_tmp, &r);
524+
return secp256k1_ec_commit_tweak(ctx, tweak32, &pubkey_tmp, data, data_size);
525+
}
526+
527+
int secp256k1_ecdsa_sign_to_contract(const secp256k1_context* ctx, secp256k1_ecdsa_signature *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata, const unsigned char* s2c_data32) {
493528
secp256k1_scalar r, s;
494-
secp256k1_scalar sec, non, msg, nonce_tweak;
529+
secp256k1_scalar sec, non, msg;
530+
secp256k1_sha256 sha;
495531
int ret = 0;
496532
int overflow = 0;
533+
int is_zero = 0;
534+
unsigned char ndata[32];
497535
VERIFY_CHECK(ctx != NULL);
498536
ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
499537
ARG_CHECK(msg32 != NULL);
@@ -502,12 +540,27 @@ int secp256k1_ecdsa_sign_nonce_tweak_add(const secp256k1_context* ctx, secp256k1
502540
if (noncefp == NULL) {
503541
noncefp = secp256k1_nonce_function_default;
504542
}
505-
506-
if (nonce_tweak32 != NULL) {
507-
secp256k1_scalar_set_b32(&nonce_tweak, nonce_tweak32, &overflow);
508-
if (overflow || secp256k1_scalar_is_zero(&nonce_tweak)) {
509-
return 0;
543+
/* sign-to-contract commitments only work with the default nonce function,
544+
* because we need to ensure that s2c_data is actually hashed into the nonce and
545+
* not just ignored. */
546+
ARG_CHECK(s2c_data32 == NULL || noncefp == secp256k1_nonce_function_default);
547+
548+
if(s2c_data32 != NULL) {
549+
/* Provide s2c_data32 and ndata (if not NULL) to the the nonce function
550+
* as additional data to derive the nonce from. If both pointers are
551+
* not NULL, they need to be hashed to get the nonce data 32 bytes.
552+
* Even if only s2c_data32 is not NULL, it's hashed because it should
553+
* be possible to derive nonces even if only a SHA256 commitment to the
554+
* data is known. This is for example important in the
555+
* anti-nonce-sidechannel protocol.
556+
*/
557+
secp256k1_sha256_initialize(&sha);
558+
secp256k1_sha256_write(&sha, s2c_data32, 32);
559+
if (noncedata != NULL) {
560+
secp256k1_sha256_write(&sha, noncedata, 32);
510561
}
562+
secp256k1_sha256_finalize(&sha, ndata);
563+
noncedata = &ndata;
511564
}
512565

513566
secp256k1_scalar_set_b32(&sec, seckey, &overflow);
@@ -522,12 +575,28 @@ int secp256k1_ecdsa_sign_nonce_tweak_add(const secp256k1_context* ctx, secp256k1
522575
break;
523576
}
524577
secp256k1_scalar_set_b32(&non, nonce32, &overflow);
525-
if (nonce_tweak32 != NULL) {
526-
secp256k1_scalar_add(&non, &non, &nonce_tweak);
527-
}
528-
if (!overflow && !secp256k1_scalar_is_zero(&non)) {
529-
if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, NULL)) {
530-
break;
578+
is_zero = secp256k1_scalar_is_zero(&non);
579+
if (!overflow && !is_zero) {
580+
if (s2c_data32 != NULL) {
581+
secp256k1_scalar nonce_tweak;
582+
unsigned char nonce_tweak32[32];
583+
if (!secp256k1_ec_commit_tweak_from_seckey(ctx, nonce_tweak32, &non, s2c_data32, 32)) {
584+
return 0;
585+
}
586+
587+
secp256k1_scalar_set_b32(&nonce_tweak, nonce_tweak32, &overflow);
588+
if (overflow || secp256k1_scalar_is_zero(&nonce_tweak)) {
589+
return 0;
590+
}
591+
592+
secp256k1_scalar_add(&non, &non, &nonce_tweak);
593+
is_zero = secp256k1_scalar_is_zero(&non);
594+
}
595+
596+
if (!is_zero) {
597+
if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, NULL)) {
598+
break;
599+
}
531600
}
532601
}
533602
count++;

0 commit comments

Comments
 (0)