code wiki / (root) / nx_poly1305_test.nx

nx_poly1305_test.nx source

↩ module page · 89 lines · 3835 B

1// nx_poly1305_test.nx -- RFC 8439 §2.5.2 KAT for Poly1305. 2// 3// Worked example from the spec: 4// Key (hex): 85d6be7857556d337f4452fe42d506a8 5// 0103808afb0db2fd4abff6af4149f51b 6// Message (ASCII): "Cryptographic Forum Research Group" (34 bytes) 7// Expected tag: a8061dc1305136c6c22b8baf0c0127a9 8// 9// Also exercises poly1305_tag_equal for constant-time tag compare 10// (the function TLS Finished verification must use to avoid a 11// timing side-channel that byte-bisects the tag). 12// 13// expect_exit: 0 14// 15// license_tier: ORIGINAL 16 17import "nx_syscalls.nx" 18import "nx_poly1305.nx" 19 20func main() -> i64 { 21 // ---- 32-byte key = r || s per RFC 8439 §2.5.1 ---- 22 let key: *u8 = sys_mmap(64) 23 key[0]=0x85; key[1]=0xd6; key[2]=0xbe; key[3]=0x78 24 key[4]=0x57; key[5]=0x55; key[6]=0x6d; key[7]=0x33 25 key[8]=0x7f; key[9]=0x44; key[10]=0x52; key[11]=0xfe 26 key[12]=0x42; key[13]=0xd5; key[14]=0x06; key[15]=0xa8 27 key[16]=0x01; key[17]=0x03; key[18]=0x80; key[19]=0x8a 28 key[20]=0xfb; key[21]=0x0d; key[22]=0xb2; key[23]=0xfd 29 key[24]=0x4a; key[25]=0xbf; key[26]=0xf6; key[27]=0xaf 30 key[28]=0x41; key[29]=0x49; key[30]=0xf5; key[31]=0x1b 31 32 // ---- 34-byte message "Cryptographic Forum Research Group" ---- 33 let msg: *u8 = sys_mmap(64) 34 msg[0]=0x43; msg[1]=0x72; msg[2]=0x79; msg[3]=0x70 35 msg[4]=0x74; msg[5]=0x6f; msg[6]=0x67; msg[7]=0x72 36 msg[8]=0x61; msg[9]=0x70; msg[10]=0x68; msg[11]=0x69 37 msg[12]=0x63; msg[13]=0x20; msg[14]=0x46; msg[15]=0x6f 38 msg[16]=0x72; msg[17]=0x75; msg[18]=0x6d; msg[19]=0x20 39 msg[20]=0x52; msg[21]=0x65; msg[22]=0x73; msg[23]=0x65 40 msg[24]=0x61; msg[25]=0x72; msg[26]=0x63; msg[27]=0x68 41 msg[28]=0x20; msg[29]=0x47; msg[30]=0x72; msg[31]=0x6f 42 msg[32]=0x75; msg[33]=0x70 43 44 let tag: *u8 = sys_mmap(32) 45 poly1305_mac(key, msg, 34, tag) 46 47 // ---- Verify tag byte-for-byte against RFC 8439 §2.5.2 ---- 48 if (tag[0] & 0xff) != 0xa8 { return 1 } 49 if (tag[1] & 0xff) != 0x06 { return 2 } 50 if (tag[2] & 0xff) != 0x1d { return 3 } 51 if (tag[3] & 0xff) != 0xc1 { return 4 } 52 if (tag[4] & 0xff) != 0x30 { return 5 } 53 if (tag[5] & 0xff) != 0x51 { return 6 } 54 if (tag[6] & 0xff) != 0x36 { return 7 } 55 if (tag[7] & 0xff) != 0xc6 { return 8 } 56 if (tag[8] & 0xff) != 0xc2 { return 9 } 57 if (tag[9] & 0xff) != 0x2b { return 10 } 58 if (tag[10] & 0xff) != 0x8b { return 11 } 59 if (tag[11] & 0xff) != 0xaf { return 12 } 60 if (tag[12] & 0xff) != 0x0c { return 13 } 61 if (tag[13] & 0xff) != 0x01 { return 14 } 62 if (tag[14] & 0xff) != 0x27 { return 15 } 63 if (tag[15] & 0xff) != 0xa9 { return 16 } 64 65 // ---- Constant-time tag compare: equal to expected = 1 ---- 66 let expected: *u8 = sys_mmap(16) 67 expected[0]=0xa8; expected[1]=0x06; expected[2]=0x1d; expected[3]=0xc1 68 expected[4]=0x30; expected[5]=0x51; expected[6]=0x36; expected[7]=0xc6 69 expected[8]=0xc2; expected[9]=0x2b; expected[10]=0x8b; expected[11]=0xaf 70 expected[12]=0x0c; expected[13]=0x01; expected[14]=0x27; expected[15]=0xa9 71 if poly1305_tag_equal(tag, expected) != 1 { return 20 } 72 73 // Flip one bit -> compare returns 0. Defends TLS Finished from 74 // timing-bisect attacks (the lesson from BEAST/Lucky13). 75 expected[7] = expected[7] ^ 1 76 if poly1305_tag_equal(tag, expected) != 0 { return 21 } 77 78 // ---- Empty-message edge case: tag = s mod 2^128 ---- 79 let empty: *u8 = sys_mmap(16) 80 let tag_e: *u8 = sys_mmap(16) 81 poly1305_mac(key, empty, 0, tag_e) 82 // Empty message: h = 0, tag = (h + s) mod 2^128 = s. 83 // s bytes 16..31 of key = 01 03 80 8a fb 0d b2 fd 4a bf f6 af 41 49 f5 1b 84 if (tag_e[0] & 0xff) != 0x01 { return 30 } 85 if (tag_e[7] & 0xff) != 0xfd { return 31 } 86 if (tag_e[15] & 0xff) != 0x1b { return 32 } 87 88 return 0 89}