Fixed some endianess stuff and added bufferedChunks function
This commit is contained in:
parent
f09a006b27
commit
62ccd373ab
4 changed files with 203 additions and 45 deletions
|
@ -2,7 +2,7 @@ module bitmanip;
|
|||
|
||||
private import std.traits : isUnsigned;
|
||||
|
||||
private import std.bitmanip : nativeToLittleEndian, littleEndianToNative, nativeToBigEndian, bigEndianToNative;
|
||||
private import std.bitmanip : nativeToLittleEndian, littleEndianToNative;
|
||||
|
||||
UIntType rotateLeft(UIntType)(in UIntType val, in size_t len) nothrow @nogc pure @safe
|
||||
if (isUnsigned!UIntType)
|
||||
|
@ -48,26 +48,3 @@ body
|
|||
ubyte[uint.sizeof] buf = input;
|
||||
return littleEndianToNative!uint(buf);
|
||||
}
|
||||
|
||||
alias bigEndianInv = nativeToBigEndian;
|
||||
|
||||
uint bigEndian(in ubyte[] input) @safe pure nothrow @nogc
|
||||
in
|
||||
{
|
||||
assert(input.length == uint.sizeof);
|
||||
}
|
||||
body
|
||||
{
|
||||
ubyte[uint.sizeof] buf = input;
|
||||
return bigEndianToNative!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);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,8 @@ auto chacha20Cipher(R)(R range, ubyte[32] key, ubyte[8] nonce)
|
|||
assert(!empty);
|
||||
if (++chachaCounter == 64)
|
||||
{
|
||||
chachaSection = chacha20Exp(key, concat!(ubyte[16])(bigEndianInv(++count), nonce));
|
||||
chachaSection = chacha20Exp(key,
|
||||
concat!(ubyte[16])(littleEndianInv(++count), nonce));
|
||||
chachaCounter = 0;
|
||||
}
|
||||
range.popFront();
|
||||
|
|
|
@ -41,7 +41,7 @@ auto salsa20Cipher(R)(R range, ubyte[32] key, ubyte[8] nonce)
|
|||
if (++salsaCounter == 64)
|
||||
{
|
||||
salsaSection = salsa20Exp(key, concat!(ubyte[16])(nonce,
|
||||
bigEndianInv(++count)));
|
||||
littleEndianInv(++count)));
|
||||
salsaCounter = 0;
|
||||
}
|
||||
range.popFront();
|
||||
|
@ -81,9 +81,9 @@ enum string quarterRound(alias _x0, alias _x1, alias _x2, alias _x3) = q{
|
|||
%2$s ^= (%1$s + %4$s).rotateLeft(7);
|
||||
%3$s ^= (%2$s + %1$s).rotateLeft(9);
|
||||
%4$s ^= (%3$s + %2$s).rotateLeft(13);
|
||||
%1$s ^= (%4$s + %3$s).rotateLeft(18);
|
||||
}.format(__traits(identifier, _x0),
|
||||
__traits(identifier, _x1), __traits(identifier, _x2), __traits(identifier, _x3));
|
||||
%1$s ^= (%4$s + %3$s).rotateLeft(18);}
|
||||
.format(__traits(identifier, _x0),
|
||||
__traits(identifier, _x1), __traits(identifier, _x2), __traits(identifier, _x3));
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
|
@ -117,14 +117,13 @@ enum string rowRound(alias _x00, alias _x01, alias _x02, alias _x03, alias _x04,
|
|||
mixin(quarterRound!(%1$s, %2$s, %3$s, %4$s));
|
||||
mixin(quarterRound!(%6$s, %7$s, %8$s, %5$s));
|
||||
mixin(quarterRound!(%11$s, %12$s, %9$s, %10$s));
|
||||
mixin(quarterRound!(%16$s, %13$s, %14$s, %15$s));
|
||||
}.format(
|
||||
__traits(identifier, _x00), __traits(identifier,
|
||||
_x01), __traits(identifier, _x02), __traits(identifier, _x03),
|
||||
__traits(identifier, _x04), __traits(identifier, _x05), __traits(identifier, _x06),
|
||||
__traits(identifier, _x07), __traits(identifier, _x08), __traits(identifier, _x09),
|
||||
__traits(identifier, _x10), __traits(identifier, _x11), __traits(identifier, _x12),
|
||||
__traits(identifier, _x13), __traits(identifier, _x14), __traits(identifier, _x15));
|
||||
mixin(quarterRound!(%16$s, %13$s, %14$s, %15$s));}
|
||||
.format(__traits(identifier, _x00), __traits(identifier, _x01),
|
||||
__traits(identifier, _x02), __traits(identifier, _x03), __traits(identifier, _x04),
|
||||
__traits(identifier, _x05), __traits(identifier, _x06), __traits(identifier, _x07),
|
||||
__traits(identifier, _x08), __traits(identifier, _x09), __traits(identifier, _x10),
|
||||
__traits(identifier, _x11), __traits(identifier, _x12), __traits(identifier,
|
||||
_x13), __traits(identifier, _x14), __traits(identifier, _x15));
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
|
@ -167,14 +166,13 @@ enum string colRound(alias _x00, alias _x01, alias _x02, alias _x03, alias _x04,
|
|||
mixin(quarterRound!(%1$s, %5$s, %9$s, %13$s));
|
||||
mixin(quarterRound!(%6$s, %10$s, %14$s, %2$s));
|
||||
mixin(quarterRound!(%11$s, %15$s, %3$s, %7$s));
|
||||
mixin(quarterRound!(%16$s, %4$s, %8$s, %12$s));
|
||||
}.format(
|
||||
__traits(identifier, _x00), __traits(identifier,
|
||||
_x01), __traits(identifier, _x02), __traits(identifier, _x03),
|
||||
__traits(identifier, _x04), __traits(identifier, _x05), __traits(identifier, _x06),
|
||||
__traits(identifier, _x07), __traits(identifier, _x08), __traits(identifier, _x09),
|
||||
__traits(identifier, _x10), __traits(identifier, _x11), __traits(identifier, _x12),
|
||||
__traits(identifier, _x13), __traits(identifier, _x14), __traits(identifier, _x15));
|
||||
mixin(quarterRound!(%16$s, %4$s, %8$s, %12$s));}
|
||||
.format(__traits(identifier, _x00), __traits(identifier, _x01),
|
||||
__traits(identifier, _x02), __traits(identifier, _x03), __traits(identifier, _x04),
|
||||
__traits(identifier, _x05), __traits(identifier, _x06), __traits(identifier, _x07),
|
||||
__traits(identifier, _x08), __traits(identifier, _x09), __traits(identifier, _x10),
|
||||
__traits(identifier, _x11), __traits(identifier, _x12), __traits(identifier,
|
||||
_x13), __traits(identifier, _x14), __traits(identifier, _x15));
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
|
|
182
source/utility.d
182
source/utility.d
|
@ -1,5 +1,8 @@
|
|||
module utility;
|
||||
|
||||
private import std.range : isInputRange, isInfinite, isForwardRange,
|
||||
ElementType;
|
||||
|
||||
auto concat(T : E[n], E, size_t n)(in E[][] args...) @nogc
|
||||
{
|
||||
size_t offset = 0;
|
||||
|
@ -26,3 +29,182 @@ auto concat(T : E[n], E, size_t n)(in E[][] args...) @nogc
|
|||
assert(concat!(int[6])([1], [2, 3], [4, 5, 6]) == [1, 2, 3, 4, 5, 6]);
|
||||
assert(concat!(char[12])("Hello", " ", "World!") == "Hello World!");
|
||||
}
|
||||
|
||||
auto bufferedChunks(Source)(Source source, size_t chunkSize)
|
||||
if (isInputRange!Source)
|
||||
{
|
||||
static struct BufferedChunks
|
||||
{
|
||||
this(Source source, size_t chunkSize)
|
||||
{
|
||||
assert(chunkSize != 0, "Cannot create a Chunk with an empty chunkSize");
|
||||
this.source = source;
|
||||
this.chunkSize = chunkSize;
|
||||
buffer.length = chunkSize;
|
||||
foreach (i; 0 .. chunkSize)
|
||||
{
|
||||
if (!this.source.empty)
|
||||
{
|
||||
buffer[i] = this.source.front;
|
||||
this.source.popFront;
|
||||
bufferLength++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto front() @property
|
||||
{
|
||||
assert(!empty);
|
||||
return buffer[0 .. bufferLength];
|
||||
}
|
||||
|
||||
void popFront()
|
||||
{
|
||||
assert(!empty);
|
||||
bufferLength = 0;
|
||||
if (!source.empty)
|
||||
{
|
||||
foreach (i; 0 .. chunkSize)
|
||||
{
|
||||
if (!source.empty)
|
||||
{
|
||||
buffer[i] = source.front;
|
||||
source.popFront;
|
||||
bufferLength++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static if (isInfinite!Source)
|
||||
{
|
||||
enum empty = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool empty() @property
|
||||
{
|
||||
return bufferLength == 0;
|
||||
}
|
||||
}
|
||||
|
||||
static if (isForwardRange!Source)
|
||||
{
|
||||
auto save()
|
||||
{
|
||||
auto ret = this;
|
||||
ret.source = source.save;
|
||||
ret.buffer = buffer.dup;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Source source;
|
||||
size_t chunkSize;
|
||||
ElementType!Source[] buffer;
|
||||
size_t bufferLength;
|
||||
}
|
||||
|
||||
return BufferedChunks(source, chunkSize);
|
||||
}
|
||||
|
||||
version (unittest) private import std.array;
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
int[] testArray;
|
||||
auto _bufferedChunks = bufferedChunks(testArray, 1);
|
||||
assert(_bufferedChunks.empty);
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
int[] testArray;
|
||||
auto _bufferedChunks = bufferedChunks(testArray, 2);
|
||||
assert(_bufferedChunks.empty);
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
auto _bufferedChunks = bufferedChunks([0], 1);
|
||||
assert(_bufferedChunks.front == [0]);
|
||||
_bufferedChunks.popFront;
|
||||
assert(_bufferedChunks.empty);
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
auto _bufferedChunks = bufferedChunks([0], 2);
|
||||
assert(_bufferedChunks.front == [0]);
|
||||
_bufferedChunks.popFront;
|
||||
assert(_bufferedChunks.empty);
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
auto _bufferedChunks = bufferedChunks([0, 1], 1);
|
||||
assert(_bufferedChunks.front == [0]);
|
||||
_bufferedChunks.popFront;
|
||||
assert(_bufferedChunks.front == [1]);
|
||||
_bufferedChunks.popFront;
|
||||
assert(_bufferedChunks.empty);
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
auto _bufferedChunks = bufferedChunks([0, 1], 2);
|
||||
assert(_bufferedChunks.front == [0, 1]);
|
||||
_bufferedChunks.popFront;
|
||||
assert(_bufferedChunks.empty);
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
auto _bufferedChunks = bufferedChunks([0, 1, 2], 2);
|
||||
assert(_bufferedChunks.front == [0, 1]);
|
||||
_bufferedChunks.popFront;
|
||||
assert(_bufferedChunks.front == [2]);
|
||||
_bufferedChunks.popFront;
|
||||
assert(_bufferedChunks.empty);
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
auto _bufferedChunks = bufferedChunks([0, 1, 2, 3], 2);
|
||||
assert(_bufferedChunks.front == [0, 1]);
|
||||
_bufferedChunks.popFront;
|
||||
assert(_bufferedChunks.front == [2, 3]);
|
||||
_bufferedChunks.popFront;
|
||||
assert(_bufferedChunks.empty);
|
||||
}
|
||||
|
||||
@system unittest
|
||||
{
|
||||
import std.exception : assertThrown;
|
||||
import core.exception : AssertError;
|
||||
|
||||
assertThrown!AssertError(bufferedChunks([0], 0));
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
auto _bufferedChunks = bufferedChunks([0], 1);
|
||||
auto otherBufferedChunks = _bufferedChunks.save;
|
||||
_bufferedChunks.popFront;
|
||||
assert(_bufferedChunks.empty);
|
||||
assert(otherBufferedChunks.front == [0]);
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
auto _bufferedChunks = bufferedChunks([0, 1], 1);
|
||||
auto otherBufferedChunks = _bufferedChunks.save;
|
||||
_bufferedChunks.popFront;
|
||||
assert(_bufferedChunks.front == [1]);
|
||||
assert(otherBufferedChunks.front == [0]);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue