libnzhash/
lib.rs

1/*
2    libNZ - experimental cryptography library
3    Copyright (C) 2021  Sylvain Saucier
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU Affero General Public License as
7    published by the Free Software Foundation, either version 3 of the
8    License, or (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU Affero General Public License for more details.
14
15    You should have received a copy of the GNU Affero General Public License
16    along with this program.  If not, see <https://www.gnu.org/licenses/>.
17*/
18
19#![allow(dead_code)]
20
21use libnzbig::Big;  
22use libnzprimes::Primes;
23
24pub struct Hash {
25  pub accumulator:Big,
26  counter:u64,
27  pub bytes:usize,   //requested size of the hash in bytes
28}
29impl Hash {
30
31  pub fn new(size:usize) -> Hash {
32    let sizeof_accumulator = size / 4 + if size % 4 > 0 {1} else {0};
33    let mut my = Hash { accumulator:Big::new(sizeof_accumulator), counter:0, bytes:size };
34    my.accumulator.add(1);
35    return my
36  }
37
38  pub fn digest(&mut self, mut value:u32){
39    self.counter += 1;
40    value += self.counter as u32;
41    for x in 0..self.accumulator.segments.len() {
42      value += x as u32;
43      self.accumulator.shift(31);
44      self.accumulator.add( value.rotate_left(x as u32) );
45    }
46  }
47  
48  pub fn get(&mut self) -> Vec<u8> {
49    let mut answer = vec![0u8;self.bytes];
50    let mut big = Big::new( self.accumulator.segments.len() );
51    big.add(1);
52    let mut primes = Primes::new();
53
54    for x in 0..self.accumulator.segments.len() {
55      for y in 0..32 {
56        let mut offset = (64 * x) + (2 * y);
57        let mask = 1u64 << y;
58        if mask & self.accumulator.segments[x] > 0 {
59          offset += 1;
60        }
61        big.multiply(primes.get(offset));
62      }
63    }
64
65    for x in 0..self.bytes {
66      //code using proper big endian conversion and byte convefrsion...
67      answer[ x ] = ( big.segments[ x/4 ] >> (24 - ( (x % 4) * 8) )) as u8;
68    }
69
70    return answer;
71  }
72}