solana_zk_sdk/zk_elgamal_proof_program/proof_data/
pubkey_validity.rs1#[cfg(target_arch = "wasm32")]
9use wasm_bindgen::prelude::*;
10#[cfg(not(target_os = "solana"))]
11use {
12 crate::{
13 encryption::elgamal::ElGamalKeypair,
14 sigma_proofs::pubkey_validity::PubkeyValidityProof,
15 zk_elgamal_proof_program::{
16 errors::{ProofGenerationError, ProofVerificationError},
17 proof_data::errors::ProofDataError,
18 },
19 },
20 bytemuck::bytes_of,
21 merlin::Transcript,
22 std::convert::TryInto,
23};
24use {
25 crate::{
26 encryption::pod::elgamal::PodElGamalPubkey,
27 sigma_proofs::pod::PodPubkeyValidityProof,
28 zk_elgamal_proof_program::proof_data::{pod::impl_wasm_to_bytes, ProofType, ZkProofData},
29 },
30 bytemuck_derive::{Pod, Zeroable},
31};
32
33#[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
39#[derive(Clone, Copy, Pod, Zeroable)]
40#[repr(C)]
41pub struct PubkeyValidityProofData {
42 pub context: PubkeyValidityProofContext, pub proof: PodPubkeyValidityProof, }
48
49#[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
51#[derive(Clone, Copy, Pod, Zeroable)]
52#[repr(C)]
53pub struct PubkeyValidityProofContext {
54 pub pubkey: PodElGamalPubkey, }
57
58#[cfg(not(target_os = "solana"))]
59#[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
60impl PubkeyValidityProofData {
61 pub fn new(keypair: &ElGamalKeypair) -> Result<Self, ProofGenerationError> {
62 let pod_pubkey = PodElGamalPubkey(keypair.pubkey().into());
63
64 let context = PubkeyValidityProofContext { pubkey: pod_pubkey };
65
66 let mut transcript = context.new_transcript();
67 let proof = PubkeyValidityProof::new(keypair, &mut transcript).into();
68
69 Ok(PubkeyValidityProofData { context, proof })
70 }
71}
72
73impl_wasm_to_bytes!(TYPE = PubkeyValidityProofData);
74
75impl ZkProofData<PubkeyValidityProofContext> for PubkeyValidityProofData {
76 const PROOF_TYPE: ProofType = ProofType::PubkeyValidity;
77
78 fn context_data(&self) -> &PubkeyValidityProofContext {
79 &self.context
80 }
81
82 #[cfg(not(target_os = "solana"))]
83 fn verify_proof(&self) -> Result<(), ProofVerificationError> {
84 let mut transcript = self.context.new_transcript();
85 let pubkey = self.context.pubkey.try_into()?;
86 let proof: PubkeyValidityProof = self.proof.try_into()?;
87 proof.verify(&pubkey, &mut transcript).map_err(|e| e.into())
88 }
89}
90
91#[allow(non_snake_case)]
92#[cfg(not(target_os = "solana"))]
93impl PubkeyValidityProofContext {
94 fn new_transcript(&self) -> Transcript {
95 let mut transcript = Transcript::new(b"pubkey-validity-instruction");
96 transcript.append_message(b"pubkey", bytes_of(&self.pubkey));
97 transcript
98 }
99}
100
101impl_wasm_to_bytes!(TYPE = PubkeyValidityProofContext);
102
103#[cfg(test)]
104mod test {
105 use super::*;
106
107 #[test]
108 fn test_pubkey_validity_instruction_correctness() {
109 let keypair = ElGamalKeypair::new_rand();
110
111 let pubkey_validity_data = PubkeyValidityProofData::new(&keypair).unwrap();
112 assert!(pubkey_validity_data.verify_proof().is_ok());
113 }
114}