Skip to content

Commit

Permalink
expose recid in secp256k1_anti_exfil_sign
Browse files Browse the repository at this point in the history
BitBox02 needs access to the recoverable ID, which it prevoiusly got
using the recovery module. We want to use the sign-to-contract (s2c)
module for the anti-exfil (antiklepto) functions.
  • Loading branch information
benma committed Jul 22, 2024
1 parent 1e04d32 commit 0b916d3
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 28 deletions.
6 changes: 4 additions & 2 deletions include/secp256k1_ecdsa_s2c.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ SECP256K1_API int secp256k1_ecdsa_s2c_sign(
secp256k1_ecdsa_s2c_opening *s2c_opening,
const unsigned char *msg32,
const unsigned char *seckey,
const unsigned char *s2c_data32
const unsigned char *s2c_data32,
int* recid
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);

/** Verify a sign-to-contract commitment.
Expand Down Expand Up @@ -204,7 +205,8 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_anti_exfil_sign(
secp256k1_ecdsa_signature *sig,
const unsigned char *msg32,
const unsigned char *seckey,
const unsigned char *host_data32
const unsigned char *host_data32,
int *recid
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);

/** Verify a signature was correctly constructed using the ECDSA Anti-Exfil Protocol.
Expand Down
2 changes: 1 addition & 1 deletion src/ctime_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ static void run_tests(secp256k1_context *ctx, unsigned char *key) {

SECP256K1_CHECKMEM_UNDEFINE(key, 32);
SECP256K1_CHECKMEM_UNDEFINE(s2c_data, 32);
ret = secp256k1_ecdsa_s2c_sign(ctx, &signature, &s2c_opening, msg, key, s2c_data);
ret = secp256k1_ecdsa_s2c_sign(ctx, &signature, &s2c_opening, msg, key, s2c_data, NULL);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);

Expand Down
8 changes: 4 additions & 4 deletions src/modules/ecdsa_s2c/main_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static void secp256k1_s2c_ecdsa_data_sha256_tagged(secp256k1_sha256 *sha) {
}

int secp256k1_ecdsa_s2c_sign(const secp256k1_context* ctx, secp256k1_ecdsa_signature* signature, secp256k1_ecdsa_s2c_opening* s2c_opening, const unsigned char
*msg32, const unsigned char *seckey, const unsigned char* s2c_data32) {
*msg32, const unsigned char *seckey, const unsigned char* s2c_data32, int* recid) {
secp256k1_scalar r, s;
int ret;
unsigned char ndata[32];
Expand All @@ -88,7 +88,7 @@ int secp256k1_ecdsa_s2c_sign(const secp256k1_context* ctx, secp256k1_ecdsa_signa
secp256k1_sha256_finalize(&s2c_sha, ndata);

secp256k1_s2c_ecdsa_point_sha256_tagged(&s2c_sha);
ret = secp256k1_ecdsa_sign_inner(ctx, &r, &s, NULL, &s2c_sha, s2c_opening, s2c_data32, msg32, seckey, NULL, ndata);
ret = secp256k1_ecdsa_sign_inner(ctx, &r, &s, recid, &s2c_sha, s2c_opening, s2c_data32, msg32, seckey, NULL, ndata);
secp256k1_scalar_cmov(&r, &secp256k1_scalar_zero, !ret);
secp256k1_scalar_cmov(&s, &secp256k1_scalar_zero, !ret);
secp256k1_ecdsa_signature_save(signature, &r, &s);
Expand Down Expand Up @@ -185,8 +185,8 @@ int secp256k1_ecdsa_anti_exfil_signer_commit(const secp256k1_context* ctx, secp2
return 1;
}

int secp256k1_anti_exfil_sign(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char* msg32, const unsigned char* seckey, const unsigned char* host_data32) {
return secp256k1_ecdsa_s2c_sign(ctx, sig, NULL, msg32, seckey, host_data32);
int secp256k1_anti_exfil_sign(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char* msg32, const unsigned char* seckey, const unsigned char* host_data32, int* recid) {
return secp256k1_ecdsa_s2c_sign(ctx, sig, NULL, msg32, seckey, host_data32, recid);
}

int secp256k1_anti_exfil_host_verify(const secp256k1_context* ctx, const secp256k1_ecdsa_signature *sig, const unsigned char *msg32, const secp256k1_pubkey *pubkey, const unsigned char *host_data32, const secp256k1_ecdsa_s2c_opening *opening) {
Expand Down
42 changes: 21 additions & 21 deletions src/modules/ecdsa_s2c/tests_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,14 @@ static void test_ecdsa_s2c_api(void) {

CHECK(secp256k1_ec_pubkey_create(CTX, &pk, sec));

CHECK_ILLEGAL(CTX, secp256k1_ecdsa_s2c_sign(CTX, NULL, &s2c_opening, msg, sec, s2c_data));
CHECK_ILLEGAL(CTX, secp256k1_ecdsa_s2c_sign(CTX, NULL, &s2c_opening, msg, sec, s2c_data, NULL));
/* NULL opening is not an API error */
CHECK(secp256k1_ecdsa_s2c_sign(CTX, &sig, NULL, msg, sec, s2c_data) == 1);
CHECK_ILLEGAL(CTX, secp256k1_ecdsa_s2c_sign(CTX, &sig, &s2c_opening, NULL, sec, s2c_data));
CHECK_ILLEGAL(CTX, secp256k1_ecdsa_s2c_sign(CTX, &sig, &s2c_opening, msg, NULL, s2c_data));
CHECK_ILLEGAL(CTX, secp256k1_ecdsa_s2c_sign(CTX, &sig, &s2c_opening, msg, sec, NULL));
CHECK(secp256k1_ecdsa_s2c_sign(CTX, &sig, &s2c_opening, msg, sec, s2c_data) == 1);
CHECK_ILLEGAL(STATIC_CTX, secp256k1_ecdsa_s2c_sign(STATIC_CTX, &sig, &s2c_opening, msg, sec, s2c_data));
CHECK(secp256k1_ecdsa_s2c_sign(CTX, &sig, NULL, msg, sec, s2c_data, NULL) == 1);
CHECK_ILLEGAL(CTX, secp256k1_ecdsa_s2c_sign(CTX, &sig, &s2c_opening, NULL, sec, s2c_data, NULL));
CHECK_ILLEGAL(CTX, secp256k1_ecdsa_s2c_sign(CTX, &sig, &s2c_opening, msg, NULL, s2c_data, NULL));
CHECK_ILLEGAL(CTX, secp256k1_ecdsa_s2c_sign(CTX, &sig, &s2c_opening, msg, sec, NULL, NULL));
CHECK(secp256k1_ecdsa_s2c_sign(CTX, &sig, &s2c_opening, msg, sec, s2c_data, NULL) == 1);
CHECK_ILLEGAL(STATIC_CTX, secp256k1_ecdsa_s2c_sign(STATIC_CTX, &sig, &s2c_opening, msg, sec, s2c_data, NULL));

CHECK(secp256k1_ecdsa_verify(CTX, &sig, msg, &pk) == 1);

Expand All @@ -106,7 +106,7 @@ static void test_ecdsa_s2c_api(void) {
CHECK(secp256k1_ecdsa_s2c_verify_commit(CTX, &sig, sec, &s2c_opening) == 0);

/* Signing with NULL s2c_opening gives the same result */
CHECK(secp256k1_ecdsa_s2c_sign(CTX, &sig, NULL, msg, sec, s2c_data) == 1);
CHECK(secp256k1_ecdsa_s2c_sign(CTX, &sig, NULL, msg, sec, s2c_data, NULL) == 1);
CHECK(secp256k1_ecdsa_s2c_verify_commit(CTX, &sig, s2c_data, &s2c_opening) == 1);

/* anti-exfil */
Expand All @@ -121,12 +121,12 @@ static void test_ecdsa_s2c_api(void) {
CHECK(secp256k1_ecdsa_anti_exfil_signer_commit(CTX, &s2c_opening, msg, sec, hostrand_commitment) == 1);
CHECK_ILLEGAL(STATIC_CTX, secp256k1_ecdsa_anti_exfil_signer_commit(STATIC_CTX, &s2c_opening, msg, sec, hostrand_commitment));

CHECK_ILLEGAL(CTX, secp256k1_anti_exfil_sign(CTX, NULL, msg, sec, hostrand));
CHECK_ILLEGAL(CTX, secp256k1_anti_exfil_sign(CTX, &sig, NULL, sec, hostrand));
CHECK_ILLEGAL(CTX, secp256k1_anti_exfil_sign(CTX, &sig, msg, NULL, hostrand));
CHECK_ILLEGAL(CTX, secp256k1_anti_exfil_sign(CTX, &sig, msg, sec, NULL));
CHECK(secp256k1_anti_exfil_sign(CTX, &sig, msg, sec, hostrand) == 1);
CHECK_ILLEGAL(STATIC_CTX, secp256k1_anti_exfil_sign(STATIC_CTX, &sig, msg, sec, hostrand));
CHECK_ILLEGAL(CTX, secp256k1_anti_exfil_sign(CTX, NULL, msg, sec, hostrand, NULL));
CHECK_ILLEGAL(CTX, secp256k1_anti_exfil_sign(CTX, &sig, NULL, sec, hostrand, NULL));
CHECK_ILLEGAL(CTX, secp256k1_anti_exfil_sign(CTX, &sig, msg, NULL, hostrand, NULL));
CHECK_ILLEGAL(CTX, secp256k1_anti_exfil_sign(CTX, &sig, msg, sec, NULL, NULL));
CHECK(secp256k1_anti_exfil_sign(CTX, &sig, msg, sec, hostrand, NULL) == 1);
CHECK_ILLEGAL(STATIC_CTX, secp256k1_anti_exfil_sign(STATIC_CTX, &sig, msg, sec, hostrand, NULL));

CHECK_ILLEGAL(CTX, secp256k1_anti_exfil_host_verify(CTX, NULL, msg, &pk, hostrand, &s2c_opening));
CHECK_ILLEGAL(CTX, secp256k1_anti_exfil_host_verify(CTX, &sig, NULL, &pk, hostrand, &s2c_opening));
Expand Down Expand Up @@ -175,7 +175,7 @@ static void test_ecdsa_s2c_fixed_vectors(void) {
unsigned char opening_ser[33];
const ecdsa_s2c_test *test = &ecdsa_s2c_tests[i];
secp256k1_ecdsa_signature signature;
CHECK(secp256k1_ecdsa_s2c_sign(CTX, &signature, &s2c_opening, message, privkey, test->s2c_data) == 1);
CHECK(secp256k1_ecdsa_s2c_sign(CTX, &signature, &s2c_opening, message, privkey, test->s2c_data, NULL) == 1);
CHECK(secp256k1_ecdsa_s2c_opening_serialize(CTX, opening_ser, &s2c_opening) == 1);
CHECK(secp256k1_memcmp_var(test->expected_s2c_opening, opening_ser, sizeof(opening_ser)) == 0);
CHECK(secp256k1_ecdsa_s2c_verify_commit(CTX, &signature, test->s2c_data, &s2c_opening) == 1);
Expand Down Expand Up @@ -208,20 +208,20 @@ static void test_ecdsa_s2c_sign_verify(void) {
{ /* invalid privkeys */
unsigned char zero_privkey[32] = {0};
unsigned char overflow_privkey[32] = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
CHECK(secp256k1_ecdsa_s2c_sign(CTX, &signature, NULL, message, zero_privkey, s2c_data) == 0);
CHECK(secp256k1_ecdsa_s2c_sign(CTX, &signature, NULL, message, overflow_privkey, s2c_data) == 0);
CHECK(secp256k1_ecdsa_s2c_sign(CTX, &signature, NULL, message, zero_privkey, s2c_data, NULL) == 0);
CHECK(secp256k1_ecdsa_s2c_sign(CTX, &signature, NULL, message, overflow_privkey, s2c_data, NULL) == 0);
}
/* Check that the sign-to-contract signature is valid, with s2c_data. Also check the commitment. */
{
CHECK(secp256k1_ecdsa_s2c_sign(CTX, &signature, &s2c_opening, message, privkey, s2c_data) == 1);
CHECK(secp256k1_ecdsa_s2c_sign(CTX, &signature, &s2c_opening, message, privkey, s2c_data, NULL) == 1);
CHECK(secp256k1_ecdsa_verify(CTX, &signature, message, &pubkey) == 1);
CHECK(secp256k1_ecdsa_s2c_verify_commit(CTX, &signature, s2c_data, &s2c_opening) == 1);
}
/* Check that an invalid commitment does not verify */
{
unsigned char sigbytes[64];
size_t i;
CHECK(secp256k1_ecdsa_s2c_sign(CTX, &signature, &s2c_opening, message, privkey, s2c_data) == 1);
CHECK(secp256k1_ecdsa_s2c_sign(CTX, &signature, &s2c_opening, message, privkey, s2c_data, NULL) == 1);
CHECK(secp256k1_ecdsa_verify(CTX, &signature, message, &pubkey) == 1);

CHECK(secp256k1_ecdsa_signature_serialize_compact(CTX, sigbytes, &signature) == 1);
Expand Down Expand Up @@ -283,7 +283,7 @@ static void test_ecdsa_anti_exfil(void) {
CHECK(secp256k1_ecdsa_anti_exfil_signer_commit(CTX, &s2c_opening, host_msg, signer_privkey, host_commitment) == 1);
/* Protocol step 3: host_nonce_contribution send to signer to be used in step 4. */
/* Protocol step 4. */
CHECK(secp256k1_anti_exfil_sign(CTX, &signature, host_msg, signer_privkey, host_nonce_contribution) == 1);
CHECK(secp256k1_anti_exfil_sign(CTX, &signature, host_msg, signer_privkey, host_nonce_contribution, NULL) == 1);
/* Protocol step 5. */
CHECK(secp256k1_anti_exfil_host_verify(CTX, &signature, host_msg, &signer_pubkey, host_nonce_contribution, &s2c_opening) == 1);
/* Protocol step 5 (explicitly) */
Expand Down Expand Up @@ -314,7 +314,7 @@ static void test_ecdsa_anti_exfil(void) {
{ /* s2c_sign: host provided data that didn't match commitment */
secp256k1_ecdsa_s2c_opening orig_opening = s2c_opening;
unsigned char bad_nonce_contribution[32] = { 1, 2, 3, 4 };
CHECK(secp256k1_ecdsa_s2c_sign(CTX, &signature, &s2c_opening, host_msg, signer_privkey, bad_nonce_contribution) == 1);
CHECK(secp256k1_ecdsa_s2c_sign(CTX, &signature, &s2c_opening, host_msg, signer_privkey, bad_nonce_contribution, NULL) == 1);
/* good signature but the opening (original public nonce does not match the original */
CHECK(secp256k1_ecdsa_verify(CTX, &signature, host_msg, &signer_pubkey) == 1);
CHECK(secp256k1_anti_exfil_host_verify(CTX, &signature, host_msg, &signer_pubkey, host_nonce_contribution, &s2c_opening) == 0);
Expand Down

0 comments on commit 0b916d3

Please sign in to comment.