[zk-token-sdk] Refactor ciphertext validity sigma proof and rename `ValidityProof` to `GroupedCiphertextValidityProof` (#32040)
* rename `CiphertextValidityProof` to `GroupedCiphertext2HandlesValidityProof` * rename `AggregatedValidityProof` to `BatchedGroupedCiphertext2HandlesValidityProof` * refactor `validity_proof` module into separate modules * update test names * update `aggregated` variable names * update transcript function names * Update zk-token-sdk/src/sigma_proofs/batched_grouped_ciphertext_validity_proof.rs Co-authored-by: Tyera <teulberg@gmail.com> * Update zk-token-sdk/src/sigma_proofs/grouped_ciphertext_validity_proof.rs Co-authored-by: Tyera <teulberg@gmail.com> * Reword constructor docs --------- Co-authored-by: Tyera <teulberg@gmail.com>
This commit is contained in:
parent
57a89a7ec8
commit
84e28c27f3
|
@ -20,7 +20,7 @@ use {
|
||||||
pedersen::PedersenOpening,
|
pedersen::PedersenOpening,
|
||||||
},
|
},
|
||||||
errors::ProofError,
|
errors::ProofError,
|
||||||
sigma_proofs::validity_proof::AggregatedValidityProof,
|
sigma_proofs::batched_grouped_ciphertext_validity_proof::BatchedGroupedCiphertext2HandlesValidityProof,
|
||||||
transcript::TranscriptProtocol,
|
transcript::TranscriptProtocol,
|
||||||
},
|
},
|
||||||
merlin::Transcript,
|
merlin::Transcript,
|
||||||
|
@ -43,7 +43,7 @@ use {
|
||||||
pub struct BatchedGroupedCiphertext2HandlesValidityProofData {
|
pub struct BatchedGroupedCiphertext2HandlesValidityProofData {
|
||||||
pub context: BatchedGroupedCiphertext2HandlesValidityProofContext,
|
pub context: BatchedGroupedCiphertext2HandlesValidityProofContext,
|
||||||
|
|
||||||
pub proof: pod::AggregatedValidityProof,
|
pub proof: pod::BatchedGroupedCiphertext2HandlesValidityProof,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||||
|
@ -84,7 +84,7 @@ impl BatchedGroupedCiphertext2HandlesValidityProofData {
|
||||||
|
|
||||||
let mut transcript = context.new_transcript();
|
let mut transcript = context.new_transcript();
|
||||||
|
|
||||||
let proof = AggregatedValidityProof::new(
|
let proof = BatchedGroupedCiphertext2HandlesValidityProof::new(
|
||||||
(destination_pubkey, auditor_pubkey),
|
(destination_pubkey, auditor_pubkey),
|
||||||
(amount_lo, amount_hi),
|
(amount_lo, amount_hi),
|
||||||
(opening_lo, opening_hi),
|
(opening_lo, opening_hi),
|
||||||
|
@ -122,7 +122,7 @@ impl ZkProofData<BatchedGroupedCiphertext2HandlesValidityProofContext>
|
||||||
let destination_handle_hi = grouped_ciphertext_hi.handles.get(0).unwrap();
|
let destination_handle_hi = grouped_ciphertext_hi.handles.get(0).unwrap();
|
||||||
let auditor_handle_hi = grouped_ciphertext_hi.handles.get(1).unwrap();
|
let auditor_handle_hi = grouped_ciphertext_hi.handles.get(1).unwrap();
|
||||||
|
|
||||||
let proof: AggregatedValidityProof = self.proof.try_into()?;
|
let proof: BatchedGroupedCiphertext2HandlesValidityProof = self.proof.try_into()?;
|
||||||
|
|
||||||
proof
|
proof
|
||||||
.verify(
|
.verify(
|
||||||
|
|
|
@ -18,7 +18,7 @@ use {
|
||||||
pedersen::PedersenOpening,
|
pedersen::PedersenOpening,
|
||||||
},
|
},
|
||||||
errors::ProofError,
|
errors::ProofError,
|
||||||
sigma_proofs::validity_proof::ValidityProof,
|
sigma_proofs::grouped_ciphertext_validity_proof::GroupedCiphertext2HandlesValidityProof,
|
||||||
transcript::TranscriptProtocol,
|
transcript::TranscriptProtocol,
|
||||||
},
|
},
|
||||||
merlin::Transcript,
|
merlin::Transcript,
|
||||||
|
@ -41,7 +41,7 @@ use {
|
||||||
pub struct GroupedCiphertext2HandlesValidityProofData {
|
pub struct GroupedCiphertext2HandlesValidityProofData {
|
||||||
pub context: GroupedCiphertext2HandlesValidityProofContext,
|
pub context: GroupedCiphertext2HandlesValidityProofContext,
|
||||||
|
|
||||||
pub proof: pod::ValidityProof,
|
pub proof: pod::GroupedCiphertext2HandlesValidityProof,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||||
|
@ -75,7 +75,7 @@ impl GroupedCiphertext2HandlesValidityProofData {
|
||||||
|
|
||||||
let mut transcript = context.new_transcript();
|
let mut transcript = context.new_transcript();
|
||||||
|
|
||||||
let proof = ValidityProof::new(
|
let proof = GroupedCiphertext2HandlesValidityProof::new(
|
||||||
(destination_pubkey, auditor_pubkey),
|
(destination_pubkey, auditor_pubkey),
|
||||||
amount,
|
amount,
|
||||||
opening,
|
opening,
|
||||||
|
@ -108,7 +108,7 @@ impl ZkProofData<GroupedCiphertext2HandlesValidityProofContext>
|
||||||
let destination_handle = grouped_ciphertext.handles.get(0).unwrap();
|
let destination_handle = grouped_ciphertext.handles.get(0).unwrap();
|
||||||
let auditor_handle = grouped_ciphertext.handles.get(1).unwrap();
|
let auditor_handle = grouped_ciphertext.handles.get(1).unwrap();
|
||||||
|
|
||||||
let proof: ValidityProof = self.proof.try_into()?;
|
let proof: GroupedCiphertext2HandlesValidityProof = self.proof.try_into()?;
|
||||||
|
|
||||||
proof
|
proof
|
||||||
.verify(
|
.verify(
|
||||||
|
|
|
@ -14,8 +14,9 @@ use {
|
||||||
},
|
},
|
||||||
range_proof::RangeProof,
|
range_proof::RangeProof,
|
||||||
sigma_proofs::{
|
sigma_proofs::{
|
||||||
|
batched_grouped_ciphertext_validity_proof::BatchedGroupedCiphertext2HandlesValidityProof,
|
||||||
ciphertext_commitment_equality_proof::CiphertextCommitmentEqualityProof,
|
ciphertext_commitment_equality_proof::CiphertextCommitmentEqualityProof,
|
||||||
fee_proof::FeeSigmaProof, validity_proof::AggregatedValidityProof,
|
fee_proof::FeeSigmaProof,
|
||||||
},
|
},
|
||||||
transcript::TranscriptProtocol,
|
transcript::TranscriptProtocol,
|
||||||
},
|
},
|
||||||
|
@ -399,9 +400,9 @@ pub struct TransferWithFeeProof {
|
||||||
pub new_source_commitment: pod::PedersenCommitment,
|
pub new_source_commitment: pod::PedersenCommitment,
|
||||||
pub claimed_commitment: pod::PedersenCommitment,
|
pub claimed_commitment: pod::PedersenCommitment,
|
||||||
pub equality_proof: pod::CiphertextCommitmentEqualityProof,
|
pub equality_proof: pod::CiphertextCommitmentEqualityProof,
|
||||||
pub ciphertext_amount_validity_proof: pod::AggregatedValidityProof,
|
pub ciphertext_amount_validity_proof: pod::BatchedGroupedCiphertext2HandlesValidityProof,
|
||||||
pub fee_sigma_proof: pod::FeeSigmaProof,
|
pub fee_sigma_proof: pod::FeeSigmaProof,
|
||||||
pub fee_ciphertext_validity_proof: pod::AggregatedValidityProof,
|
pub fee_ciphertext_validity_proof: pod::BatchedGroupedCiphertext2HandlesValidityProof,
|
||||||
pub range_proof: pod::RangeProofU256,
|
pub range_proof: pod::RangeProofU256,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,7 +444,7 @@ impl TransferWithFeeProof {
|
||||||
);
|
);
|
||||||
|
|
||||||
// generate ciphertext validity proof
|
// generate ciphertext validity proof
|
||||||
let ciphertext_amount_validity_proof = AggregatedValidityProof::new(
|
let ciphertext_amount_validity_proof = BatchedGroupedCiphertext2HandlesValidityProof::new(
|
||||||
(destination_pubkey, auditor_pubkey),
|
(destination_pubkey, auditor_pubkey),
|
||||||
(transfer_amount_lo, transfer_amount_hi),
|
(transfer_amount_lo, transfer_amount_hi),
|
||||||
(opening_lo, opening_hi),
|
(opening_lo, opening_hi),
|
||||||
|
@ -496,7 +497,7 @@ impl TransferWithFeeProof {
|
||||||
);
|
);
|
||||||
|
|
||||||
// generate ciphertext validity proof for fee ciphertexts
|
// generate ciphertext validity proof for fee ciphertexts
|
||||||
let fee_ciphertext_validity_proof = AggregatedValidityProof::new(
|
let fee_ciphertext_validity_proof = BatchedGroupedCiphertext2HandlesValidityProof::new(
|
||||||
(destination_pubkey, withdraw_withheld_authority_pubkey),
|
(destination_pubkey, withdraw_withheld_authority_pubkey),
|
||||||
(fee_amount_lo, fee_amount_hi),
|
(fee_amount_lo, fee_amount_hi),
|
||||||
(opening_fee_lo, opening_fee_hi),
|
(opening_fee_lo, opening_fee_hi),
|
||||||
|
@ -565,10 +566,10 @@ impl TransferWithFeeProof {
|
||||||
let claimed_commitment: PedersenCommitment = self.claimed_commitment.try_into()?;
|
let claimed_commitment: PedersenCommitment = self.claimed_commitment.try_into()?;
|
||||||
|
|
||||||
let equality_proof: CiphertextCommitmentEqualityProof = self.equality_proof.try_into()?;
|
let equality_proof: CiphertextCommitmentEqualityProof = self.equality_proof.try_into()?;
|
||||||
let ciphertext_amount_validity_proof: AggregatedValidityProof =
|
let ciphertext_amount_validity_proof: BatchedGroupedCiphertext2HandlesValidityProof =
|
||||||
self.ciphertext_amount_validity_proof.try_into()?;
|
self.ciphertext_amount_validity_proof.try_into()?;
|
||||||
let fee_sigma_proof: FeeSigmaProof = self.fee_sigma_proof.try_into()?;
|
let fee_sigma_proof: FeeSigmaProof = self.fee_sigma_proof.try_into()?;
|
||||||
let fee_ciphertext_validity_proof: AggregatedValidityProof =
|
let fee_ciphertext_validity_proof: BatchedGroupedCiphertext2HandlesValidityProof =
|
||||||
self.fee_ciphertext_validity_proof.try_into()?;
|
self.fee_ciphertext_validity_proof.try_into()?;
|
||||||
let range_proof: RangeProof = self.range_proof.try_into()?;
|
let range_proof: RangeProof = self.range_proof.try_into()?;
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ use {
|
||||||
},
|
},
|
||||||
range_proof::RangeProof,
|
range_proof::RangeProof,
|
||||||
sigma_proofs::{
|
sigma_proofs::{
|
||||||
|
batched_grouped_ciphertext_validity_proof::BatchedGroupedCiphertext2HandlesValidityProof,
|
||||||
ciphertext_commitment_equality_proof::CiphertextCommitmentEqualityProof,
|
ciphertext_commitment_equality_proof::CiphertextCommitmentEqualityProof,
|
||||||
validity_proof::AggregatedValidityProof,
|
|
||||||
},
|
},
|
||||||
transcript::TranscriptProtocol,
|
transcript::TranscriptProtocol,
|
||||||
},
|
},
|
||||||
|
@ -267,7 +267,7 @@ pub struct TransferProof {
|
||||||
pub equality_proof: pod::CiphertextCommitmentEqualityProof,
|
pub equality_proof: pod::CiphertextCommitmentEqualityProof,
|
||||||
|
|
||||||
/// Associated ciphertext validity proof
|
/// Associated ciphertext validity proof
|
||||||
pub validity_proof: pod::AggregatedValidityProof,
|
pub validity_proof: pod::BatchedGroupedCiphertext2HandlesValidityProof,
|
||||||
|
|
||||||
// Associated range proof
|
// Associated range proof
|
||||||
pub range_proof: pod::RangeProofU128,
|
pub range_proof: pod::RangeProofU128,
|
||||||
|
@ -301,7 +301,7 @@ impl TransferProof {
|
||||||
);
|
);
|
||||||
|
|
||||||
// generate ciphertext validity proof
|
// generate ciphertext validity proof
|
||||||
let validity_proof = AggregatedValidityProof::new(
|
let validity_proof = BatchedGroupedCiphertext2HandlesValidityProof::new(
|
||||||
(destination_pubkey, auditor_pubkey),
|
(destination_pubkey, auditor_pubkey),
|
||||||
(transfer_amount_lo, transfer_amount_hi),
|
(transfer_amount_lo, transfer_amount_hi),
|
||||||
(opening_lo, opening_hi),
|
(opening_lo, opening_hi),
|
||||||
|
@ -363,7 +363,8 @@ impl TransferProof {
|
||||||
|
|
||||||
let commitment: PedersenCommitment = self.new_source_commitment.try_into()?;
|
let commitment: PedersenCommitment = self.new_source_commitment.try_into()?;
|
||||||
let equality_proof: CiphertextCommitmentEqualityProof = self.equality_proof.try_into()?;
|
let equality_proof: CiphertextCommitmentEqualityProof = self.equality_proof.try_into()?;
|
||||||
let aggregated_validity_proof: AggregatedValidityProof = self.validity_proof.try_into()?;
|
let aggregated_validity_proof: BatchedGroupedCiphertext2HandlesValidityProof =
|
||||||
|
self.validity_proof.try_into()?;
|
||||||
let range_proof: RangeProof = self.range_proof.try_into()?;
|
let range_proof: RangeProof = self.range_proof.try_into()?;
|
||||||
|
|
||||||
// verify equality proof
|
// verify equality proof
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
//! The ciphertext validity sigma proof system.
|
||||||
|
//!
|
||||||
|
//! The ciphertext validity proof is defined with respect to a Pedersen commitment and two
|
||||||
|
//! decryption handles. The proof certifies that a given Pedersen commitment can be decrypted using
|
||||||
|
//! ElGamal private keys that are associated with each of the two decryption handles. To generate
|
||||||
|
//! the proof, a prover must provide the Pedersen opening associated with the commitment.
|
||||||
|
//!
|
||||||
|
//! The protocol guarantees computational soundness (by the hardness of discrete log) and perfect
|
||||||
|
//! zero-knowledge in the random oracle model.
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "solana"))]
|
||||||
|
use crate::encryption::{
|
||||||
|
elgamal::{DecryptHandle, ElGamalPubkey},
|
||||||
|
pedersen::{PedersenCommitment, PedersenOpening},
|
||||||
|
};
|
||||||
|
use {
|
||||||
|
crate::{
|
||||||
|
sigma_proofs::{
|
||||||
|
errors::ValidityProofError,
|
||||||
|
grouped_ciphertext_validity_proof::GroupedCiphertext2HandlesValidityProof,
|
||||||
|
},
|
||||||
|
transcript::TranscriptProtocol,
|
||||||
|
},
|
||||||
|
curve25519_dalek::scalar::Scalar,
|
||||||
|
merlin::Transcript,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Batched grouped ciphertext validity proof with two handles.
|
||||||
|
///
|
||||||
|
/// A batched grouped ciphertext validity proof certifies the validity of two instances of a
|
||||||
|
/// standard ciphertext validity proof. An instance of a standard validity proof consists of one
|
||||||
|
/// ciphertext and two decryption handles: `(commitment, destination_handle, auditor_handle)`. An
|
||||||
|
/// instance of a batched ciphertext validity proof is a pair `(commitment_0,
|
||||||
|
/// destination_handle_0, auditor_handle_0)` and `(commitment_1, destination_handle_1,
|
||||||
|
/// auditor_handle_1)`. The proof certifies the analogous decryptable properties for each one of
|
||||||
|
/// these pairs of commitment and decryption handles.
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct BatchedGroupedCiphertext2HandlesValidityProof(GroupedCiphertext2HandlesValidityProof);
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[cfg(not(target_os = "solana"))]
|
||||||
|
impl BatchedGroupedCiphertext2HandlesValidityProof {
|
||||||
|
/// Batched grouped ciphertext validity proof constructor.
|
||||||
|
///
|
||||||
|
/// The function simply batches the input openings and invokes the standard grouped ciphertext
|
||||||
|
/// validity proof constructor.
|
||||||
|
pub fn new<T: Into<Scalar>>(
|
||||||
|
(destination_pubkey, auditor_pubkey): (&ElGamalPubkey, &ElGamalPubkey),
|
||||||
|
(amount_lo, amount_hi): (T, T),
|
||||||
|
(opening_lo, opening_hi): (&PedersenOpening, &PedersenOpening),
|
||||||
|
transcript: &mut Transcript,
|
||||||
|
) -> Self {
|
||||||
|
transcript.batched_grouped_ciphertext_validity_proof_domain_sep();
|
||||||
|
|
||||||
|
let t = transcript.challenge_scalar(b"t");
|
||||||
|
|
||||||
|
let batched_message = amount_lo.into() + amount_hi.into() * t;
|
||||||
|
let batched_opening = opening_lo + &(opening_hi * &t);
|
||||||
|
|
||||||
|
BatchedGroupedCiphertext2HandlesValidityProof(GroupedCiphertext2HandlesValidityProof::new(
|
||||||
|
(destination_pubkey, auditor_pubkey),
|
||||||
|
batched_message,
|
||||||
|
&batched_opening,
|
||||||
|
transcript,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Batched grouped ciphertext validity proof verifier.
|
||||||
|
///
|
||||||
|
/// The function does *not* hash the public keys, commitment, or decryption handles into the
|
||||||
|
/// transcript. For security, the caller (the main protocol) should hash these public
|
||||||
|
/// components prior to invoking this constructor.
|
||||||
|
///
|
||||||
|
/// This function is randomized. It uses `OsRng` internally to generate random scalars.
|
||||||
|
pub fn verify(
|
||||||
|
self,
|
||||||
|
(destination_pubkey, auditor_pubkey): (&ElGamalPubkey, &ElGamalPubkey),
|
||||||
|
(commitment_lo, commitment_hi): (&PedersenCommitment, &PedersenCommitment),
|
||||||
|
(destination_handle_lo, destination_handle_hi): (&DecryptHandle, &DecryptHandle),
|
||||||
|
(auditor_handle_lo, auditor_handle_hi): (&DecryptHandle, &DecryptHandle),
|
||||||
|
transcript: &mut Transcript,
|
||||||
|
) -> Result<(), ValidityProofError> {
|
||||||
|
transcript.batched_grouped_ciphertext_validity_proof_domain_sep();
|
||||||
|
|
||||||
|
let t = transcript.challenge_scalar(b"t");
|
||||||
|
|
||||||
|
let batched_commitment = commitment_lo + commitment_hi * t;
|
||||||
|
let destination_batched_handle = destination_handle_lo + destination_handle_hi * t;
|
||||||
|
let auditor_batched_handle = auditor_handle_lo + auditor_handle_hi * t;
|
||||||
|
|
||||||
|
let BatchedGroupedCiphertext2HandlesValidityProof(validity_proof) = self;
|
||||||
|
|
||||||
|
validity_proof.verify(
|
||||||
|
&batched_commitment,
|
||||||
|
(destination_pubkey, auditor_pubkey),
|
||||||
|
(&destination_batched_handle, &auditor_batched_handle),
|
||||||
|
transcript,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_bytes(&self) -> [u8; 160] {
|
||||||
|
self.0.to_bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidityProofError> {
|
||||||
|
GroupedCiphertext2HandlesValidityProof::from_bytes(bytes).map(Self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use {
|
||||||
|
super::*,
|
||||||
|
crate::encryption::{elgamal::ElGamalKeypair, pedersen::Pedersen},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_batched_grouped_ciphertext_validity_proof() {
|
||||||
|
let destination_pubkey = ElGamalKeypair::new_rand().public;
|
||||||
|
let auditor_pubkey = ElGamalKeypair::new_rand().public;
|
||||||
|
|
||||||
|
let amount_lo: u64 = 55;
|
||||||
|
let amount_hi: u64 = 77;
|
||||||
|
|
||||||
|
let (commitment_lo, open_lo) = Pedersen::new(amount_lo);
|
||||||
|
let (commitment_hi, open_hi) = Pedersen::new(amount_hi);
|
||||||
|
|
||||||
|
let destination_handle_lo = destination_pubkey.decrypt_handle(&open_lo);
|
||||||
|
let destination_handle_hi = destination_pubkey.decrypt_handle(&open_hi);
|
||||||
|
|
||||||
|
let auditor_handle_lo = auditor_pubkey.decrypt_handle(&open_lo);
|
||||||
|
let auditor_handle_hi = auditor_pubkey.decrypt_handle(&open_hi);
|
||||||
|
|
||||||
|
let mut prover_transcript = Transcript::new(b"Test");
|
||||||
|
let mut verifier_transcript = Transcript::new(b"Test");
|
||||||
|
|
||||||
|
let proof = BatchedGroupedCiphertext2HandlesValidityProof::new(
|
||||||
|
(&destination_pubkey, &auditor_pubkey),
|
||||||
|
(amount_lo, amount_hi),
|
||||||
|
(&open_lo, &open_hi),
|
||||||
|
&mut prover_transcript,
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(proof
|
||||||
|
.verify(
|
||||||
|
(&destination_pubkey, &auditor_pubkey),
|
||||||
|
(&commitment_lo, &commitment_hi),
|
||||||
|
(&destination_handle_lo, &destination_handle_hi),
|
||||||
|
(&auditor_handle_lo, &auditor_handle_hi),
|
||||||
|
&mut verifier_transcript,
|
||||||
|
)
|
||||||
|
.is_ok());
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,12 +32,12 @@ use {
|
||||||
merlin::Transcript,
|
merlin::Transcript,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The ciphertext validity proof.
|
/// The grouped ciphertext validity proof for 2 handles.
|
||||||
///
|
///
|
||||||
/// Contains all the elliptic curve and scalar components that make up the sigma protocol.
|
/// Contains all the elliptic curve and scalar components that make up the sigma protocol.
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ValidityProof {
|
pub struct GroupedCiphertext2HandlesValidityProof {
|
||||||
Y_0: CompressedRistretto,
|
Y_0: CompressedRistretto,
|
||||||
Y_1: CompressedRistretto,
|
Y_1: CompressedRistretto,
|
||||||
Y_2: CompressedRistretto,
|
Y_2: CompressedRistretto,
|
||||||
|
@ -47,8 +47,8 @@ pub struct ValidityProof {
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[cfg(not(target_os = "solana"))]
|
#[cfg(not(target_os = "solana"))]
|
||||||
impl ValidityProof {
|
impl GroupedCiphertext2HandlesValidityProof {
|
||||||
/// The ciphertext validity proof constructor.
|
/// Creates a grouped ciphertext validity proof for 2 handles.
|
||||||
///
|
///
|
||||||
/// The function does *not* hash the public keys, commitment, or decryption handles into the
|
/// The function does *not* hash the public keys, commitment, or decryption handles into the
|
||||||
/// transcript. For security, the caller (the main protocol) should hash these public
|
/// transcript. For security, the caller (the main protocol) should hash these public
|
||||||
|
@ -70,7 +70,7 @@ impl ValidityProof {
|
||||||
opening: &PedersenOpening,
|
opening: &PedersenOpening,
|
||||||
transcript: &mut Transcript,
|
transcript: &mut Transcript,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
transcript.validity_proof_domain_sep();
|
transcript.grouped_ciphertext_validity_proof_domain_sep();
|
||||||
|
|
||||||
// extract the relevant scalar and Ristretto points from the inputs
|
// extract the relevant scalar and Ristretto points from the inputs
|
||||||
let P_dest = destination_pubkey.get_point();
|
let P_dest = destination_pubkey.get_point();
|
||||||
|
@ -111,7 +111,7 @@ impl ValidityProof {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The ciphertext validity proof verifier.
|
/// Verifies a grouped ciphertext validity proof for 2 handles.
|
||||||
///
|
///
|
||||||
/// * `commitment` - The Pedersen commitment
|
/// * `commitment` - The Pedersen commitment
|
||||||
/// * `(destination_pubkey, auditor_pubkey)` - The ElGamal pubkeys associated with the decryption
|
/// * `(destination_pubkey, auditor_pubkey)` - The ElGamal pubkeys associated with the decryption
|
||||||
|
@ -125,7 +125,7 @@ impl ValidityProof {
|
||||||
(destination_handle, auditor_handle): (&DecryptHandle, &DecryptHandle),
|
(destination_handle, auditor_handle): (&DecryptHandle, &DecryptHandle),
|
||||||
transcript: &mut Transcript,
|
transcript: &mut Transcript,
|
||||||
) -> Result<(), ValidityProofError> {
|
) -> Result<(), ValidityProofError> {
|
||||||
transcript.validity_proof_domain_sep();
|
transcript.grouped_ciphertext_validity_proof_domain_sep();
|
||||||
|
|
||||||
// include Y_0, Y_1, Y_2 to transcript and extract challenges
|
// include Y_0, Y_1, Y_2 to transcript and extract challenges
|
||||||
transcript.validate_and_append_point(b"Y_0", &self.Y_0)?;
|
transcript.validate_and_append_point(b"Y_0", &self.Y_0)?;
|
||||||
|
@ -221,7 +221,7 @@ impl ValidityProof {
|
||||||
let z_x =
|
let z_x =
|
||||||
Scalar::from_canonical_bytes(*z_x).ok_or(ProofVerificationError::Deserialization)?;
|
Scalar::from_canonical_bytes(*z_x).ok_or(ProofVerificationError::Deserialization)?;
|
||||||
|
|
||||||
Ok(ValidityProof {
|
Ok(GroupedCiphertext2HandlesValidityProof {
|
||||||
Y_0,
|
Y_0,
|
||||||
Y_1,
|
Y_1,
|
||||||
Y_2,
|
Y_2,
|
||||||
|
@ -231,89 +231,6 @@ impl ValidityProof {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Aggregated ciphertext validity proof.
|
|
||||||
///
|
|
||||||
/// An aggregated ciphertext validity proof certifies the validity of two instances of a standard
|
|
||||||
/// ciphertext validity proof. An instance of a standard validity proof consist of one ciphertext
|
|
||||||
/// and two decryption handles `(commitment, destination_handle, auditor_handle)`. An instance of an
|
|
||||||
/// aggregated ciphertext validity proof is a pair `(commitment_0, destination_handle_0,
|
|
||||||
/// auditor_handle_0)` and `(commitment_1, destination_handle_1, auditor_handle_1)`. The proof certifies
|
|
||||||
/// the analogous decryptable properties for each one of these pair of commitment and decryption
|
|
||||||
/// handles.
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct AggregatedValidityProof(ValidityProof);
|
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
#[cfg(not(target_os = "solana"))]
|
|
||||||
impl AggregatedValidityProof {
|
|
||||||
/// Aggregated ciphertext validity proof constructor.
|
|
||||||
///
|
|
||||||
/// The function simples aggregates the input openings and invokes the standard ciphertext
|
|
||||||
/// validity proof constructor.
|
|
||||||
pub fn new<T: Into<Scalar>>(
|
|
||||||
(destination_pubkey, auditor_pubkey): (&ElGamalPubkey, &ElGamalPubkey),
|
|
||||||
(amount_lo, amount_hi): (T, T),
|
|
||||||
(opening_lo, opening_hi): (&PedersenOpening, &PedersenOpening),
|
|
||||||
transcript: &mut Transcript,
|
|
||||||
) -> Self {
|
|
||||||
transcript.aggregated_validity_proof_domain_sep();
|
|
||||||
|
|
||||||
let t = transcript.challenge_scalar(b"t");
|
|
||||||
|
|
||||||
let aggregated_message = amount_lo.into() + amount_hi.into() * t;
|
|
||||||
let aggregated_opening = opening_lo + &(opening_hi * &t);
|
|
||||||
|
|
||||||
AggregatedValidityProof(ValidityProof::new(
|
|
||||||
(destination_pubkey, auditor_pubkey),
|
|
||||||
aggregated_message,
|
|
||||||
&aggregated_opening,
|
|
||||||
transcript,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Aggregated ciphertext validity proof verifier.
|
|
||||||
///
|
|
||||||
/// The function does *not* hash the public keys, commitment, or decryption handles into the
|
|
||||||
/// transcript. For security, the caller (the main protocol) should hash these public
|
|
||||||
/// components prior to invoking this constructor.
|
|
||||||
///
|
|
||||||
/// This function is randomized. It uses `OsRng` internally to generate random scalars.
|
|
||||||
pub fn verify(
|
|
||||||
self,
|
|
||||||
(destination_pubkey, auditor_pubkey): (&ElGamalPubkey, &ElGamalPubkey),
|
|
||||||
(commitment_lo, commitment_hi): (&PedersenCommitment, &PedersenCommitment),
|
|
||||||
(destination_handle_lo, destination_handle_hi): (&DecryptHandle, &DecryptHandle),
|
|
||||||
(auditor_handle_lo, auditor_handle_hi): (&DecryptHandle, &DecryptHandle),
|
|
||||||
transcript: &mut Transcript,
|
|
||||||
) -> Result<(), ValidityProofError> {
|
|
||||||
transcript.aggregated_validity_proof_domain_sep();
|
|
||||||
|
|
||||||
let t = transcript.challenge_scalar(b"t");
|
|
||||||
|
|
||||||
let aggregated_commitment = commitment_lo + commitment_hi * t;
|
|
||||||
let destination_aggregated_handle = destination_handle_lo + destination_handle_hi * t;
|
|
||||||
let auditor_aggregated_handle = auditor_handle_lo + auditor_handle_hi * t;
|
|
||||||
|
|
||||||
let AggregatedValidityProof(validity_proof) = self;
|
|
||||||
|
|
||||||
validity_proof.verify(
|
|
||||||
&aggregated_commitment,
|
|
||||||
(destination_pubkey, auditor_pubkey),
|
|
||||||
(&destination_aggregated_handle, &auditor_aggregated_handle),
|
|
||||||
transcript,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_bytes(&self) -> [u8; 160] {
|
|
||||||
self.0.to_bytes()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidityProofError> {
|
|
||||||
ValidityProof::from_bytes(bytes).map(Self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use {
|
use {
|
||||||
|
@ -322,7 +239,7 @@ mod test {
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_validity_proof_correctness() {
|
fn test_grouped_ciphertext_validity_proof_correctness() {
|
||||||
let destination_pubkey = ElGamalKeypair::new_rand().public;
|
let destination_pubkey = ElGamalKeypair::new_rand().public;
|
||||||
let auditor_pubkey = ElGamalKeypair::new_rand().public;
|
let auditor_pubkey = ElGamalKeypair::new_rand().public;
|
||||||
|
|
||||||
|
@ -335,7 +252,7 @@ mod test {
|
||||||
let mut prover_transcript = Transcript::new(b"Test");
|
let mut prover_transcript = Transcript::new(b"Test");
|
||||||
let mut verifier_transcript = Transcript::new(b"Test");
|
let mut verifier_transcript = Transcript::new(b"Test");
|
||||||
|
|
||||||
let proof = ValidityProof::new(
|
let proof = GroupedCiphertext2HandlesValidityProof::new(
|
||||||
(&destination_pubkey, &auditor_pubkey),
|
(&destination_pubkey, &auditor_pubkey),
|
||||||
amount,
|
amount,
|
||||||
&opening,
|
&opening,
|
||||||
|
@ -353,7 +270,7 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_validity_proof_edge_cases() {
|
fn test_grouped_ciphertext_validity_proof_edge_cases() {
|
||||||
// if destination public key zeroed, then the proof should always reject
|
// if destination public key zeroed, then the proof should always reject
|
||||||
let destination_pubkey = ElGamalPubkey::from_bytes(&[0u8; 32]).unwrap();
|
let destination_pubkey = ElGamalPubkey::from_bytes(&[0u8; 32]).unwrap();
|
||||||
let auditor_pubkey = ElGamalKeypair::new_rand().public;
|
let auditor_pubkey = ElGamalKeypair::new_rand().public;
|
||||||
|
@ -367,7 +284,7 @@ mod test {
|
||||||
let mut prover_transcript = Transcript::new(b"Test");
|
let mut prover_transcript = Transcript::new(b"Test");
|
||||||
let mut verifier_transcript = Transcript::new(b"Test");
|
let mut verifier_transcript = Transcript::new(b"Test");
|
||||||
|
|
||||||
let proof = ValidityProof::new(
|
let proof = GroupedCiphertext2HandlesValidityProof::new(
|
||||||
(&destination_pubkey, &auditor_pubkey),
|
(&destination_pubkey, &auditor_pubkey),
|
||||||
amount,
|
amount,
|
||||||
&opening,
|
&opening,
|
||||||
|
@ -396,7 +313,7 @@ mod test {
|
||||||
let mut prover_transcript = Transcript::new(b"Test");
|
let mut prover_transcript = Transcript::new(b"Test");
|
||||||
let mut verifier_transcript = Transcript::new(b"Test");
|
let mut verifier_transcript = Transcript::new(b"Test");
|
||||||
|
|
||||||
let proof = ValidityProof::new(
|
let proof = GroupedCiphertext2HandlesValidityProof::new(
|
||||||
(&destination_pubkey, &auditor_pubkey),
|
(&destination_pubkey, &auditor_pubkey),
|
||||||
amount,
|
amount,
|
||||||
&opening,
|
&opening,
|
||||||
|
@ -426,7 +343,7 @@ mod test {
|
||||||
let mut prover_transcript = Transcript::new(b"Test");
|
let mut prover_transcript = Transcript::new(b"Test");
|
||||||
let mut verifier_transcript = Transcript::new(b"Test");
|
let mut verifier_transcript = Transcript::new(b"Test");
|
||||||
|
|
||||||
let proof = ValidityProof::new(
|
let proof = GroupedCiphertext2HandlesValidityProof::new(
|
||||||
(&destination_pubkey, &auditor_pubkey),
|
(&destination_pubkey, &auditor_pubkey),
|
||||||
amount,
|
amount,
|
||||||
&opening,
|
&opening,
|
||||||
|
@ -455,7 +372,7 @@ mod test {
|
||||||
let mut prover_transcript = Transcript::new(b"Test");
|
let mut prover_transcript = Transcript::new(b"Test");
|
||||||
let mut verifier_transcript = Transcript::new(b"Test");
|
let mut verifier_transcript = Transcript::new(b"Test");
|
||||||
|
|
||||||
let proof = ValidityProof::new(
|
let proof = GroupedCiphertext2HandlesValidityProof::new(
|
||||||
(&destination_pubkey, &auditor_pubkey),
|
(&destination_pubkey, &auditor_pubkey),
|
||||||
amount,
|
amount,
|
||||||
&opening,
|
&opening,
|
||||||
|
@ -471,42 +388,4 @@ mod test {
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_aggregated_validity_proof() {
|
|
||||||
let destination_pubkey = ElGamalKeypair::new_rand().public;
|
|
||||||
let auditor_pubkey = ElGamalKeypair::new_rand().public;
|
|
||||||
|
|
||||||
let amount_lo: u64 = 55;
|
|
||||||
let amount_hi: u64 = 77;
|
|
||||||
|
|
||||||
let (commitment_lo, open_lo) = Pedersen::new(amount_lo);
|
|
||||||
let (commitment_hi, open_hi) = Pedersen::new(amount_hi);
|
|
||||||
|
|
||||||
let destination_handle_lo = destination_pubkey.decrypt_handle(&open_lo);
|
|
||||||
let destination_handle_hi = destination_pubkey.decrypt_handle(&open_hi);
|
|
||||||
|
|
||||||
let auditor_handle_lo = auditor_pubkey.decrypt_handle(&open_lo);
|
|
||||||
let auditor_handle_hi = auditor_pubkey.decrypt_handle(&open_hi);
|
|
||||||
|
|
||||||
let mut prover_transcript = Transcript::new(b"Test");
|
|
||||||
let mut verifier_transcript = Transcript::new(b"Test");
|
|
||||||
|
|
||||||
let proof = AggregatedValidityProof::new(
|
|
||||||
(&destination_pubkey, &auditor_pubkey),
|
|
||||||
(amount_lo, amount_hi),
|
|
||||||
(&open_lo, &open_hi),
|
|
||||||
&mut prover_transcript,
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(proof
|
|
||||||
.verify(
|
|
||||||
(&destination_pubkey, &auditor_pubkey),
|
|
||||||
(&commitment_lo, &commitment_hi),
|
|
||||||
(&destination_handle_lo, &destination_handle_hi),
|
|
||||||
(&auditor_handle_lo, &auditor_handle_hi),
|
|
||||||
&mut verifier_transcript,
|
|
||||||
)
|
|
||||||
.is_ok());
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -15,10 +15,11 @@
|
||||||
//! We refer to the zk-token paper for the formal details and security proofs of these argument
|
//! We refer to the zk-token paper for the formal details and security proofs of these argument
|
||||||
//! systems.
|
//! systems.
|
||||||
|
|
||||||
|
pub mod batched_grouped_ciphertext_validity_proof;
|
||||||
pub mod ciphertext_ciphertext_equality_proof;
|
pub mod ciphertext_ciphertext_equality_proof;
|
||||||
pub mod ciphertext_commitment_equality_proof;
|
pub mod ciphertext_commitment_equality_proof;
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
pub mod fee_proof;
|
pub mod fee_proof;
|
||||||
|
pub mod grouped_ciphertext_validity_proof;
|
||||||
pub mod pubkey_proof;
|
pub mod pubkey_proof;
|
||||||
pub mod validity_proof;
|
|
||||||
pub mod zero_balance_proof;
|
pub mod zero_balance_proof;
|
||||||
|
|
|
@ -56,11 +56,11 @@ pub trait TranscriptProtocol {
|
||||||
/// Append a domain separator for zero-balance proof.
|
/// Append a domain separator for zero-balance proof.
|
||||||
fn zero_balance_proof_domain_sep(&mut self);
|
fn zero_balance_proof_domain_sep(&mut self);
|
||||||
|
|
||||||
/// Append a domain separator for validity proof.
|
/// Append a domain separator for grouped ciphertext validity proof.
|
||||||
fn validity_proof_domain_sep(&mut self);
|
fn grouped_ciphertext_validity_proof_domain_sep(&mut self);
|
||||||
|
|
||||||
/// Append a domain separator for aggregated validity proof.
|
/// Append a domain separator for batched grouped ciphertext validity proof.
|
||||||
fn aggregated_validity_proof_domain_sep(&mut self);
|
fn batched_grouped_ciphertext_validity_proof_domain_sep(&mut self);
|
||||||
|
|
||||||
/// Append a domain separator for fee sigma proof.
|
/// Append a domain separator for fee sigma proof.
|
||||||
fn fee_sigma_proof_domain_sep(&mut self);
|
fn fee_sigma_proof_domain_sep(&mut self);
|
||||||
|
@ -168,12 +168,12 @@ impl TranscriptProtocol for Transcript {
|
||||||
self.append_message(b"dom-sep", b"zero-balance-proof")
|
self.append_message(b"dom-sep", b"zero-balance-proof")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validity_proof_domain_sep(&mut self) {
|
fn grouped_ciphertext_validity_proof_domain_sep(&mut self) {
|
||||||
self.append_message(b"dom-sep", b"validity-proof")
|
self.append_message(b"dom-sep", b"validity-proof")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn aggregated_validity_proof_domain_sep(&mut self) {
|
fn batched_grouped_ciphertext_validity_proof_domain_sep(&mut self) {
|
||||||
self.append_message(b"dom-sep", b"aggregated-validity-proof")
|
self.append_message(b"dom-sep", b"batched-validity-proof")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fee_sigma_proof_domain_sep(&mut self) {
|
fn fee_sigma_proof_domain_sep(&mut self) {
|
||||||
|
|
|
@ -23,9 +23,9 @@ pub use {
|
||||||
pedersen::PedersenCommitment,
|
pedersen::PedersenCommitment,
|
||||||
range_proof::{RangeProofU128, RangeProofU256, RangeProofU64},
|
range_proof::{RangeProofU128, RangeProofU256, RangeProofU64},
|
||||||
sigma_proofs::{
|
sigma_proofs::{
|
||||||
AggregatedValidityProof, CiphertextCiphertextEqualityProof,
|
BatchedGroupedCiphertext2HandlesValidityProof, CiphertextCiphertextEqualityProof,
|
||||||
CiphertextCommitmentEqualityProof, FeeSigmaProof, PubkeyValidityProof, ValidityProof,
|
CiphertextCommitmentEqualityProof, FeeSigmaProof, GroupedCiphertext2HandlesValidityProof,
|
||||||
ZeroBalanceProof,
|
PubkeyValidityProof, ZeroBalanceProof,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,12 @@
|
||||||
|
|
||||||
#[cfg(not(target_os = "solana"))]
|
#[cfg(not(target_os = "solana"))]
|
||||||
use crate::sigma_proofs::{
|
use crate::sigma_proofs::{
|
||||||
|
batched_grouped_ciphertext_validity_proof::BatchedGroupedCiphertext2HandlesValidityProof as DecodedBatchedGroupedCiphertext2HandlesValidityProof,
|
||||||
ciphertext_ciphertext_equality_proof::CiphertextCiphertextEqualityProof as DecodedCiphertextCiphertextEqualityProof,
|
ciphertext_ciphertext_equality_proof::CiphertextCiphertextEqualityProof as DecodedCiphertextCiphertextEqualityProof,
|
||||||
ciphertext_commitment_equality_proof::CiphertextCommitmentEqualityProof as DecodedCiphertextCommitmentEqualityProof,
|
ciphertext_commitment_equality_proof::CiphertextCommitmentEqualityProof as DecodedCiphertextCommitmentEqualityProof,
|
||||||
errors::*,
|
errors::*, fee_proof::FeeSigmaProof as DecodedFeeSigmaProof,
|
||||||
fee_proof::FeeSigmaProof as DecodedFeeSigmaProof,
|
grouped_ciphertext_validity_proof::GroupedCiphertext2HandlesValidityProof as DecodedGroupedCiphertext2HandlesValidityProof,
|
||||||
pubkey_proof::PubkeyValidityProof as DecodedPubkeyValidityProof,
|
pubkey_proof::PubkeyValidityProof as DecodedPubkeyValidityProof,
|
||||||
validity_proof::{
|
|
||||||
AggregatedValidityProof as DecodedAggregatedValidityProof,
|
|
||||||
ValidityProof as DecodedValidityProof,
|
|
||||||
},
|
|
||||||
zero_balance_proof::ZeroBalanceProof as DecodedZeroBalanceProof,
|
zero_balance_proof::ZeroBalanceProof as DecodedZeroBalanceProof,
|
||||||
};
|
};
|
||||||
use crate::zk_token_elgamal::pod::{Pod, Zeroable};
|
use crate::zk_token_elgamal::pod::{Pod, Zeroable};
|
||||||
|
@ -57,44 +54,54 @@ impl TryFrom<CiphertextCiphertextEqualityProof> for DecodedCiphertextCiphertextE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `ValidityProof` type as a `Pod`.
|
/// The `GroupedCiphertext2HandlesValidityProof` type as a `Pod`.
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct ValidityProof(pub [u8; 160]);
|
pub struct GroupedCiphertext2HandlesValidityProof(pub [u8; 160]);
|
||||||
|
|
||||||
#[cfg(not(target_os = "solana"))]
|
#[cfg(not(target_os = "solana"))]
|
||||||
impl From<DecodedValidityProof> for ValidityProof {
|
impl From<DecodedGroupedCiphertext2HandlesValidityProof>
|
||||||
fn from(decoded_proof: DecodedValidityProof) -> Self {
|
for GroupedCiphertext2HandlesValidityProof
|
||||||
|
{
|
||||||
|
fn from(decoded_proof: DecodedGroupedCiphertext2HandlesValidityProof) -> Self {
|
||||||
Self(decoded_proof.to_bytes())
|
Self(decoded_proof.to_bytes())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "solana"))]
|
#[cfg(not(target_os = "solana"))]
|
||||||
impl TryFrom<ValidityProof> for DecodedValidityProof {
|
impl TryFrom<GroupedCiphertext2HandlesValidityProof>
|
||||||
|
for DecodedGroupedCiphertext2HandlesValidityProof
|
||||||
|
{
|
||||||
type Error = ValidityProofError;
|
type Error = ValidityProofError;
|
||||||
|
|
||||||
fn try_from(pod_proof: ValidityProof) -> Result<Self, Self::Error> {
|
fn try_from(pod_proof: GroupedCiphertext2HandlesValidityProof) -> Result<Self, Self::Error> {
|
||||||
Self::from_bytes(&pod_proof.0)
|
Self::from_bytes(&pod_proof.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `AggregatedValidityProof` type as a `Pod`.
|
/// The `BatchedGroupedCiphertext2HandlesValidityProof` type as a `Pod`.
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct AggregatedValidityProof(pub [u8; 160]);
|
pub struct BatchedGroupedCiphertext2HandlesValidityProof(pub [u8; 160]);
|
||||||
|
|
||||||
#[cfg(not(target_os = "solana"))]
|
#[cfg(not(target_os = "solana"))]
|
||||||
impl From<DecodedAggregatedValidityProof> for AggregatedValidityProof {
|
impl From<DecodedBatchedGroupedCiphertext2HandlesValidityProof>
|
||||||
fn from(decoded_proof: DecodedAggregatedValidityProof) -> Self {
|
for BatchedGroupedCiphertext2HandlesValidityProof
|
||||||
|
{
|
||||||
|
fn from(decoded_proof: DecodedBatchedGroupedCiphertext2HandlesValidityProof) -> Self {
|
||||||
Self(decoded_proof.to_bytes())
|
Self(decoded_proof.to_bytes())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "solana"))]
|
#[cfg(not(target_os = "solana"))]
|
||||||
impl TryFrom<AggregatedValidityProof> for DecodedAggregatedValidityProof {
|
impl TryFrom<BatchedGroupedCiphertext2HandlesValidityProof>
|
||||||
|
for DecodedBatchedGroupedCiphertext2HandlesValidityProof
|
||||||
|
{
|
||||||
type Error = ValidityProofError;
|
type Error = ValidityProofError;
|
||||||
|
|
||||||
fn try_from(pod_proof: AggregatedValidityProof) -> Result<Self, Self::Error> {
|
fn try_from(
|
||||||
|
pod_proof: BatchedGroupedCiphertext2HandlesValidityProof,
|
||||||
|
) -> Result<Self, Self::Error> {
|
||||||
Self::from_bytes(&pod_proof.0)
|
Self::from_bytes(&pod_proof.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,11 +178,11 @@ unsafe impl Pod for CiphertextCommitmentEqualityProof {}
|
||||||
unsafe impl Zeroable for CiphertextCiphertextEqualityProof {}
|
unsafe impl Zeroable for CiphertextCiphertextEqualityProof {}
|
||||||
unsafe impl Pod for CiphertextCiphertextEqualityProof {}
|
unsafe impl Pod for CiphertextCiphertextEqualityProof {}
|
||||||
|
|
||||||
unsafe impl Zeroable for ValidityProof {}
|
unsafe impl Zeroable for GroupedCiphertext2HandlesValidityProof {}
|
||||||
unsafe impl Pod for ValidityProof {}
|
unsafe impl Pod for GroupedCiphertext2HandlesValidityProof {}
|
||||||
|
|
||||||
unsafe impl Zeroable for AggregatedValidityProof {}
|
unsafe impl Zeroable for BatchedGroupedCiphertext2HandlesValidityProof {}
|
||||||
unsafe impl Pod for AggregatedValidityProof {}
|
unsafe impl Pod for BatchedGroupedCiphertext2HandlesValidityProof {}
|
||||||
|
|
||||||
unsafe impl Zeroable for ZeroBalanceProof {}
|
unsafe impl Zeroable for ZeroBalanceProof {}
|
||||||
unsafe impl Pod for ZeroBalanceProof {}
|
unsafe impl Pod for ZeroBalanceProof {}
|
||||||
|
|
Loading…
Reference in New Issue