Mercurial > projects > dcrypt
view dcrypt/crypto/Hash.d @ 11:02970e63257d
Fix stupid error with using uint instead of int in create*
author | Thomas Dixon <reikon@reikon.us> |
---|---|
date | Wed, 20 Aug 2008 23:33:02 -0400 |
parents | cff9960a019c |
children | 8c7f8fecdd75 |
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.Util; /** 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 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) { 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 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) length.reverse; // big endian update(length); } /** * Process all data, pad and finalize. This method will * reset the digest to its original state ofr 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 Util.ubytesToHex(digest()); } /** Reset hash to initial state. */ void reset() { bytes = index = 0; } }