+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 };