6Generate a C file with ECDH testvectors from the Wycheproof project.
12from binascii
import hexlify, unhexlify
13from wycheproof_utils
import to_c_array
18 flags_to_skip = {
"InvalidAsn",
"WrongCurve"}
19 return any(flag
in test_vector_flags
for flag
in flags_to_skip)
25 tcids_to_skip = [496, 497, 502, 503, 504, 505, 507]
26 return test_vector_tcid
in tcids_to_skip
39 L = 256 * int(s[2]) + int(s[3])
42 raise ValueError(
"invalid L")
43 value = s[(offset + 2):(L + 2 + offset)]
44 rest = s[(L + 2 + offset):]
46 if len(rest) > 0
or tag == 0x06:
52 raise ValueError(
"unknown tag")
56 return hexlify(der_pub_key).decode()[2:]
61 normalized = sk[-64:].zfill(64)
62 if len(normalized) != 64:
63 raise ValueError(
"private key must be exactly 64 characters long.")
67 result_mapping = {
"invalid": 0,
"valid": 1,
"acceptable": 1}
68 return result_mapping[er]
70filename_input = sys.argv[1]
72with open(filename_input)
as f:
76offset_sk_running, offset_pk_running, offset_shared = 0, 0, 0
84for group
in doc[
'testGroups']:
85 assert group[
"type"] ==
"EcdhTest"
86 assert group[
"curve"] ==
"secp256k1"
87 for test_vector
in group[
'tests']:
96 shared_size = len(test_vector[
'shared']) // 2
97 sk_size = len(private_key) // 2
98 pk_size = len(public_key) // 2
102 sk_offset = offset_sk_running
105 if sk
not in cache_sks:
106 if num_vectors != 0
and sk_size != 0:
107 private_keys +=
",\n "
108 cache_sks[sk] = offset_sk_running
112 sk_offset = cache_sks[sk]
117 pk_offset = offset_pk_running
119 if pk
not in cache_public_keys:
120 if num_vectors != 0
and len(pk) != 0:
121 public_keys +=
",\n "
122 cache_public_keys[pk] = offset_pk_running
126 pk_offset = cache_public_keys[pk]
129 shared_secrets +=
",\n " if num_vectors
and shared_size
else ""
130 shared_secrets +=
to_c_array(test_vector[
'shared'])
131 wycheproof_tcid = test_vector[
'tcId']
133 test_vectors_out +=
" /" +
"* tcId: " + str(test_vector[
'tcId']) +
". " + test_vector[
'comment'] +
" *" +
"/\n"
134 test_vectors_out += f
" {{{pk_offset}, {pk_size}, {sk_offset}, {sk_size}, {offset_shared}, {shared_size}, {expected_result}, {wycheproof_tcid} }},\n"
136 offset_sk_running += sk_size
138 offset_pk_running += pk_size
139 offset_shared += shared_size
142struct_definition =
"""
148 size_t shared_offset;
152} wycheproof_ecdh_testvector;
155print("/* Note: this file was autogenerated using tests_wycheproof_ecdh.py. Do not edit. */")
156print(f"#define SECP256K1_ECDH_WYCHEPROOF_NUMBER_TESTVECTORS ({num_vectors})")
158print(struct_definition)
160print("static const unsigned char wycheproof_ecdh_private_keys[] = { " + private_keys + "};\n
")
161print("static const unsigned char wycheproof_ecdh_public_keys[] = { " + public_keys +
"};\n")
162print(
"static const unsigned char wycheproof_ecdh_shared_secrets[] = { " + shared_secrets +
"};\n")
164print(
"static const wycheproof_ecdh_testvector testvectors[SECP256K1_ECDH_WYCHEPROOF_NUMBER_TESTVECTORS] = {")
165print(test_vectors_out)
def normalize_private_key(sk)
def normalize_expected_result(er)
def should_skip_flags(test_vector_flags)
def should_skip_tcid(test_vector_tcid)