Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

u128 and Scalar #364

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

Entries are listed in reverse chronological order.

## 3.0.0

* Update `curve25519-dalek`, `sha3`, `digest` and `merlin` versions.
* Add `scalar_range_proof` feature, which allow `RangeProof` to be used with `Scalar`.
* Allow range proof with bitsize n = 128.
* Use `u128` instead of `u64` in range proof.

## 2.0.0

* Switch from `failure` to `std`-compatible errors via `thiserror`.
Expand Down
21 changes: 15 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ name = "bulletproofs"
# - update html_root_url
# - ensure yoloproofs was disabled in an atomic (revertable) commit
# - update CHANGELOG
version = "2.0.0"
version = "3.0.0"
authors = ["Cathie Yun <[email protected]>",
"Henry de Valence <[email protected]>",
"Oleg Andreev <[email protected]>"]
Expand All @@ -15,20 +15,20 @@ 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"
edition = "2021"

[dependencies]
curve25519-dalek = { version = "2", default-features = false, features = ["u64_backend", "nightly", "serde", "alloc"] }
curve25519-dalek = { version = "3.2.0", 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 }
sha3 = { version = "0.9", default-features = false }
digest = { version = "0.9", 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 }
merlin = { version = "3", default-features = false }
clear_on_drop = { version = "0.2", default-features = false, features = ["nightly"] }

[dev-dependencies]
Expand All @@ -42,10 +42,15 @@ default = ["std", "avx2_backend"]
avx2_backend = ["curve25519-dalek/avx2_backend"]
# yoloproofs = []
std = ["rand", "rand/std", "thiserror"]
scalar_range_proof = []

[[test]]
name = "range_proof"

[[test]]
name = "scalar_range_proof"
required-features = ["scalar_range_proof"]

[[test]]
name = "r1cs"
required-features = ["yoloproofs"]
Expand All @@ -67,3 +72,7 @@ required-features = ["yoloproofs"]
name = "linear_proof"
harness = false

[[bench]]
name = "scalar_range_proof"
harness = false
required-features = ["scalar_range_proof"]
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,15 @@ The following example shows how to create and verify a 32-bit rangeproof.
// independently of the Bulletproofs generators.
let pc_gens = PedersenGens::default();

// Generators for Bulletproofs, valid for proofs up to bitsize 64
// Generators for Bulletproofs, valid for proofs up to bitsize 128
// and aggregation size up to 1.
let bp_gens = BulletproofGens::new(64, 1);
let bp_gens = BulletproofGens::new(128, 1);

// A secret value we want to prove lies in the range [0, 2^32)
let secret_value = 1037578891u64;
# #[cfg(not(feature = "scalar_range_proof"))]
let secret_value = 1037578891u128;
# #[cfg(feature = "scalar_range_proof")]
# let secret_value = &Scalar::from(1037578891u128);

// The API takes a blinding factor for the commitment.
let blinding = Scalar::random(&mut thread_rng());
Expand Down
36 changes: 31 additions & 5 deletions benches/range_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ use bulletproofs::{BulletproofGens, PedersenGens};
static AGGREGATION_SIZES: [usize; 6] = [1, 2, 4, 8, 16, 32];

fn create_aggregated_rangeproof_helper(n: usize, c: &mut Criterion) {
let label = format!("Aggregated {}-bit rangeproof creation", n);
#[cfg(not(feature = "scalar_range_proof"))]
let label = format!("Aggregated {}-bit rangeproof verification", n);
#[cfg(feature = "scalar_range_proof")]
let label = format!("Aggregated {}-bit rangeproof verification using Scalar", n);

c.bench_function_over_inputs(
&label,
Expand All @@ -25,8 +28,13 @@ fn create_aggregated_rangeproof_helper(n: usize, c: &mut Criterion) {
let bp_gens = BulletproofGens::new(n, m);
let mut rng = rand::thread_rng();

let (min, max) = (0u64, ((1u128 << n) - 1) as u64);
let values: Vec<u64> = (0..m).map(|_| rng.gen_range(min, max)).collect();
let (min, max) = (0u128, u128::MAX >> (u128::BITS as usize - n));

#[cfg(not(feature = "scalar_range_proof"))]
let values: Vec<u128> = (0..m).map(|_| rng.gen_range(min, max)).collect();
#[cfg(feature = "scalar_range_proof")]
let values: Vec<Scalar> = (0..m).map(|_| rng.gen_range(min, max).into()).collect();

let blindings: Vec<Scalar> = (0..m).map(|_| Scalar::random(&mut rng)).collect();

b.iter(|| {
Expand Down Expand Up @@ -63,8 +71,15 @@ fn create_aggregated_rangeproof_n_64(c: &mut Criterion) {
create_aggregated_rangeproof_helper(64, c);
}

fn create_aggregated_rangeproof_n_128(c: &mut Criterion) {
create_aggregated_rangeproof_helper(128, c);
}

fn verify_aggregated_rangeproof_helper(n: usize, c: &mut Criterion) {
#[cfg(not(feature = "scalar_range_proof"))]
let label = format!("Aggregated {}-bit rangeproof verification", n);
#[cfg(feature = "scalar_range_proof")]
let label = format!("Aggregated {}-bit rangeproof verification using Scalar", n);

c.bench_function_over_inputs(
&label,
Expand All @@ -73,8 +88,13 @@ fn verify_aggregated_rangeproof_helper(n: usize, c: &mut Criterion) {
let bp_gens = BulletproofGens::new(n, m);
let mut rng = rand::thread_rng();

let (min, max) = (0u64, ((1u128 << n) - 1) as u64);
let values: Vec<u64> = (0..m).map(|_| rng.gen_range(min, max)).collect();
let (min, max) = (0u128, u128::MAX >> (u128::BITS as usize - n));

#[cfg(not(feature = "scalar_range_proof"))]
let values: Vec<u128> = (0..m).map(|_| rng.gen_range(min, max)).collect();
#[cfg(feature = "scalar_range_proof")]
let values: Vec<Scalar> = (0..m).map(|_| rng.gen_range(min, max).into()).collect();

let blindings: Vec<Scalar> = (0..m).map(|_| Scalar::random(&mut rng)).collect();

let mut transcript = Transcript::new(b"AggregateRangeProofBenchmark");
Expand Down Expand Up @@ -115,6 +135,10 @@ fn verify_aggregated_rangeproof_n_64(c: &mut Criterion) {
verify_aggregated_rangeproof_helper(64, c);
}

fn verify_aggregated_rangeproof_n_128(c: &mut Criterion) {
verify_aggregated_rangeproof_helper(128, c);
}

criterion_group! {
name = create_rp;
config = Criterion::default().sample_size(10);
Expand All @@ -123,6 +147,7 @@ criterion_group! {
create_aggregated_rangeproof_n_16,
create_aggregated_rangeproof_n_32,
create_aggregated_rangeproof_n_64,
create_aggregated_rangeproof_n_128,
}

criterion_group! {
Expand All @@ -133,6 +158,7 @@ criterion_group! {
verify_aggregated_rangeproof_n_16,
verify_aggregated_rangeproof_n_32,
verify_aggregated_rangeproof_n_64,
verify_aggregated_rangeproof_n_128,
}

criterion_main!(create_rp, verify_rp);
148 changes: 148 additions & 0 deletions benches/scalar_range_proof.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
#![allow(non_snake_case)]
#[macro_use]
extern crate criterion;
use criterion::Criterion;

use rand;
use rand::Rng;

use curve25519_dalek::scalar::Scalar;

use merlin::Transcript;

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

static AGGREGATION_SIZES: [usize; 6] = [1, 2, 4, 8, 16, 32];

fn create_aggregated_rangeproof_helper(n: usize, c: &mut Criterion) {
let label = format!("Aggregated {}-bit rangeproof verification using Scalar", n);

c.bench_function_over_inputs(
&label,
move |b, &&m| {
let pc_gens = PedersenGens::default();
let bp_gens = BulletproofGens::new(n, m);
let mut rng = rand::thread_rng();

let (min, max) = (0u128, u128::MAX >> (u128::BITS as usize - n));
let values: Vec<Scalar> = (0..m).map(|_| rng.gen_range(min, max).into()).collect();
let blindings: Vec<Scalar> = (0..m).map(|_| Scalar::random(&mut rng)).collect();

b.iter(|| {
// Each proof creation requires a clean transcript.
let mut transcript = Transcript::new(b"AggregateRangeProofBenchmark");

RangeProof::prove_multiple(
&bp_gens,
&pc_gens,
&mut transcript,
&values,
&blindings,
n,
)
})
},
&AGGREGATION_SIZES,
);
}

fn create_aggregated_rangeproof_n_8(c: &mut Criterion) {
create_aggregated_rangeproof_helper(8, c);
}

fn create_aggregated_rangeproof_n_16(c: &mut Criterion) {
create_aggregated_rangeproof_helper(16, c);
}

fn create_aggregated_rangeproof_n_32(c: &mut Criterion) {
create_aggregated_rangeproof_helper(32, c);
}

fn create_aggregated_rangeproof_n_64(c: &mut Criterion) {
create_aggregated_rangeproof_helper(64, c);
}

fn create_aggregated_rangeproof_n_128(c: &mut Criterion) {
create_aggregated_rangeproof_helper(128, c);
}

fn verify_aggregated_rangeproof_helper(n: usize, c: &mut Criterion) {
let label = format!("Aggregated {}-bit rangeproof verification using Scalar", n);

c.bench_function_over_inputs(
&label,
move |b, &&m| {
let pc_gens = PedersenGens::default();
let bp_gens = BulletproofGens::new(n, m);
let mut rng = rand::thread_rng();

let (min, max) = (0u128, u128::MAX >> (u128::BITS as usize - n));
let values: Vec<Scalar> = (0..m).map(|_| rng.gen_range(min, max).into()).collect();
let blindings: Vec<Scalar> = (0..m).map(|_| Scalar::random(&mut rng)).collect();

let mut transcript = Transcript::new(b"AggregateRangeProofBenchmark");
let (proof, value_commitments) = RangeProof::prove_multiple(
&bp_gens,
&pc_gens,
&mut transcript,
&values,
&blindings,
n,
)
.unwrap();

b.iter(|| {
// Each proof creation requires a clean transcript.
let mut transcript = Transcript::new(b"AggregateRangeProofBenchmark");

proof.verify_multiple(&bp_gens, &pc_gens, &mut transcript, &value_commitments, n)
});
},
&AGGREGATION_SIZES,
);
}

fn verify_aggregated_rangeproof_n_8(c: &mut Criterion) {
verify_aggregated_rangeproof_helper(8, c);
}

fn verify_aggregated_rangeproof_n_16(c: &mut Criterion) {
verify_aggregated_rangeproof_helper(16, c);
}

fn verify_aggregated_rangeproof_n_32(c: &mut Criterion) {
verify_aggregated_rangeproof_helper(32, c);
}

fn verify_aggregated_rangeproof_n_64(c: &mut Criterion) {
verify_aggregated_rangeproof_helper(64, c);
}

fn verify_aggregated_rangeproof_n_128(c: &mut Criterion) {
verify_aggregated_rangeproof_helper(128, c);
}

criterion_group! {
name = create_rp;
config = Criterion::default().sample_size(10);
targets =
create_aggregated_rangeproof_n_8,
create_aggregated_rangeproof_n_16,
create_aggregated_rangeproof_n_32,
create_aggregated_rangeproof_n_64,
create_aggregated_rangeproof_n_128,
}

criterion_group! {
name = verify_rp;
config = Criterion::default();
targets =
verify_aggregated_rangeproof_n_8,
verify_aggregated_rangeproof_n_16,
verify_aggregated_rangeproof_n_32,
verify_aggregated_rangeproof_n_64,
verify_aggregated_rangeproof_n_128,
}

criterion_main!(create_rp, verify_rp);
2 changes: 1 addition & 1 deletion rust-toolchain
Original file line number Diff line number Diff line change
@@ -1 +1 @@
nightly-2019-07-31
nightly-2023-01-01
14 changes: 10 additions & 4 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ pub enum ProofError {
#[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\\).
#[cfg_attr(feature = "std", error("Invalid bitsize, must have n = 8,16,32,64."))]
/// bitsize other than \\(8\\), \\(16\\), \\(32\\), \\(64\\) or \\(128\\).
#[cfg_attr(
feature = "std",
error("Invalid bitsize, must have n = 8,16,32,64,128.")
)]
InvalidBitsize,
/// This error occurs when attempting to create an aggregated
/// proof with non-power-of-two aggregation size.
Expand Down Expand Up @@ -73,8 +76,11 @@ pub enum MPCError {
#[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\\).
#[cfg_attr(feature = "std", error("Invalid bitsize, must have n = 8,16,32,64"))]
/// bitsize other than \\(8\\), \\(16\\), \\(32\\), \\(64\\) or \\(128\\).
#[cfg_attr(
feature = "std",
error("Invalid bitsize, must have n = 8,16,32,64,128")
)]
InvalidBitsize,
/// This error occurs when attempting to create an aggregated
/// proof with non-power-of-two aggregation size.
Expand Down
10 changes: 5 additions & 5 deletions 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::{ExtendableOutput, Input, XofReader};
use digest::{ExtendableOutput, Update, XofReader};
use sha3::{Sha3XofReader, Sha3_512, Shake256};

/// Represents a pair of base points for Pedersen commitments.
Expand Down Expand Up @@ -63,11 +63,11 @@ impl GeneratorsChain {
/// Creates a chain of generators, determined by the hash of `label`.
fn new(label: &[u8]) -> Self {
let mut shake = Shake256::default();
shake.input(b"GeneratorsChain");
shake.input(label);
shake.update(b"GeneratorsChain");
shake.update(label);

GeneratorsChain {
reader: shake.xof_result(),
reader: shake.finalize_xof(),
}
}

Expand Down Expand Up @@ -169,7 +169,7 @@ impl BulletproofGens {
/// slice of vectors G and H for the j-th range proof.
pub fn share(&self, j: usize) -> BulletproofGensShare<'_> {
BulletproofGensShare {
gens: &self,
gens: self,
share: j,
}
}
Expand Down
Loading