1#![no_std]
10#![allow(clippy::assign_op_pattern)]
13
14use xark::{Field, require_eq};
15
16pub fn and32(a: [Field; 32], b: [Field; 32]) -> [Field; 32] {
22 let mut out = [Field::from(0u8); 32];
23 let mut i = 0usize;
24 while i < 32 {
25 out[i] = a[i].and(b[i]);
26 i += 1;
27 }
28 out
29}
30
31pub fn xor32(a: [Field; 32], b: [Field; 32]) -> [Field; 32] {
32 let mut out = [Field::from(0u8); 32];
33 let mut i = 0usize;
34 while i < 32 {
35 out[i] = a[i].xor(b[i]);
36 i += 1;
37 }
38 out
39}
40
41pub fn or32(a: [Field; 32], b: [Field; 32]) -> [Field; 32] {
42 let mut out = [Field::from(0u8); 32];
43 let mut i = 0usize;
44 while i < 32 {
45 out[i] = a[i].or(b[i]);
46 i += 1;
47 }
48 out
49}
50
51pub fn not32(a: [Field; 32]) -> [Field; 32] {
52 let mut out = [Field::from(0u8); 32];
53 let mut i = 0usize;
54 while i < 32 {
55 out[i] = a[i].not();
56 i += 1;
57 }
58 out
59}
60
61pub fn rotr32(a: [Field; 32], n: usize) -> [Field; 32] {
63 let mut out = [Field::from(0u8); 32];
64 let mut i = 0usize;
65 while i < 32 {
66 out[i] = a[(i + n) % 32];
67 i += 1;
68 }
69 out
70}
71
72pub fn shr32(a: [Field; 32], n: usize) -> [Field; 32] {
75 let mut out = [Field::from(0u8); 32];
76 let mut i = 0usize;
77 while i < 32 {
78 if i + n < 32 {
79 out[i] = a[i + n];
80 }
81 i += 1;
82 }
83 out
84}
85
86pub fn add32(a: [Field; 32], b: [Field; 32]) -> [Field; 32] {
92 let sum = Field::from_bits::<32>(a) + Field::from_bits::<32>(b);
93
94 let mut bits = [Field::from(0u8); 33];
96 let mut i = 0usize;
97 while i < 33 {
98 bits[i] = Field::hint_bit(sum, i);
99 i += 1;
100 }
101 let mut i = 0usize;
102 while i < 33 {
103 bits[i].require_bool();
104 i += 1;
105 }
106 let mut acc = Field::from(0u8);
107 let mut pow = Field::from(1u8);
108 let mut i = 0usize;
109 while i < 33 {
110 acc = acc + bits[i] * pow;
111 pow = pow + pow;
112 i += 1;
113 }
114 require_eq(acc, sum);
115
116 let mut out = [Field::from(0u8); 32];
118 let mut i = 0usize;
119 while i < 32 {
120 out[i] = bits[i];
121 i += 1;
122 }
123 out
124}
125
126pub fn add3(a: [Field; 32], b: [Field; 32], c: [Field; 32]) -> [Field; 32] {
136 let sum = Field::from_bits::<32>(a) + Field::from_bits::<32>(b) + Field::from_bits::<32>(c);
137
138 let mut bits = [Field::from(0u8); 34];
140 let mut i = 0usize;
141 while i < 34 {
142 bits[i] = Field::hint_bit(sum, i);
143 i += 1;
144 }
145 let mut i = 0usize;
146 while i < 34 {
147 bits[i].require_bool();
148 i += 1;
149 }
150 let mut acc = Field::from(0u8);
151 let mut pow = Field::from(1u8);
152 let mut i = 0usize;
153 while i < 34 {
154 acc = acc + bits[i] * pow;
155 pow = pow + pow;
156 i += 1;
157 }
158 require_eq(acc, sum);
159
160 let mut out = [Field::from(0u8); 32];
162 let mut i = 0usize;
163 while i < 32 {
164 out[i] = bits[i];
165 i += 1;
166 }
167 out
168}
169
170pub fn to_bits64(x: Field) -> [Field; 64] {
175 let mut bits = [Field::from(0u8); 64];
176 let mut i = 0usize;
177 while i < 64 {
178 bits[i] = Field::hint_bit(x, i);
179 i += 1;
180 }
181 let mut i = 0usize;
182 while i < 64 {
183 bits[i].require_bool();
184 i += 1;
185 }
186 let mut acc = Field::from(0u8);
187 let mut pow = Field::from(1u8);
188 let mut i = 0usize;
189 while i < 64 {
190 acc = acc + bits[i] * pow;
191 pow = pow + pow;
192 i += 1;
193 }
194 require_eq(acc, x);
195 bits
196}
197
198pub fn from_bits64(bits: [Field; 64]) -> Field {
200 let mut acc = Field::from(0u8);
201 let mut pow = Field::from(1u8);
202 let mut i = 0usize;
203 while i < 64 {
204 acc = acc + bits[i] * pow;
205 pow = pow + pow;
206 i += 1;
207 }
208 acc
209}
210
211pub fn and64(a: [Field; 64], b: [Field; 64]) -> [Field; 64] {
212 let mut out = [Field::from(0u8); 64];
213 let mut i = 0usize;
214 while i < 64 {
215 out[i] = a[i].and(b[i]);
216 i += 1;
217 }
218 out
219}
220
221pub fn xor64(a: [Field; 64], b: [Field; 64]) -> [Field; 64] {
222 let mut out = [Field::from(0u8); 64];
223 let mut i = 0usize;
224 while i < 64 {
225 out[i] = a[i].xor(b[i]);
226 i += 1;
227 }
228 out
229}
230
231pub fn not64(a: [Field; 64]) -> [Field; 64] {
232 let mut out = [Field::from(0u8); 64];
233 let mut i = 0usize;
234 while i < 64 {
235 out[i] = a[i].not();
236 i += 1;
237 }
238 out
239}
240
241pub fn rotl64(a: [Field; 64], n: usize) -> [Field; 64] {
244 let m = n % 64;
245 let mut out = [Field::from(0u8); 64];
246 let mut i = 0usize;
247 while i < 64 {
248 out[i] = a[(i + 64 - m) % 64];
249 i += 1;
250 }
251 out
252}
253
254pub fn rotr64(a: [Field; 64], n: usize) -> [Field; 64] {
256 let mut out = [Field::from(0u8); 64];
257 let mut i = 0usize;
258 while i < 64 {
259 out[i] = a[(i + n) % 64];
260 i += 1;
261 }
262 out
263}
264
265pub fn read_n<const N: usize>(arr: [[Field; 32]; N], t: usize) -> [Field; 32] {
270 let mut out = [Field::from(0u8); 32];
271 let mut j = 0usize;
272 while j < 32usize {
273 out[j] = arr[t][j];
274 j += 1;
275 }
276 out
277}
278
279pub fn sha256_iv() -> [Field; 8] {
282 [
283 Field::from(1779033703u32), Field::from(3144134277u32), Field::from(1013904242u32), Field::from(2773480762u32), Field::from(1359893119u32), Field::from(2600822924u32), Field::from(528734635u32), Field::from(1541459225u32), ]
292}