From 40d7276028f18fadd8a720aacea7213b71feaddb Mon Sep 17 00:00:00 2001 From: "zhoujun.ma" Date: Thu, 30 Jan 2025 10:18:55 -0800 Subject: [PATCH] update --- .../doc/ristretto255_bulletproofs.md | 137 +++++++++++++++++- .../framework/move-stdlib/doc/features.md | 59 ++++++++ .../secp256r1_ecdsa/secp256r1_ecdsa_sigs.rs | 13 -- 3 files changed, 189 insertions(+), 20 deletions(-) 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 {