use midnight_circuits::{
field::{decomposition::chip::P2RDecompositionChip, AssignedNative, NativeChip, NativeGadget},
instructions::{
AssertionInstructions, AssignmentInstructions, ConversionInstructions,
UnsafeConversionInstructions,
},
types::AssignedByte,
};
use midnight_proofs::{
circuit::{AssignedCell, Layouter},
plonk::Error,
utils::rational::Rational,
};
pub mod blake2b;
pub mod keccak_sha3;
type NG<F> = NativeGadget<F, P2RDecompositionChip<F>, NativeChip<F>>;
fn unsafe_convert_to_bytes<V, F>(
layouter: &mut impl Layouter<F>,
native_gadget: &NG<F>,
bytes: &[AssignedCell<V, F>],
) -> Result<Vec<AssignedByte<F>>, Error>
where
F: midnight_circuits::CircuitField,
V: Clone,
for<'v> Rational<F>: From<&'v V>,
{
(bytes.iter())
.map(|b| native_gadget.convert_unsafe(layouter, &b.clone().convert_to_native()))
.collect()
}
fn convert_to_bytes<V, F>(
layouter: &mut impl Layouter<F>,
native_gadget: &NG<F>,
bytes: &[AssignedCell<V, F>],
) -> Result<Vec<AssignedByte<F>>, Error>
where
F: midnight_circuits::CircuitField,
V: Clone,
for<'v> Rational<F>: From<&'v V>,
{
let bytes_as_native: &[AssignedNative<F>] =
&bytes.iter().map(|b| b.convert_to_native()).collect::<Vec<_>>();
let extracted_bytes = bytes_as_native
.iter()
.map(|b| {
b.value().map(|b| {
<NG<F> as ConversionInstructions<_, _, AssignedByte<F>>>::convert_value(
native_gadget,
b,
)
.expect("there is visibly a soundness issue in the range checks of an external implementation (found a byte overflowing 2^8).")
})
})
.collect::<Vec<_>>();
let reassigned_bytes: Vec<AssignedByte<F>> =
native_gadget.assign_many(layouter, &extracted_bytes)?;
for (x, y) in reassigned_bytes.iter().zip(bytes_as_native.iter()) {
native_gadget.assert_equal(layouter, &AssignedNative::<F>::from(x), y)?;
}
Ok(reassigned_bytes)
}