flowlang/
sha1.rs

1/*
2    Adapted to Rust from: https://github.com/vog/sha1
3
4    Original C Code
5        -- Steve Reid <steve@edmweb.com>
6    Small changes to fit into bglibs
7        -- Bruce Guenter <bruce@untroubled.org>
8    Translation to simpler C++ Code
9        -- Volker Diels-Grabsch <v@njh.eu>
10    Safety fixes
11        -- Eugene Hopkinson <slowriot at voxelstorm dot com>
12    Header-only library
13        -- Zlatko Michailov <zlatko@michailov.org>
14*/
15
16use std::cmp;
17
18const BLOCK_INTS: usize = 16;  /* number of 32bit integers per SHA1 block */
19const 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    /* SHA1 initialization constants */
40    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    /* Reset counters */
47    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    /* Total number of hashed bits */
71    let total_bits:u64 = (self.transforms * (BLOCK_BYTES as u64) + (self.buffer.len() as u64)) * 8;
72
73    /* Padding */
74    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    /* Append total_bits, split this uint64_t into two uint32_t */
90    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    /* Reset for next run */
97    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    /* Copy digest[] to working vars */
117    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    /* 4 rounds of 20 operations each. Loop unrolled. */
124    (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    /* Add the working vars back into digest[] */
206    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    /* Count the number of transformations */
213    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