use crate::consts::SCHEDULE_SEED;
use crate::primitivefns::*;
use crate::structs::{NRound, PartialSchedArray, PrivateBlock, RawBlockRef, SchedArray, State};
pub(crate) const fn execute_until_rounds(
block: RawBlockRef,
previous_state: &State,
n: NRound,
) -> PrivateBlock {
let mut schedule_array: SchedArray = [0; 64];
let mut i = 0;
while i < 16 {
schedule_array[i] = u32::from_be_bytes([
block[i * 4],
block[i * 4 + 1],
block[i * 4 + 2],
block[i * 4 + 3],
]);
i += 1;
}
while i < n + 16 {
schedule_array[i] = lsigma1(schedule_array[i - 2])
.wrapping_add(schedule_array[i - 7])
.wrapping_add(lsigma0(schedule_array[i - 15]))
.wrapping_add(schedule_array[i - 16]);
i += 1;
}
let mut a = previous_state.a;
let mut b = previous_state.b;
let mut c = previous_state.c;
let mut d = previous_state.d;
let mut e = previous_state.e;
let mut f = previous_state.f;
let mut g = previous_state.g;
let mut h = previous_state.h;
let mut i = 0;
while i < n {
let t1 = h
.wrapping_add(sigma1(e))
.wrapping_add(ch(e, f, g))
.wrapping_add(SCHEDULE_SEED[i])
.wrapping_add(schedule_array[i]);
let t2 = sigma0(a).wrapping_add(maj(a, b, c));
h = g;
g = f;
f = e;
e = d.wrapping_add(t1);
d = c;
c = b;
b = a;
a = t1.wrapping_add(t2);
i += 1;
}
let psa: PartialSchedArray = [
schedule_array[n],
schedule_array[n + 1],
schedule_array[n + 2],
schedule_array[n + 3],
schedule_array[n + 4],
schedule_array[n + 5],
schedule_array[n + 6],
schedule_array[n + 7],
schedule_array[n + 8],
schedule_array[n + 9],
schedule_array[n + 10],
schedule_array[n + 11],
schedule_array[n + 12],
schedule_array[n + 13],
schedule_array[n + 14],
schedule_array[n + 15],
];
let state = State {
a,
b,
c,
d,
e,
f,
g,
h,
};
PrivateBlock { state, psa }
}
pub(crate) const fn execute_from_rounds(
pb: &PrivateBlock,
previous_state: State,
n: NRound,
) -> State {
let partial_state = &pb.state;
let psa = &pb.psa;
let mut rsa: SchedArray = [0u32; 64];
let mut i = 0;
while i < 16 {
rsa[i] = psa[i];
i += 1;
}
while i < 64 - n {
rsa[i] = lsigma1(rsa[i - 2])
.wrapping_add(rsa[i - 7])
.wrapping_add(lsigma0(rsa[i - 15]))
.wrapping_add(rsa[i - 16]);
i += 1;
}
let mut a = partial_state.a;
let mut b = partial_state.b;
let mut c = partial_state.c;
let mut d = partial_state.d;
let mut e = partial_state.e;
let mut f = partial_state.f;
let mut g = partial_state.g;
let mut h = partial_state.h;
let mut i = 0;
while i < 64 - n {
let t1 = h
.wrapping_add(sigma1(e))
.wrapping_add(ch(e, f, g))
.wrapping_add(SCHEDULE_SEED[i + n])
.wrapping_add(rsa[i]);
let t2 = sigma0(a).wrapping_add(maj(a, b, c));
h = g;
g = f;
f = e;
e = d.wrapping_add(t1);
d = c;
c = b;
b = a;
a = t1.wrapping_add(t2);
i += 1;
}
State {
a: a.wrapping_add(previous_state.a),
b: b.wrapping_add(previous_state.b),
c: c.wrapping_add(previous_state.c),
d: d.wrapping_add(previous_state.d),
e: e.wrapping_add(previous_state.e),
f: f.wrapping_add(previous_state.f),
g: g.wrapping_add(previous_state.g),
h: h.wrapping_add(previous_state.h),
}
}