Skip to content

Commit b0360e1

Browse files
authored
Merge pull request #128 from dalek-cryptography/rework-generators
Rework generators
2 parents 1703a79 + ca11f80 commit b0360e1

File tree

9 files changed

+63
-43
lines changed

9 files changed

+63
-43
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ description = "A pure-Rust implementation of Bulletproofs using Ristretto"
1414
[dependencies]
1515
curve25519-dalek = { version = "0.19", features = ["serde"] }
1616
subtle = "0.7"
17-
sha2 = "^0.7"
17+
sha3 = "0.7"
18+
digest = "0.7"
1819
rand = "0.5.0-pre.2"
1920
byteorder = "1.2.1"
2021
serde = "1"

benches/bulletproofs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ fn verify_aggregated_rangeproof_helper(n: usize, c: &mut Criterion) {
8787
).unwrap();
8888

8989
// XXX would be nice to have some convenience API for this
90-
let pg = &generators.pedersen_generators;
90+
let pg = &generators.pedersen_gens;
9191
let value_commitments: Vec<_> = values
9292
.iter()
9393
.zip(blindings.iter())

src/generators.rs

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

7-
// XXX we should use Sha3 everywhere
8-
use sha2::{Digest, Sha512};
9-
107
use curve25519_dalek::ristretto::RistrettoPoint;
118
use curve25519_dalek::scalar::Scalar;
129
use curve25519_dalek::traits::MultiscalarMul;
1310

11+
use digest::{ExtendableOutput, Input, XofReader};
12+
use sha3::{Sha3XofReader, Shake256};
13+
1414
/// The `GeneratorsChain` creates an arbitrary-long sequence of orthogonal generators.
1515
/// The sequence can be deterministically produced starting with an arbitrary point.
1616
struct GeneratorsChain {
17-
next_point: RistrettoPoint,
17+
reader: Sha3XofReader,
1818
}
1919

2020
impl GeneratorsChain {
2121
/// Creates a chain of generators, determined by the hash of `label`.
2222
fn new(label: &[u8]) -> Self {
23-
let mut hash = Sha512::default();
24-
hash.input(b"GeneratorsChainInit");
25-
hash.input(label);
26-
let next_point = RistrettoPoint::from_hash(hash);
27-
GeneratorsChain { next_point }
23+
let mut shake = Shake256::default();
24+
shake.process(b"GeneratorsChain");
25+
shake.process(label);
26+
27+
GeneratorsChain {
28+
reader: shake.xof_result(),
29+
}
2830
}
2931
}
3032

@@ -36,13 +38,16 @@ impl Default for GeneratorsChain {
3638

3739
impl Iterator for GeneratorsChain {
3840
type Item = RistrettoPoint;
41+
3942
fn next(&mut self) -> Option<Self::Item> {
40-
let current_point = self.next_point;
41-
let mut hash = Sha512::default();
42-
hash.input(b"GeneratorsChainNext");
43-
hash.input(current_point.compress().as_bytes());
44-
self.next_point = RistrettoPoint::from_hash(hash);
45-
Some(current_point)
43+
let mut uniform_bytes = [0u8; 64];
44+
self.reader.read(&mut uniform_bytes);
45+
46+
Some(RistrettoPoint::from_uniform_bytes(&uniform_bytes))
47+
}
48+
49+
fn size_hint(&self) -> (usize, Option<usize>) {
50+
(usize::max_value(), None)
4651
}
4752
}
4853

@@ -55,7 +60,7 @@ pub struct Generators {
5560
/// Number of values or parties
5661
pub m: usize,
5762
/// Bases for Pedersen commitments
58-
pub pedersen_generators: PedersenGenerators,
63+
pub pedersen_gens: PedersenGenerators,
5964
/// Per-bit generators for the bit values
6065
pub G: Vec<RistrettoPoint>,
6166
/// Per-bit generators for the bit blinding factors
@@ -70,7 +75,7 @@ pub struct Generators {
7075
#[derive(Copy, Clone)]
7176
pub struct GeneratorsView<'a> {
7277
/// Bases for Pedersen commitments
73-
pub pedersen_generators: &'a PedersenGenerators,
78+
pub pedersen_gens: &'a PedersenGenerators,
7479
/// Per-bit generators for the bit values
7580
pub G: &'a [RistrettoPoint],
7681
/// Per-bit generators for the bit blinding factors
@@ -109,16 +114,31 @@ impl Default for PedersenGenerators {
109114

110115
impl Generators {
111116
/// Creates generators for `m` range proofs of `n` bits each.
112-
pub fn new(pedersen_generators: PedersenGenerators, n: usize, m: usize) -> Self {
113-
let G = GeneratorsChain::new(pedersen_generators.B.compress().as_bytes())
114-
.take(n * m)
117+
pub fn new(pedersen_gens: PedersenGenerators, n: usize, m: usize) -> Self {
118+
use byteorder::{ByteOrder, LittleEndian};
119+
120+
let G = (0..m)
121+
.flat_map(|i| {
122+
let party_index = i as u32;
123+
let mut label = [b'G', 0, 0, 0, 0];
124+
LittleEndian::write_u32(&mut label[1..5], party_index);
125+
126+
GeneratorsChain::new(&label).take(n)
127+
})
115128
.collect();
116-
let H = GeneratorsChain::new(pedersen_generators.B_blinding.compress().as_bytes())
117-
.take(n * m)
129+
130+
let H = (0..m)
131+
.flat_map(|i| {
132+
let party_index = i as u32;
133+
let mut label = [b'H', 0, 0, 0, 0];
134+
LittleEndian::write_u32(&mut label[1..5], party_index);
135+
136+
GeneratorsChain::new(&label).take(n)
137+
})
118138
.collect();
119139

120140
Generators {
121-
pedersen_generators,
141+
pedersen_gens,
122142
n,
123143
m,
124144
G,
@@ -132,7 +152,7 @@ impl Generators {
132152
let lower = self.n * j;
133153
let upper = self.n * (j + 1);
134154
GeneratorsView {
135-
pedersen_generators: &self.pedersen_generators,
155+
pedersen_gens: &self.pedersen_gens,
136156
G: &self.G[lower..upper],
137157
H: &self.H[lower..upper],
138158
}

src/inner_product_proof.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ mod tests {
326326
use super::*;
327327

328328
use rand::OsRng;
329-
use sha2::Sha512;
329+
use sha3::Sha3_512;
330330
use util;
331331

332332
fn test_helper_create(n: usize) {
@@ -338,7 +338,7 @@ mod tests {
338338
let H = gens.share(0).H.to_vec();
339339

340340
// Q would be determined upstream in the protocol, so we pick a random one.
341-
let Q = RistrettoPoint::hash_from_bytes::<Sha512>(b"test point");
341+
let Q = RistrettoPoint::hash_from_bytes::<Sha3_512>(b"test point");
342342

343343
// a and b are the vectors for which we want to prove c = <a,b>
344344
let a: Vec<_> = (0..n).map(|_| Scalar::random(&mut rng)).collect();

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@
1111
extern crate byteorder;
1212
extern crate core;
1313
extern crate curve25519_dalek;
14+
extern crate digest;
1415
#[macro_use]
1516
extern crate failure;
1617
extern crate rand;
17-
extern crate sha2;
18+
extern crate sha3;
1819
extern crate subtle;
1920
extern crate tiny_keccak;
2021
#[macro_use]

src/range_proof/dealer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ impl<'a, 'b> DealerAwaitingProofShares<'a, 'b> {
211211

212212
// Get a challenge value to combine statements for the IPP
213213
let w = self.transcript.challenge_scalar();
214-
let Q = w * self.gens.pedersen_generators.B;
214+
let Q = w * self.gens.pedersen_gens.B;
215215

216216
let l_vec: Vec<Scalar> = proof_shares
217217
.iter()

src/range_proof/messages.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ impl ProofShare {
9797
.chain(h),
9898
iter::once(&value_commitment.A_j)
9999
.chain(iter::once(&value_commitment.S_j))
100-
.chain(iter::once(&gens.pedersen_generators.B_blinding))
100+
.chain(iter::once(&gens.pedersen_gens.B_blinding))
101101
.chain(gens.share(j).G.iter())
102102
.chain(gens.share(j).H.iter()),
103103
);
@@ -117,8 +117,8 @@ impl ProofShare {
117117
iter::once(&value_commitment.V_j)
118118
.chain(iter::once(&poly_commitment.T_1_j))
119119
.chain(iter::once(&poly_commitment.T_2_j))
120-
.chain(iter::once(&gens.pedersen_generators.B))
121-
.chain(iter::once(&gens.pedersen_generators.B_blinding)),
120+
.chain(iter::once(&gens.pedersen_gens.B))
121+
.chain(iter::once(&gens.pedersen_gens.B_blinding)),
122122
);
123123

124124
if t_check.is_identity() {

src/range_proof/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,8 @@ impl RangeProof {
219219
.chain(iter::once(self.T_2.decompress()))
220220
.chain(self.ipp_proof.L_vec.iter().map(|L| L.decompress()))
221221
.chain(self.ipp_proof.R_vec.iter().map(|R| R.decompress()))
222-
.chain(iter::once(Some(gens.pedersen_generators.B_blinding)))
223-
.chain(iter::once(Some(gens.pedersen_generators.B)))
222+
.chain(iter::once(Some(gens.pedersen_gens.B_blinding)))
223+
.chain(iter::once(Some(gens.pedersen_gens.B)))
224224
.chain(gens.G.iter().map(|&x| Some(x)))
225225
.chain(gens.H.iter().map(|&x| Some(x)))
226226
.chain(value_commitments.iter().map(|&x| Some(x))),
@@ -422,7 +422,7 @@ mod tests {
422422
// 2. Serialize
423423
proof_bytes = bincode::serialize(&proof).unwrap();
424424

425-
let pg = &generators.pedersen_generators;
425+
let pg = &generators.pedersen_gens;
426426

427427
// XXX would be nice to have some convenience API for this
428428
value_commitments = values

src/range_proof/party.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ impl Party {
3030
return Err(MPCError::InvalidBitsize);
3131
}
3232

33-
let V = generators
34-
.pedersen_generators
35-
.commit(Scalar::from(v), v_blinding);
33+
let V = generators.pedersen_gens.commit(Scalar::from(v), v_blinding);
3634

3735
Ok(PartyAwaitingPosition {
3836
generators,
@@ -66,7 +64,7 @@ impl<'a> PartyAwaitingPosition<'a> {
6664

6765
let a_blinding = Scalar::random(rng);
6866
// Compute A = <a_L, G> + <a_R, H> + a_blinding * B_blinding
69-
let mut A = gen_share.pedersen_generators.B_blinding * a_blinding;
67+
let mut A = gen_share.pedersen_gens.B_blinding * a_blinding;
7068

7169
use subtle::{Choice, ConditionallyAssignable};
7270
for i in 0..self.n {
@@ -85,7 +83,7 @@ impl<'a> PartyAwaitingPosition<'a> {
8583
// Compute S = <s_L, G> + <s_R, H> + s_blinding * B_blinding
8684
let S = RistrettoPoint::multiscalar_mul(
8785
iter::once(&s_blinding).chain(s_L.iter()).chain(s_R.iter()),
88-
iter::once(&gen_share.pedersen_generators.B_blinding)
86+
iter::once(&gen_share.pedersen_gens.B_blinding)
8987
.chain(gen_share.G.iter())
9088
.chain(gen_share.H.iter()),
9189
);
@@ -164,12 +162,12 @@ impl<'a> PartyAwaitingValueChallenge<'a> {
164162
let T_1 = self
165163
.generators
166164
.share(self.j)
167-
.pedersen_generators
165+
.pedersen_gens
168166
.commit(t_poly.1, t_1_blinding);
169167
let T_2 = self
170168
.generators
171169
.share(self.j)
172-
.pedersen_generators
170+
.pedersen_gens
173171
.commit(t_poly.2, t_2_blinding);
174172

175173
let poly_commitment = PolyCommitment {

0 commit comments

Comments
 (0)