use crate::consts::K;
#[cfg(not(target_arch = "aarch64"))]
compile_error!("aarch64-sha2 backend can be used only aarch64 target arches");
#[target_feature(enable = "sha2")]
#[allow(unsafe_op_in_unsafe_fn)]
pub(crate) unsafe fn compress(state: &mut [u32; 5], blocks: &[[u8; 64]]) {
use core::arch::aarch64::*;
let mut abcd = vld1q_u32(state.as_ptr());
let mut e0 = state[4];
let [k0, k1, k2, k3] = K.map(|k| vdupq_n_u32(k));
let (mut e1, mut tmp0, mut tmp1);
for block in blocks {
let abcd_cpy = abcd;
let e0_cpy = e0;
let [mut msg0, mut msg1, mut msg2, mut msg3] = [0, 1, 2, 3].map(|i| {
let p = block.as_ptr().add(16 * i);
vreinterpretq_u32_u8(vrev32q_u8(vld1q_u8(p)))
});
tmp0 = vaddq_u32(msg0, k0);
tmp1 = vaddq_u32(msg1, k0);
e1 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1cq_u32(abcd, e0, tmp0);
tmp0 = vaddq_u32(msg2, k0);
msg0 = vsha1su0q_u32(msg0, msg1, msg2);
e0 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1cq_u32(abcd, e1, tmp1);
tmp1 = vaddq_u32(msg3, k0);
msg0 = vsha1su1q_u32(msg0, msg3);
msg1 = vsha1su0q_u32(msg1, msg2, msg3);
e1 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1cq_u32(abcd, e0, tmp0);
tmp0 = vaddq_u32(msg0, k0);
msg1 = vsha1su1q_u32(msg1, msg0);
msg2 = vsha1su0q_u32(msg2, msg3, msg0);
e0 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1cq_u32(abcd, e1, tmp1);
tmp1 = vaddq_u32(msg1, k1);
msg2 = vsha1su1q_u32(msg2, msg1);
msg3 = vsha1su0q_u32(msg3, msg0, msg1);
e1 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1cq_u32(abcd, e0, tmp0);
tmp0 = vaddq_u32(msg2, k1);
msg3 = vsha1su1q_u32(msg3, msg2);
msg0 = vsha1su0q_u32(msg0, msg1, msg2);
e0 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1pq_u32(abcd, e1, tmp1);
tmp1 = vaddq_u32(msg3, k1);
msg0 = vsha1su1q_u32(msg0, msg3);
msg1 = vsha1su0q_u32(msg1, msg2, msg3);
e1 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1pq_u32(abcd, e0, tmp0);
tmp0 = vaddq_u32(msg0, k1);
msg1 = vsha1su1q_u32(msg1, msg0);
msg2 = vsha1su0q_u32(msg2, msg3, msg0);
e0 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1pq_u32(abcd, e1, tmp1);
tmp1 = vaddq_u32(msg1, k1);
msg2 = vsha1su1q_u32(msg2, msg1);
msg3 = vsha1su0q_u32(msg3, msg0, msg1);
e1 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1pq_u32(abcd, e0, tmp0);
tmp0 = vaddq_u32(msg2, k2);
msg3 = vsha1su1q_u32(msg3, msg2);
msg0 = vsha1su0q_u32(msg0, msg1, msg2);
e0 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1pq_u32(abcd, e1, tmp1);
tmp1 = vaddq_u32(msg3, k2);
msg0 = vsha1su1q_u32(msg0, msg3);
msg1 = vsha1su0q_u32(msg1, msg2, msg3);
e1 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1mq_u32(abcd, e0, tmp0);
tmp0 = vaddq_u32(msg0, k2);
msg1 = vsha1su1q_u32(msg1, msg0);
msg2 = vsha1su0q_u32(msg2, msg3, msg0);
e0 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1mq_u32(abcd, e1, tmp1);
tmp1 = vaddq_u32(msg1, k2);
msg2 = vsha1su1q_u32(msg2, msg1);
msg3 = vsha1su0q_u32(msg3, msg0, msg1);
e1 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1mq_u32(abcd, e0, tmp0);
tmp0 = vaddq_u32(msg2, k2);
msg3 = vsha1su1q_u32(msg3, msg2);
msg0 = vsha1su0q_u32(msg0, msg1, msg2);
e0 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1mq_u32(abcd, e1, tmp1);
tmp1 = vaddq_u32(msg3, k3);
msg0 = vsha1su1q_u32(msg0, msg3);
msg1 = vsha1su0q_u32(msg1, msg2, msg3);
e1 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1mq_u32(abcd, e0, tmp0);
tmp0 = vaddq_u32(msg0, k3);
msg1 = vsha1su1q_u32(msg1, msg0);
msg2 = vsha1su0q_u32(msg2, msg3, msg0);
e0 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1pq_u32(abcd, e1, tmp1);
tmp1 = vaddq_u32(msg1, k3);
msg2 = vsha1su1q_u32(msg2, msg1);
msg3 = vsha1su0q_u32(msg3, msg0, msg1);
e1 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1pq_u32(abcd, e0, tmp0);
tmp0 = vaddq_u32(msg2, k3);
msg3 = vsha1su1q_u32(msg3, msg2);
e0 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1pq_u32(abcd, e1, tmp1);
tmp1 = vaddq_u32(msg3, k3);
e1 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1pq_u32(abcd, e0, tmp0);
e0 = vsha1h_u32(vgetq_lane_u32(abcd, 0));
abcd = vsha1pq_u32(abcd, e1, tmp1);
abcd = vaddq_u32(abcd_cpy, abcd);
e0 = e0.wrapping_add(e0_cpy);
}
vst1q_u32(state.as_mut_ptr(), abcd);
state[4] = e0;
}