_ed25519_rfc8032_kat.nx source
↩ module page · 87 lines · 3221 B
1// _ed25519_rfc8032_kat.nx — RFC 8032 §7.1 TEST 1 KAT for Ed25519.
2//
3// SECRET: 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60
4// EXPECTED PUB: d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a
5// MSG: (empty)
6// EXPECTED SIG: e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b
7//
8// If our pub_from_priv or sign produces different bytes, the substrate Ed25519
9// implementation is buggy against the spec (not just internally inconsistent).
10
11import "nx_syscalls.nx"
12import "nx_ed25519_signature.nx"
13
14func _hex_byte(c: u8) -> i64 {
15 let v: i64 = c as i64
16 if v >= 0x30 { if v <= 0x39 { return v - 0x30 } }
17 if v >= 0x61 { if v <= 0x66 { return v - 0x61 + 10 } }
18 if v >= 0x41 { if v <= 0x46 { return v - 0x41 + 10 } }
19 return 0
20}
21
22func _hex_to_bytes(hex: *u8, n: i64, out: *u8) -> i64 {
23 var i: i64 = 0
24 while i < n {
25 let hi: i64 = _hex_byte(hex[i*2])
26 let lo: i64 = _hex_byte(hex[i*2 + 1])
27 out[i] = ((hi << 4) | lo) as u8
28 i = i + 1
29 }
30 return 0
31}
32
33func _byte_eq(a: *u8, b: *u8, n: i64) -> i64 {
34 var i: i64 = 0
35 while i < n {
36 if a[i] != b[i] { return 0 }
37 i = i + 1
38 }
39 return 1
40}
41
42func _hex_putd(b: u8) -> i64 {
43 let buf: *u8 = sys_mmap(2)
44 let v: i64 = b as i64
45 let hi: i64 = (v >> 4) & 0xf
46 let lo: i64 = v & 0xf
47 if hi < 10 { buf[0] = (0x30 + hi) as u8 } else { buf[0] = (0x61 + hi - 10) as u8 }
48 if lo < 10 { buf[1] = (0x30 + lo) as u8 } else { buf[1] = (0x61 + lo - 10) as u8 }
49 sys_write(2, buf, 2)
50 return 0
51}
52
53func _puthex(p: *u8, n: i64) -> i64 {
54 var i: i64 = 0
55 while i < n { _hex_putd(p[i]); i = i + 1 }
56 sys_write(2, "\n" as *u8, 1)
57 return 0
58}
59
60func main() -> i64 {
61 let priv_32: *u8 = sys_mmap(32)
62 _hex_to_bytes("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" as *u8, 32, priv_32)
63
64 let exp_pub: *u8 = sys_mmap(32)
65 _hex_to_bytes("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a" as *u8, 32, exp_pub)
66
67 let exp_sig: *u8 = sys_mmap(64)
68 _hex_to_bytes("e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b" as *u8, 64, exp_sig)
69
70 let got_pub: *u8 = sys_mmap(32)
71 if ed25519_pub_from_priv(priv_32, got_pub) != 0 { sys_write(2, "pub_from_priv FAIL\n" as *u8, 19); return 1 }
72 sys_write(2, "exp_pub: " as *u8, 9); _puthex(exp_pub, 32)
73 sys_write(2, "got_pub: " as *u8, 9); _puthex(got_pub, 32)
74 if _byte_eq(exp_pub, got_pub, 32) != 1 { sys_write(2, "PUB MISMATCH\n" as *u8, 13); return 2 }
75 sys_write(2, "PUB OK\n" as *u8, 7)
76
77 // Sign empty msg
78 let got_sig: *u8 = sys_mmap(64)
79 let empty: *u8 = sys_mmap(8)
80 if ed25519_sign_full(priv_32, empty, 0, got_sig) != 0 { sys_write(2, "sign FAIL\n" as *u8, 10); return 3 }
81 sys_write(2, "exp_sig: " as *u8, 9); _puthex(exp_sig, 64)
82 sys_write(2, "got_sig: " as *u8, 9); _puthex(got_sig, 64)
83 if _byte_eq(exp_sig, got_sig, 64) != 1 { sys_write(2, "SIG MISMATCH\n" as *u8, 13); return 4 }
84
85 sys_write(1, "RFC 8032 TEST 1 PASS\n" as *u8, 21)
86 return 0
87}