use alloc::format;
use alloc::string::String;
use alloc::vec::Vec;
use halo2_proofs::{
pasta::EqAffine,
plonk::{self, create_proof, keygen_pk, keygen_vk, verify_proof, SingleVerifier},
poly::commitment::Params,
transcript::{Blake2bRead, Blake2bWrite, Challenge255},
};
use pasta_curves::{pallas, vesta};
use rand::rngs::OsRng;
use super::circuit::{Circuit, Instance, K};
pub fn share_reveal_params() -> Params<EqAffine> {
Params::new(K)
}
pub fn share_reveal_proving_key(
params: &Params<EqAffine>,
) -> (
plonk::ProvingKey<EqAffine>,
plonk::VerifyingKey<EqAffine>,
) {
let empty_circuit = Circuit::default();
let vk = keygen_vk(params, &empty_circuit).expect("share_reveal keygen_vk should not fail");
let pk = keygen_pk(params, vk.clone(), &empty_circuit)
.expect("share_reveal keygen_pk should not fail");
(pk, vk)
}
pub fn create_share_reveal_proof(circuit: Circuit, instance: &Instance) -> Vec<u8> {
let params = share_reveal_params();
let (pk, _vk) = share_reveal_proving_key(¶ms);
let public_inputs = instance.to_halo2_instance();
let mut transcript = Blake2bWrite::<_, EqAffine, Challenge255<_>>::init(vec![]);
create_proof(
¶ms,
&pk,
&[circuit],
&[&[&public_inputs]],
OsRng,
&mut transcript,
)
.expect("share_reveal proof generation should not fail");
transcript.finalize()
}
pub fn verify_share_reveal_proof(
proof: &[u8],
instance: &Instance,
) -> Result<(), String> {
let params = share_reveal_params();
let (_pk, vk) = share_reveal_proving_key(¶ms);
let public_inputs = instance.to_halo2_instance();
let strategy = SingleVerifier::new(¶ms);
let mut transcript = Blake2bRead::<_, EqAffine, Challenge255<_>>::init(proof);
verify_proof(¶ms, &vk, strategy, &[&[&public_inputs]], &mut transcript)
.map_err(|e| format!("share_reveal verification failed: {:?}", e))
}
pub fn verify_share_reveal_proof_raw(
proof: &[u8],
public_inputs_bytes: &[u8],
) -> Result<(), String> {
use pasta_curves::group::ff::PrimeField;
const NUM_PUBLIC_INPUTS: usize = 9;
const EXPECTED_BYTES: usize = NUM_PUBLIC_INPUTS * 32;
if public_inputs_bytes.len() != EXPECTED_BYTES {
return Err(format!(
"expected {} bytes ({} × 32) for public inputs, got {}",
EXPECTED_BYTES, NUM_PUBLIC_INPUTS, public_inputs_bytes.len()
));
}
let mut public_inputs: Vec<vesta::Scalar> = Vec::with_capacity(NUM_PUBLIC_INPUTS);
for i in 0..NUM_PUBLIC_INPUTS {
let start = i * 32;
let mut repr = [0u8; 32];
repr.copy_from_slice(&public_inputs_bytes[start..start + 32]);
let fp_opt: Option<pallas::Base> = pallas::Base::from_repr(repr).into();
match fp_opt {
Some(f) => public_inputs.push(f),
None => {
return Err(format!(
"public input {} is not a canonical Pallas Fp encoding",
i
))
}
}
}
let params = share_reveal_params();
let (_pk, vk) = share_reveal_proving_key(¶ms);
let strategy = SingleVerifier::new(¶ms);
let mut transcript = Blake2bRead::<_, EqAffine, Challenge255<_>>::init(proof);
verify_proof(
¶ms,
&vk,
strategy,
&[&[&public_inputs]],
&mut transcript,
)
.map_err(|e| format!("share_reveal verification failed: {:?}", e))
}