forked from moserware/AES-Illustrated
-
Notifications
You must be signed in to change notification settings - Fork 0
/
NistKnownAnswerTestVectors.cs
88 lines (76 loc) · 3.31 KB
/
NistKnownAnswerTestVectors.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
using System;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography;
using Moserware.AesIllustrated.Transforms;
namespace Moserware.AesIllustrated
{
/// <summary>
/// Checks compliance against NIST Known Answer Test (KAT) Test Vectors.
/// </summary>
internal static class NistKnownAnswerTestVectors
{
public static void VerifyAllTestVectors()
{
int totalVectors = 0;
foreach (string file in Directory.GetFiles(ProjectPaths.NistKnownAnswerTestVectorsDirectory, "*.txt"))
{
if (!NistKnownAnswerTestFileParser.IsValidTestFileName(file))
{
continue;
}
foreach (var vector in NistKnownAnswerTestFileParser.Parse(file))
{
totalVectors++;
switch (vector.Operation)
{
case NistKnownAnswerTestOperation.Encrypt:
VerifyEncrypt(vector);
break;
case NistKnownAnswerTestOperation.Decrypt:
VerifyDecrypt(vector);
break;
}
}
}
Console.WriteLine("{0} vectors passed!", totalVectors);
}
private static void VerifyDecrypt(NistKnownAnswerTestVector vector)
{
var rijndael = new Rijndael(vector.Key);
int feedbackSize = vector.BitLength < 128 ? 8 : vector.BitLength;
var transform = RijndaelDecryptionTransformFactory.Create(rijndael, vector.CipherMode, vector.IV,
feedbackSize, PaddingMode.None);
byte[] output = new byte[vector.Ciphertext.Length];
transform.TransformBlock(vector.Ciphertext, 0, vector.Ciphertext.Length, output, 0);
AssertBytesEqual(vector.Plaintext, output, vector.BitLength);
}
private static void VerifyEncrypt(NistKnownAnswerTestVector vector)
{
var rijndael = new Rijndael(vector.Key);
int feedbackSize = vector.BitLength < 128 ? 8 : vector.BitLength;
var transform = RijndaelEncryptionTransformFactory.Create(rijndael, vector.CipherMode, vector.IV,
feedbackSize, PaddingMode.None);
byte[] output = transform.TransformFinalBlock(vector.Plaintext, 0, vector.Plaintext.Length);
AssertBytesEqual(vector.Ciphertext, output, vector.BitLength);
}
private static void AssertBytesEqual(byte[] expected, byte[] actual, int bitLength)
{
if (bitLength > 1)
{
ByteUtilities.AssertBytesEqual(expected, actual);
}
else
{
// special case CFB test vectors that do 1 bit at a time, just treat as a byte.
bool actualFirstBit = (actual[0] & 0x80) == 0x80;
bool expectedBit = (expected[0] != 0);
if (actualFirstBit != expectedBit)
{
Debugger.Break();
throw new CryptographicException("Bytes were not what was expected");
}
}
}
}
}