solana_zk_token_sdk/instruction/
pubkey_validity.rs1#[cfg(not(target_os = "solana"))]
9use {
10 crate::{
11 encryption::elgamal::ElGamalKeypair,
12 errors::{ProofGenerationError, ProofVerificationError},
13 sigma_proofs::pubkey_proof::PubkeyValidityProof,
14 transcript::TranscriptProtocol,
15 },
16 merlin::Transcript,
17 std::convert::TryInto,
18};
19use {
20 crate::{
21 instruction::{ProofType, ZkProofData},
22 zk_token_elgamal::pod,
23 },
24 bytemuck_derive::{Pod, Zeroable},
25};
26
27#[derive(Clone, Copy, Pod, Zeroable)]
33#[repr(C)]
34pub struct PubkeyValidityData {
35 pub context: PubkeyValidityProofContext, pub proof: pod::PubkeyValidityProof, }
41
42#[derive(Clone, Copy, Pod, Zeroable)]
44#[repr(C)]
45pub struct PubkeyValidityProofContext {
46 pub pubkey: pod::ElGamalPubkey, }
49
50#[cfg(not(target_os = "solana"))]
51impl PubkeyValidityData {
52 pub fn new(keypair: &ElGamalKeypair) -> Result<Self, ProofGenerationError> {
53 let pod_pubkey = pod::ElGamalPubkey(keypair.pubkey().into());
54
55 let context = PubkeyValidityProofContext { pubkey: pod_pubkey };
56
57 let mut transcript = context.new_transcript();
58 let proof = PubkeyValidityProof::new(keypair, &mut transcript).into();
59
60 Ok(PubkeyValidityData { context, proof })
61 }
62}
63
64impl ZkProofData<PubkeyValidityProofContext> for PubkeyValidityData {
65 const PROOF_TYPE: ProofType = ProofType::PubkeyValidity;
66
67 fn context_data(&self) -> &PubkeyValidityProofContext {
68 &self.context
69 }
70
71 #[cfg(not(target_os = "solana"))]
72 fn verify_proof(&self) -> Result<(), ProofVerificationError> {
73 let mut transcript = self.context.new_transcript();
74 let pubkey = self.context.pubkey.try_into()?;
75 let proof: PubkeyValidityProof = self.proof.try_into()?;
76 proof.verify(&pubkey, &mut transcript).map_err(|e| e.into())
77 }
78}
79
80#[allow(non_snake_case)]
81#[cfg(not(target_os = "solana"))]
82impl PubkeyValidityProofContext {
83 fn new_transcript(&self) -> Transcript {
84 let mut transcript = Transcript::new(b"PubkeyProof");
85 transcript.append_pubkey(b"pubkey", &self.pubkey);
86 transcript
87 }
88}
89
90#[cfg(test)]
91mod test {
92 use super::*;
93
94 #[test]
95 fn test_pubkey_validity_instruction_correctness() {
96 let keypair = ElGamalKeypair::new_rand();
97
98 let pubkey_validity_data = PubkeyValidityData::new(&keypair).unwrap();
99 assert!(pubkey_validity_data.verify_proof().is_ok());
100 }
101}