solana_zk_token_sdk/instruction/
pubkey_validity.rs#[cfg(not(target_os = "solana"))]
use {
crate::{
encryption::elgamal::ElGamalKeypair,
errors::{ProofGenerationError, ProofVerificationError},
sigma_proofs::pubkey_proof::PubkeyValidityProof,
transcript::TranscriptProtocol,
},
merlin::Transcript,
std::convert::TryInto,
};
use {
crate::{
instruction::{ProofType, ZkProofData},
zk_token_elgamal::pod,
},
bytemuck::{Pod, Zeroable},
};
#[derive(Clone, Copy, Pod, Zeroable)]
#[repr(C)]
pub struct PubkeyValidityData {
pub context: PubkeyValidityProofContext, pub proof: pod::PubkeyValidityProof, }
#[derive(Clone, Copy, Pod, Zeroable)]
#[repr(C)]
pub struct PubkeyValidityProofContext {
pub pubkey: pod::ElGamalPubkey, }
#[cfg(not(target_os = "solana"))]
impl PubkeyValidityData {
pub fn new(keypair: &ElGamalKeypair) -> Result<Self, ProofGenerationError> {
let pod_pubkey = pod::ElGamalPubkey(keypair.pubkey().to_bytes());
let context = PubkeyValidityProofContext { pubkey: pod_pubkey };
let mut transcript = context.new_transcript();
let proof = PubkeyValidityProof::new(keypair, &mut transcript).into();
Ok(PubkeyValidityData { context, proof })
}
}
impl ZkProofData<PubkeyValidityProofContext> for PubkeyValidityData {
const PROOF_TYPE: ProofType = ProofType::PubkeyValidity;
fn context_data(&self) -> &PubkeyValidityProofContext {
&self.context
}
#[cfg(not(target_os = "solana"))]
fn verify_proof(&self) -> Result<(), ProofVerificationError> {
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())
}
}
#[allow(non_snake_case)]
#[cfg(not(target_os = "solana"))]
impl PubkeyValidityProofContext {
fn new_transcript(&self) -> Transcript {
let mut transcript = Transcript::new(b"PubkeyProof");
transcript.append_pubkey(b"pubkey", &self.pubkey);
transcript
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_pubkey_validity_instruction_correctness() {
let keypair = ElGamalKeypair::new_rand();
let pubkey_validity_data = PubkeyValidityData::new(&keypair).unwrap();
assert!(pubkey_validity_data.verify_proof().is_ok());
}
}