From 78799640eae2786f9107c4a823b796bd676972fa Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Thu, 30 Sep 2021 11:11:53 -0700 Subject: [PATCH] Rename ElGamalCT to ElGamalCiphertext, ElGamalPK to ElGamalPubkey --- zk-token-sdk/src/encryption/elgamal.rs | 116 +++++++++------- zk-token-sdk/src/encryption/pedersen.rs | 8 +- zk-token-sdk/src/errors.rs | 2 +- zk-token-sdk/src/instruction/close_account.rs | 12 +- zk-token-sdk/src/instruction/transfer.rs | 38 +++--- .../src/instruction/update_account_pk.rs | 42 +++--- zk-token-sdk/src/instruction/withdraw.rs | 16 ++- zk-token-sdk/src/zk_token_elgamal/convert.rs | 26 ++-- zk-token-sdk/src/zk_token_elgamal/ops.rs | 126 ++++++++++-------- zk-token-sdk/src/zk_token_elgamal/pod.rs | 4 +- 10 files changed, 219 insertions(+), 171 deletions(-) diff --git a/zk-token-sdk/src/encryption/elgamal.rs b/zk-token-sdk/src/encryption/elgamal.rs index e9e5af4114..b4476aafa3 100644 --- a/zk-token-sdk/src/encryption/elgamal.rs +++ b/zk-token-sdk/src/encryption/elgamal.rs @@ -22,7 +22,7 @@ pub struct ElGamal; impl ElGamal { /// Generates the public and secret keys for ElGamal encryption. #[cfg(not(target_arch = "bpf"))] - pub fn keygen() -> (ElGamalPK, ElGamalSK) { + pub fn keygen() -> (ElGamalPubkey, ElGamalSK) { ElGamal::keygen_with(&mut OsRng) // using OsRng for now } @@ -30,7 +30,7 @@ impl ElGamal { /// secret keys for ElGamal encryption. #[cfg(not(target_arch = "bpf"))] #[allow(non_snake_case)] - pub fn keygen_with(rng: &mut T) -> (ElGamalPK, ElGamalSK) { + pub fn keygen_with(rng: &mut T) -> (ElGamalPubkey, ElGamalSK) { // sample a non-zero scalar let mut s: Scalar; loop { @@ -44,17 +44,17 @@ impl ElGamal { let H = PedersenBase::default().H; let P = s.invert() * H; - (ElGamalPK(P), ElGamalSK(s)) + (ElGamalPubkey(P), ElGamalSK(s)) } /// On input a public key and a message to be encrypted, the function /// returns an ElGamal ciphertext of the message under the public key. #[cfg(not(target_arch = "bpf"))] - pub fn encrypt>(pk: &ElGamalPK, amount: T) -> ElGamalCT { + pub fn encrypt>(pk: &ElGamalPubkey, amount: T) -> ElGamalCiphertext { let (message_comm, open) = Pedersen::commit(amount); let decrypt_handle = pk.gen_decrypt_handle(&open); - ElGamalCT { + ElGamalCiphertext { message_comm, decrypt_handle, } @@ -64,14 +64,14 @@ impl ElGamal { /// returns an ElGamal ciphertext of the message under the public key using /// the opening. pub fn encrypt_with>( - pk: &ElGamalPK, + pk: &ElGamalPubkey, amount: T, open: &PedersenOpen, - ) -> ElGamalCT { + ) -> ElGamalCiphertext { let message_comm = Pedersen::commit_with(amount, open); let decrypt_handle = pk.gen_decrypt_handle(open); - ElGamalCT { + ElGamalCiphertext { message_comm, decrypt_handle, } @@ -81,9 +81,9 @@ impl ElGamal { /// /// The output of the function is of type `DiscreteLogInstance`. The exact message /// can be recovered via the DiscreteLogInstance's decode method. - pub fn decrypt(sk: &ElGamalSK, ct: &ElGamalCT) -> DiscreteLogInstance { + pub fn decrypt(sk: &ElGamalSK, ct: &ElGamalCiphertext) -> DiscreteLogInstance { let ElGamalSK(s) = sk; - let ElGamalCT { + let ElGamalCiphertext { message_comm, decrypt_handle, } = ct; @@ -96,7 +96,7 @@ impl ElGamal { /// On input a secret key and a ciphertext, the function decrypts the /// ciphertext for a u32 value. - pub fn decrypt_u32(sk: &ElGamalSK, ct: &ElGamalCT) -> Option { + pub fn decrypt_u32(sk: &ElGamalSK, ct: &ElGamalCiphertext) -> Option { let discrete_log_instance = ElGamal::decrypt(sk, ct); discrete_log_instance.decode_u32() } @@ -104,8 +104,8 @@ impl ElGamal { /// Public key for the ElGamal encryption scheme. #[derive(Serialize, Deserialize, Default, Clone, Copy, Debug, Eq, PartialEq)] -pub struct ElGamalPK(RistrettoPoint); -impl ElGamalPK { +pub struct ElGamalPubkey(RistrettoPoint); +impl ElGamalPubkey { pub fn get_point(&self) -> RistrettoPoint { self.0 } @@ -115,20 +115,20 @@ impl ElGamalPK { self.0.compress().to_bytes() } - pub fn from_bytes(bytes: &[u8]) -> Option { - Some(ElGamalPK( + pub fn from_bytes(bytes: &[u8]) -> Option { + Some(ElGamalPubkey( CompressedRistretto::from_slice(bytes).decompress()?, )) } /// Utility method for code ergonomics. #[cfg(not(target_arch = "bpf"))] - pub fn encrypt>(&self, msg: T) -> ElGamalCT { + pub fn encrypt>(&self, msg: T) -> ElGamalCiphertext { ElGamal::encrypt(self, msg) } /// Utility method for code ergonomics. - pub fn encrypt_with>(&self, msg: T, open: &PedersenOpen) -> ElGamalCT { + pub fn encrypt_with>(&self, msg: T, open: &PedersenOpen) -> ElGamalCiphertext { ElGamal::encrypt_with(self, msg, open) } @@ -139,9 +139,9 @@ impl ElGamalPK { } } -impl From for ElGamalPK { - fn from(point: RistrettoPoint) -> ElGamalPK { - ElGamalPK(point) +impl From for ElGamalPubkey { + fn from(point: RistrettoPoint) -> ElGamalPubkey { + ElGamalPubkey(point) } } @@ -155,12 +155,12 @@ impl ElGamalSK { } /// Utility method for code ergonomics. - pub fn decrypt(&self, ct: &ElGamalCT) -> DiscreteLogInstance { + pub fn decrypt(&self, ct: &ElGamalCiphertext) -> DiscreteLogInstance { ElGamal::decrypt(self, ct) } /// Utility method for code ergonomics. - pub fn decrypt_u32(&self, ct: &ElGamalCT) -> Option { + pub fn decrypt_u32(&self, ct: &ElGamalCiphertext) -> Option { ElGamal::decrypt_u32(self, ct) } @@ -197,14 +197,14 @@ impl ConstantTimeEq for ElGamalSK { /// Ciphertext for the ElGamal encryption scheme. #[allow(non_snake_case)] #[derive(Serialize, Deserialize, Default, Clone, Copy, Debug, Eq, PartialEq)] -pub struct ElGamalCT { +pub struct ElGamalCiphertext { pub message_comm: PedersenComm, pub decrypt_handle: PedersenDecHandle, } -impl ElGamalCT { +impl ElGamalCiphertext { pub fn add_to_msg>(&self, message: T) -> Self { let diff_comm = Pedersen::commit_with(message, &PedersenOpen::default()); - ElGamalCT { + ElGamalCiphertext { message_comm: self.message_comm + diff_comm, decrypt_handle: self.decrypt_handle, } @@ -212,7 +212,7 @@ impl ElGamalCT { pub fn sub_to_msg>(&self, message: T) -> Self { let diff_comm = Pedersen::commit_with(message, &PedersenOpen::default()); - ElGamalCT { + ElGamalCiphertext { message_comm: self.message_comm - diff_comm, decrypt_handle: self.decrypt_handle, } @@ -227,14 +227,14 @@ impl ElGamalCT { bytes } - pub fn from_bytes(bytes: &[u8]) -> Option { + pub fn from_bytes(bytes: &[u8]) -> Option { let bytes = array_ref![bytes, 0, 64]; let (message_comm, decrypt_handle) = array_refs![bytes, 32, 32]; let message_comm = CompressedRistretto::from_slice(message_comm).decompress()?; let decrypt_handle = CompressedRistretto::from_slice(decrypt_handle).decompress()?; - Some(ElGamalCT { + Some(ElGamalCiphertext { message_comm: PedersenComm(message_comm), decrypt_handle: PedersenDecHandle(decrypt_handle), }) @@ -251,57 +251,73 @@ impl ElGamalCT { } } -impl<'a, 'b> Add<&'b ElGamalCT> for &'a ElGamalCT { - type Output = ElGamalCT; +impl<'a, 'b> Add<&'b ElGamalCiphertext> for &'a ElGamalCiphertext { + type Output = ElGamalCiphertext; - fn add(self, other: &'b ElGamalCT) -> ElGamalCT { - ElGamalCT { + fn add(self, other: &'b ElGamalCiphertext) -> ElGamalCiphertext { + ElGamalCiphertext { message_comm: self.message_comm + other.message_comm, decrypt_handle: self.decrypt_handle + other.decrypt_handle, } } } -define_add_variants!(LHS = ElGamalCT, RHS = ElGamalCT, Output = ElGamalCT); +define_add_variants!( + LHS = ElGamalCiphertext, + RHS = ElGamalCiphertext, + Output = ElGamalCiphertext +); -impl<'a, 'b> Sub<&'b ElGamalCT> for &'a ElGamalCT { - type Output = ElGamalCT; +impl<'a, 'b> Sub<&'b ElGamalCiphertext> for &'a ElGamalCiphertext { + type Output = ElGamalCiphertext; - fn sub(self, other: &'b ElGamalCT) -> ElGamalCT { - ElGamalCT { + fn sub(self, other: &'b ElGamalCiphertext) -> ElGamalCiphertext { + ElGamalCiphertext { message_comm: self.message_comm - other.message_comm, decrypt_handle: self.decrypt_handle - other.decrypt_handle, } } } -define_sub_variants!(LHS = ElGamalCT, RHS = ElGamalCT, Output = ElGamalCT); +define_sub_variants!( + LHS = ElGamalCiphertext, + RHS = ElGamalCiphertext, + Output = ElGamalCiphertext +); -impl<'a, 'b> Mul<&'b Scalar> for &'a ElGamalCT { - type Output = ElGamalCT; +impl<'a, 'b> Mul<&'b Scalar> for &'a ElGamalCiphertext { + type Output = ElGamalCiphertext; - fn mul(self, other: &'b Scalar) -> ElGamalCT { - ElGamalCT { + fn mul(self, other: &'b Scalar) -> ElGamalCiphertext { + ElGamalCiphertext { message_comm: self.message_comm * other, decrypt_handle: self.decrypt_handle * other, } } } -define_mul_variants!(LHS = ElGamalCT, RHS = Scalar, Output = ElGamalCT); +define_mul_variants!( + LHS = ElGamalCiphertext, + RHS = Scalar, + Output = ElGamalCiphertext +); -impl<'a, 'b> Div<&'b Scalar> for &'a ElGamalCT { - type Output = ElGamalCT; +impl<'a, 'b> Div<&'b Scalar> for &'a ElGamalCiphertext { + type Output = ElGamalCiphertext; - fn div(self, other: &'b Scalar) -> ElGamalCT { - ElGamalCT { + fn div(self, other: &'b Scalar) -> ElGamalCiphertext { + ElGamalCiphertext { message_comm: self.message_comm * other.invert(), decrypt_handle: self.decrypt_handle * other.invert(), } } } -define_div_variants!(LHS = ElGamalCT, RHS = Scalar, Output = ElGamalCT); +define_div_variants!( + LHS = ElGamalCiphertext, + RHS = Scalar, + Output = ElGamalCiphertext +); #[cfg(test)] mod tests { @@ -441,7 +457,7 @@ mod tests { let ct = pk.encrypt(msg); let encoded = bincode::serialize(&ct).unwrap(); - let decoded: ElGamalCT = bincode::deserialize(&encoded).unwrap(); + let decoded: ElGamalCiphertext = bincode::deserialize(&encoded).unwrap(); assert_eq!(ct, decoded); } @@ -451,7 +467,7 @@ mod tests { let (pk, _) = ElGamal::keygen(); let encoded = bincode::serialize(&pk).unwrap(); - let decoded: ElGamalPK = bincode::deserialize(&encoded).unwrap(); + let decoded: ElGamalPubkey = bincode::deserialize(&encoded).unwrap(); assert_eq!(pk, decoded); } diff --git a/zk-token-sdk/src/encryption/pedersen.rs b/zk-token-sdk/src/encryption/pedersen.rs index 830bf84646..b6ec6fc562 100644 --- a/zk-token-sdk/src/encryption/pedersen.rs +++ b/zk-token-sdk/src/encryption/pedersen.rs @@ -2,7 +2,7 @@ use rand::{rngs::OsRng, CryptoRng, RngCore}; use { crate::{ - encryption::elgamal::{ElGamalCT, ElGamalPK}, + encryption::elgamal::{ElGamalCiphertext, ElGamalPubkey}, errors::ProofError, }, core::ops::{Add, Div, Mul, Sub}, @@ -271,13 +271,13 @@ impl PedersenDecHandle { self.0 } - pub fn generate_handle(open: &PedersenOpen, pk: &ElGamalPK) -> PedersenDecHandle { + pub fn generate_handle(open: &PedersenOpen, pk: &ElGamalPubkey) -> PedersenDecHandle { PedersenDecHandle(open.get_scalar() * pk.get_point()) } /// Maps a decryption token and Pedersen commitment to ElGamal ciphertext - pub fn to_elgamal_ctxt(self, comm: PedersenComm) -> ElGamalCT { - ElGamalCT { + pub fn to_elgamal_ctxt(self, comm: PedersenComm) -> ElGamalCiphertext { + ElGamalCiphertext { message_comm: comm, decrypt_handle: self, } diff --git a/zk-token-sdk/src/errors.rs b/zk-token-sdk/src/errors.rs index d5215d4c58..2aee36d4bf 100644 --- a/zk-token-sdk/src/errors.rs +++ b/zk-token-sdk/src/errors.rs @@ -14,6 +14,6 @@ pub enum ProofError { InvalidBitsize, /// This error occurs when there are insufficient generators for the proof. InvalidGeneratorsLength, - /// This error occurs a `zk_token_elgamal::pod::ElGamalCT` contains invalid ElGamalCT ciphertext + /// This error occurs a `zk_token_elgamal::pod::ElGamalCiphertext` contains invalid ElGamalCiphertext ciphertext InconsistentCTData, } diff --git a/zk-token-sdk/src/instruction/close_account.rs b/zk-token-sdk/src/instruction/close_account.rs index 7993805e71..01d47ba0e8 100644 --- a/zk-token-sdk/src/instruction/close_account.rs +++ b/zk-token-sdk/src/instruction/close_account.rs @@ -5,7 +5,7 @@ use { #[cfg(not(target_arch = "bpf"))] use { crate::{ - encryption::elgamal::{ElGamalCT, ElGamalSK}, + encryption::elgamal::{ElGamalCiphertext, ElGamalSK}, errors::ProofError, instruction::Verifiable, transcript::TranscriptProtocol, @@ -31,7 +31,7 @@ use { #[repr(C)] pub struct CloseAccountData { /// The source account available balance in encrypted form - pub balance: pod::ElGamalCT, // 64 bytes + pub balance: pod::ElGamalCiphertext, // 64 bytes /// Proof that the source account available balance is zero pub proof: CloseAccountProof, // 64 bytes @@ -39,7 +39,7 @@ pub struct CloseAccountData { #[cfg(not(target_arch = "bpf"))] impl CloseAccountData { - pub fn new(source_sk: &ElGamalSK, balance: ElGamalCT) -> Self { + pub fn new(source_sk: &ElGamalSK, balance: ElGamalCiphertext) -> Self { let proof = CloseAccountProof::new(source_sk, &balance); CloseAccountData { @@ -74,7 +74,7 @@ impl CloseAccountProof { Transcript::new(b"CloseAccountProof") } - pub fn new(source_sk: &ElGamalSK, balance: &ElGamalCT) -> Self { + pub fn new(source_sk: &ElGamalSK, balance: &ElGamalCiphertext) -> Self { let mut transcript = Self::transcript_new(); // add a domain separator to record the start of the protocol @@ -101,7 +101,7 @@ impl CloseAccountProof { } } - pub fn verify(&self, balance: &ElGamalCT) -> Result<(), ProofError> { + pub fn verify(&self, balance: &ElGamalCiphertext) -> Result<(), ProofError> { let mut transcript = Self::transcript_new(); // add a domain separator to record the start of the protocol @@ -156,7 +156,7 @@ mod test { assert!(proof.verify(&balance).is_err()); // A zeroed cyphertext should be considered as an account balance of 0 - let zeroed_ct: ElGamalCT = pod::ElGamalCT::zeroed().try_into().unwrap(); + let zeroed_ct: ElGamalCiphertext = pod::ElGamalCiphertext::zeroed().try_into().unwrap(); let proof = CloseAccountProof::new(&source_sk, &zeroed_ct); assert!(proof.verify(&zeroed_ct).is_ok()); } diff --git a/zk-token-sdk/src/instruction/transfer.rs b/zk-token-sdk/src/instruction/transfer.rs index ff9f14ce4e..9f38832bde 100644 --- a/zk-token-sdk/src/instruction/transfer.rs +++ b/zk-token-sdk/src/instruction/transfer.rs @@ -6,7 +6,7 @@ use { use { crate::{ encryption::{ - elgamal::{ElGamalCT, ElGamalPK, ElGamalSK}, + elgamal::{ElGamalCiphertext, ElGamalPubkey, ElGamalSK}, pedersen::{Pedersen, PedersenBase, PedersenComm, PedersenDecHandle, PedersenOpen}, }, errors::ProofError, @@ -36,11 +36,11 @@ impl TransferData { pub fn new( transfer_amount: u64, spendable_balance: u64, - spendable_ct: ElGamalCT, - source_pk: ElGamalPK, + spendable_ct: ElGamalCiphertext, + source_pk: ElGamalPubkey, source_sk: &ElGamalSK, - dest_pk: ElGamalPK, - auditor_pk: ElGamalPK, + dest_pk: ElGamalPubkey, + auditor_pk: ElGamalPubkey, ) -> Self { // split and encrypt transfer amount // @@ -94,7 +94,7 @@ impl TransferData { let new_spendable_handle = spendable_handle - combine_u32_handles(handle_source_lo, handle_source_hi); - let new_spendable_ct = ElGamalCT { + let new_spendable_ct = ElGamalCiphertext { message_comm: new_spendable_comm, decrypt_handle: new_spendable_handle, }; @@ -185,7 +185,7 @@ pub struct TransferValidityProofData { pub transfer_public_keys: TransferPubKeys, // 96 bytes /// The final spendable ciphertext after the transfer - pub new_spendable_ct: pod::ElGamalCT, // 64 bytes + pub new_spendable_ct: pod::ElGamalCiphertext, // 64 bytes /// Proof that certifies that the decryption handles are generated correctly pub proof: ValidityProof, // 160 bytes @@ -235,14 +235,14 @@ impl TransferProofs { #[allow(clippy::many_single_char_names)] pub fn new( source_sk: &ElGamalSK, - source_pk: &ElGamalPK, - dest_pk: &ElGamalPK, - auditor_pk: &ElGamalPK, + source_pk: &ElGamalPubkey, + dest_pk: &ElGamalPubkey, + auditor_pk: &ElGamalPubkey, transfer_amt: (u64, u64), lo_open: &PedersenOpen, hi_open: &PedersenOpen, new_spendable_balance: u64, - new_spendable_ct: &ElGamalCT, + new_spendable_ct: &ElGamalCiphertext, ) -> (Self, TransferEphemeralState) { // TODO: should also commit to pubkeys and commitments later let mut transcript_validity_proof = merlin::Transcript::new(b"TransferValidityProof"); @@ -347,7 +347,7 @@ pub struct ValidityProof { impl ValidityProof { pub fn verify( self, - new_spendable_ct: &ElGamalCT, + new_spendable_ct: &ElGamalCiphertext, decryption_handles_lo: &TransferHandles, decryption_handles_hi: &TransferHandles, transfer_public_keys: &TransferPubKeys, @@ -355,9 +355,9 @@ impl ValidityProof { ) -> Result<(), ProofError> { let mut transcript = Transcript::new(b"TransferValidityProof"); - let source_pk: ElGamalPK = transfer_public_keys.source_pk.try_into()?; - let dest_pk: ElGamalPK = transfer_public_keys.dest_pk.try_into()?; - let auditor_pk: ElGamalPK = transfer_public_keys.auditor_pk.try_into()?; + let source_pk: ElGamalPubkey = transfer_public_keys.source_pk.try_into()?; + let dest_pk: ElGamalPubkey = transfer_public_keys.dest_pk.try_into()?; + let auditor_pk: ElGamalPubkey = transfer_public_keys.auditor_pk.try_into()?; // verify Pedersen commitment in the ephemeral state let C_ephemeral: CompressedRistretto = ephemeral_state.spendable_comm_verification.into(); @@ -455,9 +455,9 @@ impl ValidityProof { #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct TransferPubKeys { - pub source_pk: pod::ElGamalPK, // 32 bytes - pub dest_pk: pod::ElGamalPK, // 32 bytes - pub auditor_pk: pod::ElGamalPK, // 32 bytes + pub source_pk: pod::ElGamalPubkey, // 32 bytes + pub dest_pk: pod::ElGamalPubkey, // 32 bytes + pub auditor_pk: pod::ElGamalPubkey, // 32 bytes } /// The transfer amount commitments needed for a transfer @@ -504,7 +504,7 @@ pub fn combine_u32_handles( } /* -pub fn combine_u32_ciphertexts(ct_lo: ElGamalCT, ct_hi: ElGamalCT) -> ElGamalCT { +pub fn combine_u32_ciphertexts(ct_lo: ElGamalCiphertext, ct_hi: ElGamalCiphertext) -> ElGamalCiphertext { ct_lo + ct_hi * Scalar::from(TWO_32) } */ diff --git a/zk-token-sdk/src/instruction/update_account_pk.rs b/zk-token-sdk/src/instruction/update_account_pk.rs index 90ade71ba2..6b5e5b7e1e 100644 --- a/zk-token-sdk/src/instruction/update_account_pk.rs +++ b/zk-token-sdk/src/instruction/update_account_pk.rs @@ -6,7 +6,7 @@ use { use { crate::{ encryption::{ - elgamal::{ElGamalCT, ElGamalPK, ElGamalSK}, + elgamal::{ElGamalCiphertext, ElGamalPubkey, ElGamalSK}, pedersen::PedersenBase, }, errors::ProofError, @@ -34,16 +34,16 @@ use { #[repr(C)] pub struct UpdateAccountPkData { /// Current ElGamal encryption key - pub current_pk: pod::ElGamalPK, // 32 bytes + pub current_pk: pod::ElGamalPubkey, // 32 bytes /// Current encrypted available balance - pub current_ct: pod::ElGamalCT, // 64 bytes + pub current_ct: pod::ElGamalCiphertext, // 64 bytes /// New ElGamal encryption key - pub new_pk: pod::ElGamalPK, // 32 bytes + pub new_pk: pod::ElGamalPubkey, // 32 bytes /// New encrypted available balance - pub new_ct: pod::ElGamalCT, // 64 bytes + pub new_ct: pod::ElGamalCiphertext, // 64 bytes /// Proof that the current and new ciphertexts are consistent pub proof: UpdateAccountPkProof, // 160 bytes @@ -53,10 +53,10 @@ impl UpdateAccountPkData { #[cfg(not(target_arch = "bpf"))] pub fn new( current_balance: u64, - current_ct: ElGamalCT, - current_pk: ElGamalPK, + current_ct: ElGamalCiphertext, + current_pk: ElGamalPubkey, current_sk: &ElGamalSK, - new_pk: ElGamalPK, + new_pk: ElGamalPubkey, new_sk: &ElGamalSK, ) -> Self { let new_ct = new_pk.encrypt(current_balance); @@ -107,8 +107,8 @@ impl UpdateAccountPkProof { current_balance: u64, current_sk: &ElGamalSK, new_sk: &ElGamalSK, - current_ct: &ElGamalCT, - new_ct: &ElGamalCT, + current_ct: &ElGamalCiphertext, + new_ct: &ElGamalCiphertext, ) -> Self { let mut transcript = Self::transcript_new(); @@ -153,7 +153,11 @@ impl UpdateAccountPkProof { } } - fn verify(&self, current_ct: &ElGamalCT, new_ct: &ElGamalCT) -> Result<(), ProofError> { + fn verify( + &self, + current_ct: &ElGamalCiphertext, + new_ct: &ElGamalCiphertext, + ) -> Result<(), ProofError> { let mut transcript = Self::transcript_new(); // add a domain separator to record the start of the protocol @@ -233,8 +237,9 @@ mod test { // A zeroed cipehrtext should be considered as an account balance of 0 let balance: u64 = 0; - let zeroed_ct_as_current_ct: ElGamalCT = pod::ElGamalCT::zeroed().try_into().unwrap(); - let new_ct: ElGamalCT = new_pk.encrypt(balance); + let zeroed_ct_as_current_ct: ElGamalCiphertext = + pod::ElGamalCiphertext::zeroed().try_into().unwrap(); + let new_ct: ElGamalCiphertext = new_pk.encrypt(balance); let proof = UpdateAccountPkProof::new( balance, ¤t_sk, @@ -244,8 +249,9 @@ mod test { ); assert!(proof.verify(&zeroed_ct_as_current_ct, &new_ct).is_ok()); - let current_ct: ElGamalCT = pod::ElGamalCT::zeroed().try_into().unwrap(); - let zeroed_ct_as_new_ct: ElGamalCT = pod::ElGamalCT::zeroed().try_into().unwrap(); + let current_ct: ElGamalCiphertext = pod::ElGamalCiphertext::zeroed().try_into().unwrap(); + let zeroed_ct_as_new_ct: ElGamalCiphertext = + pod::ElGamalCiphertext::zeroed().try_into().unwrap(); let proof = UpdateAccountPkProof::new( balance, ¤t_sk, @@ -255,8 +261,10 @@ mod test { ); assert!(proof.verify(¤t_ct, &zeroed_ct_as_new_ct).is_ok()); - let zeroed_ct_as_current_ct: ElGamalCT = pod::ElGamalCT::zeroed().try_into().unwrap(); - let zeroed_ct_as_new_ct: ElGamalCT = pod::ElGamalCT::zeroed().try_into().unwrap(); + let zeroed_ct_as_current_ct: ElGamalCiphertext = + pod::ElGamalCiphertext::zeroed().try_into().unwrap(); + let zeroed_ct_as_new_ct: ElGamalCiphertext = + pod::ElGamalCiphertext::zeroed().try_into().unwrap(); let proof = UpdateAccountPkProof::new( balance, ¤t_sk, diff --git a/zk-token-sdk/src/instruction/withdraw.rs b/zk-token-sdk/src/instruction/withdraw.rs index 76ebb39b5b..b5cf979cf6 100644 --- a/zk-token-sdk/src/instruction/withdraw.rs +++ b/zk-token-sdk/src/instruction/withdraw.rs @@ -6,7 +6,7 @@ use { use { crate::{ encryption::{ - elgamal::{ElGamalCT, ElGamalPK, ElGamalSK}, + elgamal::{ElGamalCiphertext, ElGamalPubkey, ElGamalSK}, pedersen::{PedersenBase, PedersenOpen}, }, errors::ProofError, @@ -32,7 +32,7 @@ use { pub struct WithdrawData { /// The source account available balance *after* the withdraw (encrypted by /// `source_pk` - pub final_balance_ct: pod::ElGamalCT, // 64 bytes + pub final_balance_ct: pod::ElGamalCiphertext, // 64 bytes /// Proof that the account is solvent pub proof: WithdrawProof, // 736 bytes @@ -42,10 +42,10 @@ impl WithdrawData { #[cfg(not(target_arch = "bpf"))] pub fn new( amount: u64, - source_pk: ElGamalPK, + source_pk: ElGamalPubkey, source_sk: &ElGamalSK, current_balance: u64, - current_balance_ct: ElGamalCT, + current_balance_ct: ElGamalCiphertext, ) -> Self { // subtract withdraw amount from current balance // @@ -95,7 +95,11 @@ impl WithdrawProof { Transcript::new(b"WithdrawProof") } - pub fn new(source_sk: &ElGamalSK, final_balance: u64, final_balance_ct: &ElGamalCT) -> Self { + pub fn new( + source_sk: &ElGamalSK, + final_balance: u64, + final_balance_ct: &ElGamalCiphertext, + ) -> Self { let mut transcript = Self::transcript_new(); // add a domain separator to record the start of the protocol @@ -138,7 +142,7 @@ impl WithdrawProof { } } - pub fn verify(&self, final_balance_ct: &ElGamalCT) -> Result<(), ProofError> { + pub fn verify(&self, final_balance_ct: &ElGamalCiphertext) -> Result<(), ProofError> { let mut transcript = Self::transcript_new(); // Add a domain separator to record the start of the protocol diff --git a/zk-token-sdk/src/zk_token_elgamal/convert.rs b/zk-token-sdk/src/zk_token_elgamal/convert.rs index 39315ee2a6..4f16cf3a17 100644 --- a/zk-token-sdk/src/zk_token_elgamal/convert.rs +++ b/zk-token-sdk/src/zk_token_elgamal/convert.rs @@ -1,12 +1,12 @@ use super::pod; pub use target_arch::*; -impl From<(pod::PedersenComm, pod::PedersenDecHandle)> for pod::ElGamalCT { +impl From<(pod::PedersenComm, pod::PedersenDecHandle)> for pod::ElGamalCiphertext { fn from((comm, decrypt_handle): (pod::PedersenComm, pod::PedersenDecHandle)) -> Self { let mut buf = [0_u8; 64]; buf[..32].copy_from_slice(&comm.0); buf[32..].copy_from_slice(&decrypt_handle.0); - pod::ElGamalCT(buf) + pod::ElGamalCiphertext(buf) } } @@ -15,7 +15,7 @@ mod target_arch { use { super::pod, crate::{ - encryption::elgamal::{ElGamalCT, ElGamalPK}, + encryption::elgamal::{ElGamalCiphertext, ElGamalPubkey}, encryption::pedersen::{PedersenComm, PedersenDecHandle}, errors::ProofError, range_proof::RangeProof, @@ -36,41 +36,41 @@ mod target_arch { } } - impl From for pod::ElGamalCT { - fn from(ct: ElGamalCT) -> Self { + impl From for pod::ElGamalCiphertext { + fn from(ct: ElGamalCiphertext) -> Self { Self(ct.to_bytes()) } } - impl TryFrom for ElGamalCT { + impl TryFrom for ElGamalCiphertext { type Error = ProofError; - fn try_from(ct: pod::ElGamalCT) -> Result { + fn try_from(ct: pod::ElGamalCiphertext) -> Result { Self::from_bytes(&ct.0).ok_or(ProofError::InconsistentCTData) } } - impl fmt::Debug for pod::ElGamalCT { + impl fmt::Debug for pod::ElGamalCiphertext { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self.0) } } - impl From for pod::ElGamalPK { - fn from(pk: ElGamalPK) -> Self { + impl From for pod::ElGamalPubkey { + fn from(pk: ElGamalPubkey) -> Self { Self(pk.to_bytes()) } } - impl TryFrom for ElGamalPK { + impl TryFrom for ElGamalPubkey { type Error = ProofError; - fn try_from(pk: pod::ElGamalPK) -> Result { + fn try_from(pk: pod::ElGamalPubkey) -> Result { Self::from_bytes(&pk.0).ok_or(ProofError::InconsistentCTData) } } - impl fmt::Debug for pod::ElGamalPK { + impl fmt::Debug for pod::ElGamalPubkey { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self.0) } diff --git a/zk-token-sdk/src/zk_token_elgamal/ops.rs b/zk-token-sdk/src/zk_token_elgamal/ops.rs index 2bb6aa6d00..d05d078142 100644 --- a/zk-token-sdk/src/zk_token_elgamal/ops.rs +++ b/zk-token-sdk/src/zk_token_elgamal/ops.rs @@ -3,7 +3,7 @@ pub use target_arch::*; #[cfg(not(target_arch = "bpf"))] mod target_arch { use { - crate::{encryption::elgamal::ElGamalCT, zk_token_elgamal::pod}, + crate::{encryption::elgamal::ElGamalCiphertext, zk_token_elgamal::pod}, curve25519_dalek::{constants::RISTRETTO_BASEPOINT_COMPRESSED, scalar::Scalar}, std::convert::TryInto, }; @@ -13,69 +13,78 @@ mod target_arch { // returns `Some(x0*ct0 + x1*ct1)` or `None` if the input was invalid fn add_ciphertexts( scalar_0: Scalar, - ct_0: pod::ElGamalCT, + ct_0: pod::ElGamalCiphertext, scalar_1: Scalar, - ct_1: pod::ElGamalCT, - ) -> Option { - let ct_0: ElGamalCT = ct_0.try_into().ok()?; - let ct_1: ElGamalCT = ct_1.try_into().ok()?; + ct_1: pod::ElGamalCiphertext, + ) -> Option { + let ct_0: ElGamalCiphertext = ct_0.try_into().ok()?; + let ct_1: ElGamalCiphertext = ct_1.try_into().ok()?; let ct_sum = ct_0 * scalar_0 + ct_1 * scalar_1; - Some(pod::ElGamalCT::from(ct_sum)) + Some(pod::ElGamalCiphertext::from(ct_sum)) } pub(crate) fn combine_lo_hi( - ct_lo: pod::ElGamalCT, - ct_hi: pod::ElGamalCT, - ) -> Option { + ct_lo: pod::ElGamalCiphertext, + ct_hi: pod::ElGamalCiphertext, + ) -> Option { add_ciphertexts(Scalar::one(), ct_lo, Scalar::from(TWO_32), ct_hi) } - pub fn add(ct_0: pod::ElGamalCT, ct_1: pod::ElGamalCT) -> Option { + pub fn add( + ct_0: pod::ElGamalCiphertext, + ct_1: pod::ElGamalCiphertext, + ) -> Option { add_ciphertexts(Scalar::one(), ct_0, Scalar::one(), ct_1) } pub fn add_with_lo_hi( - ct_0: pod::ElGamalCT, - ct_1_lo: pod::ElGamalCT, - ct_1_hi: pod::ElGamalCT, - ) -> Option { + ct_0: pod::ElGamalCiphertext, + ct_1_lo: pod::ElGamalCiphertext, + ct_1_hi: pod::ElGamalCiphertext, + ) -> Option { let ct_1 = combine_lo_hi(ct_1_lo, ct_1_hi)?; add_ciphertexts(Scalar::one(), ct_0, Scalar::one(), ct_1) } - pub fn subtract(ct_0: pod::ElGamalCT, ct_1: pod::ElGamalCT) -> Option { + pub fn subtract( + ct_0: pod::ElGamalCiphertext, + ct_1: pod::ElGamalCiphertext, + ) -> Option { add_ciphertexts(Scalar::one(), ct_0, -Scalar::one(), ct_1) } pub fn subtract_with_lo_hi( - ct_0: pod::ElGamalCT, - ct_1_lo: pod::ElGamalCT, - ct_1_hi: pod::ElGamalCT, - ) -> Option { + ct_0: pod::ElGamalCiphertext, + ct_1_lo: pod::ElGamalCiphertext, + ct_1_hi: pod::ElGamalCiphertext, + ) -> Option { let ct_1 = combine_lo_hi(ct_1_lo, ct_1_hi)?; add_ciphertexts(Scalar::one(), ct_0, -Scalar::one(), ct_1) } - pub fn add_to(ct: pod::ElGamalCT, amount: u64) -> Option { + pub fn add_to(ct: pod::ElGamalCiphertext, amount: u64) -> Option { let mut amount_as_ct = [0_u8; 64]; amount_as_ct[..32].copy_from_slice(RISTRETTO_BASEPOINT_COMPRESSED.as_bytes()); add_ciphertexts( Scalar::one(), ct, Scalar::from(amount), - pod::ElGamalCT(amount_as_ct), + pod::ElGamalCiphertext(amount_as_ct), ) } - pub fn subtract_from(ct: pod::ElGamalCT, amount: u64) -> Option { + pub fn subtract_from( + ct: pod::ElGamalCiphertext, + amount: u64, + ) -> Option { let mut amount_as_ct = [0_u8; 64]; amount_as_ct[..32].copy_from_slice(RISTRETTO_BASEPOINT_COMPRESSED.as_bytes()); add_ciphertexts( Scalar::one(), ct, -Scalar::from(amount), - pod::ElGamalCT(amount_as_ct), + pod::ElGamalCiphertext(amount_as_ct), ) } } @@ -85,35 +94,44 @@ mod target_arch { mod target_arch { use crate::zk_token_elgamal::pod; - pub fn add(ct_0: pod::ElGamalCT, ct_1: pod::ElGamalCT) -> Option { + pub fn add( + ct_0: pod::ElGamalCiphertext, + ct_1: pod::ElGamalCiphertext, + ) -> Option { None } pub fn add_with_lo_hi( - ct_0: pod::ElGamalCT, - ct_1_lo: pod::ElGamalCT, - ct_1_hi: pod::ElGamalCT, - ) -> Option { + ct_0: pod::ElGamalCiphertext, + ct_1_lo: pod::ElGamalCiphertext, + ct_1_hi: pod::ElGamalCiphertext, + ) -> Option { None } - pub fn subtract(ct_0: pod::ElGamalCT, ct_1: pod::ElGamalCT) -> Option { + pub fn subtract( + ct_0: pod::ElGamalCiphertext, + ct_1: pod::ElGamalCiphertext, + ) -> Option { None } pub fn subtract_with_lo_hi( - ct_0: pod::ElGamalCT, - ct_1_lo: pod::ElGamalCT, - ct_1_hi: pod::ElGamalCT, - ) -> Option { + ct_0: pod::ElGamalCiphertext, + ct_1_lo: pod::ElGamalCiphertext, + ct_1_hi: pod::ElGamalCiphertext, + ) -> Option { None } - pub fn add_to(ct: pod::ElGamalCT, amount: u64) -> Option { + pub fn add_to(ct: pod::ElGamalCiphertext, amount: u64) -> Option { None } - pub fn subtract_from(ct: pod::ElGamalCT, amount: u64) -> Option { + pub fn subtract_from( + ct: pod::ElGamalCiphertext, + amount: u64, + ) -> Option { None } } @@ -123,7 +141,7 @@ mod tests { use { crate::{ encryption::{ - elgamal::{ElGamal, ElGamalCT}, + elgamal::{ElGamal, ElGamalCiphertext}, pedersen::{Pedersen, PedersenOpen}, }, zk_token_elgamal::{ops, pod}, @@ -136,8 +154,8 @@ mod tests { #[test] fn test_zero_ct() { - let spendable_balance = pod::ElGamalCT::zeroed(); - let spendable_ct: ElGamalCT = spendable_balance.try_into().unwrap(); + let spendable_balance = pod::ElGamalCiphertext::zeroed(); + let spendable_ct: ElGamalCiphertext = spendable_balance.try_into().unwrap(); // spendable_ct should be an encryption of 0 for any public key when // `PedersenOpen::default()` is used @@ -151,22 +169,23 @@ mod tests { // homomorphism should work like any other ciphertext let open = PedersenOpen::random(&mut OsRng); let transfer_amount_ct = pk.encrypt_with(55_u64, &open); - let transfer_amount_pod: pod::ElGamalCT = transfer_amount_ct.into(); + let transfer_amount_pod: pod::ElGamalCiphertext = transfer_amount_ct.into(); let sum = ops::add(spendable_balance, transfer_amount_pod).unwrap(); - let expected: pod::ElGamalCT = pk.encrypt_with(55_u64, &open).into(); + let expected: pod::ElGamalCiphertext = pk.encrypt_with(55_u64, &open).into(); assert_eq!(expected, sum); } #[test] fn test_add_to() { - let spendable_balance = pod::ElGamalCT::zeroed(); + let spendable_balance = pod::ElGamalCiphertext::zeroed(); let added_ct = ops::add_to(spendable_balance, 55).unwrap(); let (pk, _) = ElGamal::keygen(); - let expected: pod::ElGamalCT = pk.encrypt_with(55_u64, &PedersenOpen::default()).into(); + let expected: pod::ElGamalCiphertext = + pk.encrypt_with(55_u64, &PedersenOpen::default()).into(); assert_eq!(expected, added_ct); } @@ -176,11 +195,11 @@ mod tests { let amount = 77_u64; let (pk, _) = ElGamal::keygen(); let open = PedersenOpen::random(&mut OsRng); - let encrypted_amount: pod::ElGamalCT = pk.encrypt_with(amount, &open).into(); + let encrypted_amount: pod::ElGamalCiphertext = pk.encrypt_with(amount, &open).into(); let subtracted_ct = ops::subtract_from(encrypted_amount, 55).unwrap(); - let expected: pod::ElGamalCT = pk.encrypt_with(22_u64, &open).into(); + let expected: pod::ElGamalCiphertext = pk.encrypt_with(22_u64, &open).into(); assert_eq!(expected, subtracted_ct); } @@ -228,15 +247,16 @@ mod tests { let source_open = PedersenOpen::random(&mut OsRng); let dest_open = PedersenOpen::random(&mut OsRng); - let source_spendable_ct: pod::ElGamalCT = + let source_spendable_ct: pod::ElGamalCiphertext = source_pk.encrypt_with(77_u64, &source_open).into(); - let dest_pending_ct: pod::ElGamalCT = dest_pk.encrypt_with(77_u64, &dest_open).into(); + let dest_pending_ct: pod::ElGamalCiphertext = + dest_pk.encrypt_with(77_u64, &dest_open).into(); // program arithmetic for the source account // 1. Combine commitments and handles - let source_lo_ct: pod::ElGamalCT = (comm_lo, handle_source_lo).into(); - let source_hi_ct: pod::ElGamalCT = (comm_hi, handle_source_hi).into(); + let source_lo_ct: pod::ElGamalCiphertext = (comm_lo, handle_source_lo).into(); + let source_hi_ct: pod::ElGamalCiphertext = (comm_hi, handle_source_hi).into(); // 2. Combine lo and hi ciphertexts let source_combined_ct = ops::combine_lo_hi(source_lo_ct, source_hi_ct).unwrap(); @@ -248,15 +268,15 @@ mod tests { // test let final_source_open = source_open - (open_lo.clone() + open_hi.clone() * Scalar::from(ops::TWO_32)); - let expected_source: pod::ElGamalCT = + let expected_source: pod::ElGamalCiphertext = source_pk.encrypt_with(22_u64, &final_source_open).into(); assert_eq!(expected_source, final_source_spendable); // same for the destination account // 1. Combine commitments and handles - let dest_lo_ct: pod::ElGamalCT = (comm_lo, handle_dest_lo).into(); - let dest_hi_ct: pod::ElGamalCT = (comm_hi, handle_dest_hi).into(); + let dest_lo_ct: pod::ElGamalCiphertext = (comm_lo, handle_dest_lo).into(); + let dest_hi_ct: pod::ElGamalCiphertext = (comm_hi, handle_dest_hi).into(); // 2. Combine lo and hi ciphertexts let dest_combined_ct = ops::combine_lo_hi(dest_lo_ct, dest_hi_ct).unwrap(); @@ -265,7 +285,7 @@ mod tests { let final_dest_pending = ops::add(dest_pending_ct, dest_combined_ct).unwrap(); let final_dest_open = dest_open + (open_lo + open_hi * Scalar::from(ops::TWO_32)); - let expected_dest_ct: pod::ElGamalCT = + let expected_dest_ct: pod::ElGamalCiphertext = dest_pk.encrypt_with(132_u64, &final_dest_open).into(); assert_eq!(expected_dest_ct, final_dest_pending); } diff --git a/zk-token-sdk/src/zk_token_elgamal/pod.rs b/zk-token-sdk/src/zk_token_elgamal/pod.rs index aa26f7fe31..12c65ee7cb 100644 --- a/zk-token-sdk/src/zk_token_elgamal/pod.rs +++ b/zk-token-sdk/src/zk_token_elgamal/pod.rs @@ -10,11 +10,11 @@ pub struct CompressedRistretto(pub [u8; 32]); #[derive(Clone, Copy, Pod, Zeroable, PartialEq)] #[repr(transparent)] -pub struct ElGamalCT(pub [u8; 64]); +pub struct ElGamalCiphertext(pub [u8; 64]); #[derive(Clone, Copy, Pod, Zeroable, PartialEq)] #[repr(transparent)] -pub struct ElGamalPK(pub [u8; 32]); +pub struct ElGamalPubkey(pub [u8; 32]); #[derive(Clone, Copy, Pod, Zeroable, PartialEq)] #[repr(transparent)]