-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Buffer256 * experiment * broken * next step * K is correct * correct * still works * still works * init * still works * still * works again * remove K * Works :-) * minor * using u128.
- Loading branch information
1 parent
fe9fa10
commit ae37cb6
Showing
7 changed files
with
243 additions
and
160 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#[inline(always)] | ||
pub const fn add(a: u32, b: u32) -> u32 { | ||
a.overflowing_add(b).0 | ||
} | ||
|
||
#[inline(always)] | ||
pub const fn add2(a: u32, b: u32, c: u32) -> u32 { | ||
add(add(a, b), c) | ||
} | ||
|
||
#[inline(always)] | ||
pub const fn add3(a: u32, b: u32, c: u32, d: u32) -> u32 { | ||
add(add(a, b), add(c, d)) | ||
} | ||
|
||
#[inline(always)] | ||
pub const fn add4(a: u32, b: u32, c: u32, d: u32, e: u32) -> u32 { | ||
add2(add2(a, b, c), d, e) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,203 +1,142 @@ | ||
use crate::digest224::Digest224; | ||
|
||
struct BigSigma(u32, u32, u32); | ||
|
||
impl BigSigma { | ||
#[inline(always)] | ||
const fn get(&self, v: u32) -> u32 { | ||
v.rotate_right(self.0) ^ v.rotate_right(self.1) ^ v.rotate_right(self.2) | ||
} | ||
use crate::{ | ||
overflow32::{add, add3, add4}, | ||
sigma32::{BIG0, BIG1, SMALL0, SMALL1}, u32x4::{to_u32x4, to_u128, get_u32}, u32x8::{u32x8_add, U256}, u32x16::U512, | ||
}; | ||
|
||
const fn round([s0, s1]: U256, i: usize, w: u128, k: u128) -> U256 { | ||
let (a, e) = { | ||
let t1 = { | ||
let [e, f, g, h] = to_u32x4(s1); | ||
add4( | ||
h, | ||
BIG1.get(e), | ||
(e & f) ^ (!e & g), | ||
get_u32(k, i), | ||
get_u32(w, i), | ||
) | ||
}; | ||
let [a, b, c, d] = to_u32x4(s0); | ||
let t2 = add(BIG0.get(a), (a & b) ^ (a & c) ^ (b & c)); | ||
(add(t1, t2), add(d, t1)) | ||
}; | ||
[a as u128 | (s0 << 32), e as u128 | (s1 << 32)] | ||
} | ||
|
||
struct SmallSigma(u32, u32, u8); | ||
|
||
impl SmallSigma { | ||
#[inline(always)] | ||
const fn get(&self, v: u32) -> u32 { | ||
v.rotate_right(self.0) ^ v.rotate_right(self.1) ^ (v >> self.2) | ||
} | ||
} | ||
|
||
#[inline(always)] | ||
const fn add(a: u32, b: u32) -> u32 { | ||
a.overflowing_add(b).0 | ||
} | ||
|
||
#[inline(always)] | ||
const fn add2(a: u32, b: u32, c: u32) -> u32 { | ||
add(add(a, b), c) | ||
} | ||
|
||
#[inline(always)] | ||
const fn add3(a: u32, b: u32, c: u32, d: u32) -> u32 { | ||
add(add(a, b), add(c, d)) | ||
} | ||
|
||
#[inline(always)] | ||
const fn add4(a: u32, b: u32, c: u32, d: u32, e: u32) -> u32 { | ||
add2(add2(a, b, c), d, e) | ||
} | ||
|
||
type Digest256 = [u32; 8]; | ||
|
||
const BIG_S0: BigSigma = BigSigma(2, 13, 22); | ||
const BIG_S1: BigSigma = BigSigma(6, 11, 25); | ||
const SMALL_S0: SmallSigma = SmallSigma(7, 18, 3); | ||
const SMALL_S1: SmallSigma = SmallSigma(17, 19, 10); | ||
|
||
type Buffer = [u32; 16]; | ||
|
||
const fn round([a, b, c, d, e, f, g, h]: Digest256, i: usize, w: &Buffer, k: &Buffer) -> Digest256 { | ||
let t1 = add4(h, BIG_S1.get(e), (e & f) ^ (!e & g), k[i], w[i]); | ||
let t2 = add(BIG_S0.get(a), (a & b) ^ (a & c) ^ (b & c)); | ||
[add(t1, t2), a, b, c, add(d, t1), e, f, g] | ||
const fn round4(mut x: U256, i: usize, w: &U512, k: &U512) -> U256 { | ||
let w = w[i]; | ||
let k = k[i]; | ||
x = round(x, 0, w, k); | ||
x = round(x, 1, w, k); | ||
x = round(x, 2, w, k); | ||
round(x, 3, w, k) | ||
} | ||
|
||
const K: [Buffer; 4] = [ | ||
pub const K: [U512; 4] = [ | ||
[ | ||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, // | ||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, // | ||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, // | ||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, // | ||
0xe9b5dba5_b5c0fbcf_71374491_428a2f98, | ||
0xab1c5ed5_923f82a4_59f111f1_3956c25b, | ||
0x550c7dc3_243185be_12835b01_d807aa98, | ||
0xc19bf174_9bdc06a7_80deb1fe_72be5d74, | ||
], | ||
[ | ||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, // | ||
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, // | ||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, // | ||
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, // | ||
0x240ca1cc_0fc19dc6_efbe4786_e49b69c1, | ||
0x76f988da_5cb0a9dc_4a7484aa_2de92c6f, | ||
0xbf597fc7_b00327c8_a831c66d_983e5152, | ||
0x14292967_06ca6351_d5a79147_c6e00bf3, | ||
], | ||
[ | ||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, // | ||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, // | ||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, // | ||
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, // | ||
0x53380d13_4d2c6dfc_2e1b2138_27b70a85, | ||
0x92722c85_81c2c92e_766a0abb_650a7354, | ||
0xc76c51a3_c24b8b70_a81a664b_a2bfe8a1, | ||
0x106aa070_f40e3585_d6990624_d192e819, | ||
], | ||
[ | ||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, // | ||
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, // | ||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, // | ||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, // | ||
0x34b0bcb5_2748774c_1e376c08_19a4c116, | ||
0x682e6ff3_5b9cca4f_4ed8aa4a_391c0cb3, | ||
0x8cc70208_84c87814_78a5636f_748f82ee, | ||
0xc67178f2_bef9a3f7_a4506ceb_90befffa, | ||
], | ||
]; | ||
|
||
const fn round16(mut x: Digest256, w: &Buffer, j: usize) -> Digest256 { | ||
let k = &K[j]; | ||
x = round(x, 0, w, k); | ||
x = round(x, 1, w, k); | ||
x = round(x, 2, w, k); | ||
x = round(x, 3, w, k); | ||
x = round(x, 4, w, k); | ||
x = round(x, 5, w, k); | ||
x = round(x, 6, w, k); | ||
x = round(x, 7, w, k); | ||
x = round(x, 8, w, k); | ||
x = round(x, 9, w, k); | ||
x = round(x, 10, w, k); | ||
x = round(x, 11, w, k); | ||
x = round(x, 12, w, k); | ||
x = round(x, 13, w, k); | ||
x = round(x, 14, w, k); | ||
round(x, 15, w, k) | ||
const fn round16(mut x: U256, w: &U512, i: usize) -> U256 { | ||
let k = &K[i]; | ||
x = round4(x, 0, w, k); | ||
x = round4(x, 1, w, k); | ||
x = round4(x, 2, w, k); | ||
round4(x, 3, w, k) | ||
} | ||
|
||
#[inline(always)] | ||
const fn w_get(w: &Buffer, i: usize) -> u32 { | ||
w[i & 0xF] | ||
const fn w_round(w0: u32, w1: u32, w9: u32, we: u32) -> u32 { | ||
add3(SMALL1.get(we), w9, SMALL0.get(w1), w0) | ||
} | ||
|
||
#[inline(always)] | ||
const fn wi(w: &Buffer, i: usize) -> u32 { | ||
add3( | ||
SMALL_S1.get(w_get(w, i + 0xE)), | ||
w_get(w, i + 9), | ||
SMALL_S0.get(w_get(w, i + 1)), | ||
w[i], | ||
) | ||
const fn wi(w: &U512, i: usize) -> u128 { | ||
w[i & 3] | ||
} | ||
|
||
// 0123|4567|89AB|CDEF | ||
// 0123|0123|0123|0123 | ||
// 0:WR | | R | R | ||
// 1: WR | | R | R | ||
// 2:R WR| | R| | ||
// 3: R W|R | |R | ||
const fn w_round4(w: &U512, i: usize) -> u128 { | ||
let w10 = wi(w, i + 1) as u32; | ||
let [_, w21, w22, w23] = to_u32x4(wi(w, i + 2)); | ||
let [w30, _, w32, w33] = to_u32x4(wi(w, i + 3)); | ||
let mut w0 = to_u32x4(w[i]); | ||
w0[0] = w_round(w0[0], w0[1], w21, w32); | ||
w0[1] = w_round(w0[1], w0[2], w22, w33); | ||
w0[2] = w_round(w0[2], w0[3], w23, w0[0]); | ||
w0[3] = w_round(w0[3], w10, w30, w0[1]); | ||
to_u128(w0) | ||
} | ||
|
||
const fn next_w(mut w: Buffer) -> Buffer { | ||
w[0x0] = wi(&w, 0x0); | ||
w[0x1] = wi(&w, 0x1); | ||
w[0x2] = wi(&w, 0x2); | ||
w[0x3] = wi(&w, 0x3); | ||
w[0x4] = wi(&w, 0x4); | ||
w[0x5] = wi(&w, 0x5); | ||
w[0x6] = wi(&w, 0x6); | ||
w[0x7] = wi(&w, 0x7); | ||
w[0x8] = wi(&w, 0x8); | ||
w[0x9] = wi(&w, 0x9); | ||
w[0xA] = wi(&w, 0xA); | ||
w[0xB] = wi(&w, 0xB); | ||
w[0xC] = wi(&w, 0xC); | ||
w[0xD] = wi(&w, 0xD); | ||
w[0xE] = wi(&w, 0xE); | ||
w[0xF] = wi(&w, 0xF); | ||
const fn w_round16(mut w: U512) -> U512 { | ||
w[0] = w_round4(&w, 0); | ||
w[1] = w_round4(&w, 1); | ||
w[2] = w_round4(&w, 2); | ||
w[3] = w_round4(&w, 3); | ||
w | ||
} | ||
|
||
const SHA224_INIT: Digest256 = [ | ||
0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4, | ||
pub const INIT: U256 = [ | ||
0xf70e5939_3070dd17_367cd507_c1059ed8, | ||
0xbefa4fa4_64f98fa7_68581511_ffc00b31, | ||
]; | ||
|
||
pub const fn compress(mut w: Buffer) -> Digest224 { | ||
let mut x: Digest256 = SHA224_INIT; | ||
pub const fn compress(mut w: U512) -> U256 { | ||
let mut x: U256 = INIT; | ||
x = round16(x, &w, 0); | ||
w = next_w(w); | ||
w = w_round16(w); | ||
x = round16(x, &w, 1); | ||
w = next_w(w); | ||
w = w_round16(w); | ||
x = round16(x, &w, 2); | ||
w = next_w(w); | ||
w = w_round16(w); | ||
x = round16(x, &w, 3); | ||
[ | ||
add(x[0], SHA224_INIT[0]), | ||
add(x[1], SHA224_INIT[1]), | ||
add(x[2], SHA224_INIT[2]), | ||
add(x[3], SHA224_INIT[3]), | ||
add(x[4], SHA224_INIT[4]), | ||
add(x[5], SHA224_INIT[5]), | ||
add(x[6], SHA224_INIT[6]), | ||
] | ||
x = u32x8_add(&x, &INIT); | ||
x[1] |= 0xFFFF_FFFF << 96; | ||
x | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::static_assert::static_assert; | ||
mod test { | ||
use super::{compress, U256}; | ||
|
||
use super::{compress, Digest224}; | ||
|
||
pub const fn eq( | ||
[a0, a1, a2, a3, a4, a5, a6]: Digest224, | ||
[b0, b1, b2, b3, b4, b5, b6]: Digest224, | ||
) -> bool { | ||
a0 == b0 && a1 == b1 && a2 == b2 && a3 == b3 && a4 == b4 && a5 == b5 && a6 == b6 | ||
} | ||
|
||
const A: Digest224 = compress([0x8000_0000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); | ||
|
||
const _: () = static_assert(eq( | ||
compress([0x8000_0000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), | ||
[ | ||
0xd14a028c, 0x2a3a2bc9, 0x476102bb, 0x288234c4, 0x15a2b01f, 0x828ea62a, 0xc5b3e42f, | ||
], | ||
)); | ||
const A: U256 = compress([0x8000_0000, 0, 0, 0]); | ||
|
||
#[test] | ||
fn test() { | ||
assert!(eq( | ||
A, | ||
[0xd14a028c, 0x2a3a2bc9, 0x476102bb, 0x288234c4, 0x15a2b01f, 0x828ea62a, 0xc5b3e42f] | ||
)); | ||
assert_eq!( | ||
A, | ||
[0xd14a028c, 0x2a3a2bc9, 0x476102bb, 0x288234c4, 0x15a2b01f, 0x828ea62a, 0xc5b3e42f] | ||
); | ||
} | ||
println!("{:x?}", A); | ||
|
||
#[test] | ||
fn runtime_test() { | ||
assert_eq!( | ||
compress([0x8000_0000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), | ||
[0xd14a028c, 0x2a3a2bc9, 0x476102bb, 0x288234c4, 0x15a2b01f, 0x828ea62a, 0xc5b3e42f] | ||
A, | ||
[ | ||
0x288234c4_476102bb_2a3a2bc9_d14a028c, | ||
0xFFFFFFFF_c5b3e42f_828ea62a_15a2b01f | ||
] | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
pub struct Big(u32, u32, u32); | ||
|
||
impl Big { | ||
#[inline(always)] | ||
pub const fn get(&self, v: u32) -> u32 { | ||
v.rotate_right(self.0) ^ v.rotate_right(self.1) ^ v.rotate_right(self.2) | ||
} | ||
} | ||
|
||
pub struct Small(u32, u32, u8); | ||
|
||
impl Small { | ||
#[inline(always)] | ||
pub const fn get(&self, v: u32) -> u32 { | ||
v.rotate_right(self.0) ^ v.rotate_right(self.1) ^ (v >> self.2) | ||
} | ||
} | ||
|
||
pub const BIG0: Big = Big(2, 13, 22); | ||
pub const BIG1: Big = Big(6, 11, 25); | ||
pub const SMALL0: Small = Small(7, 18, 3); | ||
pub const SMALL1: Small = Small(17, 19, 10); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
use crate::u32x4::to_u128; | ||
|
||
pub type U512 = [u128; 4]; | ||
|
||
#[inline(always)] | ||
pub const fn to_u32x16(&[a, b, c, d]: &U512) -> [u32; 16] { | ||
[ | ||
a as u32, | ||
(a >> 32) as u32, | ||
(a >> 64) as u32, | ||
(a >> 96) as u32, | ||
b as u32, | ||
(b >> 32) as u32, | ||
(b >> 64) as u32, | ||
(b >> 96) as u32, | ||
c as u32, | ||
(c >> 32) as u32, | ||
(c >> 64) as u32, | ||
(c >> 96) as u32, | ||
d as u32, | ||
(d >> 32) as u32, | ||
(d >> 64) as u32, | ||
(d >> 96) as u32, | ||
] | ||
} | ||
|
||
#[inline(always)] | ||
pub const fn to_u512( | ||
&[w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, wa, wb, wc, wd, we, wf]: &[u32; 16], | ||
) -> U512 { | ||
[ | ||
to_u128([w0, w1, w2, w3]), | ||
to_u128([w4, w5, w6, w7]), | ||
to_u128([w8, w9, wa, wb]), | ||
to_u128([wc, wd, we, wf]), | ||
] | ||
} |
Oops, something went wrong.