[zk-token-sdk] Generate proof transcript directly from proof contexts (#31725)
* generate transcript directly from proof contexts * Update zk-token-sdk/src/instruction/transfer.rs Co-authored-by: Jon Cinque <joncinque@pm.me> * Update zk-token-sdk/src/instruction/transfer.rs Co-authored-by: Jon Cinque <joncinque@pm.me> --------- Co-authored-by: Jon Cinque <joncinque@pm.me>
This commit is contained in:
parent
359eaad4e7
commit
4796e2fd84
|
@ -78,12 +78,7 @@ impl CiphertextCiphertextEqualityProofData {
|
|||
destination_ciphertext: pod_destination_ciphertext,
|
||||
};
|
||||
|
||||
let mut transcript = CiphertextCiphertextEqualityProof::transcript_new(
|
||||
&pod_source_pubkey,
|
||||
&pod_destination_pubkey,
|
||||
&pod_source_ciphertext,
|
||||
&pod_destination_ciphertext,
|
||||
);
|
||||
let mut transcript = context.new_transcript();
|
||||
|
||||
let proof = CiphertextCiphertextEqualityProof::new(
|
||||
source_keypair,
|
||||
|
@ -110,12 +105,7 @@ impl ZkProofData<CiphertextCiphertextEqualityProofContext>
|
|||
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
fn verify_proof(&self) -> Result<(), ProofError> {
|
||||
let mut transcript = CiphertextCiphertextEqualityProof::transcript_new(
|
||||
&self.context.source_pubkey,
|
||||
&self.context.destination_pubkey,
|
||||
&self.context.source_ciphertext,
|
||||
&self.context.destination_ciphertext,
|
||||
);
|
||||
let mut transcript = self.context.new_transcript();
|
||||
|
||||
let source_pubkey = self.context.source_pubkey.try_into()?;
|
||||
let destination_pubkey = self.context.destination_pubkey.try_into()?;
|
||||
|
@ -137,20 +127,15 @@ impl ZkProofData<CiphertextCiphertextEqualityProofContext>
|
|||
|
||||
#[allow(non_snake_case)]
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl CiphertextCiphertextEqualityProof {
|
||||
fn transcript_new(
|
||||
source_pubkey: &pod::ElGamalPubkey,
|
||||
destination_pubkey: &pod::ElGamalPubkey,
|
||||
source_ciphertext: &pod::ElGamalCiphertext,
|
||||
destination_ciphertext: &pod::ElGamalCiphertext,
|
||||
) -> Transcript {
|
||||
impl CiphertextCiphertextEqualityProofContext {
|
||||
fn new_transcript(&self) -> Transcript {
|
||||
let mut transcript = Transcript::new(b"CiphertextCiphertextEqualityProof");
|
||||
|
||||
transcript.append_pubkey(b"pubkey-source", source_pubkey);
|
||||
transcript.append_pubkey(b"pubkey-dest", destination_pubkey);
|
||||
transcript.append_pubkey(b"source-pubkey", &self.source_pubkey);
|
||||
transcript.append_pubkey(b"destination-pubkey", &self.destination_pubkey);
|
||||
|
||||
transcript.append_ciphertext(b"ciphertext-source", source_ciphertext);
|
||||
transcript.append_ciphertext(b"ciphertext-dest", destination_ciphertext);
|
||||
transcript.append_ciphertext(b"source-ciphertext", &self.source_ciphertext);
|
||||
transcript.append_ciphertext(b"destination-ciphertext", &self.destination_ciphertext);
|
||||
|
||||
transcript
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ impl PubkeyValidityData {
|
|||
|
||||
let context = PubkeyValidityProofContext { pubkey: pod_pubkey };
|
||||
|
||||
let mut transcript = PubkeyValidityProof::transcript_new(&pod_pubkey);
|
||||
let mut transcript = context.new_transcript();
|
||||
let proof = PubkeyValidityProof::new(keypair, &mut transcript).into();
|
||||
|
||||
Ok(PubkeyValidityData { context, proof })
|
||||
|
@ -68,7 +68,7 @@ impl ZkProofData<PubkeyValidityProofContext> for PubkeyValidityData {
|
|||
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
fn verify_proof(&self) -> Result<(), ProofError> {
|
||||
let mut transcript = PubkeyValidityProof::transcript_new(&self.context.pubkey);
|
||||
let mut transcript = self.context.new_transcript();
|
||||
let pubkey = self.context.pubkey.try_into()?;
|
||||
let proof: PubkeyValidityProof = self.proof.try_into()?;
|
||||
proof.verify(&pubkey, &mut transcript).map_err(|e| e.into())
|
||||
|
@ -77,10 +77,10 @@ impl ZkProofData<PubkeyValidityProofContext> for PubkeyValidityData {
|
|||
|
||||
#[allow(non_snake_case)]
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl PubkeyValidityProof {
|
||||
fn transcript_new(pubkey: &pod::ElGamalPubkey) -> Transcript {
|
||||
impl PubkeyValidityProofContext {
|
||||
fn new_transcript(&self) -> Transcript {
|
||||
let mut transcript = Transcript::new(b"PubkeyProof");
|
||||
transcript.append_pubkey(b"pubkey", pubkey);
|
||||
transcript.append_pubkey(b"pubkey", &self.pubkey);
|
||||
transcript
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ use {
|
|||
transcript::TranscriptProtocol,
|
||||
},
|
||||
arrayref::{array_ref, array_refs},
|
||||
bytemuck::bytes_of,
|
||||
merlin::Transcript,
|
||||
std::convert::TryInto,
|
||||
};
|
||||
|
@ -139,13 +140,7 @@ impl TransferData {
|
|||
new_source_ciphertext: pod_new_source_ciphertext,
|
||||
};
|
||||
|
||||
let mut transcript = TransferProof::transcript_new(
|
||||
&pod_transfer_pubkeys,
|
||||
&pod_ciphertext_lo,
|
||||
&pod_ciphertext_hi,
|
||||
&pod_new_source_ciphertext,
|
||||
);
|
||||
|
||||
let mut transcript = context.new_transcript();
|
||||
let proof = TransferProof::new(
|
||||
(amount_lo, amount_hi),
|
||||
source_keypair,
|
||||
|
@ -228,12 +223,7 @@ impl ZkProofData<TransferProofContext> for TransferData {
|
|||
#[cfg(not(target_os = "solana"))]
|
||||
fn verify_proof(&self) -> Result<(), ProofError> {
|
||||
// generate transcript and append all public inputs
|
||||
let mut transcript = TransferProof::transcript_new(
|
||||
&self.context.transfer_pubkeys,
|
||||
&self.context.ciphertext_lo,
|
||||
&self.context.ciphertext_hi,
|
||||
&self.context.new_source_ciphertext,
|
||||
);
|
||||
let mut transcript = self.context.new_transcript();
|
||||
|
||||
let ciphertext_lo = self.context.ciphertext_lo.try_into()?;
|
||||
let ciphertext_hi = self.context.ciphertext_hi.try_into()?;
|
||||
|
@ -250,6 +240,22 @@ impl ZkProofData<TransferProofContext> for TransferData {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TransferProofContext {
|
||||
fn new_transcript(&self) -> Transcript {
|
||||
let mut transcript = Transcript::new(b"transfer-proof");
|
||||
transcript.append_message(b"ciphertext-lo", bytes_of(&self.ciphertext_lo));
|
||||
transcript.append_message(b"ciphertext-hi", bytes_of(&self.ciphertext_hi));
|
||||
transcript.append_message(b"transfer-pubkeys", bytes_of(&self.transfer_pubkeys));
|
||||
transcript.append_message(
|
||||
b"new-source-ciphertext",
|
||||
bytes_of(&self.new_source_ciphertext),
|
||||
);
|
||||
transcript
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||
#[repr(C)]
|
||||
|
@ -270,33 +276,6 @@ pub struct TransferProof {
|
|||
#[allow(non_snake_case)]
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TransferProof {
|
||||
fn transcript_new(
|
||||
transfer_pubkeys: &pod::TransferPubkeys,
|
||||
ciphertext_lo: &pod::TransferAmountEncryption,
|
||||
ciphertext_hi: &pod::TransferAmountEncryption,
|
||||
new_source_ciphertext: &pod::ElGamalCiphertext,
|
||||
) -> Transcript {
|
||||
let mut transcript = Transcript::new(b"transfer-proof");
|
||||
|
||||
transcript.append_pubkey(b"pubkey-source", &transfer_pubkeys.source_pubkey);
|
||||
transcript.append_pubkey(b"pubkey-dest", &transfer_pubkeys.destination_pubkey);
|
||||
transcript.append_pubkey(b"pubkey-auditor", &transfer_pubkeys.auditor_pubkey);
|
||||
|
||||
transcript.append_commitment(b"comm-lo-amount", &ciphertext_lo.commitment);
|
||||
transcript.append_handle(b"handle-lo-source", &ciphertext_lo.source_handle);
|
||||
transcript.append_handle(b"handle-lo-dest", &ciphertext_lo.destination_handle);
|
||||
transcript.append_handle(b"handle-lo-auditor", &ciphertext_lo.auditor_handle);
|
||||
|
||||
transcript.append_commitment(b"comm-hi-amount", &ciphertext_hi.commitment);
|
||||
transcript.append_handle(b"handle-hi-source", &ciphertext_hi.source_handle);
|
||||
transcript.append_handle(b"handle-hi-dest", &ciphertext_hi.destination_handle);
|
||||
transcript.append_handle(b"handle-hi-auditor", &ciphertext_hi.auditor_handle);
|
||||
|
||||
transcript.append_ciphertext(b"ciphertext-new-source", new_source_ciphertext);
|
||||
|
||||
transcript
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
(transfer_amount_lo, transfer_amount_hi): (u64, u64),
|
||||
source_keypair: &ElGamalKeypair,
|
||||
|
|
|
@ -20,6 +20,7 @@ use {
|
|||
transcript::TranscriptProtocol,
|
||||
},
|
||||
arrayref::{array_ref, array_refs},
|
||||
bytemuck::bytes_of,
|
||||
curve25519_dalek::scalar::Scalar,
|
||||
merlin::Transcript,
|
||||
std::convert::TryInto,
|
||||
|
@ -62,7 +63,7 @@ lazy_static::lazy_static! {
|
|||
|
||||
/// The instruction data that is needed for the `ProofInstruction::TransferWithFee` instruction.
|
||||
///
|
||||
/// It includes the cryptographic proof as well as the cotnext data information needed to verify
|
||||
/// It includes the cryptographic proof as well as the context data information needed to verify
|
||||
/// the proof.
|
||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||
#[repr(C)]
|
||||
|
@ -197,14 +198,7 @@ impl TransferWithFeeData {
|
|||
fee_parameters: fee_parameters.into(),
|
||||
};
|
||||
|
||||
let mut transcript = TransferWithFeeProof::transcript_new(
|
||||
&pod_transfer_with_fee_pubkeys,
|
||||
&pod_ciphertext_lo,
|
||||
&pod_ciphertext_hi,
|
||||
&pod_new_source_ciphertext,
|
||||
&pod_fee_ciphertext_lo,
|
||||
&pod_fee_ciphertext_hi,
|
||||
);
|
||||
let mut transcript = context.new_transcript();
|
||||
|
||||
let proof = TransferWithFeeProof::new(
|
||||
(amount_lo, &ciphertext_lo, &opening_lo),
|
||||
|
@ -353,14 +347,7 @@ impl ZkProofData<TransferWithFeeProofContext> for TransferWithFeeData {
|
|||
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
fn verify_proof(&self) -> Result<(), ProofError> {
|
||||
let mut transcript = TransferWithFeeProof::transcript_new(
|
||||
&self.context.transfer_with_fee_pubkeys,
|
||||
&self.context.ciphertext_lo,
|
||||
&self.context.ciphertext_hi,
|
||||
&self.context.new_source_ciphertext,
|
||||
&self.context.fee_ciphertext_lo,
|
||||
&self.context.fee_ciphertext_hi,
|
||||
);
|
||||
let mut transcript = self.context.new_transcript();
|
||||
|
||||
let ciphertext_lo = self.context.ciphertext_lo.try_into()?;
|
||||
let ciphertext_hi = self.context.ciphertext_hi.try_into()?;
|
||||
|
@ -384,7 +371,28 @@ impl ZkProofData<TransferWithFeeProofContext> for TransferWithFeeData {
|
|||
}
|
||||
}
|
||||
|
||||
// #[derive(Clone, Copy, Pod, Zeroable)]
|
||||
#[allow(non_snake_case)]
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TransferWithFeeProofContext {
|
||||
fn new_transcript(&self) -> Transcript {
|
||||
let mut transcript = Transcript::new(b"transfer-with-fee-proof");
|
||||
transcript.append_message(b"ciphertext-lo", bytes_of(&self.ciphertext_lo));
|
||||
transcript.append_message(b"ciphertext-hi", bytes_of(&self.ciphertext_hi));
|
||||
transcript.append_message(
|
||||
b"transfer-with-fee-pubkeys",
|
||||
bytes_of(&self.transfer_with_fee_pubkeys),
|
||||
);
|
||||
transcript.append_message(
|
||||
b"new-source-ciphertext",
|
||||
bytes_of(&self.new_source_ciphertext),
|
||||
);
|
||||
transcript.append_message(b"fee-ciphertext-lo", bytes_of(&self.fee_ciphertext_lo));
|
||||
transcript.append_message(b"fee-ciphertext-hi", bytes_of(&self.fee_ciphertext_hi));
|
||||
transcript.append_message(b"fee-parameters", bytes_of(&self.fee_parameters));
|
||||
transcript
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||
pub struct TransferWithFeeProof {
|
||||
|
@ -400,56 +408,6 @@ pub struct TransferWithFeeProof {
|
|||
#[allow(non_snake_case)]
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TransferWithFeeProof {
|
||||
fn transcript_new(
|
||||
transfer_with_fee_pubkeys: &pod::TransferWithFeePubkeys,
|
||||
ciphertext_lo: &pod::TransferAmountEncryption,
|
||||
ciphertext_hi: &pod::TransferAmountEncryption,
|
||||
new_source_ciphertext: &pod::ElGamalCiphertext,
|
||||
fee_ciphertext_lo: &pod::FeeEncryption,
|
||||
fee_ciphertext_hi: &pod::FeeEncryption,
|
||||
) -> Transcript {
|
||||
let mut transcript = Transcript::new(b"FeeProof");
|
||||
|
||||
transcript.append_pubkey(b"pubkey-source", &transfer_with_fee_pubkeys.source_pubkey);
|
||||
transcript.append_pubkey(
|
||||
b"pubkey-dest",
|
||||
&transfer_with_fee_pubkeys.destination_pubkey,
|
||||
);
|
||||
transcript.append_pubkey(b"pubkey-auditor", &transfer_with_fee_pubkeys.auditor_pubkey);
|
||||
transcript.append_pubkey(
|
||||
b"withdraw_withheld_authority_pubkey",
|
||||
&transfer_with_fee_pubkeys.withdraw_withheld_authority_pubkey,
|
||||
);
|
||||
|
||||
transcript.append_commitment(b"comm-lo-amount", &ciphertext_lo.commitment);
|
||||
transcript.append_handle(b"handle-lo-source", &ciphertext_lo.source_handle);
|
||||
transcript.append_handle(b"handle-lo-dest", &ciphertext_lo.destination_handle);
|
||||
transcript.append_handle(b"handle-lo-auditor", &ciphertext_lo.auditor_handle);
|
||||
|
||||
transcript.append_commitment(b"comm-hi-amount", &ciphertext_hi.commitment);
|
||||
transcript.append_handle(b"handle-hi-source", &ciphertext_hi.source_handle);
|
||||
transcript.append_handle(b"handle-hi-dest", &ciphertext_hi.destination_handle);
|
||||
transcript.append_handle(b"handle-hi-auditor", &ciphertext_hi.auditor_handle);
|
||||
|
||||
transcript.append_ciphertext(b"ctxt-new-source", new_source_ciphertext);
|
||||
|
||||
transcript.append_commitment(b"comm-fee-lo", &fee_ciphertext_lo.commitment);
|
||||
transcript.append_handle(b"handle-fee-lo-dest", &fee_ciphertext_lo.destination_handle);
|
||||
transcript.append_handle(
|
||||
b"handle-fee-lo-auditor",
|
||||
&fee_ciphertext_lo.withdraw_withheld_authority_handle,
|
||||
);
|
||||
|
||||
transcript.append_commitment(b"comm-fee-hi", &fee_ciphertext_hi.commitment);
|
||||
transcript.append_handle(b"handle-fee-hi-dest", &fee_ciphertext_hi.destination_handle);
|
||||
transcript.append_handle(
|
||||
b"handle-fee-hi-auditor",
|
||||
&fee_ciphertext_hi.withdraw_withheld_authority_handle,
|
||||
);
|
||||
|
||||
transcript
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[allow(clippy::many_single_char_names)]
|
||||
pub fn new(
|
||||
|
|
|
@ -77,7 +77,7 @@ impl WithdrawData {
|
|||
final_ciphertext: pod_final_ciphertext,
|
||||
};
|
||||
|
||||
let mut transcript = WithdrawProof::transcript_new(&pod_pubkey, &pod_final_ciphertext);
|
||||
let mut transcript = context.new_transcript();
|
||||
let proof = WithdrawProof::new(keypair, final_balance, &final_ciphertext, &mut transcript);
|
||||
|
||||
Ok(Self { context, proof })
|
||||
|
@ -93,8 +93,7 @@ impl ZkProofData<WithdrawProofContext> for WithdrawData {
|
|||
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
fn verify_proof(&self) -> Result<(), ProofError> {
|
||||
let mut transcript =
|
||||
WithdrawProof::transcript_new(&self.context.pubkey, &self.context.final_ciphertext);
|
||||
let mut transcript = self.context.new_transcript();
|
||||
|
||||
let elgamal_pubkey = self.context.pubkey.try_into()?;
|
||||
let final_balance_ciphertext = self.context.final_ciphertext.try_into()?;
|
||||
|
@ -103,6 +102,19 @@ impl ZkProofData<WithdrawProofContext> for WithdrawData {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl WithdrawProofContext {
|
||||
fn new_transcript(&self) -> Transcript {
|
||||
let mut transcript = Transcript::new(b"WithdrawProof");
|
||||
|
||||
transcript.append_pubkey(b"pubkey", &self.pubkey);
|
||||
transcript.append_ciphertext(b"ciphertext", &self.final_ciphertext);
|
||||
|
||||
transcript
|
||||
}
|
||||
}
|
||||
|
||||
/// The withdraw proof.
|
||||
///
|
||||
/// It contains a ciphertext-commitment equality proof and a 64-bit range proof.
|
||||
|
@ -123,18 +135,6 @@ pub struct WithdrawProof {
|
|||
#[allow(non_snake_case)]
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl WithdrawProof {
|
||||
fn transcript_new(
|
||||
pubkey: &pod::ElGamalPubkey,
|
||||
ciphertext: &pod::ElGamalCiphertext,
|
||||
) -> Transcript {
|
||||
let mut transcript = Transcript::new(b"WithdrawProof");
|
||||
|
||||
transcript.append_pubkey(b"pubkey", pubkey);
|
||||
transcript.append_ciphertext(b"ciphertext", ciphertext);
|
||||
|
||||
transcript
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
keypair: &ElGamalKeypair,
|
||||
final_balance: u64,
|
||||
|
|
|
@ -62,7 +62,7 @@ impl ZeroBalanceProofData {
|
|||
ciphertext: pod_ciphertext,
|
||||
};
|
||||
|
||||
let mut transcript = ZeroBalanceProof::transcript_new(&pod_pubkey, &pod_ciphertext);
|
||||
let mut transcript = context.new_transcript();
|
||||
let proof = ZeroBalanceProof::new(keypair, ciphertext, &mut transcript).into();
|
||||
|
||||
Ok(ZeroBalanceProofData { context, proof })
|
||||
|
@ -78,9 +78,7 @@ impl ZkProofData<ZeroBalanceProofContext> for ZeroBalanceProofData {
|
|||
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
fn verify_proof(&self) -> Result<(), ProofError> {
|
||||
let mut transcript =
|
||||
ZeroBalanceProof::transcript_new(&self.context.pubkey, &self.context.ciphertext);
|
||||
|
||||
let mut transcript = self.context.new_transcript();
|
||||
let pubkey = self.context.pubkey.try_into()?;
|
||||
let ciphertext = self.context.ciphertext.try_into()?;
|
||||
let proof: ZeroBalanceProof = self.proof.try_into()?;
|
||||
|
@ -92,15 +90,12 @@ impl ZkProofData<ZeroBalanceProofContext> for ZeroBalanceProofData {
|
|||
|
||||
#[allow(non_snake_case)]
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl ZeroBalanceProof {
|
||||
fn transcript_new(
|
||||
pubkey: &pod::ElGamalPubkey,
|
||||
ciphertext: &pod::ElGamalCiphertext,
|
||||
) -> Transcript {
|
||||
impl ZeroBalanceProofContext {
|
||||
fn new_transcript(&self) -> Transcript {
|
||||
let mut transcript = Transcript::new(b"ZeroBalanceProof");
|
||||
|
||||
transcript.append_pubkey(b"pubkey", pubkey);
|
||||
transcript.append_ciphertext(b"ciphertext", ciphertext);
|
||||
transcript.append_pubkey(b"pubkey", &self.pubkey);
|
||||
transcript.append_ciphertext(b"ciphertext", &self.ciphertext);
|
||||
|
||||
transcript
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue