#[cfg(feature = "heap_profiling")]
#[global_allocator]
static ALLOC: dhat::Alloc = dhat::Alloc;
use midnight_circuits::{
instructions::{AssignmentInstructions, PublicInputInstructions},
types::{AssignedByte, Instantiable},
};
use midnight_proofs::{
circuit::{Layouter, Value},
plonk::Error,
};
use midnight_zk_stdlib::{utils::plonk_api::filecoin_srs, Relation, ZkStdLib, ZkStdLibArch};
use rand::{rngs::OsRng, Rng, SeedableRng};
use rand_chacha::ChaCha8Rng;
use sha2::Digest;
type F = midnight_curves::Fq;
#[derive(Clone, Default)]
pub struct ShaPreImageCircuit;
impl Relation for ShaPreImageCircuit {
type Instance = [u8; 32];
type Witness = [u8; 24];
type Error = Error;
fn format_instance(instance: &Self::Instance) -> Result<Vec<F>, Error> {
Ok(instance.iter().flat_map(AssignedByte::<F>::as_public_input).collect())
}
fn circuit(
&self,
std_lib: &ZkStdLib,
layouter: &mut impl Layouter<F>,
_instance: Value<Self::Instance>,
witness: Value<Self::Witness>,
) -> Result<(), Error> {
let witness_bytes = witness.transpose_array();
let assigned_input = std_lib.assign_many(layouter, &witness_bytes)?;
let output = std_lib.sha2_256(layouter, &assigned_input)?;
output.iter().try_for_each(|b| std_lib.constrain_as_public_input(layouter, b))
}
fn used_chips(&self) -> ZkStdLibArch {
ZkStdLibArch {
sha2_256: true,
..ZkStdLibArch::default()
}
}
fn write_relation<W: std::io::Write>(&self, _writer: &mut W) -> std::io::Result<()> {
Ok(())
}
fn read_relation<R: std::io::Read>(_reader: &mut R) -> std::io::Result<Self> {
Ok(ShaPreImageCircuit)
}
}
fn main() {
const K: u32 = 13;
let srs = filecoin_srs(K);
let relation = ShaPreImageCircuit;
let vk = midnight_zk_stdlib::setup_vk(&srs, &relation);
let pk = midnight_zk_stdlib::setup_pk(&relation, &vk);
let mut rng = ChaCha8Rng::from_entropy();
let witness: [u8; 24] = core::array::from_fn(|_| rng.gen());
let instance = sha2::Sha256::digest(witness).into();
let proof = midnight_zk_stdlib::prove::<ShaPreImageCircuit, blake2b_simd::State>(
&srs, &pk, &relation, &instance, witness, OsRng,
)
.expect("Proof generation should not fail");
assert!(
midnight_zk_stdlib::verify::<ShaPreImageCircuit, blake2b_simd::State>(
&srs.verifier_params(),
&vk,
&instance,
None,
&proof
)
.is_ok()
)
}