amcl/
sha3.rs

1/*
2Licensed to the Apache Software Foundation (ASF) under one
3or more contributor license agreements.  See the NOTICE file
4distributed with this work for additional information
5regarding copyright ownership.  The ASF licenses this file
6to you under the Apache License, Version 2.0 (the
7"License"); you may not use this file except in compliance
8with the License.  You may obtain a copy of the License at
9
10  http://www.apache.org/licenses/LICENSE-2.0
11
12Unless required by applicable law or agreed to in writing,
13software distributed under the License is distributed on an
14"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15KIND, either express or implied.  See the License for the
16specific language governing permissions and limitations
17under the License.
18*/
19
20pub const HASH224: usize = 28;
21pub const HASH256: usize = 32;
22pub const HASH384: usize = 48;
23pub const HASH512: usize = 64;
24pub const SHAKE128: usize = 16;
25pub const SHAKE256: usize = 32;
26
27const ROUNDS: usize = 24;
28
29const RC: [u64; 24] = [
30    0x0000000000000001,
31    0x0000000000008082,
32    0x800000000000808A,
33    0x8000000080008000,
34    0x000000000000808B,
35    0x0000000080000001,
36    0x8000000080008081,
37    0x8000000000008009,
38    0x000000000000008A,
39    0x0000000000000088,
40    0x0000000080008009,
41    0x000000008000000A,
42    0x000000008000808B,
43    0x800000000000008B,
44    0x8000000000008089,
45    0x8000000000008003,
46    0x8000000000008002,
47    0x8000000000000080,
48    0x000000000000800A,
49    0x800000008000000A,
50    0x8000000080008081,
51    0x8000000000008080,
52    0x0000000080000001,
53    0x8000000080008008,
54];
55
56pub struct SHA3 {
57    length: u64,
58    rate: usize,
59    len: usize,
60    s: [[u64; 5]; 5],
61}
62
63impl SHA3 {
64    fn rotl(x: u64, n: u64) -> u64 {
65        return ((x) << n) | ((x) >> (64 - n));
66    }
67
68    fn transform(&mut self) {
69        /* basic transformation step */
70        let mut c: [u64; 5] = [0; 5];
71        let mut d: [u64; 5] = [0; 5];
72        let mut b: [[u64; 5]; 5] = [[0; 5]; 5];
73
74        for k in 0..ROUNDS {
75            c[0] = self.s[0][0] ^ self.s[0][1] ^ self.s[0][2] ^ self.s[0][3] ^ self.s[0][4];
76            c[1] = self.s[1][0] ^ self.s[1][1] ^ self.s[1][2] ^ self.s[1][3] ^ self.s[1][4];
77            c[2] = self.s[2][0] ^ self.s[2][1] ^ self.s[2][2] ^ self.s[2][3] ^ self.s[2][4];
78            c[3] = self.s[3][0] ^ self.s[3][1] ^ self.s[3][2] ^ self.s[3][3] ^ self.s[3][4];
79            c[4] = self.s[4][0] ^ self.s[4][1] ^ self.s[4][2] ^ self.s[4][3] ^ self.s[4][4];
80
81            d[0] = c[4] ^ SHA3::rotl(c[1], 1);
82            d[1] = c[0] ^ SHA3::rotl(c[2], 1);
83            d[2] = c[1] ^ SHA3::rotl(c[3], 1);
84            d[3] = c[2] ^ SHA3::rotl(c[4], 1);
85            d[4] = c[3] ^ SHA3::rotl(c[0], 1);
86
87            for i in 0..5 {
88                for j in 0..5 {
89                    self.s[i][j] ^= d[i];
90                }
91            }
92
93            b[0][0] = self.s[0][0];
94            b[1][3] = SHA3::rotl(self.s[0][1], 36);
95            b[2][1] = SHA3::rotl(self.s[0][2], 3);
96            b[3][4] = SHA3::rotl(self.s[0][3], 41);
97            b[4][2] = SHA3::rotl(self.s[0][4], 18);
98
99            b[0][2] = SHA3::rotl(self.s[1][0], 1);
100            b[1][0] = SHA3::rotl(self.s[1][1], 44);
101            b[2][3] = SHA3::rotl(self.s[1][2], 10);
102            b[3][1] = SHA3::rotl(self.s[1][3], 45);
103            b[4][4] = SHA3::rotl(self.s[1][4], 2);
104
105            b[0][4] = SHA3::rotl(self.s[2][0], 62);
106            b[1][2] = SHA3::rotl(self.s[2][1], 6);
107            b[2][0] = SHA3::rotl(self.s[2][2], 43);
108            b[3][3] = SHA3::rotl(self.s[2][3], 15);
109            b[4][1] = SHA3::rotl(self.s[2][4], 61);
110
111            b[0][1] = SHA3::rotl(self.s[3][0], 28);
112            b[1][4] = SHA3::rotl(self.s[3][1], 55);
113            b[2][2] = SHA3::rotl(self.s[3][2], 25);
114            b[3][0] = SHA3::rotl(self.s[3][3], 21);
115            b[4][3] = SHA3::rotl(self.s[3][4], 56);
116
117            b[0][3] = SHA3::rotl(self.s[4][0], 27);
118            b[1][1] = SHA3::rotl(self.s[4][1], 20);
119            b[2][4] = SHA3::rotl(self.s[4][2], 39);
120            b[3][2] = SHA3::rotl(self.s[4][3], 8);
121            b[4][0] = SHA3::rotl(self.s[4][4], 14);
122
123            for i in 0..5 {
124                for j in 0..5 {
125                    self.s[i][j] = b[i][j] ^ (!b[(i + 1) % 5][j] & b[(i + 2) % 5][j]);
126                }
127            }
128
129            self.s[0][0] ^= RC[k];
130        }
131    }
132
133    /* Initialise Hash function */
134    pub fn init(&mut self, olen: usize) {
135        /* initialise */
136        for i in 0..5 {
137            for j in 0..5 {
138                self.s[i][j] = 0;
139            }
140        }
141        self.length = 0;
142        self.len = olen;
143        self.rate = 200 - 2 * olen;
144    }
145
146    pub fn new(olen: usize) -> SHA3 {
147        let mut nh = SHA3 {
148            length: 0,
149            rate: 0,
150            len: 0,
151            s: [[0; 5]; 5],
152        };
153        nh.init(olen);
154        return nh;
155    }
156
157    /* process a single byte */
158    pub fn process(&mut self, byt: u8) {
159        /* process the next message byte */
160        let cnt = (self.length % (self.rate as u64)) as usize;
161        let b = cnt % 8;
162        let ind = cnt / 8;
163        let i = ind % 5;
164        let j = ind / 5;
165        self.s[i][j] ^= ((byt & 0xff) as u64) << (8 * b);
166        self.length += 1;
167        if cnt + 1 == self.rate {
168            self.transform();
169        }
170    }
171
172    pub fn squeeze(&mut self, buff: &mut [u8], olen: usize) {
173        //let olen=buff.len();
174        let mut done = false;
175        let mut m = 0;
176        loop {
177            for j in 0..5 {
178                for i in 0..5 {
179                    let mut el = self.s[i][j];
180                    for _ in 0..8 {
181                        buff[m] = (el & 0xff) as u8;
182                        m += 1;
183                        if m >= olen || (m % self.rate) == 0 {
184                            done = true;
185                            break;
186                        }
187                        el >>= 8;
188                    }
189                    if done {
190                        break;
191                    }
192                }
193                if done {
194                    break;
195                }
196            }
197            if m >= olen {
198                break;
199            }
200            done = false;
201            self.transform();
202        }
203    }
204
205    /* Generate 32-byte Hash */
206    pub fn hash(&mut self, digest: &mut [u8]) {
207        /* pad message and finish - supply digest */
208        let q = self.rate - (self.length % (self.rate as u64)) as usize;
209        if q == 1 {
210            self.process(0x86);
211        } else {
212            self.process(0x06);
213            while (self.length % (self.rate as u64)) as usize != self.rate - 1 {
214                self.process(0x00)
215            }
216            self.process(0x80);
217        }
218        let hlen = self.len as usize;
219        self.squeeze(digest, hlen);
220    }
221
222    pub fn shake(&mut self, digest: &mut [u8], olen: usize) {
223        let q = self.rate - (self.length % (self.rate as u64)) as usize;
224        if q == 1 {
225            self.process(0x9f);
226        } else {
227            self.process(0x1f);
228            while (self.length % (self.rate as u64)) as usize != self.rate - 1 {
229                self.process(0x00)
230            }
231            self.process(0x80);
232        }
233        self.squeeze(digest, olen);
234    }
235}
236
237//916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18
238//afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185
239//98be04516c04cc73593fef3ed0352ea9f6443942d6950e29a372a681c3deaf4535423709b02843948684e029010badcc0acd8303fc85fdad3eabf4f78cae165635f57afd28810fc2
240/*
241fn main() {
242    let s = String::from("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
243    let mut digest: [u8;100]=[0;100];
244    let test = s.into_bytes();
245
246    let mut sh=SHA3::new(HASH256);
247    for i in 0..test.len(){
248        sh.process(test[i]);
249    }
250    sh.hash(&mut digest);
251    for i in 0..32 {print!("{:02x}",digest[i])}
252    println!("");
253
254    sh=SHA3::new(HASH512);
255    for i in 0..test.len(){
256        sh.process(test[i]);
257    }
258    sh.hash(&mut digest);
259    for i in 0..64 {print!("{:02x}",digest[i])}
260    println!("");
261
262    sh=SHA3::new(SHAKE256);
263    for i in 0..test.len(){
264        sh.process(test[i]);
265    }
266    sh.shake(&mut digest,72);
267    for i in 0..72 {print!("{:02x}",digest[i])}
268    println!("");
269
270} */