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.util.digest.Sha01;
16 
17 private import tango.core.ByteSwap;
18 
19 private import tango.util.digest.MerkleDamgard;
20 
21 /*******************************************************************************
22 
23 *******************************************************************************/
24 
25 package abstract class Sha01 : MerkleDamgard
26 {
27         protected uint[5]               context;
28         private static enum ubyte      padChar = 0x80;
29         package static enum uint       mask = 0x0000000F;
30     
31         /***********************************************************************
32 
33                 The digest size of Sha-0 and Sha-1 is 20 bytes
34 
35         ***********************************************************************/
36 
37         override 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 = cast(int)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         protected __gshared immutable uint[] K =
166         [
167                 0x5A827999,
168                 0x6ED9EBA1,
169                 0x8F1BBCDC,
170                 0xCA62C1D6
171         ];
172 
173         /***********************************************************************
174 
175         ***********************************************************************/
176 
177         private __gshared immutable uint[5] initial =
178         [
179                 0x67452301,
180                 0xEFCDAB89,
181                 0x98BADCFE,
182                 0x10325476,
183                 0xC3D2E1F0
184         ];
185 }