ristretto255_bulletproofs - [mainnet]
This module implements a Bulletproof range proof verifier on the Ristretto255 curve.
A Bulletproof-based zero-knowledge range proof is a proof that a Pedersen commitment commits to an -bit value (i.e., ). Currently, this module only supports for the number of bits.
The module also supports batch range proofs, allowing verification of multiple commitments in a single proof. Each commitment in the batch must satisfy the same range constraint , and the supported batch sizes are limited to .
use 0x1::error;use 0x1::features;use 0x1::ristretto255;use 0x1::ristretto255_pedersen;
Constants
The native functions have not been rolled out yet.
const E_NATIVE_FUN_NOT_AVAILABLE: u64 = 7;
The range proof system only supports batch sizes of 1, 2, 4, 8, and 16.
const E_BATCH_SIZE_NOT_SUPPORTED: u64 = 4;
There was an error deserializing the range proof.
const E_DESERIALIZE_RANGE_PROOF: u64 = 1;
The domain separation tag exceeded the 256-byte limit.
const E_DST_TOO_LONG: u64 = 6;
The range proof system only supports proving ranges of type where .
const E_RANGE_NOT_SUPPORTED: u64 = 3;
The committed value given to the prover is too large.
const E_VALUE_OUTSIDE_RANGE: u64 = 2;
The vector lengths of values and blinding factors do not match.
const E_VECTOR_LENGTHS_MISMATCH: u64 = 5;
The maximum range supported by the Bulletproofs library is .
const MAX_RANGE_BITS: u64 = 64;
Structs
RangeProof
Represents a zero-knowledge range proof that a value committed inside a Pedersen commitment lies in
[0, 2^{MAX_RANGE_BITS})
.
struct RangeProof has copy, drop, store
Fields
-
bytes: vector<u8>
Functions
get_max_range_bits
Returns the maximum # of bits that the range proof system can verify proofs for.
public fun get_max_range_bits(): u64
Implementation
public fun get_max_range_bits(): u64 { MAX_RANGE_BITS}
range_proof_from_bytes
Deserializes a range proof from a sequence of bytes. The serialization format is the same as the format in
the zkcrypto’s bulletproofs
library (https://docs.rs/bulletproofs/4.0.0/bulletproofs/struct.RangeProof.html#method.from_bytes).
public fun range_proof_from_bytes(bytes: vector<u8>): ristretto255_bulletproofs::RangeProof
Implementation
public fun range_proof_from_bytes(bytes: vector<u8>): RangeProof { RangeProof { bytes }}
range_proof_to_bytes
Returns the byte-representation of a range proof.
public fun range_proof_to_bytes(proof: &ristretto255_bulletproofs::RangeProof): vector<u8>
Implementation
public fun range_proof_to_bytes(proof: &RangeProof): vector<u8> { proof.bytes}
verify_range_proof_pedersen
Verifies a zero-knowledge range proof that the value v
committed in com
(under the default Bulletproofs
commitment key; see pedersen::new_commitment_for_bulletproof
) satisfies . Only works
for . Additionally, checks that the prover used dst
as the domain-separation
tag (DST).
WARNING: The DST check is VERY important for security as it prevents proofs computed for one application
(a.k.a., a domain) with dst_1
from verifying in a different application with dst_2 != dst_1
.
NOTE: currently, domain separation tags of size larger than 256 bytes are not supported.
public fun verify_range_proof_pedersen(com: &ristretto255_pedersen::Commitment, proof: &ristretto255_bulletproofs::RangeProof, num_bits: u64, dst: vector<u8>): bool
Implementation
public fun verify_range_proof_pedersen(com: &pedersen::Commitment, proof: &RangeProof, num_bits: u64, dst: vector<u8>): bool { verify_range_proof( pedersen::commitment_as_point(com), &ristretto255::basepoint(), &ristretto255::hash_to_point_base(), proof, num_bits, dst )}
verify_range_proof
Verifies a zero-knowledge range proof that the value v
committed in com
(as v * val_base + r * rand_base,
for some randomness r
) satisfies v
in [0, 2^num_bits)
.
Only works for num_bits
in {8, 16, 32, 64}
.
NOTE: currently, domain separation tags of size larger than 256 bytes are not supported.
public fun verify_range_proof(com: &ristretto255::RistrettoPoint, val_base: &ristretto255::RistrettoPoint, rand_base: &ristretto255::RistrettoPoint, proof: &ristretto255_bulletproofs::RangeProof, num_bits: u64, dst: vector<u8>): bool
Implementation
public fun verify_range_proof( com: &RistrettoPoint, val_base: &RistrettoPoint, rand_base: &RistrettoPoint, proof: &RangeProof, num_bits: u64, dst: vector<u8>): bool{ assert!(features::bulletproofs_enabled(), error::invalid_state(E_NATIVE_FUN_NOT_AVAILABLE)); assert!(dst.length() <= 256, error::invalid_argument(E_DST_TOO_LONG));
verify_range_proof_internal( ristretto255::point_to_bytes(&ristretto255::point_compress(com)), val_base, rand_base, proof.bytes, num_bits, dst )}
verify_batch_range_proof_pedersen
Verifies a zero-knowledge range proof for a batch of Pedersen commitments comms
(under the default Bulletproofs commitment key; see pedersen::new_commitment_for_bulletproof
),
ensuring that all values v
satisfy v
in [0, 2^num_bits)
.
Only works for num_bits
in {8, 16, 32, 64}
and batch size (length of comms
) in {1, 2, 4, 8, 16}
.
NOTE: currently, domain separation tags of size larger than 256 bytes are not supported.
public fun verify_batch_range_proof_pedersen(comms: &vector<ristretto255_pedersen::Commitment>, proof: &ristretto255_bulletproofs::RangeProof, num_bits: u64, dst: vector<u8>): bool
Implementation
public fun verify_batch_range_proof_pedersen( comms: &vector<pedersen::Commitment>, proof: &RangeProof, num_bits: u64, dst: vector<u8>): bool{ verify_batch_range_proof( &comms.map_ref(|com| ristretto255::point_clone(pedersen::commitment_as_point(com))), &ristretto255::basepoint(), &ristretto255::hash_to_point_base(), proof, num_bits, dst )}
verify_batch_range_proof
v * val_base + r * rand_base
), ensuring that all values v
satisfy
v
in [0, 2^num_bits)
. Only works for num_bits
in {8, 16, 32, 64}
and batch size
(length of the comms
) in {1, 2, 4, 8, 16}
.
NOTE: currently, domain separation tags of size larger than 256 bytes are not supported.
public fun verify_batch_range_proof(comms: &vector<ristretto255::RistrettoPoint>, val_base: &ristretto255::RistrettoPoint, rand_base: &ristretto255::RistrettoPoint, proof: &ristretto255_bulletproofs::RangeProof, num_bits: u64, dst: vector<u8>): bool
Implementation
public fun verify_batch_range_proof( comms: &vector<RistrettoPoint>, val_base: &RistrettoPoint, rand_base: &RistrettoPoint, proof: &RangeProof, num_bits: u64, dst: vector<u8>): bool{ assert!(features::bulletproofs_batch_enabled(), error::invalid_state(E_NATIVE_FUN_NOT_AVAILABLE)); assert!(dst.length() <= 256, error::invalid_argument(E_DST_TOO_LONG));
let comms = comms.map_ref(|com| ristretto255::point_to_bytes(&ristretto255::point_compress(com)));
verify_batch_range_proof_internal( comms, val_base, rand_base, proof.bytes, num_bits, dst )}
verify_range_proof_internal
Aborts with error::invalid_argument(E_DESERIALIZE_RANGE_PROOF)
if proof
is not a valid serialization of a
range proof.
Aborts with error::invalid_argument(E_RANGE_NOT_SUPPORTED)
if an unsupported num_bits
is provided.
fun verify_range_proof_internal(com: vector<u8>, val_base: &ristretto255::RistrettoPoint, rand_base: &ristretto255::RistrettoPoint, proof: vector<u8>, num_bits: u64, dst: vector<u8>): bool
Implementation
native fun verify_range_proof_internal( com: vector<u8>, val_base: &RistrettoPoint, rand_base: &RistrettoPoint, proof: vector<u8>, num_bits: u64, dst: vector<u8>): bool;
verify_batch_range_proof_internal
Aborts with error::invalid_argument(E_DESERIALIZE_RANGE_PROOF)
if proof
is not a valid serialization of a
range proof.
Aborts with error::invalid_argument(E_RANGE_NOT_SUPPORTED)
if an unsupported num_bits
is provided.
Aborts with error::invalid_argument(E_BATCH_SIZE_NOT_SUPPORTED)
if an unsupported batch size is provided.
Aborts with error::invalid_argument(E_VECTOR_LENGTHS_MISMATCH)
if the vector lengths of comms
and proof
do not match.
fun verify_batch_range_proof_internal(comms: vector<vector<u8>>, val_base: &ristretto255::RistrettoPoint, rand_base: &ristretto255::RistrettoPoint, proof: vector<u8>, num_bits: u64, dst: vector<u8>): bool
Implementation
native fun verify_batch_range_proof_internal( comms: vector<vector<u8>>, val_base: &RistrettoPoint, rand_base: &RistrettoPoint, proof: vector<u8>, num_bits: u64, dst: vector<u8>): bool;
Specification
verify_range_proof_internal
fun verify_range_proof_internal(com: vector<u8>, val_base: &ristretto255::RistrettoPoint, rand_base: &ristretto255::RistrettoPoint, proof: vector<u8>, num_bits: u64, dst: vector<u8>): bool
pragma opaque;
verify_batch_range_proof_internal
fun verify_batch_range_proof_internal(comms: vector<vector<u8>>, val_base: &ristretto255::RistrettoPoint, rand_base: &ristretto255::RistrettoPoint, proof: vector<u8>, num_bits: u64, dst: vector<u8>): bool
pragma opaque;