code wiki / _hdl_build / nx_bip39_kat.nx
nx_bip39_kat.nx source
↩ module page · 127 lines · 7121 B
1// nx_bip39_kat.nx -- ENGINEER gate: BIP39 vs the standard's own vectors (trezor/python-mnemonic
2// vectors.json, the reference suite the BIP-0039 spec links). 8x 24-word + 3x 12-word vectors:
3// encode(entropy) must equal the published mnemonic STRING byte-exact; decode(mnemonic) must
4// return the entropy and round-trip. Negatives: swapped word -> BAD_CHECKSUM, alien word ->
5// UNKNOWN_WORD, truncated phrase -> BAD_WORD_COUNT. Plus generate_24 self-round-trip.
6// license_tier: ORIGINAL
7import "hub/nx_bip39.nx"
8import "nx_syscalls.nx"
9
10func bk_w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
11func bk_z(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
12func bk_nib(c: i64) -> i64 {
13 if c >= 48 { if c <= 57 { return c - 48 } }
14 if c >= 97 { if c <= 102 { return c - 87 } }
15 return 0
16}
17func bk_hex(hexs: *u8, out: *u8) -> i64 {
18 var i: i64 = 0
19 while hexs[i*2] != (0 as u8) {
20 out[i] = ((bk_nib(hexs[i*2] as i64) << 4) | bk_nib(hexs[i*2+1] as i64)) as u8
21 i = i + 1
22 }
23 return i
24}
25func bk_eq(a: *u8, b: *u8, n: i64) -> i64 {
26 var i: i64 = 0
27 while i < n { if (a[i] as i64) != (b[i] as i64) { return 0 } i = i + 1 }
28 return 1
29}
30
31// one vector: encode==string, decode==entropy. returns 0 good, 1 bad.
32func bk_vec(ent_hex: *u8, want_str: *u8) -> i64 {
33 let ent: *u8 = sys_mmap(40)
34 let ent_n: i64 = bk_hex(ent_hex, ent)
35 let want_n: i64 = bk_z(want_str)
36 let got: *u8 = sys_mmap(NX_B39_MAX_MNEMONIC_LEN)
37 let got_n: *i64 = sys_mmap(8) as *i64
38 if nx_bip39_encode(ent, ent_n, got, NX_B39_MAX_MNEMONIC_LEN, got_n) != NX_B39_OK {
39 bk_w("FAIL encode rc\n" as *u8); return 1
40 }
41 if got_n[0] != want_n { bk_w("FAIL encode len\n" as *u8); return 1 }
42 if bk_eq(got, want_str, want_n) == 0 {
43 bk_w("FAIL encode bytes: " as *u8); sys_write(1, got, got_n[0]); bk_w("\n" as *u8); return 1
44 }
45 let dec: *u8 = sys_mmap(40)
46 let dec_n: *i64 = sys_mmap(8) as *i64
47 if nx_bip39_decode(want_str, want_n, dec, 40, dec_n) != NX_B39_OK {
48 bk_w("FAIL decode rc\n" as *u8); return 1
49 }
50 if dec_n[0] != ent_n { bk_w("FAIL decode len\n" as *u8); return 1 }
51 if bk_eq(dec, ent, ent_n) == 0 { bk_w("FAIL decode bytes\n" as *u8); return 1 }
52 return 0
53}
54
55func main() -> i64 {
56 var bad: i64 = 0
57
58 // ---- 8 official 24-word vectors ----
59 bad = bad + bk_vec("0000000000000000000000000000000000000000000000000000000000000000" as *u8,
60 "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art" as *u8)
61 bad = bad + bk_vec("7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f" as *u8,
62 "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title" as *u8)
63 bad = bad + bk_vec("8080808080808080808080808080808080808080808080808080808080808080" as *u8,
64 "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless" as *u8)
65 bad = bad + bk_vec("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" as *u8,
66 "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote" as *u8)
67 bad = bad + bk_vec("68a79eaca2324873eacc50cb9c6eca8cc68ea5d936f98787c60c7ebc74e6ce7c" as *u8,
68 "hamster diagram private dutch cause delay private meat slide toddler razor book happy fancy gospel tennis maple dilemma loan word shrug inflict delay length" as *u8)
69 bad = bad + bk_vec("9f6a2878b2520799a44ef18bc7df394e7061a224d2c33cd015b157d746869863" as *u8,
70 "panda eyebrow bullet gorilla call smoke muffin taste mesh discover soft ostrich alcohol speed nation flash devote level hobby quick inner drive ghost inside" as *u8)
71 bad = bad + bk_vec("066dca1a2bb7e8a1db2832148ce9933eea0f3ac9548d793112d9a95c9407efad" as *u8,
72 "all hour make first leader extend hole alien behind guard gospel lava path output census museum junior mass reopen famous sing advance salt reform" as *u8)
73 bad = bad + bk_vec("f585c11aec520db57dd353c69554b21a89b20fb0650966fa0a9d6f74fd989d8f" as *u8,
74 "void come effort suffer camp survey warrior heavy shoot primary clutch crush open amazing screen patrol group space point ten exist slush involve unfold" as *u8)
75
76 // ---- 3 official 12-word vectors (multi-length path) ----
77 bad = bad + bk_vec("00000000000000000000000000000000" as *u8,
78 "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" as *u8)
79 bad = bad + bk_vec("7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f" as *u8,
80 "legal winner thank year wave sausage worth useful legal winner thank yellow" as *u8)
81 bad = bad + bk_vec("80808080808080808080808080808080" as *u8,
82 "letter advice cage absurd amount doctor acoustic avoid letter advice cage above" as *u8)
83
84 if bad == 0 { bk_w("11 vectors GREEN\n" as *u8) }
85
86 // ---- negative: last word swapped -> BAD_CHECKSUM ----
87 let tampered: *u8 = "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo" as *u8
88 let dec: *u8 = sys_mmap(40)
89 let dec_n: *i64 = sys_mmap(8) as *i64
90 if nx_bip39_decode(tampered, bk_z(tampered), dec, 40, dec_n) != (0 - NX_B39_BAD_CHECKSUM) {
91 bad = bad + 1; bk_w("FAIL tamper not BAD_CHECKSUM\n" as *u8)
92 }
93
94 // ---- negative: alien word -> UNKNOWN_WORD ----
95 let alien: *u8 = "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo nishi" as *u8
96 if nx_bip39_decode(alien, bk_z(alien), dec, 40, dec_n) != (0 - NX_B39_UNKNOWN_WORD) {
97 bad = bad + 1; bk_w("FAIL alien not UNKNOWN_WORD\n" as *u8)
98 }
99
100 // ---- negative: 13 words -> BAD_WORD_COUNT ----
101 let thirteen: *u8 = "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo" as *u8
102 if nx_bip39_decode(thirteen, bk_z(thirteen), dec, 40, dec_n) != (0 - NX_B39_BAD_WORD_COUNT) {
103 bad = bad + 1; bk_w("FAIL 13-word not BAD_WORD_COUNT\n" as *u8)
104 }
105
106 // ---- generate_24 self round trip (CSPRNG path) ----
107 let gen_ent: *u8 = sys_mmap(32)
108 let gen_str: *u8 = sys_mmap(NX_B39_MAX_MNEMONIC_LEN)
109 let gen_n: *i64 = sys_mmap(8) as *i64
110 if nx_bip39_generate_24(gen_ent, gen_str, NX_B39_MAX_MNEMONIC_LEN, gen_n) != NX_B39_OK {
111 bad = bad + 1; bk_w("FAIL generate_24\n" as *u8)
112 }
113 let rt: *u8 = sys_mmap(40)
114 let rt_n: *i64 = sys_mmap(8) as *i64
115 if nx_bip39_decode(gen_str, gen_n[0], rt, 40, rt_n) != NX_B39_OK {
116 bad = bad + 1; bk_w("FAIL generated mnemonic decode\n" as *u8)
117 }
118 if bk_eq(rt, gen_ent, 32) == 0 { bad = bad + 1; bk_w("FAIL generated round trip\n" as *u8) }
119
120 if bad == 0 {
121 bk_w("BIP39 KAT GREEN (11 official vectors byte-exact + checksum/unknown/count rejections + CSPRNG round trip)\n" as *u8)
122 sys_exit(0)
123 }
124 bk_w("BIP39 KAT FAILED\n" as *u8)
125 sys_exit(1)
126 return 1
127}