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}