hare

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

authenc.ha (13514B)


      1 // License: MPL-2.0
      2 // (c) 2022 Armin Preiml <apreiml@strohwolke.at>
      3 use bytes;
      4 use errors;
      5 
      6 type sample = struct {
      7 	msg: []u8,
      8 	cipher: []u8,
      9 	additional: []u8,
     10 	key: sessionkey,
     11 	nonce: nonce,
     12 	mac: mac,
     13 };
     14 
     15 // test vector taken from the XChacha20-Poly1305-AEAD draft rfc
     16 const rfcsample: sample = sample {
     17 	msg = [
     18 		0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64,
     19 		0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e,
     20 		0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c,
     21 		0x61, 0x73, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39,
     22 		0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, 0x6f, 0x75,
     23 		0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79,
     24 		0x6f, 0x75, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e,
     25 		0x65, 0x20, 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20,
     26 		0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65,
     27 		0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, 0x63, 0x72, 0x65, 0x65,
     28 		0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65,
     29 		0x20, 0x69, 0x74, 0x2e,
     30 	],
     31 	additional = [
     32 		0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5,
     33 		0xc6, 0xc7,
     34 	],
     35 	key = [
     36 		0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
     37 		0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93,
     38 		0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d,
     39 		0x9e, 0x9f,
     40 	],
     41 	nonce = [
     42 		0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
     43 		0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53,
     44 		0x54, 0x55, 0x56, 0x57,
     45 	],
     46 	cipher = [
     47 		0xbd, 0x6d, 0x17, 0x9d, 0x3e, 0x83, 0xd4, 0x3b, 0x95, 0x76,
     48 		0x57, 0x94, 0x93, 0xc0, 0xe9, 0x39, 0x57, 0x2a, 0x17, 0x00,
     49 		0x25, 0x2b, 0xfa, 0xcc, 0xbe, 0xd2, 0x90, 0x2c, 0x21, 0x39,
     50 		0x6c, 0xbb, 0x73, 0x1c, 0x7f, 0x1b, 0x0b, 0x4a, 0xa6, 0x44,
     51 		0x0b, 0xf3, 0xa8, 0x2f, 0x4e, 0xda, 0x7e, 0x39, 0xae, 0x64,
     52 		0xc6, 0x70, 0x8c, 0x54, 0xc2, 0x16, 0xcb, 0x96, 0xb7, 0x2e,
     53 		0x12, 0x13, 0xb4, 0x52, 0x2f, 0x8c, 0x9b, 0xa4, 0x0d, 0xb5,
     54 		0xd9, 0x45, 0xb1, 0x1b, 0x69, 0xb9, 0x82, 0xc1, 0xbb, 0x9e,
     55 		0x3f, 0x3f, 0xac, 0x2b, 0xc3, 0x69, 0x48, 0x8f, 0x76, 0xb2,
     56 		0x38, 0x35, 0x65, 0xd3, 0xff, 0xf9, 0x21, 0xf9, 0x66, 0x4c,
     57 		0x97, 0x63, 0x7d, 0xa9, 0x76, 0x88, 0x12, 0xf6, 0x15, 0xc6,
     58 		0x8b, 0x13, 0xb5, 0x2e,
     59 	],
     60 	mac = [
     61 		0xc0, 0x87, 0x59, 0x24, 0xc1, 0xc7, 0x98, 0x79, 0x47, 0xde,
     62 		0xaf, 0xd8, 0x78, 0x0a, 0xcf, 0x49,
     63 	],
     64 };
     65 
     66 
     67 const noadsample: sample = sample {
     68 	key = [
     69 		0xdf, 0x23, 0xf4, 0xad, 0xe4, 0x6f, 0xc1, 0x41, 0x36, 0xe6,
     70 		0x63, 0x48, 0x3c, 0xcd, 0x74, 0x56, 0x44, 0x6a, 0x56, 0x56,
     71 		0xd8, 0xb4, 0x34, 0x30, 0xd4, 0xfd, 0x7b, 0xa8, 0x2c, 0x60,
     72 		0xf7, 0x62,
     73 	],
     74 	msg = [
     75 		0x9b, 0x0e, 0x38, 0x4b, 0x29, 0x09, 0x8e, 0xa3, 0xb4, 0x37,
     76 		0x7c, 0x81, 0xba, 0xc0, 0xbf, 0x7e, 0x59, 0xc2, 0xdc, 0x0f,
     77 		0x43, 0x03, 0x40, 0x1f, 0xd4, 0x1b, 0xae, 0x69, 0xfd, 0x0f,
     78 		0x0f, 0x49, 0xc8, 0xef, 0xa2, 0x30, 0x21, 0x53, 0x4a, 0xfc,
     79 		0x0c, 0xa6, 0xef, 0x3c, 0x34, 0xe9, 0x9c, 0xc7, 0x8b, 0xd7,
     80 		0xe6, 0x02, 0xcd, 0xc5, 0x28, 0x43, 0x42, 0xe3, 0xdf, 0x32,
     81 		0xf2, 0x28, 0xd9, 0x09, 0xca, 0xa4, 0x45, 0x19, 0x2a, 0x9e,
     82 		0x2d, 0x99, 0xf1, 0x40, 0x55, 0x2f, 0xb4, 0xe0, 0x04, 0xd8,
     83 		0x3b, 0x2e, 0x1e, 0xed, 0xff, 0xa6, 0x51, 0xd2, 0xe1, 0x22,
     84 	],
     85 	nonce = [
     86 		0xe2, 0x5b, 0x34, 0x1f, 0xc2, 0x8b, 0x6e, 0xc3, 0x37, 0xa0,
     87 		0x92, 0x45, 0xa8, 0xcb, 0x4b, 0x40, 0x3f, 0x24, 0x1c, 0x95,
     88 		0xff, 0x72, 0xea, 0x1d,
     89 	],
     90 	cipher = [
     91 		0x0b, 0xec, 0x57, 0xc8, 0x58, 0xf0, 0xc6, 0xb3, 0x42, 0x94,
     92 		0x86, 0xce, 0xf3, 0x3f, 0x04, 0x19, 0x41, 0xc2, 0xf7, 0xc9,
     93 		0x1f, 0x12, 0x9c, 0xbd, 0x68, 0xa8, 0xf2, 0xbe, 0xd3, 0xf3,
     94 		0x11, 0xea, 0x6e, 0xae, 0x39, 0xca, 0x93, 0x06, 0x99, 0x70,
     95 		0x67, 0xd6, 0xfa, 0xd8, 0x16, 0x4b, 0x2d, 0xf3, 0xb4, 0x73,
     96 		0x22, 0x36, 0x4b, 0x2d, 0xac, 0xd2, 0xaa, 0xab, 0x13, 0x2a,
     97 		0xd7, 0x05, 0x15, 0xbf, 0x18, 0x56, 0x20, 0xdb, 0xa4, 0xbb,
     98 		0x38, 0xa8, 0x8b, 0x0d, 0x12, 0xcc, 0x3b, 0x47, 0x4c, 0xba,
     99 		0x5f, 0x11, 0x75, 0x4e, 0x34, 0x87, 0x14, 0xe9, 0xb1, 0x23,
    100 	],
    101 	mac = [
    102 		0x07, 0x92, 0x76, 0xd8, 0x7c, 0x77, 0x71, 0x4b, 0xa4, 0xf2,
    103 		0x27, 0x66, 0x79, 0xeb, 0x38, 0xc1,
    104 	],
    105 	...
    106 };
    107 
    108 const nomsg: sample = sample {
    109 	key = [
    110 		0x10, 0x28, 0xbe, 0x0e, 0x0e, 0x46, 0x38, 0x0f, 0x12, 0x9f,
    111 		0x56, 0x17, 0x21, 0xb8, 0x65, 0x44, 0x49, 0x0d, 0x48, 0x7a,
    112 		0x46, 0x79, 0x5b, 0x9c, 0x54, 0xfd, 0x42, 0xc4, 0x53, 0x82,
    113 		0x51, 0x14,
    114 	],
    115 	nonce = [
    116 		0x35, 0x54, 0xec, 0x93, 0x4d, 0xd5, 0xdc, 0x90, 0xa2, 0xd3,
    117 		0x72, 0xdc, 0xff, 0x0a, 0x73, 0x32, 0x5f, 0xbd, 0xcc, 0x36,
    118 		0xab, 0x3f, 0x47, 0x1c,
    119 	],
    120 	additional = [
    121 		0xbe, 0x71, 0xf2, 0x86, 0x5a, 0xb9, 0x1b, 0x3c, 0x07, 0x9b,
    122 		0xa3, 0x3a, 0x34, 0xa3, 0x5e, 0x4a, 0x51, 0x34, 0xf5, 0x02,
    123 		0x55, 0xb1, 0x97, 0x1d, 0xd8, 0xb8, 0xb0, 0x63, 0x07, 0x98,
    124 		0x11, 0x7c, 0x4e, 0x40, 0xd1, 0xfe, 0xf7, 0x8d, 0xc8, 0xbc,
    125 		0x45, 0x3c, 0x1f, 0x81, 0x2d, 0xf2, 0x98, 0x88, 0x36, 0x9d,
    126 		0x0d, 0x2f, 0x71, 0xf5, 0xdb, 0x9d, 0x05, 0x5e, 0xc5, 0x4d,
    127 		0x6d, 0xe3, 0xca, 0xbb, 0x46, 0xda, 0x99, 0x41, 0xb1, 0xcd,
    128 		0x4e, 0xdc, 0xa3, 0x82, 0xc1, 0xb7, 0xd3, 0x5b, 0xae, 0x41,
    129 		0x60, 0x6a, 0x59, 0x2e, 0xf9, 0xd3, 0xbf, 0x44, 0x95, 0xbd,
    130 	],
    131 	mac = [
    132 		0xe9, 0x50, 0xd4, 0x3f, 0x0a, 0x84, 0x69, 0x24, 0xa3, 0x9a,
    133 		0xe6, 0x06, 0x29, 0xf8, 0x16, 0xcf,
    134 	],
    135 	...
    136 };
    137 
    138 const nothing: sample = sample {
    139 	key = [
    140 		0xbb, 0xf5, 0xf5, 0x40, 0xd7, 0x21, 0x38, 0x22, 0xe2, 0x82,
    141 		0x34, 0x0e, 0x26, 0xaa, 0x0a, 0xce, 0x94, 0x76, 0xb1, 0xac,
    142 		0x62, 0x50, 0x3f, 0x1a, 0x7c, 0x66, 0x78, 0xb3, 0x86, 0x3e,
    143 		0x4d, 0x4f,
    144 	],
    145 	nonce = [
    146 		0x54, 0xe3, 0xf0, 0xa8, 0x06, 0x86, 0x26, 0xd8, 0xd7, 0x7e,
    147 		0x26, 0x23, 0x3b, 0x95, 0xbf, 0x44, 0x30, 0x9e, 0xf6, 0xe4,
    148 		0x00, 0x65, 0xff, 0x1a,
    149 	],
    150 	mac = [
    151 		0x14, 0x23, 0x9b, 0xb3, 0xa3, 0x35, 0x9a, 0x11, 0x9c, 0x1d,
    152 		0x79, 0x65, 0x4b, 0xe2, 0x2f, 0xaf,
    153 	],
    154 	...
    155 };
    156 
    157 const polyaligned: sample = sample {
    158 	key = [
    159 		0x8a, 0x67, 0xe3, 0x6c, 0x24, 0xbd, 0x05, 0x7f, 0x53, 0x7d,
    160 		0x3b, 0x2d, 0x25, 0x98, 0x7c, 0x21, 0xb1, 0x51, 0x90, 0xdd,
    161 		0x7a, 0x4a, 0x52, 0x49, 0x12, 0x22, 0x3e, 0x7e, 0x2e, 0x0d,
    162 		0x8a, 0x15,
    163 	],
    164 	msg = [
    165 		0xa1, 0x9c, 0x40, 0xbe, 0x6e, 0xf7, 0x43, 0x66, 0xcf, 0xe1,
    166 		0x15, 0xce, 0x0c, 0x90, 0x7c, 0x1f, 0x35, 0xfb, 0x03, 0x7f,
    167 		0x96, 0x62, 0x53, 0xa6, 0xfa, 0xf1, 0x31, 0x39, 0xae, 0x69,
    168 		0x0e, 0xf7,
    169 	],
    170 	nonce = [
    171 		0xc2, 0x16, 0x80, 0x49, 0xd1, 0x82, 0x04, 0xc5, 0x89, 0xee,
    172 		0xbc, 0x24, 0xa0, 0x37, 0x6f, 0xbb, 0x44, 0x09, 0x49, 0x8e,
    173 		0xe2, 0x73, 0x33, 0x4d,
    174 	],
    175 	additional = [
    176 		0xc1, 0xf7, 0xa5, 0xcf, 0x2f, 0xc0, 0x21, 0x55, 0x74, 0xfb,
    177 		0x75, 0xcd, 0x8b, 0x9e, 0xe2, 0x2a,
    178 	],
    179 	cipher = [
    180 		0xfe, 0xe1, 0xb9, 0xff, 0xc5, 0x03, 0x38, 0x73, 0xbb, 0x1c,
    181 		0x90, 0x7b, 0x53, 0x39, 0x65, 0xd7, 0x64, 0x12, 0xe4, 0x88,
    182 		0xa0, 0xaa, 0x8e, 0x11, 0x23, 0xd0, 0x20, 0x8a, 0x54, 0x76,
    183 		0x12, 0x75,
    184 	],
    185 	mac = [
    186 		0x7e, 0x80, 0x2c, 0x34, 0x45, 0x04, 0x5b, 0xff, 0x04, 0x58,
    187 		0x36, 0xef, 0xe2, 0x55, 0xc8, 0x45,
    188 	],
    189 };
    190 
    191 @test fn rfc() void = {
    192 	let result: []u8 = alloc(rfcsample.msg...);
    193 	defer free(result);
    194 
    195 	let b = encrypt(&rfcsample.key, &rfcsample.nonce, result[..],
    196 		rfcsample.additional[..]);
    197 
    198 	assert(bytes::equal(rfcsample.cipher, b.2));
    199 	assert(bytes::equal(rfcsample.nonce, b.1));
    200 	assert(bytes::equal(rfcsample.mac, b.0));
    201 
    202 	const plain = decrypt(&rfcsample.key, &b, rfcsample.additional);
    203 
    204 	assert(plain is []u8);
    205 	assert(bytes::equal(rfcsample.msg, plain as []u8));
    206 };
    207 
    208 @test fn rfcmultiadditonals() void = {
    209 	let result: []u8 = alloc(rfcsample.msg...);
    210 	defer free(result);
    211 
    212 	let b = encrypt(&rfcsample.key, &rfcsample.nonce, result[..],
    213 		rfcsample.additional[..4], rfcsample.additional[4..]);
    214 
    215 	assert(bytes::equal(rfcsample.cipher, b.2));
    216 	assert(bytes::equal(rfcsample.nonce, b.1));
    217 	assert(bytes::equal(rfcsample.mac, b.0));
    218 
    219 	const plain = decrypt(&rfcsample.key, &b, rfcsample.additional);
    220 
    221 	assert(plain is []u8);
    222 	assert(bytes::equal(rfcsample.msg, plain as []u8));
    223 };
    224 
    225 @test fn noadditional() void = {
    226 	let result: []u8 = alloc(noadsample.msg...);
    227 	defer free(result);
    228 
    229 	let b = encrypt(&noadsample.key, &noadsample.nonce, result[..]);
    230 
    231 	assert(bytes::equal(noadsample.cipher, b.2));
    232 	assert(bytes::equal(noadsample.nonce, b.1));
    233 	assert(bytes::equal(noadsample.mac, b.0));
    234 
    235 	const plain = decrypt(&noadsample.key, &b);
    236 
    237 	assert(plain is []u8);
    238 	assert(bytes::equal(noadsample.msg, plain as []u8));
    239 };
    240 
    241 @test fn nomsg() void = {
    242 	let result: []u8 = [];
    243 	defer free(result);
    244 
    245 	let b = encrypt(&nomsg.key, &nomsg.nonce, result[..], nomsg.additional);
    246 
    247 	assert(bytes::equal([], b.2));
    248 	assert(bytes::equal(nomsg.nonce, b.1));
    249 	assert(bytes::equal(nomsg.mac, b.0));
    250 
    251 	const plain = decrypt(&nomsg.key, &b, nomsg.additional);
    252 
    253 	assert(plain is []u8);
    254 	assert(bytes::equal([], plain as []u8));
    255 };
    256 
    257 @test fn nothing() void = {
    258 	let result: []u8 = [];
    259 	defer free(result);
    260 
    261 	let b = encrypt(&nothing.key, &nothing.nonce, result[..]);
    262 
    263 	assert(bytes::equal([], b.2));
    264 	assert(bytes::equal(nothing.nonce, b.1));
    265 	assert(bytes::equal(nothing.mac, b.0));
    266 
    267 	const plain = decrypt(&nothing.key, &b);
    268 
    269 	assert(plain is []u8);
    270 	assert(bytes::equal([], plain as []u8));
    271 };
    272 
    273 @test fn polyaligned() void = {
    274 	let result: []u8 = alloc(polyaligned.msg...);
    275 	defer free(result);
    276 
    277 	let b = encrypt(&polyaligned.key, &polyaligned.nonce, result[..],
    278 		polyaligned.additional[..]);
    279 
    280 	assert(bytes::equal(polyaligned.cipher, b.2));
    281 	assert(bytes::equal(polyaligned.nonce, b.1));
    282 	assert(bytes::equal(polyaligned.mac, b.0));
    283 
    284 	const plain = decrypt(&polyaligned.key, &b, polyaligned.additional);
    285 
    286 	assert(plain is []u8);
    287 	assert(bytes::equal(polyaligned.msg, plain as []u8));
    288 };
    289 
    290 
    291 @test fn invalidkey() void = {
    292 	const zero: [114]u8 = [0...];
    293 
    294 	let key = rfcsample.key;
    295 	key[0] = 0x00;
    296 
    297 	let cipher: []u8 = alloc(rfcsample.cipher...);
    298 	defer free(cipher);
    299 
    300 	let b: box = (rfcsample.mac, rfcsample.nonce, cipher[..]);
    301 
    302 	const plain = decrypt(&key, &b, rfcsample.additional);
    303 
    304 	assert(plain is errors::invalid);
    305 	assert(bytes::equal(zero, cipher));
    306 };
    307 
    308 @test fn invalidcipher() void = {
    309 	const zero: [114]u8 = [0...];
    310 
    311 	let cipher: []u8 = alloc(rfcsample.cipher...);
    312 	defer free(cipher);
    313 	cipher[0] = 0x00;
    314 
    315 	let b: box = (rfcsample.mac, rfcsample.nonce, cipher[..]);
    316 
    317 	const plain = decrypt(&rfcsample.key, &b, rfcsample.additional);
    318 
    319 	assert(plain is errors::invalid);
    320 	assert(bytes::equal(zero, cipher));
    321 };
    322 
    323 @test fn invalidcipher2() void = {
    324 
    325 	let cipher: []u8 = alloc(rfcsample.cipher...);
    326 	defer free(cipher);
    327 	append(cipher, 0xff);
    328 
    329 	let b: box = (rfcsample.mac, rfcsample.nonce, cipher[..]);
    330 
    331 	const plain = decrypt(&rfcsample.key, &b, rfcsample.additional);
    332 
    333 	assert(plain is errors::invalid);
    334 
    335 	const zero: [115]u8 = [0...];
    336 	assert(bytes::equal(zero, cipher));
    337 };
    338 
    339 @test fn invalidcipher3() void = {
    340 	let cipher: []u8 = alloc(rfcsample.cipher...);
    341 	defer free(cipher);
    342 	delete(cipher[len(cipher) - 1]);
    343 
    344 	let b: box = (rfcsample.mac, rfcsample.nonce, cipher[..]);
    345 
    346 	const plain = decrypt(&rfcsample.key, &b, rfcsample.additional);
    347 
    348 	assert(plain is errors::invalid);
    349 
    350 	const zero: [113]u8 = [0...];
    351 	assert(bytes::equal(zero, cipher));
    352 };
    353 
    354 @test fn invalidaddition() void = {
    355 	const zero: [114]u8 = [0...];
    356 
    357 	let cipher: []u8 = alloc(rfcsample.cipher...);
    358 	defer free(cipher);
    359 
    360 	let ad: []u8 = alloc(rfcsample.additional...);
    361 	defer free(ad);
    362 	ad[0] = 0x00;
    363 
    364 	let b: box = (rfcsample.mac, rfcsample.nonce, cipher[..]);
    365 
    366 	const plain = decrypt(&rfcsample.key, &b, ad);
    367 
    368 	assert(plain is errors::invalid);
    369 	assert(bytes::equal(zero, cipher));
    370 };
    371 
    372 @test fn invalidaddition2() void = {
    373 	const zero: [114]u8 = [0...];
    374 
    375 	let cipher: []u8 = alloc(rfcsample.cipher...);
    376 	defer free(cipher);
    377 
    378 	let ad: []u8 = alloc(rfcsample.additional...);
    379 	defer free(ad);
    380 	append(ad, 0xff);
    381 
    382 	let b: box = (rfcsample.mac, rfcsample.nonce, cipher[..]);
    383 
    384 	const plain = decrypt(&rfcsample.key, &b, ad);
    385 
    386 	assert(plain is errors::invalid);
    387 	assert(bytes::equal(zero, cipher));
    388 };
    389 
    390 @test fn invalidaddition3() void = {
    391 	const zero: [114]u8 = [0...];
    392 
    393 	let cipher: []u8 = alloc(rfcsample.cipher...);
    394 	defer free(cipher);
    395 
    396 	let ad: []u8 = alloc(rfcsample.additional...);
    397 	defer free(ad);
    398 	delete(ad[len(ad) - 1]);
    399 
    400 	let b: box = (rfcsample.mac, rfcsample.nonce, cipher[..]);
    401 
    402 	const plain = decrypt(&rfcsample.key, &b, ad);
    403 
    404 	assert(plain is errors::invalid);
    405 	assert(bytes::equal(zero, cipher));
    406 };
    407 
    408 @test fn invalidaddition4() void = {
    409 	const zero: [114]u8 = [0...];
    410 
    411 	let cipher: []u8 = alloc(rfcsample.cipher...);
    412 	defer free(cipher);
    413 
    414 	let b: box = (rfcsample.mac, rfcsample.nonce, cipher[..]);
    415 
    416 	const plain = decrypt(&rfcsample.key, &b);
    417 
    418 	assert(plain is errors::invalid);
    419 	assert(bytes::equal(zero, cipher));
    420 };
    421 
    422 @test fn invalidaddition5() void = {
    423 	const zero: [114]u8 = [0...];
    424 
    425 	let cipher: []u8 = alloc(rfcsample.cipher...);
    426 	defer free(cipher);
    427 
    428 	let b: box = (rfcsample.mac, rfcsample.nonce, cipher[..]);
    429 
    430 	const plain = decrypt(&rfcsample.key, &b, rfcsample.additional, [0xff]);
    431 
    432 	assert(plain is errors::invalid);
    433 	assert(bytes::equal(zero, cipher));
    434 };
    435 
    436 @test fn cipheradditionswap() void = {
    437 	let additional: []u8 = alloc(rfcsample.additional...);
    438 	defer free(additional);
    439 
    440 	let b: box = (rfcsample.mac, rfcsample.nonce, additional);
    441 
    442 	const plain = decrypt(&rfcsample.key, &b, rfcsample.cipher);
    443 
    444 	assert(plain is errors::invalid);
    445 
    446 	const zero: [12]u8 = [0...];
    447 	assert(bytes::equal(zero, additional));
    448 };
    449 
    450 @test fn invalidmac() void = {
    451 	const zero: [114]u8 = [0...];
    452 
    453 	let cipher: []u8 = alloc(rfcsample.cipher...);
    454 	defer free(cipher);
    455 
    456 	let mac: mac = rfcsample.mac;
    457 	mac[0] = 0xff;
    458 
    459 	let b: box = (mac, rfcsample.nonce, cipher[..]);
    460 
    461 	const plain = decrypt(&rfcsample.key, &b, rfcsample.additional);
    462 
    463 	assert(plain is errors::invalid);
    464 	assert(bytes::equal(zero, cipher));
    465 };