further optimizations
This commit is contained in:
parent
20dc2ff534
commit
e51b852a39
2 changed files with 55 additions and 96 deletions
137
source/salsa20.d
137
source/salsa20.d
|
@ -1,10 +1,14 @@
|
||||||
module salsa20;
|
module salsa20;
|
||||||
|
|
||||||
private import std.string : format;
|
private:
|
||||||
private import std.range : isInputRange, isForwardRange, ElementType;
|
|
||||||
private import std.array;
|
import std.string : format;
|
||||||
|
import std.range : isInputRange, isForwardRange, ElementType;
|
||||||
|
import std.array;
|
||||||
|
|
||||||
|
import bitmanip;
|
||||||
|
import utility;
|
||||||
|
|
||||||
private import bitmanip;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -35,10 +39,7 @@ auto salsa20Cipher(R)(R range, ubyte[32] key, ubyte[8] nonce)
|
||||||
salsaSection.popFront();
|
salsaSection.popFront();
|
||||||
if (salsaSection.empty)
|
if (salsaSection.empty)
|
||||||
{
|
{
|
||||||
ubyte[16] n;
|
salsaSection = salsa20Exp(key, concat!(ubyte[16])(nonce, littleEndianInv(++count)));
|
||||||
n[0..8] = nonce;
|
|
||||||
n[8..16] = littleEndianInv(0UL);
|
|
||||||
salsaSection = salsa20Exp(key, n).dup;
|
|
||||||
}
|
}
|
||||||
range.popFront();
|
range.popFront();
|
||||||
}
|
}
|
||||||
|
@ -50,10 +51,7 @@ auto salsa20Cipher(R)(R range, ubyte[32] key, ubyte[8] nonce)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ubyte[16] n;
|
return rangeResult(0UL, range, salsa20Exp(key, concat!(ubyte[16])(nonce, littleEndianInv(0UL))).dup);
|
||||||
n[0..8] = nonce;
|
|
||||||
n[8..16] = littleEndianInv(0UL);
|
|
||||||
return rangeResult(0UL, range, salsa20Exp(key, n).dup);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -66,7 +64,7 @@ enum string quarterRound(alias _x0, alias _x1, alias _x2, alias _x3) = q{
|
||||||
}.format(__traits(identifier, _x0), __traits(identifier, _x1),
|
}.format(__traits(identifier, _x0), __traits(identifier, _x1),
|
||||||
__traits(identifier, _x2), __traits(identifier, _x3));
|
__traits(identifier, _x2), __traits(identifier, _x3));
|
||||||
|
|
||||||
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,
|
||||||
|
@ -110,7 +108,7 @@ enum string rowRound(alias _x00, alias _x01, alias _x02, alias _x03,
|
||||||
__traits(identifier, _x12), __traits(identifier, _x13),
|
__traits(identifier, _x12), __traits(identifier, _x13),
|
||||||
__traits(identifier, _x14), __traits(identifier, _x15));
|
__traits(identifier, _x14), __traits(identifier, _x15));
|
||||||
|
|
||||||
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,
|
||||||
|
@ -162,7 +160,7 @@ enum string colRound(alias _x00, alias _x01, alias _x02, alias _x03,
|
||||||
__traits(identifier, _x12), __traits(identifier, _x13),
|
__traits(identifier, _x12), __traits(identifier, _x13),
|
||||||
__traits(identifier, _x14), __traits(identifier, _x15));
|
__traits(identifier, _x14), __traits(identifier, _x15));
|
||||||
|
|
||||||
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,
|
||||||
|
@ -198,16 +196,7 @@ unittest
|
||||||
0x481c2027, 0x53a8e4b5, 0x4c1f89c5, 0x3f78c9c8]);
|
0x481c2027, 0x53a8e4b5, 0x4c1f89c5, 0x3f78c9c8]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ubyte[64] salsa20(in ubyte[64] input) pure nothrow @safe
|
ubyte[64] salsa20(in ubyte[64] input) pure nothrow @safe @nogc
|
||||||
/*in
|
|
||||||
{
|
|
||||||
assert(input.length == 64);
|
|
||||||
}
|
|
||||||
out(result)
|
|
||||||
{
|
|
||||||
assert(result.length == 64);
|
|
||||||
}
|
|
||||||
body*/
|
|
||||||
{
|
{
|
||||||
auto x00 = littleEndian(input[00..04]), x01 = littleEndian(input[04..08]),
|
auto x00 = littleEndian(input[00..04]), x01 = littleEndian(input[04..08]),
|
||||||
x02 = littleEndian(input[08..12]), x03 = littleEndian(input[12..16]),
|
x02 = littleEndian(input[08..12]), x03 = littleEndian(input[12..16]),
|
||||||
|
@ -232,35 +221,25 @@ body*/
|
||||||
x08, x09, x10, x11, x12, x13, x14, x15));
|
x08, x09, x10, x11, x12, x13, x14, x15));
|
||||||
}
|
}
|
||||||
|
|
||||||
ubyte[64] buf;
|
return concat!(ubyte[64])(littleEndianInv(x00 + y00),
|
||||||
buf[00..04] = littleEndianInv(x00 + y00);
|
littleEndianInv(x01 + y01),
|
||||||
buf[04..08] = littleEndianInv(x01 + y01);
|
littleEndianInv(x02 + y02),
|
||||||
buf[08..12] = littleEndianInv(x02 + y02);
|
littleEndianInv(x03 + y03),
|
||||||
buf[12..16] = littleEndianInv(x03 + y03);
|
littleEndianInv(x04 + y04),
|
||||||
buf[16..20] = littleEndianInv(x04 + y04);
|
littleEndianInv(x05 + y05),
|
||||||
buf[20..24] = littleEndianInv(x05 + y05);
|
littleEndianInv(x06 + y06),
|
||||||
buf[24..28] = littleEndianInv(x06 + y06);
|
littleEndianInv(x07 + y07),
|
||||||
buf[28..32] = littleEndianInv(x07 + y07);
|
littleEndianInv(x08 + y08),
|
||||||
buf[32..36] = littleEndianInv(x08 + y08);
|
littleEndianInv(x09 + y09),
|
||||||
buf[36..40] = littleEndianInv(x09 + y09);
|
littleEndianInv(x10 + y10),
|
||||||
buf[40..44] = littleEndianInv(x10 + y10);
|
littleEndianInv(x11 + y11),
|
||||||
buf[44..48] = littleEndianInv(x11 + y11);
|
littleEndianInv(x12 + y12),
|
||||||
buf[48..52] = littleEndianInv(x12 + y12);
|
littleEndianInv(x13 + y13),
|
||||||
buf[52..56] = littleEndianInv(x13 + y13);
|
littleEndianInv(x14 + y14),
|
||||||
buf[56..60] = littleEndianInv(x14 + y14);
|
littleEndianInv(x15 + y15));
|
||||||
buf[60..64] = littleEndianInv(x15 + y15);
|
|
||||||
return buf;
|
|
||||||
/* return littleEndianInv(x00 + y00) ~ littleEndianInv(x01 + y01) ~
|
|
||||||
littleEndianInv(x02 + y02) ~ littleEndianInv(x03 + y03) ~
|
|
||||||
littleEndianInv(x04 + y04) ~ littleEndianInv(x05 + y05) ~
|
|
||||||
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);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
@ -313,55 +292,21 @@ static immutable ubyte[4] sigma1 = [110, 100, 32, 51];
|
||||||
static immutable ubyte[4] sigma2 = [ 50, 45, 98, 121];
|
static immutable ubyte[4] sigma2 = [ 50, 45, 98, 121];
|
||||||
static immutable ubyte[4] sigma3 = [116, 101, 32, 107];
|
static immutable ubyte[4] sigma3 = [116, 101, 32, 107];
|
||||||
|
|
||||||
import std.range;
|
ubyte[64] salsa20Exp(in ubyte[32] key, in ubyte[16] n) @safe pure nothrow @nogc
|
||||||
import std.algorithm;
|
{
|
||||||
import std.typetuple;
|
return salsa20(concat!(ubyte[64])(sigma0,
|
||||||
|
key[0..16],
|
||||||
template expand(alias A, alias C="A[I]") {
|
sigma1,
|
||||||
auto ref M(alias I)() @property { return mixin(C); }
|
n,
|
||||||
mixin(q{alias expand = TypeTuple!(}
|
sigma2,
|
||||||
~ iota(A.length).map!q{"M!"~text(a)}().join(",")
|
key[16..$],
|
||||||
~ q{);});
|
sigma3));
|
||||||
}
|
}
|
||||||
|
|
||||||
ubyte[64] salsa20Exp(in ubyte[32] key, in ubyte[16] n) @safe pure nothrow
|
@safe unittest
|
||||||
/*in
|
|
||||||
{
|
|
||||||
assert(key.length == 32);
|
|
||||||
assert(n.length == 16);
|
|
||||||
}
|
|
||||||
out(result)
|
|
||||||
{
|
|
||||||
assert(result.length == 64);
|
|
||||||
}
|
|
||||||
body*/
|
|
||||||
{
|
|
||||||
ubyte[64] buf = [
|
|
||||||
expand!sigma0,
|
|
||||||
expand!key[0..16],
|
|
||||||
expand!sigma1,
|
|
||||||
expand!n,
|
|
||||||
expand!sigma2,
|
|
||||||
expand!key[16..$],
|
|
||||||
expand!sigma3
|
|
||||||
];
|
|
||||||
/* buf[0..4] = sigma0;
|
|
||||||
buf[4..20] = key[0..16];
|
|
||||||
buf[20..24] = sigma1;
|
|
||||||
buf[24..40] = n;
|
|
||||||
buf[40..44] = sigma2;
|
|
||||||
buf[44..60] = key[16..$];
|
|
||||||
buf[60..64] = sigma3;*/
|
|
||||||
return salsa20(buf);
|
|
||||||
//return salsa20(σ0 ~ key[0..16] ~ σ1 ~ n ~ σ2 ~ key[16..$] ~ σ3);
|
|
||||||
}
|
|
||||||
|
|
||||||
unittest
|
|
||||||
{
|
{
|
||||||
ubyte[32] key;
|
ubyte[32] key;
|
||||||
ubyte[16] n;
|
ubyte[16] n;
|
||||||
/* key.length = 32;
|
|
||||||
n.length = 16;*/
|
|
||||||
foreach (i; 0..16)
|
foreach (i; 0..16)
|
||||||
key[i] = cast(ubyte)(i + 1);
|
key[i] = cast(ubyte)(i + 1);
|
||||||
foreach (i; 16..32)
|
foreach (i; 16..32)
|
||||||
|
|
14
source/utility.d
Normal file
14
source/utility.d
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
module utility;
|
||||||
|
|
||||||
|
auto concat(T : E[n], E, size_t n)(in E[][] args...) @nogc
|
||||||
|
{
|
||||||
|
size_t offset = 0;
|
||||||
|
T result = void;
|
||||||
|
foreach(arr; args) {
|
||||||
|
result[offset .. offset+arr.length] = arr;
|
||||||
|
offset += arr.length;
|
||||||
|
}
|
||||||
|
assert(offset == result.length);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue