From 4c944931c521b53b757b1be52a23fa51b69a1b59 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Thu, 25 Aug 2022 14:22:52 +0900 Subject: [PATCH] zk-token-sdk:add length checks (#27389) * zk-token-sdk: add length check for ristretto encodings * zk-token-sdk: add type check for sigma proofs --- zk-token-sdk/src/encryption/elgamal.rs | 36 ++++++++++++------- zk-token-sdk/src/encryption/pedersen.rs | 4 +++ .../src/sigma_proofs/equality_proof.rs | 8 +++++ zk-token-sdk/src/sigma_proofs/fee_proof.rs | 4 +++ .../src/sigma_proofs/validity_proof.rs | 4 +++ .../src/sigma_proofs/zero_balance_proof.rs | 4 +++ 6 files changed, 48 insertions(+), 12 deletions(-) diff --git a/zk-token-sdk/src/encryption/elgamal.rs b/zk-token-sdk/src/encryption/elgamal.rs index c205bb4824..928844e3f1 100644 --- a/zk-token-sdk/src/encryption/elgamal.rs +++ b/zk-token-sdk/src/encryption/elgamal.rs @@ -18,7 +18,6 @@ use { discrete_log::DiscreteLog, pedersen::{Pedersen, PedersenCommitment, PedersenOpening, G, H}, }, - arrayref::{array_ref, array_refs}, core::ops::{Add, Mul, Sub}, curve25519_dalek::{ ristretto::{CompressedRistretto, RistrettoPoint}, @@ -195,8 +194,12 @@ impl ElGamalKeypair { } pub fn from_bytes(bytes: &[u8]) -> Option { + if bytes.len() != 64 { + return None; + } + Some(Self { - public: ElGamalPubkey::from_bytes(bytes[..32].try_into().ok()?)?, + public: ElGamalPubkey::from_bytes(&bytes[..32])?, secret: ElGamalSecretKey::from_bytes(bytes[32..].try_into().ok()?)?, }) } @@ -276,7 +279,11 @@ impl ElGamalPubkey { self.0.compress().to_bytes() } - pub fn from_bytes(bytes: &[u8; 32]) -> Option { + pub fn from_bytes(bytes: &[u8]) -> Option { + if bytes.len() != 32 { + return None; + } + Some(ElGamalPubkey( CompressedRistretto::from_slice(bytes).decompress()?, )) @@ -375,8 +382,11 @@ impl ElGamalSecretKey { self.0.to_bytes() } - pub fn from_bytes(bytes: [u8; 32]) -> Option { - Scalar::from_canonical_bytes(bytes).map(ElGamalSecretKey) + pub fn from_bytes(bytes: &[u8]) -> Option { + match bytes.try_into() { + Ok(bytes) => Scalar::from_canonical_bytes(bytes).map(ElGamalSecretKey), + _ => None, + } } } @@ -431,15 +441,13 @@ impl ElGamalCiphertext { } pub fn from_bytes(bytes: &[u8]) -> Option { - let bytes = array_ref![bytes, 0, 64]; - let (commitment, handle) = array_refs![bytes, 32, 32]; - - let commitment = CompressedRistretto::from_slice(commitment).decompress()?; - let handle = CompressedRistretto::from_slice(handle).decompress()?; + if bytes.len() != 64 { + return None; + } Some(ElGamalCiphertext { - commitment: PedersenCommitment(commitment), - handle: DecryptHandle(handle), + commitment: PedersenCommitment::from_bytes(&bytes[..32])?, + handle: DecryptHandle::from_bytes(&bytes[32..])?, }) } @@ -549,6 +557,10 @@ impl DecryptHandle { } pub fn from_bytes(bytes: &[u8]) -> Option { + if bytes.len() != 32 { + return None; + } + Some(DecryptHandle( CompressedRistretto::from_slice(bytes).decompress()?, )) diff --git a/zk-token-sdk/src/encryption/pedersen.rs b/zk-token-sdk/src/encryption/pedersen.rs index 345809317d..bfa9d28018 100644 --- a/zk-token-sdk/src/encryption/pedersen.rs +++ b/zk-token-sdk/src/encryption/pedersen.rs @@ -176,6 +176,10 @@ impl PedersenCommitment { } pub fn from_bytes(bytes: &[u8]) -> Option { + if bytes.len() != 32 { + return None; + } + Some(PedersenCommitment( CompressedRistretto::from_slice(bytes).decompress()?, )) diff --git a/zk-token-sdk/src/sigma_proofs/equality_proof.rs b/zk-token-sdk/src/sigma_proofs/equality_proof.rs index f3f4feffde..79df896cec 100644 --- a/zk-token-sdk/src/sigma_proofs/equality_proof.rs +++ b/zk-token-sdk/src/sigma_proofs/equality_proof.rs @@ -205,6 +205,10 @@ impl CtxtCommEqualityProof { } pub fn from_bytes(bytes: &[u8]) -> Result { + if bytes.len() != 192 { + return Err(EqualityProofError::Format); + } + let bytes = array_ref![bytes, 0, 192]; let (Y_0, Y_1, Y_2, z_s, z_x, z_r) = array_refs![bytes, 32, 32, 32, 32, 32, 32]; @@ -424,6 +428,10 @@ impl CtxtCtxtEqualityProof { } pub fn from_bytes(bytes: &[u8]) -> Result { + if bytes.len() != 224 { + return Err(EqualityProofError::Format); + } + let bytes = array_ref![bytes, 0, 224]; let (Y_0, Y_1, Y_2, Y_3, z_s, z_x, z_r) = array_refs![bytes, 32, 32, 32, 32, 32, 32, 32]; diff --git a/zk-token-sdk/src/sigma_proofs/fee_proof.rs b/zk-token-sdk/src/sigma_proofs/fee_proof.rs index 9445b55761..ff70586bfd 100644 --- a/zk-token-sdk/src/sigma_proofs/fee_proof.rs +++ b/zk-token-sdk/src/sigma_proofs/fee_proof.rs @@ -360,6 +360,10 @@ impl FeeSigmaProof { } pub fn from_bytes(bytes: &[u8]) -> Result { + if bytes.len() != 256 { + return Err(FeeSigmaProofError::Format); + } + let bytes = array_ref![bytes, 0, 256]; let (Y_max_proof, z_max_proof, c_max_proof, Y_delta, Y_claimed, z_x, z_delta, z_claimed) = array_refs![bytes, 32, 32, 32, 32, 32, 32, 32, 32]; diff --git a/zk-token-sdk/src/sigma_proofs/validity_proof.rs b/zk-token-sdk/src/sigma_proofs/validity_proof.rs index 6084657612..de45beaf0f 100644 --- a/zk-token-sdk/src/sigma_proofs/validity_proof.rs +++ b/zk-token-sdk/src/sigma_proofs/validity_proof.rs @@ -193,6 +193,10 @@ impl ValidityProof { } pub fn from_bytes(bytes: &[u8]) -> Result { + if bytes.len() != 160 { + return Err(ValidityProofError::Format); + } + let bytes = array_ref![bytes, 0, 160]; let (Y_0, Y_1, Y_2, z_r, z_x) = array_refs![bytes, 32, 32, 32, 32, 32]; diff --git a/zk-token-sdk/src/sigma_proofs/zero_balance_proof.rs b/zk-token-sdk/src/sigma_proofs/zero_balance_proof.rs index 642e8b57ed..17c19582a0 100644 --- a/zk-token-sdk/src/sigma_proofs/zero_balance_proof.rs +++ b/zk-token-sdk/src/sigma_proofs/zero_balance_proof.rs @@ -152,6 +152,10 @@ impl ZeroBalanceProof { } pub fn from_bytes(bytes: &[u8]) -> Result { + if bytes.len() != 96 { + return Err(ZeroBalanceProofError::Format); + } + let bytes = array_ref![bytes, 0, 96]; let (Y_P, Y_D, z) = array_refs![bytes, 32, 32, 32];