From e2c2029ac4974687f38ec711fa67512fbd710386 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Thu, 18 Jan 2024 14:37:04 +0900 Subject: [PATCH] [zk-token-sdk] Restrict a single-bit of 256-bit batched range proof to 128 (#34803) * fix previous typo * restrict single-bit of 256-bit batched range proof to 128 --- .../batched_range_proof_u128.rs | 2 +- .../batched_range_proof_u256.rs | 19 +++++++++++++++++-- .../instruction/batched_range_proof/mod.rs | 9 ++++++++- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/zk-token-sdk/src/instruction/batched_range_proof/batched_range_proof_u128.rs b/zk-token-sdk/src/instruction/batched_range_proof/batched_range_proof_u128.rs index 4036be9a9..a1193c041 100644 --- a/zk-token-sdk/src/instruction/batched_range_proof/batched_range_proof_u128.rs +++ b/zk-token-sdk/src/instruction/batched_range_proof/batched_range_proof_u128.rs @@ -41,7 +41,7 @@ impl BatchedRangeProofU128Data { bit_lengths: Vec, openings: Vec<&PedersenOpening>, ) -> Result { - // the sum of the bit lengths must be 64 + // the sum of the bit lengths must be 128 let batched_bit_length = bit_lengths .iter() .try_fold(0_usize, |acc, &x| acc.checked_add(x)) diff --git a/zk-token-sdk/src/instruction/batched_range_proof/batched_range_proof_u256.rs b/zk-token-sdk/src/instruction/batched_range_proof/batched_range_proof_u256.rs index 1bdba644f..39237a3b7 100644 --- a/zk-token-sdk/src/instruction/batched_range_proof/batched_range_proof_u256.rs +++ b/zk-token-sdk/src/instruction/batched_range_proof/batched_range_proof_u256.rs @@ -5,7 +5,7 @@ use { crate::{ encryption::pedersen::{PedersenCommitment, PedersenOpening}, errors::{ProofGenerationError, ProofVerificationError}, - instruction::batched_range_proof::MAX_COMMITMENTS, + instruction::batched_range_proof::{MAX_COMMITMENTS, MAX_SINGLE_BIT_LENGTH}, range_proof::RangeProof, }, std::convert::TryInto, @@ -44,7 +44,15 @@ impl BatchedRangeProofU256Data { bit_lengths: Vec, openings: Vec<&PedersenOpening>, ) -> Result { - // the sum of the bit lengths must be 64 + // each bit length must be at most 128 + if bit_lengths + .iter() + .any(|length| *length > MAX_SINGLE_BIT_LENGTH) + { + return Err(ProofGenerationError::IllegalCommitmentLength); + } + + // the sum of the bit lengths must be 256 let batched_bit_length = bit_lengths .iter() .try_fold(0_usize, |acc, &x| acc.checked_add(x)) @@ -77,6 +85,13 @@ impl ZkProofData for BatchedRangeProofU256Data { let (commitments, bit_lengths) = self.context.try_into()?; let num_commitments = commitments.len(); + if bit_lengths + .iter() + .any(|length| *length > MAX_SINGLE_BIT_LENGTH) + { + return Err(ProofVerificationError::IllegalCommitmentLength); + } + if num_commitments > MAX_COMMITMENTS || num_commitments != bit_lengths.len() { return Err(ProofVerificationError::IllegalCommitmentLength); } diff --git a/zk-token-sdk/src/instruction/batched_range_proof/mod.rs b/zk-token-sdk/src/instruction/batched_range_proof/mod.rs index a5bd3b5fe..a002ca80b 100644 --- a/zk-token-sdk/src/instruction/batched_range_proof/mod.rs +++ b/zk-token-sdk/src/instruction/batched_range_proof/mod.rs @@ -14,7 +14,7 @@ //! the sum of all bit-lengths. //! //! The maximum number of commitments is fixed at 8. Each bit-length in `[n_1, ..., n_N]` must be a -//! power-of-two positive integer less than 256. +//! power-of-two positive integer less than 128. pub mod batched_range_proof_u128; pub mod batched_range_proof_u256; @@ -38,6 +38,13 @@ use { const MAX_COMMITMENTS: usize = 8; +/// A bit length in a batched range proof must be at most 128. +/// +/// A 256-bit range proof on a single Pedersen commitment is meaningless and hence enforce an upper +/// bound as the largest power-of-two number less than 256. +#[cfg(not(target_os = "solana"))] +const MAX_SINGLE_BIT_LENGTH: usize = 128; + /// The context data needed to verify a range-proof for a Pedersen committed value. /// /// The context data is shared by all `VerifyBatchedRangeProof{N}` instructions.