@@ -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
7383impl 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