132
|
1 /*******************************************************************************
|
|
2
|
|
3 copyright: Copyright (c) 2006 Tango. All rights reserved
|
|
4
|
|
5 license: BSD style: see doc/license.txt for details
|
|
6
|
|
7 version: Initial release: Feb 2006
|
|
8
|
|
9 author: Regan Heath, Oskar Linde
|
|
10
|
|
11 This module implements common parts of the SHA-0 and SHA-1 algoritms
|
|
12
|
|
13 *******************************************************************************/
|
|
14
|
|
15 module tango.io.digest.Sha01;
|
|
16
|
|
17 private import tango.core.ByteSwap;
|
|
18
|
|
19 private import tango.io.digest.MerkleDamgard;
|
|
20
|
|
21 /*******************************************************************************
|
|
22
|
|
23 *******************************************************************************/
|
|
24
|
|
25 package abstract class Sha01 : MerkleDamgard
|
|
26 {
|
|
27 protected uint[5] context;
|
|
28 private static const ubyte padChar = 0x80;
|
|
29 package static const uint mask = 0x0000000F;
|
|
30
|
|
31 /***********************************************************************
|
|
32
|
|
33 The digest size of Sha-0 and Sha-1 is 20 bytes
|
|
34
|
|
35 ***********************************************************************/
|
|
36
|
|
37 final uint digestSize() { return 20; }
|
|
38
|
|
39 /***********************************************************************
|
|
40
|
|
41 Initialize the cipher
|
|
42
|
|
43 Remarks:
|
|
44 Returns the cipher state to it's initial value
|
|
45
|
|
46 ***********************************************************************/
|
|
47
|
|
48 final protected override void reset()
|
|
49 {
|
|
50 super.reset();
|
|
51 context[] = initial[];
|
|
52 }
|
|
53
|
|
54 /***********************************************************************
|
|
55
|
|
56 Obtain the digest
|
|
57
|
|
58 Returns:
|
|
59 the digest
|
|
60
|
|
61 Remarks:
|
|
62 Returns a digest of the current cipher state, this may be the
|
|
63 final digest, or a digest of the state between calls to update()
|
|
64
|
|
65 ***********************************************************************/
|
|
66
|
|
67 final protected override void createDigest(ubyte[] buf)
|
|
68 {
|
|
69 version (LittleEndian)
|
|
70 ByteSwap.swap32 (context.ptr, context.length * uint.sizeof);
|
|
71
|
|
72 buf[] = cast(ubyte[]) context;
|
|
73 }
|
|
74
|
|
75 /***********************************************************************
|
|
76
|
|
77 block size
|
|
78
|
|
79 Returns:
|
|
80 the block size
|
|
81
|
|
82 Remarks:
|
|
83 Specifies the size (in bytes) of the block of data to pass to
|
|
84 each call to transform(). For SHA0 the blockSize is 64.
|
|
85
|
|
86 ***********************************************************************/
|
|
87
|
|
88 final protected override uint blockSize() { return 64; }
|
|
89
|
|
90 /***********************************************************************
|
|
91
|
|
92 Length padding size
|
|
93
|
|
94 Returns:
|
|
95 the length padding size
|
|
96
|
|
97 Remarks:
|
|
98 Specifies the size (in bytes) of the padding which uses the
|
|
99 length of the data which has been ciphered, this padding is
|
|
100 carried out by the padLength method. For SHA0 the addSize is 0.
|
|
101
|
|
102 ***********************************************************************/
|
|
103
|
|
104 final protected override uint addSize() {return 8;}
|
|
105
|
|
106 /***********************************************************************
|
|
107
|
|
108 Pads the cipher data
|
|
109
|
|
110 Params:
|
|
111 data = a slice of the cipher buffer to fill with padding
|
|
112
|
|
113 Remarks:
|
|
114 Fills the passed buffer slice with the appropriate padding for
|
|
115 the final call to transform(). This padding will fill the cipher
|
|
116 buffer up to blockSize()-addSize().
|
|
117
|
|
118 ***********************************************************************/
|
|
119
|
|
120 final protected override void padMessage(ubyte[] data)
|
|
121 {
|
|
122 data[0] = padChar;
|
|
123 data[1..$] = 0;
|
|
124 }
|
|
125
|
|
126 /***********************************************************************
|
|
127
|
|
128 Performs the length padding
|
|
129
|
|
130 Params:
|
|
131 data = the slice of the cipher buffer to fill with padding
|
|
132 length = the length of the data which has been ciphered
|
|
133
|
|
134 Remarks:
|
|
135 Fills the passed buffer slice with addSize() bytes of padding
|
|
136 based on the length in bytes of the input data which has been
|
|
137 ciphered.
|
|
138
|
|
139 ***********************************************************************/
|
|
140
|
|
141 final protected override void padLength(ubyte[] data, ulong length)
|
|
142 {
|
|
143 length <<= 3;
|
|
144 for(int j = data.length-1; j >= 0; j--)
|
|
145 data[$-j-1] = cast(ubyte) (length >> j*data.length);
|
|
146 }
|
|
147
|
|
148
|
|
149 /***********************************************************************
|
|
150
|
|
151 ***********************************************************************/
|
|
152
|
|
153 protected static uint f(uint t, uint B, uint C, uint D)
|
|
154 {
|
|
155 if (t < 20) return (B & C) | ((~B) & D);
|
|
156 else if (t < 40) return B ^ C ^ D;
|
|
157 else if (t < 60) return (B & C) | (B & D) | (C & D);
|
|
158 else return B ^ C ^ D;
|
|
159 }
|
|
160
|
|
161 /***********************************************************************
|
|
162
|
|
163 ***********************************************************************/
|
|
164
|
|
165 private static const uint[] K =
|
|
166 [
|
|
167 0x5A827999,
|
|
168 0x6ED9EBA1,
|
|
169 0x8F1BBCDC,
|
|
170 0xCA62C1D6
|
|
171 ];
|
|
172
|
|
173 /***********************************************************************
|
|
174
|
|
175 ***********************************************************************/
|
|
176
|
|
177 private static const uint[5] initial =
|
|
178 [
|
|
179 0x67452301,
|
|
180 0xEFCDAB89,
|
|
181 0x98BADCFE,
|
|
182 0x10325476,
|
|
183 0xC3D2E1F0
|
|
184 ];
|
|
185 }
|