Ran dfmt
This commit is contained in:
parent
139cbea1c8
commit
91df0c722b
7 changed files with 371 additions and 377 deletions
|
@ -62,6 +62,7 @@ void encrypt(string keyFileName, Cipher cipher, bool armor)
|
||||||
void decrypt(string keyFileName, Cipher cipher, bool armor)
|
void decrypt(string keyFileName, Cipher cipher, bool armor)
|
||||||
{
|
{
|
||||||
import std.range : inputRangeObject, InputRange;
|
import std.range : inputRangeObject, InputRange;
|
||||||
|
|
||||||
immutable key = loadKey(keyFileName, armor);
|
immutable key = loadKey(keyFileName, armor);
|
||||||
immutable ubyte[8] nonce;
|
immutable ubyte[8] nonce;
|
||||||
ubyte[chunkSize] buf;
|
ubyte[chunkSize] buf;
|
||||||
|
@ -127,6 +128,7 @@ ubyte[32] loadKey(string filename, bool armor)
|
||||||
if (armor)
|
if (armor)
|
||||||
{
|
{
|
||||||
import std.string : chomp;
|
import std.string : chomp;
|
||||||
|
|
||||||
key = Base64.decode(keyFile.readln.chomp, temp[]);
|
key = Base64.decode(keyFile.readln.chomp, temp[]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
13
source/app.d
13
source/app.d
|
@ -7,7 +7,8 @@ import actions;
|
||||||
|
|
||||||
int main(string[] args)
|
int main(string[] args)
|
||||||
{
|
{
|
||||||
bool[string] actions = ["genKey" : false, "encrypt" : false, "decrypt" : false, "benchmark" : false];
|
bool[string] actions = ["genKey" : false, "encrypt" : false, "decrypt"
|
||||||
|
: false, "benchmark" : false];
|
||||||
|
|
||||||
Cipher cipher = Cipher.chacha20;
|
Cipher cipher = Cipher.chacha20;
|
||||||
string keyFileName = "symkey.asc";
|
string keyFileName = "symkey.asc";
|
||||||
|
@ -18,11 +19,11 @@ int main(string[] args)
|
||||||
{
|
{
|
||||||
result = getopt(args, std.getopt.config.bundling, "gen-key|g",
|
result = getopt(args, std.getopt.config.bundling, "gen-key|g",
|
||||||
"Generate a new 256 bit key.", &actions["genKey"],
|
"Generate a new 256 bit key.", &actions["genKey"],
|
||||||
"encrypt|e", "Encrypt a message.", &actions["encrypt"],
|
"encrypt|e", "Encrypt a message.", &actions["encrypt"], "decrypt|d",
|
||||||
"decrypt|d", "Decrypt a message.", &actions["decrypt"],
|
"Decrypt a message.", &actions["decrypt"], "benchmark|b",
|
||||||
"benchmark|b", "Perform some benchmarks.", &actions["benchmark"],
|
"Perform some benchmarks.", &actions["benchmark"], "cipher|c",
|
||||||
"cipher|c", "The cipher to use (default: %s).".format(cipher), &cipher, "key|k",
|
"The cipher to use (default: %s).".format(cipher), &cipher,
|
||||||
"The file which contains the key (default: %s).".format(keyFileName),
|
"key|k", "The file which contains the key (default: %s).".format(keyFileName),
|
||||||
&keyFileName, "armor|a", "use ascii-armored I/O.", &armor);
|
&keyFileName, "armor|a", "use ascii-armored I/O.", &armor);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
module bitmanip;
|
module bitmanip;
|
||||||
|
|
||||||
private import std.traits : isUnsigned;
|
private import std.traits : isUnsigned;
|
||||||
|
|
||||||
private import std.bitmanip : nativeToLittleEndian, littleEndianToNative;
|
private import std.bitmanip : nativeToLittleEndian, littleEndianToNative;
|
||||||
|
|
||||||
UIntType rotateLeft(UIntType)(in UIntType val, in size_t len) nothrow @nogc pure @safe
|
UIntType rotateLeft(UIntType)(in UIntType val, in size_t len) nothrow @nogc pure @safe
|
||||||
|
|
|
@ -9,7 +9,6 @@ import std.array;
|
||||||
import bitmanip;
|
import bitmanip;
|
||||||
import utility;
|
import utility;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// TODO: Implement random access
|
// TODO: Implement random access
|
||||||
|
@ -41,11 +40,13 @@ auto chacha20Cipher(R)(R range, ubyte[32] key, ubyte[8] nonce)
|
||||||
assert(!empty);
|
assert(!empty);
|
||||||
if (++chachaCounter == 64)
|
if (++chachaCounter == 64)
|
||||||
{
|
{
|
||||||
chachaSection = chacha20Exp(key, concat!(ubyte[16])(nonce, littleEndianInv(++count)));
|
chachaSection = chacha20Exp(key, concat!(ubyte[16])(nonce,
|
||||||
|
littleEndianInv(++count)));
|
||||||
chachaCounter = 0;
|
chachaCounter = 0;
|
||||||
}
|
}
|
||||||
range.popFront();
|
range.popFront();
|
||||||
}
|
}
|
||||||
|
|
||||||
static if (isForwardRange!R)
|
static if (isForwardRange!R)
|
||||||
{
|
{
|
||||||
auto save() @property
|
auto save() @property
|
||||||
|
@ -54,7 +55,9 @@ auto chacha20Cipher(R)(R range, ubyte[32] key, ubyte[8] nonce)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rangeResult(0UL, range, chacha20Exp(key, concat!(ubyte[16])(nonce, littleEndianInv(0UL))));
|
|
||||||
|
return rangeResult(0UL, range, chacha20Exp(key, concat!(ubyte[16])(nonce,
|
||||||
|
littleEndianInv(0UL))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Create more unittests!!!
|
// TODO: Create more unittests!!!
|
||||||
|
@ -65,10 +68,11 @@ auto chacha20Cipher(R)(R range, ubyte[32] key, ubyte[8] nonce)
|
||||||
ubyte[32] key1;
|
ubyte[32] key1;
|
||||||
ubyte[8] nonce1;
|
ubyte[8] nonce1;
|
||||||
test1 = test1.chacha20Cipher(key1, nonce1).array;
|
test1 = test1.chacha20Cipher(key1, nonce1).array;
|
||||||
assert(test1 == [118,184,224,173,160,241, 61,144, 64, 93,106,229, 83,134,189, 40,
|
assert(test1 == [118, 184, 224, 173, 160, 241, 61, 144, 64, 93, 106, 229,
|
||||||
189,210, 25,184,160,141,237, 26,168, 54,239,204,139,119, 13,199,
|
83, 134, 189, 40, 189, 210, 25, 184, 160, 141, 237, 26, 168, 54,
|
||||||
218, 65, 89,124, 81, 87, 72,141,119, 36,224, 63,184,216, 74, 55,
|
239, 204, 139, 119, 13, 199, 218, 65, 89, 124, 81, 87, 72, 141,
|
||||||
106, 67,184,244, 21, 24,161, 28,195,135,182,105,178,238,101,134]);
|
119, 36, 224, 63, 184, 216, 74, 55, 106, 67, 184, 244, 21, 24, 161,
|
||||||
|
28, 195, 135, 182, 105, 178, 238, 101, 134]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -78,17 +82,16 @@ enum string quarterRound(alias _x0, alias _x1, alias _x2, alias _x3) = q{
|
||||||
%3$s += %4$s; %2$s ^= %3$s; %2$s = rotateLeft(%2$s, 12);
|
%3$s += %4$s; %2$s ^= %3$s; %2$s = rotateLeft(%2$s, 12);
|
||||||
%1$s += %2$s; %4$s ^= %1$s; %4$s = rotateLeft(%4$s, 8);
|
%1$s += %2$s; %4$s ^= %1$s; %4$s = rotateLeft(%4$s, 8);
|
||||||
%3$s += %4$s; %2$s ^= %3$s; %2$s = rotateLeft(%2$s, 7);
|
%3$s += %4$s; %2$s ^= %3$s; %2$s = rotateLeft(%2$s, 7);
|
||||||
}.format(__traits(identifier, _x0), __traits(identifier, _x1),
|
}.format(__traits(identifier, _x0),
|
||||||
__traits(identifier, _x2), __traits(identifier, _x3));
|
__traits(identifier, _x1), __traits(identifier, _x2), __traits(identifier, _x3));
|
||||||
|
|
||||||
@safe unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
uint a1 = 0x00000000, a2 = 0x00000000, a3 = 0x00000000, a4 = 0x00000000,
|
uint a1 = 0x00000000, a2 = 0x00000000, a3 = 0x00000000, a4 = 0x00000000,
|
||||||
b1 = 0x00000001, b2 = 0x00000000, b3 = 0x00000000, b4 = 0x00000000,
|
b1 = 0x00000001, b2 = 0x00000000, b3 = 0x00000000, b4 = 0x00000000, c1 = 0x00000000,
|
||||||
c1 = 0x00000000, c2 = 0x00000001, c3 = 0x00000000, c4 = 0x00000000,
|
c2 = 0x00000001, c3 = 0x00000000, c4 = 0x00000000, d1 = 0x00000000, d2 = 0x00000000,
|
||||||
d1 = 0x00000000, d2 = 0x00000000, d3 = 0x00000001, d4 = 0x00000000,
|
d3 = 0x00000001, d4 = 0x00000000, e1 = 0x00000000, e2 = 0x00000000, e3 = 0x00000000,
|
||||||
e1 = 0x00000000, e2 = 0x00000000, e3 = 0x00000000, e4 = 0x00000001,
|
e4 = 0x00000001, f1 = 0xe7e8c006, f2 = 0xc4f9417d, f3 = 0x6479b4b2, f4 = 0x68c67137,
|
||||||
f1 = 0xe7e8c006, f2 = 0xc4f9417d, f3 = 0x6479b4b2, f4 = 0x68c67137,
|
|
||||||
g1 = 0xd3917c5b, g2 = 0x55f1c407, g3 = 0x52a58a7a, g4 = 0x8f887a3b;
|
g1 = 0xd3917c5b, g2 = 0x55f1c407, g3 = 0x52a58a7a, g4 = 0x8f887a3b;
|
||||||
|
|
||||||
mixin(quarterRound!(a1, a2, a3, a4));
|
mixin(quarterRound!(a1, a2, a3, a4));
|
||||||
|
@ -108,108 +111,104 @@ enum string quarterRound(alias _x0, alias _x1, alias _x2, alias _x3) = q{
|
||||||
assert([g1, g2, g3, g4] == [0x18cb6df2, 0x41821bf8, 0x1fcb29a7, 0x92cbf922]);
|
assert([g1, g2, g3, g4] == [0x18cb6df2, 0x41821bf8, 0x1fcb29a7, 0x92cbf922]);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum string rowRound(alias _x00, alias _x01, alias _x02, alias _x03,
|
enum string rowRound(alias _x00, alias _x01, alias _x02, alias _x03, alias _x04,
|
||||||
alias _x04, alias _x05, alias _x06, alias _x07,
|
alias _x05, alias _x06, alias _x07, alias _x08, alias _x09, alias _x10,
|
||||||
alias _x08, alias _x09, alias _x10, alias _x11,
|
alias _x11, alias _x12, alias _x13, alias _x14, alias _x15,) = q{
|
||||||
alias _x12, alias _x13, alias _x14, alias _x15,) = q{
|
|
||||||
mixin(quarterRound!(%1$s, %6$s, %11$s, %16$s));
|
mixin(quarterRound!(%1$s, %6$s, %11$s, %16$s));
|
||||||
mixin(quarterRound!(%2$s, %7$s, %12$s, %13$s));
|
mixin(quarterRound!(%2$s, %7$s, %12$s, %13$s));
|
||||||
mixin(quarterRound!(%3$s, %8$s, %9$s, %14$s));
|
mixin(quarterRound!(%3$s, %8$s, %9$s, %14$s));
|
||||||
mixin(quarterRound!(%4$s, %5$s, %10$s, %15$s));
|
mixin(quarterRound!(%4$s, %5$s, %10$s, %15$s));
|
||||||
}.format(__traits(identifier, _x00), __traits(identifier, _x01),
|
}.format(
|
||||||
__traits(identifier, _x02), __traits(identifier, _x03),
|
__traits(identifier, _x00), __traits(identifier,
|
||||||
__traits(identifier, _x04), __traits(identifier, _x05),
|
_x01), __traits(identifier, _x02), __traits(identifier, _x03),
|
||||||
__traits(identifier, _x06), __traits(identifier, _x07),
|
__traits(identifier, _x04), __traits(identifier, _x05), __traits(identifier, _x06),
|
||||||
__traits(identifier, _x08), __traits(identifier, _x09),
|
__traits(identifier, _x07), __traits(identifier, _x08), __traits(identifier, _x09),
|
||||||
__traits(identifier, _x10), __traits(identifier, _x11),
|
__traits(identifier, _x10), __traits(identifier, _x11), __traits(identifier, _x12),
|
||||||
__traits(identifier, _x12), __traits(identifier, _x13),
|
__traits(identifier, _x13), __traits(identifier, _x14), __traits(identifier, _x15));
|
||||||
__traits(identifier, _x14), __traits(identifier, _x15));
|
|
||||||
|
|
||||||
@safe unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
uint y00 = 0x00000001, y01 = 0x00000000, y02 = 0x00000000, y03 = 0x00000000,
|
uint y00 = 0x00000001, y01 = 0x00000000, y02 = 0x00000000, y03 = 0x00000000,
|
||||||
y04 = 0x00000001, y05 = 0x00000000, y06 = 0x00000000, y07 = 0x00000000,
|
y04 = 0x00000001, y05 = 0x00000000, y06 = 0x00000000, y07 = 0x00000000, y08 = 0x00000001,
|
||||||
y08 = 0x00000001, y09 = 0x00000000, y10 = 0x00000000, y11 = 0x00000000,
|
y09 = 0x00000000, y10 = 0x00000000, y11 = 0x00000000, y12 = 0x00000001,
|
||||||
y12 = 0x00000001, y13 = 0x00000000, y14 = 0x00000000, y15 = 0x00000000;
|
y13 = 0x00000000, y14 = 0x00000000, y15 = 0x00000000;
|
||||||
|
|
||||||
uint x00 = 0x08521bd6, x01 = 0x1fe88837, x02 = 0xbb2aa576, x03 = 0x3aa26365,
|
uint x00 = 0x08521bd6, x01 = 0x1fe88837, x02 = 0xbb2aa576, x03 = 0x3aa26365,
|
||||||
x04 = 0xc54c6a5b, x05 = 0x2fc74c2f, x06 = 0x6dd39cc3, x07 = 0xda0a64f6,
|
x04 = 0xc54c6a5b, x05 = 0x2fc74c2f, x06 = 0x6dd39cc3, x07 = 0xda0a64f6, x08 = 0x90a2f23d,
|
||||||
x08 = 0x90a2f23d, x09 = 0x067f95a6, x10 = 0x06b35f61, x11 = 0x41e4732e,
|
x09 = 0x067f95a6, x10 = 0x06b35f61, x11 = 0x41e4732e, x12 = 0xe859c100,
|
||||||
x12 = 0xe859c100, x13 = 0xea4d84b7, x14 = 0x0f619bff, x15 = 0xbc6e965a;
|
x13 = 0xea4d84b7, x14 = 0x0f619bff, x15 = 0xbc6e965a;
|
||||||
|
|
||||||
mixin(rowRound!(y00, y01, y02, y03, y04, y05, y06, y07,
|
mixin(rowRound!(y00, y01, y02, y03, y04, y05, y06, y07, y08, y09, y10,
|
||||||
y08, y09, y10, y11, y12, y13, y14, y15));
|
y11, y12, y13, y14, y15));
|
||||||
|
|
||||||
mixin(rowRound!(x00, x01, x02, x03, x04, x05, x06, x07,
|
mixin(rowRound!(x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10,
|
||||||
x08, x09, x10, x11, x12, x13, x14, x15));
|
x11, x12, x13, x14, x15));
|
||||||
|
|
||||||
immutable uint[16] test0 = [y00, y01, y02, y03, y04, y05, y06, y07,
|
immutable uint[16] test0 = [
|
||||||
y08, y09, y10, y11, y12, y13, y14, y15];
|
y00, y01, y02, y03, y04, y05, y06, y07, y08, y09, y10, y11, y12, y13, y14, y15
|
||||||
|
];
|
||||||
|
|
||||||
immutable uint[16] test1 = [x00, x01, x02, x03, x04, x05, x06, x07,
|
immutable uint[16] test1 = [
|
||||||
x08, x09, x10, x11, x12, x13, x14, x15];
|
x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14, x15
|
||||||
|
];
|
||||||
|
|
||||||
assert(test0 == [0x10000001, 0x10000000, 0x00001000, 0x10001001,
|
assert(test0 == [0x10000001, 0x10000000, 0x00001000, 0x10001001, 0x88888808, 0x80808808, 0x80800808, 0x08080080,
|
||||||
0x88888808, 0x80808808, 0x80800808, 0x08080080,
|
0x00100001, 0x01110110, 0x01010110, 0x01010010, 0x01000010,
|
||||||
0x00100001, 0x01110110, 0x01010110, 0x01010010,
|
0x00100000, 0x01100110, 0x01000110]);
|
||||||
0x01000010, 0x00100000, 0x01100110, 0x01000110]);
|
|
||||||
|
|
||||||
assert(test1 == [0x9318dab2, 0x6219299a, 0xd68946c3, 0x3eb5b75f,
|
assert(test1 == [0x9318dab2, 0x6219299a, 0xd68946c3, 0x3eb5b75f, 0xe0df816c, 0x476df40b, 0xbb2e1d6f, 0x7608ad18,
|
||||||
0xe0df816c, 0x476df40b, 0xbb2e1d6f, 0x7608ad18,
|
0x71b82d0d, 0xe707569d, 0x4c71a945, 0x0b2b589a, 0xe34c7f87,
|
||||||
0x71b82d0d, 0xe707569d, 0x4c71a945, 0x0b2b589a,
|
0x5239bb58, 0x8a47d068, 0x475ec56d]);
|
||||||
0xe34c7f87, 0x5239bb58, 0x8a47d068, 0x475ec56d]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum string colRound(alias _x00, alias _x01, alias _x02, alias _x03,
|
enum string colRound(alias _x00, alias _x01, alias _x02, alias _x03, alias _x04,
|
||||||
alias _x04, alias _x05, alias _x06, alias _x07,
|
alias _x05, alias _x06, alias _x07, alias _x08, alias _x09, alias _x10,
|
||||||
alias _x08, alias _x09, alias _x10, alias _x11,
|
alias _x11, alias _x12, alias _x13, alias _x14, alias _x15,) = q{
|
||||||
alias _x12, alias _x13, alias _x14, alias _x15,) = q{
|
|
||||||
mixin(quarterRound!(%1$s, %5$s, %9$s, %13$s));
|
mixin(quarterRound!(%1$s, %5$s, %9$s, %13$s));
|
||||||
mixin(quarterRound!(%2$s, %6$s, %10$s, %14$s));
|
mixin(quarterRound!(%2$s, %6$s, %10$s, %14$s));
|
||||||
mixin(quarterRound!(%3$s, %7$s, %11$s, %15$s));
|
mixin(quarterRound!(%3$s, %7$s, %11$s, %15$s));
|
||||||
mixin(quarterRound!(%4$s, %8$s, %12$s, %16$s));
|
mixin(quarterRound!(%4$s, %8$s, %12$s, %16$s));
|
||||||
}.format(__traits(identifier, _x00), __traits(identifier, _x01),
|
}.format(
|
||||||
__traits(identifier, _x02), __traits(identifier, _x03),
|
__traits(identifier, _x00), __traits(identifier,
|
||||||
__traits(identifier, _x04), __traits(identifier, _x05),
|
_x01), __traits(identifier, _x02), __traits(identifier, _x03),
|
||||||
__traits(identifier, _x06), __traits(identifier, _x07),
|
__traits(identifier, _x04), __traits(identifier, _x05), __traits(identifier, _x06),
|
||||||
__traits(identifier, _x08), __traits(identifier, _x09),
|
__traits(identifier, _x07), __traits(identifier, _x08), __traits(identifier, _x09),
|
||||||
__traits(identifier, _x10), __traits(identifier, _x11),
|
__traits(identifier, _x10), __traits(identifier, _x11), __traits(identifier, _x12),
|
||||||
__traits(identifier, _x12), __traits(identifier, _x13),
|
__traits(identifier, _x13), __traits(identifier, _x14), __traits(identifier, _x15));
|
||||||
__traits(identifier, _x14), __traits(identifier, _x15));
|
|
||||||
|
|
||||||
@safe unittest{
|
@safe unittest
|
||||||
|
{
|
||||||
uint y00 = 0x00000001, y01 = 0x00000000, y02 = 0x00000000, y03 = 0x00000000,
|
uint y00 = 0x00000001, y01 = 0x00000000, y02 = 0x00000000, y03 = 0x00000000,
|
||||||
y04 = 0x00000001, y05 = 0x00000000, y06 = 0x00000000, y07 = 0x00000000,
|
y04 = 0x00000001, y05 = 0x00000000, y06 = 0x00000000, y07 = 0x00000000, y08 = 0x00000001,
|
||||||
y08 = 0x00000001, y09 = 0x00000000, y10 = 0x00000000, y11 = 0x00000000,
|
y09 = 0x00000000, y10 = 0x00000000, y11 = 0x00000000, y12 = 0x00000001,
|
||||||
y12 = 0x00000001, y13 = 0x00000000, y14 = 0x00000000, y15 = 0x00000000;
|
y13 = 0x00000000, y14 = 0x00000000, y15 = 0x00000000;
|
||||||
|
|
||||||
uint x00 = 0x08521bd6, x01 = 0x1fe88837, x02 = 0xbb2aa576, x03 = 0x3aa26365,
|
uint x00 = 0x08521bd6, x01 = 0x1fe88837, x02 = 0xbb2aa576, x03 = 0x3aa26365,
|
||||||
x04 = 0xc54c6a5b, x05 = 0x2fc74c2f, x06 = 0x6dd39cc3, x07 = 0xda0a64f6,
|
x04 = 0xc54c6a5b, x05 = 0x2fc74c2f, x06 = 0x6dd39cc3, x07 = 0xda0a64f6, x08 = 0x90a2f23d,
|
||||||
x08 = 0x90a2f23d, x09 = 0x067f95a6, x10 = 0x06b35f61, x11 = 0x41e4732e,
|
x09 = 0x067f95a6, x10 = 0x06b35f61, x11 = 0x41e4732e, x12 = 0xe859c100,
|
||||||
x12 = 0xe859c100, x13 = 0xea4d84b7, x14 = 0x0f619bff, x15 = 0xbc6e965a;
|
x13 = 0xea4d84b7, x14 = 0x0f619bff, x15 = 0xbc6e965a;
|
||||||
|
|
||||||
|
mixin(colRound!(y00, y01, y02, y03, y04, y05, y06, y07, y08, y09, y10,
|
||||||
|
y11, y12, y13, y14, y15));
|
||||||
|
|
||||||
mixin(colRound!(y00, y01, y02, y03, y04, y05, y06, y07,
|
mixin(colRound!(x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10,
|
||||||
y08, y09, y10, y11, y12, y13, y14, y15));
|
x11, x12, x13, x14, x15));
|
||||||
|
|
||||||
mixin(colRound!(x00, x01, x02, x03, x04, x05, x06, x07,
|
immutable uint[16] test0 = [
|
||||||
x08, x09, x10, x11, x12, x13, x14, x15));
|
y00, y01, y02, y03, y04, y05, y06, y07, y08, y09, y10, y11, y12, y13, y14, y15
|
||||||
|
];
|
||||||
|
|
||||||
immutable uint[16] test0 = [y00, y01, y02, y03, y04, y05, y06, y07,
|
immutable uint[16] test1 = [
|
||||||
y08, y09, y10, y11, y12, y13, y14, y15];
|
x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14, x15
|
||||||
|
];
|
||||||
|
|
||||||
immutable uint[16] test1 = [x00, x01, x02, x03, x04, x05, x06, x07,
|
assert(test0 == [0x30000002, 0x00000000, 0x00000000, 0x00000000, 0x81811899, 0x00000000, 0x00000000, 0x00000000,
|
||||||
x08, x09, x10, x11, x12, x13, x14, x15];
|
0x03030231, 0x00000000, 0x00000000, 0x00000000, 0x03000230,
|
||||||
|
0x00000000, 0x00000000, 0x00000000]);
|
||||||
|
|
||||||
assert(test0 == [0x30000002, 0x00000000, 0x00000000, 0x00000000,
|
assert(test1 == [0x54c4775a, 0xb72a4bef, 0xcaba7b13, 0xdc9d2cb9, 0x01a21f25, 0x229f731a, 0xb515e4fe, 0xcd79967d,
|
||||||
0x81811899, 0x00000000, 0x00000000, 0x00000000,
|
0xcd26b517, 0x533f496f, 0x5cd61313, 0x3c6a9772, 0xf5529d13,
|
||||||
0x03030231, 0x00000000, 0x00000000, 0x00000000,
|
0xfbee0de7, 0x7c5c8c13, 0x9c847b82]);
|
||||||
0x03000230, 0x00000000, 0x00000000, 0x00000000]);
|
|
||||||
|
|
||||||
assert(test1 == [0x54c4775a, 0xb72a4bef, 0xcaba7b13, 0xdc9d2cb9,
|
|
||||||
0x01a21f25, 0x229f731a, 0xb515e4fe, 0xcd79967d,
|
|
||||||
0xcd26b517, 0x533f496f, 0x5cd61313, 0x3c6a9772,
|
|
||||||
0xf5529d13, 0xfbee0de7, 0x7c5c8c13, 0x9c847b82]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ubyte[64] chacha20(in ubyte[64] input) @safe nothrow pure @nogc
|
ubyte[64] chacha20(in ubyte[64] input) @safe nothrow pure @nogc
|
||||||
|
@ -223,84 +222,76 @@ ubyte[64] chacha20(in ubyte[64] input) @safe nothrow pure @nogc
|
||||||
x12 = littleEndian(input[48 .. 52]), x13 = littleEndian(input[52 .. 56]),
|
x12 = littleEndian(input[48 .. 52]), x13 = littleEndian(input[52 .. 56]),
|
||||||
x14 = littleEndian(input[56 .. 60]), x15 = littleEndian(input[60 .. 64]);
|
x14 = littleEndian(input[56 .. 60]), x15 = littleEndian(input[60 .. 64]);
|
||||||
|
|
||||||
auto y00 = x00, y01 = x01, y02 = x02, y03 = x03,
|
auto y00 = x00, y01 = x01, y02 = x02, y03 = x03, y04 = x04, y05 = x05,
|
||||||
y04 = x04, y05 = x05, y06 = x06, y07 = x07,
|
y06 = x06, y07 = x07, y08 = x08, y09 = x09, y10 = x10, y11 = x11, y12 = x12,
|
||||||
y08 = x08, y09 = x09, y10 = x10, y11 = x11,
|
y13 = x13, y14 = x14, y15 = x15;
|
||||||
y12 = x12, y13 = x13, y14 = x14, y15 = x15;
|
|
||||||
|
|
||||||
foreach (i; 0 .. 10)
|
foreach (i; 0 .. 10)
|
||||||
{
|
{
|
||||||
mixin(colRound!(x00, x01, x02, x03, x04, x05, x06, x07,
|
mixin(colRound!(x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10,
|
||||||
x08, x09, x10, x11, x12, x13, x14, x15));
|
x11, x12, x13, x14, x15));
|
||||||
|
|
||||||
mixin(rowRound!(x00, x01, x02, x03, x04, x05, x06, x07,
|
mixin(rowRound!(x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10,
|
||||||
x08, x09, x10, x11, x12, x13, x14, x15));
|
x11, x12, x13, x14, x15));
|
||||||
}
|
}
|
||||||
|
|
||||||
return concat!(ubyte[64])(littleEndianInv(x00 + y00),
|
return concat!(ubyte[64])(littleEndianInv(x00 + y00), littleEndianInv(x01 + y01),
|
||||||
littleEndianInv(x01 + y01),
|
littleEndianInv(x02 + y02), littleEndianInv(x03 + y03), littleEndianInv(x04 + y04),
|
||||||
littleEndianInv(x02 + y02),
|
littleEndianInv(x05 + y05), littleEndianInv(x06 + y06), littleEndianInv(x07 + y07),
|
||||||
littleEndianInv(x03 + y03),
|
littleEndianInv(x08 + y08), littleEndianInv(x09 + y09), littleEndianInv(x10 + y10),
|
||||||
littleEndianInv(x04 + y04),
|
littleEndianInv(x11 + y11), littleEndianInv(x12 + y12), littleEndianInv(x13 + y13),
|
||||||
littleEndianInv(x05 + y05),
|
littleEndianInv(x14 + y14), littleEndianInv(x15 + y15));
|
||||||
littleEndianInv(x06 + y06),
|
|
||||||
littleEndianInv(x07 + y07),
|
|
||||||
littleEndianInv(x08 + y08),
|
|
||||||
littleEndianInv(x09 + y09),
|
|
||||||
littleEndianInv(x10 + y10),
|
|
||||||
littleEndianInv(x11 + y11),
|
|
||||||
littleEndianInv(x12 + y12),
|
|
||||||
littleEndianInv(x13 + y13),
|
|
||||||
littleEndianInv(x14 + y14),
|
|
||||||
littleEndianInv(x15 + y15));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@safe unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
ubyte[64] test0 = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
ubyte[64] test0 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
||||||
test0 = chacha20(test0);
|
test0 = chacha20(test0);
|
||||||
|
|
||||||
ubyte[64] test1 = [211,159, 13,115, 76, 55, 82,183, 3,117,222, 37,191,187,234,136,
|
ubyte[64] test1 = [211, 159, 13, 115, 76, 55, 82, 183, 3, 117, 222, 37,
|
||||||
49,237,179, 48, 1,106,178,219,175,199,166, 48, 86, 16,179,207,
|
191, 187, 234, 136, 49, 237, 179, 48, 1, 106, 178, 219, 175, 199,
|
||||||
31,240, 32, 63, 15, 83, 93,161,116,147, 48,113,238, 55,204, 36,
|
166, 48, 86, 16, 179, 207, 31, 240, 32, 63, 15, 83, 93, 161, 116, 147,
|
||||||
79,201,235, 79, 3, 81,156, 47,203, 26,244,243, 88,118,104, 54];
|
48, 113, 238, 55, 204, 36, 79, 201, 235, 79, 3, 81, 156, 47, 203, 26,
|
||||||
|
244, 243, 88, 118, 104, 54];
|
||||||
test1 = chacha20(test1);
|
test1 = chacha20(test1);
|
||||||
|
|
||||||
ubyte[64] test2 = [ 88,118,104, 54, 79,201,235, 79, 3, 81,156, 47,203, 26,244,243,
|
ubyte[64] test2 = [88, 118, 104, 54, 79, 201, 235, 79, 3, 81, 156, 47, 203,
|
||||||
191,187,234,136,211,159, 13,115, 76, 55, 82,183, 3,117,222, 37,
|
26, 244, 243, 191, 187, 234, 136, 211, 159, 13, 115, 76, 55, 82, 183,
|
||||||
86, 16,179,207, 49,237,179, 48, 1,106,178,219,175,199,166, 48,
|
3, 117, 222, 37, 86, 16, 179, 207, 49, 237, 179, 48, 1, 106, 178, 219,
|
||||||
238, 55,204, 36, 31,240, 32, 63, 15, 83, 93,161,116,147, 48,113];
|
175, 199, 166, 48, 238, 55, 204, 36, 31, 240, 32, 63, 15, 83, 93, 161, 116, 147, 48, 113];
|
||||||
test2 = chacha20(test2);
|
test2 = chacha20(test2);
|
||||||
|
|
||||||
ubyte[64] test3 = [ 6,124, 83,146, 38,191, 9, 50, 4,161, 47,222,122,182,223,185,
|
ubyte[64] test3 = [6, 124, 83, 146, 38, 191, 9, 50, 4, 161, 47, 222, 122,
|
||||||
75, 27, 0,216, 16,122, 7, 89,162,104,101,147,213, 21, 54, 95,
|
182, 223, 185, 75, 27, 0, 216, 16, 122, 7, 89, 162, 104, 101, 147, 213,
|
||||||
225,253,139,176,105,132, 23,116, 76, 41,176,207,221, 34,157,108,
|
21, 54, 95, 225, 253, 139, 176, 105, 132, 23, 116, 76, 41, 176, 207,
|
||||||
94, 94, 99, 52, 90,117, 91,220,146,190,239,143,196,176,130,186];
|
221, 34, 157, 108, 94, 94, 99, 52, 90, 117, 91, 220, 146, 190, 239,
|
||||||
|
143, 196, 176, 130, 186];
|
||||||
foreach (i; 0 .. 1_000_000)
|
foreach (i; 0 .. 1_000_000)
|
||||||
test3 = chacha20(test3);
|
test3 = chacha20(test3);
|
||||||
|
|
||||||
assert(test0 == [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
assert(test0 == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
|
||||||
|
|
||||||
assert(test1 == [ 19,135,149, 14, 40,180,217,109,187,122,124,114, 23, 14,107,241,
|
assert(test1 == [19, 135, 149, 14, 40, 180, 217, 109, 187, 122, 124, 114,
|
||||||
231, 18, 85,210, 56,159, 57,224, 96, 71, 85,167,202,180, 98, 96,
|
23, 14, 107, 241, 231, 18, 85, 210, 56, 159, 57, 224, 96, 71, 85,
|
||||||
185, 76, 56,161,168,230,132,189, 84, 59, 55,254, 39, 21, 41,153,
|
167, 202, 180, 98, 96, 185, 76, 56, 161, 168, 230, 132, 189, 84,
|
||||||
144,151, 5,208,189, 9,140, 64,226,151,219, 26, 80,221,237,194]);
|
59, 55, 254, 39, 21, 41, 153, 144, 151, 5, 208, 189, 9, 140, 64,
|
||||||
|
226, 151, 219, 26, 80, 221, 237, 194]);
|
||||||
|
|
||||||
assert(test2 == [ 76, 1, 30, 79,130,234,169,252,194, 25,110,243,141, 64, 68,140,
|
assert(test2 == [76, 1, 30, 79, 130, 234, 169, 252, 194, 25, 110, 243, 141,
|
||||||
106, 32,248,152,219, 73,115,133, 10,143, 99,162, 72,155,138, 55,
|
64, 68, 140, 106, 32, 248, 152, 219, 73, 115, 133, 10, 143, 99,
|
||||||
58,214, 79, 49, 97, 63,201,155,178,203, 15, 94, 66,224,216,184,
|
162, 72, 155, 138, 55, 58, 214, 79, 49, 97, 63, 201, 155, 178, 203,
|
||||||
64, 85,186,170, 65, 79, 11, 91, 22,247,191, 72, 68,250,229,108]);
|
15, 94, 66, 224, 216, 184, 64, 85, 186, 170, 65, 79, 11, 91, 22,
|
||||||
|
247, 191, 72, 68, 250, 229, 108]);
|
||||||
|
|
||||||
assert(test3 == [ 88, 97,168, 54,215,192,249,115,185,160,231, 86,203,147, 27, 34,
|
assert(test3 == [88, 97, 168, 54, 215, 192, 249, 115, 185, 160, 231, 86,
|
||||||
237,252,228, 40, 1,135,107, 88,160,239, 5,182,250, 16,217,224,
|
203, 147, 27, 34, 237, 252, 228, 40, 1, 135, 107, 88, 160, 239, 5,
|
||||||
101, 27,113, 5, 50,192, 52, 70, 7,110,217, 10, 3,226, 85,129,
|
182, 250, 16, 217, 224, 101, 27, 113, 5, 50, 192, 52, 70, 7, 110,
|
||||||
29,214,235,224, 96, 42, 55, 53,188, 35, 81,171, 81,218,221, 44]);
|
217, 10, 3, 226, 85, 129, 29, 214, 235, 224, 96, 42, 55, 53, 188,
|
||||||
|
35, 81, 171, 81, 218, 221, 44]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static immutable ubyte[4] sigma0 = [101, 120, 112, 97];
|
static immutable ubyte[4] sigma0 = [101, 120, 112, 97];
|
||||||
|
@ -311,48 +302,62 @@ static immutable ubyte[4] sigma3 = [116, 101, 32, 107];
|
||||||
ubyte[64] chacha20Exp(in ubyte[32] key, in ubyte[16] n) @safe pure nothrow @nogc
|
ubyte[64] chacha20Exp(in ubyte[32] key, in ubyte[16] n) @safe pure nothrow @nogc
|
||||||
|
|
||||||
{
|
{
|
||||||
return chacha20(concat!(ubyte[64])(sigma0,
|
return chacha20(concat!(ubyte[64])(sigma0, sigma1, sigma2, sigma3, key, n));
|
||||||
sigma1,
|
|
||||||
sigma2,
|
|
||||||
sigma3,
|
|
||||||
key,
|
|
||||||
n));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@safe unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
immutable ubyte[32] key = [ 1, 2, 3, 4, 5, 6, 7, 8,
|
immutable ubyte[32] key = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||||
9, 10, 11, 12, 13, 14, 15, 16,
|
15, 16, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216];
|
||||||
201,202,203,204,205,206,207,208,
|
|
||||||
209,210,211,212,213,214,215,216];
|
|
||||||
|
|
||||||
immutable ubyte[16] n = [101,102,103,104,105,106,107,108,
|
immutable ubyte[16] n = [
|
||||||
109,110,111,112,113,114,115,116];
|
101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116
|
||||||
|
];
|
||||||
|
|
||||||
assert(chacha20Exp(key, n) == [ 91, 78,219,119,210,190, 8, 62, 37,143, 86,137,217,173,192, 90,
|
assert(chacha20Exp(key, n) == [91, 78, 219, 119, 210, 190, 8, 62, 37, 143,
|
||||||
200, 33, 74, 29,135,175, 94, 6, 23,221,182, 9, 17,163, 46,191,
|
86, 137, 217, 173, 192, 90, 200, 33, 74, 29, 135, 175, 94, 6, 23,
|
||||||
222,214,172,130,247,120,162, 47,190,213, 83, 21,242,210, 49,174,
|
221, 182, 9, 17, 163, 46, 191, 222, 214, 172, 130, 247, 120, 162,
|
||||||
198, 64, 8, 65, 98, 73, 10,144, 56, 48,201, 68, 1,174,183,172]);
|
47, 190, 213, 83, 21, 242, 210, 49, 174, 198, 64, 8, 65, 98, 73,
|
||||||
|
10, 144, 56, 48, 201, 68, 1, 174, 183, 172]);
|
||||||
|
|
||||||
// Test vectors consistent with http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-7
|
// Test vectors consistent with http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-7
|
||||||
immutable ubyte[32] key1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
immutable ubyte[32] key1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
immutable ubyte[16] n1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
immutable ubyte[16] n1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
|
|
||||||
immutable ubyte[32] key2 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
|
immutable ubyte[32] key2 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
|
||||||
immutable ubyte[16] n2 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
immutable ubyte[16] n2 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
|
|
||||||
immutable ubyte[32] key3 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
immutable ubyte[32] key3 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
immutable ubyte[16] n3 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
|
immutable ubyte[16] n3 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
|
||||||
|
|
||||||
immutable ubyte[32] key4 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
immutable ubyte[32] key4 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
immutable ubyte[16] n4 = [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0];
|
immutable ubyte[16] n4 = [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0];
|
||||||
|
|
||||||
|
assert(chacha20Exp(key1, n1) == [118, 184, 224, 173, 160, 241, 61, 144, 64,
|
||||||
|
93, 106, 229, 83, 134, 189, 40, 189, 210, 25, 184, 160, 141, 237,
|
||||||
|
26, 168, 54, 239, 204, 139, 119, 13, 199, 218, 65, 89, 124, 81, 87,
|
||||||
|
72, 141, 119, 36, 224, 63, 184, 216, 74, 55, 106, 67, 184, 244, 21,
|
||||||
|
24, 161, 28, 195, 135, 182, 105, 178, 238, 101, 134]);
|
||||||
|
|
||||||
assert(chacha20Exp(key1, n1) == [118, 184, 224, 173, 160, 241, 61, 144, 64, 93, 106, 229, 83, 134, 189, 40, 189, 210, 25, 184, 160, 141, 237, 26, 168, 54, 239, 204, 139, 119, 13, 199, 218, 65, 89, 124, 81, 87, 72, 141, 119, 36, 224, 63, 184, 216, 74, 55, 106, 67, 184, 244, 21, 24, 161, 28, 195, 135, 182, 105, 178, 238, 101, 134]);
|
assert(chacha20Exp(key2, n2) == [69, 64, 240, 90, 159, 31, 178, 150, 215,
|
||||||
|
115, 110, 123, 32, 142, 60, 150, 235, 79, 225, 131, 70, 136, 210,
|
||||||
|
96, 79, 69, 9, 82, 237, 67, 45, 65, 187, 226, 160, 182, 234, 117,
|
||||||
|
102, 210, 165, 209, 231, 226, 13, 66, 175, 44, 83, 215, 146, 177,
|
||||||
|
196, 63, 234, 129, 126, 154, 210, 117, 174, 84, 105, 99]);
|
||||||
|
|
||||||
assert(chacha20Exp(key2, n2) == [69, 64, 240, 90, 159, 31, 178, 150, 215, 115, 110, 123, 32, 142, 60, 150, 235, 79, 225, 131, 70, 136, 210, 96, 79, 69, 9, 82, 237, 67, 45, 65, 187, 226, 160, 182, 234, 117, 102, 210, 165, 209, 231, 226, 13, 66, 175, 44, 83, 215, 146, 177, 196, 63, 234, 129, 126, 154, 210, 117, 174, 84, 105, 99]);
|
assert(chacha20Exp(key3, n3) == [222, 156, 186, 123, 243, 214, 158, 245,
|
||||||
|
231, 134, 220, 99, 151, 63, 101, 58, 11, 73, 224, 21, 173, 191,
|
||||||
|
247, 19, 79, 203, 125, 241, 55, 130, 16, 49, 232, 90, 5, 2, 120,
|
||||||
|
167, 8, 69, 39, 33, 79, 115, 239, 199, 250, 91, 82, 119, 6, 46,
|
||||||
|
183, 160, 67, 62, 68, 95, 65, 227, 26, 250, 183, 87]);
|
||||||
|
|
||||||
assert(chacha20Exp(key3, n3) == [222, 156, 186, 123, 243, 214, 158, 245, 231, 134, 220, 99, 151, 63, 101, 58, 11, 73, 224, 21, 173, 191, 247, 19, 79, 203, 125, 241, 55, 130, 16, 49, 232, 90, 5, 2, 120, 167, 8, 69, 39, 33, 79, 115, 239, 199, 250, 91, 82, 119, 6, 46, 183, 160, 67, 62, 68, 95, 65, 227, 26, 250, 183, 87]);
|
assert(chacha20Exp(key4, n4) == [239, 63, 223, 214, 198, 21, 120, 251, 245,
|
||||||
|
207, 53, 189, 61, 211, 59, 128, 9, 99, 22, 52, 210, 30, 66, 172,
|
||||||
assert(chacha20Exp(key4, n4) == [239, 63, 223, 214, 198, 21, 120, 251, 245, 207, 53, 189, 61, 211, 59, 128, 9, 99, 22, 52, 210, 30, 66, 172, 51, 150, 11, 209, 56, 229, 13, 50, 17, 30, 76, 175, 35, 126, 229, 60, 168, 173, 100, 38, 25, 74, 136, 84, 93, 220, 73, 122, 11, 70, 110, 125, 107, 189, 176, 4, 27, 47, 88, 107]);
|
51, 150, 11, 209, 56, 229, 13, 50, 17, 30, 76, 175, 35, 126, 229,
|
||||||
|
60, 168, 173, 100, 38, 25, 74, 136, 84, 93, 220, 73, 122, 11, 70,
|
||||||
|
110, 125, 107, 189, 176, 4, 27, 47, 88, 107]);
|
||||||
}
|
}
|
|
@ -2,8 +2,8 @@ module cipher;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
import std.range : isInputRange, isForwardRange, ElementType,
|
import std.range : isInputRange, isForwardRange, ElementType, InputRange,
|
||||||
InputRange, ForwardRange, inputRangeObject;
|
ForwardRange, inputRangeObject;
|
||||||
import std.string : format;
|
import std.string : format;
|
||||||
|
|
||||||
import salsa20;
|
import salsa20;
|
||||||
|
@ -17,8 +17,7 @@ enum Cipher
|
||||||
chacha20
|
chacha20
|
||||||
}
|
}
|
||||||
|
|
||||||
template cipherFunction(R)
|
template cipherFunction(R) if (isInputRange!R && is(ElementType!R : ubyte))
|
||||||
if (isInputRange!R && is(ElementType!R : ubyte))
|
|
||||||
{
|
{
|
||||||
static if (isForwardRange!R)
|
static if (isForwardRange!R)
|
||||||
alias ReturnType = ForwardRange;
|
alias ReturnType = ForwardRange;
|
||||||
|
|
297
source/salsa20.d
297
source/salsa20.d
|
@ -9,7 +9,6 @@ import std.array;
|
||||||
import bitmanip;
|
import bitmanip;
|
||||||
import utility;
|
import utility;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// TODO: Implement random access
|
// TODO: Implement random access
|
||||||
|
@ -41,11 +40,13 @@ auto salsa20Cipher(R)(R range, ubyte[32] key, ubyte[8] nonce)
|
||||||
assert(!empty);
|
assert(!empty);
|
||||||
if (++salsaCounter == 64)
|
if (++salsaCounter == 64)
|
||||||
{
|
{
|
||||||
salsaSection = salsa20Exp(key, concat!(ubyte[16])(nonce, littleEndianInv(++count)));
|
salsaSection = salsa20Exp(key, concat!(ubyte[16])(nonce,
|
||||||
|
littleEndianInv(++count)));
|
||||||
salsaCounter = 0;
|
salsaCounter = 0;
|
||||||
}
|
}
|
||||||
range.popFront();
|
range.popFront();
|
||||||
}
|
}
|
||||||
|
|
||||||
static if (isForwardRange!R)
|
static if (isForwardRange!R)
|
||||||
{
|
{
|
||||||
auto save() @property
|
auto save() @property
|
||||||
|
@ -54,7 +55,9 @@ auto salsa20Cipher(R)(R range, ubyte[32] key, ubyte[8] nonce)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rangeResult(0UL, range, salsa20Exp(key, concat!(ubyte[16])(nonce, littleEndianInv(0UL))));
|
|
||||||
|
return rangeResult(0UL, range, salsa20Exp(key, concat!(ubyte[16])(nonce,
|
||||||
|
littleEndianInv(0UL))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Create more unittests!!!
|
// TODO: Create more unittests!!!
|
||||||
|
@ -65,10 +68,11 @@ auto salsa20Cipher(R)(R range, ubyte[32] key, ubyte[8] nonce)
|
||||||
ubyte[32] key;
|
ubyte[32] key;
|
||||||
ubyte[8] nonce;
|
ubyte[8] nonce;
|
||||||
test = test.salsa20Cipher(key, nonce).array;
|
test = test.salsa20Cipher(key, nonce).array;
|
||||||
assert(test == [154,151,246, 91,155, 76,114, 27,150, 10,103, 33, 69,252,168,212,
|
assert(test == [154, 151, 246, 91, 155, 76, 114, 27, 150, 10, 103, 33, 69,
|
||||||
227, 46,103,249, 17, 30,169,121,206,156, 72, 38,128,106,238,230,
|
252, 168, 212, 227, 46, 103, 249, 17, 30, 169, 121, 206, 156, 72,
|
||||||
61,233,192,218, 43,215,249, 30,188,178, 99,155,249,137,198, 37,
|
38, 128, 106, 238, 230, 61, 233, 192, 218, 43, 215, 249, 30, 188,
|
||||||
27, 41,191, 56,211,154,155,220,231,197, 95, 75, 42,193, 42, 57]);
|
178, 99, 155, 249, 137, 198, 37, 27, 41, 191, 56, 211, 154, 155,
|
||||||
|
220, 231, 197, 95, 75, 42, 193, 42, 57]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -78,17 +82,16 @@ enum string quarterRound(alias _x0, alias _x1, alias _x2, alias _x3) = q{
|
||||||
%3$s ^= (%2$s + %1$s).rotateLeft(9);
|
%3$s ^= (%2$s + %1$s).rotateLeft(9);
|
||||||
%4$s ^= (%3$s + %2$s).rotateLeft(13);
|
%4$s ^= (%3$s + %2$s).rotateLeft(13);
|
||||||
%1$s ^= (%4$s + %3$s).rotateLeft(18);
|
%1$s ^= (%4$s + %3$s).rotateLeft(18);
|
||||||
}.format(__traits(identifier, _x0), __traits(identifier, _x1),
|
}.format(__traits(identifier, _x0),
|
||||||
__traits(identifier, _x2), __traits(identifier, _x3));
|
__traits(identifier, _x1), __traits(identifier, _x2), __traits(identifier, _x3));
|
||||||
|
|
||||||
@safe unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
uint a1 = 0x00000000, a2 = 0x00000000, a3 = 0x00000000, a4 = 0x00000000,
|
uint a1 = 0x00000000, a2 = 0x00000000, a3 = 0x00000000, a4 = 0x00000000,
|
||||||
b1 = 0x00000001, b2 = 0x00000000, b3 = 0x00000000, b4 = 0x00000000,
|
b1 = 0x00000001, b2 = 0x00000000, b3 = 0x00000000, b4 = 0x00000000, c1 = 0x00000000,
|
||||||
c1 = 0x00000000, c2 = 0x00000001, c3 = 0x00000000, c4 = 0x00000000,
|
c2 = 0x00000001, c3 = 0x00000000, c4 = 0x00000000, d1 = 0x00000000, d2 = 0x00000000,
|
||||||
d1 = 0x00000000, d2 = 0x00000000, d3 = 0x00000001, d4 = 0x00000000,
|
d3 = 0x00000001, d4 = 0x00000000, e1 = 0x00000000, e2 = 0x00000000, e3 = 0x00000000,
|
||||||
e1 = 0x00000000, e2 = 0x00000000, e3 = 0x00000000, e4 = 0x00000001,
|
e4 = 0x00000001, f1 = 0xe7e8c006, f2 = 0xc4f9417d, f3 = 0x6479b4b2, f4 = 0x68c67137,
|
||||||
f1 = 0xe7e8c006, f2 = 0xc4f9417d, f3 = 0x6479b4b2, f4 = 0x68c67137,
|
|
||||||
g1 = 0xd3917c5b, g2 = 0x55f1c407, g3 = 0x52a58a7a, g4 = 0x8f887a3b;
|
g1 = 0xd3917c5b, g2 = 0x55f1c407, g3 = 0x52a58a7a, g4 = 0x8f887a3b;
|
||||||
|
|
||||||
mixin(quarterRound!(a1, a2, a3, a4));
|
mixin(quarterRound!(a1, a2, a3, a4));
|
||||||
|
@ -108,109 +111,104 @@ enum string quarterRound(alias _x0, alias _x1, alias _x2, alias _x3) = q{
|
||||||
assert([g1, g2, g3, g4] == [0x3e2f308c, 0xd90a8f36, 0x6ab2a923, 0x2883524c]);
|
assert([g1, g2, g3, g4] == [0x3e2f308c, 0xd90a8f36, 0x6ab2a923, 0x2883524c]);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum string rowRound(alias _x00, alias _x01, alias _x02, alias _x03,
|
enum string rowRound(alias _x00, alias _x01, alias _x02, alias _x03, alias _x04,
|
||||||
alias _x04, alias _x05, alias _x06, alias _x07,
|
alias _x05, alias _x06, alias _x07, alias _x08, alias _x09, alias _x10,
|
||||||
alias _x08, alias _x09, alias _x10, alias _x11,
|
alias _x11, alias _x12, alias _x13, alias _x14, alias _x15) = q{
|
||||||
alias _x12, alias _x13, alias _x14, alias _x15) = q{
|
|
||||||
mixin(quarterRound!(%1$s, %2$s, %3$s, %4$s));
|
mixin(quarterRound!(%1$s, %2$s, %3$s, %4$s));
|
||||||
mixin(quarterRound!(%6$s, %7$s, %8$s, %5$s));
|
mixin(quarterRound!(%6$s, %7$s, %8$s, %5$s));
|
||||||
mixin(quarterRound!(%11$s, %12$s, %9$s, %10$s));
|
mixin(quarterRound!(%11$s, %12$s, %9$s, %10$s));
|
||||||
mixin(quarterRound!(%16$s, %13$s, %14$s, %15$s));
|
mixin(quarterRound!(%16$s, %13$s, %14$s, %15$s));
|
||||||
}.format(__traits(identifier, _x00), __traits(identifier, _x01),
|
}.format(
|
||||||
__traits(identifier, _x02), __traits(identifier, _x03),
|
__traits(identifier, _x00), __traits(identifier,
|
||||||
__traits(identifier, _x04), __traits(identifier, _x05),
|
_x01), __traits(identifier, _x02), __traits(identifier, _x03),
|
||||||
__traits(identifier, _x06), __traits(identifier, _x07),
|
__traits(identifier, _x04), __traits(identifier, _x05), __traits(identifier, _x06),
|
||||||
__traits(identifier, _x08), __traits(identifier, _x09),
|
__traits(identifier, _x07), __traits(identifier, _x08), __traits(identifier, _x09),
|
||||||
__traits(identifier, _x10), __traits(identifier, _x11),
|
__traits(identifier, _x10), __traits(identifier, _x11), __traits(identifier, _x12),
|
||||||
__traits(identifier, _x12), __traits(identifier, _x13),
|
__traits(identifier, _x13), __traits(identifier, _x14), __traits(identifier, _x15));
|
||||||
__traits(identifier, _x14), __traits(identifier, _x15));
|
|
||||||
|
|
||||||
@safe unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
uint y00 = 0x00000001, y01 = 0x00000000, y02 = 0x00000000, y03 = 0x00000000,
|
uint y00 = 0x00000001, y01 = 0x00000000, y02 = 0x00000000, y03 = 0x00000000,
|
||||||
y04 = 0x00000001, y05 = 0x00000000, y06 = 0x00000000, y07 = 0x00000000,
|
y04 = 0x00000001, y05 = 0x00000000, y06 = 0x00000000, y07 = 0x00000000, y08 = 0x00000001,
|
||||||
y08 = 0x00000001, y09 = 0x00000000, y10 = 0x00000000, y11 = 0x00000000,
|
y09 = 0x00000000, y10 = 0x00000000, y11 = 0x00000000, y12 = 0x00000001,
|
||||||
y12 = 0x00000001, y13 = 0x00000000, y14 = 0x00000000, y15 = 0x00000000;
|
y13 = 0x00000000, y14 = 0x00000000, y15 = 0x00000000;
|
||||||
|
|
||||||
uint x00 = 0x08521bd6, x01 = 0x1fe88837, x02 = 0xbb2aa576, x03 = 0x3aa26365,
|
uint x00 = 0x08521bd6, x01 = 0x1fe88837, x02 = 0xbb2aa576, x03 = 0x3aa26365,
|
||||||
x04 = 0xc54c6a5b, x05 = 0x2fc74c2f, x06 = 0x6dd39cc3, x07 = 0xda0a64f6,
|
x04 = 0xc54c6a5b, x05 = 0x2fc74c2f, x06 = 0x6dd39cc3, x07 = 0xda0a64f6, x08 = 0x90a2f23d,
|
||||||
x08 = 0x90a2f23d, x09 = 0x067f95a6, x10 = 0x06b35f61, x11 = 0x41e4732e,
|
x09 = 0x067f95a6, x10 = 0x06b35f61, x11 = 0x41e4732e, x12 = 0xe859c100,
|
||||||
x12 = 0xe859c100, x13 = 0xea4d84b7, x14 = 0x0f619bff, x15 = 0xbc6e965a;
|
x13 = 0xea4d84b7, x14 = 0x0f619bff, x15 = 0xbc6e965a;
|
||||||
|
|
||||||
mixin(rowRound!(y00, y01, y02, y03, y04, y05, y06, y07,
|
mixin(rowRound!(y00, y01, y02, y03, y04, y05, y06, y07, y08, y09, y10,
|
||||||
y08, y09, y10, y11, y12, y13, y14, y15));
|
y11, y12, y13, y14, y15));
|
||||||
|
|
||||||
mixin(rowRound!(x00, x01, x02, x03, x04, x05, x06, x07,
|
mixin(rowRound!(x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10,
|
||||||
x08, x09, x10, x11, x12, x13, x14, x15));
|
x11, x12, x13, x14, x15));
|
||||||
|
|
||||||
immutable uint[16] test0 = [y00, y01, y02, y03, y04, y05, y06, y07,
|
immutable uint[16] test0 = [
|
||||||
y08, y09, y10, y11, y12, y13, y14, y15];
|
y00, y01, y02, y03, y04, y05, y06, y07, y08, y09, y10, y11, y12, y13, y14, y15
|
||||||
|
];
|
||||||
|
|
||||||
immutable uint[16] test1 = [x00, x01, x02, x03, x04, x05, x06, x07,
|
immutable uint[16] test1 = [
|
||||||
x08, x09, x10, x11, x12, x13, x14, x15];
|
x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14, x15
|
||||||
|
];
|
||||||
|
|
||||||
assert(test0 == [0x08008145, 0x00000080, 0x00010200, 0x20500000,
|
assert(test0 == [0x08008145, 0x00000080, 0x00010200, 0x20500000, 0x20100001, 0x00048044, 0x00000080, 0x00010000,
|
||||||
0x20100001, 0x00048044, 0x00000080, 0x00010000,
|
0x00000001, 0x00002000, 0x80040000, 0x00000000, 0x00000001,
|
||||||
0x00000001, 0x00002000, 0x80040000, 0x00000000,
|
0x00000200, 0x00402000, 0x88000100]);
|
||||||
0x00000001, 0x00000200, 0x00402000, 0x88000100]);
|
|
||||||
|
|
||||||
assert(test1 == [0xa890d39d, 0x65d71596, 0xe9487daa, 0xc8ca6a86,
|
assert(test1 == [0xa890d39d, 0x65d71596, 0xe9487daa, 0xc8ca6a86, 0x949d2192, 0x764b7754, 0xe408d9b9, 0x7a41b4d1,
|
||||||
0x949d2192, 0x764b7754, 0xe408d9b9, 0x7a41b4d1,
|
0x3402e183, 0x3c3af432, 0x50669f96, 0xd89ef0a8, 0x0040ede5,
|
||||||
0x3402e183, 0x3c3af432, 0x50669f96, 0xd89ef0a8,
|
0xb545fbce, 0xd257ed4f, 0x1818882d]);
|
||||||
0x0040ede5, 0xb545fbce, 0xd257ed4f, 0x1818882d]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum string colRound(alias _x00, alias _x01, alias _x02, alias _x03,
|
enum string colRound(alias _x00, alias _x01, alias _x02, alias _x03, alias _x04,
|
||||||
alias _x04, alias _x05, alias _x06, alias _x07,
|
alias _x05, alias _x06, alias _x07, alias _x08, alias _x09, alias _x10,
|
||||||
alias _x08, alias _x09, alias _x10, alias _x11,
|
alias _x11, alias _x12, alias _x13, alias _x14, alias _x15,) = q{
|
||||||
alias _x12, alias _x13, alias _x14, alias _x15,) = q{
|
|
||||||
mixin(quarterRound!(%1$s, %5$s, %9$s, %13$s));
|
mixin(quarterRound!(%1$s, %5$s, %9$s, %13$s));
|
||||||
mixin(quarterRound!(%6$s, %10$s, %14$s, %2$s));
|
mixin(quarterRound!(%6$s, %10$s, %14$s, %2$s));
|
||||||
mixin(quarterRound!(%11$s, %15$s, %3$s, %7$s));
|
mixin(quarterRound!(%11$s, %15$s, %3$s, %7$s));
|
||||||
mixin(quarterRound!(%16$s, %4$s, %8$s, %12$s));
|
mixin(quarterRound!(%16$s, %4$s, %8$s, %12$s));
|
||||||
}.format(__traits(identifier, _x00), __traits(identifier, _x01),
|
}.format(
|
||||||
__traits(identifier, _x02), __traits(identifier, _x03),
|
__traits(identifier, _x00), __traits(identifier,
|
||||||
__traits(identifier, _x04), __traits(identifier, _x05),
|
_x01), __traits(identifier, _x02), __traits(identifier, _x03),
|
||||||
__traits(identifier, _x06), __traits(identifier, _x07),
|
__traits(identifier, _x04), __traits(identifier, _x05), __traits(identifier, _x06),
|
||||||
__traits(identifier, _x08), __traits(identifier, _x09),
|
__traits(identifier, _x07), __traits(identifier, _x08), __traits(identifier, _x09),
|
||||||
__traits(identifier, _x10), __traits(identifier, _x11),
|
__traits(identifier, _x10), __traits(identifier, _x11), __traits(identifier, _x12),
|
||||||
__traits(identifier, _x12), __traits(identifier, _x13),
|
__traits(identifier, _x13), __traits(identifier, _x14), __traits(identifier, _x15));
|
||||||
__traits(identifier, _x14), __traits(identifier, _x15));
|
|
||||||
|
|
||||||
@safe unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
uint y00 = 0x00000001, y01 = 0x00000000, y02 = 0x00000000, y03 = 0x00000000,
|
uint y00 = 0x00000001, y01 = 0x00000000, y02 = 0x00000000, y03 = 0x00000000,
|
||||||
y04 = 0x00000001, y05 = 0x00000000, y06 = 0x00000000, y07 = 0x00000000,
|
y04 = 0x00000001, y05 = 0x00000000, y06 = 0x00000000, y07 = 0x00000000, y08 = 0x00000001,
|
||||||
y08 = 0x00000001, y09 = 0x00000000, y10 = 0x00000000, y11 = 0x00000000,
|
y09 = 0x00000000, y10 = 0x00000000, y11 = 0x00000000, y12 = 0x00000001,
|
||||||
y12 = 0x00000001, y13 = 0x00000000, y14 = 0x00000000, y15 = 0x00000000;
|
y13 = 0x00000000, y14 = 0x00000000, y15 = 0x00000000;
|
||||||
|
|
||||||
uint x00 = 0x08521bd6, x01 = 0x1fe88837, x02 = 0xbb2aa576, x03 = 0x3aa26365,
|
uint x00 = 0x08521bd6, x01 = 0x1fe88837, x02 = 0xbb2aa576, x03 = 0x3aa26365,
|
||||||
x04 = 0xc54c6a5b, x05 = 0x2fc74c2f, x06 = 0x6dd39cc3, x07 = 0xda0a64f6,
|
x04 = 0xc54c6a5b, x05 = 0x2fc74c2f, x06 = 0x6dd39cc3, x07 = 0xda0a64f6, x08 = 0x90a2f23d,
|
||||||
x08 = 0x90a2f23d, x09 = 0x067f95a6, x10 = 0x06b35f61, x11 = 0x41e4732e,
|
x09 = 0x067f95a6, x10 = 0x06b35f61, x11 = 0x41e4732e, x12 = 0xe859c100,
|
||||||
x12 = 0xe859c100, x13 = 0xea4d84b7, x14 = 0x0f619bff, x15 = 0xbc6e965a;
|
x13 = 0xea4d84b7, x14 = 0x0f619bff, x15 = 0xbc6e965a;
|
||||||
|
|
||||||
|
mixin(colRound!(y00, y01, y02, y03, y04, y05, y06, y07, y08, y09, y10,
|
||||||
|
y11, y12, y13, y14, y15));
|
||||||
|
|
||||||
mixin(colRound!(y00, y01, y02, y03, y04, y05, y06, y07,
|
mixin(colRound!(x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10,
|
||||||
y08, y09, y10, y11, y12, y13, y14, y15));
|
x11, x12, x13, x14, x15));
|
||||||
|
|
||||||
mixin(colRound!(x00, x01, x02, x03, x04, x05, x06, x07,
|
immutable uint[16] test0 = [
|
||||||
x08, x09, x10, x11, x12, x13, x14, x15));
|
y00, y01, y02, y03, y04, y05, y06, y07, y08, y09, y10, y11, y12, y13, y14, y15
|
||||||
|
];
|
||||||
|
|
||||||
immutable uint[16] test0 = [y00, y01, y02, y03, y04, y05, y06, y07,
|
immutable uint[16] test1 = [
|
||||||
y08, y09, y10, y11, y12, y13, y14, y15];
|
x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14, x15
|
||||||
|
];
|
||||||
|
|
||||||
immutable uint[16] test1 = [x00, x01, x02, x03, x04, x05, x06, x07,
|
assert(test0 == [0x10090288, 0x00000000, 0x00000000, 0x00000000, 0x00000101, 0x00000000, 0x00000000, 0x00000000,
|
||||||
x08, x09, x10, x11, x12, x13, x14, x15];
|
0x00020401, 0x00000000, 0x00000000, 0x00000000, 0x40a04001,
|
||||||
|
0x00000000, 0x00000000, 0x00000000]);
|
||||||
|
|
||||||
assert(test0 == [0x10090288, 0x00000000, 0x00000000, 0x00000000,
|
assert(test1 == [0x8c9d190a, 0xce8e4c90, 0x1ef8e9d3, 0x1326a71a, 0x90a20123, 0xead3c4f3, 0x63a091a0, 0xf0708d69,
|
||||||
0x00000101, 0x00000000, 0x00000000, 0x00000000,
|
0x789b010c, 0xd195a681, 0xeb7d5504, 0xa774135c, 0x481c2027,
|
||||||
0x00020401, 0x00000000, 0x00000000, 0x00000000,
|
0x53a8e4b5, 0x4c1f89c5, 0x3f78c9c8]);
|
||||||
0x40a04001, 0x00000000, 0x00000000, 0x00000000]);
|
|
||||||
|
|
||||||
assert(test1 == [0x8c9d190a, 0xce8e4c90, 0x1ef8e9d3, 0x1326a71a,
|
|
||||||
0x90a20123, 0xead3c4f3, 0x63a091a0, 0xf0708d69,
|
|
||||||
0x789b010c, 0xd195a681, 0xeb7d5504, 0xa774135c,
|
|
||||||
0x481c2027, 0x53a8e4b5, 0x4c1f89c5, 0x3f78c9c8]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ubyte[64] salsa20(in ubyte[64] input) pure nothrow @safe @nogc
|
ubyte[64] salsa20(in ubyte[64] input) pure nothrow @safe @nogc
|
||||||
|
@ -224,84 +222,76 @@ ubyte[64] salsa20(in ubyte[64] input) pure nothrow @safe @nogc
|
||||||
x12 = littleEndian(input[48 .. 52]), x13 = littleEndian(input[52 .. 56]),
|
x12 = littleEndian(input[48 .. 52]), x13 = littleEndian(input[52 .. 56]),
|
||||||
x14 = littleEndian(input[56 .. 60]), x15 = littleEndian(input[60 .. 64]);
|
x14 = littleEndian(input[56 .. 60]), x15 = littleEndian(input[60 .. 64]);
|
||||||
|
|
||||||
auto y00 = x00, y01 = x01, y02 = x02, y03 = x03,
|
auto y00 = x00, y01 = x01, y02 = x02, y03 = x03, y04 = x04, y05 = x05,
|
||||||
y04 = x04, y05 = x05, y06 = x06, y07 = x07,
|
y06 = x06, y07 = x07, y08 = x08, y09 = x09, y10 = x10, y11 = x11, y12 = x12,
|
||||||
y08 = x08, y09 = x09, y10 = x10, y11 = x11,
|
y13 = x13, y14 = x14, y15 = x15;
|
||||||
y12 = x12, y13 = x13, y14 = x14, y15 = x15;
|
|
||||||
|
|
||||||
foreach (i; 0 .. 10)
|
foreach (i; 0 .. 10)
|
||||||
{
|
{
|
||||||
mixin(colRound!(x00, x01, x02, x03, x04, x05, x06, x07,
|
mixin(colRound!(x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10,
|
||||||
x08, x09, x10, x11, x12, x13, x14, x15));
|
x11, x12, x13, x14, x15));
|
||||||
|
|
||||||
mixin(rowRound!(x00, x01, x02, x03, x04, x05, x06, x07,
|
mixin(rowRound!(x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10,
|
||||||
x08, x09, x10, x11, x12, x13, x14, x15));
|
x11, x12, x13, x14, x15));
|
||||||
}
|
}
|
||||||
|
|
||||||
return concat!(ubyte[64])(littleEndianInv(x00 + y00),
|
return concat!(ubyte[64])(littleEndianInv(x00 + y00), littleEndianInv(x01 + y01),
|
||||||
littleEndianInv(x01 + y01),
|
littleEndianInv(x02 + y02), littleEndianInv(x03 + y03), littleEndianInv(x04 + y04),
|
||||||
littleEndianInv(x02 + y02),
|
littleEndianInv(x05 + y05), littleEndianInv(x06 + y06), littleEndianInv(x07 + y07),
|
||||||
littleEndianInv(x03 + y03),
|
littleEndianInv(x08 + y08), littleEndianInv(x09 + y09), littleEndianInv(x10 + y10),
|
||||||
littleEndianInv(x04 + y04),
|
littleEndianInv(x11 + y11), littleEndianInv(x12 + y12), littleEndianInv(x13 + y13),
|
||||||
littleEndianInv(x05 + y05),
|
littleEndianInv(x14 + y14), littleEndianInv(x15 + y15));
|
||||||
littleEndianInv(x06 + y06),
|
|
||||||
littleEndianInv(x07 + y07),
|
|
||||||
littleEndianInv(x08 + y08),
|
|
||||||
littleEndianInv(x09 + y09),
|
|
||||||
littleEndianInv(x10 + y10),
|
|
||||||
littleEndianInv(x11 + y11),
|
|
||||||
littleEndianInv(x12 + y12),
|
|
||||||
littleEndianInv(x13 + y13),
|
|
||||||
littleEndianInv(x14 + y14),
|
|
||||||
littleEndianInv(x15 + y15));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@safe unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
ubyte[64] test0 = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
ubyte[64] test0 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
||||||
test0 = salsa20(test0);
|
test0 = salsa20(test0);
|
||||||
|
|
||||||
ubyte[64] test1 = [211,159, 13,115, 76, 55, 82,183, 3,117,222, 37,191,187,234,136,
|
ubyte[64] test1 = [211, 159, 13, 115, 76, 55, 82, 183, 3, 117, 222, 37,
|
||||||
49,237,179, 48, 1,106,178,219,175,199,166, 48, 86, 16,179,207,
|
191, 187, 234, 136, 49, 237, 179, 48, 1, 106, 178, 219, 175, 199,
|
||||||
31,240, 32, 63, 15, 83, 93,161,116,147, 48,113,238, 55,204, 36,
|
166, 48, 86, 16, 179, 207, 31, 240, 32, 63, 15, 83, 93, 161, 116, 147,
|
||||||
79,201,235, 79, 3, 81,156, 47,203, 26,244,243, 88,118,104, 54];
|
48, 113, 238, 55, 204, 36, 79, 201, 235, 79, 3, 81, 156, 47, 203, 26,
|
||||||
|
244, 243, 88, 118, 104, 54];
|
||||||
test1 = salsa20(test1);
|
test1 = salsa20(test1);
|
||||||
|
|
||||||
ubyte[64] test2 = [ 88,118,104, 54, 79,201,235, 79, 3, 81,156, 47,203, 26,244,243,
|
ubyte[64] test2 = [88, 118, 104, 54, 79, 201, 235, 79, 3, 81, 156, 47, 203,
|
||||||
191,187,234,136,211,159, 13,115, 76, 55, 82,183, 3,117,222, 37,
|
26, 244, 243, 191, 187, 234, 136, 211, 159, 13, 115, 76, 55, 82, 183,
|
||||||
86, 16,179,207, 49,237,179, 48, 1,106,178,219,175,199,166, 48,
|
3, 117, 222, 37, 86, 16, 179, 207, 49, 237, 179, 48, 1, 106, 178, 219,
|
||||||
238, 55,204, 36, 31,240, 32, 63, 15, 83, 93,161,116,147, 48,113];
|
175, 199, 166, 48, 238, 55, 204, 36, 31, 240, 32, 63, 15, 83, 93, 161, 116, 147, 48, 113];
|
||||||
test2 = salsa20(test2);
|
test2 = salsa20(test2);
|
||||||
|
|
||||||
ubyte[64] test3 = [ 6,124, 83,146, 38,191, 9, 50, 4,161, 47,222,122,182,223,185,
|
ubyte[64] test3 = [6, 124, 83, 146, 38, 191, 9, 50, 4, 161, 47, 222, 122,
|
||||||
75, 27, 0,216, 16,122, 7, 89,162,104,101,147,213, 21, 54, 95,
|
182, 223, 185, 75, 27, 0, 216, 16, 122, 7, 89, 162, 104, 101, 147, 213,
|
||||||
225,253,139,176,105,132, 23,116, 76, 41,176,207,221, 34,157,108,
|
21, 54, 95, 225, 253, 139, 176, 105, 132, 23, 116, 76, 41, 176, 207,
|
||||||
94, 94, 99, 52, 90,117, 91,220,146,190,239,143,196,176,130,186];
|
221, 34, 157, 108, 94, 94, 99, 52, 90, 117, 91, 220, 146, 190, 239,
|
||||||
|
143, 196, 176, 130, 186];
|
||||||
foreach (i; 0 .. 1_000_000)
|
foreach (i; 0 .. 1_000_000)
|
||||||
test3 = salsa20(test3);
|
test3 = salsa20(test3);
|
||||||
|
|
||||||
assert(test0 == [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
assert(test0 == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
|
||||||
|
|
||||||
assert(test1 == [109, 42,178,168,156,240,248,238,168,196,190,203, 26,110,170,154,
|
assert(test1 == [109, 42, 178, 168, 156, 240, 248, 238, 168, 196, 190, 203,
|
||||||
29, 29,150, 26,150, 30,235,249,190,163,251, 48, 69,144, 51, 57,
|
26, 110, 170, 154, 29, 29, 150, 26, 150, 30, 235, 249, 190, 163,
|
||||||
118, 40,152,157,180, 57, 27, 94,107, 42,236, 35, 27,111,114,114,
|
251, 48, 69, 144, 51, 57, 118, 40, 152, 157, 180, 57, 27, 94,
|
||||||
219,236,232,135,111,155,110, 18, 24,232, 95,158,179, 19, 48,202]);
|
107, 42, 236, 35, 27, 111, 114, 114, 219, 236, 232, 135, 111,
|
||||||
|
155, 110, 18, 24, 232, 95, 158, 179, 19, 48, 202]);
|
||||||
|
|
||||||
assert(test2 == [179, 19, 48,202,219,236,232,135,111,155,110, 18, 24,232, 95,158,
|
assert(test2 == [179, 19, 48, 202, 219, 236, 232, 135, 111, 155, 110, 18,
|
||||||
26,110,170,154,109, 42,178,168,156,240,248,238,168,196,190,203,
|
24, 232, 95, 158, 26, 110, 170, 154, 109, 42, 178, 168, 156, 240,
|
||||||
69,144, 51, 57, 29, 29,150, 26,150, 30,235,249,190,163,251, 48,
|
248, 238, 168, 196, 190, 203, 69, 144, 51, 57, 29, 29, 150, 26,
|
||||||
27,111,114,114,118, 40,152,157,180, 57, 27, 94,107, 42,236, 35]);
|
150, 30, 235, 249, 190, 163, 251, 48, 27, 111, 114, 114, 118, 40,
|
||||||
|
152, 157, 180, 57, 27, 94, 107, 42, 236, 35]);
|
||||||
|
|
||||||
assert(test3 == [ 8, 18, 38,199,119, 76,215, 67,173,127,144,162,103,212,176,217,
|
assert(test3 == [8, 18, 38, 199, 119, 76, 215, 67, 173, 127, 144, 162,
|
||||||
192, 19,233, 33,159,197,154,160,128,243,219, 65,171,136,135,225,
|
103, 212, 176, 217, 192, 19, 233, 33, 159, 197, 154, 160, 128, 243,
|
||||||
123, 11, 68, 86,237, 82, 20,155,133,189, 9, 83,167,116,194, 78,
|
219, 65, 171, 136, 135, 225, 123, 11, 68, 86, 237, 82, 20, 155,
|
||||||
122,127,195,185,185,204,188, 90,245, 9,183,248,226, 85,245,104]);
|
133, 189, 9, 83, 167, 116, 194, 78, 122, 127, 195, 185, 185, 204,
|
||||||
|
188, 90, 245, 9, 183, 248, 226, 85, 245, 104]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static immutable ubyte[4] sigma0 = [101, 120, 112, 97];
|
static immutable ubyte[4] sigma0 = [101, 120, 112, 97];
|
||||||
|
@ -311,27 +301,22 @@ static immutable ubyte[4] sigma3 = [116, 101, 32, 107];
|
||||||
|
|
||||||
ubyte[64] salsa20Exp(in ref ubyte[32] key, in ubyte[16] n) @safe pure nothrow @nogc
|
ubyte[64] salsa20Exp(in ref ubyte[32] key, in ubyte[16] n) @safe pure nothrow @nogc
|
||||||
{
|
{
|
||||||
return salsa20(concat!(ubyte[64])(sigma0,
|
return salsa20(concat!(ubyte[64])(sigma0, key[0 .. 16], sigma1, n,
|
||||||
key[0..16],
|
sigma2, key[16 .. $], sigma3));
|
||||||
sigma1,
|
|
||||||
n,
|
|
||||||
sigma2,
|
|
||||||
key[16..$],
|
|
||||||
sigma3));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@safe unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
immutable ubyte[32] key = [ 1, 2, 3, 4, 5, 6, 7, 8,
|
immutable ubyte[32] key = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||||
9, 10, 11, 12, 13, 14, 15, 16,
|
15, 16, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216];
|
||||||
201,202,203,204,205,206,207,208,
|
|
||||||
209,210,211,212,213,214,215,216];
|
|
||||||
|
|
||||||
immutable ubyte[16] n = [101,102,103,104,105,106,107,108,
|
immutable ubyte[16] n = [
|
||||||
109,110,111,112,113,114,115,116];
|
101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116
|
||||||
|
];
|
||||||
|
|
||||||
assert(salsa20Exp(key, n) == [ 69, 37, 68, 39, 41, 15,107,193,255,139,122, 6,170,233,217, 98,
|
assert(salsa20Exp(key, n) == [69, 37, 68, 39, 41, 15, 107, 193, 255, 139,
|
||||||
89,144,182,106, 21, 51,200, 65,239, 49,222, 34,215,114, 40,126,
|
122, 6, 170, 233, 217, 98, 89, 144, 182, 106, 21, 51, 200, 65, 239,
|
||||||
104,197, 7,225,197,153, 31, 2,102, 78, 76,176, 84,245,246,184,
|
49, 222, 34, 215, 114, 40, 126, 104, 197, 7, 225, 197, 153, 31,
|
||||||
177,160,133,130, 6, 72,149,119,192,195,132,236,234,103,246, 74]);
|
2, 102, 78, 76, 176, 84, 245, 246, 184, 177, 160, 133, 130, 6, 72,
|
||||||
|
149, 119, 192, 195, 132, 236, 234, 103, 246, 74]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,8 @@ auto concat(T : E[n], E, size_t n)(in E[][] args...) @nogc
|
||||||
{
|
{
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
T result = void;
|
T result = void;
|
||||||
foreach(arr; args) {
|
foreach (arr; args)
|
||||||
|
{
|
||||||
result[offset .. offset + arr.length] = arr;
|
result[offset .. offset + arr.length] = arr;
|
||||||
offset += arr.length;
|
offset += arr.length;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue