mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-09 09:13:09 +00:00
Merge pull request #1111 from topos-protocol/lookup_serial
Lookup serialization
This commit is contained in:
commit
bfa7ab369e
@ -837,6 +837,7 @@ where
|
|||||||
buffer.write_prover_only_circuit_data(
|
buffer.write_prover_only_circuit_data(
|
||||||
&wrapper.circuit.prover_only,
|
&wrapper.circuit.prover_only,
|
||||||
generator_serializer,
|
generator_serializer,
|
||||||
|
&wrapper.circuit.common,
|
||||||
)?;
|
)?;
|
||||||
buffer.write_verifier_only_circuit_data(&wrapper.circuit.verifier_only)?;
|
buffer.write_verifier_only_circuit_data(&wrapper.circuit.verifier_only)?;
|
||||||
buffer.write_target_proof_with_public_inputs(&wrapper.proof_with_pis_target)?;
|
buffer.write_target_proof_with_public_inputs(&wrapper.proof_with_pis_target)?;
|
||||||
|
|||||||
@ -248,18 +248,18 @@ where
|
|||||||
fn test_serialization<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>(
|
fn test_serialization<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>(
|
||||||
proof: &ProofWithPublicInputs<F, C, D>,
|
proof: &ProofWithPublicInputs<F, C, D>,
|
||||||
vd: &VerifierOnlyCircuitData<C, D>,
|
vd: &VerifierOnlyCircuitData<C, D>,
|
||||||
cd: &CommonCircuitData<F, D>,
|
common_data: &CommonCircuitData<F, D>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let proof_bytes = proof.to_bytes();
|
let proof_bytes = proof.to_bytes();
|
||||||
info!("Proof length: {} bytes", proof_bytes.len());
|
info!("Proof length: {} bytes", proof_bytes.len());
|
||||||
let proof_from_bytes = ProofWithPublicInputs::from_bytes(proof_bytes, cd)?;
|
let proof_from_bytes = ProofWithPublicInputs::from_bytes(proof_bytes, common_data)?;
|
||||||
assert_eq!(proof, &proof_from_bytes);
|
assert_eq!(proof, &proof_from_bytes);
|
||||||
|
|
||||||
let now = std::time::Instant::now();
|
let now = std::time::Instant::now();
|
||||||
let compressed_proof = proof.clone().compress(&vd.circuit_digest, cd)?;
|
let compressed_proof = proof.clone().compress(&vd.circuit_digest, common_data)?;
|
||||||
let decompressed_compressed_proof = compressed_proof
|
let decompressed_compressed_proof = compressed_proof
|
||||||
.clone()
|
.clone()
|
||||||
.decompress(&vd.circuit_digest, cd)?;
|
.decompress(&vd.circuit_digest, common_data)?;
|
||||||
info!("{:.4}s to compress proof", now.elapsed().as_secs_f64());
|
info!("{:.4}s to compress proof", now.elapsed().as_secs_f64());
|
||||||
assert_eq!(proof, &decompressed_compressed_proof);
|
assert_eq!(proof, &decompressed_compressed_proof);
|
||||||
|
|
||||||
@ -269,11 +269,11 @@ fn test_serialization<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>,
|
|||||||
compressed_proof_bytes.len()
|
compressed_proof_bytes.len()
|
||||||
);
|
);
|
||||||
let compressed_proof_from_bytes =
|
let compressed_proof_from_bytes =
|
||||||
CompressedProofWithPublicInputs::from_bytes(compressed_proof_bytes, cd)?;
|
CompressedProofWithPublicInputs::from_bytes(compressed_proof_bytes, common_data)?;
|
||||||
assert_eq!(compressed_proof, compressed_proof_from_bytes);
|
assert_eq!(compressed_proof, compressed_proof_from_bytes);
|
||||||
|
|
||||||
let gate_serializer = DefaultGateSerializer;
|
let gate_serializer = DefaultGateSerializer;
|
||||||
let common_data_bytes = cd
|
let common_data_bytes = common_data
|
||||||
.to_bytes(&gate_serializer)
|
.to_bytes(&gate_serializer)
|
||||||
.map_err(|_| anyhow::Error::msg("CommonCircuitData serialization failed."))?;
|
.map_err(|_| anyhow::Error::msg("CommonCircuitData serialization failed."))?;
|
||||||
info!(
|
info!(
|
||||||
@ -283,7 +283,7 @@ fn test_serialization<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>,
|
|||||||
let common_data_from_bytes =
|
let common_data_from_bytes =
|
||||||
CommonCircuitData::<F, D>::from_bytes(common_data_bytes, &gate_serializer)
|
CommonCircuitData::<F, D>::from_bytes(common_data_bytes, &gate_serializer)
|
||||||
.map_err(|_| anyhow::Error::msg("CommonCircuitData deserialization failed."))?;
|
.map_err(|_| anyhow::Error::msg("CommonCircuitData deserialization failed."))?;
|
||||||
assert_eq!(cd, &common_data_from_bytes);
|
assert_eq!(common_data, &common_data_from_bytes);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -312,35 +312,35 @@ pub fn benchmark_function(
|
|||||||
};
|
};
|
||||||
// Start with a dummy proof of specified size
|
// Start with a dummy proof of specified size
|
||||||
let inner = dummy_proof_function(config, log2_inner_size)?;
|
let inner = dummy_proof_function(config, log2_inner_size)?;
|
||||||
let (_, _, cd) = &inner;
|
let (_, _, common_data) = &inner;
|
||||||
info!(
|
info!(
|
||||||
"Initial {} degree {} = 2^{}",
|
"Initial {} degree {} = 2^{}",
|
||||||
name,
|
name,
|
||||||
cd.degree(),
|
common_data.degree(),
|
||||||
cd.degree_bits()
|
common_data.degree_bits()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Recursively verify the proof
|
// Recursively verify the proof
|
||||||
let middle = recursive_proof::<F, C, C, D>(&inner, config, None)?;
|
let middle = recursive_proof::<F, C, C, D>(&inner, config, None)?;
|
||||||
let (_, _, cd) = &middle;
|
let (_, _, common_data) = &middle;
|
||||||
info!(
|
info!(
|
||||||
"Single recursion {} degree {} = 2^{}",
|
"Single recursion {} degree {} = 2^{}",
|
||||||
name,
|
name,
|
||||||
cd.degree(),
|
common_data.degree(),
|
||||||
cd.degree_bits()
|
common_data.degree_bits()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Add a second layer of recursion to shrink the proof size further
|
// Add a second layer of recursion to shrink the proof size further
|
||||||
let outer = recursive_proof::<F, C, C, D>(&middle, config, None)?;
|
let outer = recursive_proof::<F, C, C, D>(&middle, config, None)?;
|
||||||
let (proof, vd, cd) = &outer;
|
let (proof, vd, common_data) = &outer;
|
||||||
info!(
|
info!(
|
||||||
"Double recursion {} degree {} = 2^{}",
|
"Double recursion {} degree {} = 2^{}",
|
||||||
name,
|
name,
|
||||||
cd.degree(),
|
common_data.degree(),
|
||||||
cd.degree_bits()
|
common_data.degree_bits()
|
||||||
);
|
);
|
||||||
|
|
||||||
test_serialization(proof, vd, cd)?;
|
test_serialization(proof, vd, common_data)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ use plonky2::iop::generator::{
|
|||||||
use plonky2::iop::target::Target;
|
use plonky2::iop::target::Target;
|
||||||
use plonky2::iop::witness::{PartialWitness, PartitionWitness, Witness, WitnessWrite};
|
use plonky2::iop::witness::{PartialWitness, PartitionWitness, Witness, WitnessWrite};
|
||||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||||
use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData};
|
use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData, CommonCircuitData};
|
||||||
use plonky2::plonk::config::{AlgebraicHasher, GenericConfig, PoseidonGoldilocksConfig};
|
use plonky2::plonk::config::{AlgebraicHasher, GenericConfig, PoseidonGoldilocksConfig};
|
||||||
use plonky2::recursion::dummy_circuit::DummyProofGenerator;
|
use plonky2::recursion::dummy_circuit::DummyProofGenerator;
|
||||||
use plonky2::util::serialization::{
|
use plonky2::util::serialization::{
|
||||||
@ -32,7 +32,7 @@ struct SquareRootGenerator<F: RichField + Extendable<D>, const D: usize> {
|
|||||||
_phantom: PhantomData<F>,
|
_phantom: PhantomData<F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
|
||||||
for SquareRootGenerator<F, D>
|
for SquareRootGenerator<F, D>
|
||||||
{
|
{
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
@ -52,12 +52,12 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
|||||||
out_buffer.set_target(self.x, x);
|
out_buffer.set_target(self.x, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_target(self.x)?;
|
dst.write_target(self.x)?;
|
||||||
dst.write_target(self.x_squared)
|
dst.write_target(self.x_squared)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let x = src.read_target()?;
|
let x = src.read_target()?;
|
||||||
let x_squared = src.read_target()?;
|
let x_squared = src.read_target()?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
|||||||
@ -11,6 +11,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator};
|
|||||||
use crate::iop::target::{BoolTarget, Target};
|
use crate::iop::target::{BoolTarget, Target};
|
||||||
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
|
use crate::plonk::circuit_data::CommonCircuitData;
|
||||||
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
||||||
|
|
||||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||||
@ -379,7 +380,7 @@ pub struct EqualityGenerator {
|
|||||||
inv: Target,
|
inv: Target,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField> SimpleGenerator<F> for EqualityGenerator {
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for EqualityGenerator {
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
"EqualityGenerator".to_string()
|
"EqualityGenerator".to_string()
|
||||||
}
|
}
|
||||||
@ -398,14 +399,14 @@ impl<F: RichField> SimpleGenerator<F> for EqualityGenerator {
|
|||||||
out_buffer.set_target(self.inv, inv);
|
out_buffer.set_target(self.inv, inv);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_target(self.x)?;
|
dst.write_target(self.x)?;
|
||||||
dst.write_target(self.y)?;
|
dst.write_target(self.y)?;
|
||||||
dst.write_target_bool(self.equal)?;
|
dst.write_target_bool(self.equal)?;
|
||||||
dst.write_target(self.inv)
|
dst.write_target(self.inv)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let x = src.read_target()?;
|
let x = src.read_target()?;
|
||||||
let y = src.read_target()?;
|
let y = src.read_target()?;
|
||||||
let equal = src.read_target_bool()?;
|
let equal = src.read_target_bool()?;
|
||||||
|
|||||||
@ -12,6 +12,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator};
|
|||||||
use crate::iop::target::Target;
|
use crate::iop::target::Target;
|
||||||
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
|
use crate::plonk::circuit_data::CommonCircuitData;
|
||||||
use crate::util::bits_u64;
|
use crate::util::bits_u64;
|
||||||
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
||||||
|
|
||||||
@ -501,7 +502,7 @@ pub struct QuotientGeneratorExtension<const D: usize> {
|
|||||||
quotient: ExtensionTarget<D>,
|
quotient: ExtensionTarget<D>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
|
||||||
for QuotientGeneratorExtension<D>
|
for QuotientGeneratorExtension<D>
|
||||||
{
|
{
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
@ -521,13 +522,13 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
|||||||
out_buffer.set_extension_target(self.quotient, quotient)
|
out_buffer.set_extension_target(self.quotient, quotient)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_target_ext(self.numerator)?;
|
dst.write_target_ext(self.numerator)?;
|
||||||
dst.write_target_ext(self.denominator)?;
|
dst.write_target_ext(self.denominator)?;
|
||||||
dst.write_target_ext(self.quotient)
|
dst.write_target_ext(self.quotient)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let numerator = src.read_target_ext()?;
|
let numerator = src.read_target_ext()?;
|
||||||
let denominator = src.read_target_ext()?;
|
let denominator = src.read_target_ext()?;
|
||||||
let quotient = src.read_target_ext()?;
|
let quotient = src.read_target_ext()?;
|
||||||
|
|||||||
@ -7,6 +7,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator};
|
|||||||
use crate::iop::target::{BoolTarget, Target};
|
use crate::iop::target::{BoolTarget, Target};
|
||||||
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
|
use crate::plonk::circuit_data::CommonCircuitData;
|
||||||
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
||||||
|
|
||||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||||
@ -60,7 +61,7 @@ pub struct LowHighGenerator {
|
|||||||
high: Target,
|
high: Target,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField> SimpleGenerator<F> for LowHighGenerator {
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for LowHighGenerator {
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
"LowHighGenerator".to_string()
|
"LowHighGenerator".to_string()
|
||||||
}
|
}
|
||||||
@ -78,14 +79,14 @@ impl<F: RichField> SimpleGenerator<F> for LowHighGenerator {
|
|||||||
out_buffer.set_target(self.high, F::from_canonical_u64(high));
|
out_buffer.set_target(self.high, F::from_canonical_u64(high));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_target(self.integer)?;
|
dst.write_target(self.integer)?;
|
||||||
dst.write_usize(self.n_log)?;
|
dst.write_usize(self.n_log)?;
|
||||||
dst.write_target(self.low)?;
|
dst.write_target(self.low)?;
|
||||||
dst.write_target(self.high)
|
dst.write_target(self.high)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let integer = src.read_target()?;
|
let integer = src.read_target()?;
|
||||||
let n_log = src.read_usize()?;
|
let n_log = src.read_usize()?;
|
||||||
let low = src.read_target()?;
|
let low = src.read_target()?;
|
||||||
|
|||||||
@ -5,13 +5,13 @@ use core::borrow::Borrow;
|
|||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use crate::field::extension::Extendable;
|
use crate::field::extension::Extendable;
|
||||||
use crate::field::types::Field;
|
|
||||||
use crate::gates::base_sum::BaseSumGate;
|
use crate::gates::base_sum::BaseSumGate;
|
||||||
use crate::hash::hash_types::RichField;
|
use crate::hash::hash_types::RichField;
|
||||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator};
|
use crate::iop::generator::{GeneratedValues, SimpleGenerator};
|
||||||
use crate::iop::target::{BoolTarget, Target};
|
use crate::iop::target::{BoolTarget, Target};
|
||||||
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
|
use crate::plonk::circuit_data::CommonCircuitData;
|
||||||
use crate::util::log_floor;
|
use crate::util::log_floor;
|
||||||
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
||||||
|
|
||||||
@ -86,7 +86,9 @@ pub struct BaseSumGenerator<const B: usize> {
|
|||||||
limbs: Vec<BoolTarget>,
|
limbs: Vec<BoolTarget>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Field, const B: usize> SimpleGenerator<F> for BaseSumGenerator<B> {
|
impl<F: RichField + Extendable<D>, const B: usize, const D: usize> SimpleGenerator<F, D>
|
||||||
|
for BaseSumGenerator<B>
|
||||||
|
{
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
"BaseSumGenerator".to_string()
|
"BaseSumGenerator".to_string()
|
||||||
}
|
}
|
||||||
@ -108,12 +110,12 @@ impl<F: Field, const B: usize> SimpleGenerator<F> for BaseSumGenerator<B> {
|
|||||||
out_buffer.set_target(Target::wire(self.row, BaseSumGate::<B>::WIRE_SUM), sum);
|
out_buffer.set_target(Target::wire(self.row, BaseSumGate::<B>::WIRE_SUM), sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.row)?;
|
dst.write_usize(self.row)?;
|
||||||
dst.write_target_bool_vec(&self.limbs)
|
dst.write_target_bool_vec(&self.limbs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let row = src.read_usize()?;
|
let row = src.read_usize()?;
|
||||||
let limbs = src.read_target_bool_vec()?;
|
let limbs = src.read_target_bool_vec()?;
|
||||||
Ok(Self { row, limbs })
|
Ok(Self { row, limbs })
|
||||||
@ -123,6 +125,7 @@ impl<F: Field, const B: usize> SimpleGenerator<F> for BaseSumGenerator<B> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use plonky2_field::types::Field;
|
||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator};
|
|||||||
use crate::iop::target::{BoolTarget, Target};
|
use crate::iop::target::{BoolTarget, Target};
|
||||||
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
|
use crate::plonk::circuit_data::CommonCircuitData;
|
||||||
use crate::util::ceil_div_usize;
|
use crate::util::ceil_div_usize;
|
||||||
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ pub struct SplitGenerator {
|
|||||||
bits: Vec<Target>,
|
bits: Vec<Target>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField> SimpleGenerator<F> for SplitGenerator {
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for SplitGenerator {
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
"SplitGenerator".to_string()
|
"SplitGenerator".to_string()
|
||||||
}
|
}
|
||||||
@ -86,12 +87,12 @@ impl<F: RichField> SimpleGenerator<F> for SplitGenerator {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_target(self.integer)?;
|
dst.write_target(self.integer)?;
|
||||||
dst.write_target_vec(&self.bits)
|
dst.write_target_vec(&self.bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let integer = src.read_target()?;
|
let integer = src.read_target()?;
|
||||||
let bits = src.read_target_vec()?;
|
let bits = src.read_target_vec()?;
|
||||||
Ok(Self { integer, bits })
|
Ok(Self { integer, bits })
|
||||||
@ -105,7 +106,7 @@ pub struct WireSplitGenerator {
|
|||||||
num_limbs: usize,
|
num_limbs: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField> SimpleGenerator<F> for WireSplitGenerator {
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for WireSplitGenerator {
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
"WireSplitGenerator".to_string()
|
"WireSplitGenerator".to_string()
|
||||||
}
|
}
|
||||||
@ -141,13 +142,13 @@ impl<F: RichField> SimpleGenerator<F> for WireSplitGenerator {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_target(self.integer)?;
|
dst.write_target(self.integer)?;
|
||||||
dst.write_usize_vec(&self.gates)?;
|
dst.write_usize_vec(&self.gates)?;
|
||||||
dst.write_usize(self.num_limbs)
|
dst.write_usize(self.num_limbs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let integer = src.read_target()?;
|
let integer = src.read_target()?;
|
||||||
let gates = src.read_usize_vec()?;
|
let gates = src.read_usize_vec()?;
|
||||||
let num_limbs = src.read_usize()?;
|
let num_limbs = src.read_usize()?;
|
||||||
|
|||||||
@ -13,7 +13,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGeneratorRe
|
|||||||
use crate::iop::target::Target;
|
use crate::iop::target::Target;
|
||||||
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
use crate::plonk::circuit_data::CircuitConfig;
|
use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData};
|
||||||
use crate::plonk::vars::{
|
use crate::plonk::vars::{
|
||||||
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
|
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
|
||||||
EvaluationVarsBasePacked,
|
EvaluationVarsBasePacked,
|
||||||
@ -60,11 +60,11 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ArithmeticGate
|
|||||||
format!("{self:?}")
|
format!("{self:?}")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.num_ops)
|
dst.write_usize(self.num_ops)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let num_ops = src.read_usize()?;
|
let num_ops = src.read_usize()?;
|
||||||
Ok(Self { num_ops })
|
Ok(Self { num_ops })
|
||||||
}
|
}
|
||||||
@ -126,7 +126,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ArithmeticGate
|
|||||||
constraints
|
constraints
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generators(&self, row: usize, local_constants: &[F]) -> Vec<WitnessGeneratorRef<F>> {
|
fn generators(&self, row: usize, local_constants: &[F]) -> Vec<WitnessGeneratorRef<F, D>> {
|
||||||
(0..self.num_ops)
|
(0..self.num_ops)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
WitnessGeneratorRef::new(
|
WitnessGeneratorRef::new(
|
||||||
@ -188,7 +188,7 @@ pub struct ArithmeticBaseGenerator<F: RichField + Extendable<D>, const D: usize>
|
|||||||
i: usize,
|
i: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
|
||||||
for ArithmeticBaseGenerator<F, D>
|
for ArithmeticBaseGenerator<F, D>
|
||||||
{
|
{
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
@ -221,14 +221,14 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
|||||||
out_buffer.set_target(output_target, computed_output)
|
out_buffer.set_target(output_target, computed_output)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.row)?;
|
dst.write_usize(self.row)?;
|
||||||
dst.write_field(self.const_0)?;
|
dst.write_field(self.const_0)?;
|
||||||
dst.write_field(self.const_1)?;
|
dst.write_field(self.const_1)?;
|
||||||
dst.write_usize(self.i)
|
dst.write_usize(self.i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let row = src.read_usize()?;
|
let row = src.read_usize()?;
|
||||||
let const_0 = src.read_field()?;
|
let const_0 = src.read_field()?;
|
||||||
let const_1 = src.read_field()?;
|
let const_1 = src.read_field()?;
|
||||||
|
|||||||
@ -12,7 +12,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGeneratorRe
|
|||||||
use crate::iop::target::Target;
|
use crate::iop::target::Target;
|
||||||
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
use crate::plonk::circuit_data::CircuitConfig;
|
use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData};
|
||||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||||
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
||||||
|
|
||||||
@ -56,11 +56,11 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ArithmeticExte
|
|||||||
format!("{self:?}")
|
format!("{self:?}")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.num_ops)
|
dst.write_usize(self.num_ops)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let num_ops = src.read_usize()?;
|
let num_ops = src.read_usize()?;
|
||||||
Ok(Self { num_ops })
|
Ok(Self { num_ops })
|
||||||
}
|
}
|
||||||
@ -131,7 +131,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ArithmeticExte
|
|||||||
constraints
|
constraints
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generators(&self, row: usize, local_constants: &[F]) -> Vec<WitnessGeneratorRef<F>> {
|
fn generators(&self, row: usize, local_constants: &[F]) -> Vec<WitnessGeneratorRef<F, D>> {
|
||||||
(0..self.num_ops)
|
(0..self.num_ops)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
WitnessGeneratorRef::new(
|
WitnessGeneratorRef::new(
|
||||||
@ -172,7 +172,7 @@ pub struct ArithmeticExtensionGenerator<F: RichField + Extendable<D>, const D: u
|
|||||||
i: usize,
|
i: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
|
||||||
for ArithmeticExtensionGenerator<F, D>
|
for ArithmeticExtensionGenerator<F, D>
|
||||||
{
|
{
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
@ -214,14 +214,14 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
|||||||
out_buffer.set_extension_target(output_target, computed_output)
|
out_buffer.set_extension_target(output_target, computed_output)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.row)?;
|
dst.write_usize(self.row)?;
|
||||||
dst.write_field(self.const_0)?;
|
dst.write_field(self.const_0)?;
|
||||||
dst.write_field(self.const_1)?;
|
dst.write_field(self.const_1)?;
|
||||||
dst.write_usize(self.i)
|
dst.write_usize(self.i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let row = src.read_usize()?;
|
let row = src.read_usize()?;
|
||||||
let const_0 = src.read_field()?;
|
let const_0 = src.read_field()?;
|
||||||
let const_1 = src.read_field()?;
|
let const_1 = src.read_field()?;
|
||||||
|
|||||||
@ -15,7 +15,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGeneratorRe
|
|||||||
use crate::iop::target::Target;
|
use crate::iop::target::Target;
|
||||||
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
use crate::plonk::circuit_data::CircuitConfig;
|
use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData};
|
||||||
use crate::plonk::plonk_common::{reduce_with_powers, reduce_with_powers_ext_circuit};
|
use crate::plonk::plonk_common::{reduce_with_powers, reduce_with_powers_ext_circuit};
|
||||||
use crate::plonk::vars::{
|
use crate::plonk::vars::{
|
||||||
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
|
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
|
||||||
@ -55,11 +55,11 @@ impl<F: RichField + Extendable<D>, const D: usize, const B: usize> Gate<F, D> fo
|
|||||||
format!("{self:?} + Base: {B}")
|
format!("{self:?} + Base: {B}")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.num_limbs)
|
dst.write_usize(self.num_limbs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let num_limbs = src.read_usize()?;
|
let num_limbs = src.read_usize()?;
|
||||||
Ok(Self { num_limbs })
|
Ok(Self { num_limbs })
|
||||||
}
|
}
|
||||||
@ -118,7 +118,7 @@ impl<F: RichField + Extendable<D>, const D: usize, const B: usize> Gate<F, D> fo
|
|||||||
constraints
|
constraints
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F>> {
|
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F, D>> {
|
||||||
let gen = BaseSplitGenerator::<B> {
|
let gen = BaseSplitGenerator::<B> {
|
||||||
row,
|
row,
|
||||||
num_limbs: self.num_limbs,
|
num_limbs: self.num_limbs,
|
||||||
@ -175,7 +175,9 @@ pub struct BaseSplitGenerator<const B: usize> {
|
|||||||
num_limbs: usize,
|
num_limbs: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField, const B: usize> SimpleGenerator<F> for BaseSplitGenerator<B> {
|
impl<F: RichField + Extendable<D>, const B: usize, const D: usize> SimpleGenerator<F, D>
|
||||||
|
for BaseSplitGenerator<B>
|
||||||
|
{
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
"BaseSplitGenerator".to_string()
|
"BaseSplitGenerator".to_string()
|
||||||
}
|
}
|
||||||
@ -209,12 +211,12 @@ impl<F: RichField, const B: usize> SimpleGenerator<F> for BaseSplitGenerator<B>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.row)?;
|
dst.write_usize(self.row)?;
|
||||||
dst.write_usize(self.num_limbs)
|
dst.write_usize(self.num_limbs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let row = src.read_usize()?;
|
let row = src.read_usize()?;
|
||||||
let num_limbs = src.read_usize()?;
|
let num_limbs = src.read_usize()?;
|
||||||
Ok(Self { row, num_limbs })
|
Ok(Self { row, num_limbs })
|
||||||
|
|||||||
@ -13,6 +13,7 @@ use crate::hash::hash_types::RichField;
|
|||||||
use crate::iop::ext_target::ExtensionTarget;
|
use crate::iop::ext_target::ExtensionTarget;
|
||||||
use crate::iop::generator::WitnessGeneratorRef;
|
use crate::iop::generator::WitnessGeneratorRef;
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
|
use crate::plonk::circuit_data::CommonCircuitData;
|
||||||
use crate::plonk::vars::{
|
use crate::plonk::vars::{
|
||||||
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
|
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
|
||||||
EvaluationVarsBasePacked,
|
EvaluationVarsBasePacked,
|
||||||
@ -46,11 +47,11 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ConstantGate {
|
|||||||
format!("{self:?}")
|
format!("{self:?}")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.num_consts)
|
dst.write_usize(self.num_consts)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let num_consts = src.read_usize()?;
|
let num_consts = src.read_usize()?;
|
||||||
Ok(Self { num_consts })
|
Ok(Self { num_consts })
|
||||||
}
|
}
|
||||||
@ -90,7 +91,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ConstantGate {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generators(&self, _row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F>> {
|
fn generators(&self, _row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F, D>> {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,7 @@ use crate::iop::target::Target;
|
|||||||
use crate::iop::wire::Wire;
|
use crate::iop::wire::Wire;
|
||||||
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
|
use crate::plonk::circuit_data::CommonCircuitData;
|
||||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||||
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
||||||
|
|
||||||
@ -168,14 +169,14 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for CosetInterpola
|
|||||||
format!("{self:?}<D={D}>")
|
format!("{self:?}<D={D}>")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.subgroup_bits)?;
|
dst.write_usize(self.subgroup_bits)?;
|
||||||
dst.write_usize(self.degree)?;
|
dst.write_usize(self.degree)?;
|
||||||
dst.write_usize(self.barycentric_weights.len())?;
|
dst.write_usize(self.barycentric_weights.len())?;
|
||||||
dst.write_field_vec(&self.barycentric_weights)
|
dst.write_field_vec(&self.barycentric_weights)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let subgroup_bits = src.read_usize()?;
|
let subgroup_bits = src.read_usize()?;
|
||||||
let degree = src.read_usize()?;
|
let degree = src.read_usize()?;
|
||||||
let length = src.read_usize()?;
|
let length = src.read_usize()?;
|
||||||
@ -362,7 +363,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for CosetInterpola
|
|||||||
constraints
|
constraints
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F>> {
|
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F, D>> {
|
||||||
let gen = InterpolationGenerator::<F, D>::new(row, self.clone());
|
let gen = InterpolationGenerator::<F, D>::new(row, self.clone());
|
||||||
vec![WitnessGeneratorRef::new(gen.adapter())]
|
vec![WitnessGeneratorRef::new(gen.adapter())]
|
||||||
}
|
}
|
||||||
@ -406,7 +407,7 @@ impl<F: RichField + Extendable<D>, const D: usize> InterpolationGenerator<F, D>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
|
||||||
for InterpolationGenerator<F, D>
|
for InterpolationGenerator<F, D>
|
||||||
{
|
{
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
@ -496,14 +497,14 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
|||||||
out_buffer.set_ext_wires(evaluation_value_wires, computed_eval);
|
out_buffer.set_ext_wires(evaluation_value_wires, computed_eval);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.row)?;
|
dst.write_usize(self.row)?;
|
||||||
self.gate.serialize(dst)
|
self.gate.serialize(dst, _common_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let row = src.read_usize()?;
|
let row = src.read_usize()?;
|
||||||
let gate = CosetInterpolationGate::deserialize(src)?;
|
let gate = CosetInterpolationGate::deserialize(src, _common_data)?;
|
||||||
Ok(Self::new(row, gate))
|
Ok(Self::new(row, gate))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ use crate::iop::target::Target;
|
|||||||
use crate::iop::wire::Wire;
|
use crate::iop::wire::Wire;
|
||||||
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
use crate::plonk::circuit_data::CircuitConfig;
|
use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData};
|
||||||
use crate::plonk::vars::{
|
use crate::plonk::vars::{
|
||||||
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
|
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
|
||||||
EvaluationVarsBasePacked,
|
EvaluationVarsBasePacked,
|
||||||
@ -76,11 +76,11 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for Exponentiation
|
|||||||
format!("{self:?}<D={D}>")
|
format!("{self:?}<D={D}>")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.num_power_bits)
|
dst.write_usize(self.num_power_bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let num_power_bits = src.read_usize()?;
|
let num_power_bits = src.read_usize()?;
|
||||||
Ok(Self::new(num_power_bits))
|
Ok(Self::new(num_power_bits))
|
||||||
}
|
}
|
||||||
@ -173,7 +173,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for Exponentiation
|
|||||||
constraints
|
constraints
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F>> {
|
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F, D>> {
|
||||||
let gen = ExponentiationGenerator::<F, D> {
|
let gen = ExponentiationGenerator::<F, D> {
|
||||||
row,
|
row,
|
||||||
gate: self.clone(),
|
gate: self.clone(),
|
||||||
@ -243,7 +243,7 @@ pub struct ExponentiationGenerator<F: RichField + Extendable<D>, const D: usize>
|
|||||||
gate: ExponentiationGate<F, D>,
|
gate: ExponentiationGate<F, D>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
|
||||||
for ExponentiationGenerator<F, D>
|
for ExponentiationGenerator<F, D>
|
||||||
{
|
{
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
@ -295,14 +295,14 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
|||||||
out_buffer.set_wire(output_wire, intermediate_values[num_power_bits - 1]);
|
out_buffer.set_wire(output_wire, intermediate_values[num_power_bits - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.row)?;
|
dst.write_usize(self.row)?;
|
||||||
self.gate.serialize(dst)
|
self.gate.serialize(dst, _common_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let row = src.read_usize()?;
|
let row = src.read_usize()?;
|
||||||
let gate = ExponentiationGate::deserialize(src)?;
|
let gate = ExponentiationGate::deserialize(src, _common_data)?;
|
||||||
Ok(Self { row, gate })
|
Ok(Self { row, gate })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ use crate::hash::hash_types::RichField;
|
|||||||
use crate::iop::ext_target::ExtensionTarget;
|
use crate::iop::ext_target::ExtensionTarget;
|
||||||
use crate::iop::generator::WitnessGeneratorRef;
|
use crate::iop::generator::WitnessGeneratorRef;
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
|
use crate::plonk::circuit_data::CommonCircuitData;
|
||||||
use crate::plonk::vars::{
|
use crate::plonk::vars::{
|
||||||
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
|
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
|
||||||
};
|
};
|
||||||
@ -28,9 +29,9 @@ use crate::util::serialization::{Buffer, IoResult};
|
|||||||
pub trait Gate<F: RichField + Extendable<D>, const D: usize>: 'static + Send + Sync {
|
pub trait Gate<F: RichField + Extendable<D>, const D: usize>: 'static + Send + Sync {
|
||||||
fn id(&self) -> String;
|
fn id(&self) -> String;
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()>;
|
fn serialize(&self, dst: &mut Vec<u8>, common_data: &CommonCircuitData<F, D>) -> IoResult<()>;
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self>
|
fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData<F, D>) -> IoResult<Self>
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
|
|
||||||
@ -175,7 +176,7 @@ pub trait Gate<F: RichField + Extendable<D>, const D: usize>: 'static + Send + S
|
|||||||
|
|
||||||
/// The generators used to populate the witness.
|
/// The generators used to populate the witness.
|
||||||
/// Note: This should return exactly 1 generator per operation in the gate.
|
/// Note: This should return exactly 1 generator per operation in the gate.
|
||||||
fn generators(&self, row: usize, local_constants: &[F]) -> Vec<WitnessGeneratorRef<F>>;
|
fn generators(&self, row: usize, local_constants: &[F]) -> Vec<WitnessGeneratorRef<F, D>>;
|
||||||
|
|
||||||
/// The number of wires used by this gate.
|
/// The number of wires used by this gate.
|
||||||
fn num_wires(&self) -> usize;
|
fn num_wires(&self) -> usize;
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
use alloc::format;
|
use alloc::format;
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use alloc::sync::Arc;
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::usize;
|
use core::usize;
|
||||||
|
|
||||||
|
use itertools::Itertools;
|
||||||
|
use keccak_hash::keccak;
|
||||||
|
|
||||||
use super::lookup_table::LookupTable;
|
use super::lookup_table::LookupTable;
|
||||||
use crate::field::extension::Extendable;
|
use crate::field::extension::Extendable;
|
||||||
use crate::field::packed::PackedField;
|
use crate::field::packed::PackedField;
|
||||||
@ -16,7 +18,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGeneratorRe
|
|||||||
use crate::iop::target::Target;
|
use crate::iop::target::Target;
|
||||||
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
use crate::plonk::circuit_data::CircuitConfig;
|
use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData};
|
||||||
use crate::plonk::vars::{
|
use crate::plonk::vars::{
|
||||||
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
|
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
|
||||||
EvaluationVarsBasePacked,
|
EvaluationVarsBasePacked,
|
||||||
@ -32,13 +34,21 @@ pub struct LookupGate {
|
|||||||
pub num_slots: usize,
|
pub num_slots: usize,
|
||||||
/// LUT associated to the gate.
|
/// LUT associated to the gate.
|
||||||
lut: LookupTable,
|
lut: LookupTable,
|
||||||
|
/// The Keccak hash of the lookup table.
|
||||||
|
lut_hash: [u8; 32],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LookupGate {
|
impl LookupGate {
|
||||||
pub fn new_from_table(config: &CircuitConfig, lut: LookupTable) -> Self {
|
pub fn new_from_table(config: &CircuitConfig, lut: LookupTable) -> Self {
|
||||||
|
let table_bytes = lut
|
||||||
|
.iter()
|
||||||
|
.flat_map(|(input, output)| [input.to_le_bytes(), output.to_le_bytes()].concat())
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
num_slots: Self::num_slots(config),
|
num_slots: Self::num_slots(config),
|
||||||
lut,
|
lut,
|
||||||
|
lut_hash: keccak(table_bytes).0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn num_slots(config: &CircuitConfig) -> usize {
|
pub(crate) fn num_slots(config: &CircuitConfig) -> usize {
|
||||||
@ -57,21 +67,35 @@ impl LookupGate {
|
|||||||
|
|
||||||
impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for LookupGate {
|
impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for LookupGate {
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
format!("{self:?}")
|
// Custom implementation to not have the entire lookup table
|
||||||
|
format!(
|
||||||
|
"LookupGate {{num_slots: {}, lut_hash: {:?}}}",
|
||||||
|
self.num_slots, self.lut_hash
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.num_slots)?;
|
dst.write_usize(self.num_slots)?;
|
||||||
dst.write_lut(&self.lut)
|
for (i, lut) in common_data.luts.iter().enumerate() {
|
||||||
|
if lut == &self.lut {
|
||||||
|
dst.write_usize(i)?;
|
||||||
|
return dst.write_all(&self.lut_hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("The associated lookup table couldn't be found.")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let num_slots = src.read_usize()?;
|
let num_slots = src.read_usize()?;
|
||||||
let lut = src.read_lut()?;
|
let lut_index = src.read_usize()?;
|
||||||
|
let mut lut_hash = [0u8; 32];
|
||||||
|
src.read_exact(&mut lut_hash)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
num_slots,
|
num_slots,
|
||||||
lut: Arc::new(lut),
|
lut: common_data.luts[lut_index].clone(),
|
||||||
|
lut_hash,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +125,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for LookupGate {
|
|||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F>> {
|
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F, D>> {
|
||||||
(0..self.num_slots)
|
(0..self.num_slots)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
WitnessGeneratorRef::new(
|
WitnessGeneratorRef::new(
|
||||||
@ -149,7 +173,7 @@ pub struct LookupGenerator {
|
|||||||
slot_nb: usize,
|
slot_nb: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField> SimpleGenerator<F> for LookupGenerator {
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for LookupGenerator {
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
"LookupGenerator".to_string()
|
"LookupGenerator".to_string()
|
||||||
}
|
}
|
||||||
@ -165,39 +189,47 @@ impl<F: RichField> SimpleGenerator<F> for LookupGenerator {
|
|||||||
let get_wire = |wire: usize| -> F { witness.get_target(Target::wire(self.row, wire)) };
|
let get_wire = |wire: usize| -> F { witness.get_target(Target::wire(self.row, wire)) };
|
||||||
|
|
||||||
let input_val = get_wire(LookupGate::wire_ith_looking_inp(self.slot_nb));
|
let input_val = get_wire(LookupGate::wire_ith_looking_inp(self.slot_nb));
|
||||||
let output_val = if input_val
|
let (input, output) = self.lut[input_val.to_canonical_u64() as usize];
|
||||||
== F::from_canonical_u16(self.lut[input_val.to_canonical_u64() as usize].0)
|
if input_val == F::from_canonical_u16(input) {
|
||||||
{
|
let output_val = F::from_canonical_u16(output);
|
||||||
F::from_canonical_u16(self.lut[input_val.to_canonical_u64() as usize].1)
|
|
||||||
|
let out_wire = Target::wire(self.row, LookupGate::wire_ith_looking_out(self.slot_nb));
|
||||||
|
out_buffer.set_target(out_wire, output_val);
|
||||||
} else {
|
} else {
|
||||||
let mut cur_idx = 0;
|
for (input, output) in self.lut.iter() {
|
||||||
while input_val != F::from_canonical_u16(self.lut[cur_idx].0)
|
if input_val == F::from_canonical_u16(*input) {
|
||||||
&& cur_idx < self.lut.len()
|
let output_val = F::from_canonical_u16(*output);
|
||||||
{
|
|
||||||
cur_idx += 1;
|
let out_wire =
|
||||||
|
Target::wire(self.row, LookupGate::wire_ith_looking_out(self.slot_nb));
|
||||||
|
out_buffer.set_target(out_wire, output_val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
assert!(cur_idx < self.lut.len(), "Incorrect input value provided");
|
panic!("Incorrect input value provided");
|
||||||
F::from_canonical_u16(self.lut[cur_idx].1)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let out_wire = Target::wire(self.row, LookupGate::wire_ith_looking_out(self.slot_nb));
|
|
||||||
out_buffer.set_target(out_wire, output_val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.row)?;
|
dst.write_usize(self.row)?;
|
||||||
dst.write_lut(&self.lut)?;
|
dst.write_usize(self.slot_nb)?;
|
||||||
dst.write_usize(self.slot_nb)
|
for (i, lut) in common_data.luts.iter().enumerate() {
|
||||||
|
if lut == &self.lut {
|
||||||
|
return dst.write_usize(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("The associated lookup table couldn't be found.")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let row = src.read_usize()?;
|
let row = src.read_usize()?;
|
||||||
let lut = src.read_lut()?;
|
|
||||||
let slot_nb = src.read_usize()?;
|
let slot_nb = src.read_usize()?;
|
||||||
|
let lut_index = src.read_usize()?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
row,
|
row,
|
||||||
lut: Arc::new(lut),
|
lut: common_data.luts[lut_index].clone(),
|
||||||
slot_nb,
|
slot_nb,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,8 @@ use alloc::sync::Arc;
|
|||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::usize;
|
use core::usize;
|
||||||
|
|
||||||
|
use itertools::Itertools;
|
||||||
|
use keccak_hash::keccak;
|
||||||
use plonky2_util::ceil_div_usize;
|
use plonky2_util::ceil_div_usize;
|
||||||
|
|
||||||
use crate::field::extension::Extendable;
|
use crate::field::extension::Extendable;
|
||||||
@ -17,7 +19,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGeneratorRe
|
|||||||
use crate::iop::target::Target;
|
use crate::iop::target::Target;
|
||||||
use crate::iop::witness::{PartitionWitness, WitnessWrite};
|
use crate::iop::witness::{PartitionWitness, WitnessWrite};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
use crate::plonk::circuit_data::CircuitConfig;
|
use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData};
|
||||||
use crate::plonk::vars::{
|
use crate::plonk::vars::{
|
||||||
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
|
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
|
||||||
EvaluationVarsBasePacked,
|
EvaluationVarsBasePacked,
|
||||||
@ -33,15 +35,23 @@ pub struct LookupTableGate {
|
|||||||
pub num_slots: usize,
|
pub num_slots: usize,
|
||||||
/// Lookup table associated to the gate.
|
/// Lookup table associated to the gate.
|
||||||
pub lut: LookupTable,
|
pub lut: LookupTable,
|
||||||
|
/// The Keccak hash of the lookup table.
|
||||||
|
lut_hash: [u8; 32],
|
||||||
/// First row of the lookup table.
|
/// First row of the lookup table.
|
||||||
last_lut_row: usize,
|
last_lut_row: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LookupTableGate {
|
impl LookupTableGate {
|
||||||
pub fn new_from_table(config: &CircuitConfig, lut: LookupTable, last_lut_row: usize) -> Self {
|
pub fn new_from_table(config: &CircuitConfig, lut: LookupTable, last_lut_row: usize) -> Self {
|
||||||
|
let table_bytes = lut
|
||||||
|
.iter()
|
||||||
|
.flat_map(|(input, output)| [input.to_le_bytes(), output.to_le_bytes()].concat())
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
num_slots: Self::num_slots(config),
|
num_slots: Self::num_slots(config),
|
||||||
lut,
|
lut,
|
||||||
|
lut_hash: keccak(table_bytes).0,
|
||||||
last_lut_row,
|
last_lut_row,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,23 +79,37 @@ impl LookupTableGate {
|
|||||||
|
|
||||||
impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for LookupTableGate {
|
impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for LookupTableGate {
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
format!("{self:?}")
|
// Custom implementation to not have the entire lookup table
|
||||||
|
format!(
|
||||||
|
"LookupGate {{num_slots: {}, lut_hash: {:?}, last_lut_row: {}}}",
|
||||||
|
self.num_slots, self.lut_hash, self.last_lut_row
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.num_slots)?;
|
dst.write_usize(self.num_slots)?;
|
||||||
dst.write_lut(&self.lut)?;
|
dst.write_usize(self.last_lut_row)?;
|
||||||
dst.write_usize(self.last_lut_row)
|
for (i, lut) in common_data.luts.iter().enumerate() {
|
||||||
|
if lut == &self.lut {
|
||||||
|
dst.write_usize(i)?;
|
||||||
|
return dst.write_all(&self.lut_hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("The associated lookup table couldn't be found.")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let num_slots = src.read_usize()?;
|
let num_slots = src.read_usize()?;
|
||||||
let lut = src.read_lut()?;
|
|
||||||
let last_lut_row = src.read_usize()?;
|
let last_lut_row = src.read_usize()?;
|
||||||
|
let lut_index = src.read_usize()?;
|
||||||
|
let mut lut_hash = [0u8; 32];
|
||||||
|
src.read_exact(&mut lut_hash)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
num_slots,
|
num_slots,
|
||||||
lut: Arc::new(lut),
|
lut: common_data.luts[lut_index].clone(),
|
||||||
|
lut_hash,
|
||||||
last_lut_row,
|
last_lut_row,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -116,7 +140,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for LookupTableGat
|
|||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F>> {
|
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F, D>> {
|
||||||
(0..self.num_slots)
|
(0..self.num_slots)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
WitnessGeneratorRef::new(
|
WitnessGeneratorRef::new(
|
||||||
@ -168,7 +192,7 @@ pub struct LookupTableGenerator {
|
|||||||
last_lut_row: usize,
|
last_lut_row: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField> SimpleGenerator<F> for LookupTableGenerator {
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for LookupTableGenerator {
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
"LookupTableGenerator".to_string()
|
"LookupTableGenerator".to_string()
|
||||||
}
|
}
|
||||||
@ -187,14 +211,9 @@ impl<F: RichField> SimpleGenerator<F> for LookupTableGenerator {
|
|||||||
Target::wire(self.row, LookupTableGate::wire_ith_looked_out(self.slot_nb));
|
Target::wire(self.row, LookupTableGate::wire_ith_looked_out(self.slot_nb));
|
||||||
|
|
||||||
if slot < self.lut.len() {
|
if slot < self.lut.len() {
|
||||||
out_buffer.set_target(
|
let (input, output) = self.lut[slot];
|
||||||
slot_input_target,
|
out_buffer.set_target(slot_input_target, F::from_canonical_usize(input as usize));
|
||||||
F::from_canonical_usize(self.lut[slot].0 as usize),
|
out_buffer.set_target(slot_output_target, F::from_canonical_usize(output as usize));
|
||||||
);
|
|
||||||
out_buffer.set_target(
|
|
||||||
slot_output_target,
|
|
||||||
F::from_canonical_usize(self.lut[slot].1.into()),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
// Pad with zeros.
|
// Pad with zeros.
|
||||||
out_buffer.set_target(slot_input_target, F::ZERO);
|
out_buffer.set_target(slot_input_target, F::ZERO);
|
||||||
@ -202,24 +221,30 @@ impl<F: RichField> SimpleGenerator<F> for LookupTableGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.row)?;
|
dst.write_usize(self.row)?;
|
||||||
dst.write_lut(&self.lut)?;
|
|
||||||
dst.write_usize(self.slot_nb)?;
|
dst.write_usize(self.slot_nb)?;
|
||||||
dst.write_usize(self.num_slots)?;
|
dst.write_usize(self.num_slots)?;
|
||||||
dst.write_usize(self.last_lut_row)
|
dst.write_usize(self.last_lut_row)?;
|
||||||
|
for (i, lut) in common_data.luts.iter().enumerate() {
|
||||||
|
if lut == &self.lut {
|
||||||
|
return dst.write_usize(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("The associated lookup table couldn't be found.")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let row = src.read_usize()?;
|
let row = src.read_usize()?;
|
||||||
let lut = src.read_lut()?;
|
|
||||||
let slot_nb = src.read_usize()?;
|
let slot_nb = src.read_usize()?;
|
||||||
let num_slots = src.read_usize()?;
|
let num_slots = src.read_usize()?;
|
||||||
let last_lut_row = src.read_usize()?;
|
let last_lut_row = src.read_usize()?;
|
||||||
|
let lut_index = src.read_usize()?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
row,
|
row,
|
||||||
lut: Arc::new(lut),
|
lut: common_data.luts[lut_index].clone(),
|
||||||
slot_nb,
|
slot_nb,
|
||||||
num_slots,
|
num_slots,
|
||||||
last_lut_row,
|
last_lut_row,
|
||||||
|
|||||||
@ -12,7 +12,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGeneratorRe
|
|||||||
use crate::iop::target::Target;
|
use crate::iop::target::Target;
|
||||||
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
use crate::plonk::circuit_data::CircuitConfig;
|
use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData};
|
||||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||||
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
||||||
|
|
||||||
@ -53,11 +53,11 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for MulExtensionGa
|
|||||||
format!("{self:?}")
|
format!("{self:?}")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.num_ops)
|
dst.write_usize(self.num_ops)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let num_ops = src.read_usize()?;
|
let num_ops = src.read_usize()?;
|
||||||
Ok(Self { num_ops })
|
Ok(Self { num_ops })
|
||||||
}
|
}
|
||||||
@ -119,7 +119,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for MulExtensionGa
|
|||||||
constraints
|
constraints
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generators(&self, row: usize, local_constants: &[F]) -> Vec<WitnessGeneratorRef<F>> {
|
fn generators(&self, row: usize, local_constants: &[F]) -> Vec<WitnessGeneratorRef<F, D>> {
|
||||||
(0..self.num_ops)
|
(0..self.num_ops)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
WitnessGeneratorRef::new(
|
WitnessGeneratorRef::new(
|
||||||
@ -158,7 +158,7 @@ pub struct MulExtensionGenerator<F: RichField + Extendable<D>, const D: usize> {
|
|||||||
i: usize,
|
i: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
|
||||||
for MulExtensionGenerator<F, D>
|
for MulExtensionGenerator<F, D>
|
||||||
{
|
{
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
@ -191,13 +191,13 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
|||||||
out_buffer.set_extension_target(output_target, computed_output)
|
out_buffer.set_extension_target(output_target, computed_output)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.row)?;
|
dst.write_usize(self.row)?;
|
||||||
dst.write_field(self.const_0)?;
|
dst.write_field(self.const_0)?;
|
||||||
dst.write_usize(self.i)
|
dst.write_usize(self.i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let row = src.read_usize()?;
|
let row = src.read_usize()?;
|
||||||
let const_0 = src.read_field()?;
|
let const_0 = src.read_field()?;
|
||||||
let i = src.read_usize()?;
|
let i = src.read_usize()?;
|
||||||
|
|||||||
@ -7,6 +7,7 @@ use crate::hash::hash_types::RichField;
|
|||||||
use crate::iop::ext_target::ExtensionTarget;
|
use crate::iop::ext_target::ExtensionTarget;
|
||||||
use crate::iop::generator::WitnessGeneratorRef;
|
use crate::iop::generator::WitnessGeneratorRef;
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
|
use crate::plonk::circuit_data::CommonCircuitData;
|
||||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBaseBatch};
|
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBaseBatch};
|
||||||
use crate::util::serialization::{Buffer, IoResult};
|
use crate::util::serialization::{Buffer, IoResult};
|
||||||
|
|
||||||
@ -18,11 +19,15 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for NoopGate {
|
|||||||
"NoopGate".into()
|
"NoopGate".into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, _dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(
|
||||||
|
&self,
|
||||||
|
_dst: &mut Vec<u8>,
|
||||||
|
_common_data: &CommonCircuitData<F, D>,
|
||||||
|
) -> IoResult<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(_src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(_src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
Ok(Self)
|
Ok(Self)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +47,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for NoopGate {
|
|||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generators(&self, _row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F>> {
|
fn generators(&self, _row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F, D>> {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,7 @@ use crate::iop::target::Target;
|
|||||||
use crate::iop::wire::Wire;
|
use crate::iop::wire::Wire;
|
||||||
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
|
use crate::plonk::circuit_data::CommonCircuitData;
|
||||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||||
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
||||||
|
|
||||||
@ -99,11 +100,15 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for PoseidonGate<F
|
|||||||
format!("{self:?}<WIDTH={SPONGE_WIDTH}>")
|
format!("{self:?}<WIDTH={SPONGE_WIDTH}>")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, _dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(
|
||||||
|
&self,
|
||||||
|
_dst: &mut Vec<u8>,
|
||||||
|
_common_data: &CommonCircuitData<F, D>,
|
||||||
|
) -> IoResult<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(_src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(_src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
Ok(PoseidonGate::new())
|
Ok(PoseidonGate::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -380,7 +385,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for PoseidonGate<F
|
|||||||
constraints
|
constraints
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F>> {
|
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F, D>> {
|
||||||
let gen = PoseidonGenerator::<F, D> {
|
let gen = PoseidonGenerator::<F, D> {
|
||||||
row,
|
row,
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
@ -415,7 +420,7 @@ pub struct PoseidonGenerator<F: RichField + Extendable<D> + Poseidon, const D: u
|
|||||||
_phantom: PhantomData<F>,
|
_phantom: PhantomData<F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField + Extendable<D> + Poseidon, const D: usize> SimpleGenerator<F>
|
impl<F: RichField + Extendable<D> + Poseidon, const D: usize> SimpleGenerator<F, D>
|
||||||
for PoseidonGenerator<F, D>
|
for PoseidonGenerator<F, D>
|
||||||
{
|
{
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
@ -512,11 +517,11 @@ impl<F: RichField + Extendable<D> + Poseidon, const D: usize> SimpleGenerator<F>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.row)
|
dst.write_usize(self.row)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let row = src.read_usize()?;
|
let row = src.read_usize()?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
row,
|
row,
|
||||||
|
|||||||
@ -16,6 +16,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGeneratorRe
|
|||||||
use crate::iop::target::Target;
|
use crate::iop::target::Target;
|
||||||
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
|
use crate::plonk::circuit_data::CommonCircuitData;
|
||||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||||
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
||||||
|
|
||||||
@ -118,11 +119,15 @@ impl<F: RichField + Extendable<D> + Poseidon, const D: usize> Gate<F, D> for Pos
|
|||||||
format!("{self:?}<WIDTH={SPONGE_WIDTH}>")
|
format!("{self:?}<WIDTH={SPONGE_WIDTH}>")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, _dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(
|
||||||
|
&self,
|
||||||
|
_dst: &mut Vec<u8>,
|
||||||
|
_common_data: &CommonCircuitData<F, D>,
|
||||||
|
) -> IoResult<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(_src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(_src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
Ok(PoseidonMdsGate::new())
|
Ok(PoseidonMdsGate::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,7 +192,7 @@ impl<F: RichField + Extendable<D> + Poseidon, const D: usize> Gate<F, D> for Pos
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F>> {
|
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F, D>> {
|
||||||
let gen = PoseidonMdsGenerator::<D> { row };
|
let gen = PoseidonMdsGenerator::<D> { row };
|
||||||
vec![WitnessGeneratorRef::new(gen.adapter())]
|
vec![WitnessGeneratorRef::new(gen.adapter())]
|
||||||
}
|
}
|
||||||
@ -214,7 +219,7 @@ pub struct PoseidonMdsGenerator<const D: usize> {
|
|||||||
row: usize,
|
row: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField + Extendable<D> + Poseidon, const D: usize> SimpleGenerator<F>
|
impl<F: RichField + Extendable<D> + Poseidon, const D: usize> SimpleGenerator<F, D>
|
||||||
for PoseidonMdsGenerator<D>
|
for PoseidonMdsGenerator<D>
|
||||||
{
|
{
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
@ -250,11 +255,11 @@ impl<F: RichField + Extendable<D> + Poseidon, const D: usize> SimpleGenerator<F>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.row)
|
dst.write_usize(self.row)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let row = src.read_usize()?;
|
let row = src.read_usize()?;
|
||||||
Ok(Self { row })
|
Ok(Self { row })
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ use crate::hash::hash_types::RichField;
|
|||||||
use crate::iop::ext_target::ExtensionTarget;
|
use crate::iop::ext_target::ExtensionTarget;
|
||||||
use crate::iop::generator::WitnessGeneratorRef;
|
use crate::iop::generator::WitnessGeneratorRef;
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
|
use crate::plonk::circuit_data::CommonCircuitData;
|
||||||
use crate::plonk::vars::{
|
use crate::plonk::vars::{
|
||||||
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
|
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
|
||||||
EvaluationVarsBasePacked,
|
EvaluationVarsBasePacked,
|
||||||
@ -31,11 +32,15 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for PublicInputGat
|
|||||||
"PublicInputGate".into()
|
"PublicInputGate".into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, _dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(
|
||||||
|
&self,
|
||||||
|
_dst: &mut Vec<u8>,
|
||||||
|
_common_data: &CommonCircuitData<F, D>,
|
||||||
|
) -> IoResult<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(_src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(_src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
Ok(Self)
|
Ok(Self)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +77,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for PublicInputGat
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generators(&self, _row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F>> {
|
fn generators(&self, _row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F, D>> {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,7 @@ use crate::iop::target::Target;
|
|||||||
use crate::iop::wire::Wire;
|
use crate::iop::wire::Wire;
|
||||||
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
use crate::plonk::circuit_data::CircuitConfig;
|
use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData};
|
||||||
use crate::plonk::vars::{
|
use crate::plonk::vars::{
|
||||||
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
|
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
|
||||||
EvaluationVarsBasePacked,
|
EvaluationVarsBasePacked,
|
||||||
@ -122,14 +122,14 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for RandomAccessGa
|
|||||||
format!("{self:?}<D={D}>")
|
format!("{self:?}<D={D}>")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.bits)?;
|
dst.write_usize(self.bits)?;
|
||||||
dst.write_usize(self.num_copies)?;
|
dst.write_usize(self.num_copies)?;
|
||||||
dst.write_usize(self.num_extra_constants)?;
|
dst.write_usize(self.num_extra_constants)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let bits = src.read_usize()?;
|
let bits = src.read_usize()?;
|
||||||
let num_copies = src.read_usize()?;
|
let num_copies = src.read_usize()?;
|
||||||
let num_extra_constants = src.read_usize()?;
|
let num_extra_constants = src.read_usize()?;
|
||||||
@ -252,7 +252,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for RandomAccessGa
|
|||||||
constraints
|
constraints
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F>> {
|
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F, D>> {
|
||||||
(0..self.num_copies)
|
(0..self.num_copies)
|
||||||
.map(|copy| {
|
.map(|copy| {
|
||||||
WitnessGeneratorRef::new(
|
WitnessGeneratorRef::new(
|
||||||
@ -345,7 +345,7 @@ pub struct RandomAccessGenerator<F: RichField + Extendable<D>, const D: usize> {
|
|||||||
copy: usize,
|
copy: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
|
||||||
for RandomAccessGenerator<F, D>
|
for RandomAccessGenerator<F, D>
|
||||||
{
|
{
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
@ -394,16 +394,16 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.row)?;
|
dst.write_usize(self.row)?;
|
||||||
dst.write_usize(self.copy)?;
|
dst.write_usize(self.copy)?;
|
||||||
self.gate.serialize(dst)
|
self.gate.serialize(dst, _common_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let row = src.read_usize()?;
|
let row = src.read_usize()?;
|
||||||
let copy = src.read_usize()?;
|
let copy = src.read_usize()?;
|
||||||
let gate = RandomAccessGate::<F, D>::deserialize(src)?;
|
let gate = RandomAccessGate::<F, D>::deserialize(src, _common_data)?;
|
||||||
Ok(Self { row, gate, copy })
|
Ok(Self { row, gate, copy })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGeneratorRe
|
|||||||
use crate::iop::target::Target;
|
use crate::iop::target::Target;
|
||||||
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
|
use crate::plonk::circuit_data::CommonCircuitData;
|
||||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||||
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
||||||
|
|
||||||
@ -60,12 +61,12 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ReducingGate<D
|
|||||||
format!("{self:?}")
|
format!("{self:?}")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.num_coeffs)?;
|
dst.write_usize(self.num_coeffs)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self>
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
@ -150,7 +151,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ReducingGate<D
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F>> {
|
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F, D>> {
|
||||||
vec![WitnessGeneratorRef::new(
|
vec![WitnessGeneratorRef::new(
|
||||||
ReducingGenerator {
|
ReducingGenerator {
|
||||||
row,
|
row,
|
||||||
@ -183,7 +184,7 @@ pub struct ReducingGenerator<const D: usize> {
|
|||||||
gate: ReducingGate<D>,
|
gate: ReducingGate<D>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F> for ReducingGenerator<D> {
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for ReducingGenerator<D> {
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
"ReducingGenerator".to_string()
|
"ReducingGenerator".to_string()
|
||||||
}
|
}
|
||||||
@ -225,14 +226,14 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F> for Reduci
|
|||||||
out_buffer.set_extension_target(output, acc);
|
out_buffer.set_extension_target(output, acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.row)?;
|
dst.write_usize(self.row)?;
|
||||||
<ReducingGate<D> as Gate<F, D>>::serialize(&self.gate, dst)
|
<ReducingGate<D> as Gate<F, D>>::serialize(&self.gate, dst, _common_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let row = src.read_usize()?;
|
let row = src.read_usize()?;
|
||||||
let gate = <ReducingGate<D> as Gate<F, D>>::deserialize(src)?;
|
let gate = <ReducingGate<D> as Gate<F, D>>::deserialize(src, _common_data)?;
|
||||||
Ok(Self { row, gate })
|
Ok(Self { row, gate })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGeneratorRe
|
|||||||
use crate::iop::target::Target;
|
use crate::iop::target::Target;
|
||||||
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
|
use crate::plonk::circuit_data::CommonCircuitData;
|
||||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||||
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
||||||
|
|
||||||
@ -63,12 +64,12 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ReducingExtens
|
|||||||
format!("{self:?}")
|
format!("{self:?}")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.num_coeffs)?;
|
dst.write_usize(self.num_coeffs)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self>
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
@ -150,7 +151,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ReducingExtens
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F>> {
|
fn generators(&self, row: usize, _local_constants: &[F]) -> Vec<WitnessGeneratorRef<F, D>> {
|
||||||
vec![WitnessGeneratorRef::new(
|
vec![WitnessGeneratorRef::new(
|
||||||
ReducingGenerator {
|
ReducingGenerator {
|
||||||
row,
|
row,
|
||||||
@ -183,7 +184,7 @@ pub struct ReducingGenerator<const D: usize> {
|
|||||||
gate: ReducingExtensionGate<D>,
|
gate: ReducingExtensionGate<D>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F> for ReducingGenerator<D> {
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for ReducingGenerator<D> {
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
"ReducingExtensionGenerator".to_string()
|
"ReducingExtensionGenerator".to_string()
|
||||||
}
|
}
|
||||||
@ -219,14 +220,14 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F> for Reduci
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.row)?;
|
dst.write_usize(self.row)?;
|
||||||
<ReducingExtensionGate<D> as Gate<F, D>>::serialize(&self.gate, dst)
|
<ReducingExtensionGate<D> as Gate<F, D>>::serialize(&self.gate, dst, _common_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let row = src.read_usize()?;
|
let row = src.read_usize()?;
|
||||||
let gate = <ReducingExtensionGate<D> as Gate<F, D>>::deserialize(src)?;
|
let gate = <ReducingExtensionGate<D> as Gate<F, D>>::deserialize(src, _common_data)?;
|
||||||
Ok(Self { row, gate })
|
Ok(Self { row, gate })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -98,7 +98,9 @@ pub(crate) fn generate_partial_witness<
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A generator participates in the generation of the witness.
|
/// A generator participates in the generation of the witness.
|
||||||
pub trait WitnessGenerator<F: Field>: 'static + Send + Sync + Debug {
|
pub trait WitnessGenerator<F: RichField + Extendable<D>, const D: usize>:
|
||||||
|
'static + Send + Sync + Debug
|
||||||
|
{
|
||||||
fn id(&self) -> String;
|
fn id(&self) -> String;
|
||||||
|
|
||||||
/// Targets to be "watched" by this generator. Whenever a target in the watch list is populated,
|
/// Targets to be "watched" by this generator. Whenever a target in the watch list is populated,
|
||||||
@ -110,32 +112,34 @@ pub trait WitnessGenerator<F: Field>: 'static + Send + Sync + Debug {
|
|||||||
/// run next time a target in its watch list is populated.
|
/// run next time a target in its watch list is populated.
|
||||||
fn run(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) -> bool;
|
fn run(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) -> bool;
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()>;
|
fn serialize(&self, dst: &mut Vec<u8>, common_data: &CommonCircuitData<F, D>) -> IoResult<()>;
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self>
|
fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData<F, D>) -> IoResult<Self>
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A wrapper around an `Box<WitnessGenerator>` which implements `PartialEq`
|
/// A wrapper around an `Box<WitnessGenerator>` which implements `PartialEq`
|
||||||
/// and `Eq` based on generator IDs.
|
/// and `Eq` based on generator IDs.
|
||||||
pub struct WitnessGeneratorRef<F: Field>(pub Box<dyn WitnessGenerator<F>>);
|
pub struct WitnessGeneratorRef<F: RichField + Extendable<D>, const D: usize>(
|
||||||
|
pub Box<dyn WitnessGenerator<F, D>>,
|
||||||
|
);
|
||||||
|
|
||||||
impl<F: Field> WitnessGeneratorRef<F> {
|
impl<F: RichField + Extendable<D>, const D: usize> WitnessGeneratorRef<F, D> {
|
||||||
pub fn new<G: WitnessGenerator<F>>(generator: G) -> WitnessGeneratorRef<F> {
|
pub fn new<G: WitnessGenerator<F, D>>(generator: G) -> WitnessGeneratorRef<F, D> {
|
||||||
WitnessGeneratorRef(Box::new(generator))
|
WitnessGeneratorRef(Box::new(generator))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Field> PartialEq for WitnessGeneratorRef<F> {
|
impl<F: RichField + Extendable<D>, const D: usize> PartialEq for WitnessGeneratorRef<F, D> {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.0.id() == other.0.id()
|
self.0.id() == other.0.id()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Field> Eq for WitnessGeneratorRef<F> {}
|
impl<F: RichField + Extendable<D>, const D: usize> Eq for WitnessGeneratorRef<F, D> {}
|
||||||
|
|
||||||
impl<F: Field> Debug for WitnessGeneratorRef<F> {
|
impl<F: RichField + Extendable<D>, const D: usize> Debug for WitnessGeneratorRef<F, D> {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
write!(f, "{}", self.0.id())
|
write!(f, "{}", self.0.id())
|
||||||
}
|
}
|
||||||
@ -190,14 +194,16 @@ impl<F: Field> GeneratedValues<F> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A generator which runs once after a list of dependencies is present in the witness.
|
/// A generator which runs once after a list of dependencies is present in the witness.
|
||||||
pub trait SimpleGenerator<F: Field>: 'static + Send + Sync + Debug {
|
pub trait SimpleGenerator<F: RichField + Extendable<D>, const D: usize>:
|
||||||
|
'static + Send + Sync + Debug
|
||||||
|
{
|
||||||
fn id(&self) -> String;
|
fn id(&self) -> String;
|
||||||
|
|
||||||
fn dependencies(&self) -> Vec<Target>;
|
fn dependencies(&self) -> Vec<Target>;
|
||||||
|
|
||||||
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>);
|
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>);
|
||||||
|
|
||||||
fn adapter(self) -> SimpleGeneratorAdapter<F, Self>
|
fn adapter(self) -> SimpleGeneratorAdapter<F, Self, D>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
@ -207,20 +213,26 @@ pub trait SimpleGenerator<F: Field>: 'static + Send + Sync + Debug {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()>;
|
fn serialize(&self, dst: &mut Vec<u8>, common_data: &CommonCircuitData<F, D>) -> IoResult<()>;
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self>
|
fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData<F, D>) -> IoResult<Self>
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SimpleGeneratorAdapter<F: Field, SG: SimpleGenerator<F> + ?Sized> {
|
pub struct SimpleGeneratorAdapter<
|
||||||
|
F: RichField + Extendable<D>,
|
||||||
|
SG: SimpleGenerator<F, D> + ?Sized,
|
||||||
|
const D: usize,
|
||||||
|
> {
|
||||||
_phantom: PhantomData<F>,
|
_phantom: PhantomData<F>,
|
||||||
inner: SG,
|
inner: SG,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Field, SG: SimpleGenerator<F>> WitnessGenerator<F> for SimpleGeneratorAdapter<F, SG> {
|
impl<F: RichField + Extendable<D>, SG: SimpleGenerator<F, D>, const D: usize> WitnessGenerator<F, D>
|
||||||
|
for SimpleGeneratorAdapter<F, SG, D>
|
||||||
|
{
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
self.inner.id()
|
self.inner.id()
|
||||||
}
|
}
|
||||||
@ -238,13 +250,13 @@ impl<F: Field, SG: SimpleGenerator<F>> WitnessGenerator<F> for SimpleGeneratorAd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
self.inner.serialize(dst)
|
self.inner.serialize(dst, common_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
inner: SG::deserialize(src)?,
|
inner: SG::deserialize(src, common_data)?,
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -257,7 +269,7 @@ pub struct CopyGenerator {
|
|||||||
pub(crate) dst: Target,
|
pub(crate) dst: Target,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Field> SimpleGenerator<F> for CopyGenerator {
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for CopyGenerator {
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
"CopyGenerator".to_string()
|
"CopyGenerator".to_string()
|
||||||
}
|
}
|
||||||
@ -271,12 +283,12 @@ impl<F: Field> SimpleGenerator<F> for CopyGenerator {
|
|||||||
out_buffer.set_target(self.dst, value);
|
out_buffer.set_target(self.dst, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_target(self.src)?;
|
dst.write_target(self.src)?;
|
||||||
dst.write_target(self.dst)
|
dst.write_target(self.dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(source: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(source: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let src = source.read_target()?;
|
let src = source.read_target()?;
|
||||||
let dst = source.read_target()?;
|
let dst = source.read_target()?;
|
||||||
Ok(Self { src, dst })
|
Ok(Self { src, dst })
|
||||||
@ -289,7 +301,7 @@ pub struct RandomValueGenerator {
|
|||||||
pub(crate) target: Target,
|
pub(crate) target: Target,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Field> SimpleGenerator<F> for RandomValueGenerator {
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for RandomValueGenerator {
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
"RandomValueGenerator".to_string()
|
"RandomValueGenerator".to_string()
|
||||||
}
|
}
|
||||||
@ -303,11 +315,11 @@ impl<F: Field> SimpleGenerator<F> for RandomValueGenerator {
|
|||||||
out_buffer.set_target(self.target, random_value);
|
out_buffer.set_target(self.target, random_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_target(self.target)
|
dst.write_target(self.target)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let target = src.read_target()?;
|
let target = src.read_target()?;
|
||||||
Ok(Self { target })
|
Ok(Self { target })
|
||||||
}
|
}
|
||||||
@ -320,7 +332,7 @@ pub struct NonzeroTestGenerator {
|
|||||||
pub(crate) dummy: Target,
|
pub(crate) dummy: Target,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Field> SimpleGenerator<F> for NonzeroTestGenerator {
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for NonzeroTestGenerator {
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
"NonzeroTestGenerator".to_string()
|
"NonzeroTestGenerator".to_string()
|
||||||
}
|
}
|
||||||
@ -341,12 +353,12 @@ impl<F: Field> SimpleGenerator<F> for NonzeroTestGenerator {
|
|||||||
out_buffer.set_target(self.dummy, dummy_value);
|
out_buffer.set_target(self.dummy, dummy_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_target(self.to_test)?;
|
dst.write_target(self.to_test)?;
|
||||||
dst.write_target(self.dummy)
|
dst.write_target(self.dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let to_test = src.read_target()?;
|
let to_test = src.read_target()?;
|
||||||
let dummy = src.read_target()?;
|
let dummy = src.read_target()?;
|
||||||
Ok(Self { to_test, dummy })
|
Ok(Self { to_test, dummy })
|
||||||
@ -368,7 +380,7 @@ impl<F: Field> ConstantGenerator<F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField> SimpleGenerator<F> for ConstantGenerator<F> {
|
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for ConstantGenerator<F> {
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
"ConstantGenerator".to_string()
|
"ConstantGenerator".to_string()
|
||||||
}
|
}
|
||||||
@ -381,14 +393,14 @@ impl<F: RichField> SimpleGenerator<F> for ConstantGenerator<F> {
|
|||||||
out_buffer.set_target(Target::wire(self.row, self.wire_index), self.constant);
|
out_buffer.set_target(Target::wire(self.row, self.wire_index), self.constant);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_usize(self.row)?;
|
dst.write_usize(self.row)?;
|
||||||
dst.write_usize(self.constant_index)?;
|
dst.write_usize(self.constant_index)?;
|
||||||
dst.write_usize(self.wire_index)?;
|
dst.write_usize(self.wire_index)?;
|
||||||
dst.write_field(self.constant)
|
dst.write_field(self.constant)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
let row = src.read_usize()?;
|
let row = src.read_usize()?;
|
||||||
let constant_index = src.read_usize()?;
|
let constant_index = src.read_usize()?;
|
||||||
let wire_index = src.read_usize()?;
|
let wire_index = src.read_usize()?;
|
||||||
|
|||||||
@ -109,7 +109,7 @@ pub struct CircuitBuilder<F: RichField + Extendable<D>, const D: usize> {
|
|||||||
context_log: ContextTree,
|
context_log: ContextTree,
|
||||||
|
|
||||||
/// Generators used to generate the witness.
|
/// Generators used to generate the witness.
|
||||||
generators: Vec<WitnessGeneratorRef<F>>,
|
generators: Vec<WitnessGeneratorRef<F, D>>,
|
||||||
|
|
||||||
constants_to_targets: HashMap<F, Target>,
|
constants_to_targets: HashMap<F, Target>,
|
||||||
targets_to_constants: HashMap<Target, F>,
|
targets_to_constants: HashMap<Target, F>,
|
||||||
@ -444,11 +444,11 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
|||||||
self.connect(x, one);
|
self.connect(x, one);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_generators(&mut self, generators: Vec<WitnessGeneratorRef<F>>) {
|
pub fn add_generators(&mut self, generators: Vec<WitnessGeneratorRef<F, D>>) {
|
||||||
self.generators.extend(generators);
|
self.generators.extend(generators);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_simple_generator<G: SimpleGenerator<F>>(&mut self, generator: G) {
|
pub fn add_simple_generator<G: SimpleGenerator<F, D>>(&mut self, generator: G) {
|
||||||
self.generators
|
self.generators
|
||||||
.push(WitnessGeneratorRef::new(generator.adapter()));
|
.push(WitnessGeneratorRef::new(generator.adapter()));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -295,7 +295,7 @@ pub struct ProverOnlyCircuitData<
|
|||||||
C: GenericConfig<D, F = F>,
|
C: GenericConfig<D, F = F>,
|
||||||
const D: usize,
|
const D: usize,
|
||||||
> {
|
> {
|
||||||
pub generators: Vec<WitnessGeneratorRef<F>>,
|
pub generators: Vec<WitnessGeneratorRef<F, D>>,
|
||||||
/// Generator indices (within the `Vec` above), indexed by the representative of each target
|
/// Generator indices (within the `Vec` above), indexed by the representative of each target
|
||||||
/// they watch.
|
/// they watch.
|
||||||
pub generator_indices_by_watches: BTreeMap<usize, Vec<usize>>,
|
pub generator_indices_by_watches: BTreeMap<usize, Vec<usize>>,
|
||||||
@ -321,6 +321,29 @@ pub struct ProverOnlyCircuitData<
|
|||||||
pub lut_to_lookups: Vec<Lookup>,
|
pub lut_to_lookups: Vec<Lookup>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
|
||||||
|
ProverOnlyCircuitData<F, C, D>
|
||||||
|
{
|
||||||
|
pub fn to_bytes(
|
||||||
|
&self,
|
||||||
|
generator_serializer: &dyn WitnessGeneratorSerializer<F, D>,
|
||||||
|
common_data: &CommonCircuitData<F, D>,
|
||||||
|
) -> IoResult<Vec<u8>> {
|
||||||
|
let mut buffer = Vec::new();
|
||||||
|
buffer.write_prover_only_circuit_data(self, generator_serializer, common_data)?;
|
||||||
|
Ok(buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_bytes(
|
||||||
|
bytes: &[u8],
|
||||||
|
generator_serializer: &dyn WitnessGeneratorSerializer<F, D>,
|
||||||
|
common_data: &CommonCircuitData<F, D>,
|
||||||
|
) -> IoResult<Self> {
|
||||||
|
let mut buffer = Buffer::new(bytes);
|
||||||
|
buffer.read_prover_only_circuit_data(generator_serializer, common_data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Circuit data required by the verifier, but not the prover.
|
/// Circuit data required by the verifier, but not the prover.
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
|
#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
|
||||||
pub struct VerifierOnlyCircuitData<C: GenericConfig<D>, const D: usize> {
|
pub struct VerifierOnlyCircuitData<C: GenericConfig<D>, const D: usize> {
|
||||||
|
|||||||
@ -80,15 +80,14 @@ pub fn set_lookup_wires<
|
|||||||
let remaining_slots = (num_entries
|
let remaining_slots = (num_entries
|
||||||
- (prover_data.lut_to_lookups[lut_index].len() % num_entries))
|
- (prover_data.lut_to_lookups[lut_index].len() % num_entries))
|
||||||
% num_entries;
|
% num_entries;
|
||||||
let first_inp_value = F::from_canonical_u16(common_data.luts[lut_index][0].0);
|
let (first_inp_value, first_out_value) = common_data.luts[lut_index][0];
|
||||||
let first_out_value = F::from_canonical_u16(common_data.luts[lut_index][0].1);
|
|
||||||
for slot in (num_entries - remaining_slots)..num_entries {
|
for slot in (num_entries - remaining_slots)..num_entries {
|
||||||
let inp_target =
|
let inp_target =
|
||||||
Target::wire(last_lut_gate - 1, LookupGate::wire_ith_looking_inp(slot));
|
Target::wire(last_lut_gate - 1, LookupGate::wire_ith_looking_inp(slot));
|
||||||
let out_target =
|
let out_target =
|
||||||
Target::wire(last_lut_gate - 1, LookupGate::wire_ith_looking_out(slot));
|
Target::wire(last_lut_gate - 1, LookupGate::wire_ith_looking_out(slot));
|
||||||
pw.set_target(inp_target, first_inp_value);
|
pw.set_target(inp_target, F::from_canonical_u16(first_inp_value));
|
||||||
pw.set_target(out_target, first_out_value);
|
pw.set_target(out_target, F::from_canonical_u16(first_out_value));
|
||||||
|
|
||||||
multiplicities[0] += 1;
|
multiplicities[0] += 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,11 +37,8 @@ pub(crate) fn get_lut_poly<F: RichField + Extendable<D>, const D: usize>(
|
|||||||
let b = deltas[LookupChallenges::ChallengeB as usize];
|
let b = deltas[LookupChallenges::ChallengeB as usize];
|
||||||
let mut coeffs = Vec::new();
|
let mut coeffs = Vec::new();
|
||||||
let n = common_data.luts[lut_index].len();
|
let n = common_data.luts[lut_index].len();
|
||||||
for i in 0..n {
|
for (input, output) in common_data.luts[lut_index].iter() {
|
||||||
coeffs.push(
|
coeffs.push(F::from_canonical_u16(*input) + b * F::from_canonical_u16(*output));
|
||||||
F::from_canonical_u16(common_data.luts[lut_index][i].0)
|
|
||||||
+ b * F::from_canonical_u16(common_data.luts[lut_index][i].1),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
coeffs.append(&mut vec![F::ZERO; degree - n]);
|
coeffs.append(&mut vec![F::ZERO; degree - n]);
|
||||||
coeffs.reverse();
|
coeffs.reverse();
|
||||||
@ -760,14 +757,11 @@ pub(crate) fn get_lut_poly_circuit<F: RichField + Extendable<D>, const D: usize>
|
|||||||
let b = deltas[LookupChallenges::ChallengeB as usize];
|
let b = deltas[LookupChallenges::ChallengeB as usize];
|
||||||
let delta = deltas[LookupChallenges::ChallengeDelta as usize];
|
let delta = deltas[LookupChallenges::ChallengeDelta as usize];
|
||||||
let n = common_data.luts[lut_index].len();
|
let n = common_data.luts[lut_index].len();
|
||||||
let mut coeffs: Vec<Target> = (0..n)
|
let mut coeffs: Vec<Target> = common_data.luts[lut_index]
|
||||||
.map(|i| {
|
.iter()
|
||||||
let temp =
|
.map(|(input, output)| {
|
||||||
builder.mul_const(F::from_canonical_u16(common_data.luts[lut_index][i].1), b);
|
let temp = builder.mul_const(F::from_canonical_u16(*output), b);
|
||||||
builder.add_const(
|
builder.add_const(temp, F::from_canonical_u16(*input))
|
||||||
temp,
|
|
||||||
F::from_canonical_u16(common_data.luts[lut_index][i].0),
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
for _ in n..degree {
|
for _ in n..degree {
|
||||||
|
|||||||
@ -215,30 +215,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, C, const D: usize> DummyProofGenerator<F, C, D>
|
impl<F, C, const D: usize> SimpleGenerator<F, D> for DummyProofGenerator<F, C, D>
|
||||||
where
|
|
||||||
F: RichField + Extendable<D>,
|
|
||||||
C: GenericConfig<D, F = F> + 'static,
|
|
||||||
C::Hasher: AlgebraicHasher<F>,
|
|
||||||
{
|
|
||||||
pub fn deserialize_with_circuit_data(
|
|
||||||
src: &mut Buffer,
|
|
||||||
cd: &CommonCircuitData<F, D>,
|
|
||||||
) -> IoResult<Self> {
|
|
||||||
let proof_with_pis_target = src.read_target_proof_with_public_inputs()?;
|
|
||||||
let proof_with_pis = src.read_proof_with_public_inputs(cd)?;
|
|
||||||
let verifier_data_target = src.read_target_verifier_circuit()?;
|
|
||||||
let verifier_data = src.read_verifier_only_circuit_data()?;
|
|
||||||
Ok(Self {
|
|
||||||
proof_with_pis_target,
|
|
||||||
proof_with_pis,
|
|
||||||
verifier_data_target,
|
|
||||||
verifier_data,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<F, C, const D: usize> SimpleGenerator<F> for DummyProofGenerator<F, C, D>
|
|
||||||
where
|
where
|
||||||
F: RichField + Extendable<D>,
|
F: RichField + Extendable<D>,
|
||||||
C: GenericConfig<D, F = F> + 'static,
|
C: GenericConfig<D, F = F> + 'static,
|
||||||
@ -257,14 +234,23 @@ where
|
|||||||
out_buffer.set_verifier_data_target(&self.verifier_data_target, &self.verifier_data);
|
out_buffer.set_verifier_data_target(&self.verifier_data_target, &self.verifier_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
|
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||||
dst.write_target_proof_with_public_inputs(&self.proof_with_pis_target)?;
|
dst.write_target_proof_with_public_inputs(&self.proof_with_pis_target)?;
|
||||||
dst.write_proof_with_public_inputs(&self.proof_with_pis)?;
|
dst.write_proof_with_public_inputs(&self.proof_with_pis)?;
|
||||||
dst.write_target_verifier_circuit(&self.verifier_data_target)?;
|
dst.write_target_verifier_circuit(&self.verifier_data_target)?;
|
||||||
dst.write_verifier_only_circuit_data(&self.verifier_data)
|
dst.write_verifier_only_circuit_data(&self.verifier_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(_src: &mut Buffer) -> IoResult<Self> {
|
fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||||
panic!()
|
let proof_with_pis_target = src.read_target_proof_with_public_inputs()?;
|
||||||
|
let proof_with_pis = src.read_proof_with_public_inputs(common_data)?;
|
||||||
|
let verifier_data_target = src.read_target_verifier_circuit()?;
|
||||||
|
let verifier_data = src.read_verifier_only_circuit_data()?;
|
||||||
|
Ok(Self {
|
||||||
|
proof_with_pis_target,
|
||||||
|
proof_with_pis,
|
||||||
|
verifier_data_target,
|
||||||
|
verifier_data,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -218,10 +218,10 @@ mod tests {
|
|||||||
type F = <C as GenericConfig<D>>::F;
|
type F = <C as GenericConfig<D>>::F;
|
||||||
let config = CircuitConfig::standard_recursion_zk_config();
|
let config = CircuitConfig::standard_recursion_zk_config();
|
||||||
|
|
||||||
let (proof, vd, cd) = dummy_proof::<F, C, D>(&config, 4_000)?;
|
let (proof, vd, common_data) = dummy_proof::<F, C, D>(&config, 4_000)?;
|
||||||
let (proof, vd, cd) =
|
let (proof, vd, common_data) =
|
||||||
recursive_proof::<F, C, C, D>(proof, vd, cd, &config, None, true, true)?;
|
recursive_proof::<F, C, C, D>(proof, vd, common_data, &config, None, true, true)?;
|
||||||
test_serialization(&proof, &vd, &cd)?;
|
test_serialization(&proof, &vd, &common_data)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -234,10 +234,10 @@ mod tests {
|
|||||||
type F = <C as GenericConfig<D>>::F;
|
type F = <C as GenericConfig<D>>::F;
|
||||||
let config = CircuitConfig::standard_recursion_zk_config();
|
let config = CircuitConfig::standard_recursion_zk_config();
|
||||||
|
|
||||||
let (proof, vd, cd) = dummy_lookup_proof::<F, C, D>(&config, 10)?;
|
let (proof, vd, common_data) = dummy_lookup_proof::<F, C, D>(&config, 10)?;
|
||||||
let (proof, vd, cd) =
|
let (proof, vd, common_data) =
|
||||||
recursive_proof::<F, C, C, D>(proof, vd, cd, &config, None, true, true)?;
|
recursive_proof::<F, C, C, D>(proof, vd, common_data, &config, None, true, true)?;
|
||||||
test_serialization(&proof, &vd, &cd)?;
|
test_serialization(&proof, &vd, &common_data)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -250,10 +250,10 @@ mod tests {
|
|||||||
type F = <C as GenericConfig<D>>::F;
|
type F = <C as GenericConfig<D>>::F;
|
||||||
let config = CircuitConfig::standard_recursion_config();
|
let config = CircuitConfig::standard_recursion_config();
|
||||||
|
|
||||||
let (proof, vd, cd) = dummy_two_luts_proof::<F, C, D>(&config)?;
|
let (proof, vd, common_data) = dummy_two_luts_proof::<F, C, D>(&config)?;
|
||||||
let (proof, vd, cd) =
|
let (proof, vd, common_data) =
|
||||||
recursive_proof::<F, C, C, D>(proof, vd, cd, &config, None, true, true)?;
|
recursive_proof::<F, C, C, D>(proof, vd, common_data, &config, None, true, true)?;
|
||||||
test_serialization(&proof, &vd, &cd)?;
|
test_serialization(&proof, &vd, &common_data)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -266,10 +266,10 @@ mod tests {
|
|||||||
type F = <C as GenericConfig<D>>::F;
|
type F = <C as GenericConfig<D>>::F;
|
||||||
let config = CircuitConfig::standard_recursion_config();
|
let config = CircuitConfig::standard_recursion_config();
|
||||||
|
|
||||||
let (proof, vd, cd) = dummy_too_many_rows_proof::<F, C, D>(&config)?;
|
let (proof, vd, common_data) = dummy_too_many_rows_proof::<F, C, D>(&config)?;
|
||||||
let (proof, vd, cd) =
|
let (proof, vd, common_data) =
|
||||||
recursive_proof::<F, C, C, D>(proof, vd, cd, &config, None, true, true)?;
|
recursive_proof::<F, C, C, D>(proof, vd, common_data, &config, None, true, true)?;
|
||||||
test_serialization(&proof, &vd, &cd)?;
|
test_serialization(&proof, &vd, &common_data)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -284,20 +284,20 @@ mod tests {
|
|||||||
let config = CircuitConfig::standard_recursion_config();
|
let config = CircuitConfig::standard_recursion_config();
|
||||||
|
|
||||||
// Start with a degree 2^14 proof
|
// Start with a degree 2^14 proof
|
||||||
let (proof, vd, cd) = dummy_proof::<F, C, D>(&config, 16_000)?;
|
let (proof, vd, common_data) = dummy_proof::<F, C, D>(&config, 16_000)?;
|
||||||
assert_eq!(cd.degree_bits(), 14);
|
assert_eq!(common_data.degree_bits(), 14);
|
||||||
|
|
||||||
// Shrink it to 2^13.
|
// Shrink it to 2^13.
|
||||||
let (proof, vd, cd) =
|
let (proof, vd, common_data) =
|
||||||
recursive_proof::<F, C, C, D>(proof, vd, cd, &config, Some(13), false, false)?;
|
recursive_proof::<F, C, C, D>(proof, vd, common_data, &config, Some(13), false, false)?;
|
||||||
assert_eq!(cd.degree_bits(), 13);
|
assert_eq!(common_data.degree_bits(), 13);
|
||||||
|
|
||||||
// Shrink it to 2^12.
|
// Shrink it to 2^12.
|
||||||
let (proof, vd, cd) =
|
let (proof, vd, common_data) =
|
||||||
recursive_proof::<F, C, C, D>(proof, vd, cd, &config, None, true, true)?;
|
recursive_proof::<F, C, C, D>(proof, vd, common_data, &config, None, true, true)?;
|
||||||
assert_eq!(cd.degree_bits(), 12);
|
assert_eq!(common_data.degree_bits(), 12);
|
||||||
|
|
||||||
test_serialization(&proof, &vd, &cd)?;
|
test_serialization(&proof, &vd, &common_data)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -316,13 +316,20 @@ mod tests {
|
|||||||
let standard_config = CircuitConfig::standard_recursion_config();
|
let standard_config = CircuitConfig::standard_recursion_config();
|
||||||
|
|
||||||
// An initial dummy proof.
|
// An initial dummy proof.
|
||||||
let (proof, vd, cd) = dummy_proof::<F, C, D>(&standard_config, 4_000)?;
|
let (proof, vd, common_data) = dummy_proof::<F, C, D>(&standard_config, 4_000)?;
|
||||||
assert_eq!(cd.degree_bits(), 12);
|
assert_eq!(common_data.degree_bits(), 12);
|
||||||
|
|
||||||
// A standard recursive proof.
|
// A standard recursive proof.
|
||||||
let (proof, vd, cd) =
|
let (proof, vd, common_data) = recursive_proof::<F, C, C, D>(
|
||||||
recursive_proof::<F, C, C, D>(proof, vd, cd, &standard_config, None, false, false)?;
|
proof,
|
||||||
assert_eq!(cd.degree_bits(), 12);
|
vd,
|
||||||
|
common_data,
|
||||||
|
&standard_config,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
)?;
|
||||||
|
assert_eq!(common_data.degree_bits(), 12);
|
||||||
|
|
||||||
// A high-rate recursive proof, designed to be verifiable with fewer routed wires.
|
// A high-rate recursive proof, designed to be verifiable with fewer routed wires.
|
||||||
let high_rate_config = CircuitConfig {
|
let high_rate_config = CircuitConfig {
|
||||||
@ -334,9 +341,16 @@ mod tests {
|
|||||||
},
|
},
|
||||||
..standard_config
|
..standard_config
|
||||||
};
|
};
|
||||||
let (proof, vd, cd) =
|
let (proof, vd, common_data) = recursive_proof::<F, C, C, D>(
|
||||||
recursive_proof::<F, C, C, D>(proof, vd, cd, &high_rate_config, None, true, true)?;
|
proof,
|
||||||
assert_eq!(cd.degree_bits(), 12);
|
vd,
|
||||||
|
common_data,
|
||||||
|
&high_rate_config,
|
||||||
|
None,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
)?;
|
||||||
|
assert_eq!(common_data.degree_bits(), 12);
|
||||||
|
|
||||||
// A final proof, optimized for size.
|
// A final proof, optimized for size.
|
||||||
let final_config = CircuitConfig {
|
let final_config = CircuitConfig {
|
||||||
@ -350,11 +364,18 @@ mod tests {
|
|||||||
},
|
},
|
||||||
..high_rate_config
|
..high_rate_config
|
||||||
};
|
};
|
||||||
let (proof, vd, cd) =
|
let (proof, vd, common_data) = recursive_proof::<F, KC, C, D>(
|
||||||
recursive_proof::<F, KC, C, D>(proof, vd, cd, &final_config, None, true, true)?;
|
proof,
|
||||||
assert_eq!(cd.degree_bits(), 12, "final proof too large");
|
vd,
|
||||||
|
common_data,
|
||||||
|
&final_config,
|
||||||
|
None,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
)?;
|
||||||
|
assert_eq!(common_data.degree_bits(), 12, "final proof too large");
|
||||||
|
|
||||||
test_serialization(&proof, &vd, &cd)?;
|
test_serialization(&proof, &vd, &common_data)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -368,15 +389,15 @@ mod tests {
|
|||||||
type F = <PC as GenericConfig<D>>::F;
|
type F = <PC as GenericConfig<D>>::F;
|
||||||
|
|
||||||
let config = CircuitConfig::standard_recursion_config();
|
let config = CircuitConfig::standard_recursion_config();
|
||||||
let (proof, vd, cd) = dummy_proof::<F, PC, D>(&config, 4_000)?;
|
let (proof, vd, common_data) = dummy_proof::<F, PC, D>(&config, 4_000)?;
|
||||||
|
|
||||||
let (proof, vd, cd) =
|
let (proof, vd, common_data) =
|
||||||
recursive_proof::<F, PC, PC, D>(proof, vd, cd, &config, None, false, false)?;
|
recursive_proof::<F, PC, PC, D>(proof, vd, common_data, &config, None, false, false)?;
|
||||||
test_serialization(&proof, &vd, &cd)?;
|
test_serialization(&proof, &vd, &common_data)?;
|
||||||
|
|
||||||
let (proof, vd, cd) =
|
let (proof, vd, common_data) =
|
||||||
recursive_proof::<F, KC, PC, D>(proof, vd, cd, &config, None, false, false)?;
|
recursive_proof::<F, KC, PC, D>(proof, vd, common_data, &config, None, false, false)?;
|
||||||
test_serialization(&proof, &vd, &cd)?;
|
test_serialization(&proof, &vd, &common_data)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -662,18 +683,18 @@ mod tests {
|
|||||||
>(
|
>(
|
||||||
proof: &ProofWithPublicInputs<F, C, D>,
|
proof: &ProofWithPublicInputs<F, C, D>,
|
||||||
vd: &VerifierOnlyCircuitData<C, D>,
|
vd: &VerifierOnlyCircuitData<C, D>,
|
||||||
cd: &CommonCircuitData<F, D>,
|
common_data: &CommonCircuitData<F, D>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let proof_bytes = proof.to_bytes();
|
let proof_bytes = proof.to_bytes();
|
||||||
info!("Proof length: {} bytes", proof_bytes.len());
|
info!("Proof length: {} bytes", proof_bytes.len());
|
||||||
let proof_from_bytes = ProofWithPublicInputs::from_bytes(proof_bytes, cd)?;
|
let proof_from_bytes = ProofWithPublicInputs::from_bytes(proof_bytes, common_data)?;
|
||||||
assert_eq!(proof, &proof_from_bytes);
|
assert_eq!(proof, &proof_from_bytes);
|
||||||
|
|
||||||
let now = std::time::Instant::now();
|
let now = std::time::Instant::now();
|
||||||
let compressed_proof = proof.clone().compress(&vd.circuit_digest, cd)?;
|
let compressed_proof = proof.clone().compress(&vd.circuit_digest, common_data)?;
|
||||||
let decompressed_compressed_proof = compressed_proof
|
let decompressed_compressed_proof = compressed_proof
|
||||||
.clone()
|
.clone()
|
||||||
.decompress(&vd.circuit_digest, cd)?;
|
.decompress(&vd.circuit_digest, common_data)?;
|
||||||
info!("{:.4}s to compress proof", now.elapsed().as_secs_f64());
|
info!("{:.4}s to compress proof", now.elapsed().as_secs_f64());
|
||||||
assert_eq!(proof, &decompressed_compressed_proof);
|
assert_eq!(proof, &decompressed_compressed_proof);
|
||||||
|
|
||||||
@ -683,7 +704,7 @@ mod tests {
|
|||||||
compressed_proof_bytes.len()
|
compressed_proof_bytes.len()
|
||||||
);
|
);
|
||||||
let compressed_proof_from_bytes =
|
let compressed_proof_from_bytes =
|
||||||
CompressedProofWithPublicInputs::from_bytes(compressed_proof_bytes, cd)?;
|
CompressedProofWithPublicInputs::from_bytes(compressed_proof_bytes, common_data)?;
|
||||||
assert_eq!(compressed_proof, compressed_proof_from_bytes);
|
assert_eq!(compressed_proof, compressed_proof_from_bytes);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@ -2,21 +2,31 @@ use plonky2_field::extension::Extendable;
|
|||||||
|
|
||||||
use crate::gates::gate::GateRef;
|
use crate::gates::gate::GateRef;
|
||||||
use crate::hash::hash_types::RichField;
|
use crate::hash::hash_types::RichField;
|
||||||
|
use crate::plonk::circuit_data::CommonCircuitData;
|
||||||
use crate::util::serialization::{Buffer, IoResult};
|
use crate::util::serialization::{Buffer, IoResult};
|
||||||
|
|
||||||
pub trait GateSerializer<F: RichField + Extendable<D>, const D: usize> {
|
pub trait GateSerializer<F: RichField + Extendable<D>, const D: usize> {
|
||||||
fn read_gate(&self, buf: &mut Buffer) -> IoResult<GateRef<F, D>>;
|
fn read_gate(
|
||||||
fn write_gate(&self, buf: &mut Vec<u8>, gate: &GateRef<F, D>) -> IoResult<()>;
|
&self,
|
||||||
|
buf: &mut Buffer,
|
||||||
|
common_data: &CommonCircuitData<F, D>,
|
||||||
|
) -> IoResult<GateRef<F, D>>;
|
||||||
|
fn write_gate(
|
||||||
|
&self,
|
||||||
|
buf: &mut Vec<u8>,
|
||||||
|
gate: &GateRef<F, D>,
|
||||||
|
common_data: &CommonCircuitData<F, D>,
|
||||||
|
) -> IoResult<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! read_gate_impl {
|
macro_rules! read_gate_impl {
|
||||||
($buf:expr, $tag:expr, $($gate_types:ty),+) => {{
|
($buf:expr, $tag:expr, $common:expr, $($gate_types:ty),+) => {{
|
||||||
let tag = $tag;
|
let tag = $tag;
|
||||||
let buf = $buf;
|
let buf = $buf;
|
||||||
let mut i = 0..;
|
let mut i = 0..;
|
||||||
$(if tag == i.next().unwrap() {
|
$(if tag == i.next().unwrap() {
|
||||||
let gate = <$gate_types as $crate::gates::gate::Gate<F, D>>::deserialize(buf)?;
|
let gate = <$gate_types as $crate::gates::gate::Gate<F, D>>::deserialize(buf, $common)?;
|
||||||
Ok($crate::gates::gate::GateRef::<F, D>::new(gate))
|
Ok($crate::gates::gate::GateRef::<F, D>::new(gate))
|
||||||
} else)*
|
} else)*
|
||||||
{
|
{
|
||||||
@ -47,16 +57,25 @@ macro_rules! get_gate_tag_impl {
|
|||||||
/// this as first argument, followed by all the targeted gates.
|
/// this as first argument, followed by all the targeted gates.
|
||||||
macro_rules! impl_gate_serializer {
|
macro_rules! impl_gate_serializer {
|
||||||
($target:ty, $($gate_types:ty),+) => {
|
($target:ty, $($gate_types:ty),+) => {
|
||||||
fn read_gate(&self, buf: &mut $crate::util::serialization::Buffer) -> $crate::util::serialization::IoResult<$crate::gates::gate::GateRef<F, D>> {
|
fn read_gate(
|
||||||
|
&self,
|
||||||
|
buf: &mut $crate::util::serialization::Buffer,
|
||||||
|
common: &$crate::plonk::circuit_data::CommonCircuitData<F, D>,
|
||||||
|
) -> $crate::util::serialization::IoResult<$crate::gates::gate::GateRef<F, D>> {
|
||||||
let tag = $crate::util::serialization::Read::read_u32(buf)?;
|
let tag = $crate::util::serialization::Read::read_u32(buf)?;
|
||||||
read_gate_impl!(buf, tag, $($gate_types),+)
|
read_gate_impl!(buf, tag, common, $($gate_types),+)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_gate(&self, buf: &mut Vec<u8>, gate: &$crate::gates::gate::GateRef<F, D>) -> $crate::util::serialization::IoResult<()> {
|
fn write_gate(
|
||||||
|
&self,
|
||||||
|
buf: &mut Vec<u8>,
|
||||||
|
gate: &$crate::gates::gate::GateRef<F, D>,
|
||||||
|
common: &$crate::plonk::circuit_data::CommonCircuitData<F, D>,
|
||||||
|
) -> $crate::util::serialization::IoResult<()> {
|
||||||
let tag = get_gate_tag_impl!(gate, $($gate_types),+)?;
|
let tag = get_gate_tag_impl!(gate, $($gate_types),+)?;
|
||||||
|
|
||||||
$crate::util::serialization::Write::write_u32(buf, tag)?;
|
$crate::util::serialization::Write::write_u32(buf, tag)?;
|
||||||
gate.0.serialize(buf)?;
|
gate.0.serialize(buf, common)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -11,12 +11,14 @@ pub trait WitnessGeneratorSerializer<F: RichField + Extendable<D>, const D: usiz
|
|||||||
fn read_generator(
|
fn read_generator(
|
||||||
&self,
|
&self,
|
||||||
buf: &mut Buffer,
|
buf: &mut Buffer,
|
||||||
common: &CommonCircuitData<F, D>,
|
common_data: &CommonCircuitData<F, D>,
|
||||||
) -> IoResult<WitnessGeneratorRef<F>>;
|
) -> IoResult<WitnessGeneratorRef<F, D>>;
|
||||||
|
|
||||||
fn write_generator(
|
fn write_generator(
|
||||||
&self,
|
&self,
|
||||||
buf: &mut Vec<u8>,
|
buf: &mut Vec<u8>,
|
||||||
generator: &WitnessGeneratorRef<F>,
|
generator: &WitnessGeneratorRef<F, D>,
|
||||||
|
common_data: &CommonCircuitData<F, D>,
|
||||||
) -> IoResult<()>;
|
) -> IoResult<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,19 +29,11 @@ macro_rules! read_generator_impl {
|
|||||||
let buf = $buf;
|
let buf = $buf;
|
||||||
let mut i = 0..;
|
let mut i = 0..;
|
||||||
|
|
||||||
if tag == 0 {
|
|
||||||
let generator: $crate::recursion::dummy_circuit::DummyProofGenerator<F, C, D> =
|
|
||||||
$crate::recursion::dummy_circuit::DummyProofGenerator::deserialize_with_circuit_data(buf, $common)?;
|
|
||||||
return Ok($crate::iop::generator::WitnessGeneratorRef::<F>::new(
|
|
||||||
$crate::iop::generator::SimpleGenerator::<F>::adapter(generator),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
$(if tag == i.next().unwrap() {
|
$(if tag == i.next().unwrap() {
|
||||||
let generator =
|
let generator =
|
||||||
<$generator_types as $crate::iop::generator::SimpleGenerator<F>>::deserialize(buf)?;
|
<$generator_types as $crate::iop::generator::SimpleGenerator<F, D>>::deserialize(buf, $common)?;
|
||||||
Ok($crate::iop::generator::WitnessGeneratorRef::<F>::new(
|
Ok($crate::iop::generator::WitnessGeneratorRef::<F, D>::new(
|
||||||
$crate::iop::generator::SimpleGenerator::<F>::adapter(generator),
|
$crate::iop::generator::SimpleGenerator::<F, D>::adapter(generator),
|
||||||
))
|
))
|
||||||
} else)*
|
} else)*
|
||||||
{
|
{
|
||||||
@ -52,7 +46,7 @@ macro_rules! read_generator_impl {
|
|||||||
macro_rules! get_generator_tag_impl {
|
macro_rules! get_generator_tag_impl {
|
||||||
($generator:expr, $($generator_types:ty),+) => {{
|
($generator:expr, $($generator_types:ty),+) => {{
|
||||||
let mut i = 0..;
|
let mut i = 0..;
|
||||||
$(if let (tag, true) = (i.next().unwrap(), $generator.0.id() == $crate::iop::generator::SimpleGenerator::<F>::id(&<$generator_types>::default())) {
|
$(if let (tag, true) = (i.next().unwrap(), $generator.0.id() == $crate::iop::generator::SimpleGenerator::<F, D>::id(&<$generator_types>::default())) {
|
||||||
Ok(tag)
|
Ok(tag)
|
||||||
} else)*
|
} else)*
|
||||||
{
|
{
|
||||||
@ -67,17 +61,13 @@ macro_rules! get_generator_tag_impl {
|
|||||||
/// To serialize a list of generators used for a circuit,
|
/// To serialize a list of generators used for a circuit,
|
||||||
/// this macro should be called with a struct on which to implement
|
/// this macro should be called with a struct on which to implement
|
||||||
/// this as first argument, followed by all the targeted generators.
|
/// this as first argument, followed by all the targeted generators.
|
||||||
///
|
|
||||||
/// ***NOTE:*** If you need to include `DummyProofGenerator`, you **MUST**
|
|
||||||
/// place it at the *beginning* of the generators list, right after
|
|
||||||
/// the serializer struct.
|
|
||||||
macro_rules! impl_generator_serializer {
|
macro_rules! impl_generator_serializer {
|
||||||
($target:ty, $($generator_types:ty),+) => {
|
($target:ty, $($generator_types:ty),+) => {
|
||||||
fn read_generator(
|
fn read_generator(
|
||||||
&self,
|
&self,
|
||||||
buf: &mut $crate::util::serialization::Buffer,
|
buf: &mut $crate::util::serialization::Buffer,
|
||||||
common: &$crate::plonk::circuit_data::CommonCircuitData<F, D>,
|
common: &$crate::plonk::circuit_data::CommonCircuitData<F, D>,
|
||||||
) -> $crate::util::serialization::IoResult<$crate::iop::generator::WitnessGeneratorRef<F>> {
|
) -> $crate::util::serialization::IoResult<$crate::iop::generator::WitnessGeneratorRef<F, D>> {
|
||||||
let tag = $crate::util::serialization::Read::read_u32(buf)?;
|
let tag = $crate::util::serialization::Read::read_u32(buf)?;
|
||||||
read_generator_impl!(buf, tag, common, $($generator_types),+)
|
read_generator_impl!(buf, tag, common, $($generator_types),+)
|
||||||
}
|
}
|
||||||
@ -85,12 +75,13 @@ macro_rules! impl_generator_serializer {
|
|||||||
fn write_generator(
|
fn write_generator(
|
||||||
&self,
|
&self,
|
||||||
buf: &mut Vec<u8>,
|
buf: &mut Vec<u8>,
|
||||||
generator: &$crate::iop::generator::WitnessGeneratorRef<F>,
|
generator: &$crate::iop::generator::WitnessGeneratorRef<F, D>,
|
||||||
|
common: &$crate::plonk::circuit_data::CommonCircuitData<F, D>,
|
||||||
) -> $crate::util::serialization::IoResult<()> {
|
) -> $crate::util::serialization::IoResult<()> {
|
||||||
let tag = get_generator_tag_impl!(generator, $($generator_types),+)?;
|
let tag = get_generator_tag_impl!(generator, $($generator_types),+)?;
|
||||||
|
|
||||||
$crate::util::serialization::Write::write_u32(buf, tag)?;
|
$crate::util::serialization::Write::write_u32(buf, tag)?;
|
||||||
generator.0.serialize(buf)?;
|
generator.0.serialize(buf, common)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -139,13 +130,13 @@ pub mod default {
|
|||||||
{
|
{
|
||||||
impl_generator_serializer! {
|
impl_generator_serializer! {
|
||||||
DefaultGeneratorSerializer,
|
DefaultGeneratorSerializer,
|
||||||
DummyProofGenerator<F, C, D>,
|
|
||||||
ArithmeticBaseGenerator<F, D>,
|
ArithmeticBaseGenerator<F, D>,
|
||||||
ArithmeticExtensionGenerator<F, D>,
|
ArithmeticExtensionGenerator<F, D>,
|
||||||
BaseSplitGenerator<2>,
|
BaseSplitGenerator<2>,
|
||||||
BaseSumGenerator<2>,
|
BaseSumGenerator<2>,
|
||||||
ConstantGenerator<F>,
|
ConstantGenerator<F>,
|
||||||
CopyGenerator,
|
CopyGenerator,
|
||||||
|
DummyProofGenerator<F, C, D>,
|
||||||
EqualityGenerator,
|
EqualityGenerator,
|
||||||
ExponentiationGenerator<F, D>,
|
ExponentiationGenerator<F, D>,
|
||||||
InterpolationGenerator<F, D>,
|
InterpolationGenerator<F, D>,
|
||||||
|
|||||||
@ -684,13 +684,14 @@ pub trait Read {
|
|||||||
fn read_gate<F: RichField + Extendable<D>, const D: usize>(
|
fn read_gate<F: RichField + Extendable<D>, const D: usize>(
|
||||||
&mut self,
|
&mut self,
|
||||||
gate_serializer: &dyn GateSerializer<F, D>,
|
gate_serializer: &dyn GateSerializer<F, D>,
|
||||||
|
common_data: &CommonCircuitData<F, D>,
|
||||||
) -> IoResult<GateRef<F, D>>;
|
) -> IoResult<GateRef<F, D>>;
|
||||||
|
|
||||||
fn read_generator<F: RichField + Extendable<D>, const D: usize>(
|
fn read_generator<F: RichField + Extendable<D>, const D: usize>(
|
||||||
&mut self,
|
&mut self,
|
||||||
generator_serializer: &dyn WitnessGeneratorSerializer<F, D>,
|
generator_serializer: &dyn WitnessGeneratorSerializer<F, D>,
|
||||||
common_data: &CommonCircuitData<F, D>,
|
common_data: &CommonCircuitData<F, D>,
|
||||||
) -> IoResult<WitnessGeneratorRef<F>>;
|
) -> IoResult<WitnessGeneratorRef<F, D>>;
|
||||||
|
|
||||||
fn read_selectors_info(&mut self) -> IoResult<SelectorsInfo> {
|
fn read_selectors_info(&mut self) -> IoResult<SelectorsInfo> {
|
||||||
let selector_indices = self.read_usize_vec()?;
|
let selector_indices = self.read_usize_vec()?;
|
||||||
@ -743,13 +744,6 @@ pub trait Read {
|
|||||||
let config = self.read_circuit_config()?;
|
let config = self.read_circuit_config()?;
|
||||||
let fri_params = self.read_fri_params()?;
|
let fri_params = self.read_fri_params()?;
|
||||||
|
|
||||||
let gates_len = self.read_usize()?;
|
|
||||||
let mut gates = Vec::with_capacity(gates_len);
|
|
||||||
for _ in 0..gates_len {
|
|
||||||
let gate = self.read_gate::<F, D>(gate_serializer)?;
|
|
||||||
gates.push(gate);
|
|
||||||
}
|
|
||||||
|
|
||||||
let selectors_info = self.read_selectors_info()?;
|
let selectors_info = self.read_selectors_info()?;
|
||||||
let quotient_degree_factor = self.read_usize()?;
|
let quotient_degree_factor = self.read_usize()?;
|
||||||
let num_gate_constraints = self.read_usize()?;
|
let num_gate_constraints = self.read_usize()?;
|
||||||
@ -770,10 +764,15 @@ pub trait Read {
|
|||||||
luts.push(Arc::new(self.read_lut()?));
|
luts.push(Arc::new(self.read_lut()?));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(CommonCircuitData {
|
let gates_len = self.read_usize()?;
|
||||||
|
let mut gates = Vec::with_capacity(gates_len);
|
||||||
|
|
||||||
|
// We construct the common data without gates first,
|
||||||
|
// to pass it as argument when reading the gates.
|
||||||
|
let mut common_data = CommonCircuitData {
|
||||||
config,
|
config,
|
||||||
fri_params,
|
fri_params,
|
||||||
gates,
|
gates: vec![],
|
||||||
selectors_info,
|
selectors_info,
|
||||||
quotient_degree_factor,
|
quotient_degree_factor,
|
||||||
num_gate_constraints,
|
num_gate_constraints,
|
||||||
@ -784,7 +783,16 @@ pub trait Read {
|
|||||||
num_lookup_polys,
|
num_lookup_polys,
|
||||||
num_lookup_selectors,
|
num_lookup_selectors,
|
||||||
luts,
|
luts,
|
||||||
})
|
};
|
||||||
|
|
||||||
|
for _ in 0..gates_len {
|
||||||
|
let gate = self.read_gate::<F, D>(gate_serializer, &common_data)?;
|
||||||
|
gates.push(gate);
|
||||||
|
}
|
||||||
|
|
||||||
|
common_data.gates = gates;
|
||||||
|
|
||||||
|
Ok(common_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_circuit_data<
|
fn read_circuit_data<
|
||||||
@ -813,12 +821,12 @@ pub trait Read {
|
|||||||
>(
|
>(
|
||||||
&mut self,
|
&mut self,
|
||||||
generator_serializer: &dyn WitnessGeneratorSerializer<F, D>,
|
generator_serializer: &dyn WitnessGeneratorSerializer<F, D>,
|
||||||
cd: &CommonCircuitData<F, D>,
|
common_data: &CommonCircuitData<F, D>,
|
||||||
) -> IoResult<ProverOnlyCircuitData<F, C, D>> {
|
) -> IoResult<ProverOnlyCircuitData<F, C, D>> {
|
||||||
let gen_len = self.read_usize()?;
|
let gen_len = self.read_usize()?;
|
||||||
let mut generators = Vec::with_capacity(gen_len);
|
let mut generators = Vec::with_capacity(gen_len);
|
||||||
for _ in 0..gen_len {
|
for _ in 0..gen_len {
|
||||||
generators.push(self.read_generator(generator_serializer, cd)?);
|
generators.push(self.read_generator(generator_serializer, common_data)?);
|
||||||
}
|
}
|
||||||
let map_len = self.read_usize()?;
|
let map_len = self.read_usize()?;
|
||||||
let mut generator_indices_by_watches = BTreeMap::new();
|
let mut generator_indices_by_watches = BTreeMap::new();
|
||||||
@ -1689,12 +1697,14 @@ pub trait Write {
|
|||||||
&mut self,
|
&mut self,
|
||||||
gate: &GateRef<F, D>,
|
gate: &GateRef<F, D>,
|
||||||
gate_serializer: &dyn GateSerializer<F, D>,
|
gate_serializer: &dyn GateSerializer<F, D>,
|
||||||
|
common_data: &CommonCircuitData<F, D>,
|
||||||
) -> IoResult<()>;
|
) -> IoResult<()>;
|
||||||
|
|
||||||
fn write_generator<F: RichField + Extendable<D>, const D: usize>(
|
fn write_generator<F: RichField + Extendable<D>, const D: usize>(
|
||||||
&mut self,
|
&mut self,
|
||||||
generator: &WitnessGeneratorRef<F>,
|
generator: &WitnessGeneratorRef<F, D>,
|
||||||
generator_serializer: &dyn WitnessGeneratorSerializer<F, D>,
|
generator_serializer: &dyn WitnessGeneratorSerializer<F, D>,
|
||||||
|
common_data: &CommonCircuitData<F, D>,
|
||||||
) -> IoResult<()>;
|
) -> IoResult<()>;
|
||||||
|
|
||||||
fn write_selectors_info(&mut self, selectors_info: &SelectorsInfo) -> IoResult<()> {
|
fn write_selectors_info(&mut self, selectors_info: &SelectorsInfo) -> IoResult<()> {
|
||||||
@ -1757,11 +1767,6 @@ pub trait Write {
|
|||||||
self.write_circuit_config(config)?;
|
self.write_circuit_config(config)?;
|
||||||
self.write_fri_params(fri_params)?;
|
self.write_fri_params(fri_params)?;
|
||||||
|
|
||||||
self.write_usize(gates.len())?;
|
|
||||||
for gate in gates.iter() {
|
|
||||||
self.write_gate::<F, D>(gate, gate_serializer)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.write_selectors_info(selectors_info)?;
|
self.write_selectors_info(selectors_info)?;
|
||||||
self.write_usize(*quotient_degree_factor)?;
|
self.write_usize(*quotient_degree_factor)?;
|
||||||
self.write_usize(*num_gate_constraints)?;
|
self.write_usize(*num_gate_constraints)?;
|
||||||
@ -1780,6 +1785,11 @@ pub trait Write {
|
|||||||
self.write_lut(lut)?;
|
self.write_lut(lut)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.write_usize(gates.len())?;
|
||||||
|
for gate in gates.iter() {
|
||||||
|
self.write_gate::<F, D>(gate, gate_serializer, common_data)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1794,7 +1804,11 @@ pub trait Write {
|
|||||||
generator_serializer: &dyn WitnessGeneratorSerializer<F, D>,
|
generator_serializer: &dyn WitnessGeneratorSerializer<F, D>,
|
||||||
) -> IoResult<()> {
|
) -> IoResult<()> {
|
||||||
self.write_common_circuit_data(&circuit_data.common, gate_serializer)?;
|
self.write_common_circuit_data(&circuit_data.common, gate_serializer)?;
|
||||||
self.write_prover_only_circuit_data(&circuit_data.prover_only, generator_serializer)?;
|
self.write_prover_only_circuit_data(
|
||||||
|
&circuit_data.prover_only,
|
||||||
|
generator_serializer,
|
||||||
|
&circuit_data.common,
|
||||||
|
)?;
|
||||||
self.write_verifier_only_circuit_data(&circuit_data.verifier_only)
|
self.write_verifier_only_circuit_data(&circuit_data.verifier_only)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1806,6 +1820,7 @@ pub trait Write {
|
|||||||
&mut self,
|
&mut self,
|
||||||
prover_only_circuit_data: &ProverOnlyCircuitData<F, C, D>,
|
prover_only_circuit_data: &ProverOnlyCircuitData<F, C, D>,
|
||||||
generator_serializer: &dyn WitnessGeneratorSerializer<F, D>,
|
generator_serializer: &dyn WitnessGeneratorSerializer<F, D>,
|
||||||
|
common_data: &CommonCircuitData<F, D>,
|
||||||
) -> IoResult<()> {
|
) -> IoResult<()> {
|
||||||
let ProverOnlyCircuitData {
|
let ProverOnlyCircuitData {
|
||||||
generators,
|
generators,
|
||||||
@ -1823,7 +1838,7 @@ pub trait Write {
|
|||||||
|
|
||||||
self.write_usize(generators.len())?;
|
self.write_usize(generators.len())?;
|
||||||
for generator in generators.iter() {
|
for generator in generators.iter() {
|
||||||
self.write_generator::<F, D>(generator, generator_serializer)?;
|
self.write_generator::<F, D>(generator, generator_serializer, common_data)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.write_usize(generator_indices_by_watches.len())?;
|
self.write_usize(generator_indices_by_watches.len())?;
|
||||||
@ -1883,7 +1898,11 @@ pub trait Write {
|
|||||||
generator_serializer: &dyn WitnessGeneratorSerializer<F, D>,
|
generator_serializer: &dyn WitnessGeneratorSerializer<F, D>,
|
||||||
) -> IoResult<()> {
|
) -> IoResult<()> {
|
||||||
self.write_common_circuit_data(&prover_circuit_data.common, gate_serializer)?;
|
self.write_common_circuit_data(&prover_circuit_data.common, gate_serializer)?;
|
||||||
self.write_prover_only_circuit_data(&prover_circuit_data.prover_only, generator_serializer)
|
self.write_prover_only_circuit_data(
|
||||||
|
&prover_circuit_data.prover_only,
|
||||||
|
generator_serializer,
|
||||||
|
&prover_circuit_data.common,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_verifier_only_circuit_data<
|
fn write_verifier_only_circuit_data<
|
||||||
@ -2110,16 +2129,18 @@ impl Write for Vec<u8> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
gate: &GateRef<F, D>,
|
gate: &GateRef<F, D>,
|
||||||
gate_serializer: &dyn GateSerializer<F, D>,
|
gate_serializer: &dyn GateSerializer<F, D>,
|
||||||
|
common_data: &CommonCircuitData<F, D>,
|
||||||
) -> IoResult<()> {
|
) -> IoResult<()> {
|
||||||
gate_serializer.write_gate(self, gate)
|
gate_serializer.write_gate(self, gate, common_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_generator<F: RichField + Extendable<D>, const D: usize>(
|
fn write_generator<F: RichField + Extendable<D>, const D: usize>(
|
||||||
&mut self,
|
&mut self,
|
||||||
generator: &WitnessGeneratorRef<F>,
|
generator: &WitnessGeneratorRef<F, D>,
|
||||||
generator_serializer: &dyn WitnessGeneratorSerializer<F, D>,
|
generator_serializer: &dyn WitnessGeneratorSerializer<F, D>,
|
||||||
|
common_data: &CommonCircuitData<F, D>,
|
||||||
) -> IoResult<()> {
|
) -> IoResult<()> {
|
||||||
generator_serializer.write_generator(self, generator)
|
generator_serializer.write_generator(self, generator, common_data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2178,15 +2199,16 @@ impl<'a> Read for Buffer<'a> {
|
|||||||
fn read_gate<F: RichField + Extendable<D>, const D: usize>(
|
fn read_gate<F: RichField + Extendable<D>, const D: usize>(
|
||||||
&mut self,
|
&mut self,
|
||||||
gate_serializer: &dyn GateSerializer<F, D>,
|
gate_serializer: &dyn GateSerializer<F, D>,
|
||||||
|
common_data: &CommonCircuitData<F, D>,
|
||||||
) -> IoResult<GateRef<F, D>> {
|
) -> IoResult<GateRef<F, D>> {
|
||||||
gate_serializer.read_gate(self)
|
gate_serializer.read_gate(self, common_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_generator<F: RichField + Extendable<D>, const D: usize>(
|
fn read_generator<F: RichField + Extendable<D>, const D: usize>(
|
||||||
&mut self,
|
&mut self,
|
||||||
generator_serializer: &dyn WitnessGeneratorSerializer<F, D>,
|
generator_serializer: &dyn WitnessGeneratorSerializer<F, D>,
|
||||||
common_data: &CommonCircuitData<F, D>,
|
common_data: &CommonCircuitData<F, D>,
|
||||||
) -> IoResult<WitnessGeneratorRef<F>> {
|
) -> IoResult<WitnessGeneratorRef<F, D>> {
|
||||||
generator_serializer.read_generator(self, common_data)
|
generator_serializer.read_generator(self, common_data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user