99//! # use fastcrypto::bulletproofs::Range::Bits16;
1010//! # use fastcrypto::groups::ristretto255::RistrettoScalar;
1111//! # use fastcrypto::groups::Scalar;
12- //! use fastcrypto::pedersen::Blinding;
12+ //! use fastcrypto::pedersen::{ Blinding, PedersenCommitment} ;
1313//! let value = 300;
1414//! let range = Bits16;
1515//! let mut rng = rand::thread_rng();
16- //! let output =
17- //! RangeProof::prove(value, Blinding::rand(&mut rng), &range, b"MY_DOMAIN", &mut rng).unwrap();
18- //! assert!(output.proof.verify(&output.commitment, &range, b"MY_DOMAIN").is_ok());
16+ //! let blinding = Blinding::rand(&mut rng);
17+ //! let proof =
18+ //! RangeProof::prove(value, &blinding, &range, b"MY_DOMAIN", &mut rng).unwrap();
19+ //! let commitment = PedersenCommitment::from_blinding(&RistrettoScalar::from(value), &blinding);
20+ //! assert!(proof.verify(&commitment, &range, b"MY_DOMAIN").is_ok());
1921//! ```
2022
2123use crate :: error:: FastCryptoError :: { GeneralOpaqueError , InvalidInput , InvalidProof } ;
2224use crate :: error:: FastCryptoResult ;
23- use crate :: groups:: ristretto255:: RistrettoPoint ;
2425use crate :: pedersen:: { Blinding , PedersenCommitment } ;
2526use crate :: traits:: AllowedRng ;
2627use bulletproofs:: { BulletproofGens , PedersenGens , RangeProof as ExternalRangeProof } ;
@@ -31,30 +32,6 @@ use serde::{Deserialize, Serialize};
3132#[ derive( Debug , Serialize , Deserialize ) ]
3233pub struct RangeProof ( ExternalRangeProof ) ;
3334
34- /// The output of [RangeProof::prove].
35- pub struct RangeProofOutput {
36- /// The bulletproof range proof.
37- pub proof : RangeProof ,
38-
39- /// A commitment to the value used in the range proof.
40- pub commitment : PedersenCommitment ,
41-
42- /// The blinding factor. The prover should keep this secret until the commitment needs to be revealed.
43- pub blinding : Blinding ,
44- }
45-
46- /// The output of [RangeProof::prove_aggregated].
47- pub struct AggregateRangeProofOutput {
48- /// The bulletproof range proof.
49- pub proof : RangeProof ,
50-
51- /// Commitments to the value used in the range proof.
52- pub commitments : Vec < PedersenCommitment > ,
53-
54- /// The blinding factors. The prover should keep these secret until the commitment needs to be revealed.
55- pub blindings : Vec < Blinding > ,
56- }
57-
5835pub enum Range {
5936 /// The range [0,...,2^8).
6037 Bits8 ,
@@ -93,18 +70,12 @@ impl RangeProof {
9370 /// Returns an `InvalidInput` error if the value is not in range.
9471 pub fn prove (
9572 value : u64 ,
96- blinding : Blinding ,
73+ blinding : & Blinding ,
9774 range : & Range ,
9875 domain : & ' static [ u8 ] ,
9976 rng : & mut impl AllowedRng ,
100- ) -> FastCryptoResult < RangeProofOutput > {
101- Self :: prove_aggregated ( & [ value] , vec ! [ blinding] , range, domain, rng) . map ( |value| {
102- RangeProofOutput {
103- proof : value. proof ,
104- commitment : value. commitments [ 0 ] . clone ( ) ,
105- blinding : value. blindings [ 0 ] . clone ( ) ,
106- }
107- } )
77+ ) -> FastCryptoResult < RangeProof > {
78+ Self :: prove_batch ( & [ value] , & [ blinding. clone ( ) ] , range, domain, rng)
10879 }
10980
11081 /// Verifies a range proof: That the commitment is to a value in the given range.
@@ -114,7 +85,7 @@ impl RangeProof {
11485 range : & Range ,
11586 domain : & ' static [ u8 ] ,
11687 ) -> FastCryptoResult < ( ) > {
117- self . verify_aggregated ( & [ commitment. clone ( ) ] , range, domain)
88+ self . verify_batch ( & [ commitment. clone ( ) ] , range, domain)
11889 }
11990
12091 /// Create a proof that all the given `values` are in the range using the given commitment blindings.
@@ -124,13 +95,13 @@ impl RangeProof {
12495 /// * any of the `values` are <i>not</i> in the range.
12596 /// * `values.len() != blindings.len()`,
12697 /// * `values.len()` is not a power of 2,
127- pub fn prove_aggregated (
98+ pub fn prove_batch (
12899 values : & [ u64 ] ,
129- blindings : Vec < Blinding > ,
100+ blindings : & [ Blinding ] ,
130101 range : & Range ,
131102 domain : & ' static [ u8 ] ,
132103 rng : & mut impl AllowedRng ,
133- ) -> FastCryptoResult < AggregateRangeProofOutput > {
104+ ) -> FastCryptoResult < RangeProof > {
134105 if values. iter ( ) . any ( |& v| !range. is_in_range ( v) )
135106 || blindings. len ( ) != values. len ( )
136107 || !values. len ( ) . is_power_of_two ( )
@@ -143,7 +114,7 @@ impl RangeProof {
143114 let bp_gens = BulletproofGens :: new ( bits, values. len ( ) ) ;
144115 let mut prover_transcript = Transcript :: new ( domain) ;
145116
146- // TODO: Can we avoid calculating the Pedersen commitments here if they are already available ?
117+ // TODO: Can we avoid calculating the Pedersen commitments here?
147118 ExternalRangeProof :: prove_multiple_with_rng (
148119 & bp_gens,
149120 & pc_gens,
@@ -153,22 +124,12 @@ impl RangeProof {
153124 bits,
154125 rng,
155126 )
156- . map ( |( proof, commitments) | {
157- AggregateRangeProofOutput {
158- proof : RangeProof ( proof) ,
159- // TODO: There's an unnecessary compression happening inside the external crate
160- commitments : commitments
161- . iter ( )
162- . map ( |c| PedersenCommitment ( RistrettoPoint ( c. decompress ( ) . unwrap ( ) ) ) )
163- . collect ( ) ,
164- blindings,
165- }
166- } )
127+ . map ( |( proof, _) | RangeProof ( proof) )
167128 . map_err ( |_| GeneralOpaqueError )
168129 }
169130
170131 /// Verifies that a range proof that all commitments are to values in the given `range`.
171- pub fn verify_aggregated (
132+ pub fn verify_batch (
172133 & self ,
173134 commitments : & [ PedersenCommitment ] ,
174135 range : & Range ,
@@ -211,12 +172,14 @@ fn test_is_in_range() {
211172
212173#[ test]
213174fn test_range_proof_valid ( ) {
175+ use crate :: groups:: ristretto255:: RistrettoScalar ;
176+
214177 let range = Range :: Bits32 ;
215178 let mut rng = rand:: thread_rng ( ) ;
216- let output =
217- RangeProof :: prove ( 1u64 , Blinding :: rand ( & mut rng ) , & range , b"NARWHAL" , & mut rng ) . unwrap ( ) ;
218- assert ! ( output
219- . proof
220- . verify ( & output . commitment , & range , b"NARWHAL" )
221- . is_ok( ) ) ;
179+ let blinding = Blinding :: rand ( & mut rng ) ;
180+
181+ let value = 1u64 ;
182+ let proof = RangeProof :: prove ( value , & blinding , & range , b"NARWHAL" , & mut rng ) . unwrap ( ) ;
183+ let commitment = PedersenCommitment :: from_blinding ( & RistrettoScalar :: from ( value ) , & blinding ) ;
184+ assert ! ( proof . verify ( & commitment , & range , b"NARWHAL" ) . is_ok( ) ) ;
222185}
0 commit comments