Mercurial > projects > dcrypt
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 } |