#![no_std]
#![allow(clippy::assign_op_pattern)]
use xark::{Field, require_eq};
pub fn and32(a: [Field; 32], b: [Field; 32]) -> [Field; 32] {
let mut out = [Field::from(0u8); 32];
let mut i = 0usize;
while i < 32 {
out[i] = a[i].and(b[i]);
i += 1;
}
out
}
pub fn xor32(a: [Field; 32], b: [Field; 32]) -> [Field; 32] {
let mut out = [Field::from(0u8); 32];
let mut i = 0usize;
while i < 32 {
out[i] = a[i].xor(b[i]);
i += 1;
}
out
}
pub fn or32(a: [Field; 32], b: [Field; 32]) -> [Field; 32] {
let mut out = [Field::from(0u8); 32];
let mut i = 0usize;
while i < 32 {
out[i] = a[i].or(b[i]);
i += 1;
}
out
}
pub fn not32(a: [Field; 32]) -> [Field; 32] {
let mut out = [Field::from(0u8); 32];
let mut i = 0usize;
while i < 32 {
out[i] = a[i].not();
i += 1;
}
out
}
pub fn rotr32(a: [Field; 32], n: usize) -> [Field; 32] {
let mut out = [Field::from(0u8); 32];
let mut i = 0usize;
while i < 32 {
out[i] = a[(i + n) % 32];
i += 1;
}
out
}
pub fn shr32(a: [Field; 32], n: usize) -> [Field; 32] {
let mut out = [Field::from(0u8); 32];
let mut i = 0usize;
while i < 32 {
if i + n < 32 {
out[i] = a[i + n];
}
i += 1;
}
out
}
pub fn add32(a: [Field; 32], b: [Field; 32]) -> [Field; 32] {
let sum = Field::from_bits::<32>(a) + Field::from_bits::<32>(b);
let mut bits = [Field::from(0u8); 33];
let mut i = 0usize;
while i < 33 {
bits[i] = Field::hint_bit(sum, i);
i += 1;
}
let mut i = 0usize;
while i < 33 {
bits[i].require_bool();
i += 1;
}
let mut acc = Field::from(0u8);
let mut pow = Field::from(1u8);
let mut i = 0usize;
while i < 33 {
acc = acc + bits[i] * pow;
pow = pow + pow;
i += 1;
}
require_eq(acc, sum);
let mut out = [Field::from(0u8); 32];
let mut i = 0usize;
while i < 32 {
out[i] = bits[i];
i += 1;
}
out
}
pub fn add3(a: [Field; 32], b: [Field; 32], c: [Field; 32]) -> [Field; 32] {
let sum = Field::from_bits::<32>(a) + Field::from_bits::<32>(b) + Field::from_bits::<32>(c);
let mut bits = [Field::from(0u8); 34];
let mut i = 0usize;
while i < 34 {
bits[i] = Field::hint_bit(sum, i);
i += 1;
}
let mut i = 0usize;
while i < 34 {
bits[i].require_bool();
i += 1;
}
let mut acc = Field::from(0u8);
let mut pow = Field::from(1u8);
let mut i = 0usize;
while i < 34 {
acc = acc + bits[i] * pow;
pow = pow + pow;
i += 1;
}
require_eq(acc, sum);
let mut out = [Field::from(0u8); 32];
let mut i = 0usize;
while i < 32 {
out[i] = bits[i];
i += 1;
}
out
}
pub fn to_bits64(x: Field) -> [Field; 64] {
let mut bits = [Field::from(0u8); 64];
let mut i = 0usize;
while i < 64 {
bits[i] = Field::hint_bit(x, i);
i += 1;
}
let mut i = 0usize;
while i < 64 {
bits[i].require_bool();
i += 1;
}
let mut acc = Field::from(0u8);
let mut pow = Field::from(1u8);
let mut i = 0usize;
while i < 64 {
acc = acc + bits[i] * pow;
pow = pow + pow;
i += 1;
}
require_eq(acc, x);
bits
}
pub fn from_bits64(bits: [Field; 64]) -> Field {
let mut acc = Field::from(0u8);
let mut pow = Field::from(1u8);
let mut i = 0usize;
while i < 64 {
acc = acc + bits[i] * pow;
pow = pow + pow;
i += 1;
}
acc
}
pub fn and64(a: [Field; 64], b: [Field; 64]) -> [Field; 64] {
let mut out = [Field::from(0u8); 64];
let mut i = 0usize;
while i < 64 {
out[i] = a[i].and(b[i]);
i += 1;
}
out
}
pub fn xor64(a: [Field; 64], b: [Field; 64]) -> [Field; 64] {
let mut out = [Field::from(0u8); 64];
let mut i = 0usize;
while i < 64 {
out[i] = a[i].xor(b[i]);
i += 1;
}
out
}
pub fn not64(a: [Field; 64]) -> [Field; 64] {
let mut out = [Field::from(0u8); 64];
let mut i = 0usize;
while i < 64 {
out[i] = a[i].not();
i += 1;
}
out
}
pub fn rotl64(a: [Field; 64], n: usize) -> [Field; 64] {
let m = n % 64;
let mut out = [Field::from(0u8); 64];
let mut i = 0usize;
while i < 64 {
out[i] = a[(i + 64 - m) % 64];
i += 1;
}
out
}
pub fn rotr64(a: [Field; 64], n: usize) -> [Field; 64] {
let mut out = [Field::from(0u8); 64];
let mut i = 0usize;
while i < 64 {
out[i] = a[(i + n) % 64];
i += 1;
}
out
}
pub fn read_n<const N: usize>(arr: [[Field; 32]; N], t: usize) -> [Field; 32] {
let mut out = [Field::from(0u8); 32];
let mut j = 0usize;
while j < 32usize {
out[j] = arr[t][j];
j += 1;
}
out
}
pub fn sha256_iv() -> [Field; 8] {
[
Field::from(1779033703u32), Field::from(3144134277u32), Field::from(1013904242u32), Field::from(2773480762u32), Field::from(1359893119u32), Field::from(2600822924u32), Field::from(528734635u32), Field::from(1541459225u32), ]
}