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 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}