hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

+test.ha (8356B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use bytes;
      5 use io;
      6 use memio;
      7 
      8 // test vector taken from rfc8439
      9 @test fn chacha20() void = {
     10 	const key: [_]u8 = [
     11 		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
     12 		0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
     13 		0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
     14 		0x1e, 0x1f,
     15 	];
     16 	const nonce: [_]u8 = [
     17 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00,
     18 		0x00, 0x00
     19 	];
     20 	const msg: [_]u8 = [
     21 		0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64,
     22 		0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e,
     23 		0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c,
     24 		0x61, 0x73, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39,
     25 		0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, 0x6f, 0x75,
     26 		0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79,
     27 		0x6f, 0x75, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e,
     28 		0x65, 0x20, 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20,
     29 		0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65,
     30 		0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, 0x63, 0x72, 0x65, 0x65,
     31 		0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65,
     32 		0x20, 0x69, 0x74, 0x2e,
     33 	];
     34 	const cipher: [_]u8 = [
     35 		0x6e, 0x2e, 0x35, 0x9a, 0x25, 0x68, 0xf9, 0x80, 0x41, 0xba,
     36 		0x07, 0x28, 0xdd, 0x0d, 0x69, 0x81, 0xe9, 0x7e, 0x7a, 0xec,
     37 		0x1d, 0x43, 0x60, 0xc2, 0x0a, 0x27, 0xaf, 0xcc, 0xfd, 0x9f,
     38 		0xae, 0x0b, 0xf9, 0x1b, 0x65, 0xc5, 0x52, 0x47, 0x33, 0xab,
     39 		0x8f, 0x59, 0x3d, 0xab, 0xcd, 0x62, 0xb3, 0x57, 0x16, 0x39,
     40 		0xd6, 0x24, 0xe6, 0x51, 0x52, 0xab, 0x8f, 0x53, 0x0c, 0x35,
     41 		0x9f, 0x08, 0x61, 0xd8, 0x07, 0xca, 0x0d, 0xbf, 0x50, 0x0d,
     42 		0x6a, 0x61, 0x56, 0xa3, 0x8e, 0x08, 0x8a, 0x22, 0xb6, 0x5e,
     43 		0x52, 0xbc, 0x51, 0x4d, 0x16, 0xcc, 0xf8, 0x06, 0x81, 0x8c,
     44 		0xe9, 0x1a, 0xb7, 0x79, 0x37, 0x36, 0x5a, 0xf9, 0x0b, 0xbf,
     45 		0x74, 0xa3, 0x5b, 0xe6, 0xb4, 0x0b, 0x8e, 0xed, 0xf2, 0x78,
     46 		0x5e, 0x42, 0x87, 0x4d,
     47 	];
     48 
     49 	let result: [114]u8 = [0...];
     50 
     51 	let cipherbuf = memio::fixed(result);
     52 
     53 	let c = chacha20();
     54 	defer io::close(&c)!;
     55 
     56 	chacha20_init(&c, &cipherbuf, key, nonce);
     57 	setctr(&c, 1);
     58 
     59 	const n = io::writeall(&c, msg)!;
     60 	assert(n == len(msg));
     61 	assert(bytes::equal(cipher, result));
     62 
     63 	result = [0...];
     64 	cipherbuf = memio::fixed(result);
     65 
     66 	chacha20_init(&c, &cipherbuf, key, nonce);
     67 	setctr(&c, 1);
     68 	io::write(&c, msg[..10])!;
     69 	io::write(&c, msg[10..63])!;
     70 	io::writeall(&c, msg[63..])!;
     71 	assert(bytes::equal(cipher, result));
     72 };
     73 
     74 // test vector taken from xchacha20 rfc
     75 const xkey: [_]u8 = [
     76 	0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
     77 	0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93,
     78 	0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d,
     79 	0x9e, 0x9f,
     80 ];
     81 const xnonce: [_]u8 = [
     82 	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
     83 	0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53,
     84 	0x54, 0x55, 0x56, 0x58,
     85 ];
     86 
     87 const xmsg: [_]u8 = [
     88 	0x54, 0x68, 0x65, 0x20, 0x64, 0x68, 0x6f, 0x6c, 0x65, 0x20,
     89 	0x28, 0x70, 0x72, 0x6f, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65,
     90 	0x64, 0x20, 0x22, 0x64, 0x6f, 0x6c, 0x65, 0x22, 0x29, 0x20,
     91 	0x69, 0x73, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x6b, 0x6e,
     92 	0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65,
     93 	0x20, 0x41, 0x73, 0x69, 0x61, 0x74, 0x69, 0x63, 0x20, 0x77,
     94 	0x69, 0x6c, 0x64, 0x20, 0x64, 0x6f, 0x67, 0x2c, 0x20, 0x72,
     95 	0x65, 0x64, 0x20, 0x64, 0x6f, 0x67, 0x2c, 0x20, 0x61, 0x6e,
     96 	0x64, 0x20, 0x77, 0x68, 0x69, 0x73, 0x74, 0x6c, 0x69, 0x6e,
     97 	0x67, 0x20, 0x64, 0x6f, 0x67, 0x2e, 0x20, 0x49, 0x74, 0x20,
     98 	0x69, 0x73, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x20, 0x74,
     99 	0x68, 0x65, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6f, 0x66,
    100 	0x20, 0x61, 0x20, 0x47, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x20,
    101 	0x73, 0x68, 0x65, 0x70, 0x68, 0x65, 0x72, 0x64, 0x20, 0x62,
    102 	0x75, 0x74, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x73, 0x20, 0x6d,
    103 	0x6f, 0x72, 0x65, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x61,
    104 	0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x2d, 0x6c, 0x65, 0x67, 0x67,
    105 	0x65, 0x64, 0x20, 0x66, 0x6f, 0x78, 0x2e, 0x20, 0x54, 0x68,
    106 	0x69, 0x73, 0x20, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x79, 0x20,
    107 	0x65, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x20, 0x61, 0x6e,
    108 	0x64, 0x20, 0x73, 0x6b, 0x69, 0x6c, 0x6c, 0x65, 0x64, 0x20,
    109 	0x6a, 0x75, 0x6d, 0x70, 0x65, 0x72, 0x20, 0x69, 0x73, 0x20,
    110 	0x63, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x66, 0x69, 0x65, 0x64,
    111 	0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x77, 0x6f, 0x6c, 0x76,
    112 	0x65, 0x73, 0x2c, 0x20, 0x63, 0x6f, 0x79, 0x6f, 0x74, 0x65,
    113 	0x73, 0x2c, 0x20, 0x6a, 0x61, 0x63, 0x6b, 0x61, 0x6c, 0x73,
    114 	0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x6f, 0x78, 0x65,
    115 	0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74,
    116 	0x61, 0x78, 0x6f, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x20, 0x66,
    117 	0x61, 0x6d, 0x69, 0x6c, 0x79, 0x20, 0x43, 0x61, 0x6e, 0x69,
    118 	0x64, 0x61, 0x65, 0x2e,
    119 ];
    120 
    121 const xcipher: [_]u8 = [
    122 	0x7d, 0x0a, 0x2e, 0x6b, 0x7f, 0x7c, 0x65, 0xa2, 0x36, 0x54,
    123 	0x26, 0x30, 0x29, 0x4e, 0x06, 0x3b, 0x7a, 0xb9, 0xb5, 0x55,
    124 	0xa5, 0xd5, 0x14, 0x9a, 0xa2, 0x1e, 0x4a, 0xe1, 0xe4, 0xfb,
    125 	0xce, 0x87, 0xec, 0xc8, 0xe0, 0x8a, 0x8b, 0x5e, 0x35, 0x0a,
    126 	0xbe, 0x62, 0x2b, 0x2f, 0xfa, 0x61, 0x7b, 0x20, 0x2c, 0xfa,
    127 	0xd7, 0x20, 0x32, 0xa3, 0x03, 0x7e, 0x76, 0xff, 0xdc, 0xdc,
    128 	0x43, 0x76, 0xee, 0x05, 0x3a, 0x19, 0x0d, 0x7e, 0x46, 0xca,
    129 	0x1d, 0xe0, 0x41, 0x44, 0x85, 0x03, 0x81, 0xb9, 0xcb, 0x29,
    130 	0xf0, 0x51, 0x91, 0x53, 0x86, 0xb8, 0xa7, 0x10, 0xb8, 0xac,
    131 	0x4d, 0x02, 0x7b, 0x8b, 0x05, 0x0f, 0x7c, 0xba, 0x58, 0x54,
    132 	0xe0, 0x28, 0xd5, 0x64, 0xe4, 0x53, 0xb8, 0xa9, 0x68, 0x82,
    133 	0x41, 0x73, 0xfc, 0x16, 0x48, 0x8b, 0x89, 0x70, 0xca, 0xc8,
    134 	0x28, 0xf1, 0x1a, 0xe5, 0x3c, 0xab, 0xd2, 0x01, 0x12, 0xf8,
    135 	0x71, 0x07, 0xdf, 0x24, 0xee, 0x61, 0x83, 0xd2, 0x27, 0x4f,
    136 	0xe4, 0xc8, 0xb1, 0x48, 0x55, 0x34, 0xef, 0x2c, 0x5f, 0xbc,
    137 	0x1e, 0xc2, 0x4b, 0xfc, 0x36, 0x63, 0xef, 0xaa, 0x08, 0xbc,
    138 	0x04, 0x7d, 0x29, 0xd2, 0x50, 0x43, 0x53, 0x2d, 0xb8, 0x39,
    139 	0x1a, 0x8a, 0x3d, 0x77, 0x6b, 0xf4, 0x37, 0x2a, 0x69, 0x55,
    140 	0x82, 0x7c, 0xcb, 0x0c, 0xdd, 0x4a, 0xf4, 0x03, 0xa7, 0xce,
    141 	0x4c, 0x63, 0xd5, 0x95, 0xc7, 0x5a, 0x43, 0xe0, 0x45, 0xf0,
    142 	0xcc, 0xe1, 0xf2, 0x9c, 0x8b, 0x93, 0xbd, 0x65, 0xaf, 0xc5,
    143 	0x97, 0x49, 0x22, 0xf2, 0x14, 0xa4, 0x0b, 0x7c, 0x40, 0x2c,
    144 	0xdb, 0x91, 0xae, 0x73, 0xc0, 0xb6, 0x36, 0x15, 0xcd, 0xad,
    145 	0x04, 0x80, 0x68, 0x0f, 0x16, 0x51, 0x5a, 0x7a, 0xce, 0x9d,
    146 	0x39, 0x23, 0x64, 0x64, 0x32, 0x8a, 0x37, 0x74, 0x3f, 0xfc,
    147 	0x28, 0xf4, 0xdd, 0xb3, 0x24, 0xf4, 0xd0, 0xf5, 0xbb, 0xdc,
    148 	0x27, 0x0c, 0x65, 0xb1, 0x74, 0x9a, 0x6e, 0xff, 0xf1, 0xfb,
    149 	0xaa, 0x09, 0x53, 0x61, 0x75, 0xcc, 0xd2, 0x9f, 0xb9, 0xe6,
    150 	0x05, 0x7b, 0x30, 0x73, 0x20, 0xd3, 0x16, 0x83, 0x8a, 0x9c,
    151 	0x71, 0xf7, 0x0b, 0x5b, 0x59, 0x07, 0xa6, 0x6f, 0x7e, 0xa4,
    152 	0x9a, 0xad, 0xc4, 0x09,
    153 ];
    154 
    155 
    156 @test fn xchacha20() void = {
    157 	let result: [304]u8 = [0...];
    158 	let cipherbuf = memio::fixed(result);
    159 
    160 	let c = chacha20();
    161 	defer io::close(&c)!;
    162 
    163 	xchacha20_init(&c, &cipherbuf, xkey, xnonce);
    164 	setctr(&c, 1);
    165 
    166 	io::writeall(&c, xmsg)!;
    167 	assert(bytes::equal(xcipher, result));
    168 };
    169 
    170 @test fn skipblocks() void = {
    171 	let result: [18]u8 = [0...];
    172 	let cipherbuf = memio::fixed(result);
    173 
    174 	let c = chacha20();
    175 	defer io::close(&c)!;
    176 
    177 	xchacha20_init(&c, &cipherbuf, xkey, xnonce);
    178 
    179 	// just encrypt a few bytes of each block, to check if setctr works
    180 	setctr(&c, 1);
    181 	io::writeall(&c, xmsg[..5])!;
    182 
    183 	setctr(&c, 2);
    184 	io::writeall(&c, xmsg[64..70])!;
    185 
    186 	setctr(&c, 3);
    187 	io::writeall(&c, xmsg[128..135])!;
    188 
    189 	assert(bytes::equal(result[..5], xcipher[..5]));
    190 	assert(bytes::equal(result[5..11], xcipher[64..70]));
    191 	assert(bytes::equal(result[11..], xcipher[128..135]));
    192 };
    193 
    194 // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha-03#section-2.2.1
    195 @test fn hchacha20() void = {
    196 	const key: [_]u8 = [
    197 		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
    198 		0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
    199 		0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
    200 		0x1e, 0x1f,
    201 	];
    202 	const nonce: [_]u8 = [
    203 		0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00,
    204 		0x00, 0x00, 0x31, 0x41, 0x59, 0x27,
    205 	];
    206 	const expected: [_]u8 = [
    207 		0x82, 0x41, 0x3b, 0x42, 0x27, 0xb2, 0x7b, 0xfe, 0xd3, 0x0e,
    208 		0x42, 0x50, 0x8a, 0x87, 0x7d, 0x73, 0xa0, 0xf9, 0xe4, 0xd5,
    209 		0x8a, 0x74, 0xa8, 0x53, 0xc1, 0x2e, 0xc4, 0x13, 0x26, 0xd3,
    210 		0xec, 0xdc,
    211 	];
    212 
    213 	let out: [32]u8 = [0...];
    214 	hchacha20(&out, key, nonce);
    215 	assert(bytes::equal(out, expected));
    216 };