Skip to content

Commit cc57967

Browse files
authored
Merge branch 'main' into note-edits-2
2 parents 3c04cb4 + 08ba98e commit cc57967

File tree

1 file changed

+52
-15
lines changed

1 file changed

+52
-15
lines changed

src/generators.rs

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,30 @@
44
#![allow(non_snake_case)]
55
#![deny(missing_docs)]
66

7+
use curve25519_dalek::constants::RISTRETTO_BASEPOINT_COMPRESSED;
8+
use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT;
79
use curve25519_dalek::ristretto::RistrettoPoint;
810
use curve25519_dalek::scalar::Scalar;
911
use curve25519_dalek::traits::MultiscalarMul;
1012

1113
use digest::{ExtendableOutput, Input, XofReader};
12-
use sha3::{Sha3XofReader, Shake256};
14+
use sha3::{Sha3XofReader, Sha3_512, Shake256};
1315

1416
/// Represents a pair of base points for Pedersen commitments.
17+
///
18+
/// The Bulletproofs implementation and API is designed to support
19+
/// pluggable bases for Pedersen commitments, so that the choice of
20+
/// bases is not hard-coded.
21+
///
22+
/// The default generators are:
23+
///
24+
/// * `B`: the `ristretto255` basepoint;
25+
/// * `B_blinding`: the result of `ristretto255` SHA3-512
26+
/// hash-to-group on input `B_bytes`.
1527
#[derive(Copy, Clone)]
1628
pub struct PedersenGens {
1729
/// Base for the committed value
1830
pub B: RistrettoPoint,
19-
2031
/// Base for the blinding factor
2132
pub B_blinding: RistrettoPoint,
2233
}
@@ -31,18 +42,17 @@ impl PedersenGens {
3142
impl Default for PedersenGens {
3243
fn default() -> Self {
3344
PedersenGens {
34-
B: GeneratorsChain::new(b"Bulletproofs.Generators.B")
35-
.next()
36-
.unwrap(),
37-
B_blinding: GeneratorsChain::new(b"Bulletproofs.Generators.B_blinding")
38-
.next()
39-
.unwrap(),
45+
B: RISTRETTO_BASEPOINT_POINT,
46+
B_blinding: RistrettoPoint::hash_from_bytes::<Sha3_512>(
47+
RISTRETTO_BASEPOINT_COMPRESSED.as_bytes(),
48+
),
4049
}
4150
}
4251
}
4352

44-
/// The `GeneratorsChain` creates an arbitrary-long sequence of orthogonal generators.
45-
/// The sequence can be deterministically produced starting with an arbitrary point.
53+
/// The `GeneratorsChain` creates an arbitrary-long sequence of
54+
/// orthogonal generators. The sequence can be deterministically
55+
/// produced starting with an arbitrary point.
4656
struct GeneratorsChain {
4757
reader: Sha3XofReader,
4858
}
@@ -75,14 +85,37 @@ impl Iterator for GeneratorsChain {
7585

7686
Some(RistrettoPoint::from_uniform_bytes(&uniform_bytes))
7787
}
78-
7988
fn size_hint(&self) -> (usize, Option<usize>) {
8089
(usize::max_value(), None)
8190
}
8291
}
8392

84-
/// The `BulletproofGens` struct contains all the generators needed for
85-
/// aggregating `m` range proofs of `n` bits each.
93+
/// The `BulletproofGens` struct contains all the generators needed
94+
/// for aggregating up to `m` range proofs of up to `n` bits each.
95+
///
96+
/// # Extensible Generator Generation
97+
///
98+
/// Instead of constructing a single vector of size `m*n`, as
99+
/// described in the Bulletproofs paper, we construct each party's
100+
/// generators separately.
101+
///
102+
/// To construct an arbitrary-length chain of generators, we apply
103+
/// SHAKE256 to a domain separator label, and feed each 64 bytes of
104+
/// XOF output into the `ristretto255` hash-to-group function.
105+
/// Each of the `m` parties' generators are constructed using a
106+
/// different domain separation label, and proving and verification
107+
/// uses the first `n` elements of the arbitrary-length chain.
108+
///
109+
/// This means that the aggregation size (number of
110+
/// parties) is orthogonal to the rangeproof size (number of bits),
111+
/// and allows using the same `BulletproofGens` object for different
112+
/// proving parameters.
113+
///
114+
/// This construction is also forward-compatible with constraint
115+
/// system proofs, which use a much larger slice of the generator
116+
/// chain, and even forward-compatible to multiparty aggregation of
117+
/// constraint system proofs, since the generators are namespaced by
118+
/// their party index.
86119
#[derive(Clone)]
87120
pub struct BulletproofGens {
88121
/// The maximum number of usable generators for each party.
@@ -105,6 +138,7 @@ impl BulletproofGens {
105138
/// `64`, the maximum bitsize of the rangeproofs. For circuit
106139
/// proofs, the capacity must be greater than the number of
107140
/// multipliers, rounded up to the next power of two.
141+
///
108142
/// * `party_capacity` is the maximum number of parties that can
109143
/// produce an aggregated proof.
110144
pub fn new(gens_capacity: usize, party_capacity: usize) -> Self {
@@ -200,11 +234,14 @@ impl<'a> Iterator for AggregatedGensIter<'a> {
200234
}
201235
}
202236

203-
/// The `BulletproofGensShare` is produced by `BulletproofGens::share()`.
237+
/// Represents a view of the generators used by a specific party in an
238+
/// aggregated proof.
204239
///
205240
/// The `BulletproofGens` struct represents generators for an aggregated
206241
/// range proof `m` proofs of `n` bits each; the `BulletproofGensShare`
207-
/// represents the generators for one of the `m` parties' shares.
242+
/// provides a view of the generators for one of the `m` parties' shares.
243+
///
244+
/// The `BulletproofGensShare` is produced by [`BulletproofGens::share()`].
208245
#[derive(Copy, Clone)]
209246
pub struct BulletproofGensShare<'a> {
210247
/// The parent object that this is a view into

0 commit comments

Comments
 (0)