| ... | ... | @@ -228,12 +228,12 @@ pub const Aead = struct { |
| 228 | 228 | } |
| 229 | 229 | |
| 230 | 230 | /// c: ciphertext: output buffer should be of size m.len |
| 231 | | /// at: authentication tag: output MAC |
| 231 | /// tag: authentication tag: output MAC |
| 232 | 232 | /// m: message |
| 233 | 233 | /// ad: Associated Data |
| 234 | 234 | /// npub: public nonce |
| 235 | 235 | /// k: private key |
| 236 | | pub fn encrypt(c: []u8, at: *[tag_length]u8, m: []const u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) void { |
| 236 | pub fn encrypt(c: []u8, tag: *[tag_length]u8, m: []const u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) void { |
| 237 | 237 | assert(c.len == m.len); |
| 238 | 238 | |
| 239 | 239 | var state = Aead.init(ad, npub, k); |
| ... | ... | @@ -269,17 +269,17 @@ pub const Aead = struct { |
| 269 | 269 | |
| 270 | 270 | // After the final non-full block of plaintext, the first 16 bytes |
| 271 | 271 | // of the state are output as an authentication tag. |
| 272 | | std.mem.copy(u8, at, buf[0..State.RATE]); |
| 272 | std.mem.copy(u8, tag, buf[0..State.RATE]); |
| 273 | 273 | } |
| 274 | 274 | |
| 275 | 275 | /// m: message: output buffer should be of size c.len |
| 276 | 276 | /// c: ciphertext |
| 277 | | /// at: authentication tag |
| 277 | /// tag: authentication tag |
| 278 | 278 | /// ad: Associated Data |
| 279 | 279 | /// npub: public nonce |
| 280 | 280 | /// k: private key |
| 281 | 281 | /// NOTE: the check of the authentication tag is currently not done in constant time |
| 282 | | pub fn decrypt(m: []u8, c: []const u8, at: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) !void { |
| 282 | pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) !void { |
| 283 | 283 | assert(c.len == m.len); |
| 284 | 284 | |
| 285 | 285 | var state = Aead.init(ad, npub, k); |
| ... | ... | @@ -312,7 +312,7 @@ pub const Aead = struct { |
| 312 | 312 | // After the final non-full block of plaintext, the first 16 bytes |
| 313 | 313 | // of the state are the authentication tag. |
| 314 | 314 | // TODO: use a constant-time equality check here, see https://github.com/ziglang/zig/issues/1776 |
| 315 | | if (!mem.eql(u8, buf[0..State.RATE], &at)) { |
| 315 | if (!mem.eql(u8, buf[0..State.RATE], &tag)) { |
| 316 | 316 | @memset(m.ptr, undefined, m.len); |
| 317 | 317 | return error.InvalidMessage; |
| 318 | 318 | } |
| ... | ... | @@ -332,13 +332,13 @@ test "cipher" { |
| 332 | 332 | const pt: [0]u8 = undefined; |
| 333 | 333 | |
| 334 | 334 | var ct: [pt.len]u8 = undefined; |
| 335 | | var at: [16]u8 = undefined; |
| 336 | | Aead.encrypt(&ct, &at, &pt, &ad, nonce, key); |
| 335 | var tag: [16]u8 = undefined; |
| 336 | Aead.encrypt(&ct, &tag, &pt, &ad, nonce, key); |
| 337 | 337 | htest.assertEqual("", &ct); |
| 338 | | htest.assertEqual("14DA9BB7120BF58B985A8E00FDEBA15B", &at); |
| 338 | htest.assertEqual("14DA9BB7120BF58B985A8E00FDEBA15B", &tag); |
| 339 | 339 | |
| 340 | 340 | var pt2: [pt.len]u8 = undefined; |
| 341 | | try Aead.decrypt(&pt2, &ct, at, &ad, nonce, key); |
| 341 | try Aead.decrypt(&pt2, &ct, tag, &ad, nonce, key); |
| 342 | 342 | testing.expectEqualSlices(u8, &pt, &pt2); |
| 343 | 343 | } |
| 344 | 344 | { // test vector (34) from NIST KAT submission. |
| ... | ... | @@ -347,13 +347,13 @@ test "cipher" { |
| 347 | 347 | try std.fmt.hexToBytes(&pt, "00"); |
| 348 | 348 | |
| 349 | 349 | var ct: [pt.len]u8 = undefined; |
| 350 | | var at: [16]u8 = undefined; |
| 351 | | Aead.encrypt(&ct, &at, &pt, &ad, nonce, key); |
| 350 | var tag: [16]u8 = undefined; |
| 351 | Aead.encrypt(&ct, &tag, &pt, &ad, nonce, key); |
| 352 | 352 | htest.assertEqual("7F", &ct); |
| 353 | | htest.assertEqual("80492C317B1CD58A1EDC3A0D3E9876FC", &at); |
| 353 | htest.assertEqual("80492C317B1CD58A1EDC3A0D3E9876FC", &tag); |
| 354 | 354 | |
| 355 | 355 | var pt2: [pt.len]u8 = undefined; |
| 356 | | try Aead.decrypt(&pt2, &ct, at, &ad, nonce, key); |
| 356 | try Aead.decrypt(&pt2, &ct, tag, &ad, nonce, key); |
| 357 | 357 | testing.expectEqualSlices(u8, &pt, &pt2); |
| 358 | 358 | } |
| 359 | 359 | { // test vector (106) from NIST KAT submission. |
| ... | ... | @@ -363,13 +363,13 @@ test "cipher" { |
| 363 | 363 | try std.fmt.hexToBytes(&pt, "000102"); |
| 364 | 364 | |
| 365 | 365 | var ct: [pt.len]u8 = undefined; |
| 366 | | var at: [16]u8 = undefined; |
| 367 | | Aead.encrypt(&ct, &at, &pt, &ad, nonce, key); |
| 366 | var tag: [16]u8 = undefined; |
| 367 | Aead.encrypt(&ct, &tag, &pt, &ad, nonce, key); |
| 368 | 368 | htest.assertEqual("484D35", &ct); |
| 369 | | htest.assertEqual("030BBEA23B61C00CED60A923BDCF9147", &at); |
| 369 | htest.assertEqual("030BBEA23B61C00CED60A923BDCF9147", &tag); |
| 370 | 370 | |
| 371 | 371 | var pt2: [pt.len]u8 = undefined; |
| 372 | | try Aead.decrypt(&pt2, &ct, at, &ad, nonce, key); |
| 372 | try Aead.decrypt(&pt2, &ct, tag, &ad, nonce, key); |
| 373 | 373 | testing.expectEqualSlices(u8, &pt, &pt2); |
| 374 | 374 | } |
| 375 | 375 | { // test vector (790) from NIST KAT submission. |
| ... | ... | @@ -379,13 +379,13 @@ test "cipher" { |
| 379 | 379 | try std.fmt.hexToBytes(&pt, "000102030405060708090A0B0C0D0E0F10111213141516"); |
| 380 | 380 | |
| 381 | 381 | var ct: [pt.len]u8 = undefined; |
| 382 | | var at: [16]u8 = undefined; |
| 383 | | Aead.encrypt(&ct, &at, &pt, &ad, nonce, key); |
| 382 | var tag: [16]u8 = undefined; |
| 383 | Aead.encrypt(&ct, &tag, &pt, &ad, nonce, key); |
| 384 | 384 | htest.assertEqual("6815B4A0ECDAD01596EAD87D9E690697475D234C6A13D1", &ct); |
| 385 | | htest.assertEqual("DFE23F1642508290D68245279558B2FB", &at); |
| 385 | htest.assertEqual("DFE23F1642508290D68245279558B2FB", &tag); |
| 386 | 386 | |
| 387 | 387 | var pt2: [pt.len]u8 = undefined; |
| 388 | | try Aead.decrypt(&pt2, &ct, at, &ad, nonce, key); |
| 388 | try Aead.decrypt(&pt2, &ct, tag, &ad, nonce, key); |
| 389 | 389 | testing.expectEqualSlices(u8, &pt, &pt2); |
| 390 | 390 | } |
| 391 | 391 | { // test vector (1057) from NIST KAT submission. |
| ... | ... | @@ -394,13 +394,13 @@ test "cipher" { |
| 394 | 394 | try std.fmt.hexToBytes(&pt, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"); |
| 395 | 395 | |
| 396 | 396 | var ct: [pt.len]u8 = undefined; |
| 397 | | var at: [16]u8 = undefined; |
| 398 | | Aead.encrypt(&ct, &at, &pt, &ad, nonce, key); |
| 397 | var tag: [16]u8 = undefined; |
| 398 | Aead.encrypt(&ct, &tag, &pt, &ad, nonce, key); |
| 399 | 399 | htest.assertEqual("7F8A2CF4F52AA4D6B2E74105C30A2777B9D0C8AEFDD555DE35861BD3011F652F", &ct); |
| 400 | | htest.assertEqual("7256456FA935AC34BBF55AE135F33257", &at); |
| 400 | htest.assertEqual("7256456FA935AC34BBF55AE135F33257", &tag); |
| 401 | 401 | |
| 402 | 402 | var pt2: [pt.len]u8 = undefined; |
| 403 | | try Aead.decrypt(&pt2, &ct, at, &ad, nonce, key); |
| 403 | try Aead.decrypt(&pt2, &ct, tag, &ad, nonce, key); |
| 404 | 404 | testing.expectEqualSlices(u8, &pt, &pt2); |
| 405 | 405 | } |
| 406 | 406 | } |