hare

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

gcm.ha (22291B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use bytes;
      5 use crypto::cipher;
      6 use errors;
      7 use io;
      8 use memio;
      9 
     10 type gcmtestcase = struct {
     11 	key: []u8,
     12 	iv: []u8,
     13 	plain: []u8,
     14 	additional: []u8,
     15 	cipher: []u8,
     16 	tag: [16]u8,
     17 };
     18 
     19 // Testcases from Appendix B of https://csrc.nist.rip/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf
     20 const gcmtestcases: []gcmtestcase = [
     21 	gcmtestcase {
     22 		key = [0...]: [16]u8,
     23 		iv = [0...]: [12]u8,
     24 		plain = [],
     25 		cipher = [],
     26 		tag = [
     27 			0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, 0x36,
     28 			0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a,
     29 		],
     30 		...
     31 	},
     32 	gcmtestcase {
     33 		key = [0...]: [16]u8,
     34 		iv = [0...]: [12]u8,
     35 		plain = [0...]: [16]u8,
     36 		cipher = [
     37 			0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, 0xf3,
     38 			0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78,
     39 		],
     40 		tag = [
     41 			0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, 0xf5,
     42 			0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf,
     43 		],
     44 		...
     45 	},
     46 	gcmtestcase {
     47 		key = [
     48 			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d,
     49 			0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
     50 		],
     51 		plain = [
     52 			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5,
     53 			0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7,
     54 			0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30,
     55 			0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95,
     56 			0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49,
     57 			0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d,
     58 			0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2,
     59 			0x55,
     60 		],
     61 		iv = [
     62 			0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde,
     63 			0xca, 0xf8, 0x88,
     64 		],
     65 		cipher = [
     66 			0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b,
     67 			0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, 0xe3, 0xaa,
     68 			0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 0x35, 0xc1, 0x7e,
     69 			0x23, 0x29, 0xac, 0xa1, 0x2e, 0x21, 0xd5, 0x14, 0xb2,
     70 			0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f, 0x6a, 0x5a, 0xac,
     71 			0x84, 0xaa, 0x05, 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a,
     72 			0xac, 0x97, 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59,
     73 			0x85,
     74 		],
     75 		tag = [
     76 			0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, 0x2c,
     77 			0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4,
     78 		],
     79 		...
     80 	},
     81 	gcmtestcase {
     82 		key = [
     83 			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d,
     84 			0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
     85 		],
     86 		plain = [
     87 			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5,
     88 			0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7,
     89 			0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30,
     90 			0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95,
     91 			0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49,
     92 			0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d,
     93 			0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39,
     94 		],
     95 		additional = [
     96 			0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe,
     97 			0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad,
     98 			0xda, 0xd2,
     99 		],
    100 		iv = [
    101 			0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde,
    102 			0xca, 0xf8, 0x88,
    103 		],
    104 		cipher = [
    105 			0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b,
    106 			0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, 0xe3, 0xaa,
    107 			0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 0x35, 0xc1, 0x7e,
    108 			0x23, 0x29, 0xac, 0xa1, 0x2e, 0x21, 0xd5, 0x14, 0xb2,
    109 			0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f, 0x6a, 0x5a, 0xac,
    110 			0x84, 0xaa, 0x05, 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a,
    111 			0xac, 0x97, 0x3d, 0x58, 0xe0, 0x91,
    112 		],
    113 		tag = [
    114 			0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, 0x94,
    115 			0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47,
    116 		],
    117 	},
    118 	gcmtestcase {
    119 		key = [
    120 			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d,
    121 			0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
    122 		],
    123 		plain = [
    124 			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5,
    125 			0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7,
    126 			0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30,
    127 			0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95,
    128 			0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49,
    129 			0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d,
    130 			0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39,
    131 		],
    132 		additional = [
    133 			0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe,
    134 			0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad,
    135 			0xda, 0xd2,
    136 		],
    137 		iv = [
    138 			0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
    139 		],
    140 		cipher = [
    141 			0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, 0x77,
    142 			0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, 0x69, 0x9b,
    143 			0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, 0x37, 0x66, 0xe5,
    144 			0xf9, 0x7b, 0x6c, 0x74, 0x23, 0x73, 0x80, 0x69, 0x00,
    145 			0xe4, 0x9f, 0x24, 0xb2, 0x2b, 0x09, 0x75, 0x44, 0xd4,
    146 			0x89, 0x6b, 0x42, 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac,
    147 			0x0f, 0x07, 0xc2, 0x3f, 0x45, 0x98,
    148 		],
    149 		tag = [
    150 			0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, 0x56,
    151 			0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb,
    152 		],
    153 		...
    154 	},
    155 	gcmtestcase {
    156 		key = [
    157 			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d,
    158 			0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
    159 		],
    160 		plain = [
    161 			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5,
    162 			0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7,
    163 			0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30,
    164 			0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95,
    165 			0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49,
    166 			0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d,
    167 			0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39,
    168 		],
    169 		additional = [
    170 			0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe,
    171 			0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad,
    172 			0xda, 0xd2,
    173 		],
    174 		iv = [
    175 			0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, 0x55,
    176 			0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, 0x6a, 0x7a,
    177 			0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, 0xe4, 0xc3, 0x03,
    178 			0xd2, 0xa3, 0x18, 0xa7, 0x28, 0xc3, 0xc0, 0xc9, 0x51,
    179 			0x56, 0x80, 0x95, 0x39, 0xfc, 0xf0, 0xe2, 0x42, 0x9a,
    180 			0x6b, 0x52, 0x54, 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde,
    181 			0x6a, 0x57, 0xa6, 0x37, 0xb3, 0x9b,
    182 		],
    183 		cipher = [
    184 			0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, 0x03,
    185 			0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, 0xbe, 0x91,
    186 			0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, 0xba, 0x26, 0x2a,
    187 			0x3c, 0xca, 0x7e, 0x2c, 0xa7, 0x01, 0xe4, 0xa9, 0xa4,
    188 			0xfb, 0xa4, 0x3c, 0x90, 0xcc, 0xdc, 0xb2, 0x81, 0xd4,
    189 			0x8c, 0x7c, 0x6f, 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4,
    190 			0x17, 0x03, 0x4c, 0x34, 0xae, 0xe5,
    191 		],
    192 		tag = [
    193 			0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, 0x46,
    194 			0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50,
    195 		],
    196 	},
    197 	gcmtestcase {
    198 		key = [
    199 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    200 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    201 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    202 		],
    203 		iv = [
    204 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    205 			0x00, 0x00, 0x00,
    206 		],
    207 		tag = [
    208 			0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, 0xa0,
    209 			0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35,
    210 		],
    211 		...
    212 	},
    213 	gcmtestcase {
    214 		key = [
    215 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    216 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    217 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    218 		],
    219 		plain = [
    220 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    221 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    222 		],
    223 		iv = [
    224 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    225 			0x00, 0x00, 0x00,
    226 		],
    227 		cipher = [
    228 			0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, 0x1c,
    229 			0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00,
    230 		],
    231 		tag = [
    232 			0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, 0x8e,
    233 			0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb,
    234 		],
    235 		...
    236 	},
    237 	gcmtestcase {
    238 		key = [
    239 			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d,
    240 			0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, 0xfe, 0xff,
    241 			0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
    242 		],
    243 		plain = [
    244 			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5,
    245 			0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7,
    246 			0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30,
    247 			0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95,
    248 			0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49,
    249 			0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d,
    250 			0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2,
    251 			0x55,
    252 		],
    253 		iv = [
    254 			0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde,
    255 			0xca, 0xf8, 0x88,
    256 		],
    257 		cipher = [
    258 			0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, 0xeb,
    259 			0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, 0x85, 0x9e,
    260 			0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, 0x62, 0x85, 0x93,
    261 			0xb4, 0x0c, 0xa1, 0xe1, 0x9c, 0x7d, 0x77, 0x3d, 0x00,
    262 			0xc1, 0x44, 0xc5, 0x25, 0xac, 0x61, 0x9d, 0x18, 0xc8,
    263 			0x4a, 0x3f, 0x47, 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3,
    264 			0x24, 0xd9, 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2,
    265 			0x56,
    266 		],
    267 		tag = [
    268 			0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, 0xb1,
    269 			0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14,
    270 		],
    271 		...
    272 	},
    273 	gcmtestcase {
    274 		key = [
    275 			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d,
    276 			0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, 0xfe, 0xff,
    277 			0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
    278 		],
    279 		plain = [
    280 			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5,
    281 			0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7,
    282 			0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30,
    283 			0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95,
    284 			0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49,
    285 			0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d,
    286 			0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39,
    287 		],
    288 		additional = [
    289 			0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe,
    290 			0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad,
    291 			0xda, 0xd2,
    292 		],
    293 		iv = [
    294 			0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde,
    295 			0xca, 0xf8, 0x88,
    296 		],
    297 		cipher = [
    298 			0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, 0xeb,
    299 			0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, 0x85, 0x9e,
    300 			0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, 0x62, 0x85, 0x93,
    301 			0xb4, 0x0c, 0xa1, 0xe1, 0x9c, 0x7d, 0x77, 0x3d, 0x00,
    302 			0xc1, 0x44, 0xc5, 0x25, 0xac, 0x61, 0x9d, 0x18, 0xc8,
    303 			0x4a, 0x3f, 0x47, 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3,
    304 			0x24, 0xd9, 0xcc, 0xda, 0x27, 0x10,
    305 		],
    306 		tag = [
    307 			0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, 0x37,
    308 			0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c,
    309 		],
    310 		...
    311 	},
    312 	gcmtestcase {
    313 		key = [
    314 			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d,
    315 			0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, 0xfe, 0xff,
    316 			0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
    317 		],
    318 		plain = [
    319 			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5,
    320 			0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7,
    321 			0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30,
    322 			0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95,
    323 			0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49,
    324 			0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d,
    325 			0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39,
    326 		],
    327 		additional = [
    328 			0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe,
    329 			0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad,
    330 			0xda, 0xd2,
    331 		],
    332 		iv = [
    333 			0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
    334 		],
    335 		cipher = [
    336 			0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, 0xed,
    337 			0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, 0xc5, 0x66,
    338 			0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, 0x83, 0x47, 0x28,
    339 			0x0f, 0xc4, 0x50, 0x70, 0x57, 0xfd, 0xdc, 0x29, 0xdf,
    340 			0x9a, 0x47, 0x1f, 0x75, 0xc6, 0x65, 0x41, 0xd4, 0xd4,
    341 			0xda, 0xd1, 0xc9, 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b,
    342 			0x47, 0x3f, 0xa0, 0xf0, 0x62, 0xf7,
    343 		],
    344 		tag = [
    345 			0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, 0x09,
    346 			0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8,
    347 		],
    348 		...
    349 	},
    350 	gcmtestcase {
    351 		key = [
    352 			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d,
    353 			0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, 0xfe, 0xff,
    354 			0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
    355 		],
    356 		plain = [
    357 			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5,
    358 			0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7,
    359 			0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30,
    360 			0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95,
    361 			0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49,
    362 			0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d,
    363 			0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39,
    364 		],
    365 		additional = [
    366 			0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe,
    367 			0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad,
    368 			0xda, 0xd2,
    369 		],
    370 		iv = [
    371 			0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, 0x55,
    372 			0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, 0x6a, 0x7a,
    373 			0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, 0xe4, 0xc3, 0x03,
    374 			0xd2, 0xa3, 0x18, 0xa7, 0x28, 0xc3, 0xc0, 0xc9, 0x51,
    375 			0x56, 0x80, 0x95, 0x39, 0xfc, 0xf0, 0xe2, 0x42, 0x9a,
    376 			0x6b, 0x52, 0x54, 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde,
    377 			0x6a, 0x57, 0xa6, 0x37, 0xb3, 0x9b,
    378 		],
    379 		cipher = [
    380 			0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, 0x48,
    381 			0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, 0x1d, 0xe9,
    382 			0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, 0x6e, 0xf7, 0xb7,
    383 			0x98, 0x28, 0x66, 0x6e, 0x45, 0x81, 0xe7, 0x90, 0x12,
    384 			0xaf, 0x34, 0xdd, 0xd9, 0xe2, 0xf0, 0x37, 0x58, 0x9b,
    385 			0x29, 0x2d, 0xb3, 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa,
    386 			0x22, 0xe7, 0xe9, 0xb7, 0x37, 0x3b,
    387 		],
    388 		tag = [
    389 			0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, 0xb8,
    390 			0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9,
    391 		],
    392 		...
    393 	},
    394 	gcmtestcase {
    395 		key = [
    396 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    397 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    398 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    399 			0x00, 0x00, 0x00, 0x00, 0x00,
    400 		],
    401 		iv = [
    402 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    403 			0x00, 0x00, 0x00,
    404 		],
    405 		tag = [
    406 			0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, 0xa9,
    407 			0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b,
    408 		],
    409 		...
    410 	},
    411 	gcmtestcase {
    412 		key = [
    413 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    414 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    415 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    416 			0x00, 0x00, 0x00, 0x00, 0x00,
    417 		],
    418 		plain = [
    419 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    420 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    421 		],
    422 		iv = [
    423 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    424 			0x00, 0x00, 0x00,
    425 		],
    426 		cipher = [
    427 			0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, 0x07,
    428 			0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18,
    429 		],
    430 		tag = [
    431 			0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, 0x26,
    432 			0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19,
    433 		],
    434 		...
    435 	},
    436 	gcmtestcase {
    437 		key = [
    438 			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d,
    439 			0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, 0xfe, 0xff,
    440 			0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f,
    441 			0x94, 0x67, 0x30, 0x83, 0x08,
    442 		],
    443 		plain = [
    444 			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5,
    445 			0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7,
    446 			0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30,
    447 			0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95,
    448 			0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49,
    449 			0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d,
    450 			0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2,
    451 			0x55,
    452 		],
    453 		iv = [
    454 			0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde,
    455 			0xca, 0xf8, 0x88,
    456 		],
    457 		cipher = [
    458 			0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 0xf4,
    459 			0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, 0x64, 0x3a,
    460 			0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, 0x75, 0x98, 0xa2,
    461 			0xbd, 0x25, 0x55, 0xd1, 0xaa, 0x8c, 0xb0, 0x8e, 0x48,
    462 			0x59, 0x0d, 0xbb, 0x3d, 0xa7, 0xb0, 0x8b, 0x10, 0x56,
    463 			0x82, 0x88, 0x38, 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba,
    464 			0x7a, 0x0a, 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15,
    465 			0xad,
    466 		],
    467 		tag = [
    468 			0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, 0xec,
    469 			0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c,
    470 		],
    471 		...
    472 	},
    473 	gcmtestcase {
    474 		key = [
    475 			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d,
    476 			0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, 0xfe, 0xff,
    477 			0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f,
    478 			0x94, 0x67, 0x30, 0x83, 0x08,
    479 		],
    480 		plain = [
    481 			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5,
    482 			0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7,
    483 			0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30,
    484 			0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95,
    485 			0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49,
    486 			0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d,
    487 			0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39,
    488 		],
    489 		additional = [
    490 			0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe,
    491 			0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad,
    492 			0xda, 0xd2,
    493 		],
    494 		iv = [
    495 			0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde,
    496 			0xca, 0xf8, 0x88,
    497 		],
    498 		cipher = [
    499 			0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 0xf4,
    500 			0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, 0x64, 0x3a,
    501 			0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, 0x75, 0x98, 0xa2,
    502 			0xbd, 0x25, 0x55, 0xd1, 0xaa, 0x8c, 0xb0, 0x8e, 0x48,
    503 			0x59, 0x0d, 0xbb, 0x3d, 0xa7, 0xb0, 0x8b, 0x10, 0x56,
    504 			0x82, 0x88, 0x38, 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba,
    505 			0x7a, 0x0a, 0xbc, 0xc9, 0xf6, 0x62,
    506 		],
    507 		tag = [
    508 			0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, 0xcd,
    509 			0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b,
    510 		],
    511 		...
    512 	},
    513 	gcmtestcase {
    514 		key = [
    515 			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d,
    516 			0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, 0xfe, 0xff,
    517 			0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f,
    518 			0x94, 0x67, 0x30, 0x83, 0x08,
    519 		],
    520 		plain = [
    521 			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5,
    522 			0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7,
    523 			0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30,
    524 			0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95,
    525 			0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49,
    526 			0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d,
    527 			0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39,
    528 		],
    529 		additional = [
    530 			0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe,
    531 			0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad,
    532 			0xda, 0xd2,
    533 		],
    534 		iv = [
    535 			0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
    536 		],
    537 		cipher = [
    538 			0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, 0xae,
    539 			0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, 0xaf, 0x1a,
    540 			0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, 0xc5, 0x2f, 0xf7,
    541 			0xd7, 0x9b, 0xba, 0x9d, 0xe0, 0xfe, 0xb5, 0x82, 0xd3,
    542 			0x39, 0x34, 0xa4, 0xf0, 0x95, 0x4c, 0xc2, 0x36, 0x3b,
    543 			0xc7, 0x3f, 0x78, 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab,
    544 			0xe4, 0x99, 0xf4, 0x7c, 0x9b, 0x1f,
    545 		],
    546 		tag = [
    547 			0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, 0x5e,
    548 			0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2,
    549 		],
    550 		...
    551 	},
    552 	gcmtestcase {
    553 		key = [
    554 			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d,
    555 			0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, 0xfe, 0xff,
    556 			0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f,
    557 			0x94, 0x67, 0x30, 0x83, 0x08,
    558 		],
    559 		plain = [
    560 			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5,
    561 			0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7,
    562 			0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30,
    563 			0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95,
    564 			0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49,
    565 			0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d,
    566 			0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39,
    567 		],
    568 		additional = [
    569 			0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe,
    570 			0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad,
    571 			0xda, 0xd2,
    572 		],
    573 		iv = [
    574 			0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, 0x55,
    575 			0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, 0x6a, 0x7a,
    576 			0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, 0xe4, 0xc3, 0x03,
    577 			0xd2, 0xa3, 0x18, 0xa7, 0x28, 0xc3, 0xc0, 0xc9, 0x51,
    578 			0x56, 0x80, 0x95, 0x39, 0xfc, 0xf0, 0xe2, 0x42, 0x9a,
    579 			0x6b, 0x52, 0x54, 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde,
    580 			0x6a, 0x57, 0xa6, 0x37, 0xb3, 0x9b,
    581 		],
    582 		cipher = [
    583 			0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, 0xf7,
    584 			0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, 0xee, 0xb2,
    585 			0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, 0xa0, 0x58, 0xab,
    586 			0x4f, 0x6f, 0x74, 0x6b, 0xf4, 0x0f, 0xc0, 0xc3, 0xb7,
    587 			0x80, 0xf2, 0x44, 0x45, 0x2d, 0xa3, 0xeb, 0xf1, 0xc5,
    588 			0xd8, 0x2c, 0xde, 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e,
    589 			0xf8, 0x2e, 0x44, 0xae, 0x7e, 0x3f,
    590 		],
    591 		tag = [
    592 			0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, 0xc8,
    593 			0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a,
    594 		],
    595 		...
    596 	},
    597 ];
    598 
    599 @test fn gcm_encrypt() void = {
    600 	for (let i = 0z; i < len(gcmtestcases); i += 1) {
    601 		const t = gcmtestcases[i];
    602 
    603 		let b = ct64();
    604 		ct64_init(&b, t.key);
    605 
    606 		let result: []u8 = if (len(t.cipher) == 0) {
    607 			yield [];
    608 		} else {
    609 			yield alloc([0...], len(t.cipher));
    610 		};
    611 		defer free(result);
    612 		let resultbuf = memio::fixed(result);
    613 
    614 		let gstream = cipher::gcm();
    615 		cipher::gcm_init(&gstream, &resultbuf, &b, t.iv, t.additional);
    616 		defer io::close(&gstream)!;
    617 
    618 		io::writeall(&gstream, t.plain)!;
    619 		let tag: [cipher::GCMTAGSZ]u8 = [0...];
    620 		cipher::gcm_seal(&gstream, tag);
    621 
    622 		assert(bytes::equal(t.cipher, result));
    623 		assert(bytes::equal(t.tag, tag));
    624 	};
    625 };
    626 
    627 @test fn gcm_decrypt() void = {
    628 	for (let i = 0z; i < len(gcmtestcases); i += 1) {
    629 		const t = gcmtestcases[i];
    630 
    631 		let b = ct64();
    632 		ct64_init(&b, t.key);
    633 
    634 		let result: []u8 = if (len(t.cipher) == 0) {
    635 			yield [];
    636 		} else {
    637 			yield alloc([0...], len(t.cipher));
    638 		};
    639 		defer free(result);
    640 		let cipherbuf = memio::fixed(t.cipher);
    641 
    642 		let gstream = cipher::gcm();
    643 		cipher::gcm_init(&gstream, &cipherbuf, &b, t.iv, t.additional);
    644 		defer io::close(&gstream)!;
    645 
    646 		io::readall(&gstream, result)!;
    647 
    648 		assert(bytes::equal(t.plain, result));
    649 		cipher::gcm_verify(&gstream, t.tag)!;
    650 
    651 		let wrongtag: [16]u8 = t.tag;
    652 		wrongtag[0] += 1;
    653 		match (cipher::gcm_verify(&gstream, wrongtag)) {
    654 		case errors::invalid => void;
    655 		case =>
    656 			assert(false);
    657 		};
    658 	};
    659 };
    660 
    661 @test fn gcm_inplace() void = {
    662 	for (let i = 0z; i < len(gcmtestcases); i += 1) {
    663 		const t = gcmtestcases[i];
    664 
    665 		let b = ct64();
    666 		ct64_init(&b, t.key);
    667 
    668 		let result: []u8 = if (len(t.plain) == 0) {
    669 			yield [];
    670 		} else {
    671 			let r: []u8 = alloc([0...], len(t.plain));
    672 			r[..] = t.plain[..];
    673 			yield r;
    674 		};
    675 		defer free(result);
    676 		let resultbuf = memio::fixed(result);
    677 
    678 		let gstream = cipher::gcm();
    679 		// beware: did not close the stream for sake of simplicity
    680 		cipher::gcm_init(&gstream, &resultbuf, &b, t.iv, t.additional);
    681 
    682 		io::writeall(&gstream, result)!;
    683 
    684 		let tag: [cipher::GCMTAGSZ]u8 = [0...];
    685 		cipher::gcm_seal(&gstream, tag);
    686 		assert(bytes::equal(t.cipher, result));
    687 		assert(bytes::equal(t.tag, tag));
    688 
    689 		let resultbuf = memio::fixed(result);
    690 		let gstream = cipher::gcm();
    691 		cipher::gcm_init(&gstream, &resultbuf, &b, t.iv, t.additional);
    692 		io::readall(&gstream, result)!;
    693 
    694 		assert(bytes::equal(t.plain, result));
    695 		cipher::gcm_verify(&gstream, t.tag)!;
    696 	};
    697 };