nx_ecdsa_p384_test.nx source
↩ module page · 110 lines · 6014 B
1// nx_ecdsa_p384_test.nx -- KAT for ECDSA-P384 verify against the
2// RFC 6979 §A.2.6 vector (P-384 with SHA-256 over "sample").
3//
4// Inputs loaded via u384_load_be from BIG-ENDIAN byte tables --
5// mirrors the pattern used by nx_ecdsa_p256_test, eliminates the
6// hand-transcribed LE-limb error class. A prior version of this
7// file had a typo at sig_r[1] (0xFA2B3C36 vs correct 0x2FA2B3C3)
8// because manually splitting a BE hex string into LE 32-bit limbs
9// is error-prone. See [[feedback-canonical-constants-kat-against-
10// reference-not-hand-converted]] -- same lesson: don't hand-
11// convert representation; load_be takes the bytes as-is.
12//
13// expect_exit: 0
14// license_tier: ORIGINAL
15
16import "nx_syscalls.nx"
17import "nx_u384.nx"
18import "nx_ecdsa_p384.nx"
19
20func main() -> i64 {
21 // Pubkey U.x (48 BE bytes)
22 let qx_bytes: *u8 = sys_mmap(48)
23 qx_bytes[0]=0xEC; qx_bytes[1]=0x3A; qx_bytes[2]=0x4E; qx_bytes[3]=0x41
24 qx_bytes[4]=0x5B; qx_bytes[5]=0x4E; qx_bytes[6]=0x19; qx_bytes[7]=0xA4
25 qx_bytes[8]=0x56; qx_bytes[9]=0x86; qx_bytes[10]=0x18; qx_bytes[11]=0x02
26 qx_bytes[12]=0x9F; qx_bytes[13]=0x42; qx_bytes[14]=0x7F; qx_bytes[15]=0xA5
27 qx_bytes[16]=0xDA; qx_bytes[17]=0x9A; qx_bytes[18]=0x8B; qx_bytes[19]=0xC4
28 qx_bytes[20]=0xAE; qx_bytes[21]=0x92; qx_bytes[22]=0xE0; qx_bytes[23]=0x2E
29 qx_bytes[24]=0x06; qx_bytes[25]=0xAA; qx_bytes[26]=0xE5; qx_bytes[27]=0x28
30 qx_bytes[28]=0x6B; qx_bytes[29]=0x30; qx_bytes[30]=0x0C; qx_bytes[31]=0x64
31 qx_bytes[32]=0xDE; qx_bytes[33]=0xF8; qx_bytes[34]=0xF0; qx_bytes[35]=0xEA
32 qx_bytes[36]=0x90; qx_bytes[37]=0x55; qx_bytes[38]=0x86; qx_bytes[39]=0x60
33 qx_bytes[40]=0x64; qx_bytes[41]=0xA2; qx_bytes[42]=0x54; qx_bytes[43]=0x51
34 qx_bytes[44]=0x54; qx_bytes[45]=0x80; qx_bytes[46]=0xBC; qx_bytes[47]=0x13
35
36 // Pubkey U.y
37 let qy_bytes: *u8 = sys_mmap(48)
38 qy_bytes[0]=0x80; qy_bytes[1]=0x15; qy_bytes[2]=0xD9; qy_bytes[3]=0xB7
39 qy_bytes[4]=0x2D; qy_bytes[5]=0x7D; qy_bytes[6]=0x57; qy_bytes[7]=0x24
40 qy_bytes[8]=0x4E; qy_bytes[9]=0xA8; qy_bytes[10]=0xEF; qy_bytes[11]=0x9A
41 qy_bytes[12]=0xC0; qy_bytes[13]=0xC6; qy_bytes[14]=0x21; qy_bytes[15]=0x89
42 qy_bytes[16]=0x67; qy_bytes[17]=0x08; qy_bytes[18]=0xA5; qy_bytes[19]=0x93
43 qy_bytes[20]=0x67; qy_bytes[21]=0xF9; qy_bytes[22]=0xDF; qy_bytes[23]=0xB9
44 qy_bytes[24]=0xF5; qy_bytes[25]=0x4C; qy_bytes[26]=0xA8; qy_bytes[27]=0x4B
45 qy_bytes[28]=0x3F; qy_bytes[29]=0x1C; qy_bytes[30]=0x9D; qy_bytes[31]=0xB1
46 qy_bytes[32]=0x28; qy_bytes[33]=0x8B; qy_bytes[34]=0x23; qy_bytes[35]=0x1C
47 qy_bytes[36]=0x3A; qy_bytes[37]=0xE0; qy_bytes[38]=0xD4; qy_bytes[39]=0xFE
48 qy_bytes[40]=0x73; qy_bytes[41]=0x44; qy_bytes[42]=0xFD; qy_bytes[43]=0x25
49 qy_bytes[44]=0x33; qy_bytes[45]=0x26; qy_bytes[46]=0x47; qy_bytes[47]=0x20
50
51 // SHA-256("sample") = 32 BE bytes; load into low 256 bits of
52 // a 48-byte buffer (zero-extended on the high 128 bits).
53 let e_bytes: *u8 = sys_mmap(48)
54 var zi: i64 = 0
55 while zi < 16 { e_bytes[zi] = 0; zi = zi + 1 }
56 e_bytes[16]=0xAF; e_bytes[17]=0x2B; e_bytes[18]=0xDB; e_bytes[19]=0xE1
57 e_bytes[20]=0xAA; e_bytes[21]=0x9B; e_bytes[22]=0x6E; e_bytes[23]=0xC1
58 e_bytes[24]=0xE2; e_bytes[25]=0xAD; e_bytes[26]=0xE1; e_bytes[27]=0xD6
59 e_bytes[28]=0x94; e_bytes[29]=0xF4; e_bytes[30]=0x1F; e_bytes[31]=0xC7
60 e_bytes[32]=0x1A; e_bytes[33]=0x83; e_bytes[34]=0x1D; e_bytes[35]=0x02
61 e_bytes[36]=0x68; e_bytes[37]=0xE9; e_bytes[38]=0x89; e_bytes[39]=0x15
62 e_bytes[40]=0x62; e_bytes[41]=0x11; e_bytes[42]=0x3D; e_bytes[43]=0x8A
63 e_bytes[44]=0x62; e_bytes[45]=0xAD; e_bytes[46]=0xD1; e_bytes[47]=0xBF
64
65 // Signature r
66 let r_bytes: *u8 = sys_mmap(48)
67 r_bytes[0]=0x21; r_bytes[1]=0xB1; r_bytes[2]=0x3D; r_bytes[3]=0x1E
68 r_bytes[4]=0x01; r_bytes[5]=0x3C; r_bytes[6]=0x7F; r_bytes[7]=0xA1
69 r_bytes[8]=0x39; r_bytes[9]=0x2D; r_bytes[10]=0x03; r_bytes[11]=0xC5
70 r_bytes[12]=0xF9; r_bytes[13]=0x9A; r_bytes[14]=0xF8; r_bytes[15]=0xB3
71 r_bytes[16]=0x0C; r_bytes[17]=0x57; r_bytes[18]=0x0C; r_bytes[19]=0x6F
72 r_bytes[20]=0x98; r_bytes[21]=0xD4; r_bytes[22]=0xEA; r_bytes[23]=0x8E
73 r_bytes[24]=0x35; r_bytes[25]=0x4B; r_bytes[26]=0x63; r_bytes[27]=0xA2
74 r_bytes[28]=0x1D; r_bytes[29]=0x3D; r_bytes[30]=0xAA; r_bytes[31]=0x33
75 r_bytes[32]=0xBD; r_bytes[33]=0xE1; r_bytes[34]=0xE8; r_bytes[35]=0x88
76 r_bytes[36]=0xE6; r_bytes[37]=0x33; r_bytes[38]=0x55; r_bytes[39]=0xD9
77 r_bytes[40]=0x2F; r_bytes[41]=0xA2; r_bytes[42]=0xB3; r_bytes[43]=0xC3
78 r_bytes[44]=0x6D; r_bytes[45]=0x8F; r_bytes[46]=0xB2; r_bytes[47]=0xCD
79
80 // Signature s
81 let s_bytes: *u8 = sys_mmap(48)
82 s_bytes[0]=0xF3; s_bytes[1]=0xAA; s_bytes[2]=0x44; s_bytes[3]=0x3F
83 s_bytes[4]=0xB1; s_bytes[5]=0x07; s_bytes[6]=0x74; s_bytes[7]=0x5B
84 s_bytes[8]=0xF4; s_bytes[9]=0xBD; s_bytes[10]=0x77; s_bytes[11]=0xCB
85 s_bytes[12]=0x38; s_bytes[13]=0x91; s_bytes[14]=0x67; s_bytes[15]=0x46
86 s_bytes[16]=0x32; s_bytes[17]=0x06; s_bytes[18]=0x8A; s_bytes[19]=0x10
87 s_bytes[20]=0xCA; s_bytes[21]=0x67; s_bytes[22]=0xE3; s_bytes[23]=0xD4
88 s_bytes[24]=0x5D; s_bytes[25]=0xB2; s_bytes[26]=0x26; s_bytes[27]=0x6F
89 s_bytes[28]=0xA7; s_bytes[29]=0xD1; s_bytes[30]=0xFE; s_bytes[31]=0xEB
90 s_bytes[32]=0xEF; s_bytes[33]=0xDC; s_bytes[34]=0x63; s_bytes[35]=0xEC
91 s_bytes[36]=0xCD; s_bytes[37]=0x1A; s_bytes[38]=0xC4; s_bytes[39]=0x2E
92 s_bytes[40]=0xC0; s_bytes[41]=0xCB; s_bytes[42]=0x86; s_bytes[43]=0x68
93 s_bytes[44]=0xA4; s_bytes[45]=0xFA; s_bytes[46]=0x0A; s_bytes[47]=0xB0
94
95 let pub_x: *i64 = u384_alloc()
96 let pub_y: *i64 = u384_alloc()
97 let e: *i64 = u384_alloc()
98 let r: *i64 = u384_alloc()
99 let s: *i64 = u384_alloc()
100 u384_load_be(pub_x, qx_bytes)
101 u384_load_be(pub_y, qy_bytes)
102 u384_load_be(e, e_bytes)
103 u384_load_be(r, r_bytes)
104 u384_load_be(s, s_bytes)
105
106 let v: i64 = nx_ecdsa_p384_verify(pub_x, pub_y, e, r, s)
107 if v != NX_ECDSA_P384_OK { return v }
108
109 return 0
110}