use std::fmt::{ self, Debug, Display, Formatter };
use std::ptr::copy_nonoverlapping;
use crate::number::{ SmallUInt, LongUnion };
#[allow(non_camel_case_types)]
#[allow(non_upper_case_globals)]
pub type SHA2_512_t_Expanded<const t: usize = 512,
const A5A5A5A5A5A5A5A5: u64 = 0xa5a5a5a5a5a5a5a5,
const H0: u64 = 0x6a09e667f3bcc908, const H1: u64 = 0xbb67ae8584caa73b,
const H2: u64 = 0x3c6ef372fe94f82b, const H3: u64 = 0xa54ff53a5f1d36f1,
const H4: u64 = 0x510e527fade682d1, const H5: u64 = 0x9b05688c2b3e6c1f,
const H6: u64 = 0x1f83d9abfb41bd6b, const H7: u64 = 0x5be0cd19137e2179,
const ROUND: usize = 80>
= SHA2_512_t_Generic<t, A5A5A5A5A5A5A5A5, H0, H1, H2, H3, H4, H5, H6, H7, ROUND>;
#[allow(non_camel_case_types)]
pub type SHA2_512_t_256_Expanded<const A5A5A5A5A5A5A5A5: u64 = 0xa5a5a5a5a5a5a5a5,
const ROUND: usize = 80>
= SHA2_512_t_Expanded<256, A5A5A5A5A5A5A5A5,
0x6a09e667f3bcc908, 0xbb67ae8584caa73b,
0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
0x510e527fade682d1, 0x9b05688c2b3e6c1f,
0x1f83d9abfb41bd6b, 0x5be0cd19137e2179, ROUND>;
#[allow(non_camel_case_types)]
pub type SHA2_512_t_224_Expanded<const A5A5A5A5A5A5A5A5: u64 = 0xa5a5a5a5a5a5a5a5,
const ROUND: usize = 80>
= SHA2_512_t_Expanded<224, A5A5A5A5A5A5A5A5,
0x6a09e667f3bcc908, 0xbb67ae8584caa73b,
0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
0x510e527fade682d1, 0x9b05688c2b3e6c1f,
0x1f83d9abfb41bd6b, 0x5be0cd19137e2179, ROUND>;
#[allow(non_camel_case_types)]
#[allow(non_upper_case_globals)]
pub type SHA2_512_t_Generic_HRS_fixed<const t: usize = 512, const ROUND: usize = 80,
const K00: u64 = 0x428a2f98d728ae22, const K01: u64 = 0x7137449123ef65cd,
const K02: u64 = 0xb5c0fbcfec4d3b2f, const K03: u64 = 0xe9b5dba58189dbbc,
const K04: u64 = 0x3956c25bf348b538, const K05: u64 = 0x59f111f1b605d019,
const K06: u64 = 0x923f82a4af194f9b, const K07: u64 = 0xab1c5ed5da6d8118,
const K08: u64 = 0xd807aa98a3030242, const K09: u64 = 0x12835b0145706fbe,
const K10: u64 = 0x243185be4ee4b28c, const K11: u64 = 0x550c7dc3d5ffb4e2,
const K12: u64 = 0x72be5d74f27b896f, const K13: u64 = 0x80deb1fe3b1696b1,
const K14: u64 = 0x9bdc06a725c71235, const K15: u64 = 0xc19bf174cf692694,
const K16: u64 = 0xe49b69c19ef14ad2, const K17: u64 = 0xefbe4786384f25e3,
const K18: u64 = 0x0fc19dc68b8cd5b5, const K19: u64 = 0x240ca1cc77ac9c65,
const K20: u64 = 0x2de92c6f592b0275, const K21: u64 = 0x4a7484aa6ea6e483,
const K22: u64 = 0x5cb0a9dcbd41fbd4, const K23: u64 = 0x76f988da831153b5,
const K24: u64 = 0x983e5152ee66dfab, const K25: u64 = 0xa831c66d2db43210,
const K26: u64 = 0xb00327c898fb213f, const K27: u64 = 0xbf597fc7beef0ee4,
const K28: u64 = 0xc6e00bf33da88fc2, const K29: u64 = 0xd5a79147930aa725,
const K30: u64 = 0x06ca6351e003826f, const K31: u64 = 0x142929670a0e6e70,
const K32: u64 = 0x27b70a8546d22ffc, const K33: u64 = 0x2e1b21385c26c926,
const K34: u64 = 0x4d2c6dfc5ac42aed, const K35: u64 = 0x53380d139d95b3df,
const K36: u64 = 0x650a73548baf63de, const K37: u64 = 0x766a0abb3c77b2a8,
const K38: u64 = 0x81c2c92e47edaee6, const K39: u64 = 0x92722c851482353b,
const K40: u64 = 0xa2bfe8a14cf10364, const K41: u64 = 0xa81a664bbc423001,
const K42: u64 = 0xc24b8b70d0f89791, const K43: u64 = 0xc76c51a30654be30,
const K44: u64 = 0xd192e819d6ef5218, const K45: u64 = 0xd69906245565a910,
const K46: u64 = 0xf40e35855771202a, const K47: u64 = 0x106aa07032bbd1b8,
const K48: u64 = 0x19a4c116b8d2d0c8, const K49: u64 = 0x1e376c085141ab53,
const K50: u64 = 0x2748774cdf8eeb99, const K51: u64 = 0x34b0bcb5e19b48a8,
const K52: u64 = 0x391c0cb3c5c95a63, const K53: u64 = 0x4ed8aa4ae3418acb,
const K54: u64 = 0x5b9cca4f7763e373, const K55: u64 = 0x682e6ff3d6b2b8a3,
const K56: u64 = 0x748f82ee5defb2fc, const K57: u64 = 0x78a5636f43172f60,
const K58: u64 = 0x84c87814a1f0ab72, const K59: u64 = 0x8cc702081a6439ec,
const K60: u64 = 0x90befffa23631e28, const K61: u64 = 0xa4506cebde82bde9,
const K62: u64 = 0xbef9a3f7b2c67915, const K63: u64 = 0xc67178f2e372532b,
const K64: u64 = 0xca273eceea26619c, const K65: u64 = 0xd186b8c721c0c207,
const K66: u64 = 0xeada7dd6cde0eb1e, const K67: u64 = 0xf57d4f7fee6ed178,
const K68: u64 = 0x06f067aa72176fba, const K69: u64 = 0x0a637dc5a2c898a6,
const K70: u64 = 0x113f9804bef90dae, const K71: u64 = 0x1b710b35131c471b,
const K72: u64 = 0x28db77f523047d84, const K73: u64 = 0x32caab7b40c72493,
const K74: u64 = 0x3c9ebe0a15c9bebc, const K75: u64 = 0x431d67c49c100d4c,
const K76: u64 = 0x4cc5d4becb3e42b6, const K77: u64 = 0x597f299cfc657e2a,
const K78: u64 = 0x5fcb6fab3ad6faec, const K79: u64 = 0x6c44198c4a475817>
= SHA2_512_t_Generic<t, 0xa5a5a5a5a5a5a5a5,
0x6a09e667f3bcc908, 0xbb67ae8584caa73b,
0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
0x510e527fade682d1, 0x9b05688c2b3e6c1f,
0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
ROUND,
K00, K01, K02, K03, K04, K05, K06, K07,
K08, K09, K10, K11, K12, K13, K14, K15,
K16, K17, K18, K19, K20, K21, K22, K23,
K24, K25, K26, K27, K28, K29, K30, K31,
K32, K33, K34, K35, K36, K37, K38, K39,
K40, K41, K42, K43, K44, K45, K46, K47,
K48, K49, K50, K51, K52, K53, K54, K55,
K56, K57, K58, K59, K60, K61, K62, K63,
K64, K65, K66, K67, K68, K69, K70, K71,
K72, K73, K74, K75, K76, K77, K78, K79,
1, 8, 14, 18, 19, 28, 34, 39, 41, 61, 6, 7>;
#[allow(non_camel_case_types)]
#[allow(non_upper_case_globals)]
pub type SHA2_512_t<const t: usize = 512> = SHA2_512_t_Generic<t>;
#[allow(non_camel_case_types)]
pub type SHA2_512_t_256 = SHA2_512_t_Generic<256>;
#[allow(non_camel_case_types)]
pub type SHA2_512_t_224 = SHA2_512_t_Generic<224>;
#[allow(non_camel_case_types)]
pub type SHA2_512_0 = SHA2_512_t_Generic;
#[derive(Debug, Clone)]
#[allow(non_camel_case_types)]
#[allow(non_upper_case_globals)]
pub struct SHA2_512_t_Generic<const t: usize = 512,
const A5A5A5A5A5A5A5A5: u64 = 0xa5a5a5a5a5a5a5a5,
const H0: u64 = 0x6a09e667f3bcc908, const H1: u64 = 0xbb67ae8584caa73b,
const H2: u64 = 0x3c6ef372fe94f82b, const H3: u64 = 0xa54ff53a5f1d36f1,
const H4: u64 = 0x510e527fade682d1, const H5: u64 = 0x9b05688c2b3e6c1f,
const H6: u64 = 0x1f83d9abfb41bd6b, const H7: u64 = 0x5be0cd19137e2179,
const ROUND: usize = 80,
const K00: u64 = 0x428a2f98d728ae22, const K01: u64 = 0x7137449123ef65cd,
const K02: u64 = 0xb5c0fbcfec4d3b2f, const K03: u64 = 0xe9b5dba58189dbbc,
const K04: u64 = 0x3956c25bf348b538, const K05: u64 = 0x59f111f1b605d019,
const K06: u64 = 0x923f82a4af194f9b, const K07: u64 = 0xab1c5ed5da6d8118,
const K08: u64 = 0xd807aa98a3030242, const K09: u64 = 0x12835b0145706fbe,
const K10: u64 = 0x243185be4ee4b28c, const K11: u64 = 0x550c7dc3d5ffb4e2,
const K12: u64 = 0x72be5d74f27b896f, const K13: u64 = 0x80deb1fe3b1696b1,
const K14: u64 = 0x9bdc06a725c71235, const K15: u64 = 0xc19bf174cf692694,
const K16: u64 = 0xe49b69c19ef14ad2, const K17: u64 = 0xefbe4786384f25e3,
const K18: u64 = 0x0fc19dc68b8cd5b5, const K19: u64 = 0x240ca1cc77ac9c65,
const K20: u64 = 0x2de92c6f592b0275, const K21: u64 = 0x4a7484aa6ea6e483,
const K22: u64 = 0x5cb0a9dcbd41fbd4, const K23: u64 = 0x76f988da831153b5,
const K24: u64 = 0x983e5152ee66dfab, const K25: u64 = 0xa831c66d2db43210,
const K26: u64 = 0xb00327c898fb213f, const K27: u64 = 0xbf597fc7beef0ee4,
const K28: u64 = 0xc6e00bf33da88fc2, const K29: u64 = 0xd5a79147930aa725,
const K30: u64 = 0x06ca6351e003826f, const K31: u64 = 0x142929670a0e6e70,
const K32: u64 = 0x27b70a8546d22ffc, const K33: u64 = 0x2e1b21385c26c926,
const K34: u64 = 0x4d2c6dfc5ac42aed, const K35: u64 = 0x53380d139d95b3df,
const K36: u64 = 0x650a73548baf63de, const K37: u64 = 0x766a0abb3c77b2a8,
const K38: u64 = 0x81c2c92e47edaee6, const K39: u64 = 0x92722c851482353b,
const K40: u64 = 0xa2bfe8a14cf10364, const K41: u64 = 0xa81a664bbc423001,
const K42: u64 = 0xc24b8b70d0f89791, const K43: u64 = 0xc76c51a30654be30,
const K44: u64 = 0xd192e819d6ef5218, const K45: u64 = 0xd69906245565a910,
const K46: u64 = 0xf40e35855771202a, const K47: u64 = 0x106aa07032bbd1b8,
const K48: u64 = 0x19a4c116b8d2d0c8, const K49: u64 = 0x1e376c085141ab53,
const K50: u64 = 0x2748774cdf8eeb99, const K51: u64 = 0x34b0bcb5e19b48a8,
const K52: u64 = 0x391c0cb3c5c95a63, const K53: u64 = 0x4ed8aa4ae3418acb,
const K54: u64 = 0x5b9cca4f7763e373, const K55: u64 = 0x682e6ff3d6b2b8a3,
const K56: u64 = 0x748f82ee5defb2fc, const K57: u64 = 0x78a5636f43172f60,
const K58: u64 = 0x84c87814a1f0ab72, const K59: u64 = 0x8cc702081a6439ec,
const K60: u64 = 0x90befffa23631e28, const K61: u64 = 0xa4506cebde82bde9,
const K62: u64 = 0xbef9a3f7b2c67915, const K63: u64 = 0xc67178f2e372532b,
const K64: u64 = 0xca273eceea26619c, const K65: u64 = 0xd186b8c721c0c207,
const K66: u64 = 0xeada7dd6cde0eb1e, const K67: u64 = 0xf57d4f7fee6ed178,
const K68: u64 = 0x06f067aa72176fba, const K69: u64 = 0x0a637dc5a2c898a6,
const K70: u64 = 0x113f9804bef90dae, const K71: u64 = 0x1b710b35131c471b,
const K72: u64 = 0x28db77f523047d84, const K73: u64 = 0x32caab7b40c72493,
const K74: u64 = 0x3c9ebe0a15c9bebc, const K75: u64 = 0x431d67c49c100d4c,
const K76: u64 = 0x4cc5d4becb3e42b6, const K77: u64 = 0x597f299cfc657e2a,
const K78: u64 = 0x5fcb6fab3ad6faec, const K79: u64 = 0x6c44198c4a475817,
const RR1: u32 = 1, const RR8: u32 = 8, const RR14: u32 = 14,
const RR18: u32 = 18, const RR19: u32 = 19, const RR28: u32 = 28,
const RR34: u32 = 34, const RR39: u32 = 39, const RR41: u32 = 41,
const RR61: u32 = 61, const SR6: i32 = 6, const SR7: i32 = 7>
{
hash_code: [LongUnion; 8],
o: [u64; 8],
}
#[allow(non_upper_case_globals)]
impl<const t: usize, const A5A5A5A5A5A5A5A5: u64,
const H0: u64, const H1: u64, const H2: u64, const H3: u64,
const H4: u64, const H5: u64, const H6: u64, const H7: u64,
const ROUND: usize,
const K00: u64, const K01: u64, const K02: u64, const K03: u64,
const K04: u64, const K05: u64, const K06: u64, const K07: u64,
const K08: u64, const K09: u64, const K10: u64, const K11: u64,
const K12: u64, const K13: u64, const K14: u64, const K15: u64,
const K16: u64, const K17: u64, const K18: u64, const K19: u64,
const K20: u64, const K21: u64, const K22: u64, const K23: u64,
const K24: u64, const K25: u64, const K26: u64, const K27: u64,
const K28: u64, const K29: u64, const K30: u64, const K31: u64,
const K32: u64, const K33: u64, const K34: u64, const K35: u64,
const K36: u64, const K37: u64, const K38: u64, const K39: u64,
const K40: u64, const K41: u64, const K42: u64, const K43: u64,
const K44: u64, const K45: u64, const K46: u64, const K47: u64,
const K48: u64, const K49: u64, const K50: u64, const K51: u64,
const K52: u64, const K53: u64, const K54: u64, const K55: u64,
const K56: u64, const K57: u64, const K58: u64, const K59: u64,
const K60: u64, const K61: u64, const K62: u64, const K63: u64,
const K64: u64, const K65: u64, const K66: u64, const K67: u64,
const K68: u64, const K69: u64, const K70: u64, const K71: u64,
const K72: u64, const K73: u64, const K74: u64, const K75: u64,
const K76: u64, const K77: u64, const K78: u64, const K79: u64,
const RR1: u32, const RR8: u32, const RR14: u32, const RR18: u32,
const RR19: u32, const RR28: u32, const RR34: u32, const RR39: u32,
const RR41: u32, const RR61: u32, const SR6: i32, const SR7: i32>
SHA2_512_t_Generic<t, A5A5A5A5A5A5A5A5,
H0, H1, H2, H3, H4, H5, H6, H7, ROUND,
K00, K01, K02, K03, K04, K05, K06, K07,
K08, K09, K10, K11, K12, K13, K14, K15,
K16, K17, K18, K19, K20, K21, K22, K23,
K24, K25, K26, K27, K28, K29, K30, K31,
K32, K33, K34, K35, K36, K37, K38, K39,
K40, K41, K42, K43, K44, K45, K46, K47,
K48, K49, K50, K51, K52, K53, K54, K55,
K56, K57, K58, K59, K60, K61, K62, K63,
K64, K65, K66, K67, K68, K69, K70, K71,
K72, K73, K74, K75, K76, K77, K78, K79,
RR1, RR8, RR14, RR18, RR19, RR28, RR34,
RR39, RR41, RR61, SR6, SR7>
{
pub(crate) const DEFUALT_OUTPUT_LENGTH_IN_BYTES: usize = t / 8;
const K: [u64; 80] = [ K00, K01, K02, K03, K04, K05, K06, K07,
K08, K09, K10, K11, K12, K13, K14, K15,
K16, K17, K18, K19, K20, K21, K22, K23,
K24, K25, K26, K27, K28, K29, K30, K31,
K32, K33, K34, K35, K36, K37, K38, K39,
K40, K41, K42, K43, K44, K45, K46, K47,
K48, K49, K50, K51, K52, K53, K54, K55,
K56, K57, K58, K59, K60, K61, K62, K63,
K64, K65, K66, K67, K68, K69, K70, K71,
K72, K73, K74, K75, K76, K77, K78, K79 ];
const H: [u64; 8] = [ H0, H1, H2, H3, H4, H5, H6, H7 ];
#[inline]
pub fn new() -> Self
{
Self::new_with_seed_text(format!("SHA-512/{}", t).as_str())
}
#[inline]
pub fn box_new() -> Box<Self>
{
Box::new(Self::new())
}
pub fn new_with_seed_text(seed_text: &str) -> Self
{
if t > 512
{ panic!("t cannot be greater than 512."); }
if (t & 0b111) != 0
{ panic!("t should be multiple of 8."); }
let seed_text = format!("{}", seed_text);
let o = [ Self::H[0] ^ A5A5A5A5A5A5A5A5,
Self::H[1] ^ A5A5A5A5A5A5A5A5,
Self::H[2] ^ A5A5A5A5A5A5A5A5,
Self::H[3] ^ A5A5A5A5A5A5A5A5,
Self::H[4] ^ A5A5A5A5A5A5A5A5,
Self::H[5] ^ A5A5A5A5A5A5A5A5,
Self::H[6] ^ A5A5A5A5A5A5A5A5,
Self::H[7] ^ A5A5A5A5A5A5A5A5 ];
let mut h = SHA2_512_0::new_with_h(&o);
h.digest(seed_text.as_ptr(), seed_text.len() as u64);
let mut o = [0_u64; 8];
h.put_hash_value_in_array(&mut o);
for i in 0..8
{ o[i] = o[i].to_be(); }
Self::new_with_h(&o)
}
fn new_with_h(h: &[u64; 8]) -> Self
{
Self
{
hash_code: [LongUnion::new_with(h[0]),
LongUnion::new_with(h[1]),
LongUnion::new_with(h[2]),
LongUnion::new_with(h[3]),
LongUnion::new_with(h[4]),
LongUnion::new_with(h[5]),
LongUnion::new_with(h[6]),
LongUnion::new_with(h[7])],
o: [ h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7] ],
}
}
pub fn digest(&mut self, message: *const u8, length_in_bytes: u64)
{
type MessageType = u64;
const SHIFT_NUM: usize = 7;
const CHUNK_NUM: usize = 16;
let mut block: [MessageType; CHUNK_NUM] = [0; CHUNK_NUM];
self.initialize();
let length_done = (length_in_bytes >> SHIFT_NUM) as usize;
for i in 0..length_done
{
unsafe { copy_nonoverlapping(message.add(i << SHIFT_NUM) as *const u8, block.as_mut_ptr() as *mut u8, CHUNK_NUM * 8); }
self.update(&block);
}
self.finalize(unsafe { message.add(length_done << SHIFT_NUM) }, length_in_bytes);
}
#[inline]
pub fn digest_str(&mut self, message: &str)
{
self.digest(message.as_ptr(), message.len() as u64);
}
#[inline]
pub fn digest_string(&mut self, message: &String)
{
self.digest(message.as_ptr(), message.len() as u64);
}
#[inline]
pub fn digest_array<T, const M: usize>(&mut self, message: &[T; M])
where T: SmallUInt + Copy + Clone + Display + Debug + ToString
{
self.digest(message.as_ptr() as *const u8, (M as u32 * T::size_in_bytes()) as u64);
}
#[inline]
pub fn digest_vec<T>(&mut self, message: &Vec<T>)
where T: SmallUInt + Copy + Clone + Display + Debug + ToString
{
self.digest(message.as_ptr() as *const u8, (message.len() as u32 * T::size_in_bytes()) as u64);
}
pub fn ruminate(&mut self, n: usize, message: *const u8, length_in_bytes: u64)
{
self.digest(message, length_in_bytes);
for _ in 1..n
{ self.digest_array(&self.get_hash_value_in_array()); }
}
#[inline]
pub fn ruminate_str(&mut self, n: usize, message: &str)
{
self.ruminate(n, message.as_ptr(), message.len() as u64);
}
#[inline]
pub fn ruminate_string(&mut self, n: usize, message: &String)
{
self.ruminate(n, message.as_ptr(), message.len() as u64);
}
#[inline]
pub fn ruminate_array<T, const M: usize>(&mut self, n: usize, message: &[T; M])
where T: SmallUInt + Copy + Clone
{
self.ruminate(n, message.as_ptr() as *const u8, (M as u32 * T::size_in_bytes()) as u64);
}
#[inline]
pub fn ruminate_vec<T>(&mut self, n: usize, message: &Vec<T>)
where T: SmallUInt + Copy + Clone
{
self.ruminate(n, message.as_ptr() as *const u8, (message.len() as u32 * T::size_in_bytes()) as u64);
}
pub fn get_hash_value(&self, hash_value: *mut u8, length: usize)
{
let n = t & 0b11_1111;
let nn = (t >> 6) + if n == 0 {0} else {1};
let n_length = if length < (t >> 3) {length} else {t >> 3};
let mut hash_code = [0_u64; 8];
for i in 0..nn
{ hash_code[i] = self.hash_code[i].get(); }
if n != 0
{
let mask = (!0_u64) << (64-n);
hash_code[nn-1] &= mask;
}
for i in 0..nn
{ hash_code[i] = hash_code[i].to_be(); }
unsafe { copy_nonoverlapping(hash_code.as_ptr() as *const u8, hash_value, n_length); }
}
pub fn get_hash_value_in_string(&self) -> String
{
let n = t & 0b11_1111; let nn = (t >> 6) + if n != 0 {1} else {0};
let mut txt = String::new();
for i in 0..if n == 0 {nn} else {nn-1}
{
let hs = self.hash_code[i];
for j in 0..8
{
let byte = hs.get_ubyte_(7-j);
txt.push(Self::to_char(byte >> 4));
txt.push(Self::to_char(byte & 0b1111));
}
}
if n != 0
{
let hs = self.hash_code[nn-1];
let m = n >> 3; for j in 0..m
{
let byte = hs.get_ubyte_(7-j);
txt.push(Self::to_char(byte >> 4));
txt.push(Self::to_char(byte & 0b1111));
}
}
txt
}
pub fn get_hash_value_in_array(&self) -> [u64; 8]
{
let mut res = [0_u64; 8];
for i in 0..8
{ res[i] = self.hash_code[i].get().to_be(); }
res
}
pub fn get_hash_value_in_array_tm<T, const M: usize>(&self) -> [T; M]
where T: SmallUInt + Copy + Clone + Display + Debug + ToString
{
let mut o = [T::zero(); M];
self.put_hash_value_in_array(&mut o);
o
}
pub fn get_hash_value_in_vec(&self) -> Vec<u64>
{
let n = t & 0b11_1111; let nn = (t >> 6) + if n == 0 {0} else {1};
let mut res = Vec::new();
for i in 0..nn
{ res.push(self.hash_code[i].get().to_be()); }
if n != 0
{ res[nn-1] &= (!0_u64) << (64-n); }
res
}
pub fn put_hash_value_in_array<T, const M: usize>(&self, out: &mut [T; M])
where T: SmallUInt + Copy + Clone + Display + Debug + ToString
{
let res = self.get_hash_value_in_array();
let out_size = T::size_in_bytes() * M as u32;
let length = if out_size < 64 {out_size} else {64};
unsafe { copy_nonoverlapping(res.as_ptr() as *const u8, out as *mut T as *mut u8, length as usize); }
}
#[inline]
pub fn tangle(&mut self, tangling: u64)
{
let mut m = [0_u64; 9];
for i in 0..8
{ m[i] = self.hash_code[i].get(); }
m[8] = tangling;
self.finalize(m.as_ptr() as *const u8, 72);
}
fn initialize(&mut self)
{
for i in 0..8_usize
{ self.hash_code[i] = LongUnion::new_with(self.o[i]); }
}
fn update(&mut self, message: &[u64])
{
let mut w = [0_u64; 16];
let mut a = self.hash_code[0].get();
let mut b = self.hash_code[1].get();
let mut c = self.hash_code[2].get();
let mut d = self.hash_code[3].get();
let mut e = self.hash_code[4].get();
let mut f = self.hash_code[5].get();
let mut g = self.hash_code[6].get();
let mut h = self.hash_code[7].get();
for i in 0..16_usize
{
w[i] = message[i].to_be();
let s1 = e.rotate_right(RR14) ^ e.rotate_right(RR18) ^ e.rotate_right(RR41);
let t1 = Self::ch(e, f, g).wrapping_add(h)
.wrapping_add(Self::get_k(i))
.wrapping_add(w[i])
.wrapping_add(s1);
let s0 = a.rotate_right(RR28) ^ a.rotate_right(RR34) ^ a.rotate_right(RR39);
let t2 = Self::maj(a, b, c).wrapping_add(s0);
h = g;
g = f;
f = e;
e = d.wrapping_add(t1);
d = c;
c = b;
b = a;
a = t1.wrapping_add(t2);
}
for i in 16..ROUND {
let j = i & 0b1111;
w[j] = Self::get_w(&w, i);
let s1 = e.rotate_right(RR14) ^ e.rotate_right(RR18) ^ e.rotate_right(RR41);
let t1 = Self::ch(e, f, g).wrapping_add(h)
.wrapping_add(Self::get_k(i))
.wrapping_add(w[j])
.wrapping_add(s1);
let s0 = a.rotate_right(RR28) ^ a.rotate_right(RR34) ^ a.rotate_right(RR39);
let t2 = Self::maj(a, b, c).wrapping_add(s0);
h = g;
g = f;
f = e;
e = d.wrapping_add(t1);
d = c;
c = b;
b = a;
a = t1.wrapping_add(t2);
}
self.hash_code[0].set(self.hash_code[0].get().wrapping_add(a));
self.hash_code[1].set(self.hash_code[1].get().wrapping_add(b));
self.hash_code[2].set(self.hash_code[2].get().wrapping_add(c));
self.hash_code[3].set(self.hash_code[3].get().wrapping_add(d));
self.hash_code[4].set(self.hash_code[4].get().wrapping_add(e));
self.hash_code[5].set(self.hash_code[5].get().wrapping_add(f));
self.hash_code[6].set(self.hash_code[6].get().wrapping_add(g));
self.hash_code[7].set(self.hash_code[7].get().wrapping_add(h));
}
fn finalize(&mut self, message: *const u8, length_in_bytes: u64)
{
type ChunkType = u128;
type PieceType = u64;
const MESSAGE_NUM: usize = 128;
const LAST_BYTES: u64 = 0b111_1111;
union MU
{
chunk: [ChunkType; 8],
piece: [PieceType; 16],
txt: [u8; MESSAGE_NUM],
}
let mut mu = MU { txt: [0; MESSAGE_NUM] };
let last_bytes = (length_in_bytes & LAST_BYTES) as usize; unsafe { copy_nonoverlapping(message, mu.txt.as_mut_ptr(), last_bytes); }
unsafe { mu.txt[last_bytes] = 0b1000_0000; }
if last_bytes > 110 {
self.update(unsafe {&mu.piece});
for i in 0..7
{ unsafe { mu.chunk[i] = 0; } }
}
unsafe { mu.chunk[7] = ((length_in_bytes as u128) << 3).to_be(); } self.update(unsafe {&mu.piece});
}
#[inline] fn get_k(idx: usize) -> u64 { Self::K[idx % 80] }
#[inline] fn get_s0(w: &[u64; 16], idx: usize) -> u64 { let ww = w[(idx-15) & 0b1111]; ww.rotate_right(RR1) ^ ww.rotate_right(RR8) ^ (ww >> SR7) }
#[inline] fn get_s1(w: &[u64; 16], idx: usize) -> u64 { let ww = w[(idx-2) & 0b1111]; ww.rotate_right(RR19) ^ ww.rotate_right(RR61) ^ (ww >> SR6) }
#[inline] fn get_w(w: &[u64; 16], idx: usize) -> u64 { w[(idx-16) & 0b1111].wrapping_add(Self::get_s0(&w, idx)).wrapping_add(w[(idx-7) & 0b1111]).wrapping_add(Self::get_s1(&w, idx)) }
#[inline] fn ch(x: u64, y: u64, z: u64) -> u64 { z ^ (x & (y ^ z)) } #[inline] fn maj(x: u64, y: u64, z: u64) -> u64 { (x & y) | (z & (x | y)) } #[inline] fn to_char(nibble: u8) -> char { if nibble < 10 { ('0' as u8 + nibble) as u8 as char } else { ('A' as u8 - 10 + nibble) as char } }
}
#[allow(non_upper_case_globals)]
impl<const t: usize, const A5A5A5A5A5A5A5A5: u64,
const H0: u64, const H1: u64, const H2: u64, const H3: u64,
const H4: u64, const H5: u64, const H6: u64, const H7: u64,
const ROUND: usize,
const K00: u64, const K01: u64, const K02: u64, const K03: u64,
const K04: u64, const K05: u64, const K06: u64, const K07: u64,
const K08: u64, const K09: u64, const K10: u64, const K11: u64,
const K12: u64, const K13: u64, const K14: u64, const K15: u64,
const K16: u64, const K17: u64, const K18: u64, const K19: u64,
const K20: u64, const K21: u64, const K22: u64, const K23: u64,
const K24: u64, const K25: u64, const K26: u64, const K27: u64,
const K28: u64, const K29: u64, const K30: u64, const K31: u64,
const K32: u64, const K33: u64, const K34: u64, const K35: u64,
const K36: u64, const K37: u64, const K38: u64, const K39: u64,
const K40: u64, const K41: u64, const K42: u64, const K43: u64,
const K44: u64, const K45: u64, const K46: u64, const K47: u64,
const K48: u64, const K49: u64, const K50: u64, const K51: u64,
const K52: u64, const K53: u64, const K54: u64, const K55: u64,
const K56: u64, const K57: u64, const K58: u64, const K59: u64,
const K60: u64, const K61: u64, const K62: u64, const K63: u64,
const K64: u64, const K65: u64, const K66: u64, const K67: u64,
const K68: u64, const K69: u64, const K70: u64, const K71: u64,
const K72: u64, const K73: u64, const K74: u64, const K75: u64,
const K76: u64, const K77: u64, const K78: u64, const K79: u64,
const RR1: u32, const RR8: u32, const RR14: u32, const RR18: u32,
const RR19: u32, const RR28: u32, const RR34: u32, const RR39: u32,
const RR41: u32, const RR61: u32, const SR6: i32, const SR7: i32>
Display for SHA2_512_t_Generic<t, A5A5A5A5A5A5A5A5,
H0, H1, H2, H3, H4, H5, H6, H7, ROUND,
K00, K01, K02, K03, K04, K05, K06, K07,
K08, K09, K10, K11, K12, K13, K14, K15,
K16, K17, K18, K19, K20, K21, K22, K23,
K24, K25, K26, K27, K28, K29, K30, K31,
K32, K33, K34, K35, K36, K37, K38, K39,
K40, K41, K42, K43, K44, K45, K46, K47,
K48, K49, K50, K51, K52, K53, K54, K55,
K56, K57, K58, K59, K60, K61, K62, K63,
K64, K65, K66, K67, K68, K69, K70, K71,
K72, K73, K74, K75, K76, K77, K78, K79,
RR1, RR8, RR14, RR18, RR19, RR28, RR34,
RR39, RR41, RR61, SR6, SR7>
{
fn fmt(&self, f: &mut Formatter) -> fmt::Result
{
write!(f, "{}", self.get_hash_value_in_string())
}
}