crypto2 0.1.2

cryptographic algorithms
use super::K32;
use super::Sha256;


macro_rules! CH {
    ($x:expr, $y:expr, $z:expr) => (
        ( ($x) & ($y) ) ^ ( !($x) & ($z) )
    )
}
macro_rules! MAJ {
    ($x:expr, $y:expr, $z:expr) => (
        ( ($x) & ($y) ) ^ ( ($x) & ($z) ) ^ ( ($y) & ($z) )
    )
}
macro_rules! EP0 {
    ($v:expr) => (
        $v.rotate_right(2) ^ $v.rotate_right(13) ^ $v.rotate_right(22)
    )
}
macro_rules! EP1 {
    ($v:expr) => (
        $v.rotate_right(6) ^ $v.rotate_right(11) ^ $v.rotate_right(25)
    )
}
macro_rules! SIG0 {
    ($v:expr) => (
        $v.rotate_right(7) ^ $v.rotate_right(18) ^ ($v >> 3)
    )
}
macro_rules! SIG1 {
    ($v:expr) => (
        $v.rotate_right(17) ^ $v.rotate_right(19) ^ ($v >> 10)
    )
}


#[inline]
pub fn transform(state: &mut [u32; 8], block: &[u8]) {
    debug_assert_eq!(state.len(), 8);
    debug_assert_eq!(block.len(), Sha256::BLOCK_LEN);
    
    let mut w = [0u32; 64];
    for i in 0..16 {
        w[i] = u32::from_be_bytes([
            block[i*4 + 0], block[i*4 + 1],
            block[i*4 + 2], block[i*4 + 3],
        ]);
    }
    for t in 16..64 {
        w[t] = SIG1!(w[t - 2])
                .wrapping_add(w[t - 7])
                .wrapping_add(SIG0!(w[t - 15]))
                .wrapping_add(w[t - 16]);
    }

    let mut a = state[0];
    let mut b = state[1];
    let mut c = state[2];
    let mut d = state[3];
    let mut e = state[4];
    let mut f = state[5];
    let mut g = state[6];
    let mut h = state[7];
    
    for i in 0..64 {
        let t1 = h.wrapping_add(EP1!(e))
                .wrapping_add(CH!(e, f, g))
                .wrapping_add(K32[i])
                .wrapping_add(w[i]);
        let t2 = EP0!(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);
    }

    state[0] = state[0].wrapping_add(a);
    state[1] = state[1].wrapping_add(b);
    state[2] = state[2].wrapping_add(c);
    state[3] = state[3].wrapping_add(d);
    state[4] = state[4].wrapping_add(e);
    state[5] = state[5].wrapping_add(f);
    state[6] = state[6].wrapping_add(g);
    state[7] = state[7].wrapping_add(h);
}