Files
2025-03-17 00:17:41 +01:00

113 lines
4.0 KiB
Zig

const std = @import("std");
const testing = std.testing;
const serpent = @import("primitive").blockcipher.serpent;
// https://biham.cs.technion.ac.il/Reports/Serpent/Serpent-128-128.verified.test-vectors
test "NESSIE Serpent-128 test vector set 1" {
try test_encryption(
&fromhex(16, "80000000000000000000000000000000"),
&fromhex(16, "00000000000000000000000000000000"),
&fromhex(16, "264e5481eff42a4606abda06c0bfda3d"),
);
try test_encryption(
&fromhex(16, "40000000000000000000000000000000"),
&fromhex(16, "00000000000000000000000000000000"),
&fromhex(16, "4A231B3BC727993407AC6EC8350E8524"),
);
try test_encryption(
&fromhex(16, "20000000000000000000000000000000"),
&fromhex(16, "00000000000000000000000000000000"),
&fromhex(16, "E03269F9E9FD853C7D8156DF14B98D56"),
);
try test_encryption(
&fromhex(16, "10000000000000000000000000000000"),
&fromhex(16, "00000000000000000000000000000000"),
&fromhex(16, "A798181C3081AC59D5BA89754DACC48F"),
);
// TODO: ...
}
test "NESSIE Serpent-128 test vector set 2" {
try test_encryption(
&fromhex(16, "00000000000000000000000000000000"),
&fromhex(16, "80000000000000000000000000000000"),
&fromhex(16, "A3B35DE7C358DDD82644678C64B8BCBB"),
);
try test_encryption(
&fromhex(16, "00000000000000000000000000000000"),
&fromhex(16, "40000000000000000000000000000000"),
&fromhex(16, "04ABCFE4E0AF27FF92A2BB10949D7DD2"),
);
try test_encryption(
&fromhex(16, "00000000000000000000000000000000"),
&fromhex(16, "20000000000000000000000000000000"),
&fromhex(16, "8F773194B78EF2B2740237EF12D08608"),
);
try test_encryption(
&fromhex(16, "00000000000000000000000000000000"),
&fromhex(16, "10000000000000000000000000000000"),
&fromhex(16, "8B1EA69EE8D7C8D95B1DE4A670EC6997"),
);
// TODO: ...
}
test "NESSIE Serpent-128 test vector set 3" {
try test_encryption(
&fromhex(16, "00000000000000000000000000000000"),
&fromhex(16, "00000000000000000000000000000000"),
&fromhex(16, "3620B17AE6A993D09618B8768266BAE9"),
);
try test_encryption(
&fromhex(16, "01010101010101010101010101010101"),
&fromhex(16, "01010101010101010101010101010101"),
&fromhex(16, "5107E36DBE81D9996D1EF7F3656FFC63"),
);
try test_encryption(
&fromhex(16, "02020202020202020202020202020202"),
&fromhex(16, "02020202020202020202020202020202"),
&fromhex(16, "1AE5355487F88F824B6462B45C4C6AA5"),
);
try test_encryption(
&fromhex(16, "03030303030303030303030303030303"),
&fromhex(16, "03030303030303030303030303030303"),
&fromhex(16, "1F830AF7D2A1B18F7A011C6FD0EEE8FB"),
);
// TODO: ...
}
// Helpers
fn test_encryption(key: *const [16]u8, plain: *const [16]u8, cipher: *const [16]u8) !void {
var output: [16]u8 = undefined;
const key_schedule = try serpent.expand_key(key);
serpent.encrypt_block(plain, &output, &key_schedule);
try testing.expectEqualSlices(u8, cipher, &output);
}
// This monstrosity is only temporary...
fn fromhex(L: comptime_int, comptime s: *const [2 * L]u8) [L]u8 {
var result: [L]u8 = undefined;
inline for (0..L) |i| {
result[i] = (if (s[2 * i] >= '0' and s[2 * i] <= '9')
s[2 * i] - '0'
else if (s[2 * i] >= 'a' and s[2 * i] <= 'f')
s[2 * i] - 'a' + 10
else if (s[2 * i] >= 'A' and s[2 * i] <= 'F')
s[2 * i] - 'A' + 10
else
@compileError("Invalid hex string.")) * 16 + (if (s[2 * i + 1] >= '0' and s[2 * i + 1] <= '9')
s[2 * i + 1] - '0'
else if (s[2 * i + 1] >= 'a' and s[2 * i + 1] <= 'f')
s[2 * i + 1] - 'a' + 10
else if (s[2 * i + 1] >= 'A' and s[2 * i + 1] <= 'F')
s[2 * i + 1] - 'A' + 10
else
@compileError("Invalid hex string."));
}
return result;
}