Skip to content

Commit ce4eedc

Browse files
committed
Simplify flow
1 parent 9b2e19d commit ce4eedc

File tree

3 files changed

+29
-74
lines changed

3 files changed

+29
-74
lines changed

fastcrypto/src/bulletproofs.rs

Lines changed: 24 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,19 @@
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
2123
use crate::error::FastCryptoError::{GeneralOpaqueError, InvalidInput, InvalidProof};
2224
use crate::error::FastCryptoResult;
23-
use crate::groups::ristretto255::RistrettoPoint;
2425
use crate::pedersen::{Blinding, PedersenCommitment};
2526
use crate::traits::AllowedRng;
2627
use bulletproofs::{BulletproofGens, PedersenGens, RangeProof as ExternalRangeProof};
@@ -31,30 +32,6 @@ use serde::{Deserialize, Serialize};
3132
#[derive(Debug, Serialize, Deserialize)]
3233
pub 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-
5835
pub 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]
213174
fn 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
}

fastcrypto/src/pedersen.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub struct PedersenCommitment(pub(crate) RistrettoPoint);
1818
pub struct Blinding(pub(crate) RistrettoScalar);
1919

2020
impl PedersenCommitment {
21-
pub(crate) fn from_blinding(value: &RistrettoScalar, blinding: &Blinding) -> Self {
21+
pub fn from_blinding(value: &RistrettoScalar, blinding: &Blinding) -> Self {
2222
Self(RistrettoPoint(
2323
PedersenGens::default().commit(value.0, blinding.0 .0),
2424
))

fastcrypto/src/twisted_elgamal.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -294,20 +294,12 @@ fn encrypt_and_range_proof() {
294294
let (pk, sk) = generate_keypair(&mut rng);
295295
let (ciphertext, blinding) = Ciphertext::encrypt(&pk, value, &mut rng);
296296
let domain = b"test";
297-
let range_proof = crate::bulletproofs::RangeProof::prove(
298-
value as u64,
299-
blinding.clone(),
300-
&range,
301-
domain,
302-
&mut rng,
303-
)
304-
.unwrap();
297+
let range_proof =
298+
crate::bulletproofs::RangeProof::prove(value as u64, &blinding, &range, domain, &mut rng)
299+
.unwrap();
305300

306-
assert_eq!(&range_proof.blinding, &blinding);
307-
assert_eq!(&range_proof.commitment, &ciphertext.commitment);
308301
assert!(range_proof
309-
.proof
310-
.verify(&range_proof.commitment, &range, domain)
302+
.verify(&ciphertext.commitment, &range, domain)
311303
.is_ok());
312304

313305
assert_eq!(ciphertext.decrypt(&sk, &precompute_table()).unwrap(), value);

0 commit comments

Comments
 (0)