| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- /* This file is part of DarkFi (https://dark.fi)
- *
- * Copyright (C) 2020-2025 Dyne.org foundation
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- use std::{io, io::Cursor};
- #[cfg(feature = "async-serial")]
- use darkfi_serial::async_trait;
- use darkfi_sdk::pasta::{pallas, vesta};
- use darkfi_serial::{SerialDecodable, SerialEncodable};
- use halo2_proofs::{
- helpers::SerdeFormat,
- plonk,
- plonk::{Circuit, SingleVerifier},
- poly::commitment::Params,
- transcript::{Blake2bRead, Blake2bWrite},
- };
- use rand::RngCore;
- #[derive(Clone, Debug)]
- pub struct VerifyingKey {
- pub params: Params<vesta::Affine>,
- pub vk: plonk::VerifyingKey<vesta::Affine>,
- }
- impl VerifyingKey {
- pub fn build(k: u32, c: &impl Circuit<pallas::Base>) -> Self {
- let params = Params::new(k);
- let vk = plonk::keygen_vk(¶ms, c).unwrap();
- VerifyingKey { params, vk }
- }
- pub fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
- let mut params = vec![];
- self.params.write(&mut params)?;
- let mut vk = vec![];
- self.vk.write(&mut vk, SerdeFormat::RawBytes)?;
- let _ = writer.write(&(params.len() as u32).to_le_bytes())?;
- let _ = writer.write(¶ms)?;
- let _ = writer.write(&(vk.len() as u32).to_le_bytes())?;
- let _ = writer.write(&vk)?;
- Ok(())
- }
- pub fn read<R: io::Read, ConcreteCircuit: Circuit<pallas::Base>>(
- reader: &mut R,
- circuit: ConcreteCircuit,
- ) -> io::Result<Self> {
- // The format chosen in write():
- // [params.len()<u32>, params..., vk.len()<u32>, vk...]
- let mut params_len = [0u8; 4];
- reader.read_exact(&mut params_len)?;
- let params_len = u32::from_le_bytes(params_len) as usize;
- let mut params_buf = vec![0u8; params_len];
- reader.read_exact(&mut params_buf)?;
- assert!(params_buf.len() == params_len);
- let mut vk_len = [0u8; 4];
- reader.read_exact(&mut vk_len)?;
- let vk_len = u32::from_le_bytes(vk_len) as usize;
- let mut vk_buf = vec![0u8; vk_len];
- reader.read_exact(&mut vk_buf)?;
- assert!(vk_buf.len() == vk_len);
- let mut params_c = Cursor::new(params_buf);
- let params: Params<vesta::Affine> = Params::read(&mut params_c)?;
- let mut vk_c = Cursor::new(vk_buf);
- let vk: plonk::VerifyingKey<vesta::Affine> =
- plonk::VerifyingKey::read::<Cursor<Vec<u8>>, ConcreteCircuit>(
- &mut vk_c,
- SerdeFormat::RawBytes,
- circuit.params(),
- )?;
- Ok(Self { params, vk })
- }
- }
- #[derive(Clone, Debug)]
- pub struct ProvingKey {
- pub params: Params<vesta::Affine>,
- pub pk: plonk::ProvingKey<vesta::Affine>,
- }
- impl ProvingKey {
- pub fn build(k: u32, c: &impl Circuit<pallas::Base>) -> Self {
- let params = Params::new(k);
- let vk = plonk::keygen_vk(¶ms, c).unwrap();
- let pk = plonk::keygen_pk(¶ms, vk, c).unwrap();
- ProvingKey { params, pk }
- }
- pub fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
- let mut params = vec![];
- self.params.write(&mut params)?;
- let mut pk = vec![];
- self.pk.write(&mut pk, SerdeFormat::RawBytes)?;
- let _ = writer.write(&(params.len() as u32).to_le_bytes())?;
- let _ = writer.write(¶ms)?;
- let _ = writer.write(&(pk.len() as u32).to_le_bytes())?;
- let _ = writer.write(&pk)?;
- Ok(())
- }
- pub fn read<R: io::Read, ConcreteCircuit: Circuit<pallas::Base>>(
- reader: &mut R,
- circuit: ConcreteCircuit,
- ) -> io::Result<Self> {
- let mut params_len = [0u8; 4];
- reader.read_exact(&mut params_len)?;
- let params_len = u32::from_le_bytes(params_len) as usize;
- let mut params_buf = vec![0u8; params_len];
- reader.read_exact(&mut params_buf)?;
- assert!(params_buf.len() == params_len);
- let mut pk_len = [0u8; 4];
- reader.read_exact(&mut pk_len)?;
- let pk_len = u32::from_le_bytes(pk_len) as usize;
- let mut pk_buf = vec![0u8; pk_len];
- reader.read_exact(&mut pk_buf)?;
- assert!(pk_buf.len() == pk_len);
- let mut params_c = Cursor::new(params_buf);
- let params: Params<vesta::Affine> = Params::read(&mut params_c)?;
- let mut pk_c = Cursor::new(pk_buf);
- let pk: plonk::ProvingKey<vesta::Affine> =
- plonk::ProvingKey::read::<Cursor<Vec<u8>>, ConcreteCircuit>(
- &mut pk_c,
- SerdeFormat::RawBytes,
- circuit.params(),
- )?;
- Ok(Self { params, pk })
- }
- }
- #[derive(Clone, Default, PartialEq, Eq, SerialEncodable, SerialDecodable)]
- pub struct Proof(Vec<u8>);
- impl AsRef<[u8]> for Proof {
- fn as_ref(&self) -> &[u8] {
- &self.0
- }
- }
- impl core::fmt::Debug for Proof {
- fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
- write!(f, "Proof({:?})", self.0)
- }
- }
- impl Proof {
- pub fn create(
- pk: &ProvingKey,
- circuits: &[impl Circuit<pallas::Base>],
- instances: &[pallas::Base],
- mut rng: impl RngCore,
- ) -> std::result::Result<Self, plonk::Error> {
- let mut transcript = Blake2bWrite::<_, vesta::Affine, _>::init(vec![]);
- plonk::create_proof(
- &pk.params,
- &pk.pk,
- circuits,
- &[&[instances]],
- &mut rng,
- &mut transcript,
- )?;
- Ok(Proof(transcript.finalize()))
- }
- pub fn verify(
- &self,
- vk: &VerifyingKey,
- instances: &[pallas::Base],
- ) -> std::result::Result<(), plonk::Error> {
- let strategy = SingleVerifier::new(&vk.params);
- let mut transcript = Blake2bRead::init(&self.0[..]);
- plonk::verify_proof(&vk.params, &vk.vk, strategy, &[&[instances]], &mut transcript)
- }
- pub fn new(bytes: Vec<u8>) -> Self {
- Proof(bytes)
- }
- }
|