diff --git a/aptos-move/framework/aptos-stdlib/doc/ristretto255_bulletproofs.md b/aptos-move/framework/aptos-stdlib/doc/ristretto255_bulletproofs.md index 22fe4660646e5..6d91ed71085f0 100644 --- a/aptos-move/framework/aptos-stdlib/doc/ristretto255_bulletproofs.md +++ b/aptos-move/framework/aptos-stdlib/doc/ristretto255_bulletproofs.md @@ -9,6 +9,10 @@ A Bulletproof-based zero-knowledge range proof is a proof that a Pedersen commit $c = v G + r H$ commits to an $n$-bit value $v$ (i.e., $v \in [0, 2^n)$). Currently, this module only supports $n \in \{8, 16, 32, 64\}$ 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 $v \in [0, 2^n)$, and the supported batch +sizes are limited to $\{1, 2, 4, 8, 16\}$. + - [Struct `RangeProof`](#0x1_ristretto255_bulletproofs_RangeProof) - [Constants](#@Constants_0) @@ -17,7 +21,10 @@ $n \in \{8, 16, 32, 64\}$ for the number of bits. - [Function `range_proof_to_bytes`](#0x1_ristretto255_bulletproofs_range_proof_to_bytes) - [Function `verify_range_proof_pedersen`](#0x1_ristretto255_bulletproofs_verify_range_proof_pedersen) - [Function `verify_range_proof`](#0x1_ristretto255_bulletproofs_verify_range_proof) +- [Function `verify_batch_range_proof_pedersen`](#0x1_ristretto255_bulletproofs_verify_batch_range_proof_pedersen) +- [Function `verify_batch_range_proof`](#0x1_ristretto255_bulletproofs_verify_batch_range_proof) - [Function `verify_range_proof_internal`](#0x1_ristretto255_bulletproofs_verify_range_proof_internal) +- [Function `verify_batch_range_proof_internal`](#0x1_ristretto255_bulletproofs_verify_batch_range_proof_internal) - [Specification](#@Specification_1) - [Function `verify_range_proof_internal`](#@Specification_1_verify_range_proof_internal) @@ -74,12 +81,12 @@ The native functions have not been rolled out yet. - + -There was an error deserializing the range proof. +The range proof system only supports batch sizes of 1, 2, 4, 8, and 16. -
const E_DESERIALIZE_RANGE_PROOF: u64 = 1;
+const E_BATCH_SIZE_NOT_SUPPORTED: u64 = 3;
@@ -89,7 +96,7 @@ There was an error deserializing the range proof.
The range proof system only supports proving ranges of type $[0, 2^b)$ where $b \in \{8, 16, 32, 64\}$.
-const E_RANGE_NOT_SUPPORTED: u64 = 3;
+const E_RANGE_NOT_SUPPORTED: u64 = 2;
@@ -99,7 +106,17 @@ The range proof system only supports proving ranges of type $[0, 2^b)$ where $b
The committed value given to the prover is too large.
-const E_VALUE_OUTSIDE_RANGE: u64 = 2;
+const E_VALUE_OUTSIDE_RANGE: u64 = 1;
+
+
+
+
+
+
+The vector lengths of values and blinding factors do not match.
+
+
+const E_VECTOR_LENGTHS_MISMATCH: u64 = 4;
@@ -265,14 +282,89 @@ for some randomness r
) satisfies v
in [0, 2^num_
+
+
+
+
+## Function `verify_batch_range_proof_pedersen`
+
+Verifies a zero-knowledge range proof for a batch of Pedersen commitments comms
, 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}
.
+
+
+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
+{
+ assert!(features::bulletproofs_batch_enabled(), error::invalid_state(E_NATIVE_FUN_NOT_AVAILABLE));
+
+ let comms = std::vector::map_ref(comms, |com| ristretto255::point_to_bytes(&pedersen::commitment_as_compressed_point(com)));
+
+ verify_batch_range_proof_internal(
+ comms,
+ &ristretto255::basepoint(), &ristretto255::hash_to_point_base(),
+ proof.bytes, num_bits, dst
+ )
+}
+
+
+
+
+
+
+
+
+## Function `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}
.
+
+
+public fun verify_batch_range_proof(comms: &vector<ristretto255_pedersen::Commitment>, 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<pedersen::Commitment>,
+ 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));
+
+ let comms = std::vector::map_ref(comms, |com| ristretto255::point_to_bytes(&pedersen::commitment_as_compressed_point(com)));
+
+ verify_batch_range_proof_internal(
+ comms,
+ val_base, rand_base,
+ proof.bytes, num_bits, dst
+ )
+}
+
+
+
+
## Function `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.
@@ -296,6 +388,37 @@ Aborts with
+
+## Function `verify_batch_range_proof_internal`
+
+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;
+
+
+
+
diff --git a/aptos-move/framework/move-stdlib/doc/features.md b/aptos-move/framework/move-stdlib/doc/features.md
index 69b1082ad9b59..e010c138dd13c 100644
--- a/aptos-move/framework/move-stdlib/doc/features.md
+++ b/aptos-move/framework/move-stdlib/doc/features.md
@@ -139,6 +139,8 @@ return true.
- [Function `is_permissioned_signer_enabled`](#0x1_features_is_permissioned_signer_enabled)
- [Function `get_account_abstraction_feature`](#0x1_features_get_account_abstraction_feature)
- [Function `is_account_abstraction_enabled`](#0x1_features_is_account_abstraction_enabled)
+- [Function `get_bulletproofs_batch_feature`](#0x1_features_get_bulletproofs_batch_feature)
+- [Function `bulletproofs_batch_enabled`](#0x1_features_bulletproofs_batch_enabled)
- [Function `change_feature_flags`](#0x1_features_change_feature_flags)
- [Function `change_feature_flags_internal`](#0x1_features_change_feature_flags_internal)
- [Function `change_feature_flags_for_next_epoch`](#0x1_features_change_feature_flags_for_next_epoch)
@@ -326,6 +328,17 @@ Lifetime: transient
+
+
+Whether the batch Bulletproofs native functions are available. This is needed because of the introduction of a new native function.
+Lifetime: transient
+
+
+const BULLETPROOFS_BATCH_NATIVES: u64 = 87;
+
+
+
+
Whether the Bulletproofs zero-knowledge range proof module is enabled, and the related native function is
@@ -3447,6 +3460,52 @@ Deprecated feature
+
+
+
+
+## Function `get_bulletproofs_batch_feature`
+
+
+
+public fun get_bulletproofs_batch_feature(): u64
+
+
+
+
+
+Implementation
+
+
+public fun get_bulletproofs_batch_feature(): u64 { BULLETPROOFS_BATCH_NATIVES }
+
+
+
+
+
+
+
+
+## Function `bulletproofs_batch_enabled`
+
+
+
+public fun bulletproofs_batch_enabled(): bool
+
+
+
+
+
+Implementation
+
+
+public fun bulletproofs_batch_enabled(): bool acquires Features {
+ is_enabled(BULLETPROOFS_BATCH_NATIVES)
+}
+
+
+
+
diff --git a/crates/aptos-crypto/src/secp256r1_ecdsa/secp256r1_ecdsa_sigs.rs b/crates/aptos-crypto/src/secp256r1_ecdsa/secp256r1_ecdsa_sigs.rs
index aac404aaaba40..94471fbd38a3f 100644
--- a/crates/aptos-crypto/src/secp256r1_ecdsa/secp256r1_ecdsa_sigs.rs
+++ b/crates/aptos-crypto/src/secp256r1_ecdsa/secp256r1_ecdsa_sigs.rs
@@ -35,19 +35,6 @@ impl Signature {
/// Deserialize an P256Signature, without checking for malleability
/// Uses the SEC1 serialization format.
- #[cfg(not(feature = "fuzzing"))]
- pub(crate) fn from_bytes_unchecked(
- bytes: &[u8],
- ) -> std::result::Result {
- match p256::ecdsa::Signature::try_from(bytes) {
- Ok(p256_signature) => Ok(Signature(p256_signature)),
- Err(_) => Err(CryptoMaterialError::DeserializationError),
- }
- }
-
- /// Deserialize an P256Signature, without checking for malleability
- /// Uses the SEC1 serialization format.
- #[cfg(any(test, feature = "fuzzing"))]
pub fn from_bytes_unchecked(
bytes: &[u8],
) -> std::result::Result {