code wiki / (root) / nx_ecdsa_sig_der_test.nx

nx_ecdsa_sig_der_test.nx source

↩ module page · 151 lines · 6803 B

1// nx_ecdsa_sig_der_test.nx -- KAT for the ECDSA DER-sig parser. 2// 3// Test vector: RFC 6979 §A.2.5 (NIST P-256 + SHA-256, "sample") 4// r = EFD48B2AACB6A8FD1140DD9CD45E81D6 9D2C877B56AAF991C34D0EA84EAF3716 5// s = F7CB1C942D657C41D436C7A1B6E29F65 F3E900DBB9AFF4064DC4AB2F843ACDA8 6// 7// Both r and s have their leading byte's high bit set (0xEF and 8// 0xF7 respectively), so DER encoding prepends 0x00 to each -> 9// 33-byte INTEGER bodies. 10// 11// expect_exit: 0 12// license_tier: ORIGINAL 13 14import "nx_syscalls.nx" 15import "nx_u256.nx" 16import "nx_ecdsa_sig_der.nx" 17 18func main() -> i64 { 19 // ---- Build RFC 6979 §A.2.5 DER-encoded sig ---- 20 // 30 46 SEQUENCE length 70 21 // 02 21 00 EF D4 ... 37 16 INTEGER (33 bytes) r 22 // 02 21 00 F7 CB ... CD A8 INTEGER (33 bytes) s 23 // total: 2 + 35 + 35 = 72 bytes 24 let buf: *u8 = sys_mmap(128) 25 buf[0] = 0x30; buf[1] = 0x46 // SEQUENCE 70 26 27 // INTEGER tag + length + 0x00 + 32-byte r 28 buf[2] = 0x02; buf[3] = 0x21; buf[4] = 0x00 29 buf[5] = 0xEF; buf[6] = 0xD4; buf[7] = 0x8B; buf[8] = 0x2A 30 buf[9] = 0xAC; buf[10] = 0xB6; buf[11] = 0xA8; buf[12] = 0xFD 31 buf[13] = 0x11; buf[14] = 0x40; buf[15] = 0xDD; buf[16] = 0x9C 32 buf[17] = 0xD4; buf[18] = 0x5E; buf[19] = 0x81; buf[20] = 0xD6 33 buf[21] = 0x9D; buf[22] = 0x2C; buf[23] = 0x87; buf[24] = 0x7B 34 buf[25] = 0x56; buf[26] = 0xAA; buf[27] = 0xF9; buf[28] = 0x91 35 buf[29] = 0xC3; buf[30] = 0x4D; buf[31] = 0x0E; buf[32] = 0xA8 36 buf[33] = 0x4E; buf[34] = 0xAF; buf[35] = 0x37; buf[36] = 0x16 37 38 // INTEGER tag + length + 0x00 + 32-byte s 39 buf[37] = 0x02; buf[38] = 0x21; buf[39] = 0x00 40 buf[40] = 0xF7; buf[41] = 0xCB; buf[42] = 0x1C; buf[43] = 0x94 41 buf[44] = 0x2D; buf[45] = 0x65; buf[46] = 0x7C; buf[47] = 0x41 42 buf[48] = 0xD4; buf[49] = 0x36; buf[50] = 0xC7; buf[51] = 0xA1 43 buf[52] = 0xB6; buf[53] = 0xE2; buf[54] = 0x9F; buf[55] = 0x65 44 buf[56] = 0xF3; buf[57] = 0xE9; buf[58] = 0x00; buf[59] = 0xDB 45 buf[60] = 0xB9; buf[61] = 0xAF; buf[62] = 0xF4; buf[63] = 0x06 46 buf[64] = 0x4D; buf[65] = 0xC4; buf[66] = 0xAB; buf[67] = 0x2F 47 buf[68] = 0x84; buf[69] = 0x3A; buf[70] = 0xCD; buf[71] = 0xA8 48 49 let der_total: i64 = 72 50 let r: *i64 = u256_alloc() 51 let s: *i64 = u256_alloc() 52 53 // ---- Test A: parse succeeds + extracts known values ---- 54 let v: i64 = nx_ecdsa_sig_parse_der(buf, der_total, r, s) 55 if v != NX_ECDSA_DER_OK { return 1 } 56 57 // Verify r limbs (LE) against the expected BE bytes: 58 // limb[7] = 0xEFD48B2A (top of r) 59 // limb[0] = 0x4EAF3716 (bottom of r) 60 if r[7] != 0xEFD48B2A { return 2 } 61 if r[6] != 0xACB6A8FD { return 3 } 62 if r[5] != 0x1140DD9C { return 4 } 63 if r[4] != 0xD45E81D6 { return 5 } 64 if r[3] != 0x9D2C877B { return 6 } 65 if r[2] != 0x56AAF991 { return 7 } 66 if r[1] != 0xC34D0EA8 { return 8 } 67 if r[0] != 0x4EAF3716 { return 9 } 68 69 // Verify s limbs: 70 if s[7] != 0xF7CB1C94 { return 10 } 71 if s[6] != 0x2D657C41 { return 11 } 72 if s[5] != 0xD436C7A1 { return 12 } 73 if s[4] != 0xB6E29F65 { return 13 } 74 if s[3] != 0xF3E900DB { return 14 } 75 if s[2] != 0xB9AFF406 { return 15 } 76 if s[1] != 0x4DC4AB2F { return 16 } 77 if s[0] != 0x843ACDA8 { return 17 } 78 79 // ---- Test B: short INTEGER (< 32 bytes -> zero-pad high) ---- 80 // 30 06 02 01 05 02 01 07 (r=5, s=7) 81 let small: *u8 = sys_mmap(32) 82 small[0]=0x30; small[1]=0x06; small[2]=0x02; small[3]=0x01 83 small[4]=0x05; small[5]=0x02; small[6]=0x01; small[7]=0x07 84 let r2: *i64 = u256_alloc() 85 let s2: *i64 = u256_alloc() 86 if nx_ecdsa_sig_parse_der(small, 8, r2, s2) != NX_ECDSA_DER_OK { return 20 } 87 if r2[0] != 5 { return 21 } 88 if s2[0] != 7 { return 22 } 89 var i: i64 = 1 90 while i < 8 { 91 if r2[i] != 0 { return 23 } 92 if s2[i] != 0 { return 24 } 93 i = i + 1 94 } 95 96 // ---- Test C: outer tag != SEQUENCE ---- 97 let bad_outer: *u8 = sys_mmap(16) 98 bad_outer[0]=0x99; bad_outer[1]=0x00 99 if nx_ecdsa_sig_parse_der(bad_outer, 2, r2, s2) != NX_ECDSA_DER_BAD_OUTER { return 30 } 100 101 // ---- Test D: r tag != INTEGER ---- 102 let bad_r: *u8 = sys_mmap(16) 103 bad_r[0]=0x30; bad_r[1]=0x02; bad_r[2]=0x99; bad_r[3]=0x00 104 if nx_ecdsa_sig_parse_der(bad_r, 4, r2, s2) != NX_ECDSA_DER_BAD_R { return 40 } 105 106 // ---- Test E: s tag != INTEGER ---- 107 let bad_s: *u8 = sys_mmap(16) 108 bad_s[0]=0x30; bad_s[1]=0x05; bad_s[2]=0x02; bad_s[3]=0x01 109 bad_s[4]=0x05; bad_s[5]=0x99; bad_s[6]=0x00 110 if nx_ecdsa_sig_parse_der(bad_s, 7, r2, s2) != NX_ECDSA_DER_BAD_S { return 50 } 111 112 // ---- Test F: oversized INTEGER (34 bytes) rejected ---- 113 let big_int: *u8 = sys_mmap(64) 114 big_int[0]=0x30; big_int[1]=0x24 // SEQUENCE 36 115 big_int[2]=0x02; big_int[3]=0x22 // INTEGER 34 bytes 116 var bi: i64 = 0 117 while bi < 34 { big_int[4 + bi] = 0xAA as u8; bi = bi + 1 } 118 if nx_ecdsa_sig_parse_der(big_int, 38, r2, s2) != NX_ECDSA_DER_LEN_TOO_BIG { return 60 } 119 120 // ---- Test G: 33-byte INTEGER without leading 0x00 rejected ---- 121 let bad_pad: *u8 = sys_mmap(64) 122 bad_pad[0]=0x30; bad_pad[1]=0x23 // SEQUENCE 35 123 bad_pad[2]=0x02; bad_pad[3]=0x21 // INTEGER 33 bytes 124 bad_pad[4]=0x77 // NOT 0x00 125 bi = 0 126 while bi < 32 { bad_pad[5 + bi] = 0xBB as u8; bi = bi + 1 } 127 if nx_ecdsa_sig_parse_der(bad_pad, 37, r2, s2) != NX_ECDSA_DER_LEN_TOO_BIG { return 70 } 128 129 // ---- Test H: trailing bytes inside outer SEQUENCE rejected ---- 130 // 30 09 02 01 05 02 01 07 02 01 09 (3 INTEGERs instead of 2) 131 let trail: *u8 = sys_mmap(16) 132 trail[0]=0x30; trail[1]=0x09 133 trail[2]=0x02; trail[3]=0x01; trail[4]=0x05 134 trail[5]=0x02; trail[6]=0x01; trail[7]=0x07 135 trail[8]=0x02; trail[9]=0x01; trail[10]=0x09 136 if nx_ecdsa_sig_parse_der(trail, 11, r2, s2) != NX_ECDSA_DER_TRAILING { return 80 } 137 138 // ---- Test I: verdict gate ---- 139 if nx_ecdsa_sig_der_verdict_is_valid(NX_ECDSA_DER_OK) != 1 { return 90 } 140 if nx_ecdsa_sig_der_verdict_is_valid(NX_ECDSA_DER_BAD_OUTER) != 1 { return 91 } 141 if nx_ecdsa_sig_der_verdict_is_valid(NX_ECDSA_DER_BAD_R) != 1 { return 92 } 142 if nx_ecdsa_sig_der_verdict_is_valid(NX_ECDSA_DER_BAD_S) != 1 { return 93 } 143 if nx_ecdsa_sig_der_verdict_is_valid(NX_ECDSA_DER_LEN_TOO_BIG) != 1 { return 94 } 144 if nx_ecdsa_sig_der_verdict_is_valid(NX_ECDSA_DER_TRAILING) != 1 { return 95 } 145 if nx_ecdsa_sig_der_verdict_is_valid(NX_ECDSA_DER_VERDICT_N) != 0 { return 96 } 146 if nx_ecdsa_sig_der_verdict_is_valid(0) != 0 { return 97 } 147 if nx_ecdsa_sig_der_verdict_is_valid(0 - 1) != 0 { return 98 } 148 if nx_ecdsa_sig_der_verdict_is_valid(999) != 0 { return 99 } 149 150 return 0 151}