Skip to content

Commit 20f2749

Browse files
vickiniuoleganza
authored andcommitted
gens: dynamically growable BulletproofGens (#263)
This adds `increase_capacity` method to `BulletproofGens`.
1 parent 461d4a5 commit 20f2749

File tree

1 file changed

+70
-27
lines changed

1 file changed

+70
-27
lines changed

src/generators.rs

Lines changed: 70 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,16 @@ impl GeneratorsChain {
6868
reader: shake.xof_result(),
6969
}
7070
}
71+
72+
/// Advances the reader n times, squeezing and discarding
73+
/// the result.
74+
fn fast_forward(mut self, n: usize) -> Self {
75+
for _ in 0..n {
76+
let mut buf = [0u8; 64];
77+
self.reader.read(&mut buf);
78+
}
79+
self
80+
}
7181
}
7282

7383
impl Default for GeneratorsChain {
@@ -85,6 +95,7 @@ impl Iterator for GeneratorsChain {
8595

8696
Some(RistrettoPoint::from_uniform_bytes(&uniform_bytes))
8797
}
98+
8899
fn size_hint(&self) -> (usize, Option<usize>) {
89100
(usize::max_value(), None)
90101
}
@@ -142,34 +153,14 @@ impl BulletproofGens {
142153
/// * `party_capacity` is the maximum number of parties that can
143154
/// produce an aggregated proof.
144155
pub fn new(gens_capacity: usize, party_capacity: usize) -> Self {
145-
use byteorder::{ByteOrder, LittleEndian};
146-
147-
BulletproofGens {
148-
gens_capacity,
156+
let mut gens = BulletproofGens {
157+
gens_capacity: 0,
149158
party_capacity,
150-
G_vec: (0..party_capacity)
151-
.map(|i| {
152-
let party_index = i as u32;
153-
let mut label = [b'G', 0, 0, 0, 0];
154-
LittleEndian::write_u32(&mut label[1..5], party_index);
155-
156-
GeneratorsChain::new(&label)
157-
.take(gens_capacity)
158-
.collect::<Vec<_>>()
159-
})
160-
.collect(),
161-
H_vec: (0..party_capacity)
162-
.map(|i| {
163-
let party_index = i as u32;
164-
let mut label = [b'H', 0, 0, 0, 0];
165-
LittleEndian::write_u32(&mut label[1..5], party_index);
166-
167-
GeneratorsChain::new(&label)
168-
.take(gens_capacity)
169-
.collect::<Vec<_>>()
170-
})
171-
.collect(),
172-
}
159+
G_vec: (0..party_capacity).map(|_| Vec::new()).collect(),
160+
H_vec: (0..party_capacity).map(|_| Vec::new()).collect(),
161+
};
162+
gens.increase_capacity(gens_capacity);
163+
gens
173164
}
174165

175166
/// Returns j-th share of generators, with an appropriate
@@ -181,6 +172,35 @@ impl BulletproofGens {
181172
}
182173
}
183174

175+
/// Increases the generators' capacity to the amount specified.
176+
/// If less than or equal to the current capacity, does nothing.
177+
pub fn increase_capacity(&mut self, new_capacity: usize) {
178+
use byteorder::{ByteOrder, LittleEndian};
179+
180+
if self.gens_capacity >= new_capacity {
181+
return;
182+
}
183+
184+
for i in 0..self.party_capacity {
185+
let party_index = i as u32;
186+
let mut label = [b'G', 0, 0, 0, 0];
187+
LittleEndian::write_u32(&mut label[1..5], party_index);
188+
self.G_vec[i].extend(
189+
&mut GeneratorsChain::new(&label)
190+
.fast_forward(self.gens_capacity)
191+
.take(new_capacity - self.gens_capacity),
192+
);
193+
194+
label[0] = b'H';
195+
self.H_vec[i].extend(
196+
&mut GeneratorsChain::new(&label)
197+
.fast_forward(self.gens_capacity)
198+
.take(new_capacity - self.gens_capacity),
199+
);
200+
}
201+
self.gens_capacity = new_capacity;
202+
}
203+
184204
/// Return an iterator over the aggregation of the parties' G generators with given size `n`.
185205
pub(crate) fn G(&self, n: usize, m: usize) -> impl Iterator<Item = &RistrettoPoint> {
186206
AggregatedGensIter {
@@ -308,4 +328,27 @@ mod tests {
308328
helper(16, 2);
309329
helper(16, 1);
310330
}
331+
332+
#[test]
333+
fn resizing_small_gens_matches_creating_bigger_gens() {
334+
let gens = BulletproofGens::new(64, 8);
335+
336+
let mut gen_resized = BulletproofGens::new(32, 8);
337+
gen_resized.increase_capacity(64);
338+
339+
let helper = |n: usize, m: usize| {
340+
let gens_G: Vec<RistrettoPoint> = gens.G(n, m).cloned().collect();
341+
let gens_H: Vec<RistrettoPoint> = gens.H(n, m).cloned().collect();
342+
343+
let resized_G: Vec<RistrettoPoint> = gen_resized.G(n, m).cloned().collect();
344+
let resized_H: Vec<RistrettoPoint> = gen_resized.H(n, m).cloned().collect();
345+
346+
assert_eq!(gens_G, resized_G);
347+
assert_eq!(gens_H, resized_H);
348+
};
349+
350+
helper(64, 8);
351+
helper(32, 8);
352+
helper(16, 8);
353+
}
311354
}

0 commit comments

Comments
 (0)