Moved bit-rotation functions to a separate module and fixed 'statement not reachable' warnings
This commit is contained in:
parent
826aad7786
commit
a2ea77f667
4 changed files with 46 additions and 22 deletions
37
source/bitmanip.d
Normal file
37
source/bitmanip.d
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
module bitmanip;
|
||||||
|
|
||||||
|
private import std.traits : isUnsigned;
|
||||||
|
|
||||||
|
UIntType rotateLeft(UIntType)(in UIntType val, in size_t len) nothrow @nogc pure
|
||||||
|
if(isUnsigned!UIntType)
|
||||||
|
{
|
||||||
|
auto reducedLen = len % (8 * UIntType.sizeof);
|
||||||
|
// TODO: ensure the compiler does not create different code paths here
|
||||||
|
return cast(UIntType)((val << reducedLen) | (val >> (8 * UIntType.sizeof - reducedLen)));
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
ubyte[] test = [0, 1, 128];
|
||||||
|
assert(test[0].rotateLeft(1) == 0);
|
||||||
|
assert(test[1].rotateLeft(1) == 2);
|
||||||
|
assert(test[2].rotateLeft(1) == 1);
|
||||||
|
assert(test[1].rotateLeft(7) == 128);
|
||||||
|
}
|
||||||
|
|
||||||
|
UIntType rotateRight(UIntType)(in UIntType val, in size_t len) nothrow @nogc pure
|
||||||
|
if(isUnsigned!UIntType)
|
||||||
|
{
|
||||||
|
auto reducedLen = len % (8 * UIntType.sizeof);
|
||||||
|
// TODO: ensure the compiler does not create different code paths here
|
||||||
|
return cast(UIntType)((val >> reducedLen) | (val << (8 * UIntType.sizeof - reducedLen)));
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
ubyte[] test = [0, 1, 128];
|
||||||
|
assert(test[0].rotateRight(1) == 0);
|
||||||
|
assert(test[1].rotateRight(1) == 128);
|
||||||
|
assert(test[2].rotateRight(1) == 64);
|
||||||
|
assert(test[2].rotateRight(7) == 1);
|
||||||
|
}
|
|
@ -1,11 +1,12 @@
|
||||||
module chacha20;
|
module chacha20;
|
||||||
|
|
||||||
private import std.traits : isUnsigned;
|
|
||||||
private import std.string : format;
|
private import std.string : format;
|
||||||
private import std.range : isInputRange, isForwardRange, ElementType;
|
private import std.range : isInputRange, isForwardRange, ElementType;
|
||||||
private import std.bitmanip : nativeToLittleEndian, littleEndianToNative;
|
private import std.bitmanip : nativeToLittleEndian, littleEndianToNative;
|
||||||
private import std.array;
|
private import std.array;
|
||||||
|
|
||||||
|
private import bitmanip;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// TODO: Create unittests!!!!
|
// TODO: Create unittests!!!!
|
||||||
|
@ -72,14 +73,6 @@ auto chacha20Cipher(R)(R range, ubyte[32] key, ubyte[8] nonce)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
UIntType rotateLeft(UIntType)(in UIntType val, in size_t len) nothrow @nogc pure
|
|
||||||
if(isUnsigned!UIntType)
|
|
||||||
{
|
|
||||||
auto reducedLen = len % (8 * UIntType.sizeof);
|
|
||||||
// TODO: ensure the compiler does not create different code paths here
|
|
||||||
return cast(UIntType)((val << reducedLen) | (val >> (8 * UIntType.sizeof - reducedLen)));
|
|
||||||
}
|
|
||||||
|
|
||||||
enum string quarterRound(alias _x0, alias _x1, alias _x2, alias _x3) = q{
|
enum string quarterRound(alias _x0, alias _x1, alias _x2, alias _x3) = q{
|
||||||
%1$s += %2$s; %4$s ^= %1$s; %4$s = rotateLeft(%4$s, 16);
|
%1$s += %2$s; %4$s ^= %1$s; %4$s = rotateLeft(%4$s, 16);
|
||||||
%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);
|
||||||
|
@ -228,7 +221,7 @@ in
|
||||||
}
|
}
|
||||||
body
|
body
|
||||||
{
|
{
|
||||||
ubyte buf[uint.sizeof] = input;
|
ubyte[uint.sizeof] buf = input;
|
||||||
return littleEndianToNative!uint(buf);
|
return littleEndianToNative!uint(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,12 @@ module cipher;
|
||||||
private import std.range : isInputRange, ElementType;
|
private import std.range : isInputRange, ElementType;
|
||||||
private import salsa20;
|
private import salsa20;
|
||||||
private import chacha20;
|
private import chacha20;
|
||||||
|
import std.stdio;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum Cipher {
|
enum Cipher
|
||||||
|
{
|
||||||
salsa20,
|
salsa20,
|
||||||
chacha20
|
chacha20
|
||||||
}
|
}
|
||||||
|
@ -18,10 +20,8 @@ auto cipherFunction(R)(R range, ubyte[32] key, ubyte[8] nonce, Cipher cipher)
|
||||||
{
|
{
|
||||||
case Cipher.salsa20:
|
case Cipher.salsa20:
|
||||||
return salsa20Cipher(range, key, nonce);
|
return salsa20Cipher(range, key, nonce);
|
||||||
break;
|
|
||||||
|
|
||||||
case Cipher.chacha20:
|
case Cipher.chacha20:
|
||||||
return salsa20Cipher(range, key, nonce);
|
return salsa20Cipher(range, key, nonce);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ private import std.range : isInputRange, isForwardRange, ElementType;
|
||||||
private import std.bitmanip : nativeToLittleEndian, littleEndianToNative;
|
private import std.bitmanip : nativeToLittleEndian, littleEndianToNative;
|
||||||
private import std.array;
|
private import std.array;
|
||||||
|
|
||||||
|
private import bitmanip;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
auto salsa20Cipher(R)(R range, ubyte[32] key, ubyte[8] nonce)
|
auto salsa20Cipher(R)(R range, ubyte[32] key, ubyte[8] nonce)
|
||||||
|
@ -70,14 +72,6 @@ auto salsa20Cipher(R)(R range, ubyte[32] key, ubyte[8] nonce)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
UIntType rotateLeft(UIntType)(in UIntType val, in size_t len)
|
|
||||||
if(isUnsigned!UIntType)
|
|
||||||
{
|
|
||||||
auto reducedLen = len % (8 * UIntType.sizeof);
|
|
||||||
// TODO: ensure the compiler does not create different code paths here
|
|
||||||
return cast(UIntType)((val << reducedLen) | (val >> (8 * UIntType.sizeof - reducedLen)));
|
|
||||||
}
|
|
||||||
|
|
||||||
enum string quarterRound(alias _x0, alias _x1, alias _x2, alias _x3) = q{
|
enum string quarterRound(alias _x0, alias _x1, alias _x2, alias _x3) = q{
|
||||||
%2$s ^= (%1$s + %4$s).rotateLeft(7);
|
%2$s ^= (%1$s + %4$s).rotateLeft(7);
|
||||||
%3$s ^= (%2$s + %1$s).rotateLeft(9);
|
%3$s ^= (%2$s + %1$s).rotateLeft(9);
|
||||||
|
@ -227,7 +221,7 @@ in
|
||||||
}
|
}
|
||||||
body
|
body
|
||||||
{
|
{
|
||||||
ubyte buf[uint.sizeof] = input;
|
ubyte[uint.sizeof] buf = input;
|
||||||
return littleEndianToNative!uint(buf);
|
return littleEndianToNative!uint(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue