[zk-token-sdk] reorganize errors (#29005)

* reorganize error using DRY principle

* rename error `Format` to `Deserialization`

* Rename `EncryptionError` to `DiscreteLogError`

* resolve errors from rebase

* resolve clippy

* change `ProofInstructionError` to `ProofError`
This commit is contained in:
samkim-crypto 2022-12-01 20:29:14 +09:00 committed by GitHub
parent f766895f78
commit ae57a14ef6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 248 additions and 228 deletions

View File

@ -17,7 +17,7 @@
#![cfg(not(target_os = "solana"))]
use {
crate::encryption::errors::EncryptionError,
crate::encryption::errors::DiscreteLogError,
curve25519_dalek::{
constants::RISTRETTO_BASEPOINT_POINT as G,
ristretto::RistrettoPoint,
@ -100,10 +100,10 @@ impl DiscreteLog {
}
/// Adjusts number of threads in a discrete log instance.
pub fn num_threads(&mut self, num_threads: usize) -> Result<(), EncryptionError> {
pub fn num_threads(&mut self, num_threads: usize) -> Result<(), DiscreteLogError> {
// number of threads must be a positive power-of-two integer
if num_threads == 0 || (num_threads & (num_threads - 1)) != 0 || num_threads > 65536 {
return Err(EncryptionError::DiscreteLogThreads);
return Err(DiscreteLogError::DiscreteLogThreads);
}
self.num_threads = num_threads;
@ -117,9 +117,9 @@ impl DiscreteLog {
pub fn set_compression_batch_size(
&mut self,
compression_batch_size: usize,
) -> Result<(), EncryptionError> {
) -> Result<(), DiscreteLogError> {
if compression_batch_size >= TWO16 as usize {
return Err(EncryptionError::DiscreteLogBatchSize);
return Err(DiscreteLogError::DiscreteLogBatchSize);
}
self.compression_batch_size = compression_batch_size;

View File

@ -2,7 +2,7 @@
use thiserror::Error;
#[derive(Error, Clone, Debug, Eq, PartialEq)]
pub enum EncryptionError {
pub enum DiscreteLogError {
#[error("discrete log number of threads not power-of-two")]
DiscreteLogThreads,
#[error("discrete log batch size too large")]

View File

@ -10,30 +10,46 @@ pub enum ProofError {
TransferAmount,
#[error("proof generation failed")]
Generation,
#[error("proof failed to verify")]
RangeProof,
#[error("equality proof failed to verify")]
EqualityProof,
#[error("fee proof failed to verify")]
FeeProof,
#[error("zero-balance proof failed to verify")]
ZeroBalanceProof,
#[error("validity proof failed to verify")]
ValidityProof,
#[error("public-key sigma proof failed to verify")]
PubkeySigmaProof,
#[error("proof verification failed")]
VerificationError(ProofType, ProofVerificationError),
#[error("failed to decrypt ciphertext")]
Decryption,
#[error("invalid ciphertext data")]
CiphertextDeserialization,
#[error("invalid scalar data")]
ScalarDeserialization,
#[error("invalid public key data")]
#[error("invalid pubkey data")]
PubkeyDeserialization,
#[error("ciphertext does not exist in proof data")]
#[error("ciphertext does not exist in instruction data")]
MissingCiphertext,
#[error("transfer amount split failed")]
TransferSplit,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ProofType {
EqualityProof,
ValidityProof,
ZeroBalanceProof,
FeeSigmaProof,
PubkeyValidityProof,
RangeProof,
}
#[derive(Error, Clone, Debug, Eq, PartialEq)]
pub enum ProofVerificationError {
#[error("required algebraic relation does not hold")]
AlgebraicRelation,
#[error("malformed proof")]
Deserialization,
#[error("multiscalar multiplication failed")]
MultiscalarMul,
#[error("transcript failed to produce a challenge")]
Transcript(#[from] TranscriptError),
#[error(
"attempted to verify range proof with a non-power-of-two bit size or bit size is too big"
)]
InvalidBitSize,
#[error("insufficient generators for the proof")]
InvalidGeneratorsLength,
#[error("number of blinding factors do not match the number of values")]
WrongNumBlindingFactors,
}
#[derive(Error, Clone, Debug, Eq, PartialEq)]
@ -43,36 +59,36 @@ pub enum TranscriptError {
}
impl From<RangeProofError> for ProofError {
fn from(_err: RangeProofError) -> Self {
Self::RangeProof
fn from(err: RangeProofError) -> Self {
Self::VerificationError(ProofType::RangeProof, err.0)
}
}
impl From<EqualityProofError> for ProofError {
fn from(_err: EqualityProofError) -> Self {
Self::EqualityProof
fn from(err: EqualityProofError) -> Self {
Self::VerificationError(ProofType::EqualityProof, err.0)
}
}
impl From<FeeSigmaProofError> for ProofError {
fn from(_err: FeeSigmaProofError) -> Self {
Self::FeeProof
fn from(err: FeeSigmaProofError) -> Self {
Self::VerificationError(ProofType::FeeSigmaProof, err.0)
}
}
impl From<ZeroBalanceProofError> for ProofError {
fn from(_err: ZeroBalanceProofError) -> Self {
Self::ZeroBalanceProof
fn from(err: ZeroBalanceProofError) -> Self {
Self::VerificationError(ProofType::ZeroBalanceProof, err.0)
}
}
impl From<ValidityProofError> for ProofError {
fn from(_err: ValidityProofError) -> Self {
Self::ValidityProof
fn from(err: ValidityProofError) -> Self {
Self::VerificationError(ProofType::ValidityProof, err.0)
}
}
impl From<PubkeySigmaProofError> for ProofError {
fn from(_err: PubkeySigmaProofError) -> Self {
Self::PubkeySigmaProof
impl From<PubkeyValidityProofError> for ProofError {
fn from(err: PubkeyValidityProofError) -> Self {
Self::VerificationError(ProofType::PubkeyValidityProof, err.0)
}
}

View File

@ -455,11 +455,11 @@ impl TransferPubkeys {
let (source_pubkey, destination_pubkey, auditor_pubkey) = array_refs![bytes, 32, 32, 32];
let source_pubkey =
ElGamalPubkey::from_bytes(source_pubkey).ok_or(ProofError::Decryption)?;
let destination_pubkey =
ElGamalPubkey::from_bytes(destination_pubkey).ok_or(ProofError::Decryption)?;
ElGamalPubkey::from_bytes(source_pubkey).ok_or(ProofError::PubkeyDeserialization)?;
let destination_pubkey = ElGamalPubkey::from_bytes(destination_pubkey)
.ok_or(ProofError::PubkeyDeserialization)?;
let auditor_pubkey =
ElGamalPubkey::from_bytes(auditor_pubkey).ok_or(ProofError::Decryption)?;
ElGamalPubkey::from_bytes(auditor_pubkey).ok_or(ProofError::PubkeyDeserialization)?;
Ok(Self {
source_pubkey,

View File

@ -74,3 +74,13 @@ macro_rules! define_mul_variants {
}
};
}
macro_rules! impl_from_transcript_error {
($sigma_error_type:ty) => {
impl From<TranscriptError> for $sigma_error_type {
fn from(err: TranscriptError) -> Self {
ProofVerificationError::Transcript(err).into()
}
}
};
}

View File

@ -1,26 +1,10 @@
//! Errors related to proving and verifying range proofs.
use {crate::errors::TranscriptError, thiserror::Error};
use {
crate::errors::{ProofVerificationError, TranscriptError},
thiserror::Error,
};
#[derive(Error, Clone, Debug, Eq, PartialEq)]
pub enum RangeProofError {
#[error("the required algebraic relation does not hold")]
AlgebraicRelation,
#[error("malformed proof")]
Format,
#[error("attempted to create a proof with a non-power-of-two bitsize or bitsize too big")]
InvalidBitsize,
#[error("insufficient generators for the proof")]
InvalidGeneratorsLength,
#[error("multiscalar multiplication failed")]
MultiscalarMul,
#[error("transcript failed to produce a challenge")]
Transcript,
#[error("number of blinding factors do not match the number of values")]
WrongNumBlindingFactors,
}
impl From<TranscriptError> for RangeProofError {
fn from(_err: TranscriptError) -> Self {
Self::Transcript
}
}
#[error("range proof verification failed: {0}")]
pub struct RangeProofError(#[from] pub(crate) ProofVerificationError);
impl_from_transcript_error!(RangeProofError);

View File

@ -1,5 +1,6 @@
use {
crate::{
errors::ProofVerificationError,
range_proof::{errors::RangeProofError, util},
transcript::TranscriptProtocol,
},
@ -208,10 +209,10 @@ impl InnerProductProof {
if lg_n >= 32 {
// 4 billion multiplications should be enough for anyone
// and this check prevents overflow in 1<<lg_n below.
return Err(RangeProofError::InvalidBitsize);
return Err(ProofVerificationError::InvalidBitSize.into());
}
if n != (1 << lg_n) {
return Err(RangeProofError::InvalidBitsize);
return Err(ProofVerificationError::InvalidBitSize.into());
}
transcript.innerproduct_domain_sep(n as u64);
@ -298,13 +299,19 @@ impl InnerProductProof {
let Ls = self
.L_vec
.iter()
.map(|p| p.decompress().ok_or(RangeProofError::Format))
.map(|p| {
p.decompress()
.ok_or(ProofVerificationError::Deserialization)
})
.collect::<Result<Vec<_>, _>>()?;
let Rs = self
.R_vec
.iter()
.map(|p| p.decompress().ok_or(RangeProofError::Format))
.map(|p| {
p.decompress()
.ok_or(ProofVerificationError::Deserialization)
})
.collect::<Result<Vec<_>, _>>()?;
let expect_P = RistrettoPoint::vartime_multiscalar_mul(
@ -323,7 +330,7 @@ impl InnerProductProof {
if expect_P == *P {
Ok(())
} else {
Err(RangeProofError::AlgebraicRelation)
Err(ProofVerificationError::AlgebraicRelation.into())
}
}
@ -360,18 +367,18 @@ impl InnerProductProof {
pub fn from_bytes(slice: &[u8]) -> Result<InnerProductProof, RangeProofError> {
let b = slice.len();
if b % 32 != 0 {
return Err(RangeProofError::Format);
return Err(ProofVerificationError::Deserialization.into());
}
let num_elements = b / 32;
if num_elements < 2 {
return Err(RangeProofError::Format);
return Err(ProofVerificationError::Deserialization.into());
}
if (num_elements - 2) % 2 != 0 {
return Err(RangeProofError::Format);
return Err(ProofVerificationError::Deserialization.into());
}
let lg_n = (num_elements - 2) / 2;
if lg_n >= 32 {
return Err(RangeProofError::Format);
return Err(ProofVerificationError::Deserialization.into());
}
let mut L_vec: Vec<CompressedRistretto> = Vec::with_capacity(lg_n);
@ -384,9 +391,9 @@ impl InnerProductProof {
let pos = 2 * lg_n * 32;
let a = Scalar::from_canonical_bytes(util::read32(&slice[pos..]))
.ok_or(RangeProofError::Format)?;
.ok_or(ProofVerificationError::Deserialization)?;
let b = Scalar::from_canonical_bytes(util::read32(&slice[pos + 32..]))
.ok_or(RangeProofError::Format)?;
.ok_or(ProofVerificationError::Deserialization)?;
Ok(InnerProductProof { L_vec, R_vec, a, b })
}

View File

@ -8,6 +8,7 @@ use {
use {
crate::{
encryption::pedersen::{G, H},
errors::ProofVerificationError,
range_proof::{
errors::RangeProofError, generators::BulletproofGens, inner_product::InnerProductProof,
},
@ -232,7 +233,7 @@ impl RangeProof {
let bp_gens = BulletproofGens::new(nm);
if !nm.is_power_of_two() {
return Err(RangeProofError::InvalidBitsize);
return Err(ProofVerificationError::InvalidBitSize.into());
}
// append proof data to transcript and derive appropriate challenge scalars
@ -310,12 +311,12 @@ impl RangeProof {
.chain(bp_gens.H(nm).map(|&x| Some(x)))
.chain(comms.iter().map(|V| Some(*V.get_point()))),
)
.ok_or(RangeProofError::MultiscalarMul)?;
.ok_or(ProofVerificationError::MultiscalarMul)?;
if mega_check.is_identity() {
Ok(())
} else {
Err(RangeProofError::AlgebraicRelation)
Err(ProofVerificationError::AlgebraicRelation.into())
}
}
@ -338,10 +339,10 @@ impl RangeProof {
// changed.
pub fn from_bytes(slice: &[u8]) -> Result<RangeProof, RangeProofError> {
if slice.len() % 32 != 0 {
return Err(RangeProofError::Format);
return Err(ProofVerificationError::Deserialization.into());
}
if slice.len() < 7 * 32 {
return Err(RangeProofError::Format);
return Err(ProofVerificationError::Deserialization.into());
}
let A = CompressedRistretto(util::read32(&slice[0..]));
@ -350,11 +351,11 @@ impl RangeProof {
let T_2 = CompressedRistretto(util::read32(&slice[3 * 32..]));
let t_x = Scalar::from_canonical_bytes(util::read32(&slice[4 * 32..]))
.ok_or(RangeProofError::Format)?;
.ok_or(ProofVerificationError::Deserialization)?;
let t_x_blinding = Scalar::from_canonical_bytes(util::read32(&slice[5 * 32..]))
.ok_or(RangeProofError::Format)?;
.ok_or(ProofVerificationError::Deserialization)?;
let e_blinding = Scalar::from_canonical_bytes(util::read32(&slice[6 * 32..]))
.ok_or(RangeProofError::Format)?;
.ok_or(ProofVerificationError::Deserialization)?;
let ipp_proof = InnerProductProof::from_bytes(&slice[7 * 32..])?;

View File

@ -12,9 +12,12 @@
#[cfg(not(target_os = "solana"))]
use {
crate::encryption::{
elgamal::{ElGamalCiphertext, ElGamalKeypair, ElGamalPubkey},
pedersen::{PedersenCommitment, PedersenOpening, G, H},
crate::{
encryption::{
elgamal::{ElGamalCiphertext, ElGamalKeypair, ElGamalPubkey},
pedersen::{PedersenCommitment, PedersenOpening, G, H},
},
errors::ProofVerificationError,
},
curve25519_dalek::traits::MultiscalarMul,
rand::rngs::OsRng,
@ -153,9 +156,18 @@ impl CtxtCommEqualityProof {
let ww_negated = -&ww;
// check that the required algebraic condition holds
let Y_0 = self.Y_0.decompress().ok_or(EqualityProofError::Format)?;
let Y_1 = self.Y_1.decompress().ok_or(EqualityProofError::Format)?;
let Y_2 = self.Y_2.decompress().ok_or(EqualityProofError::Format)?;
let Y_0 = self
.Y_0
.decompress()
.ok_or(ProofVerificationError::Deserialization)?;
let Y_1 = self
.Y_1
.decompress()
.ok_or(ProofVerificationError::Deserialization)?;
let Y_2 = self
.Y_2
.decompress()
.ok_or(ProofVerificationError::Deserialization)?;
let check = RistrettoPoint::vartime_multiscalar_mul(
vec![
@ -189,7 +201,7 @@ impl CtxtCommEqualityProof {
if check.is_identity() {
Ok(())
} else {
Err(EqualityProofError::AlgebraicRelation)
Err(ProofVerificationError::AlgebraicRelation.into())
}
}
@ -206,7 +218,7 @@ impl CtxtCommEqualityProof {
pub fn from_bytes(bytes: &[u8]) -> Result<Self, EqualityProofError> {
if bytes.len() != 192 {
return Err(EqualityProofError::Format);
return Err(ProofVerificationError::Deserialization.into());
}
let bytes = array_ref![bytes, 0, 192];
@ -216,9 +228,12 @@ impl CtxtCommEqualityProof {
let Y_1 = CompressedRistretto::from_slice(Y_1);
let Y_2 = CompressedRistretto::from_slice(Y_2);
let z_s = Scalar::from_canonical_bytes(*z_s).ok_or(EqualityProofError::Format)?;
let z_x = Scalar::from_canonical_bytes(*z_x).ok_or(EqualityProofError::Format)?;
let z_r = Scalar::from_canonical_bytes(*z_r).ok_or(EqualityProofError::Format)?;
let z_s =
Scalar::from_canonical_bytes(*z_s).ok_or(ProofVerificationError::Deserialization)?;
let z_x =
Scalar::from_canonical_bytes(*z_x).ok_or(ProofVerificationError::Deserialization)?;
let z_r =
Scalar::from_canonical_bytes(*z_r).ok_or(ProofVerificationError::Deserialization)?;
Ok(CtxtCommEqualityProof {
Y_0,
@ -368,10 +383,22 @@ impl CtxtCtxtEqualityProof {
let www_negated = -&www;
// check that the required algebraic condition holds
let Y_0 = self.Y_0.decompress().ok_or(EqualityProofError::Format)?;
let Y_1 = self.Y_1.decompress().ok_or(EqualityProofError::Format)?;
let Y_2 = self.Y_2.decompress().ok_or(EqualityProofError::Format)?;
let Y_3 = self.Y_3.decompress().ok_or(EqualityProofError::Format)?;
let Y_0 = self
.Y_0
.decompress()
.ok_or(ProofVerificationError::Deserialization)?;
let Y_1 = self
.Y_1
.decompress()
.ok_or(ProofVerificationError::Deserialization)?;
let Y_2 = self
.Y_2
.decompress()
.ok_or(ProofVerificationError::Deserialization)?;
let Y_3 = self
.Y_3
.decompress()
.ok_or(ProofVerificationError::Deserialization)?;
let check = RistrettoPoint::vartime_multiscalar_mul(
vec![
@ -411,7 +438,7 @@ impl CtxtCtxtEqualityProof {
if check.is_identity() {
Ok(())
} else {
Err(EqualityProofError::AlgebraicRelation)
Err(ProofVerificationError::AlgebraicRelation.into())
}
}
@ -429,7 +456,7 @@ impl CtxtCtxtEqualityProof {
pub fn from_bytes(bytes: &[u8]) -> Result<Self, EqualityProofError> {
if bytes.len() != 224 {
return Err(EqualityProofError::Format);
return Err(ProofVerificationError::Deserialization.into());
}
let bytes = array_ref![bytes, 0, 224];
@ -440,9 +467,12 @@ impl CtxtCtxtEqualityProof {
let Y_2 = CompressedRistretto::from_slice(Y_2);
let Y_3 = CompressedRistretto::from_slice(Y_3);
let z_s = Scalar::from_canonical_bytes(*z_s).ok_or(EqualityProofError::Format)?;
let z_x = Scalar::from_canonical_bytes(*z_x).ok_or(EqualityProofError::Format)?;
let z_r = Scalar::from_canonical_bytes(*z_r).ok_or(EqualityProofError::Format)?;
let z_s =
Scalar::from_canonical_bytes(*z_s).ok_or(ProofVerificationError::Deserialization)?;
let z_x =
Scalar::from_canonical_bytes(*z_x).ok_or(ProofVerificationError::Deserialization)?;
let z_r =
Scalar::from_canonical_bytes(*z_r).ok_or(ProofVerificationError::Deserialization)?;
Ok(CtxtCtxtEqualityProof {
Y_0,

View File

@ -1,92 +1,30 @@
//! Errors related to proving and verifying sigma proofs.
use {crate::errors::TranscriptError, thiserror::Error};
use {
crate::errors::{ProofVerificationError, TranscriptError},
thiserror::Error,
};
#[derive(Error, Clone, Debug, Eq, PartialEq)]
pub enum EqualityProofError {
#[error("the required algebraic relation does not hold")]
AlgebraicRelation,
#[error("malformed proof")]
Format,
#[error("multiscalar multiplication failed")]
MultiscalarMul,
#[error("transcript failed to produce a challenge")]
Transcript,
}
impl From<TranscriptError> for EqualityProofError {
fn from(_err: TranscriptError) -> Self {
Self::Transcript
}
}
#[error("equality proof verification failed: {0}")]
pub struct EqualityProofError(#[from] pub(crate) ProofVerificationError);
impl_from_transcript_error!(EqualityProofError);
#[derive(Error, Clone, Debug, Eq, PartialEq)]
pub enum ValidityProofError {
#[error("the required algebraic relation does not hold")]
AlgebraicRelation,
#[error("malformed proof")]
Format,
#[error("multiscalar multiplication failed")]
MultiscalarMul,
#[error("transcript failed to produce a challenge")]
Transcript,
}
impl From<TranscriptError> for ValidityProofError {
fn from(_err: TranscriptError) -> Self {
Self::Transcript
}
}
#[error("validity proof verification failed: {0}")]
pub struct ValidityProofError(#[from] pub(crate) ProofVerificationError);
impl_from_transcript_error!(ValidityProofError);
#[derive(Error, Clone, Debug, Eq, PartialEq)]
pub enum ZeroBalanceProofError {
#[error("the required algebraic relation does not hold")]
AlgebraicRelation,
#[error("malformed proof")]
Format,
#[error("multiscalar multiplication failed")]
MultiscalarMul,
#[error("transcript failed to produce a challenge")]
Transcript,
}
impl From<TranscriptError> for ZeroBalanceProofError {
fn from(_err: TranscriptError) -> Self {
Self::Transcript
}
}
#[error("zero-balance proof verification failed: {0}")]
pub struct ZeroBalanceProofError(#[from] pub(crate) ProofVerificationError);
impl_from_transcript_error!(ZeroBalanceProofError);
#[derive(Error, Clone, Debug, Eq, PartialEq)]
pub enum FeeSigmaProofError {
#[error("the required algebraic relation does not hold")]
AlgebraicRelation,
#[error("malformed proof")]
Format,
#[error("multiscalar multiplication failed")]
MultiscalarMul,
#[error("transcript failed to produce a challenge")]
Transcript,
}
impl From<TranscriptError> for FeeSigmaProofError {
fn from(_err: TranscriptError) -> Self {
Self::Transcript
}
}
#[error("fee sigma proof verification failed: {0}")]
pub struct FeeSigmaProofError(#[from] pub(crate) ProofVerificationError);
impl_from_transcript_error!(FeeSigmaProofError);
#[derive(Error, Clone, Debug, Eq, PartialEq)]
pub enum PubkeySigmaProofError {
#[error("the required algebraic relation does not hold")]
AlgebraicRelation,
#[error("malformed proof")]
Format,
#[error("multiscalar multiplication failed")]
MultiscalarMul,
#[error("transcript failed to produce a challenge")]
Transcript,
}
impl From<TranscriptError> for PubkeySigmaProofError {
fn from(_err: TranscriptError) -> Self {
Self::Transcript
}
}
#[error("public key validity proof verification failed: {0}")]
pub struct PubkeyValidityProofError(#[from] pub(crate) ProofVerificationError);
impl_from_transcript_error!(PubkeyValidityProofError);

View File

@ -8,7 +8,10 @@ use {
rand::rngs::OsRng,
};
use {
crate::{sigma_proofs::errors::FeeSigmaProofError, transcript::TranscriptProtocol},
crate::{
errors::ProofVerificationError, sigma_proofs::errors::FeeSigmaProofError,
transcript::TranscriptProtocol,
},
arrayref::{array_ref, array_refs},
curve25519_dalek::{
ristretto::{CompressedRistretto, RistrettoPoint},
@ -284,19 +287,19 @@ impl FeeSigmaProof {
.fee_max_proof
.Y_max_proof
.decompress()
.ok_or(FeeSigmaProofError::Format)?;
.ok_or(ProofVerificationError::Deserialization)?;
let z_max = self.fee_max_proof.z_max_proof;
let Y_delta_real = self
.fee_equality_proof
.Y_delta
.decompress()
.ok_or(FeeSigmaProofError::Format)?;
.ok_or(ProofVerificationError::Deserialization)?;
let Y_claimed = self
.fee_equality_proof
.Y_claimed
.decompress()
.ok_or(FeeSigmaProofError::Format)?;
.ok_or(ProofVerificationError::Deserialization)?;
let z_x = self.fee_equality_proof.z_x;
let z_delta_real = self.fee_equality_proof.z_delta;
let z_claimed = self.fee_equality_proof.z_claimed;
@ -342,7 +345,7 @@ impl FeeSigmaProof {
if check.is_identity() {
Ok(())
} else {
Err(FeeSigmaProofError::AlgebraicRelation)
Err(ProofVerificationError::AlgebraicRelation.into())
}
}
@ -361,7 +364,7 @@ impl FeeSigmaProof {
pub fn from_bytes(bytes: &[u8]) -> Result<Self, FeeSigmaProofError> {
if bytes.len() != 256 {
return Err(FeeSigmaProofError::Format);
return Err(ProofVerificationError::Deserialization.into());
}
let bytes = array_ref![bytes, 0, 256];
@ -369,17 +372,19 @@ impl FeeSigmaProof {
array_refs![bytes, 32, 32, 32, 32, 32, 32, 32, 32];
let Y_max_proof = CompressedRistretto::from_slice(Y_max_proof);
let z_max_proof =
Scalar::from_canonical_bytes(*z_max_proof).ok_or(FeeSigmaProofError::Format)?;
let c_max_proof =
Scalar::from_canonical_bytes(*c_max_proof).ok_or(FeeSigmaProofError::Format)?;
let z_max_proof = Scalar::from_canonical_bytes(*z_max_proof)
.ok_or(ProofVerificationError::Deserialization)?;
let c_max_proof = Scalar::from_canonical_bytes(*c_max_proof)
.ok_or(ProofVerificationError::Deserialization)?;
let Y_delta = CompressedRistretto::from_slice(Y_delta);
let Y_claimed = CompressedRistretto::from_slice(Y_claimed);
let z_x = Scalar::from_canonical_bytes(*z_x).ok_or(FeeSigmaProofError::Format)?;
let z_delta = Scalar::from_canonical_bytes(*z_delta).ok_or(FeeSigmaProofError::Format)?;
let z_claimed =
Scalar::from_canonical_bytes(*z_claimed).ok_or(FeeSigmaProofError::Format)?;
let z_x =
Scalar::from_canonical_bytes(*z_x).ok_or(ProofVerificationError::Deserialization)?;
let z_delta = Scalar::from_canonical_bytes(*z_delta)
.ok_or(ProofVerificationError::Deserialization)?;
let z_claimed = Scalar::from_canonical_bytes(*z_claimed)
.ok_or(ProofVerificationError::Deserialization)?;
Ok(Self {
fee_max_proof: FeeMaxProof {

View File

@ -17,7 +17,10 @@ use {
zeroize::Zeroize,
};
use {
crate::{sigma_proofs::errors::PubkeySigmaProofError, transcript::TranscriptProtocol},
crate::{
errors::ProofVerificationError, sigma_proofs::errors::PubkeyValidityProofError,
transcript::TranscriptProtocol,
},
arrayref::{array_ref, array_refs},
curve25519_dalek::{
ristretto::{CompressedRistretto, RistrettoPoint},
@ -87,7 +90,7 @@ impl PubkeySigmaProof {
self,
elgamal_pubkey: &ElGamalPubkey,
transcript: &mut Transcript,
) -> Result<(), PubkeySigmaProofError> {
) -> Result<(), PubkeyValidityProofError> {
transcript.pubkey_proof_domain_sep();
// extract the relvant scalar and Ristretto points from the input
@ -98,7 +101,10 @@ impl PubkeySigmaProof {
let c = transcript.challenge_scalar(b"c");
// check that the required algebraic condition holds
let Y = self.Y.decompress().ok_or(PubkeySigmaProofError::Format)?;
let Y = self
.Y
.decompress()
.ok_or(ProofVerificationError::Deserialization)?;
let check = RistrettoPoint::vartime_multiscalar_mul(
vec![&self.z, &(-&c), &(-&Scalar::one())],
@ -108,7 +114,7 @@ impl PubkeySigmaProof {
if check.is_identity() {
Ok(())
} else {
Err(PubkeySigmaProofError::AlgebraicRelation)
Err(ProofVerificationError::AlgebraicRelation.into())
}
}
@ -119,16 +125,16 @@ impl PubkeySigmaProof {
buf
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self, PubkeySigmaProofError> {
pub fn from_bytes(bytes: &[u8]) -> Result<Self, PubkeyValidityProofError> {
if bytes.len() != 64 {
return Err(PubkeySigmaProofError::Format);
return Err(ProofVerificationError::Deserialization.into());
}
let bytes = array_ref![bytes, 0, 64];
let (Y, z) = array_refs![bytes, 32, 32];
let Y = CompressedRistretto::from_slice(Y);
let z = Scalar::from_canonical_bytes(*z).ok_or(PubkeySigmaProofError::Format)?;
let z = Scalar::from_canonical_bytes(*z).ok_or(ProofVerificationError::Deserialization)?;
Ok(PubkeySigmaProof { Y, z })
}

View File

@ -10,9 +10,12 @@
#[cfg(not(target_os = "solana"))]
use {
crate::encryption::{
elgamal::{DecryptHandle, ElGamalPubkey},
pedersen::{PedersenCommitment, PedersenOpening, G, H},
crate::{
encryption::{
elgamal::{DecryptHandle, ElGamalPubkey},
pedersen::{PedersenCommitment, PedersenOpening, G, H},
},
errors::ProofVerificationError,
},
curve25519_dalek::traits::MultiscalarMul,
rand::rngs::OsRng,
@ -137,9 +140,18 @@ impl ValidityProof {
let ww_negated = -&ww;
// check the required algebraic conditions
let Y_0 = self.Y_0.decompress().ok_or(ValidityProofError::Format)?;
let Y_1 = self.Y_1.decompress().ok_or(ValidityProofError::Format)?;
let Y_2 = self.Y_2.decompress().ok_or(ValidityProofError::Format)?;
let Y_0 = self
.Y_0
.decompress()
.ok_or(ProofVerificationError::Deserialization)?;
let Y_1 = self
.Y_1
.decompress()
.ok_or(ProofVerificationError::Deserialization)?;
let Y_2 = self
.Y_2
.decompress()
.ok_or(ProofVerificationError::Deserialization)?;
let P_dest = destination_pubkey.get_point();
let P_auditor = auditor_pubkey.get_point();
@ -178,7 +190,7 @@ impl ValidityProof {
if check.is_identity() {
Ok(())
} else {
Err(ValidityProofError::AlgebraicRelation)
Err(ProofVerificationError::AlgebraicRelation.into())
}
}
@ -194,7 +206,7 @@ impl ValidityProof {
pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidityProofError> {
if bytes.len() != 160 {
return Err(ValidityProofError::Format);
return Err(ProofVerificationError::Deserialization.into());
}
let bytes = array_ref![bytes, 0, 160];
@ -204,8 +216,10 @@ impl ValidityProof {
let Y_1 = CompressedRistretto::from_slice(Y_1);
let Y_2 = CompressedRistretto::from_slice(Y_2);
let z_r = Scalar::from_canonical_bytes(*z_r).ok_or(ValidityProofError::Format)?;
let z_x = Scalar::from_canonical_bytes(*z_x).ok_or(ValidityProofError::Format)?;
let z_r =
Scalar::from_canonical_bytes(*z_r).ok_or(ProofVerificationError::Deserialization)?;
let z_x =
Scalar::from_canonical_bytes(*z_x).ok_or(ProofVerificationError::Deserialization)?;
Ok(ValidityProof {
Y_0,

View File

@ -9,9 +9,12 @@
#[cfg(not(target_os = "solana"))]
use {
crate::encryption::{
elgamal::{ElGamalCiphertext, ElGamalKeypair, ElGamalPubkey},
pedersen::H,
crate::{
encryption::{
elgamal::{ElGamalCiphertext, ElGamalKeypair, ElGamalPubkey},
pedersen::H,
},
errors::ProofVerificationError,
},
curve25519_dalek::traits::MultiscalarMul,
rand::rngs::OsRng,
@ -117,8 +120,14 @@ impl ZeroBalanceProof {
let w_negated = -&w;
// decompress Y or return verification error
let Y_P = self.Y_P.decompress().ok_or(ZeroBalanceProofError::Format)?;
let Y_D = self.Y_D.decompress().ok_or(ZeroBalanceProofError::Format)?;
let Y_P = self
.Y_P
.decompress()
.ok_or(ProofVerificationError::Deserialization)?;
let Y_D = self
.Y_D
.decompress()
.ok_or(ProofVerificationError::Deserialization)?;
// check the required algebraic relation
let check = RistrettoPoint::multiscalar_mul(
@ -143,7 +152,7 @@ impl ZeroBalanceProof {
if check.is_identity() {
Ok(())
} else {
Err(ZeroBalanceProofError::AlgebraicRelation)
Err(ProofVerificationError::AlgebraicRelation.into())
}
}
@ -157,7 +166,7 @@ impl ZeroBalanceProof {
pub fn from_bytes(bytes: &[u8]) -> Result<Self, ZeroBalanceProofError> {
if bytes.len() != 96 {
return Err(ZeroBalanceProofError::Format);
return Err(ProofVerificationError::Deserialization.into());
}
let bytes = array_ref![bytes, 0, 96];
@ -166,7 +175,7 @@ impl ZeroBalanceProof {
let Y_P = CompressedRistretto::from_slice(Y_P);
let Y_D = CompressedRistretto::from_slice(Y_D);
let z = Scalar::from_canonical_bytes(*z).ok_or(ZeroBalanceProofError::Format)?;
let z = Scalar::from_canonical_bytes(*z).ok_or(ProofVerificationError::Deserialization)?;
Ok(ZeroBalanceProof { Y_P, Y_D, z })
}

View File

@ -57,7 +57,7 @@ mod target_arch {
elgamal::{DecryptHandle, ElGamalCiphertext, ElGamalPubkey},
pedersen::PedersenCommitment,
},
errors::ProofError,
errors::{ProofError, ProofVerificationError},
instruction::{
transfer::{TransferAmountEncryption, TransferPubkeys},
transfer_with_fee::{FeeEncryption, FeeParameters, TransferWithFeePubkeys},
@ -282,7 +282,7 @@ mod target_arch {
}
impl TryFrom<pod::PubkeySigmaProof> for PubkeySigmaProof {
type Error = PubkeySigmaProofError;
type Error = PubkeyValidityProofError;
fn try_from(pod: pod::PubkeySigmaProof) -> Result<Self, Self::Error> {
Self::from_bytes(&pod.0)
@ -294,7 +294,7 @@ mod target_arch {
fn try_from(proof: RangeProof) -> Result<Self, Self::Error> {
if proof.ipp_proof.serialized_size() != 448 {
return Err(RangeProofError::Format);
return Err(ProofVerificationError::Deserialization.into());
}
let mut buf = [0_u8; 672];
@ -324,7 +324,7 @@ mod target_arch {
fn try_from(proof: RangeProof) -> Result<Self, Self::Error> {
if proof.ipp_proof.serialized_size() != 512 {
return Err(RangeProofError::Format);
return Err(ProofVerificationError::Deserialization.into());
}
let mut buf = [0_u8; 736];
@ -354,7 +354,7 @@ mod target_arch {
fn try_from(proof: RangeProof) -> Result<Self, Self::Error> {
if proof.ipp_proof.serialized_size() != 576 {
return Err(RangeProofError::Format);
return Err(ProofVerificationError::Deserialization.into());
}
let mut buf = [0_u8; 800];