# HG changeset patch # User Thomas Dixon # Date 1218772316 14400 # Node ID cff9960a019c0f52e2e2292e2bb2fa5cffbce680 # Parent 3de3a2de13a0e73f21b8c9cc0713b8ae45a36df9 Removed update(ubyte x) from Hash class. Rewrote hash function padding. Updated hash functions to use ulong counter for bytes (was previously uint). diff -r 3de3a2de13a0 -r cff9960a019c dcrypt/crypto/Hash.d --- a/dcrypt/crypto/Hash.d Thu Aug 14 01:45:24 2008 -0400 +++ b/dcrypt/crypto/Hash.d Thu Aug 14 23:51:56 2008 -0400 @@ -12,84 +12,88 @@ /** Base class for all cryptographic hash functions */ class Hash { - private const enum { - MODE_MD=0, // MDx, RipeMD, etc - MODE_SHA, - MODE_TIGER - } + private const enum { + MODE_MD=0, // MDx, RipeMD, etc + MODE_SHA, + MODE_TIGER + } - protected { + protected { ubyte[] buffer; - uint bytes, - index; + ulong bytes; + uint index; } - this (void[] input_=null) { - buffer = new ubyte[blockSize]; + this (void[] input_=null) { + buffer = new ubyte[blockSize]; ubyte[] input = cast(ubyte[]) input_; if (input) update(input); - } + } + + /** Returns: The block size of the hash function in bytes. */ + abstract uint blockSize(); - /** Returns: The block size of the hash function in bytes. */ - abstract uint blockSize(); - - /** Returns: The output size of the hash function in bytes. */ - abstract uint digestSize(); - - /** Returns: The name of the algorithm we're implementing. */ - abstract char[] name(); + /** Returns: The output size of the hash function in bytes. */ + abstract uint digestSize(); + + /** Returns: The name of the algorithm we're implementing. */ + abstract char[] name(); /** Returns: A copy of this hash object. */ abstract Hash copy(); - /** - * Introduce data into the hash function. - * - * Params: - * input_ = Data to be processed. - */ - void update(void[] input_) { - ubyte[] input = cast(ubyte[]) input_; - foreach (ubyte i; input) - update(i); - } - - void update(ubyte input) { - bytes++; - buffer[index++] = input; - if (index == blockSize) { - transform(buffer); - index = 0; - } - } - - /** Hash function's internal transformation. */ - protected abstract void transform(ubyte[] input); + /** + * Introduce data into the hash function. + * + * Params: + * input_ = Data to be processed. + */ + void update(void[] input_) { + ubyte[] input = cast(ubyte[]) input_; + foreach (ubyte i; input) { + bytes++; + buffer[index++] = i; + if (index == blockSize) { + transform(buffer); + index = 0; + } + } + + } + + /** Hash function's internal transformation. */ + protected abstract void transform(ubyte[] input); - /** - * Pad message in the respective manner. - * - * Params: - * mode = Mode constant dictating in which manner - * to pad the message. - */ - protected void padMessage(uint mode) { - ulong length = bytes << 3; - - update(((mode == MODE_TIGER) ? 0x01 : 0x80)); - uint count = (blockSize-(blockSize >> 3)); - if (index > count) - while (index != 0) - update(0); - while (index < (count + ((blockSize == 128) ? 8 : 0))) - update(0); + /** + * Pad message in the respective manner. + * + * Params: + * mode = Mode constant dictating in which manner + * to pad the message. + */ + protected void padMessage(uint mode) { + ulong bits = bytes << 3; + + // Add the pad marker + buffer[index++] = ((mode == MODE_TIGER) ? 0x01 : 0x80); + if (index == blockSize) { + transform(buffer); + index = 0; + } + + // Pad with null bytes + if (index >= (blockSize-(blockSize >> 3))) + update(new ubyte[blockSize-index]); + update(new ubyte[(blockSize-ulong.sizeof)-index]); + + // Length padding + ubyte[] length = new ubyte[ulong.sizeof]; + for (int i = 0, j = 0; i < 64; i+=8) // little endian + length[j++] = bits >> i; if (mode == MODE_SHA) - for (int i = 56; i >= 0; i-=8) // big endian - update(length >> i); - else - for (int i = 0; i < 64; i+=8) // little endian - update(length >> i); + length.reverse; // big endian + update(length); } /**