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