diff --git a/source/bitmanip.d b/source/bitmanip.d index bafb3cb..1d4f5cb 100644 --- a/source/bitmanip.d +++ b/source/bitmanip.d @@ -1,6 +1,7 @@ module bitmanip; private import std.traits : isUnsigned; +private import std.bitmanip : nativeToLittleEndian, littleEndianToNative; UIntType rotateLeft(UIntType)(in UIntType val, in size_t len) nothrow @nogc pure @safe if(isUnsigned!UIntType) @@ -35,3 +36,26 @@ unittest assert(test[2].rotateRight(1) == 64); assert(test[2].rotateRight(7) == 1); } + +alias littleEndianInv = nativeToLittleEndian; + +uint littleEndian(in ubyte[] input) @safe pure nothrow @nogc +in +{ + assert(input.length == uint.sizeof); +} +body +{ + ubyte[uint.sizeof] buf = input; + return littleEndianToNative!uint(buf); +} + +unittest +{ + ubyte[] test0 = [0, 0, 0, 0]; + ubyte[] test1 = [86, 75, 30, 9]; + ubyte[] test2 = [255, 255, 255, 250]; + assert(littleEndian(test0) == 0x00000000); + assert(littleEndian(test1) == 0x091e4b56); + assert(littleEndian(test2) == 0xfaffffff); +} diff --git a/source/chacha20.d b/source/chacha20.d index f472b7d..9ebb82e 100644 --- a/source/chacha20.d +++ b/source/chacha20.d @@ -3,9 +3,9 @@ module chacha20; private import std.string : format; private import std.range : isInputRange, isForwardRange, ElementType; private import std.array; +private import std.traits : hasElaborateCopyConstructor; private import bitmanip; -private import endian; public: @@ -54,7 +54,7 @@ auto chacha20Cipher(R)(R range, ubyte[32] key, ubyte[8] nonce) } range.popFront(); } - static if(isForwardRange!R) + static if (isForwardRange!R) { auto save() @property { @@ -67,6 +67,13 @@ auto chacha20Cipher(R)(R range, ubyte[32] key, ubyte[8] nonce) return copy; } } + + // We need this, so choose works with, if hasElaborateCopyConstructor!R + static if (hasElaborateCopyConstructor!R) + this(this) + { + + } } return rangeResult(range, key, nonce); } diff --git a/source/cipher.d b/source/cipher.d index cddfc9c..e693e7b 100644 --- a/source/cipher.d +++ b/source/cipher.d @@ -1,6 +1,6 @@ module cipher; -private import std.range : isInputRange, ElementType; +private import std.range : isInputRange, ElementType, chooseAmong; private import salsa20; private import chacha20; import std.stdio; @@ -16,12 +16,7 @@ enum Cipher auto cipherFunction(R)(R range, ubyte[32] key, ubyte[8] nonce, Cipher cipher) if(isInputRange!R && is(ElementType!R : ubyte)) { - final switch(cipher) - { - case Cipher.salsa20: - return range.salsa20Cipher(key, nonce); - - case Cipher.chacha20: - return range.salsa20Cipher(key, nonce); - } + return chooseAmong(cipher, + range.salsa20Cipher(key, nonce), + range.chacha20Cipher(key, nonce)); } diff --git a/source/endian.d b/source/endian.d index 322852c..8b13789 100644 --- a/source/endian.d +++ b/source/endian.d @@ -1,24 +1 @@ -private import std.bitmanip : nativeToLittleEndian, littleEndianToNative; -alias littleEndianInv = nativeToLittleEndian; - -uint littleEndian(in ubyte[] input) @safe pure nothrow @nogc -in -{ - assert(input.length == uint.sizeof); -} -body -{ - ubyte[uint.sizeof] buf = input; - return littleEndianToNative!uint(buf); -} - -unittest -{ - ubyte[] test0 = [0, 0, 0, 0]; - ubyte[] test1 = [86, 75, 30, 9]; - ubyte[] test2 = [255, 255, 255, 250]; - assert(littleEndian(test0) == 0x00000000); - assert(littleEndian(test1) == 0x091e4b56); - assert(littleEndian(test2) == 0xfaffffff); -} diff --git a/source/salsa20.d b/source/salsa20.d index a2cc631..0030d1a 100644 --- a/source/salsa20.d +++ b/source/salsa20.d @@ -3,9 +3,9 @@ module salsa20; private import std.string : format; private import std.range : isInputRange, isForwardRange, ElementType; private import std.array; +private import std.traits : hasElaborateCopyConstructor; private import bitmanip; -private import endian; public: @@ -52,7 +52,7 @@ auto salsa20Cipher(R)(R range, ubyte[32] key, ubyte[8] nonce) } range.popFront(); } - static if(isForwardRange!R) + static if (isForwardRange!R) { auto save() @property { @@ -65,7 +65,16 @@ auto salsa20Cipher(R)(R range, ubyte[32] key, ubyte[8] nonce) return copy; } } + + // We need this, so choose works with, if hasElaborateCopyConstructor!R + static if (hasElaborateCopyConstructor!R) + this(this) + { + + } + } + return rangeResult(range, key, nonce); }