@@ -5,7 +5,7 @@ use rand::RngCore;
55
66use crate :: codec:: Shake128DuplexSponge ;
77use crate :: fiat_shamir:: Nizk ;
8- use crate :: linear_relation:: CanonicalLinearRelation ;
8+ use crate :: linear_relation:: { CanonicalLinearRelation , Sum } ;
99
1010use crate :: linear_relation:: { LinearRelation , VariableMultiScalarMul } ;
1111
@@ -200,6 +200,97 @@ pub fn pedersen_commitment_dleq<G: PrimeGroup, R: RngCore>(
200200 ( instance, witness_vec)
201201}
202202
203+ /// Test that a Pedersen commitment is between 0 and 1337.
204+ #[ allow( non_snake_case) ]
205+ pub fn test_range < G : PrimeGroup , R : RngCore > (
206+ mut rng : & mut R ,
207+ ) -> ( CanonicalLinearRelation < G > , Vec < G :: Scalar > ) {
208+ let G = G :: generator ( ) ;
209+ let H = G :: random ( & mut rng) ;
210+
211+ let bases = [ 1 , 2 , 4 , 8 , 16 , 32 , 64 , 128 , 256 , 313 , 512 ] ;
212+ const BITS : usize = 11 ;
213+
214+ let mut instance = LinearRelation :: new ( ) ;
215+ let [ var_G, var_H] = instance. allocate_elements ( ) ;
216+ let [ var_x, var_r] = instance. allocate_scalars ( ) ;
217+ let vars_b = instance. allocate_scalars :: < BITS > ( ) ;
218+ let vars_s = instance. allocate_scalars :: < BITS > ( ) ;
219+ let var_s2 = instance. allocate_scalars :: < BITS > ( ) ;
220+
221+ let var_C = instance. allocate_eq ( var_x * var_G + var_r * var_H) ;
222+ let mut var_Ds = Vec :: new ( ) ;
223+ for i in 0 ..BITS {
224+ let var_D_i = instance. allocate_eq ( vars_b[ i] * var_G + vars_s[ i] * var_H) ;
225+ instance. append_equation ( var_D_i, vars_b[ i] * var_D_i + var_s2[ i] * var_H) ;
226+ var_Ds. push ( var_D_i) ;
227+ }
228+ instance. append_equation (
229+ var_C,
230+ ( 0 ..BITS )
231+ . map ( |i| var_Ds[ i] * vars_b[ i] * G :: Scalar :: from ( bases[ i] ) )
232+ . sum :: < Sum < _ > > ( ) ,
233+ ) ;
234+
235+ let r = G :: Scalar :: random ( & mut rng) ;
236+ let x = G :: Scalar :: from ( 822 ) ;
237+ let b = [
238+ G :: Scalar :: ZERO ,
239+ G :: Scalar :: ONE ,
240+ G :: Scalar :: ONE ,
241+ G :: Scalar :: ZERO ,
242+ G :: Scalar :: ONE ,
243+ G :: Scalar :: ONE ,
244+ G :: Scalar :: ZERO ,
245+ G :: Scalar :: ZERO ,
246+ G :: Scalar :: ONE ,
247+ G :: Scalar :: ZERO ,
248+ G :: Scalar :: ONE ,
249+ ] ;
250+ // set the randomness for the bit decomposition
251+ let mut s = ( 0 ..BITS )
252+ . map ( |_| G :: Scalar :: random ( & mut rng) )
253+ . collect :: < Vec < _ > > ( ) ;
254+ let partial_sum = ( 0 ..BITS - 1 )
255+ . map ( |i| b[ i] * G :: Scalar :: from ( bases[ i] ) * s[ i] )
256+ . sum :: < G :: Scalar > ( ) ;
257+ s[ BITS - 1 ] = r - partial_sum;
258+ s[ BITS - 1 ] *= ( b[ BITS - 1 ] * G :: Scalar :: from ( bases[ BITS - 1 ] ) )
259+ . invert ( )
260+ . unwrap ( ) ;
261+ let s2 = ( 0 ..BITS )
262+ . map ( |i| ( G :: Scalar :: ONE - b[ i] ) * s[ i] )
263+ . collect :: < Vec < _ > > ( ) ;
264+ let witness = [ x, r]
265+ . iter ( )
266+ . chain ( & b)
267+ . chain ( & s)
268+ . chain ( & s2)
269+ . copied ( )
270+ . collect :: < Vec < _ > > ( ) ;
271+
272+ println ! ( "test_range: witness length = {}" , witness. len( ) ) ;
273+
274+ instance. set_elements ( [ ( var_G, G ) , ( var_H, H ) ] ) ;
275+ instance. set_element ( var_C, G * x + H * r) ;
276+ for i in 0 ..BITS {
277+ instance. set_element ( var_Ds[ i] , G * b[ i] + H * s[ i] ) ;
278+ }
279+ assert ! (
280+ instance. canonical( ) . is_ok( ) ,
281+ "{}" ,
282+ instance. canonical( ) . err( ) . unwrap( )
283+ ) ;
284+
285+ let canonical = instance. canonical ( ) . unwrap ( ) ;
286+ println ! (
287+ "test_range: relation has {} scalar variables" ,
288+ canonical. num_scalars
289+ ) ;
290+
291+ ( canonical, witness)
292+ }
293+
203294/// LinearMap for knowledge of an opening for use in a BBS commitment.
204295// BBS message length is 3
205296#[ allow( non_snake_case) ]
@@ -454,6 +545,7 @@ fn test_relations() {
454545 ( "twisted_pedersen_commitment" , & twisted_pedersen_commitment) ,
455546 ( "pedersen_commitment_dleq" , & pedersen_commitment_dleq) ,
456547 ( "bbs_blind_commitment" , & bbs_blind_commitment) ,
548+ ( "test_range" , & test_range) ,
457549 ( "weird_linear_combination" , & weird_linear_combination) ,
458550 ( "simple_subtractions" , & simple_subtractions) ,
459551 ( "subtractions_with_shift" , & subtractions_with_shift) ,
0 commit comments