egra: better selectors (they can be customised with return type now, and has proper...
[iv.d.git] / stc / testing.d
blob849668e0138bbfab1d4c0c257aa55877a9c285ac
1 /*
2 * Stream cipher testing support.
3 * Copyright (C) 2014 Ketmar Dark // Invisible Vector (ketmar@ketmar.no-ip.org)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * Get a copy of the GNU GPL from <http://www.gnu.org/licenses/>.
16 module iv.stc.testing /*is aliced*/;
18 import iv.alice;
19 import std.stdio;
20 import std.range;
23 public uint count = 0;
25 public void test(alias T) (const(ubyte)[] key, const(ubyte)[] iv, const(ubyte)[] output, bool big=false) {
26 ubyte[] res = new ubyte[!big ? 512 : 131072];
27 auto ctx = T(key, iv);
28 ctx.process(res, res);
29 if (!big) {
30 assert(res[0..64] == output[0..64]);
31 assert(res[192..256] == output[64..128]);
32 assert(res[256..320] == output[128..192]);
33 assert(res[448..512] == output[192..256]);
34 } else {
35 assert(res[0..64] == output[0..64]);
36 assert(res[65472..65536] == output[64..128]);
37 assert(res[65536..65600] == output[128..192]);
38 assert(res[131008..131072] == output[192..256]);
40 ++count;
44 public void processTVFile(alias T) (string tvs) {
45 import std.algorithm;
46 import std.string;
47 ubyte[32] key = void;
48 ubyte[32] iv = void;
49 ubyte[256] output = void;
51 void skipSpaces () {
52 usize pos = 0;
53 while (pos < tvs.length && (tvs[pos] == ' ' || tvs[pos] == '\t' || tvs[pos] == '\n' || tvs[pos] == '\r')) ++pos;
54 tvs = tvs[pos..$];
57 usize h2x (ubyte[] arr, int len=16) {
58 usize pos = 0;
59 while (tvs.length) {
60 if (tvs[0] < '0' || (tvs[0] > '9' && tvs[0] < 'A') || tvs[0] > 'F') break;
61 uint n0 = tvs[0]-'0';
62 if (n0 > 9) n0 -= 'A'-'9'-1;
63 uint n1 = tvs[1]-'0';
64 if (n1 > 9) n1 -= 'A'-'9'-1;
65 arr[pos++] = cast(ubyte)(n0*16+n1);
66 tvs = tvs[2..$];
67 if (len != 666) {
68 --len;
69 assert(len >= 0);
72 assert(len == 666 || len == 0);
73 skipSpaces();
74 return pos;
77 static immutable string[3][2] ranges = [
78 ["stream[192..255] = ",
79 "stream[256..319] = ",
80 "stream[448..511] = "],
81 ["stream[65472..65535] = ",
82 "stream[65536..65599] = ",
83 "stream[131008..131071] = "]
86 auto xpos = tvs.indexOf("\nSet ");
87 while (xpos >= 0) {
88 usize keylen, ivlen;
89 int rng = 0;
90 // key
91 xpos = tvs.indexOf("key = ");
92 tvs = tvs[xpos+6..$];
93 keylen = h2x(key, 666);
94 if (!tvs.startsWith("IV = ")) {
95 // 256-bit key
96 keylen += h2x(key[keylen..$], 666);
98 // iv
99 assert(tvs.skipOver("IV = "));
100 ivlen = h2x(iv, 666);
101 // first stream part
102 assert(tvs.skipOver("stream[0..63] = "));
103 h2x(output[0*16..$]);
104 h2x(output[1*16..$]);
105 h2x(output[2*16..$]);
106 h2x(output[3*16..$]);
107 rng = (tvs.startsWith(ranges[0][0]) ? 0 : 1);
108 for (usize f = 1; f < 4; ++f) {
109 assert(tvs.skipOver(ranges[rng][f-1]));
110 h2x(output[64*f+0*16..$]);
111 h2x(output[64*f+1*16..$]);
112 h2x(output[64*f+2*16..$]);
113 h2x(output[64*f+3*16..$]);
115 test!T(key[0..keylen], iv[0..ivlen], output, (rng > 0));
116 xpos = tvs.indexOf("\nSet ");