ceremonyclient/crates/bls48581/src/sha3.rs
Cassandra Heart 35561a9e41
v1.4.19-p1 (#235)
* v1.4.19-p1

* remove integrity check from startup
2024-06-15 11:05:06 -05:00

345 lines
9.7 KiB
Rust

/*
* Copyright (c) 2012-2020 MIRACL UK Ltd.
*
* This file is part of MIRACL Core
* (see https://github.com/miracl/core).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
pub const HASH224: usize = 28;
pub const HASH256: usize = 32;
pub const HASH384: usize = 48;
pub const HASH512: usize = 64;
pub const SHAKE128: usize = 16;
pub const SHAKE256: usize = 32;
const ROUNDS: usize = 24;
const RC: [u64; 24] = [
0x0000000000000001,
0x0000000000008082,
0x800000000000808A,
0x8000000080008000,
0x000000000000808B,
0x0000000080000001,
0x8000000080008081,
0x8000000000008009,
0x000000000000008A,
0x0000000000000088,
0x0000000080008009,
0x000000008000000A,
0x000000008000808B,
0x800000000000008B,
0x8000000000008089,
0x8000000000008003,
0x8000000000008002,
0x8000000000000080,
0x000000000000800A,
0x800000008000000A,
0x8000000080008081,
0x8000000000008080,
0x0000000080000001,
0x8000000080008008,
];
pub struct SHA3 {
length: usize,
rate: usize,
len: usize,
//s: [[u64; 5]; 5],
s: [u64;25],
}
impl SHA3 {
fn rotl(x: u64, n: u64) -> u64 {
((x) << n) | ((x) >> (64 - n))
}
fn transform(&mut self) {
for k in 0..ROUNDS {
let c0=self.s[0]^self.s[5]^self.s[10]^self.s[15]^self.s[20];
let c1=self.s[1]^self.s[6]^self.s[11]^self.s[16]^self.s[21];
let c2=self.s[2]^self.s[7]^self.s[12]^self.s[17]^self.s[22];
let c3=self.s[3]^self.s[8]^self.s[13]^self.s[18]^self.s[23];
let c4=self.s[4]^self.s[9]^self.s[14]^self.s[19]^self.s[24];
let d0=c4^SHA3::rotl(c1,1);
let d1=c0^SHA3::rotl(c2,1);
let d2=c1^SHA3::rotl(c3,1);
let d3=c2^SHA3::rotl(c4,1);
let d4=c3^SHA3::rotl(c0,1);
let b00 = self.s[0]^d0;
let b02 = SHA3::rotl(self.s[1]^d1, 1);
let b04 = SHA3::rotl(self.s[2]^d2, 62);
let b01 = SHA3::rotl(self.s[3]^d3, 28);
let b03 = SHA3::rotl(self.s[4]^d4, 27);
let b13 = SHA3::rotl(self.s[5]^d0, 36);
let b10 = SHA3::rotl(self.s[6]^d1, 44);
let b12 = SHA3::rotl(self.s[7]^d2, 6);
let b14 = SHA3::rotl(self.s[8]^d3, 55);
let b11 = SHA3::rotl(self.s[9]^d4, 20);
let b21 = SHA3::rotl(self.s[10]^d0, 3);
let b23 = SHA3::rotl(self.s[11]^d1, 10);
let b20 = SHA3::rotl(self.s[12]^d2, 43);
let b22 = SHA3::rotl(self.s[13]^d3, 25);
let b24 = SHA3::rotl(self.s[14]^d4, 39);
let b34 = SHA3::rotl(self.s[15]^d0, 41);
let b31 = SHA3::rotl(self.s[16]^d1, 45);
let b33 = SHA3::rotl(self.s[17]^d2, 15);
let b30 = SHA3::rotl(self.s[18]^d3, 21);
let b32 = SHA3::rotl(self.s[19]^d4, 8);
let b42 = SHA3::rotl(self.s[20]^d0, 18);
let b44 = SHA3::rotl(self.s[21]^d1, 2);
let b41 = SHA3::rotl(self.s[22]^d2, 61);
let b43 = SHA3::rotl(self.s[23]^d3, 56);
let b40 = SHA3::rotl(self.s[24]^d4, 14);
self.s[0]=b00^(!b10&b20);
self.s[1]=b10^(!b20&b30);
self.s[2]=b20^(!b30&b40);
self.s[3]=b30^(!b40&b00);
self.s[4]=b40^(!b00&b10);
self.s[5]=b01^(!b11&b21);
self.s[6]=b11^(!b21&b31);
self.s[7]=b21^(!b31&b41);
self.s[8]=b31^(!b41&b01);
self.s[9]=b41^(!b01&b11);
self.s[10]=b02^(!b12&b22);
self.s[11]=b12^(!b22&b32);
self.s[12]=b22^(!b32&b42);
self.s[13]=b32^(!b42&b02);
self.s[14]=b42^(!b02&b12);
self.s[15]=b03^(!b13&b23);
self.s[16]=b13^(!b23&b33);
self.s[17]=b23^(!b33&b43);
self.s[18]=b33^(!b43&b03);
self.s[19]=b43^(!b03&b13);
self.s[20]=b04^(!b14&b24);
self.s[21]=b14^(!b24&b34);
self.s[22]=b24^(!b34&b44);
self.s[23]=b34^(!b44&b04);
self.s[24]=b44^(!b04&b14);
self.s[0] ^= RC[k];
}
}
/* Initialise Hash function */
pub fn init(&mut self, olen: usize) {
/* initialise */
for i in 0..25 {
self.s[i] = 0;
}
self.length = 0;
self.len = olen;
self.rate = 200 - 2 * olen;
}
pub fn new(olen: usize) -> SHA3 {
let mut nh = SHA3 {
length: 0,
rate: 0,
len: 0,
s: [0; 25],
};
nh.init(olen);
nh
}
pub fn new_copy(hh: &SHA3) -> SHA3 {
let mut nh = SHA3 {
length: 0,
rate: 0,
len: 0,
s: [0; 25],
};
nh.length=hh.length;
nh.len=hh.len;
nh.rate=hh.rate;
for i in 0..25 {
nh.s[i] = hh.s[i];
}
nh
}
/* process a single byte */
pub fn process(&mut self, byt: u8) {
/* process the next message byte */
let cnt = self.length as usize;
let b = cnt % 8;
let ind = cnt / 8;
self.s[ind] ^= (byt as u64) << (8 * b);
self.length += 1;
if self.length == self.rate {
self.length=0;
self.transform();
}
}
/* process an array of bytes */
pub fn process_array(&mut self, b: &[u8]) {
for i in 0..b.len() {
self.process(b[i])
}
}
/* process a 32-bit integer */
pub fn process_num(&mut self, n: i32) {
self.process(((n >> 24) & 0xff) as u8);
self.process(((n >> 16) & 0xff) as u8);
self.process(((n >> 8) & 0xff) as u8);
self.process((n & 0xff) as u8);
}
pub fn squeeze(&mut self, buff: &mut [u8], olen: usize) {
let mut m = 0;
let nb=olen/self.rate;
for _ in 0..nb {
for i in 0..self.rate/8 {
let mut el=self.s[i];
for _ in 0..8 {
buff[m]=(el & 0xff) as u8;
m += 1;
el >>= 8;
}
}
self.transform();
}
let mut i=0;
while m<olen {
let mut el=self.s[i]; i += 1;
for _ in 0..8 {
buff[m]=(el & 0xff) as u8;
m += 1;
if m >= olen {
break;
}
el >>= 8;
}
}
/*
loop {
for i in 0..25 {
let mut el = self.s[i];
for _ in 0..8 {
buff[m] = (el & 0xff) as u8;
m += 1;
if m >= olen || (m % self.rate) == 0 {
done = true;
break;
}
el >>= 8;
}
if done {
break;
}
}
if m >= olen {
break;
}
done = false;
self.transform();
} */
}
/* Generate 32-byte Hash */
pub fn hash(&mut self, digest: &mut [u8]) {
/* pad message and finish - supply digest */
let q = self.rate - self.length;
if q == 1 {
self.process(0x86);
} else {
self.process(0x06);
while self.length != self.rate - 1 {
self.process(0x00)
}
self.process(0x80);
}
let hlen = self.len as usize;
self.squeeze(digest, hlen);
}
pub fn continuing_hash(&mut self, digest: &mut [u8]) {
let mut sh=SHA3::new_copy(self);
sh.hash(digest)
}
pub fn shake(&mut self, digest: &mut [u8], olen: usize) {
let q = self.rate - self.length;
if q == 1 {
self.process(0x9f);
} else {
self.process(0x1f);
while self.length != self.rate - 1 {
self.process(0x00)
}
self.process(0x80);
}
self.squeeze(digest, olen);
}
pub fn continuing_shake(&mut self, digest: &mut [u8], olen: usize) {
let mut sh=SHA3::new_copy(self);
sh.shake(digest,olen);
}
}
//916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18
//afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185
//98be04516c04cc73593fef3ed0352ea9f6443942d6950e29a372a681c3deaf4535423709b02843948684e029010badcc0acd8303fc85fdad3eabf4f78cae165635f57afd28810fc2
/*
fn main() {
let s = String::from("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
let mut digest: [u8;100]=[0;100];
let test = s.into_bytes();
let mut sh=SHA3::new(HASH256);
for i in 0..test.len(){
sh.process(test[i]);
}
sh.hash(&mut digest);
for i in 0..32 {print!("{:02x}",digest[i])}
println!("");
sh=SHA3::new(HASH512);
for i in 0..test.len(){
sh.process(test[i]);
}
sh.hash(&mut digest);
for i in 0..64 {print!("{:02x}",digest[i])}
println!("");
sh=SHA3::new(SHAKE256);
for i in 0..test.len(){
sh.process(test[i]);
}
sh.shake(&mut digest,72);
for i in 0..72 {print!("{:02x}",digest[i])}
println!("");
} */