penis/
hashfns.rs

1use crate::consts::SCHEDULE_SEED;
2use crate::primitivefns::*;
3use crate::structs::{NRound, PartialSchedArray, PrivateBlock, RawBlockRef, SchedArray, State};
4
5pub(crate) const fn execute_until_rounds(
6    block: RawBlockRef,
7    previous_state: &State,
8    n: NRound,
9) -> PrivateBlock {
10    let mut schedule_array: SchedArray = [0; 64];
11
12    let mut i = 0;
13    while i < 16 {
14        schedule_array[i] = u32::from_be_bytes([
15            block[i * 4],
16            block[i * 4 + 1],
17            block[i * 4 + 2],
18            block[i * 4 + 3],
19        ]);
20        i += 1;
21    }
22
23    while i < n + 16 {
24        schedule_array[i] = lsigma1(schedule_array[i - 2])
25            .wrapping_add(schedule_array[i - 7])
26            .wrapping_add(lsigma0(schedule_array[i - 15]))
27            .wrapping_add(schedule_array[i - 16]);
28        i += 1;
29    }
30
31    let mut a = previous_state.a;
32    let mut b = previous_state.b;
33    let mut c = previous_state.c;
34    let mut d = previous_state.d;
35    let mut e = previous_state.e;
36    let mut f = previous_state.f;
37    let mut g = previous_state.g;
38    let mut h = previous_state.h;
39
40    let mut i = 0;
41    while i < n {
42        let t1 = h
43            .wrapping_add(sigma1(e))
44            .wrapping_add(ch(e, f, g))
45            .wrapping_add(SCHEDULE_SEED[i])
46            .wrapping_add(schedule_array[i]);
47        let t2 = sigma0(a).wrapping_add(maj(a, b, c));
48        h = g;
49        g = f;
50        f = e;
51        e = d.wrapping_add(t1);
52        d = c;
53        c = b;
54        b = a;
55        a = t1.wrapping_add(t2);
56        i += 1;
57    }
58
59    // copy the array, equivalent to
60    // psa.copy_from_slice(&schedule_array[n..(n + 16)]);
61    // but it can't be const, so we do it manually
62    // Additionally, we can avoid the mut variable
63    let psa: PartialSchedArray = [
64        schedule_array[n],
65        schedule_array[n + 1],
66        schedule_array[n + 2],
67        schedule_array[n + 3],
68        schedule_array[n + 4],
69        schedule_array[n + 5],
70        schedule_array[n + 6],
71        schedule_array[n + 7],
72        schedule_array[n + 8],
73        schedule_array[n + 9],
74        schedule_array[n + 10],
75        schedule_array[n + 11],
76        schedule_array[n + 12],
77        schedule_array[n + 13],
78        schedule_array[n + 14],
79        schedule_array[n + 15],
80    ];
81
82    let state = State {
83        a,
84        b,
85        c,
86        d,
87        e,
88        f,
89        g,
90        h,
91    };
92    PrivateBlock { state, psa }
93}
94
95pub(crate) const fn execute_from_rounds(
96    pb: &PrivateBlock,
97    previous_state: State,
98    n: NRound,
99) -> State {
100    let partial_state = &pb.state;
101    let psa = &pb.psa;
102    let mut rsa: SchedArray = [0u32; 64];
103
104    let mut i = 0;
105    while i < 16 {
106        rsa[i] = psa[i];
107        i += 1;
108    }
109    while i < 64 - n {
110        rsa[i] = lsigma1(rsa[i - 2])
111            .wrapping_add(rsa[i - 7])
112            .wrapping_add(lsigma0(rsa[i - 15]))
113            .wrapping_add(rsa[i - 16]);
114        i += 1;
115    }
116
117    let mut a = partial_state.a;
118    let mut b = partial_state.b;
119    let mut c = partial_state.c;
120    let mut d = partial_state.d;
121    let mut e = partial_state.e;
122    let mut f = partial_state.f;
123    let mut g = partial_state.g;
124    let mut h = partial_state.h;
125
126    let mut i = 0;
127    while i < 64 - n {
128        let t1 = h
129            .wrapping_add(sigma1(e))
130            .wrapping_add(ch(e, f, g))
131            .wrapping_add(SCHEDULE_SEED[i + n])
132            .wrapping_add(rsa[i]);
133        let t2 = sigma0(a).wrapping_add(maj(a, b, c));
134        h = g;
135        g = f;
136        f = e;
137        e = d.wrapping_add(t1);
138        d = c;
139        c = b;
140        b = a;
141        a = t1.wrapping_add(t2);
142        i += 1;
143    }
144
145    State {
146        a: a.wrapping_add(previous_state.a),
147        b: b.wrapping_add(previous_state.b),
148        c: c.wrapping_add(previous_state.c),
149        d: d.wrapping_add(previous_state.d),
150        e: e.wrapping_add(previous_state.e),
151        f: f.wrapping_add(previous_state.f),
152        g: g.wrapping_add(previous_state.g),
153        h: h.wrapping_add(previous_state.h),
154    }
155}