Skip to content

Commit

Permalink
Merge branch 'release/2.0.0' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
hdevalence committed Jan 18, 2020
2 parents 4b9d2c9 + 7ac88e1 commit 1a10ce1
Show file tree
Hide file tree
Showing 23 changed files with 452 additions and 190 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

Entries are listed in reverse chronological order.

## 2.0.0

* Switch from `failure` to `std`-compatible errors via `thiserror`.
* Update `rand`, `curve25519-dalek`, `merlin` versions.
* Adds `no_std` support by @xoloki.

## 1.0.4

* Change doc-include paths to allow compilation on the latest Rust nightly
Expand Down
43 changes: 24 additions & 19 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
[package]
name = "bulletproofs"
version = "1.0.4"
# Before doing a release:
# - update version field
# - update html_root_url
# - ensure yoloproofs was disabled in an atomic (revertable) commit
# - update CHANGELOG
version = "2.0.0"
authors = ["Cathie Yun <[email protected]>",
"Henry de Valence <[email protected]>",
"Oleg Andreev <[email protected]>"]
Expand All @@ -10,33 +15,33 @@ repository = "https://github.com/dalek-cryptography/bulletproofs"
categories = ["cryptography"]
keywords = ["cryptography", "crypto", "ristretto", "zero-knowledge", "bulletproofs"]
description = "A pure-Rust implementation of Bulletproofs using Ristretto"
edition = "2018"

[dependencies]
curve25519-dalek = { version = "1.0.3", features = ["serde"] }
subtle = "2"
sha3 = "0.8"
digest = "0.8"
rand = "0.6"
byteorder = "1"
serde = "1"
serde_derive = "1"
failure = "0.1"
merlin = "1.1"
clear_on_drop = "0.2"
curve25519-dalek = { version = "2", default-features = false, features = ["u64_backend", "nightly", "serde", "alloc"] }
subtle = { version = "2", default-features = false }
sha3 = { version = "0.8", default-features = false }
digest = { version = "0.8", default-features = false }
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 }
thiserror = { version = "1", optional = true }
merlin = { version = "2", default-features = false }
clear_on_drop = { version = "0.2", default-features = false, features = ["nightly"] }

[dev-dependencies]
hex = "0.3"
criterion = "0.2"
criterion = "0.3"
bincode = "1"
rand_chacha = "0.1"
rand_chacha = "0.2"

[features]
default = ["std", "avx2_backend"]
avx2_backend = ["curve25519-dalek/avx2_backend"]
# Disable the yoloproofs feature in the released crate.
# To test it, use a git dependency on the develop branch and enable the
# yoloproofs feature. Note that this means it's impossible to publish a crate
# depending on the unstable R1CS API.
#yoloproofs = []
# yoloproofs = []
std = ["rand", "rand/std", "thiserror"]

[[test]]
name = "range_proof"
Expand Down
1 change: 0 additions & 1 deletion benches/generators.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
extern crate bulletproofs;
use bulletproofs::{BulletproofGens, PedersenGens};

#[macro_use]
Expand Down
7 changes: 4 additions & 3 deletions benches/r1cs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ use bulletproofs::{BulletproofGens, PedersenGens};
use curve25519_dalek::ristretto::CompressedRistretto;
use curve25519_dalek::scalar::Scalar;
use merlin::Transcript;
use rand::{thread_rng, Rng};
use rand::seq::SliceRandom;
use rand::Rng;

// Shuffle gadget (documented in markdown file)

Expand Down Expand Up @@ -177,7 +178,7 @@ fn bench_kshuffle_prove(c: &mut Criterion) {
.map(|_| Scalar::from(rng.gen_range(min, max)))
.collect();
let mut output = input.clone();
rand::thread_rng().shuffle(&mut output);
output.shuffle(&mut rand::thread_rng());

// Make kshuffle proof
b.iter(|| {
Expand Down Expand Up @@ -219,7 +220,7 @@ fn bench_kshuffle_verify(c: &mut Criterion) {
.map(|_| Scalar::from(rng.gen_range(min, max)))
.collect();
let mut output = input.clone();
rand::thread_rng().shuffle(&mut output);
output.shuffle(&mut rand::thread_rng());

let mut prover_transcript = Transcript::new(b"ShuffleBenchmark");

Expand Down
5 changes: 1 addition & 4 deletions benches/range_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@
extern crate criterion;
use criterion::Criterion;

extern crate rand;
use rand;
use rand::Rng;

extern crate curve25519_dalek;
use curve25519_dalek::scalar::Scalar;

extern crate merlin;
use merlin::Transcript;

extern crate bulletproofs;
use bulletproofs::RangeProof;
use bulletproofs::{BulletproofGens, PedersenGens};

Expand Down
15 changes: 5 additions & 10 deletions docs/notes-r1cs.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,7 @@ the proof would still work if \\({\mathbf{a}}\_{O}\\) was rearranged on the righ
If we reorder terms, we get:

\\[
w\_c + \langle \mathbf{w}\_V, \mathbf{v} \rangle
=
w\_c + \langle \mathbf{w}\_V, \mathbf{v} \rangle =
\langle \mathbf{a}\_L \circ \mathbf{a}\_R, \mathbf{y}^n \rangle -
\langle \mathbf{a}\_O, \mathbf{y}^n \rangle +
\langle \mathbf{w}\_L, \mathbf{a}\_L \rangle +
Expand All @@ -266,8 +265,7 @@ w\_c + \langle \mathbf{w}\_V, \mathbf{v} \rangle
Merge the statements containing \\(\mathbf{a}\_O \\):

\\[
w\_c + \langle \mathbf{w}\_V, \mathbf{v} \rangle
=
w\_c + \langle \mathbf{w}\_V, \mathbf{v} \rangle =
\langle \mathbf{a}\_L \circ \mathbf{a}\_R, \mathbf{y}^n \rangle +
\langle \mathbf{a}\_L, \mathbf{w}\_L \rangle +
\langle \mathbf{a}\_O, -\mathbf{y}^n + \mathbf{w}\_O \rangle +
Expand All @@ -278,8 +276,7 @@ Rearrange \\(\langle \mathbf{a}\_L \circ \mathbf{a}\_R, \mathbf{y}^n \rangle\\)
\\(\langle \mathbf{a}\_L, \mathbf{y}^n \circ \mathbf{a}\_R \rangle\\):

\\[
w\_c + \langle \mathbf{w}\_V, \mathbf{v} \rangle
=
w\_c + \langle \mathbf{w}\_V, \mathbf{v} \rangle =
\langle \mathbf{a}\_L, \mathbf{y}^n \circ \mathbf{a}\_R \rangle +
\langle \mathbf{a}\_L, \mathbf{w}\_L \rangle +
\langle \mathbf{a}\_O, -\mathbf{y}^n + \mathbf{w}\_O \rangle +
Expand All @@ -290,8 +287,7 @@ Multiply the \\( \langle \mathbf{a}\_R,
\mathbf{w}\_R \rangle \\) term by \\(\mathbf{y}^n\\) one one side of the inner product and by \\(\mathbf{y}^{-n}\\) on the other side:

\\[
w\_c + \langle \mathbf{w}\_V, \mathbf{v} \rangle
=
w\_c + \langle \mathbf{w}\_V, \mathbf{v} \rangle =
\langle \mathbf{a}\_L, \mathbf{y}^n \circ \mathbf{a}\_R \rangle +
\langle \mathbf{a}\_L, \mathbf{w}\_L \rangle +
\langle \mathbf{a}\_O, -\mathbf{y}^n + \mathbf{w}\_O \rangle +
Expand All @@ -301,8 +297,7 @@ w\_c + \langle \mathbf{w}\_V, \mathbf{v} \rangle
Merge the statements containing \\(\mathbf{y}^n \circ \mathbf{a}\_R\\):

\\[
w\_c + \langle \mathbf{w}\_V, \mathbf{v} \rangle
=
w\_c + \langle \mathbf{w}\_V, \mathbf{v} \rangle =
\langle \mathbf{a}\_L + \mathbf{y}^{-n} \circ \mathbf{w}\_R, \mathbf{y}^n \circ \mathbf{a}\_R \rangle +
\langle \mathbf{a}\_L, \mathbf{w}\_L \rangle +
\langle \mathbf{a}\_O, -\mathbf{y}^n + \mathbf{w}\_O \rangle
Expand Down
73 changes: 50 additions & 23 deletions src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,49 @@
//! Errors related to proving and verifying proofs.
extern crate alloc;
use alloc::vec::Vec;

#[cfg(feature = "std")]
use thiserror::Error;

/// Represents an error in proof creation, verification, or parsing.
#[derive(Fail, Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "std", derive(Error))]
pub enum ProofError {
/// This error occurs when a proof failed to verify.
#[fail(display = "Proof verification failed.")]
#[cfg_attr(feature = "std", error("Proof verification failed."))]
VerificationError,
/// This error occurs when the proof encoding is malformed.
#[fail(display = "Proof data could not be parsed.")]
#[cfg_attr(feature = "std", error("Proof data could not be parsed."))]
FormatError,
/// This error occurs during proving if the number of blinding
/// factors does not match the number of values.
#[fail(display = "Wrong number of blinding factors supplied.")]
#[cfg_attr(feature = "std", error("Wrong number of blinding factors supplied."))]
WrongNumBlindingFactors,
/// This error occurs when attempting to create a proof with
/// bitsize other than \\(8\\), \\(16\\), \\(32\\), or \\(64\\).
#[fail(display = "Invalid bitsize, must have n = 8,16,32,64.")]
#[cfg_attr(feature = "std", error("Invalid bitsize, must have n = 8,16,32,64."))]
InvalidBitsize,
/// This error occurs when attempting to create an aggregated
/// proof with non-power-of-two aggregation size.
#[fail(display = "Invalid aggregation size, m must be a power of 2.")]
#[cfg_attr(
feature = "std",
error("Invalid aggregation size, m must be a power of 2.")
)]
InvalidAggregation,
/// This error occurs when there are insufficient generators for the proof.
#[fail(display = "Invalid generators size, too few generators for proof")]
#[cfg_attr(
feature = "std",
error("Invalid generators size, too few generators for proof")
)]
InvalidGeneratorsLength,
/// This error results from an internal error during proving.
///
/// The single-party prover is implemented by performing
/// multiparty computation with ourselves. However, because the
/// MPC protocol is not exposed by the single-party API, we
/// consider its errors to be internal errors.
#[fail(display = "Internal error during proof creation: {}", _0)]
#[cfg_attr(feature = "std", error("Internal error during proof creation: {0}"))]
ProvingError(MPCError),
}

Expand All @@ -52,38 +65,48 @@ impl From<MPCError> for ProofError {
/// API: although the MPC protocol is used internally for single-party
/// proving, its API should not expose the complexity of the MPC
/// protocol.
#[derive(Fail, Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "std", derive(Error))]
pub enum MPCError {
/// This error occurs when the dealer gives a zero challenge,
/// which would annihilate the blinding factors.
#[fail(display = "Dealer gave a malicious challenge value.")]
#[cfg_attr(feature = "std", error("Dealer gave a malicious challenge value."))]
MaliciousDealer,
/// This error occurs when attempting to create a proof with
/// bitsize other than \\(8\\), \\(16\\), \\(32\\), or \\(64\\).
#[fail(display = "Invalid bitsize, must have n = 8,16,32,64")]
#[cfg_attr(feature = "std", error("Invalid bitsize, must have n = 8,16,32,64"))]
InvalidBitsize,
/// This error occurs when attempting to create an aggregated
/// proof with non-power-of-two aggregation size.
#[fail(display = "Invalid aggregation size, m must be a power of 2")]
#[cfg_attr(
feature = "std",
error("Invalid aggregation size, m must be a power of 2")
)]
InvalidAggregation,
/// This error occurs when there are insufficient generators for the proof.
#[fail(display = "Invalid generators size, too few generators for proof")]
#[cfg_attr(
feature = "std",
error("Invalid generators size, too few generators for proof")
)]
InvalidGeneratorsLength,
/// This error occurs when the dealer is given the wrong number of
/// value commitments.
#[fail(display = "Wrong number of value commitments")]
#[cfg_attr(feature = "std", error("Wrong number of value commitments"))]
WrongNumBitCommitments,
/// This error occurs when the dealer is given the wrong number of
/// polynomial commitments.
#[fail(display = "Wrong number of value commitments")]
#[cfg_attr(feature = "std", error("Wrong number of value commitments"))]
WrongNumPolyCommitments,
/// This error occurs when the dealer is given the wrong number of
/// proof shares.
#[fail(display = "Wrong number of proof shares")]
#[cfg_attr(feature = "std", error("Wrong number of proof shares"))]
WrongNumProofShares,
/// This error occurs when one or more parties submit malformed
/// proof shares.
#[fail(display = "Malformed proof shares from parties {:?}", bad_shares)]
#[cfg_attr(
feature = "std",
error("Malformed proof shares from parties {bad_shares:?}")
)]
MalformedProofShares {
/// A vector with the indexes of the parties whose shares were malformed.
bad_shares: Vec<usize>,
Expand All @@ -94,27 +117,31 @@ pub enum MPCError {
///
/// XXX: should this be separate from a `ProofError`?
#[cfg(feature = "yoloproofs")]
#[derive(Fail, Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "std", derive(Error))]
pub enum R1CSError {
/// Occurs when there are insufficient generators for the proof.
#[fail(display = "Invalid generators size, too few generators for proof")]
#[cfg_attr(
feature = "std",
error("Invalid generators size, too few generators for proof")
)]
InvalidGeneratorsLength,
/// This error occurs when the proof encoding is malformed.
#[fail(display = "Proof data could not be parsed.")]
#[cfg_attr(feature = "std", error("Proof data could not be parsed."))]
FormatError,
/// Occurs when verification of an
/// [`R1CSProof`](::r1cs::R1CSProof) fails.
#[fail(display = "R1CSProof did not verify correctly.")]
#[cfg_attr(feature = "std", error("R1CSProof did not verify correctly."))]
VerificationError,

/// Occurs when trying to use a missing variable assignment.
/// Used by gadgets that build the constraint system to signal that
/// a variable assignment is not provided when the prover needs it.
#[fail(display = "Variable does not have a value assignment.")]
#[cfg_attr(feature = "std", error("Variable does not have a value assignment."))]
MissingAssignment,

/// Occurs when a gadget receives an inconsistent input.
#[fail(display = "Gadget error: {:?}", description)]
#[cfg_attr(feature = "std", error("Gadget error: {description:?}"))]
GadgetError {
/// The description of the reasons for the error.
description: String,
Expand Down
8 changes: 5 additions & 3 deletions src/generators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
#![allow(non_snake_case)]
#![deny(missing_docs)]

extern crate alloc;

use alloc::vec::Vec;
use curve25519_dalek::constants::RISTRETTO_BASEPOINT_COMPRESSED;
use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT;
use curve25519_dalek::ristretto::RistrettoPoint;
use curve25519_dalek::scalar::Scalar;
use curve25519_dalek::traits::MultiscalarMul;

use digest::{ExtendableOutput, Input, XofReader};
use sha3::{Sha3XofReader, Sha3_512, Shake256};

Expand Down Expand Up @@ -165,7 +167,7 @@ impl BulletproofGens {

/// Returns j-th share of generators, with an appropriate
/// slice of vectors G and H for the j-th range proof.
pub fn share(&self, j: usize) -> BulletproofGensShare {
pub fn share(&self, j: usize) -> BulletproofGensShare<'_> {
BulletproofGensShare {
gens: &self,
share: j,
Expand Down Expand Up @@ -251,7 +253,7 @@ impl<'a> Iterator for AggregatedGensIter<'a> {
}

fn size_hint(&self) -> (usize, Option<usize>) {
let size = self.n * self.m;
let size = self.n * (self.m - self.party_idx) - self.gen_idx;
(size, Some(size))
}
}
Expand Down
Loading

0 comments on commit 1a10ce1

Please sign in to comment.