Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ name = "sumcheckeq"
harness = false

[features]
default = ["halo2curves/asm"]
default = ["halo2curves/asm", "io"]
flamegraph = ["pprof2/flamegraph", "pprof2/criterion"]
experimental = []
io = []
29 changes: 16 additions & 13 deletions src/digest.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
use crate::constants::NUM_HASH_BITS;
use bincode::{enc::write::Writer, error::EncodeError};
use ff::PrimeField;
use serde::Serialize;
use sha3::{Digest, Sha3_256};
use std::{io, marker::PhantomData};
use std::marker::PhantomData;

/// Trait for components with potentially discrete digests to be included in their container's digest.
pub trait Digestible {
/// Write the byte representation of Self in a byte buffer
fn write_bytes<W: Sized + io::Write>(&self, byte_sink: &mut W) -> Result<(), io::Error>;
fn write_bytes<W: Sized + Writer>(&self, byte_sink: &mut W) -> Result<(), EncodeError>;
}

/// Marker trait to be implemented for types that implement `Digestible` and `Serialize`.
/// Their instances will be serialized to bytes then digested.
pub trait SimpleDigestible: Serialize {}

impl<T: SimpleDigestible> Digestible for T {
fn write_bytes<W: Sized + io::Write>(&self, byte_sink: &mut W) -> Result<(), io::Error> {
fn write_bytes<W: Sized + Writer>(&self, byte_sink: &mut W) -> Result<(), EncodeError> {
let config = bincode::config::legacy()
.with_little_endian()
.with_fixed_int_encoding();
// Note: bincode recursively length-prefixes every field!
bincode::serde::encode_into_std_write(self, byte_sink, config)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
Ok(())
bincode::serde::encode_into_writer(self, byte_sink, config)
}
}

Expand Down Expand Up @@ -64,13 +63,17 @@ impl<'a, F: PrimeField, T: Digestible> DigestComputer<'a, F, T> {
}

/// Compute the digest of a `Digestible` instance.
pub fn digest(&self) -> Result<F, io::Error> {
let mut hasher = Self::hasher();
self
.inner
.write_bytes(&mut hasher)
.expect("Serialization error");
let bytes: [u8; 32] = hasher.finalize().into();
pub fn digest(&self) -> Result<F, EncodeError> {
struct Hasher(Sha3_256);
impl Writer for Hasher {
fn write(&mut self, bytes: &[u8]) -> Result<(), EncodeError> {
self.0.update(bytes);
Ok(())
}
}
let mut hasher = Hasher(Self::hasher());
self.inner.write_bytes(&mut hasher)?;
let bytes: [u8; 32] = hasher.0.finalize().into();
Ok(Self::map_to_field(&bytes))
}
}
Expand Down
11 changes: 4 additions & 7 deletions src/frontend/constraint_system.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{io, marker::PhantomData};
use std::marker::PhantomData;

use ff::PrimeField;

Expand All @@ -16,7 +16,7 @@ pub trait Circuit<Scalar: PrimeField> {
/// This is an error that could occur during circuit synthesis contexts,
/// such as CRS generation, proving or verification.
#[allow(clippy::upper_case_acronyms)]
#[derive(thiserror::Error, Debug)]
#[derive(thiserror::Error, Debug, Clone)]
pub enum SynthesisError {
/// During synthesis, we lacked knowledge of a variable assignment.
#[error("an assignment for a variable could not be computed")]
Expand All @@ -25,17 +25,14 @@ pub enum SynthesisError {
#[error("division by zero")]
DivisionByZero,
/// During synthesis, we constructed an unsatisfiable constraint system.
#[error("unsatisfiable constraint system")]
Unsatisfiable,
#[error("unsatisfiable constraint system: {0}")]
Unsatisfiable(String),
/// During synthesis, our polynomials ended up being too high of degree
#[error("polynomial degree is too large")]
PolynomialDegreeTooLarge,
/// During proof generation, we encountered an identity in the CRS
#[error("encountered an identity element in the CRS")]
UnexpectedIdentity,
/// During proof generation, we encountered an I/O error with the CRS
#[error("encountered an I/O error: {0}")]
IoError(#[from] io::Error),
/// During verification, our verifying key was malformed.
#[error("malformed verifying key")]
MalformedVerifyingKey,
Expand Down
4 changes: 3 additions & 1 deletion src/frontend/gadgets/boolean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,9 @@ impl Boolean {
if a == b {
Ok(())
} else {
Err(SynthesisError::Unsatisfiable)
Err(SynthesisError::Unsatisfiable(
"Booleans are not equal".to_string(),
))
}
}
(&Boolean::Constant(true), a) | (a, &Boolean::Constant(true)) => {
Expand Down
5 changes: 1 addition & 4 deletions src/frontend/gadgets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ pub trait Assignment<T> {

impl<T> Assignment<T> for Option<T> {
fn get(&self) -> Result<&T, SynthesisError> {
match *self {
Some(ref v) => Ok(v),
None => Err(SynthesisError::AssignmentMissing),
}
self.as_ref().ok_or(SynthesisError::AssignmentMissing)
}
}
1 change: 1 addition & 0 deletions src/frontend/util_cs/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//! The `util_cs` module provides a set of utilities for working with constraint system

#[cfg(test)]
pub mod test_cs;
pub mod witness_cs;
21 changes: 10 additions & 11 deletions src/gadgets/nonnative/bignat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ pub fn nat_to_limbs<Scalar: PrimeField>(
.collect(),
)
} else {
eprintln!("nat {nat} does not fit in {n_limbs} limbs of width {limb_width}");
Err(SynthesisError::Unsatisfiable)
Err(SynthesisError::Unsatisfiable(format!(
"nat {nat} does not fit in {n_limbs} limbs of width {limb_width}"
)))
}
}

Expand Down Expand Up @@ -132,8 +133,9 @@ impl<Scalar: PrimeField> BigNat<Scalar> {
|| match values_cell {
Ok(ref vs) => {
if vs.len() != n_limbs {
eprintln!("Values do not match stated limb count");
return Err(SynthesisError::Unsatisfiable);
return Err(SynthesisError::Unsatisfiable(
"Values do not match stated limb count".to_string(),
));
}
if value.is_none() {
value = Some(limbs_to_nat::<Scalar, _, _>(vs.iter(), limb_width));
Expand All @@ -143,8 +145,7 @@ impl<Scalar: PrimeField> BigNat<Scalar> {
}
Ok(vs[limb_i])
}
// Hack b/c SynthesisError and io::Error don't implement Clone
Err(ref e) => Err(SynthesisError::from(std::io::Error::other(format!("{e}")))),
Err(ref e) => Err(e.clone()),
},
)
.map(|v| LinearCombination::zero() + v)
Expand Down Expand Up @@ -192,8 +193,7 @@ impl<Scalar: PrimeField> BigNat<Scalar> {
limb_values.push(vs[limb_i]);
Ok(vs[limb_i])
}
// Hack b/c SynthesisError and io::Error don't implement Clone
Err(ref e) => Err(SynthesisError::from(std::io::Error::other(format!("{e}")))),
Err(ref e) => Err(e.clone()),
},
)
.map(|v| LinearCombination::zero() + v)
Expand Down Expand Up @@ -317,11 +317,10 @@ impl<Scalar: PrimeField> BigNat<Scalar> {
if self.params.limb_width == other.params.limb_width {
Ok(self.params.limb_width)
} else {
eprintln!(
Err(SynthesisError::Unsatisfiable(format!(
"Limb widths {}, {}, do not agree at {}",
self.params.limb_width, other.params.limb_width, location
);
Err(SynthesisError::Unsatisfiable)
)))
}
}

Expand Down
16 changes: 1 addition & 15 deletions src/gadgets/nonnative/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,9 @@ use super::{BitAccess, OptionExt};
use crate::frontend::{
num::AllocatedNum, ConstraintSystem, LinearCombination, SynthesisError, Variable,
};
use byteorder::WriteBytesExt;
use ff::PrimeField;
use num_bigint::{BigInt, Sign};
use std::{
convert::From,
io::{self, Write},
};
use std::convert::From;

#[derive(Clone)]
/// A representation of a bit
Expand Down Expand Up @@ -232,18 +228,8 @@ impl<Scalar: PrimeField> From<AllocatedNum<Scalar>> for Num<Scalar> {
}
}

fn write_be<F: PrimeField, W: Write>(f: &F, mut writer: W) -> io::Result<()> {
for digit in f.to_repr().as_ref().iter().rev() {
writer.write_u8(*digit)?;
}

Ok(())
}

/// Convert a field element to a natural number
pub fn f_to_nat<Scalar: PrimeField>(f: &Scalar) -> BigInt {
let mut s = Vec::new();
write_be(f, &mut s).unwrap(); // f.to_repr().write_be(&mut s).unwrap();
BigInt::from_bytes_le(Sign::Plus, f.to_repr().as_ref())
}

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
)]
#![allow(non_snake_case)]
#![forbid(unsafe_code)]
#![cfg_attr(not(test), warn(clippy::print_stdout, clippy::print_stderr))]

// main APIs exposed by this library
pub mod nova;
Expand Down
4 changes: 1 addition & 3 deletions src/neutron/relation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,8 @@ impl<E: Engine> Structure<E> {
.reduce(|| E::Scalar::ZERO, |acc, x| acc + x);

if sum != U.T {
println!("sum: {:?}", sum);
println!("U.T: {:?}", U.T);
return Err(NovaError::UnSat {
reason: "sum != U.T".to_string(),
reason: format!("sum != U.T\n sum: {:?}\n U.T: {:?}", sum, U.T),
});
}

Expand Down
1 change: 0 additions & 1 deletion src/provider/bn256_grumpkin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ use num_integer::Integer;
use num_traits::{Num, ToPrimitive};
use rayon::prelude::*;
use sha3::Shake256;
use std::io::Read;

/// Re-exports that give access to the standard aliases used in the code base, for bn256
pub mod bn256 {
Expand Down
11 changes: 5 additions & 6 deletions src/provider/hyperkzg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,12 @@
//! (2) HyperKZG is specialized to use KZG as the univariate commitment scheme, so it includes several optimizations (both during the transformation of multilinear-to-univariate claims
//! and within the KZG commitment scheme implementation itself).
#![allow(non_snake_case)]
#[cfg(feature = "io")]
use crate::provider::{ptau::PtauFileError, read_ptau, write_ptau};
use crate::{
errors::NovaError,
gadgets::utils::to_bignat_repr,
provider::{
ptau::PtauFileError,
read_ptau,
traits::{DlogGroup, DlogGroupExt, PairingGroup},
write_ptau,
},
provider::traits::{DlogGroup, DlogGroupExt, PairingGroup},
traits::{
commitment::{CommitmentEngineTrait, CommitmentTrait, Len},
evaluation::EvaluationEngineTrait,
Expand Down Expand Up @@ -140,6 +137,7 @@ where
E::GE: PairingGroup,
{
/// Save keys
#[cfg(feature = "io")]
pub fn save_to(
&self,
mut writer: &mut (impl std::io::Write + std::io::Seek),
Expand Down Expand Up @@ -541,6 +539,7 @@ where
}
}

#[cfg(feature = "io")]
fn load_setup(
reader: &mut (impl std::io::Read + std::io::Seek),
label: &'static [u8],
Expand Down
2 changes: 2 additions & 0 deletions src/provider/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub mod secp_secq;
pub(crate) mod blitzar;
pub(crate) mod keccak;
pub(crate) mod pedersen;
#[cfg(feature = "io")]
pub(crate) mod ptau;
pub(crate) mod traits;

Expand All @@ -31,6 +32,7 @@ use crate::{
},
traits::Engine,
};
#[cfg(feature = "io")]
pub use ptau::{check_sanity_of_ptau_file, read_ptau, write_ptau};
use serde::{Deserialize, Serialize};

Expand Down
1 change: 0 additions & 1 deletion src/provider/pasta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use num_integer::Integer;
use num_traits::{Num, ToPrimitive};
use rayon::prelude::*;
use sha3::Shake256;
use std::io::Read;

/// Re-exports that give access to the standard aliases used in the code base, for pallas
pub mod pallas {
Expand Down
10 changes: 6 additions & 4 deletions src/provider/pedersen.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
//! This module provides an implementation of a commitment engine
#[cfg(feature = "io")]
use crate::provider::ptau::{read_points, write_points, PtauFileError};
use crate::{
errors::NovaError,
gadgets::utils::to_bignat_repr,
provider::{
ptau::{read_points, write_points, PtauFileError},
traits::{DlogGroup, DlogGroupExt},
},
provider::traits::{DlogGroup, DlogGroupExt},
traits::{
commitment::{CommitmentEngineTrait, CommitmentTrait, Len},
AbsorbInRO2Trait, AbsorbInROTrait, Engine, ROTrait, TranscriptReprTrait,
Expand All @@ -22,6 +21,7 @@ use num_traits::ToPrimitive;
use rayon::prelude::*;
use serde::{Deserialize, Serialize};

#[cfg(feature = "io")]
const KEY_FILE_HEAD: [u8; 12] = *b"PEDERSEN_KEY";

/// A type that holds commitment generators
Expand Down Expand Up @@ -192,6 +192,7 @@ impl<E: Engine> CommitmentKey<E>
where
E::GE: DlogGroup,
{
#[cfg(feature = "io")]
pub fn save_to(&self, writer: &mut impl std::io::Write) -> Result<(), PtauFileError> {
writer.write_all(&KEY_FILE_HEAD)?;
let mut points = Vec::with_capacity(self.ck.len() + 1);
Expand Down Expand Up @@ -278,6 +279,7 @@ where
}
}

#[cfg(feature = "io")]
fn load_setup(
reader: &mut (impl std::io::Read + std::io::Seek),
_label: &'static [u8],
Expand Down
1 change: 0 additions & 1 deletion src/provider/secp_secq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ use num_integer::Integer;
use num_traits::{Num, ToPrimitive};
use rayon::prelude::*;
use sha3::Shake256;
use std::io::Read;

/// Re-exports that give access to the standard aliases used in the code base, for secp
pub mod secp256k1 {
Expand Down
2 changes: 1 addition & 1 deletion src/provider/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ macro_rules! impl_traits_no_dlog_ext {
let mut uniform_bytes_vec = Vec::new();
for _ in 0..n {
let mut uniform_bytes = [0u8; 32];
reader.read_exact(&mut uniform_bytes).unwrap();
digest::XofReader::read(&mut reader, &mut uniform_bytes);
uniform_bytes_vec.push(uniform_bytes);
}
let gens_proj: Vec<$name_curve> = (0..n)
Expand Down
9 changes: 0 additions & 9 deletions src/spartan/polys/univariate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,15 +157,6 @@ pub fn gaussian_elimination<F: PrimeField>(matrix: &mut [Vec<F>]) -> Vec<F> {
eliminate(matrix, i);
}

// Disable cargo clippy warnings about needless range loops.
// Checking the diagonal like this is simpler than any alternative.
#[allow(clippy::needless_range_loop)]
for i in 0..size {
if matrix[i][i] == F::ZERO {
println!("Infinitely many solutions");
}
}

let mut result: Vec<F> = vec![F::ZERO; size];
for i in 0..size {
result[i] = div_f(matrix[i][size], matrix[i][i]);
Expand Down
Loading