Struct tari_bulletproofs::range_proof::RangeProof
source · pub struct RangeProof { /* private fields */ }
Expand description
The RangeProof
struct represents a proof that one or more values
are in a range.
The RangeProof
struct contains functions for creating and
verifying aggregated range proofs. The single-value case is
implemented as a special case of aggregated range proofs.
The bitsize of the range, as well as the list of commitments to the values, are not included in the proof, and must be known to the verifier.
This implementation requires that both the bitsize n
and the
aggregation size m
be powers of two, so that n = 8, 16, 32, 64
and m = 1, 2, 4, 8, 16, ...
. Note that the aggregation size is
not given as an explicit parameter, but is determined by the
number of values or commitments passed to the prover or verifier.
Note
For proving, these functions run the multiparty aggregation
protocol locally. That API is exposed in the aggregation
module and can be used to perform online aggregation between
parties without revealing secret values to each other.
Implementations§
source§impl RangeProof
impl RangeProof
sourcepub fn prove_single_with_rng<T: RngCore + CryptoRng>(
bp_gens: &BulletproofGens,
pc_gens: &PedersenGens,
transcript: &mut Transcript,
v: u64,
v_blinding: &Scalar,
n: usize,
rng: &mut T
) -> Result<(RangeProof, CompressedRistretto), ProofError>
pub fn prove_single_with_rng<T: RngCore + CryptoRng>( bp_gens: &BulletproofGens, pc_gens: &PedersenGens, transcript: &mut Transcript, v: u64, v_blinding: &Scalar, n: usize, rng: &mut T ) -> Result<(RangeProof, CompressedRistretto), ProofError>
Create a rangeproof for a given pair of value v
and
blinding scalar v_blinding
.
This is a convenience wrapper around RangeProof::prove_multiple
.
Example
extern crate rand;
use rand::thread_rng;
extern crate curve25519_dalek;
use curve25519_dalek::scalar::Scalar;
extern crate merlin;
use merlin::Transcript;
extern crate tari_bulletproofs;
use tari_bulletproofs::{BulletproofGens, PedersenGens, RangeProof};
// Generators for Pedersen commitments. These can be selected
// independently of the Bulletproofs generators.
let pc_gens = PedersenGens::default();
// Generators for Bulletproofs, valid for proofs up to bitsize 64
// and aggregation size up to 1.
let bp_gens = BulletproofGens::new(64, 1);
// A secret value we want to prove lies in the range [0, 2^32)
let secret_value = 1037578891u64;
// The API takes a blinding factor for the commitment.
let blinding = Scalar::random(&mut thread_rng());
// The proof can be chained to an existing transcript.
// Here we create a transcript with a doctest domain separator.
let mut prover_transcript = Transcript::new(b"doctest example");
// Create a 32-bit rangeproof.
let (proof, committed_value) = RangeProof::prove_single(
&bp_gens,
&pc_gens,
&mut prover_transcript,
secret_value,
&blinding,
32,
).expect("A real program could handle errors");
// Verification requires a transcript with identical initial state:
let mut verifier_transcript = Transcript::new(b"doctest example");
assert!(
proof
.verify_single(&bp_gens, &pc_gens, &mut verifier_transcript, &committed_value, 32)
.is_ok()
);
sourcepub fn prove_single_with_rng_and_rewind_key<T: RngCore + CryptoRng>(
bp_gens: &BulletproofGens,
pc_gens: &PedersenGens,
transcript: &mut Transcript,
v: u64,
v_blinding: &Scalar,
n: usize,
rng: &mut T,
pvt_rewind_key: &Scalar,
pvt_blinding_key: &Scalar,
proof_message: &[u8; 23]
) -> Result<(RangeProof, CompressedRistretto), ProofError>
pub fn prove_single_with_rng_and_rewind_key<T: RngCore + CryptoRng>( bp_gens: &BulletproofGens, pc_gens: &PedersenGens, transcript: &mut Transcript, v: u64, v_blinding: &Scalar, n: usize, rng: &mut T, pvt_rewind_key: &Scalar, pvt_blinding_key: &Scalar, proof_message: &[u8; 23] ) -> Result<(RangeProof, CompressedRistretto), ProofError>
Create a rangeproof for a given pair of value v
and
blinding scalar v_blinding
, passing in a rewind key to
enable rangeproof rewinding with 23 bytes worth of extra
data that can be embedded.
This is a convenience wrapper around RangeProof::prove_multiple
.
Example
extern crate rand;
use rand::thread_rng;
extern crate curve25519_dalek;
use curve25519_dalek::scalar::Scalar;
extern crate merlin;
use merlin::Transcript;
extern crate tari_bulletproofs;
use tari_bulletproofs::{BulletproofGens, PedersenGens, RangeProof};
// Generators for Pedersen commitments. These can be selected
// independently of the Bulletproofs generators.
use curve25519_dalek::ristretto::RistrettoPoint;
use curve25519_dalek::constants::RISTRETTO_BASEPOINT_TABLE;
use tari_bulletproofs::range_proof::{get_rewind_nonce_from_pub_key, get_secret_nonce_from_pvt_key};
let pc_gens = PedersenGens::default();
// Generators for Bulletproofs, valid for proofs up to bitsize 64
// and aggregation size up to 1.
let bp_gens = BulletproofGens::new(64, 1);
// A secret value we want to prove lies in the range [0, 2^32)
let confidential_value = 1037578891u64;
// The API takes a blinding factor for the commitment.
let blinding_factor = Scalar::random(&mut thread_rng());
// The private keys for range proof rewinding; these may be based on a wallet's private root key
let pvt_rewind_key = Scalar::random(&mut thread_rng());
let pvt_blinding_key = Scalar::random(&mut thread_rng());
// Up to 23 bytes extra data may be embedded in the range proof meta data
let proof_message: [u8; 23] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23];
// The proof can be chained to an existing transcript.
// Here we create a transcript with a doctest domain separator.
let mut prover_transcript = Transcript::new(b"doctest example");
// Create a 32-bit rangeproof.
let (proof, committed_value) = RangeProof::prove_single_with_rewind_key(
&bp_gens,
&pc_gens,
&mut prover_transcript,
confidential_value,
&blinding_factor,
32,
&pvt_rewind_key,
&pvt_blinding_key,
&proof_message,
).expect("A real program could handle errors");
// Verification requires a transcript with identical initial state:
let mut verifier_transcript = Transcript::new(b"doctest example");
assert!(
proof
.verify_single(&bp_gens, &pc_gens, &mut verifier_transcript, &committed_value, 32)
.is_ok()
);
// A third party may have access to the public keys and extra data for range proof rewinding
let pub_rewind_key_1 = RistrettoPoint::from(&pvt_rewind_key * &RISTRETTO_BASEPOINT_TABLE).compress();
let pub_rewind_key_2 = RistrettoPoint::from(&pvt_blinding_key * &RISTRETTO_BASEPOINT_TABLE).compress();
// The rewind nonce is necessary to rewind the range proof, which is uniquely bound to the commitment
let rewind_nonce_1 = get_rewind_nonce_from_pub_key(&pub_rewind_key_1, &committed_value);
let rewind_nonce_2 = get_rewind_nonce_from_pub_key(&pub_rewind_key_2, &committed_value);
// A owner or third party can extract the value and extra data; if it is the wrong combination
// garbage data will be extracted
let mut rewind_transcript = Transcript::new(b"doctest example");
assert_eq!(
proof.rewind_single_get_value_only(
&bp_gens,
&mut rewind_transcript,
&committed_value,
32,
&rewind_nonce_1,
&rewind_nonce_2,
),
Ok((confidential_value, proof_message))
);
// The two blinding nonces are necessary to rewind the range proof fully, which are also
// uniquely bound to the commitment
let blinding_nonce_1 = get_secret_nonce_from_pvt_key(&pvt_rewind_key, &committed_value);
let blinding_nonce_2 = get_secret_nonce_from_pvt_key(&pvt_blinding_key, &committed_value);
// The owner or trusted party can extract the value, extra data and blinding factor; if it is the
// wrong combination an error will be returned
let mut rewind_transcript = Transcript::new(b"doctest example");
assert_eq!(
proof.rewind_single_get_commitment_data(
&bp_gens,
&pc_gens,
&mut rewind_transcript,
&committed_value,
32,
&rewind_nonce_1,
&rewind_nonce_2,
&blinding_nonce_1,
&blinding_nonce_2,
),
Ok((confidential_value, blinding_factor, proof_message))
);
sourcepub fn prove_single(
bp_gens: &BulletproofGens,
pc_gens: &PedersenGens,
transcript: &mut Transcript,
v: u64,
v_blinding: &Scalar,
n: usize
) -> Result<(RangeProof, CompressedRistretto), ProofError>
pub fn prove_single( bp_gens: &BulletproofGens, pc_gens: &PedersenGens, transcript: &mut Transcript, v: u64, v_blinding: &Scalar, n: usize ) -> Result<(RangeProof, CompressedRistretto), ProofError>
Create a rangeproof for a given pair of value v
and
blinding scalar v_blinding
.
This is a convenience wrapper around RangeProof::prove_single_with_rng
,
passing in a threadsafe RNG.
sourcepub fn prove_single_with_rewind_key(
bp_gens: &BulletproofGens,
pc_gens: &PedersenGens,
transcript: &mut Transcript,
v: u64,
v_blinding: &Scalar,
n: usize,
pvt_rewind_key: &Scalar,
pvt_blinding_key: &Scalar,
proof_message: &[u8; 23]
) -> Result<(RangeProof, CompressedRistretto), ProofError>
pub fn prove_single_with_rewind_key( bp_gens: &BulletproofGens, pc_gens: &PedersenGens, transcript: &mut Transcript, v: u64, v_blinding: &Scalar, n: usize, pvt_rewind_key: &Scalar, pvt_blinding_key: &Scalar, proof_message: &[u8; 23] ) -> Result<(RangeProof, CompressedRistretto), ProofError>
Create a rangeproof for a given pair of value v
and
blinding scalar v_blinding
, passing in a rewind key to
enable rangeproof rewinding with 23 bytes worth of extra
data that can be embedded.
This is a convenience wrapper around
RangeProof::prove_single_with_rng_and_rewind_key
,
passing in a threadsafe RNG.
sourcepub fn prove_multiple_with_rng<T: RngCore + CryptoRng>(
bp_gens: &BulletproofGens,
pc_gens: &PedersenGens,
transcript: &mut Transcript,
values: &[u64],
blindings: &[Scalar],
n: usize,
rng: &mut T
) -> Result<(RangeProof, Vec<CompressedRistretto>), ProofError>
pub fn prove_multiple_with_rng<T: RngCore + CryptoRng>( bp_gens: &BulletproofGens, pc_gens: &PedersenGens, transcript: &mut Transcript, values: &[u64], blindings: &[Scalar], n: usize, rng: &mut T ) -> Result<(RangeProof, Vec<CompressedRistretto>), ProofError>
Create a rangeproof for a set of values.
Example
extern crate rand;
use rand::thread_rng;
extern crate curve25519_dalek;
use curve25519_dalek::scalar::Scalar;
extern crate merlin;
use merlin::Transcript;
extern crate tari_bulletproofs;
use tari_bulletproofs::{BulletproofGens, PedersenGens, RangeProof};
// Generators for Pedersen commitments. These can be selected
// independently of the Bulletproofs generators.
let pc_gens = PedersenGens::default();
// Generators for Bulletproofs, valid for proofs up to bitsize 64
// and aggregation size up to 16.
let bp_gens = BulletproofGens::new(64, 16);
// Four secret values we want to prove lie in the range [0, 2^32)
let secrets = [4242344947u64, 3718732727u64, 2255562556u64, 2526146994u64];
// The API takes blinding factors for the commitments.
let blindings: Vec<_> = (0..4).map(|_| Scalar::random(&mut thread_rng())).collect();
// The proof can be chained to an existing transcript.
// Here we create a transcript with a doctest domain separator.
let mut prover_transcript = Transcript::new(b"doctest example");
// Create an aggregated 32-bit rangeproof and corresponding commitments.
let (proof, commitments) = RangeProof::prove_multiple(
&bp_gens,
&pc_gens,
&mut prover_transcript,
&secrets,
&blindings,
32,
).expect("A real program could handle errors");
// Verification requires a transcript with identical initial state:
let mut verifier_transcript = Transcript::new(b"doctest example");
assert!(
proof
.verify_multiple(&bp_gens, &pc_gens, &mut verifier_transcript, &commitments, 32)
.is_ok()
);
sourcepub fn prove_multiple(
bp_gens: &BulletproofGens,
pc_gens: &PedersenGens,
transcript: &mut Transcript,
values: &[u64],
blindings: &[Scalar],
n: usize
) -> Result<(RangeProof, Vec<CompressedRistretto>), ProofError>
pub fn prove_multiple( bp_gens: &BulletproofGens, pc_gens: &PedersenGens, transcript: &mut Transcript, values: &[u64], blindings: &[Scalar], n: usize ) -> Result<(RangeProof, Vec<CompressedRistretto>), ProofError>
Create a rangeproof for a set of values.
This is a convenience wrapper around RangeProof::prove_multiple_with_rng
,
passing in a threadsafe RNG.
sourcepub fn verify_single_with_rng<T: RngCore + CryptoRng>(
&self,
bp_gens: &BulletproofGens,
pc_gens: &PedersenGens,
transcript: &mut Transcript,
V: &CompressedRistretto,
n: usize,
rng: &mut T
) -> Result<(), ProofError>
pub fn verify_single_with_rng<T: RngCore + CryptoRng>( &self, bp_gens: &BulletproofGens, pc_gens: &PedersenGens, transcript: &mut Transcript, V: &CompressedRistretto, n: usize, rng: &mut T ) -> Result<(), ProofError>
Verifies a rangeproof for a given value commitment \(V\).
This is a convenience wrapper around verify_multiple
for the m=1
case.
sourcepub fn verify_single(
&self,
bp_gens: &BulletproofGens,
pc_gens: &PedersenGens,
transcript: &mut Transcript,
V: &CompressedRistretto,
n: usize
) -> Result<(), ProofError>
pub fn verify_single( &self, bp_gens: &BulletproofGens, pc_gens: &PedersenGens, transcript: &mut Transcript, V: &CompressedRistretto, n: usize ) -> Result<(), ProofError>
Verifies a rangeproof for a given value commitment \(V\).
This is a convenience wrapper around RangeProof::verify_single_with_rng
,
passing in a threadsafe RNG.
sourcepub fn verify_multiple_with_rng<T: RngCore + CryptoRng>(
&self,
bp_gens: &BulletproofGens,
pc_gens: &PedersenGens,
transcript: &mut Transcript,
value_commitments: &[CompressedRistretto],
n: usize,
rng: &mut T
) -> Result<(), ProofError>
pub fn verify_multiple_with_rng<T: RngCore + CryptoRng>( &self, bp_gens: &BulletproofGens, pc_gens: &PedersenGens, transcript: &mut Transcript, value_commitments: &[CompressedRistretto], n: usize, rng: &mut T ) -> Result<(), ProofError>
Verifies an aggregated rangeproof for the given value commitments.
sourcepub fn verify_multiple(
&self,
bp_gens: &BulletproofGens,
pc_gens: &PedersenGens,
transcript: &mut Transcript,
value_commitments: &[CompressedRistretto],
n: usize
) -> Result<(), ProofError>
pub fn verify_multiple( &self, bp_gens: &BulletproofGens, pc_gens: &PedersenGens, transcript: &mut Transcript, value_commitments: &[CompressedRistretto], n: usize ) -> Result<(), ProofError>
Verifies an aggregated rangeproof for the given value commitments.
This is a convenience wrapper around RangeProof::verify_multiple_with_rng
,
passing in a threadsafe RNG.
sourcepub fn to_bytes(&self) -> Vec<u8>
pub fn to_bytes(&self) -> Vec<u8>
Serializes the proof into a byte array of \(2 \lg n + 9\) 32-byte elements, where \(n\) is the number of secret bits.
Layout
The layout of the range proof encoding is:
- four compressed Ristretto points \(A,S,T_1,T_2\),
- three scalars \(t_x, \tilde{t}_x, \tilde{e}\),
- \(n\) pairs of compressed Ristretto points \(L_0,R_0\dots,L_{n-1},R_{n-1}\),
- two scalars \(a, b\).
sourcepub fn from_bytes(slice: &[u8]) -> Result<RangeProof, ProofError>
pub fn from_bytes(slice: &[u8]) -> Result<RangeProof, ProofError>
Deserializes the proof from a byte slice.
Returns an error if the byte slice cannot be parsed into a RangeProof
.
sourcepub fn rewind_single_get_commitment_data(
&self,
bp_gens: &BulletproofGens,
pc_gens: &PedersenGens,
transcript: &mut Transcript,
value_commitment: &CompressedRistretto,
n: usize,
rewind_nonce_1: &Scalar,
rewind_nonce_2: &Scalar,
blinding_nonce_1: &Scalar,
blinding_nonce_2: &Scalar
) -> Result<(u64, Scalar, [u8; 23]), ProofError>
pub fn rewind_single_get_commitment_data( &self, bp_gens: &BulletproofGens, pc_gens: &PedersenGens, transcript: &mut Transcript, value_commitment: &CompressedRistretto, n: usize, rewind_nonce_1: &Scalar, rewind_nonce_2: &Scalar, blinding_nonce_1: &Scalar, blinding_nonce_2: &Scalar ) -> Result<(u64, Scalar, [u8; 23]), ProofError>
Rewinds a rangeproof for a given value commitment \(V\), returning the value, blinding factor and 23 bytes extra data upon success.
sourcepub fn rewind_single_get_value_only(
&self,
bp_gens: &BulletproofGens,
transcript: &mut Transcript,
V: &CompressedRistretto,
n: usize,
rewind_nonce_1: &Scalar,
rewind_nonce_2: &Scalar
) -> Result<(u64, [u8; 23]), ProofError>
pub fn rewind_single_get_value_only( &self, bp_gens: &BulletproofGens, transcript: &mut Transcript, V: &CompressedRistretto, n: usize, rewind_nonce_1: &Scalar, rewind_nonce_2: &Scalar ) -> Result<(u64, [u8; 23]), ProofError>
Rewinds a rangeproof for a given value commitment \(V\) to get the value and 23 bytes extra data only. If the wrong rewind_nonce is provided, garbage data will be returned.
Trait Implementations§
source§impl Clone for RangeProof
impl Clone for RangeProof
source§fn clone(&self) -> RangeProof
fn clone(&self) -> RangeProof
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read more