mirror of
https://github.com/arnaucube/hyperplonk.git
synced 2026-01-11 16:41:28 +01:00
move transcript to trait (#46)
This commit is contained in:
@@ -2,5 +2,6 @@
|
|||||||
members = [
|
members = [
|
||||||
"hyperplonk",
|
"hyperplonk",
|
||||||
"pcs",
|
"pcs",
|
||||||
"poly-iop"
|
"poly-iop",
|
||||||
|
"transcript",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -17,8 +17,7 @@ ark-bls12-381 = { version = "0.3.0", default-features = false, features = [ "cur
|
|||||||
|
|
||||||
displaydoc = { version = "0.2.3", default-features = false }
|
displaydoc = { version = "0.2.3", default-features = false }
|
||||||
|
|
||||||
poly-iop = { path = "../poly-iop" }
|
transcript = { path = "../transcript" }
|
||||||
|
|
||||||
|
|
||||||
# Benchmarks
|
# Benchmarks
|
||||||
[[bench]]
|
[[bench]]
|
||||||
@@ -34,9 +33,7 @@ parallel = [
|
|||||||
"ark-ff/parallel",
|
"ark-ff/parallel",
|
||||||
"ark-poly/parallel",
|
"ark-poly/parallel",
|
||||||
"ark-ec/parallel",
|
"ark-ec/parallel",
|
||||||
"poly-iop/parallel"
|
|
||||||
]
|
]
|
||||||
print-trace = [
|
print-trace = [
|
||||||
"ark-std/print-trace",
|
"ark-std/print-trace",
|
||||||
"poly-iop/print-trace"
|
|
||||||
]
|
]
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
use ark_serialize::SerializationError;
|
use ark_serialize::SerializationError;
|
||||||
use ark_std::string::String;
|
use ark_std::string::String;
|
||||||
use displaydoc::Display;
|
use displaydoc::Display;
|
||||||
use poly_iop::PolyIOPErrors;
|
use transcript::TranscriptErrors;
|
||||||
|
|
||||||
/// A `enum` specifying the possible failure modes of the PCS.
|
/// A `enum` specifying the possible failure modes of the PCS.
|
||||||
#[derive(Display, Debug)]
|
#[derive(Display, Debug)]
|
||||||
@@ -18,8 +18,8 @@ pub enum PCSErrors {
|
|||||||
InvalidParameters(String),
|
InvalidParameters(String),
|
||||||
/// An error during (de)serialization: {0}
|
/// An error during (de)serialization: {0}
|
||||||
SerializationError(SerializationError),
|
SerializationError(SerializationError),
|
||||||
/// PolyIOP error {0}
|
/// Transcript error {0}
|
||||||
PolyIOPErrors(PolyIOPErrors),
|
TranscriptError(TranscriptErrors),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SerializationError> for PCSErrors {
|
impl From<SerializationError> for PCSErrors {
|
||||||
@@ -28,8 +28,8 @@ impl From<SerializationError> for PCSErrors {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PolyIOPErrors> for PCSErrors {
|
impl From<TranscriptErrors> for PCSErrors {
|
||||||
fn from(e: PolyIOPErrors) -> Self {
|
fn from(e: TranscriptErrors) -> Self {
|
||||||
Self::PolyIOPErrors(e)
|
Self::TranscriptError(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use crate::{
|
|||||||
use ark_ec::PairingEngine;
|
use ark_ec::PairingEngine;
|
||||||
use ark_poly::{DenseMultilinearExtension, EvaluationDomain, MultilinearExtension, Polynomial};
|
use ark_poly::{DenseMultilinearExtension, EvaluationDomain, MultilinearExtension, Polynomial};
|
||||||
use ark_std::{end_timer, start_timer, vec::Vec};
|
use ark_std::{end_timer, start_timer, vec::Vec};
|
||||||
use poly_iop::IOPTranscript;
|
use transcript::IOPTranscript;
|
||||||
|
|
||||||
/// Input
|
/// Input
|
||||||
/// - the prover parameters for univariate KZG,
|
/// - the prover parameters for univariate KZG,
|
||||||
@@ -237,12 +237,12 @@ pub(super) fn batch_verify_internal<E: PairingEngine>(
|
|||||||
|
|
||||||
// 3. check `q(r) == batch_proof.q_x_value.last` and `q(omega^i) =
|
// 3. check `q(r) == batch_proof.q_x_value.last` and `q(omega^i) =
|
||||||
// batch_proof.q_x_value[i]`
|
// batch_proof.q_x_value[i]`
|
||||||
for i in 0..points_len {
|
for (i, value) in values.iter().enumerate().take(points_len) {
|
||||||
if !KZGUnivariatePCS::verify(
|
if !KZGUnivariatePCS::verify(
|
||||||
uni_verifier_param,
|
uni_verifier_param,
|
||||||
&batch_proof.q_x_commit,
|
&batch_proof.q_x_commit,
|
||||||
&domain.element(i),
|
&domain.element(i),
|
||||||
&values[i],
|
&value,
|
||||||
&batch_proof.q_x_opens[i],
|
&batch_proof.q_x_opens[i],
|
||||||
)? {
|
)? {
|
||||||
#[cfg(debug_assertion)]
|
#[cfg(debug_assertion)]
|
||||||
|
|||||||
@@ -7,9 +7,20 @@ use ark_poly::{
|
|||||||
MultilinearExtension, Polynomial, Radix2EvaluationDomain,
|
MultilinearExtension, Polynomial, Radix2EvaluationDomain,
|
||||||
};
|
};
|
||||||
use ark_std::{end_timer, log2, start_timer};
|
use ark_std::{end_timer, log2, start_timer};
|
||||||
use poly_iop::bit_decompose;
|
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
|
|
||||||
|
/// Decompose an integer into a binary vector in little endian.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(crate) fn bit_decompose(input: u64, num_var: usize) -> Vec<bool> {
|
||||||
|
let mut res = Vec::with_capacity(num_var);
|
||||||
|
let mut i = input;
|
||||||
|
for _ in 0..num_var {
|
||||||
|
res.push(i & 1 == 1);
|
||||||
|
i >>= 1;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
/// For an MLE w with `mle_num_vars` variables, and `point_len` number of
|
/// For an MLE w with `mle_num_vars` variables, and `point_len` number of
|
||||||
/// points, compute the degree of the univariate polynomial `q(x):= w(l(x))`
|
/// points, compute the degree of the univariate polynomial `q(x):= w(l(x))`
|
||||||
/// where l(x) is a list of polynomials that go through all points.
|
/// where l(x) is a list of polynomials that go through all points.
|
||||||
|
|||||||
@@ -14,11 +14,12 @@ ark-serialize = { version = "^0.3.0", default-features = false }
|
|||||||
ark-bls12-381 = { version = "0.3.0", default-features = false, features = [ "curve" ] }
|
ark-bls12-381 = { version = "0.3.0", default-features = false, features = [ "curve" ] }
|
||||||
|
|
||||||
rand_chacha = { version = "0.3.0", default-features = false }
|
rand_chacha = { version = "0.3.0", default-features = false }
|
||||||
merlin = { version = "3.0.0", default-features = false }
|
|
||||||
displaydoc = { version = "0.2.3", default-features = false }
|
displaydoc = { version = "0.2.3", default-features = false }
|
||||||
|
|
||||||
rayon = { version = "1.5.2", default-features = false, optional = true }
|
rayon = { version = "1.5.2", default-features = false, optional = true }
|
||||||
|
|
||||||
|
transcript = { path = "../transcript" }
|
||||||
|
|
||||||
# Benchmarks
|
# Benchmarks
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "poly-iop-benches"
|
name = "poly-iop-benches"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
use ark_std::string::String;
|
use ark_std::string::String;
|
||||||
use displaydoc::Display;
|
use displaydoc::Display;
|
||||||
|
use transcript::TranscriptErrors;
|
||||||
|
|
||||||
/// A `enum` specifying the possible failure modes of the PolyIOP.
|
/// A `enum` specifying the possible failure modes of the PolyIOP.
|
||||||
#[derive(Display, Debug)]
|
#[derive(Display, Debug)]
|
||||||
@@ -14,12 +15,14 @@ pub enum PolyIOPErrors {
|
|||||||
InvalidProof(String),
|
InvalidProof(String),
|
||||||
/// Invalid parameters: {0}
|
/// Invalid parameters: {0}
|
||||||
InvalidParameters(String),
|
InvalidParameters(String),
|
||||||
/// Invalid Transcript: {0}
|
/// Invalid challenge: {0}
|
||||||
InvalidTranscript(String),
|
InvalidChallenge(String),
|
||||||
/// Should not arrive to this point
|
/// Should not arrive to this point
|
||||||
ShouldNotArrive,
|
ShouldNotArrive,
|
||||||
/// An error during (de)serialization: {0}
|
/// An error during (de)serialization: {0}
|
||||||
SerializationError(ark_serialize::SerializationError),
|
SerializationError(ark_serialize::SerializationError),
|
||||||
|
/// Transcript Error: {0}
|
||||||
|
TranscriptError(TranscriptErrors),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ark_serialize::SerializationError> for PolyIOPErrors {
|
impl From<ark_serialize::SerializationError> for PolyIOPErrors {
|
||||||
@@ -27,3 +30,9 @@ impl From<ark_serialize::SerializationError> for PolyIOPErrors {
|
|||||||
Self::SerializationError(e)
|
Self::SerializationError(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<TranscriptErrors> for PolyIOPErrors {
|
||||||
|
fn from(e: TranscriptErrors) -> Self {
|
||||||
|
Self::TranscriptError(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
//! Main module for the HyperPlonk PolyIOP.
|
//! Main module for the HyperPlonk PolyIOP.
|
||||||
|
|
||||||
use crate::{
|
use crate::{errors::PolyIOPErrors, perm_check::PermutationCheck, zero_check::ZeroCheck};
|
||||||
errors::PolyIOPErrors, perm_check::PermutationCheck, transcript::IOPTranscript,
|
|
||||||
zero_check::ZeroCheck,
|
|
||||||
};
|
|
||||||
use ark_ff::PrimeField;
|
use ark_ff::PrimeField;
|
||||||
use ark_poly::DenseMultilinearExtension;
|
use ark_poly::DenseMultilinearExtension;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use transcript::IOPTranscript;
|
||||||
|
|
||||||
/// A trait for HyperPlonk Poly-IOPs
|
/// A trait for HyperPlonk Poly-IOPs
|
||||||
pub trait HyperPlonkPIOP<F: PrimeField> {
|
pub trait HyperPlonkPIOP<F: PrimeField> {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ mod perm_check;
|
|||||||
mod prod_check;
|
mod prod_check;
|
||||||
mod structs;
|
mod structs;
|
||||||
mod sum_check;
|
mod sum_check;
|
||||||
mod transcript;
|
|
||||||
mod utils;
|
mod utils;
|
||||||
mod virtual_poly;
|
mod virtual_poly;
|
||||||
mod zero_check;
|
mod zero_check;
|
||||||
@@ -20,7 +19,6 @@ pub use perm_check::{
|
|||||||
};
|
};
|
||||||
pub use prod_check::ProductCheck;
|
pub use prod_check::ProductCheck;
|
||||||
pub use sum_check::SumCheck;
|
pub use sum_check::SumCheck;
|
||||||
pub use transcript::IOPTranscript;
|
|
||||||
pub use utils::*;
|
pub use utils::*;
|
||||||
pub use virtual_poly::{VPAuxInfo, VirtualPolynomial};
|
pub use virtual_poly::{VPAuxInfo, VirtualPolynomial};
|
||||||
pub use zero_check::ZeroCheck;
|
pub use zero_check::ZeroCheck;
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
//! Main module for the Permutation Check protocol
|
//! Main module for the Permutation Check protocol
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::PolyIOPErrors, perm_check::util::compute_prod_0, structs::IOPProof,
|
errors::PolyIOPErrors, perm_check::util::compute_prod_0, structs::IOPProof, utils::get_index,
|
||||||
transcript::IOPTranscript, utils::get_index, PolyIOP, VirtualPolynomial, ZeroCheck,
|
PolyIOP, VirtualPolynomial, ZeroCheck,
|
||||||
};
|
};
|
||||||
use ark_ff::PrimeField;
|
use ark_ff::PrimeField;
|
||||||
use ark_poly::DenseMultilinearExtension;
|
use ark_poly::DenseMultilinearExtension;
|
||||||
use ark_std::{end_timer, start_timer};
|
use ark_std::{end_timer, start_timer};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use transcript::IOPTranscript;
|
||||||
|
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
|
||||||
@@ -221,7 +222,7 @@ impl<F: PrimeField> PermutationCheck<F> for PolyIOP<F> {
|
|||||||
prod_x_binding: &F,
|
prod_x_binding: &F,
|
||||||
) -> Result<(), PolyIOPErrors> {
|
) -> Result<(), PolyIOPErrors> {
|
||||||
if challenge.alpha.is_some() {
|
if challenge.alpha.is_some() {
|
||||||
return Err(PolyIOPErrors::InvalidTranscript(
|
return Err(PolyIOPErrors::InvalidChallenge(
|
||||||
"alpha should not be sampled at the current stage".to_string(),
|
"alpha should not be sampled at the current stage".to_string(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -268,7 +269,7 @@ impl<F: PrimeField> PermutationCheck<F> for PolyIOP<F> {
|
|||||||
let start = start_timer!(|| "compute all prod polynomial");
|
let start = start_timer!(|| "compute all prod polynomial");
|
||||||
|
|
||||||
if challenge.alpha.is_some() {
|
if challenge.alpha.is_some() {
|
||||||
return Err(PolyIOPErrors::InvalidTranscript(
|
return Err(PolyIOPErrors::InvalidChallenge(
|
||||||
"alpha is already sampled".to_string(),
|
"alpha is already sampled".to_string(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -372,7 +373,7 @@ impl<F: PrimeField> PermutationCheck<F> for PolyIOP<F> {
|
|||||||
let alpha = match challenge.alpha {
|
let alpha = match challenge.alpha {
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
None => {
|
None => {
|
||||||
return Err(PolyIOPErrors::InvalidTranscript(
|
return Err(PolyIOPErrors::InvalidChallenge(
|
||||||
"alpha is not sampled yet".to_string(),
|
"alpha is not sampled yet".to_string(),
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
//! Main module for the Permutation Check protocol
|
//! Main module for the Permutation Check protocol
|
||||||
|
|
||||||
use crate::{errors::PolyIOPErrors, transcript::IOPTranscript, VirtualPolynomial, ZeroCheck};
|
use crate::{errors::PolyIOPErrors, VirtualPolynomial, ZeroCheck};
|
||||||
use ark_ff::PrimeField;
|
use ark_ff::PrimeField;
|
||||||
use ark_poly::DenseMultilinearExtension;
|
use ark_poly::DenseMultilinearExtension;
|
||||||
|
use transcript::IOPTranscript;
|
||||||
|
|
||||||
/// A ProductCheck is derived from ZeroCheck.
|
/// A ProductCheck is derived from ZeroCheck.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -2,17 +2,18 @@
|
|||||||
|
|
||||||
use crate::VirtualPolynomial;
|
use crate::VirtualPolynomial;
|
||||||
use ark_ff::PrimeField;
|
use ark_ff::PrimeField;
|
||||||
|
use ark_serialize::{CanonicalSerialize, SerializationError, Write};
|
||||||
|
|
||||||
/// An IOP proof is a collections of messages from prover to verifier at each
|
/// An IOP proof is a collections of messages from prover to verifier at each
|
||||||
/// round through the interactive protocol.
|
/// round through the interactive protocol.
|
||||||
#[derive(Clone, Debug, Default, PartialEq)]
|
#[derive(Clone, Debug, Default, PartialEq, CanonicalSerialize)]
|
||||||
pub struct IOPProof<F: PrimeField> {
|
pub struct IOPProof<F: PrimeField> {
|
||||||
pub proofs: Vec<IOPProverMessage<F>>,
|
pub proofs: Vec<IOPProverMessage<F>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A message from the prover to the verifier at a given round
|
/// A message from the prover to the verifier at a given round
|
||||||
/// is a list of evaluations.
|
/// is a list of evaluations.
|
||||||
#[derive(Clone, Debug, Default, PartialEq)]
|
#[derive(Clone, Debug, Default, PartialEq, CanonicalSerialize)]
|
||||||
pub struct IOPProverMessage<F: PrimeField> {
|
pub struct IOPProverMessage<F: PrimeField> {
|
||||||
pub(crate) evaluations: Vec<F>,
|
pub(crate) evaluations: Vec<F>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
errors::PolyIOPErrors,
|
errors::PolyIOPErrors,
|
||||||
structs::{IOPProof, IOPProverState, IOPVerifierState},
|
structs::{IOPProof, IOPProverState, IOPVerifierState},
|
||||||
transcript::IOPTranscript,
|
|
||||||
virtual_poly::{VPAuxInfo, VirtualPolynomial},
|
virtual_poly::{VPAuxInfo, VirtualPolynomial},
|
||||||
PolyIOP,
|
PolyIOP,
|
||||||
};
|
};
|
||||||
use ark_ff::PrimeField;
|
use ark_ff::PrimeField;
|
||||||
use ark_poly::DenseMultilinearExtension;
|
use ark_poly::DenseMultilinearExtension;
|
||||||
use ark_std::{end_timer, start_timer};
|
use ark_std::{end_timer, start_timer};
|
||||||
|
use transcript::IOPTranscript;
|
||||||
|
|
||||||
mod prover;
|
mod prover;
|
||||||
mod verifier;
|
mod verifier;
|
||||||
@@ -160,7 +160,7 @@ impl<F: PrimeField> SumCheck<F> for PolyIOP<F> {
|
|||||||
) -> Result<Self::Proof, PolyIOPErrors> {
|
) -> Result<Self::Proof, PolyIOPErrors> {
|
||||||
let start = start_timer!(|| "sum check prove");
|
let start = start_timer!(|| "sum check prove");
|
||||||
|
|
||||||
transcript.append_aux_info(&poly.aux_info)?;
|
transcript.append_serializable_element(b"aux info", &poly.aux_info)?;
|
||||||
|
|
||||||
let mut prover_state = IOPProverState::prover_init(poly)?;
|
let mut prover_state = IOPProverState::prover_init(poly)?;
|
||||||
let mut challenge = None;
|
let mut challenge = None;
|
||||||
@@ -168,7 +168,7 @@ impl<F: PrimeField> SumCheck<F> for PolyIOP<F> {
|
|||||||
for _ in 0..poly.aux_info.num_variables {
|
for _ in 0..poly.aux_info.num_variables {
|
||||||
let prover_msg =
|
let prover_msg =
|
||||||
IOPProverState::prove_round_and_update_state(&mut prover_state, &challenge)?;
|
IOPProverState::prove_round_and_update_state(&mut prover_state, &challenge)?;
|
||||||
transcript.append_prover_message(&prover_msg)?;
|
transcript.append_serializable_element(b"prover msg", &prover_msg)?;
|
||||||
prover_msgs.push(prover_msg);
|
prover_msgs.push(prover_msg);
|
||||||
challenge = Some(transcript.get_and_append_challenge(b"Internal round")?);
|
challenge = Some(transcript.get_and_append_challenge(b"Internal round")?);
|
||||||
}
|
}
|
||||||
@@ -188,11 +188,11 @@ impl<F: PrimeField> SumCheck<F> for PolyIOP<F> {
|
|||||||
) -> Result<Self::SumCheckSubClaim, PolyIOPErrors> {
|
) -> Result<Self::SumCheckSubClaim, PolyIOPErrors> {
|
||||||
let start = start_timer!(|| "sum check verify");
|
let start = start_timer!(|| "sum check verify");
|
||||||
|
|
||||||
transcript.append_aux_info(aux_info)?;
|
transcript.append_serializable_element(b"aux info", aux_info)?;
|
||||||
let mut verifier_state = IOPVerifierState::verifier_init(aux_info);
|
let mut verifier_state = IOPVerifierState::verifier_init(aux_info);
|
||||||
for i in 0..aux_info.num_variables {
|
for i in 0..aux_info.num_variables {
|
||||||
let prover_msg = proof.proofs.get(i).expect("proof is incomplete");
|
let prover_msg = proof.proofs.get(i).expect("proof is incomplete");
|
||||||
transcript.append_prover_message(prover_msg)?;
|
transcript.append_serializable_element(b"prover msg", prover_msg)?;
|
||||||
IOPVerifierState::verify_round_and_update_state(
|
IOPVerifierState::verify_round_and_update_state(
|
||||||
&mut verifier_state,
|
&mut verifier_state,
|
||||||
prover_msg,
|
prover_msg,
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ use super::{SumCheckSubClaim, SumCheckVerifier};
|
|||||||
use crate::{
|
use crate::{
|
||||||
errors::PolyIOPErrors,
|
errors::PolyIOPErrors,
|
||||||
structs::{IOPProverMessage, IOPVerifierState},
|
structs::{IOPProverMessage, IOPVerifierState},
|
||||||
transcript::IOPTranscript,
|
|
||||||
virtual_poly::VPAuxInfo,
|
virtual_poly::VPAuxInfo,
|
||||||
};
|
};
|
||||||
use ark_ff::PrimeField;
|
use ark_ff::PrimeField;
|
||||||
use ark_std::{end_timer, start_timer};
|
use ark_std::{end_timer, start_timer};
|
||||||
|
use transcript::IOPTranscript;
|
||||||
|
|
||||||
#[cfg(feature = "parallel")]
|
#[cfg(feature = "parallel")]
|
||||||
use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator};
|
use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator};
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
use crate::errors::PolyIOPErrors;
|
use crate::errors::PolyIOPErrors;
|
||||||
use ark_ff::PrimeField;
|
use ark_ff::PrimeField;
|
||||||
use ark_poly::{DenseMultilinearExtension, MultilinearExtension};
|
use ark_poly::{DenseMultilinearExtension, MultilinearExtension};
|
||||||
|
use ark_serialize::{CanonicalSerialize, SerializationError, Write};
|
||||||
use ark_std::{
|
use ark_std::{
|
||||||
end_timer,
|
end_timer,
|
||||||
rand::{Rng, RngCore},
|
rand::{Rng, RngCore},
|
||||||
@@ -51,7 +52,7 @@ pub struct VirtualPolynomial<F: PrimeField> {
|
|||||||
raw_pointers_lookup_table: HashMap<*const DenseMultilinearExtension<F>, usize>,
|
raw_pointers_lookup_table: HashMap<*const DenseMultilinearExtension<F>, usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, PartialEq)]
|
#[derive(Clone, Debug, Default, PartialEq, CanonicalSerialize)]
|
||||||
/// Auxiliary information about the multilinear polynomial
|
/// Auxiliary information about the multilinear polynomial
|
||||||
pub struct VPAuxInfo<F: PrimeField> {
|
pub struct VPAuxInfo<F: PrimeField> {
|
||||||
/// max number of multiplicands in each product
|
/// max number of multiplicands in each product
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
//! Main module for the ZeroCheck protocol.
|
//! Main module for the ZeroCheck protocol.
|
||||||
|
|
||||||
use crate::{errors::PolyIOPErrors, sum_check::SumCheck, transcript::IOPTranscript, PolyIOP};
|
use crate::{errors::PolyIOPErrors, sum_check::SumCheck, PolyIOP};
|
||||||
use ark_ff::PrimeField;
|
use ark_ff::PrimeField;
|
||||||
use ark_std::{end_timer, start_timer};
|
use ark_std::{end_timer, start_timer};
|
||||||
|
use transcript::IOPTranscript;
|
||||||
|
|
||||||
/// A zero check IOP subclaim for \hat f(x) is 0, consists of the following:
|
/// A zero check IOP subclaim for \hat f(x) is 0, consists of the following:
|
||||||
/// - the SubClaim from the SumCheck
|
/// - the SubClaim from the SumCheck
|
||||||
|
|||||||
17
transcript/Cargo.toml
Normal file
17
transcript/Cargo.toml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
[package]
|
||||||
|
name = "transcript"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
|
||||||
|
merlin = { version = "3.0.0", default-features = false }
|
||||||
|
|
||||||
|
|
||||||
|
ark-ff = { version = "^0.3.0", default-features = false }
|
||||||
|
ark-serialize = { version = "^0.3.0", default-features = false }
|
||||||
|
ark-std = { version = "^0.3.0", default-features = false }
|
||||||
|
|
||||||
|
displaydoc = { version = "0.2.3", default-features = false }
|
||||||
19
transcript/src/errors.rs
Normal file
19
transcript/src/errors.rs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//! Error module.
|
||||||
|
|
||||||
|
use ark_std::string::String;
|
||||||
|
use displaydoc::Display;
|
||||||
|
|
||||||
|
/// A `enum` specifying the possible failure modes of the Transcript.
|
||||||
|
#[derive(Display, Debug)]
|
||||||
|
pub enum TranscriptErrors {
|
||||||
|
/// Invalid Transcript: {0}
|
||||||
|
InvalidTranscript(String),
|
||||||
|
/// An error during (de)serialization: {0}
|
||||||
|
SerializationError(ark_serialize::SerializationError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ark_serialize::SerializationError> for TranscriptErrors {
|
||||||
|
fn from(e: ark_serialize::SerializationError) -> Self {
|
||||||
|
Self::SerializationError(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,13 +3,14 @@
|
|||||||
//! useful.
|
//! useful.
|
||||||
//! TODO(ZZ): decide which APIs need to be public.
|
//! TODO(ZZ): decide which APIs need to be public.
|
||||||
|
|
||||||
|
mod errors;
|
||||||
|
pub use errors::TranscriptErrors;
|
||||||
|
|
||||||
use ark_ff::PrimeField;
|
use ark_ff::PrimeField;
|
||||||
use ark_serialize::CanonicalSerialize;
|
use ark_serialize::CanonicalSerialize;
|
||||||
use merlin::Transcript;
|
use merlin::Transcript;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use crate::{errors::PolyIOPErrors, structs::IOPProverMessage, to_bytes, virtual_poly::VPAuxInfo};
|
|
||||||
|
|
||||||
/// An IOP transcript consists of a Merlin transcript and a flag `is_empty` to
|
/// An IOP transcript consists of a Merlin transcript and a flag `is_empty` to
|
||||||
/// indicate that if the transcript is empty.
|
/// indicate that if the transcript is empty.
|
||||||
///
|
///
|
||||||
@@ -27,6 +28,7 @@ pub struct IOPTranscript<F: PrimeField> {
|
|||||||
phantom: PhantomData<F>,
|
phantom: PhantomData<F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Make this into a Trait
|
||||||
impl<F: PrimeField> IOPTranscript<F> {
|
impl<F: PrimeField> IOPTranscript<F> {
|
||||||
/// Create a new IOP transcript.
|
/// Create a new IOP transcript.
|
||||||
pub fn new(label: &'static [u8]) -> Self {
|
pub fn new(label: &'static [u8]) -> Self {
|
||||||
@@ -42,29 +44,18 @@ impl<F: PrimeField> IOPTranscript<F> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
label: &'static [u8],
|
label: &'static [u8],
|
||||||
msg: &[u8],
|
msg: &[u8],
|
||||||
) -> Result<(), PolyIOPErrors> {
|
) -> Result<(), TranscriptErrors> {
|
||||||
self.transcript.append_message(label, msg);
|
self.transcript.append_message(label, msg);
|
||||||
self.is_empty = false;
|
self.is_empty = false;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append the aux information for a virtual polynomial.
|
|
||||||
pub(crate) fn append_aux_info(&mut self, aux_info: &VPAuxInfo<F>) -> Result<(), PolyIOPErrors> {
|
|
||||||
let message = format!(
|
|
||||||
"max_mul {} num_var {}",
|
|
||||||
aux_info.max_degree, aux_info.num_variables
|
|
||||||
);
|
|
||||||
self.append_message(b"aux info", message.as_bytes())?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append the message to the transcript.
|
// Append the message to the transcript.
|
||||||
pub fn append_field_element(
|
pub fn append_field_element(
|
||||||
&mut self,
|
&mut self,
|
||||||
label: &'static [u8],
|
label: &'static [u8],
|
||||||
field_elem: &F,
|
field_elem: &F,
|
||||||
) -> Result<(), PolyIOPErrors> {
|
) -> Result<(), TranscriptErrors> {
|
||||||
self.append_message(label, &to_bytes!(field_elem)?)
|
self.append_message(label, &to_bytes!(field_elem)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,30 +64,22 @@ impl<F: PrimeField> IOPTranscript<F> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
label: &'static [u8],
|
label: &'static [u8],
|
||||||
group_elem: &S,
|
group_elem: &S,
|
||||||
) -> Result<(), PolyIOPErrors> {
|
) -> Result<(), TranscriptErrors> {
|
||||||
self.append_message(label, &to_bytes!(group_elem)?)
|
self.append_message(label, &to_bytes!(group_elem)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append a prover message to the transcript.
|
|
||||||
pub(crate) fn append_prover_message(
|
|
||||||
&mut self,
|
|
||||||
prover_message: &IOPProverMessage<F>,
|
|
||||||
) -> Result<(), PolyIOPErrors> {
|
|
||||||
for e in prover_message.evaluations.iter() {
|
|
||||||
self.append_field_element(b"prover_message", e)?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate the challenge from the current transcript
|
// Generate the challenge from the current transcript
|
||||||
// and append it to the transcript.
|
// and append it to the transcript.
|
||||||
//
|
//
|
||||||
// The output field element is statistical uniform as long
|
// The output field element is statistical uniform as long
|
||||||
// as the field has a size less than 2^384.
|
// as the field has a size less than 2^384.
|
||||||
pub fn get_and_append_challenge(&mut self, label: &'static [u8]) -> Result<F, PolyIOPErrors> {
|
pub fn get_and_append_challenge(
|
||||||
|
&mut self,
|
||||||
|
label: &'static [u8],
|
||||||
|
) -> Result<F, TranscriptErrors> {
|
||||||
// we need to reject when transcript is empty
|
// we need to reject when transcript is empty
|
||||||
if self.is_empty {
|
if self.is_empty {
|
||||||
return Err(PolyIOPErrors::InvalidTranscript(
|
return Err(TranscriptErrors::InvalidTranscript(
|
||||||
"transcript is empty".to_string(),
|
"transcript is empty".to_string(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -114,14 +97,14 @@ impl<F: PrimeField> IOPTranscript<F> {
|
|||||||
//
|
//
|
||||||
// The output field element are statistical uniform as long
|
// The output field element are statistical uniform as long
|
||||||
// as the field has a size less than 2^384.
|
// as the field has a size less than 2^384.
|
||||||
pub(crate) fn get_and_append_challenge_vectors(
|
pub fn get_and_append_challenge_vectors(
|
||||||
&mut self,
|
&mut self,
|
||||||
label: &'static [u8],
|
label: &'static [u8],
|
||||||
len: usize,
|
len: usize,
|
||||||
) -> Result<Vec<F>, PolyIOPErrors> {
|
) -> Result<Vec<F>, TranscriptErrors> {
|
||||||
// we need to reject when transcript is empty
|
// we need to reject when transcript is empty
|
||||||
if self.is_empty {
|
if self.is_empty {
|
||||||
return Err(PolyIOPErrors::InvalidTranscript(
|
return Err(TranscriptErrors::InvalidTranscript(
|
||||||
"transcript is empty".to_string(),
|
"transcript is empty".to_string(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -133,3 +116,14 @@ impl<F: PrimeField> IOPTranscript<F> {
|
|||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Takes as input a struct, and converts them to a series of bytes. All traits
|
||||||
|
/// that implement `CanonicalSerialize` can be automatically converted to bytes
|
||||||
|
/// in this manner.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! to_bytes {
|
||||||
|
($x:expr) => {{
|
||||||
|
let mut buf = ark_std::vec![];
|
||||||
|
ark_serialize::CanonicalSerialize::serialize($x, &mut buf).map(|_| buf)
|
||||||
|
}};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user