11 "This script converts BIP MuSig2 test vectors in a given directory to a C file that can be used in the test framework." 13 print(
"Usage: %s <dir>" % sys.argv[0])
18 return ", ".join([f
"0x{b:02X}" for b
in bytes.fromhex(str)])
23 static const struct musig_%s_vector musig_%s_vector = { 35 s = textwrap.indent(
"{\n", 4 *
" ")
39 s += textwrap.indent(
"\n},\n", 4 *
" ")
44 return " %d, { %s }" % (
46 ", ".join(map(str, array)
if len(array) > 0
else "0"),
51 if len(case[
"tweak_indices"]) > 0:
52 return ", ".join(map(
lambda x:
"1" if x
else "0", case[
"is_xonly"]))
61 s = textwrap.indent(
"{\n", 4 *
" ")
62 for (i, case)
in enumerate(cases):
63 s += textwrap.indent(
"%s\n" % f(case), 8 *
" ")
64 s += textwrap.indent(
"},\n", 4 *
" ")
74 * Automatically generated by %s. 76 * The test vectors for the KeySort function are included in this file. They can 77 * be found in src/modules/extrakeys/tests_impl.h. */ 97 with open(sys.argv[1] +
"/key_agg_vectors.json",
"r") as f: 100 max_key_indices = max( 101 len(test_case["key_indices"])
for test_case
in data[
"valid_test_cases"]
103 max_tweak_indices = max(
104 len(test_case[
"tweak_indices"])
for test_case
in data[
"error_test_cases"]
106 num_pubkeys = len(data[
"pubkeys"])
107 max_pubkeys = max(num_pubkeys, max_pubkeys)
108 num_tweaks = len(data[
"tweaks"])
109 num_valid_cases = len(data[
"valid_test_cases"])
110 num_error_cases = len(data[
"error_test_cases"])
115 struct musig_key_agg_valid_test_case { 116 size_t key_indices_len; 117 size_t key_indices[%d]; 118 unsigned char expected[32]; 124 struct musig_key_agg_error_test_case { 125 size_t key_indices_len; 126 size_t key_indices[%d]; 127 size_t tweak_indices_len; 128 size_t tweak_indices[%d]; 130 enum MUSIG_ERROR error; 140 struct musig_key_agg_vector { 141 unsigned char pubkeys[%d][33]; 142 unsigned char tweaks[%d][32]; 143 struct musig_key_agg_valid_test_case valid_case[%d]; 144 struct musig_key_agg_error_test_case error_case[%d]; 160 data[
"valid_test_cases"],
161 lambda case:
"{ %s, { %s }}," 166 comment = case[
"comment"]
167 if "public key" in comment.lower():
168 return "MUSIG_PUBKEY" 169 elif "tweak" in comment.lower():
172 sys.exit(
"Unknown error")
176 data[
"error_test_cases"],
177 lambda case:
"{ %s, %s, { %s }, %s }," 189 with open(sys.argv[1] +
"/nonce_gen_vectors.json",
"r") as f: 193 data[
"test_cases"] = list(
194 filter(
lambda c: c[
"msg"]
is None or len(c[
"msg"]) == 64, data[
"test_cases"])
197 num_tests = len(data[
"test_cases"])
200 struct musig_nonce_gen_test_case { 201 unsigned char rand_[32]; 203 unsigned char sk[32]; 204 unsigned char pk[33]; 206 unsigned char aggpk[32]; 208 unsigned char msg[32]; 210 unsigned char extra_in[32]; 211 unsigned char expected_secnonce[97]; 212 unsigned char expected_pubnonce[66]; 218 struct musig_nonce_gen_vector { 219 struct musig_nonce_gen_test_case test_case[%d]; 228 return "%d , { %s }" % (
229 0
if array
is None else 1,
235 lambda case:
"{ { %s }, %s, { %s }, %s, %s, %s, { %s }, { %s } }," 251 with open(sys.argv[1] +
"/nonce_agg_vectors.json",
"r") as f: 254 num_pnonces = len(data["pnonces"])
255 num_valid_cases = len(data[
"valid_test_cases"])
256 num_error_cases = len(data[
"error_test_cases"])
258 pnonce_indices_len = 2
259 for case
in data[
"valid_test_cases"] + data[
"error_test_cases"]:
260 assert len(case[
"pnonce_indices"]) == pnonce_indices_len
264 struct musig_nonce_agg_test_case { 265 size_t pnonce_indices[2]; 267 unsigned char expected[66]; 269 int invalid_nonce_idx; 274 struct musig_nonce_agg_vector { 275 unsigned char pnonces[%d][66]; 276 struct musig_nonce_agg_test_case valid_case[%d]; 277 struct musig_nonce_agg_test_case error_case[%d]; 288 for cases
in (data[
"valid_test_cases"], data[
"error_test_cases"]):
291 lambda case:
"{ { %s }, { %s }, %d }," 293 ", ".join(map(str, case[
"pnonce_indices"])),
295 case[
"error"][
"signer"]
if "error" in case
else 0,
301 with open(sys.argv[1] +
"/sign_verify_vectors.json",
"r") as f: 305 assert list(filter(
lambda x: len(x) == 64, data[
"msgs"]))[0] == data[
"msgs"][0]
306 data[
"msgs"] = [data[
"msgs"][0]]
309 return list(filter(
lambda x: x[
"msg_index"] == 0, data[k]))
311 data[
"valid_test_cases"] =
filter_msg32(
"valid_test_cases")
312 data[
"sign_error_test_cases"] =
filter_msg32(
"sign_error_test_cases")
313 data[
"verify_error_test_cases"] =
filter_msg32(
"verify_error_test_cases")
314 data[
"verify_fail_test_cases"] =
filter_msg32(
"verify_fail_test_cases")
316 num_pubkeys = len(data[
"pubkeys"])
317 max_pubkeys = max(num_pubkeys, max_pubkeys)
318 num_secnonces = len(data[
"secnonces"])
319 num_pubnonces = len(data[
"pnonces"])
320 num_aggnonces = len(data[
"aggnonces"])
321 num_msgs = len(data[
"msgs"])
322 num_valid_cases = len(data[
"valid_test_cases"])
323 num_sign_error_cases = len(data[
"sign_error_test_cases"])
324 num_verify_fail_cases = len(data[
"verify_fail_test_cases"])
325 num_verify_error_cases = len(data[
"verify_error_test_cases"])
328 data[
"valid_test_cases"]
329 + data[
"sign_error_test_cases"]
330 + data[
"verify_error_test_cases"]
331 + data[
"verify_fail_test_cases"]
333 max_key_indices = max(len(test_case[
"key_indices"])
for test_case
in all_cases)
334 max_nonce_indices = max(
335 len(test_case[
"nonce_indices"])
if "nonce_indices" in test_case
else 0
336 for test_case
in all_cases
341 /* Omit pubnonces in the test vectors because our partial signature verification 342 * implementation is able to accept the aggnonce directly. */ 343 struct musig_valid_case { 344 size_t key_indices_len; 345 size_t key_indices[%d]; 346 size_t aggnonce_index; 349 unsigned char expected[32]; 357 struct musig_sign_error_case { 358 size_t key_indices_len; 359 size_t key_indices[%d]; 360 size_t aggnonce_index; 362 size_t secnonce_index; 363 enum MUSIG_ERROR error; 370 struct musig_verify_fail_error_case { 371 unsigned char sig[32]; 372 size_t key_indices_len; 373 size_t key_indices[%d]; 374 size_t nonce_indices_len; 375 size_t nonce_indices[%d]; 378 enum MUSIG_ERROR error; 387 struct musig_sign_verify_vector { 388 unsigned char sk[32]; 389 unsigned char pubkeys[%d][33]; 390 unsigned char secnonces[%d][194]; 391 unsigned char pubnonces[%d][194]; 392 unsigned char aggnonces[%d][66]; 393 unsigned char msgs[%d][32]; 394 struct musig_valid_case valid_case[%d]; 395 struct musig_sign_error_case sign_error_case[%d]; 396 struct musig_verify_fail_error_case verify_fail_case[%d]; 397 struct musig_verify_fail_error_case verify_error_case[%d]; 406 num_sign_error_cases,
407 num_verify_fail_cases,
408 num_verify_error_cases,
420 data[
"valid_test_cases"],
421 lambda case:
"{ %s, %d, %d, %d, { %s }}," 424 case[
"aggnonce_index"],
426 case[
"signer_index"],
432 comment = case[
"comment"]
433 if "pubkey" in comment
or "public key" in comment:
434 return "MUSIG_PUBKEY" 435 elif "Aggregate nonce" in comment:
436 return "MUSIG_AGGNONCE" 437 elif "Secnonce" in comment:
438 return "MUSIG_SECNONCE" 440 sys.exit(
"Unknown sign error")
443 data[
"sign_error_test_cases"],
444 lambda case:
"{ %s, %d, %d, %d, %s }," 447 case[
"aggnonce_index"],
449 case[
"secnonce_index"],
455 comment = case[
"comment"]
456 if "exceeds" in comment:
458 elif "Wrong signer" in comment
or "Wrong signature" in comment:
459 return "MUSIG_SIG_VERIFY" 460 elif "pubnonce" in comment:
461 return "MUSIG_PUBNONCE" 462 elif "pubkey" in comment:
463 return "MUSIG_PUBKEY" 465 sys.exit(
"Unknown verify error")
467 for cases
in (
"verify_fail_test_cases",
"verify_error_test_cases"):
470 lambda case:
"{ { %s }, %s, %s, %d, %d, %s }," 476 case[
"signer_index"],
484 with open(sys.argv[1] +
"/tweak_vectors.json",
"r") as f: 487 num_pubkeys = len(data["pubkeys"])
488 max_pubkeys = max(num_pubkeys, max_pubkeys)
489 num_pubnonces = len(data[
"pnonces"])
490 num_tweaks = len(data[
"tweaks"])
491 num_valid_cases = len(data[
"valid_test_cases"])
492 num_error_cases = len(data[
"error_test_cases"])
494 all_cases = data[
"valid_test_cases"] + data[
"error_test_cases"]
495 max_key_indices = max(len(test_case[
"key_indices"])
for test_case
in all_cases)
496 max_tweak_indices = max(len(test_case[
"tweak_indices"])
for test_case
in all_cases)
497 max_nonce_indices = max(len(test_case[
"nonce_indices"])
for test_case
in all_cases)
500 struct musig_tweak_case { 501 size_t key_indices_len; 502 size_t key_indices[%d]; 503 size_t nonce_indices_len; 504 size_t nonce_indices[%d]; 505 size_t tweak_indices_len; 506 size_t tweak_indices[%d]; 509 unsigned char expected[32]; 520 struct musig_tweak_vector { 521 unsigned char sk[32]; 522 unsigned char secnonce[97]; 523 unsigned char aggnonce[66]; 524 unsigned char msg[32]; 525 unsigned char pubkeys[%d][33]; 526 unsigned char pubnonces[%d][194]; 527 unsigned char tweaks[%d][32]; 528 struct musig_tweak_case valid_case[%d]; 529 struct musig_tweak_case error_case[%d]; 548 data[
"valid_test_cases"],
549 lambda case:
"{ %s, %s, %s, { %s }, %d, { %s }}," 555 case[
"signer_index"],
561 data[
"error_test_cases"],
562 lambda case:
"{ %s, %s, %s, { %s }, %d, { %s }}," 568 case[
"signer_index"],
576 with open(sys.argv[1] +
"/sig_agg_vectors.json",
"r") as f: 579 num_pubkeys = len(data["pubkeys"])
580 max_pubkeys = max(num_pubkeys, max_pubkeys)
581 num_tweaks = len(data[
"tweaks"])
582 num_psigs = len(data[
"psigs"])
583 num_valid_cases = len(data[
"valid_test_cases"])
584 num_error_cases = len(data[
"error_test_cases"])
586 all_cases = data[
"valid_test_cases"] + data[
"error_test_cases"]
587 max_key_indices = max(len(test_case[
"key_indices"])
for test_case
in all_cases)
588 max_tweak_indices = max(len(test_case[
"tweak_indices"])
for test_case
in all_cases)
589 max_psig_indices = max(len(test_case[
"psig_indices"])
for test_case
in all_cases)
593 /* Omit pubnonces in the test vectors because they're only needed for 594 * implementations that do not directly accept an aggnonce. */ 595 struct musig_sig_agg_case { 596 size_t key_indices_len; 597 size_t key_indices[%d]; 598 size_t tweak_indices_len; 599 size_t tweak_indices[%d]; 601 unsigned char aggnonce[66]; 602 size_t psig_indices_len; 603 size_t psig_indices[%d]; 605 unsigned char expected[64]; 618 struct musig_sig_agg_vector { 619 unsigned char pubkeys[%d][33]; 620 unsigned char tweaks[%d][32]; 621 unsigned char psigs[%d][32]; 622 unsigned char msg[32]; 623 struct musig_sig_agg_case valid_case[%d]; 624 struct musig_sig_agg_case error_case[%d]; 640 for cases
in (data[
"valid_test_cases"], data[
"error_test_cases"]):
643 lambda case:
"{ %s, %s, { %s }, { %s }, %s, { %s }, %d }," 651 case[
"error"][
"signer"]
if "error" in case
else 0,
655 s +=
"enum { MUSIG_VECTORS_MAX_PUBKEYS = %d };" % max_pubkeys
def init_optional_expected(case)
def hexstr_to_intarray(str)
def comment_to_error(case)
def init_array_maybe(array)