Skip to content

Commit 5f659e6

Browse files
committed
tests: impl bitflip test for schnorrsig randomizer gen
- refactor `secp256k1_batch_add_schnorrsig_randomizer` to support testing - `randomizer_gen` -> generates a 32-byte array randomizer - `randomizer_set` -> converts the 32-byte array to secp256k1_scalar - impl bitflip test for `secp256k1_batch_add_schnorrsig_randomizer_gen`
1 parent f793514 commit 5f659e6

File tree

2 files changed

+88
-13
lines changed

2 files changed

+88
-13
lines changed

src/modules/batch/tests_impl.h

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@
55

66
#define MAX_TERMS 10
77

8+
/*
9+
todo: separate tests of batch_add_* from (create, destroy, verify)
10+
since, compiling libsecp with batch module and without
11+
schnorrsig, won't compile add functions. So, can't use them in tests
12+
*/
813

914
/* Tests for the equality of two sha256 structs. This function only produces a
1015
* correct result if an integer multiple of 64 many bytes have been written
1116
* into the hash functions. */
12-
void batch_test_sha256_eq(const secp256k1_sha256 *sha1, const secp256k1_sha256 *sha2) {
17+
void test_batch_sha256_eq(const secp256k1_sha256 *sha1, const secp256k1_sha256 *sha2) {
1318
/* Is buffer fully consumed? */
1419
CHECK((sha1->bytes & 0x3F) == 0);
1520

@@ -26,7 +31,67 @@ void test_batch_sha256_tagged(void) {
2631

2732
secp256k1_sha256_initialize_tagged(&sha, (unsigned char *) tag, sizeof(tag));
2833
secp256k1_batch_sha256_tagged(&sha_optimized);
29-
batch_test_sha256_eq(&sha, &sha_optimized);
34+
test_batch_sha256_eq(&sha, &sha_optimized);
35+
}
36+
37+
/* Checks that a bit flip in the n_flip-th argument (that has n_bytes many
38+
* bytes) changes the hash function
39+
*/
40+
void batch_schnorrsig_randomizer_gen_bitflip(secp256k1_sha256 *sha, unsigned char **args, size_t n_flip, size_t n_bytes, size_t msglen) {
41+
unsigned char randomizers[2][32];
42+
secp256k1_sha256 sha_cpy;
43+
sha_cpy = *sha;
44+
CHECK(secp256k1_batch_schnorrsig_randomizer_gen(randomizers[0], &sha_cpy, args[0], args[1], msglen, args[2]) == 1);
45+
secp256k1_testrand_flip(args[n_flip], n_bytes);
46+
sha_cpy = *sha;
47+
CHECK(secp256k1_batch_schnorrsig_randomizer_gen(randomizers[1], &sha_cpy, args[0], args[1], msglen, args[2]) == 1);
48+
CHECK(secp256k1_memcmp_var(randomizers[0], randomizers[1], 32) != 0);
49+
}
50+
51+
/*todo: make n_sigs var global macro? then, wouldn't it affects n_sigs api tests?*/
52+
void run_batch_schnorrsig_randomizer_gen_tests(void) {
53+
secp256k1_sha256 sha;
54+
size_t n_sigs = 20;
55+
unsigned char msg[32];
56+
size_t msglen = sizeof(msg[0]);
57+
unsigned char sig[64];
58+
unsigned char compressed_pk[33];
59+
unsigned char *args[3];
60+
uint8_t rand;
61+
size_t i; /* loops through n_sigs */
62+
int j; /* loops through count */
63+
64+
secp256k1_batch_sha256_tagged(&sha);
65+
66+
for (i = 0; i < n_sigs; i++) {
67+
/* generate i-th schnorrsig verify data */
68+
secp256k1_testrand256(msg);
69+
secp256k1_testrand256(&sig[0]);
70+
secp256k1_testrand256(&sig[32]);
71+
secp256k1_testrand256(&compressed_pk[1]);
72+
rand = secp256k1_testrand_int(2) + 2; /* randomly choose 2 or 3 */
73+
compressed_pk[0] = (unsigned char)rand;
74+
75+
/* check that bitflip in an argument results in different nonces */
76+
args[0] = sig;
77+
args[1] = msg;
78+
args[2] = compressed_pk;
79+
80+
for (j = 0; j < count; j++) {
81+
batch_schnorrsig_randomizer_gen_bitflip(&sha, args, 0, 64, msglen);
82+
batch_schnorrsig_randomizer_gen_bitflip(&sha, args, 1, 32, msglen);
83+
batch_schnorrsig_randomizer_gen_bitflip(&sha, args, 2, 33, msglen);
84+
}
85+
86+
/* write i-th schnorrsig verify data to the sha object
87+
* this is required for generating the next randomizer */
88+
secp256k1_sha256_write(&sha, sig, 64);
89+
secp256k1_sha256_write(&sha, msg, msglen);
90+
secp256k1_sha256_write(&sha, compressed_pk, 33);
91+
92+
}
93+
94+
/* todo: msglen difference test?? */
3095
}
3196

3297
void test_batch_api(void) {
@@ -113,6 +178,7 @@ void test_batch_api(void) {
113178
void run_batch_tests(void) {
114179
test_batch_api();
115180
test_batch_sha256_tagged();
181+
run_batch_schnorrsig_randomizer_gen_tests();
116182
}
117183

118184
#endif /* SECP256K1_MODULE_BATCH_TESTS_H */

src/modules/schnorrsig/batch_add_impl.h

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,26 @@
55
#include "src/hash.h"
66
#include "src/modules/batch/main_impl.h"
77

8-
static int secp256k1_batch_schnorrsig_randomizer(const secp256k1_context *ctx, secp256k1_batch *batch, secp256k1_scalar *r, const unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_xonly_pubkey *pubkey) {
8+
static int secp256k1_batch_schnorrsig_randomizer_gen(unsigned char *randomizer32, secp256k1_sha256 *sha256, const unsigned char *sig64, const unsigned char *msg, size_t msglen, const unsigned char *compressed_pk33) {
99
secp256k1_sha256 sha256_cpy;
10+
11+
/* add schnorrsig data to sha256 object */
12+
secp256k1_sha256_write(sha256, sig64, 64);
13+
secp256k1_sha256_write(sha256, msg, msglen);
14+
secp256k1_sha256_write(sha256, compressed_pk33, 33);
15+
16+
/* generate randomizer */
17+
sha256_cpy = *sha256;
18+
secp256k1_sha256_finalize(&sha256_cpy, randomizer32);
19+
20+
return 1;
21+
}
22+
23+
static int secp256k1_batch_schnorrsig_randomizer_set(const secp256k1_context *ctx, secp256k1_batch *batch, secp256k1_scalar *r, const unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_xonly_pubkey *pubkey) {
24+
int overflow;
1025
unsigned char randomizer[32];
1126
unsigned char buf[33];
1227
size_t buflen = sizeof(buf);
13-
int overflow;
1428

1529
/* We use compressed serialization here. If we would use
1630
* xonly_pubkey serialization and a user would wrongly memcpy
@@ -20,14 +34,9 @@ static int secp256k1_batch_schnorrsig_randomizer(const secp256k1_context *ctx, s
2034
return 0;
2135
}
2236

23-
/* add schnorrsig data to sha256 object */
24-
secp256k1_sha256_write(&batch->sha256, sig64, 64);
25-
secp256k1_sha256_write(&batch->sha256, msg, msglen);
26-
secp256k1_sha256_write(&batch->sha256, buf, buflen);
27-
28-
/* generate randomizer */
29-
sha256_cpy = batch->sha256;
30-
secp256k1_sha256_finalize(&sha256_cpy, randomizer);
37+
if(!secp256k1_batch_schnorrsig_randomizer_gen(randomizer, &batch->sha256, sig64, msg, msglen, buf)) {
38+
return 0;
39+
}
3140
secp256k1_scalar_set_b32(r, randomizer, &overflow);
3241
VERIFY_CHECK(overflow == 0);
3342

@@ -112,7 +121,7 @@ int secp256k1_batch_add_schnorrsig(const secp256k1_context* ctx, secp256k1_batch
112121
secp256k1_schnorrsig_challenge(&e, &sig64[0], msg, msglen, buf);
113122

114123
/* Compute ai */
115-
if (!secp256k1_batch_schnorrsig_randomizer(ctx, batch, &ai, sig64, msg, msglen, pubkey)) {
124+
if (!secp256k1_batch_schnorrsig_randomizer_set(ctx, batch, &ai, sig64, msg, msglen, pubkey)) {
116125
return 0;
117126
}
118127

0 commit comments

Comments
 (0)