comparison dcrypt/crypto/Hash.d @ 0:0e08791a1418

Initial import.
author Thomas Dixon <reikon@reikon.us>
date Sun, 10 Aug 2008 14:20:17 -0400
parents
children 71aae178f89a
comparison
equal deleted inserted replaced
-1:000000000000 0:0e08791a1418
1 /**
2 * This file is part of the dcrypt project.
3 *
4 * Copyright: Copyright (C) dcrypt contributors 2008. All rights reserved.
5 * License: MIT
6 * Authors: Thomas Dixon
7 */
8
9 module dcrypt.crypto.Hash;
10
11 public import dcrypt.misc.Util;
12
13 /** Base class for all cryptographic hash functions */
14 class Hash {
15 private const enum {
16 MODE_MD=0, // MDx, RipeMD, etc
17 MODE_SHA,
18 MODE_TIGER
19 }
20 private ubyte[] buffer;
21 uint bytes,
22 index;
23
24 this (void[] input_=null) {
25 buffer = new ubyte[blockSize];
26 ubyte[] input = cast(ubyte[]) input_;
27 if (input)
28 update(input);
29 }
30
31 /** Returns: The block size of the hash function in bytes. */
32 abstract uint blockSize();
33
34 /** Returns: The output size of the hash function in bytes. */
35 abstract uint digestSize();
36
37 /** Returns: The name of the algorithm we're implementing. */
38 abstract char[] name();
39
40 /**
41 * Introduce data into the hash function.
42 *
43 * Params:
44 * input_ = Data to be processed.
45 */
46 void update(void[] input_) {
47 ubyte[] input = cast(ubyte[]) input_;
48 foreach (ubyte i; input)
49 update(i);
50 }
51
52 void update(ubyte input) {
53 bytes++;
54 buffer[index++] = input;
55 if (index == blockSize) {
56 transform(buffer);
57 index = 0;
58 }
59 }
60
61 /** Hash function's internal transformation. */
62 protected abstract void transform(ubyte[] input);
63
64 /**
65 * Pad message in the respective manner.
66 *
67 * Params:
68 * mode = Mode constant dictating in which manner
69 * to pad the message.
70 */
71 protected void padMessage(uint mode) {
72 ulong length = bytes << 3;
73
74 update(((mode == MODE_TIGER) ? 0x01 : 0x80));
75 uint count = (blockSize-(blockSize >> 3));
76 if (index > count)
77 while (index != 0)
78 update(0);
79 while (index < (count + ((blockSize == 128) ? 8 : 0)))
80 update(0);
81 if (mode == MODE_SHA)
82 for (int i = 56; i >= 0; i-=8) // big endian
83 update(length >> i);
84 else
85 for (int i = 0; i < 64; i+=8) // little endian
86 update(length >> i);
87 }
88
89 /**
90 * Process all data, pad and finalize. This method will
91 * reset the digest to its original state ofr subsequent use.
92 *
93 * Returns: Binary representation of the hash in bytes.
94 */
95 abstract ubyte[] digest();
96
97 /**
98 * Same as digest() but returns hash value in hex.
99 *
100 * Returns: Representation of the final hash value in hex.
101 */
102 char[] hexDigest() {
103 return Util.ubytesToHex(digest());
104 }
105
106 /** Reset hash to initial state. */
107 void reset() {
108 bytes = index = 0;
109 }
110 }