Skip to content

Commit

Permalink
Merge pull request #3 from edgeware-builders/build-update
Browse files Browse the repository at this point in the history
Compiling to no_std
  • Loading branch information
drewstone committed Nov 24, 2020
2 parents e8615e4 + 2d426d3 commit 74e4306
Show file tree
Hide file tree
Showing 11 changed files with 190 additions and 175 deletions.
10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ description = "A pure-Rust implementation of Bulletproofs using Ristretto"
edition = "2018"

[dependencies]
curve25519-dalek = { version = "3.0.0", default-features = false, features = ["u64_backend", "nightly", "serde", "alloc"] }
curve25519-dalek = { version = "3.0.0", default-features = false, features = ["u64_backend", "nightly", "alloc"] }
subtle = { version = "2", default-features = false }
sha3 = { version = "0.9.1", default-features = false }
digest = { version = "0.9.0", default-features = false }
digest = { version = "0.9.0", default-features = false, features = ["alloc"] }
rand_core = { version = "0.5", default-features = false, features = ["alloc"] }
rand = { version = "0.7", default-features = false, optional = true }
byteorder = { version = "1", default-features = false }
serde = { version = "1", default-features = false, features = ["alloc"] }
serde_derive = { version = "1", default-features = false }
# serde = { version = "1", default-features = false, features = ["alloc"] }
# serde_derive = { version = "1", default-features = false }
thiserror = { version = "1", optional = true }
merlin = { version = "2", default-features = false }
clear_on_drop = { version = "0.2", default-features = false, features = ["nightly"] }
Expand All @@ -38,7 +38,7 @@ bincode = "1"
rand_chacha = "0.2"

[features]
default = ["std", "yoloproofs"]
default = ["std"]
avx2_backend = ["curve25519-dalek/avx2_backend"]
yoloproofs = []
std = ["rand", "rand/std", "thiserror"]
Expand Down
13 changes: 6 additions & 7 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,12 @@ pub enum R1CSError {
/// a variable assignment is not provided when the prover needs it.
#[cfg_attr(feature = "std", error("Variable does not have a value assignment."))]
MissingAssignment,

/// Occurs when a gadget receives an inconsistent input.
#[cfg_attr(feature = "std", error("Gadget error: {description:?}"))]
GadgetError {
/// The description of the reasons for the error.
description: String,
},
// Occurs when a gadget receives an inconsistent input.
// #[cfg_attr(feature = "std", error("Gadget error: {description:?}"))]
// GadgetError {
// /// The description of the reasons for the error.
// description: String,
// },
}

#[cfg(feature = "yoloproofs")]
Expand Down
2 changes: 1 addition & 1 deletion src/generators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT;
use curve25519_dalek::ristretto::RistrettoPoint;
use curve25519_dalek::scalar::Scalar;
use curve25519_dalek::traits::MultiscalarMul;
use digest::{XofReader, ExtendableOutputDirty, Update};
use digest::{ExtendableOutputDirty, Update, XofReader};
use sha3::{Sha3XofReader, Sha3_512, Shake256};

/// Represents a pair of base points for Pedersen commitments.
Expand Down
5 changes: 3 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
#![doc(html_logo_url = "https://doc.dalek.rs/assets/dalek-logo-clear.png")]
#![doc(html_root_url = "https://docs.rs/bulletproofs/2.0.0")]

#[macro_use]
extern crate alloc;

#[macro_use]
extern crate serde_derive;
// #[macro_use]
// extern crate serde_derive;

mod util;

Expand Down
5 changes: 4 additions & 1 deletion src/r1cs/constraint_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,10 @@ pub trait ConstraintSystem {
/// Allocate a single variable using a closure, similar to `allocate`.
/// When allocating left variable, return left variable and None.
/// When allocating right variable, return right variable and output variable.
fn allocate_single(&mut self, assignment: Option<Scalar>) -> Result<(Variable, Option<Variable>), R1CSError>;
fn allocate_single(
&mut self,
assignment: Option<Scalar>,
) -> Result<(Variable, Option<Variable>), R1CSError>;
}

/// An extension to the constraint system trait that permits randomized constraints.
Expand Down
29 changes: 3 additions & 26 deletions src/r1cs/linear_combination.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
//! Definition of linear combinations.

use alloc::vec::Vec;
use core::iter::FromIterator;
use core::ops::{Add, Mul, Neg, Sub};
use curve25519_dalek::scalar::Scalar;
#[cfg(feature = "std")]
use std::collections::HashMap;
#[cfg(feature = "std")]
use std::iter::FromIterator;
#[cfg(feature = "std")]
use std::ops::{Add, Mul, Neg, Sub};

/// Represents a variable in a constraint system.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -119,26 +116,6 @@ impl LinearCombination {
pub fn get_terms(self) -> Vec<(Variable, Scalar)> {
self.terms
}

/// Simplify linear combination by taking Variables common across terms and adding their corresponding scalars.
/// Useful when linear combinations become large. Takes ownership of linear combination as this function is useful
/// when memory is limited and the obvious action after this function call will be to free the memory held by the old linear combination
#[cfg(feature = "std")]
pub fn simplify(self) -> Self {
// Build hashmap to hold unique variables with their values.
let mut vars: HashMap<Variable, Scalar> = HashMap::new();

let terms = self.get_terms();
for (var, val) in terms {
*vars.entry(var).or_insert(Scalar::zero()) += val;
}

let mut new_lc_terms = vec![];
for (var, val) in vars {
new_lc_terms.push((var, val));
}
new_lc_terms.iter().collect()
}
}

impl Default for LinearCombination {
Expand Down
87 changes: 44 additions & 43 deletions src/r1cs/proof.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![allow(non_snake_case)]
//! Definition of the proof struct.

use alloc::vec::Vec;
use curve25519_dalek::ristretto::CompressedRistretto;
use curve25519_dalek::scalar::Scalar;
use curve25519_dalek::traits::{Identity, IsIdentity};
Expand All @@ -9,8 +10,8 @@ use crate::errors::R1CSError;
use crate::inner_product_proof::InnerProductProof;
use crate::util;

use serde::de::Visitor;
use serde::{self, Deserialize, Deserializer, Serialize, Serializer};
// use serde::de::Visitor;
// use serde::{self, Deserialize, Deserializer, Serialize, Serializer};

const ONE_PHASE_COMMITMENTS: u8 = 0;
const TWO_PHASE_COMMITMENTS: u8 = 1;
Expand Down Expand Up @@ -204,44 +205,44 @@ impl R1CSProof {
}
}

impl Serialize for R1CSProof {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_bytes(&self.to_bytes()[..])
}
}

impl<'de> Deserialize<'de> for R1CSProof {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct R1CSProofVisitor;

impl<'de> Visitor<'de> for R1CSProofVisitor {
type Value = R1CSProof;

fn expecting(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
formatter.write_str("a valid R1CSProof")
}

fn visit_bytes<E>(self, v: &[u8]) -> Result<R1CSProof, E>
where
E: serde::de::Error,
{
// Using Error::custom requires T: Display, which our error
// type only implements when it implements std::error::Error.
#[cfg(feature = "std")]
return R1CSProof::from_bytes(v).map_err(serde::de::Error::custom);
// In no-std contexts, drop the error message.
#[cfg(not(feature = "std"))]
return R1CSProof::from_bytes(v)
.map_err(|_| serde::de::Error::custom("deserialization error"));
}
}

deserializer.deserialize_bytes(R1CSProofVisitor)
}
}
// impl Serialize for R1CSProof {
// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
// where
// S: Serializer,
// {
// serializer.serialize_bytes(&self.to_bytes()[..])
// }
// }

// impl<'de> Deserialize<'de> for R1CSProof {
// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
// where
// D: Deserializer<'de>,
// {
// struct R1CSProofVisitor;

// impl<'de> Visitor<'de> for R1CSProofVisitor {
// type Value = R1CSProof;

// fn expecting(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
// formatter.write_str("a valid R1CSProof")
// }

// fn visit_bytes<E>(self, v: &[u8]) -> Result<R1CSProof, E>
// where
// E: serde::de::Error,
// {
// // Using Error::custom requires T: Display, which our error
// // type only implements when it implements std::error::Error.
// #[cfg(feature = "std")]
// return R1CSProof::from_bytes(v).map_err(serde::de::Error::custom);
// // In no-std contexts, drop the error message.
// #[cfg(not(feature = "std"))]
// return R1CSProof::from_bytes(v)
// .map_err(|_| serde::de::Error::custom("deserialization error"));
// }
// }

// deserializer.deserialize_bytes(R1CSProofVisitor)
// }
// }
21 changes: 18 additions & 3 deletions src/r1cs/prover.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
#![allow(non_snake_case)]

use alloc::boxed::Box;
use alloc::vec::Vec;
use clear_on_drop::clear::Clear;
use core::mem;
use curve25519_dalek::ristretto::{CompressedRistretto, RistrettoPoint};
use curve25519_dalek::scalar::Scalar;
use curve25519_dalek::traits::{Identity, MultiscalarMul};
use merlin::Transcript;
use rand_core::{CryptoRng, RngCore};

use super::{
ConstraintSystem, LinearCombination, R1CSProof, RandomizableConstraintSystem,
Expand All @@ -17,6 +20,9 @@ use crate::generators::{BulletproofGens, PedersenGens};
use crate::inner_product_proof::InnerProductProof;
use crate::transcript::TranscriptProtocol;

#[cfg(feature = "std")]
use rand::thread_rng;

/// A [`ConstraintSystem`] implementation for use by the prover.
///
/// The prover commits high-level variables and their blinding factors `(v, v_blinding)`,
Expand Down Expand Up @@ -407,9 +413,19 @@ impl<'t, 'g> Prover<'t, 'g> {
}

/// Consume this `ConstraintSystem` to produce a proof.
#[cfg(feature = "std")]
pub fn prove(mut self, bp_gens: &BulletproofGens) -> Result<R1CSProof, R1CSError> {
self.prove_with_rng(&bp_gens, &mut thread_rng())
}

/// Consume this `ConstraintSystem` to produce a proof.
pub fn prove_with_rng<T: RngCore + CryptoRng>(
mut self,
bp_gens: &BulletproofGens,
prng: &mut T,
) -> Result<R1CSProof, R1CSError> {
use crate::util;
use std::iter;
use core::iter;

// Commit a length _suffix_ for the number of high-level variables.
// We cannot do this in advance because user can commit variables one-by-one,
Expand Down Expand Up @@ -438,8 +454,7 @@ impl<'t, 'g> Prover<'t, 'g> {
builder = builder.rekey_with_witness_bytes(b"v_blinding", v_b.as_bytes());
}

use rand::thread_rng;
builder.finalize(&mut thread_rng())
builder.finalize(prng)
};

// Commit to the first-phase low-level witness variables.
Expand Down
27 changes: 23 additions & 4 deletions src/r1cs/verifier.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
#![allow(non_snake_case)]

use alloc::boxed::Box;
use alloc::vec::Vec;
use core::mem;
use curve25519_dalek::ristretto::{CompressedRistretto, RistrettoPoint};
use curve25519_dalek::scalar::Scalar;
use curve25519_dalek::traits::VartimeMultiscalarMul;
use merlin::Transcript;
use rand_core::{CryptoRng, RngCore};

#[cfg(feature = "std")]
use rand::thread_rng;

use super::{
ConstraintSystem, LinearCombination, R1CSProof, RandomizableConstraintSystem,
Expand Down Expand Up @@ -121,6 +127,9 @@ impl<'t> ConstraintSystem for Verifier<'t> {
}

fn constrain(&mut self, lc: LinearCombination) {
// TODO: check that the linear combinations are valid
// (e.g. that variables are valid, that the linear combination
// evals to 0 for prover, etc).
self.constraints.push(lc);
}

Expand Down Expand Up @@ -347,17 +356,28 @@ impl<'t> Verifier<'t> {
}
}

#[cfg(feature = "std")]
pub fn verify(
mut self,
proof: &R1CSProof,
pc_gens: &PedersenGens,
bp_gens: &BulletproofGens,
) -> Result<(), R1CSError> {
self.verify_with_rng(proof, pc_gens, bp_gens, &mut thread_rng())
}

/// Consume this `VerifierCS` and attempt to verify the supplied `proof`.
/// The `pc_gens` and `bp_gens` are generators for Pedersen commitments and
/// Bulletproofs vector commitments, respectively. The
/// [`BulletproofGens`] should have `gens_capacity` greater than
/// the number of multiplication constraints that will eventually
/// be added into the constraint system.
pub fn verify(
pub fn verify_with_rng<T: RngCore + CryptoRng>(
mut self,
proof: &R1CSProof,
pc_gens: &PedersenGens,
bp_gens: &BulletproofGens,
prng: &mut T,
) -> Result<(), R1CSError> {
// Commit a length _suffix_ for the number of high-level variables.
// We cannot do this in advance because user can commit variables one-by-one,
Expand All @@ -384,7 +404,7 @@ impl<'t> Verifier<'t> {

use crate::inner_product_proof::inner_product;
use crate::util;
use std::iter;
use core::iter;

if bp_gens.gens_capacity < padded_n {
return Err(R1CSError::InvalidGeneratorsLength);
Expand Down Expand Up @@ -471,8 +491,7 @@ impl<'t> Verifier<'t> {
// Create a `TranscriptRng` from the transcript. The verifier
// has no witness data to commit, so this just mixes external
// randomness into the existing transcript.
use rand::thread_rng;
let mut rng = self.transcript.build_rng().finalize(&mut thread_rng());
let mut rng = self.transcript.build_rng().finalize(prng);
let r = Scalar::random(&mut rng);

let xx = x * x;
Expand Down
Loading

0 comments on commit 74e4306

Please sign in to comment.