1use std::cmp;
17
18const BLOCK_INTS: usize = 16; const BLOCK_BYTES: usize = BLOCK_INTS * 4;
20
21pub struct SHA1 {
22 digest: [u32; 5],
23 buffer: Vec<u8>,
24 transforms: u64,
25}
26
27impl SHA1 {
28 pub fn new() -> SHA1 {
29 let mut d = SHA1{
30 digest: [0,0,0,0,0],
31 buffer: Vec::new(),
32 transforms: 0,
33 };
34 d.reset();
35 d
36 }
37
38 pub fn reset(&mut self) {
39 self.digest[0] = 0x67452301;
41 self.digest[1] = 0xefcdab89;
42 self.digest[2] = 0x98badcfe;
43 self.digest[3] = 0x10325476;
44 self.digest[4] = 0xc3d2e1f0;
45
46 self.buffer = Vec::new();
48 self.transforms = 0;
49 }
50
51 pub fn update(&mut self, s:&str) {
52 self.update_bytes(s.as_bytes().to_vec());
53 }
54
55 pub fn update_bytes(&mut self, mut ba: Vec<u8>) {
56 loop {
57 let n = cmp::min(ba.len(), BLOCK_BYTES - self.buffer.len());
58 self.buffer.extend_from_slice(&ba[0..n]);
59 if self.buffer.len() != BLOCK_BYTES {
60 return;
61 }
62 ba = ba[n..].to_vec();
63 let block = self.buffer_to_block();
64 self.transform(block);
65 self.buffer = Vec::new();
66 }
67 }
68
69 pub fn finish(&mut self) -> Vec<u8> {
70 let total_bits:u64 = (self.transforms * (BLOCK_BYTES as u64) + (self.buffer.len() as u64)) * 8;
72
73 self.buffer.push(0x80);
75 let orig_size = self.buffer.len();
76 while self.buffer.len() < BLOCK_BYTES {
77 self.buffer.push(0x00);
78 }
79 let mut block = self.buffer_to_block();
80 if orig_size > BLOCK_BYTES - 8 {
81 self.transform(block);
82 let mut i = 0;
83 while i < BLOCK_INTS - 2 {
84 block[i] = 0;
85 i += 1;
86 }
87 }
88
89 block[BLOCK_INTS - 1] = total_bits as u32;
91 block[BLOCK_INTS - 2] = (total_bits >> 32) as u32;
92 self.transform(block);
93
94 let res = to_bytes(&self.digest);
95
96 self.reset();
98
99 res
100 }
101
102 pub fn buffer_to_block(&self) -> [u32; BLOCK_INTS]{
103 let mut block: [u32; BLOCK_INTS] = [0; BLOCK_INTS];
104 let mut i = 0;
105 while i < BLOCK_INTS {
106 block[i] = (self.buffer[4*i+3] as u32 & 0xff)
107 | (self.buffer[4*i+2] as u32 & 0xff)<<8
108 | (self.buffer[4*i+1] as u32 & 0xff)<<16
109 | (self.buffer[4*i+0] as u32 & 0xff)<<24;
110 i += 1;
111 }
112 block
113 }
114
115 pub fn transform(&mut self, mut block:[u32; BLOCK_INTS]) {
116 let mut a = self.digest[0];
118 let mut b = self.digest[1];
119 let mut c = self.digest[2];
120 let mut d = self.digest[3];
121 let mut e = self.digest[4];
122
123 (b, e, block) = r0(block, a, b, c, d, e, 0);
125 (a, d, block) = r0(block, e, a, b, c, d, 1);
126 (e, c, block) = r0(block, d, e, a, b, c, 2);
127 (d, b, block) = r0(block, c, d, e, a, b, 3);
128 (c, a, block) = r0(block, b, c, d, e, a, 4);
129 (b, e, block) = r0(block, a, b, c, d, e, 5);
130 (a, d, block) = r0(block, e, a, b, c, d, 6);
131 (e, c, block) = r0(block, d, e, a, b, c, 7);
132 (d, b, block) = r0(block, c, d, e, a, b, 8);
133 (c, a, block) = r0(block, b, c, d, e, a, 9);
134 (b, e, block) = r0(block, a, b, c, d, e, 10);
135 (a, d, block) = r0(block, e, a, b, c, d, 11);
136 (e, c, block) = r0(block, d, e, a, b, c, 12);
137 (d, b, block) = r0(block, c, d, e, a, b, 13);
138 (c, a, block) = r0(block, b, c, d, e, a, 14);
139 (b, e, block) = r0(block, a, b, c, d, e, 15);
140 (a, d, block) = r1(block, e, a, b, c, d, 0);
141 (e, c, block) = r1(block, d, e, a, b, c, 1);
142 (d, b, block) = r1(block, c, d, e, a, b, 2);
143 (c, a, block) = r1(block, b, c, d, e, a, 3);
144 (b, e, block) = r2(block, a, b, c, d, e, 4);
145 (a, d, block) = r2(block, e, a, b, c, d, 5);
146 (e, c, block) = r2(block, d, e, a, b, c, 6);
147 (d, b, block) = r2(block, c, d, e, a, b, 7);
148 (c, a, block) = r2(block, b, c, d, e, a, 8);
149 (b, e, block) = r2(block, a, b, c, d, e, 9);
150 (a, d, block) = r2(block, e, a, b, c, d, 10);
151 (e, c, block) = r2(block, d, e, a, b, c, 11);
152 (d, b, block) = r2(block, c, d, e, a, b, 12);
153 (c, a, block) = r2(block, b, c, d, e, a, 13);
154 (b, e, block) = r2(block, a, b, c, d, e, 14);
155 (a, d, block) = r2(block, e, a, b, c, d, 15);
156 (e, c, block) = r2(block, d, e, a, b, c, 0);
157 (d, b, block) = r2(block, c, d, e, a, b, 1);
158 (c, a, block) = r2(block, b, c, d, e, a, 2);
159 (b, e, block) = r2(block, a, b, c, d, e, 3);
160 (a, d, block) = r2(block, e, a, b, c, d, 4);
161 (e, c, block) = r2(block, d, e, a, b, c, 5);
162 (d, b, block) = r2(block, c, d, e, a, b, 6);
163 (c, a, block) = r2(block, b, c, d, e, a, 7);
164 (b, e, block) = r3(block, a, b, c, d, e, 8);
165 (a, d, block) = r3(block, e, a, b, c, d, 9);
166 (e, c, block) = r3(block, d, e, a, b, c, 10);
167 (d, b, block) = r3(block, c, d, e, a, b, 11);
168 (c, a, block) = r3(block, b, c, d, e, a, 12);
169 (b, e, block) = r3(block, a, b, c, d, e, 13);
170 (a, d, block) = r3(block, e, a, b, c, d, 14);
171 (e, c, block) = r3(block, d, e, a, b, c, 15);
172 (d, b, block) = r3(block, c, d, e, a, b, 0);
173 (c, a, block) = r3(block, b, c, d, e, a, 1);
174 (b, e, block) = r3(block, a, b, c, d, e, 2);
175 (a, d, block) = r3(block, e, a, b, c, d, 3);
176 (e, c, block) = r3(block, d, e, a, b, c, 4);
177 (d, b, block) = r3(block, c, d, e, a, b, 5);
178 (c, a, block) = r3(block, b, c, d, e, a, 6);
179 (b, e, block) = r3(block, a, b, c, d, e, 7);
180 (a, d, block) = r3(block, e, a, b, c, d, 8);
181 (e, c, block) = r3(block, d, e, a, b, c, 9);
182 (d, b, block) = r3(block, c, d, e, a, b, 10);
183 (c, a, block) = r3(block, b, c, d, e, a, 11);
184 (b, e, block) = r4(block, a, b, c, d, e, 12);
185 (a, d, block) = r4(block, e, a, b, c, d, 13);
186 (e, c, block) = r4(block, d, e, a, b, c, 14);
187 (d, b, block) = r4(block, c, d, e, a, b, 15);
188 (c, a, block) = r4(block, b, c, d, e, a, 0);
189 (b, e, block) = r4(block, a, b, c, d, e, 1);
190 (a, d, block) = r4(block, e, a, b, c, d, 2);
191 (e, c, block) = r4(block, d, e, a, b, c, 3);
192 (d, b, block) = r4(block, c, d, e, a, b, 4);
193 (c, a, block) = r4(block, b, c, d, e, a, 5);
194 (b, e, block) = r4(block, a, b, c, d, e, 6);
195 (a, d, block) = r4(block, e, a, b, c, d, 7);
196 (e, c, block) = r4(block, d, e, a, b, c, 8);
197 (d, b, block) = r4(block, c, d, e, a, b, 9);
198 (c, a, block) = r4(block, b, c, d, e, a, 10);
199 (b, e, block) = r4(block, a, b, c, d, e, 11);
200 (a, d, block) = r4(block, e, a, b, c, d, 12);
201 (e, c, block) = r4(block, d, e, a, b, c, 13);
202 (d, b, block) = r4(block, c, d, e, a, b, 14);
203 (c, a, _) = r4(block, b, c, d, e, a, 15);
204
205 self.digest[0] = self.digest[0].wrapping_add(a);
207 self.digest[1] = self.digest[1].wrapping_add(b);
208 self.digest[2] = self.digest[2].wrapping_add(c);
209 self.digest[3] = self.digest[3].wrapping_add(d);
210 self.digest[4] = self.digest[4].wrapping_add(e);
211
212 self.transforms += 1;
214 }
215}
216
217fn r0(block: [u32; BLOCK_INTS], v: u32, mut w: u32, x: u32, y: u32, mut z: u32, i: usize) -> (u32, u32, [u32; BLOCK_INTS]) {
218 z = z.wrapping_add(((w&(x^y))^y).wrapping_add(block[i]).wrapping_add(0x5a827999).wrapping_add(rol(v, 5)));
219 w = rol(w, 30);
220 (w, z, block)
221}
222
223fn r1(mut block: [u32; BLOCK_INTS], v: u32, mut w: u32, x: u32, y: u32, mut z: u32, i: usize) -> (u32, u32, [u32; BLOCK_INTS]) {
224 block[i] = blk(block, i);
225 z = z.wrapping_add((w&(x^y))^y).wrapping_add(block[i]).wrapping_add(0x5a827999).wrapping_add(rol(v, 5));
226 w = rol(w, 30);
227 (w, z, block)
228}
229
230fn r2(mut block: [u32; BLOCK_INTS], v: u32, mut w: u32, x: u32, y: u32, mut z: u32, i: usize) -> (u32, u32, [u32; BLOCK_INTS]) {
231 block[i] = blk(block, i);
232 z = z.wrapping_add(w^x^y).wrapping_add(block[i]).wrapping_add(0x6ed9eba1).wrapping_add(rol(v, 5));
233 w = rol(w, 30);
234 (w, z, block)
235}
236
237fn r3(mut block: [u32; BLOCK_INTS], v: u32, mut w: u32, x: u32, y: u32, mut z: u32, i: usize) -> (u32, u32, [u32; BLOCK_INTS]) {
238 block[i] = blk(block, i);
239 z = z.wrapping_add(((w|x)&y)|(w&x)).wrapping_add(block[i]).wrapping_add(0x8f1bbcdc).wrapping_add(rol(v, 5));
240 w = rol(w, 30);
241 (w, z, block)
242}
243
244fn r4(mut block: [u32; BLOCK_INTS], v: u32, mut w: u32, x: u32, y: u32, mut z: u32, i: usize) -> (u32, u32, [u32; BLOCK_INTS]) {
245 block[i] = blk(block, i);
246 z = z.wrapping_add(w^x^y).wrapping_add(block[i]).wrapping_add(0xca62c1d6).wrapping_add(rol(v, 5));
247 w = rol(w, 30);
248 (w, z, block)
249}
250
251fn rol(value: u32, bits: usize) -> u32 {
252 return (value << bits) | (value >> (32 - bits));
253}
254
255fn blk(block: [u32; BLOCK_INTS], i: usize) -> u32 {
256 return rol(block[(i+13)&15] ^ block[(i+8)&15] ^ block[(i+2)&15] ^ block[i], 1);
257}
258
259fn to_bytes(input: &[u32]) -> Vec<u8> {
260 let mut bytes = Vec::with_capacity(4 * input.len());
261
262 for value in input {
263 bytes.extend(&value.to_be_bytes());
264 }
265
266 bytes
267}
268