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