move transcript to trait (#46)

This commit is contained in:
zhenfei
2022-07-26 11:34:47 -04:00
committed by GitHub
parent 17cff52765
commit 229148eb5a
19 changed files with 122 additions and 72 deletions

View File

@@ -2,5 +2,6 @@
members = [ members = [
"hyperplonk", "hyperplonk",
"pcs", "pcs",
"poly-iop" "poly-iop",
"transcript",
] ]

View File

@@ -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"
] ]

View File

@@ -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)
} }
} }

View File

@@ -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)]

View File

@@ -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.

View File

@@ -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"

View File

@@ -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)
}
}

View File

@@ -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> {

View File

@@ -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;

View File

@@ -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(),
)) ))
}, },

View File

@@ -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.
/// ///

View File

@@ -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>,
} }

View File

@@ -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,

View File

@@ -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};

View File

@@ -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

View File

@@ -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
View 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
View 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)
}
}

View File

@@ -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)
}};
}