Mercurial > projects > dcrypt
view dcrypt/crypto/Hash.d @ 29:b9ba770b8f16
Second go at D2 compatibility. Changed the hexEncode method of the ByteConverter class and the hexDigest methods of various classes to return char[] instead of string.
author | Thomas Dixon <reikon@reikon.us> |
---|---|
date | Mon, 11 May 2009 01:39:19 -0400 |
parents | ad687db713a4 |
children | 21847420b1ac |
line wrap: on
line source
/** * This file is part of the dcrypt project. * * Copyright: Copyright (C) dcrypt contributors 2008. All rights reserved. * License: MIT * Authors: Thomas Dixon */ module dcrypt.crypto.Hash; public import dcrypt.misc.ByteConverter; public import dcrypt.misc.Bitwise; /** Base class for all cryptographic hash functions */ class Hash { private const enum { MODE_MD=0, // MDx, RipeMD, etc MODE_SHA, MODE_TIGER } protected { ubyte[] buffer; ulong bytes; uint index; } 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 output size of the hash function in bytes. */ abstract uint digestSize(); /** Returns: The name of the algorithm we're implementing. */ abstract string name(); /** Returns: A copy of this hash object. */ abstract Hash copy(); /** * Introduce data into the hash function. * * Params: * input_ = Data to be processed. * * Returns: Self */ Hash update(void[] input_) { ubyte[] input = cast(ubyte[]) input_; foreach (ubyte i; input) { bytes++; buffer[index++] = i; if (index == blockSize) { transform(buffer); index = 0; } } return this; } /** 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 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 while ((index & (blockSize - 1)) != (blockSize - (blockSize >> 3))) { buffer[index++] = 0; if (index == blockSize) { transform(buffer); index = 0; } } // Length padding for (int i = 0; i < blockSize; i+=8, bits>>=8) // little endian buffer[index++] = bits; if (mode == MODE_SHA) buffer[(buffer.length-(blockSize >> 3))..buffer.length].reverse; // big endian transform(buffer); index = 0; } /** * Process all data, pad and finalize. This method will * reset the digest to its original state for subsequent use. * * Returns: Binary representation of the hash in bytes. */ abstract ubyte[] digest(); /** * Same as digest() but returns hash value in hex. * * Returns: Representation of the final hash value in hex. */ char[] hexDigest() { return ByteConverter.hexEncode(digest()); } /** Reset hash to initial state. */ void reset() { bytes = index = 0; } }