Rename ElGamalCT to ElGamalCiphertext, ElGamalPK to ElGamalPubkey

This commit is contained in:
Michael Vines 2021-09-30 11:11:53 -07:00
parent f3e7e62813
commit 78799640ea
10 changed files with 219 additions and 171 deletions

View File

@ -22,7 +22,7 @@ pub struct ElGamal;
impl ElGamal { impl ElGamal {
/// Generates the public and secret keys for ElGamal encryption. /// Generates the public and secret keys for ElGamal encryption.
#[cfg(not(target_arch = "bpf"))] #[cfg(not(target_arch = "bpf"))]
pub fn keygen() -> (ElGamalPK, ElGamalSK) { pub fn keygen() -> (ElGamalPubkey, ElGamalSK) {
ElGamal::keygen_with(&mut OsRng) // using OsRng for now ElGamal::keygen_with(&mut OsRng) // using OsRng for now
} }
@ -30,7 +30,7 @@ impl ElGamal {
/// secret keys for ElGamal encryption. /// secret keys for ElGamal encryption.
#[cfg(not(target_arch = "bpf"))] #[cfg(not(target_arch = "bpf"))]
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub fn keygen_with<T: RngCore + CryptoRng>(rng: &mut T) -> (ElGamalPK, ElGamalSK) { pub fn keygen_with<T: RngCore + CryptoRng>(rng: &mut T) -> (ElGamalPubkey, ElGamalSK) {
// sample a non-zero scalar // sample a non-zero scalar
let mut s: Scalar; let mut s: Scalar;
loop { loop {
@ -44,17 +44,17 @@ impl ElGamal {
let H = PedersenBase::default().H; let H = PedersenBase::default().H;
let P = s.invert() * 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 /// On input a public key and a message to be encrypted, the function
/// returns an ElGamal ciphertext of the message under the public key. /// returns an ElGamal ciphertext of the message under the public key.
#[cfg(not(target_arch = "bpf"))] #[cfg(not(target_arch = "bpf"))]
pub fn encrypt<T: Into<Scalar>>(pk: &ElGamalPK, amount: T) -> ElGamalCT { pub fn encrypt<T: Into<Scalar>>(pk: &ElGamalPubkey, amount: T) -> ElGamalCiphertext {
let (message_comm, open) = Pedersen::commit(amount); let (message_comm, open) = Pedersen::commit(amount);
let decrypt_handle = pk.gen_decrypt_handle(&open); let decrypt_handle = pk.gen_decrypt_handle(&open);
ElGamalCT { ElGamalCiphertext {
message_comm, message_comm,
decrypt_handle, decrypt_handle,
} }
@ -64,14 +64,14 @@ impl ElGamal {
/// returns an ElGamal ciphertext of the message under the public key using /// returns an ElGamal ciphertext of the message under the public key using
/// the opening. /// the opening.
pub fn encrypt_with<T: Into<Scalar>>( pub fn encrypt_with<T: Into<Scalar>>(
pk: &ElGamalPK, pk: &ElGamalPubkey,
amount: T, amount: T,
open: &PedersenOpen, open: &PedersenOpen,
) -> ElGamalCT { ) -> ElGamalCiphertext {
let message_comm = Pedersen::commit_with(amount, open); let message_comm = Pedersen::commit_with(amount, open);
let decrypt_handle = pk.gen_decrypt_handle(open); let decrypt_handle = pk.gen_decrypt_handle(open);
ElGamalCT { ElGamalCiphertext {
message_comm, message_comm,
decrypt_handle, decrypt_handle,
} }
@ -81,9 +81,9 @@ impl ElGamal {
/// ///
/// The output of the function is of type `DiscreteLogInstance`. The exact message /// The output of the function is of type `DiscreteLogInstance`. The exact message
/// can be recovered via the DiscreteLogInstance's decode method. /// 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 ElGamalSK(s) = sk;
let ElGamalCT { let ElGamalCiphertext {
message_comm, message_comm,
decrypt_handle, decrypt_handle,
} = ct; } = ct;
@ -96,7 +96,7 @@ impl ElGamal {
/// On input a secret key and a ciphertext, the function decrypts the /// On input a secret key and a ciphertext, the function decrypts the
/// ciphertext for a u32 value. /// ciphertext for a u32 value.
pub fn decrypt_u32(sk: &ElGamalSK, ct: &ElGamalCT) -> Option<u32> { pub fn decrypt_u32(sk: &ElGamalSK, ct: &ElGamalCiphertext) -> Option<u32> {
let discrete_log_instance = ElGamal::decrypt(sk, ct); let discrete_log_instance = ElGamal::decrypt(sk, ct);
discrete_log_instance.decode_u32() discrete_log_instance.decode_u32()
} }
@ -104,8 +104,8 @@ impl ElGamal {
/// Public key for the ElGamal encryption scheme. /// Public key for the ElGamal encryption scheme.
#[derive(Serialize, Deserialize, Default, Clone, Copy, Debug, Eq, PartialEq)] #[derive(Serialize, Deserialize, Default, Clone, Copy, Debug, Eq, PartialEq)]
pub struct ElGamalPK(RistrettoPoint); pub struct ElGamalPubkey(RistrettoPoint);
impl ElGamalPK { impl ElGamalPubkey {
pub fn get_point(&self) -> RistrettoPoint { pub fn get_point(&self) -> RistrettoPoint {
self.0 self.0
} }
@ -115,20 +115,20 @@ impl ElGamalPK {
self.0.compress().to_bytes() self.0.compress().to_bytes()
} }
pub fn from_bytes(bytes: &[u8]) -> Option<ElGamalPK> { pub fn from_bytes(bytes: &[u8]) -> Option<ElGamalPubkey> {
Some(ElGamalPK( Some(ElGamalPubkey(
CompressedRistretto::from_slice(bytes).decompress()?, CompressedRistretto::from_slice(bytes).decompress()?,
)) ))
} }
/// Utility method for code ergonomics. /// Utility method for code ergonomics.
#[cfg(not(target_arch = "bpf"))] #[cfg(not(target_arch = "bpf"))]
pub fn encrypt<T: Into<Scalar>>(&self, msg: T) -> ElGamalCT { pub fn encrypt<T: Into<Scalar>>(&self, msg: T) -> ElGamalCiphertext {
ElGamal::encrypt(self, msg) ElGamal::encrypt(self, msg)
} }
/// Utility method for code ergonomics. /// Utility method for code ergonomics.
pub fn encrypt_with<T: Into<Scalar>>(&self, msg: T, open: &PedersenOpen) -> ElGamalCT { pub fn encrypt_with<T: Into<Scalar>>(&self, msg: T, open: &PedersenOpen) -> ElGamalCiphertext {
ElGamal::encrypt_with(self, msg, open) ElGamal::encrypt_with(self, msg, open)
} }
@ -139,9 +139,9 @@ impl ElGamalPK {
} }
} }
impl From<RistrettoPoint> for ElGamalPK { impl From<RistrettoPoint> for ElGamalPubkey {
fn from(point: RistrettoPoint) -> ElGamalPK { fn from(point: RistrettoPoint) -> ElGamalPubkey {
ElGamalPK(point) ElGamalPubkey(point)
} }
} }
@ -155,12 +155,12 @@ impl ElGamalSK {
} }
/// Utility method for code ergonomics. /// Utility method for code ergonomics.
pub fn decrypt(&self, ct: &ElGamalCT) -> DiscreteLogInstance { pub fn decrypt(&self, ct: &ElGamalCiphertext) -> DiscreteLogInstance {
ElGamal::decrypt(self, ct) ElGamal::decrypt(self, ct)
} }
/// Utility method for code ergonomics. /// Utility method for code ergonomics.
pub fn decrypt_u32(&self, ct: &ElGamalCT) -> Option<u32> { pub fn decrypt_u32(&self, ct: &ElGamalCiphertext) -> Option<u32> {
ElGamal::decrypt_u32(self, ct) ElGamal::decrypt_u32(self, ct)
} }
@ -197,14 +197,14 @@ impl ConstantTimeEq for ElGamalSK {
/// Ciphertext for the ElGamal encryption scheme. /// Ciphertext for the ElGamal encryption scheme.
#[allow(non_snake_case)] #[allow(non_snake_case)]
#[derive(Serialize, Deserialize, Default, Clone, Copy, Debug, Eq, PartialEq)] #[derive(Serialize, Deserialize, Default, Clone, Copy, Debug, Eq, PartialEq)]
pub struct ElGamalCT { pub struct ElGamalCiphertext {
pub message_comm: PedersenComm, pub message_comm: PedersenComm,
pub decrypt_handle: PedersenDecHandle, pub decrypt_handle: PedersenDecHandle,
} }
impl ElGamalCT { impl ElGamalCiphertext {
pub fn add_to_msg<T: Into<Scalar>>(&self, message: T) -> Self { pub fn add_to_msg<T: Into<Scalar>>(&self, message: T) -> Self {
let diff_comm = Pedersen::commit_with(message, &PedersenOpen::default()); let diff_comm = Pedersen::commit_with(message, &PedersenOpen::default());
ElGamalCT { ElGamalCiphertext {
message_comm: self.message_comm + diff_comm, message_comm: self.message_comm + diff_comm,
decrypt_handle: self.decrypt_handle, decrypt_handle: self.decrypt_handle,
} }
@ -212,7 +212,7 @@ impl ElGamalCT {
pub fn sub_to_msg<T: Into<Scalar>>(&self, message: T) -> Self { pub fn sub_to_msg<T: Into<Scalar>>(&self, message: T) -> Self {
let diff_comm = Pedersen::commit_with(message, &PedersenOpen::default()); let diff_comm = Pedersen::commit_with(message, &PedersenOpen::default());
ElGamalCT { ElGamalCiphertext {
message_comm: self.message_comm - diff_comm, message_comm: self.message_comm - diff_comm,
decrypt_handle: self.decrypt_handle, decrypt_handle: self.decrypt_handle,
} }
@ -227,14 +227,14 @@ impl ElGamalCT {
bytes bytes
} }
pub fn from_bytes(bytes: &[u8]) -> Option<ElGamalCT> { pub fn from_bytes(bytes: &[u8]) -> Option<ElGamalCiphertext> {
let bytes = array_ref![bytes, 0, 64]; let bytes = array_ref![bytes, 0, 64];
let (message_comm, decrypt_handle) = array_refs![bytes, 32, 32]; let (message_comm, decrypt_handle) = array_refs![bytes, 32, 32];
let message_comm = CompressedRistretto::from_slice(message_comm).decompress()?; let message_comm = CompressedRistretto::from_slice(message_comm).decompress()?;
let decrypt_handle = CompressedRistretto::from_slice(decrypt_handle).decompress()?; let decrypt_handle = CompressedRistretto::from_slice(decrypt_handle).decompress()?;
Some(ElGamalCT { Some(ElGamalCiphertext {
message_comm: PedersenComm(message_comm), message_comm: PedersenComm(message_comm),
decrypt_handle: PedersenDecHandle(decrypt_handle), decrypt_handle: PedersenDecHandle(decrypt_handle),
}) })
@ -251,57 +251,73 @@ impl ElGamalCT {
} }
} }
impl<'a, 'b> Add<&'b ElGamalCT> for &'a ElGamalCT { impl<'a, 'b> Add<&'b ElGamalCiphertext> for &'a ElGamalCiphertext {
type Output = ElGamalCT; type Output = ElGamalCiphertext;
fn add(self, other: &'b ElGamalCT) -> ElGamalCT { fn add(self, other: &'b ElGamalCiphertext) -> ElGamalCiphertext {
ElGamalCT { ElGamalCiphertext {
message_comm: self.message_comm + other.message_comm, message_comm: self.message_comm + other.message_comm,
decrypt_handle: self.decrypt_handle + other.decrypt_handle, 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 { impl<'a, 'b> Sub<&'b ElGamalCiphertext> for &'a ElGamalCiphertext {
type Output = ElGamalCT; type Output = ElGamalCiphertext;
fn sub(self, other: &'b ElGamalCT) -> ElGamalCT { fn sub(self, other: &'b ElGamalCiphertext) -> ElGamalCiphertext {
ElGamalCT { ElGamalCiphertext {
message_comm: self.message_comm - other.message_comm, message_comm: self.message_comm - other.message_comm,
decrypt_handle: self.decrypt_handle - other.decrypt_handle, 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 { impl<'a, 'b> Mul<&'b Scalar> for &'a ElGamalCiphertext {
type Output = ElGamalCT; type Output = ElGamalCiphertext;
fn mul(self, other: &'b Scalar) -> ElGamalCT { fn mul(self, other: &'b Scalar) -> ElGamalCiphertext {
ElGamalCT { ElGamalCiphertext {
message_comm: self.message_comm * other, message_comm: self.message_comm * other,
decrypt_handle: self.decrypt_handle * 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 { impl<'a, 'b> Div<&'b Scalar> for &'a ElGamalCiphertext {
type Output = ElGamalCT; type Output = ElGamalCiphertext;
fn div(self, other: &'b Scalar) -> ElGamalCT { fn div(self, other: &'b Scalar) -> ElGamalCiphertext {
ElGamalCT { ElGamalCiphertext {
message_comm: self.message_comm * other.invert(), message_comm: self.message_comm * other.invert(),
decrypt_handle: self.decrypt_handle * 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)] #[cfg(test)]
mod tests { mod tests {
@ -441,7 +457,7 @@ mod tests {
let ct = pk.encrypt(msg); let ct = pk.encrypt(msg);
let encoded = bincode::serialize(&ct).unwrap(); let encoded = bincode::serialize(&ct).unwrap();
let decoded: ElGamalCT = bincode::deserialize(&encoded).unwrap(); let decoded: ElGamalCiphertext = bincode::deserialize(&encoded).unwrap();
assert_eq!(ct, decoded); assert_eq!(ct, decoded);
} }
@ -451,7 +467,7 @@ mod tests {
let (pk, _) = ElGamal::keygen(); let (pk, _) = ElGamal::keygen();
let encoded = bincode::serialize(&pk).unwrap(); let encoded = bincode::serialize(&pk).unwrap();
let decoded: ElGamalPK = bincode::deserialize(&encoded).unwrap(); let decoded: ElGamalPubkey = bincode::deserialize(&encoded).unwrap();
assert_eq!(pk, decoded); assert_eq!(pk, decoded);
} }

View File

@ -2,7 +2,7 @@
use rand::{rngs::OsRng, CryptoRng, RngCore}; use rand::{rngs::OsRng, CryptoRng, RngCore};
use { use {
crate::{ crate::{
encryption::elgamal::{ElGamalCT, ElGamalPK}, encryption::elgamal::{ElGamalCiphertext, ElGamalPubkey},
errors::ProofError, errors::ProofError,
}, },
core::ops::{Add, Div, Mul, Sub}, core::ops::{Add, Div, Mul, Sub},
@ -271,13 +271,13 @@ impl PedersenDecHandle {
self.0 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()) PedersenDecHandle(open.get_scalar() * pk.get_point())
} }
/// Maps a decryption token and Pedersen commitment to ElGamal ciphertext /// Maps a decryption token and Pedersen commitment to ElGamal ciphertext
pub fn to_elgamal_ctxt(self, comm: PedersenComm) -> ElGamalCT { pub fn to_elgamal_ctxt(self, comm: PedersenComm) -> ElGamalCiphertext {
ElGamalCT { ElGamalCiphertext {
message_comm: comm, message_comm: comm,
decrypt_handle: self, decrypt_handle: self,
} }

View File

@ -14,6 +14,6 @@ pub enum ProofError {
InvalidBitsize, InvalidBitsize,
/// This error occurs when there are insufficient generators for the proof. /// This error occurs when there are insufficient generators for the proof.
InvalidGeneratorsLength, 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, InconsistentCTData,
} }

View File

@ -5,7 +5,7 @@ use {
#[cfg(not(target_arch = "bpf"))] #[cfg(not(target_arch = "bpf"))]
use { use {
crate::{ crate::{
encryption::elgamal::{ElGamalCT, ElGamalSK}, encryption::elgamal::{ElGamalCiphertext, ElGamalSK},
errors::ProofError, errors::ProofError,
instruction::Verifiable, instruction::Verifiable,
transcript::TranscriptProtocol, transcript::TranscriptProtocol,
@ -31,7 +31,7 @@ use {
#[repr(C)] #[repr(C)]
pub struct CloseAccountData { pub struct CloseAccountData {
/// The source account available balance in encrypted form /// 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 /// Proof that the source account available balance is zero
pub proof: CloseAccountProof, // 64 bytes pub proof: CloseAccountProof, // 64 bytes
@ -39,7 +39,7 @@ pub struct CloseAccountData {
#[cfg(not(target_arch = "bpf"))] #[cfg(not(target_arch = "bpf"))]
impl CloseAccountData { 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); let proof = CloseAccountProof::new(source_sk, &balance);
CloseAccountData { CloseAccountData {
@ -74,7 +74,7 @@ impl CloseAccountProof {
Transcript::new(b"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(); let mut transcript = Self::transcript_new();
// add a domain separator to record the start of the protocol // 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(); let mut transcript = Self::transcript_new();
// add a domain separator to record the start of the protocol // add a domain separator to record the start of the protocol
@ -156,7 +156,7 @@ mod test {
assert!(proof.verify(&balance).is_err()); assert!(proof.verify(&balance).is_err());
// A zeroed cyphertext should be considered as an account balance of 0 // 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); let proof = CloseAccountProof::new(&source_sk, &zeroed_ct);
assert!(proof.verify(&zeroed_ct).is_ok()); assert!(proof.verify(&zeroed_ct).is_ok());
} }

View File

@ -6,7 +6,7 @@ use {
use { use {
crate::{ crate::{
encryption::{ encryption::{
elgamal::{ElGamalCT, ElGamalPK, ElGamalSK}, elgamal::{ElGamalCiphertext, ElGamalPubkey, ElGamalSK},
pedersen::{Pedersen, PedersenBase, PedersenComm, PedersenDecHandle, PedersenOpen}, pedersen::{Pedersen, PedersenBase, PedersenComm, PedersenDecHandle, PedersenOpen},
}, },
errors::ProofError, errors::ProofError,
@ -36,11 +36,11 @@ impl TransferData {
pub fn new( pub fn new(
transfer_amount: u64, transfer_amount: u64,
spendable_balance: u64, spendable_balance: u64,
spendable_ct: ElGamalCT, spendable_ct: ElGamalCiphertext,
source_pk: ElGamalPK, source_pk: ElGamalPubkey,
source_sk: &ElGamalSK, source_sk: &ElGamalSK,
dest_pk: ElGamalPK, dest_pk: ElGamalPubkey,
auditor_pk: ElGamalPK, auditor_pk: ElGamalPubkey,
) -> Self { ) -> Self {
// split and encrypt transfer amount // split and encrypt transfer amount
// //
@ -94,7 +94,7 @@ impl TransferData {
let new_spendable_handle = let new_spendable_handle =
spendable_handle - combine_u32_handles(handle_source_lo, handle_source_hi); 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, message_comm: new_spendable_comm,
decrypt_handle: new_spendable_handle, decrypt_handle: new_spendable_handle,
}; };
@ -185,7 +185,7 @@ pub struct TransferValidityProofData {
pub transfer_public_keys: TransferPubKeys, // 96 bytes pub transfer_public_keys: TransferPubKeys, // 96 bytes
/// The final spendable ciphertext after the transfer /// 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 /// Proof that certifies that the decryption handles are generated correctly
pub proof: ValidityProof, // 160 bytes pub proof: ValidityProof, // 160 bytes
@ -235,14 +235,14 @@ impl TransferProofs {
#[allow(clippy::many_single_char_names)] #[allow(clippy::many_single_char_names)]
pub fn new( pub fn new(
source_sk: &ElGamalSK, source_sk: &ElGamalSK,
source_pk: &ElGamalPK, source_pk: &ElGamalPubkey,
dest_pk: &ElGamalPK, dest_pk: &ElGamalPubkey,
auditor_pk: &ElGamalPK, auditor_pk: &ElGamalPubkey,
transfer_amt: (u64, u64), transfer_amt: (u64, u64),
lo_open: &PedersenOpen, lo_open: &PedersenOpen,
hi_open: &PedersenOpen, hi_open: &PedersenOpen,
new_spendable_balance: u64, new_spendable_balance: u64,
new_spendable_ct: &ElGamalCT, new_spendable_ct: &ElGamalCiphertext,
) -> (Self, TransferEphemeralState) { ) -> (Self, TransferEphemeralState) {
// TODO: should also commit to pubkeys and commitments later // TODO: should also commit to pubkeys and commitments later
let mut transcript_validity_proof = merlin::Transcript::new(b"TransferValidityProof"); let mut transcript_validity_proof = merlin::Transcript::new(b"TransferValidityProof");
@ -347,7 +347,7 @@ pub struct ValidityProof {
impl ValidityProof { impl ValidityProof {
pub fn verify( pub fn verify(
self, self,
new_spendable_ct: &ElGamalCT, new_spendable_ct: &ElGamalCiphertext,
decryption_handles_lo: &TransferHandles, decryption_handles_lo: &TransferHandles,
decryption_handles_hi: &TransferHandles, decryption_handles_hi: &TransferHandles,
transfer_public_keys: &TransferPubKeys, transfer_public_keys: &TransferPubKeys,
@ -355,9 +355,9 @@ impl ValidityProof {
) -> Result<(), ProofError> { ) -> Result<(), ProofError> {
let mut transcript = Transcript::new(b"TransferValidityProof"); let mut transcript = Transcript::new(b"TransferValidityProof");
let source_pk: ElGamalPK = transfer_public_keys.source_pk.try_into()?; let source_pk: ElGamalPubkey = transfer_public_keys.source_pk.try_into()?;
let dest_pk: ElGamalPK = transfer_public_keys.dest_pk.try_into()?; let dest_pk: ElGamalPubkey = transfer_public_keys.dest_pk.try_into()?;
let auditor_pk: ElGamalPK = transfer_public_keys.auditor_pk.try_into()?; let auditor_pk: ElGamalPubkey = transfer_public_keys.auditor_pk.try_into()?;
// verify Pedersen commitment in the ephemeral state // verify Pedersen commitment in the ephemeral state
let C_ephemeral: CompressedRistretto = ephemeral_state.spendable_comm_verification.into(); let C_ephemeral: CompressedRistretto = ephemeral_state.spendable_comm_verification.into();
@ -455,9 +455,9 @@ impl ValidityProof {
#[derive(Clone, Copy, Pod, Zeroable)] #[derive(Clone, Copy, Pod, Zeroable)]
#[repr(C)] #[repr(C)]
pub struct TransferPubKeys { pub struct TransferPubKeys {
pub source_pk: pod::ElGamalPK, // 32 bytes pub source_pk: pod::ElGamalPubkey, // 32 bytes
pub dest_pk: pod::ElGamalPK, // 32 bytes pub dest_pk: pod::ElGamalPubkey, // 32 bytes
pub auditor_pk: pod::ElGamalPK, // 32 bytes pub auditor_pk: pod::ElGamalPubkey, // 32 bytes
} }
/// The transfer amount commitments needed for a transfer /// 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) ct_lo + ct_hi * Scalar::from(TWO_32)
} }
*/ */

View File

@ -6,7 +6,7 @@ use {
use { use {
crate::{ crate::{
encryption::{ encryption::{
elgamal::{ElGamalCT, ElGamalPK, ElGamalSK}, elgamal::{ElGamalCiphertext, ElGamalPubkey, ElGamalSK},
pedersen::PedersenBase, pedersen::PedersenBase,
}, },
errors::ProofError, errors::ProofError,
@ -34,16 +34,16 @@ use {
#[repr(C)] #[repr(C)]
pub struct UpdateAccountPkData { pub struct UpdateAccountPkData {
/// Current ElGamal encryption key /// Current ElGamal encryption key
pub current_pk: pod::ElGamalPK, // 32 bytes pub current_pk: pod::ElGamalPubkey, // 32 bytes
/// Current encrypted available balance /// Current encrypted available balance
pub current_ct: pod::ElGamalCT, // 64 bytes pub current_ct: pod::ElGamalCiphertext, // 64 bytes
/// New ElGamal encryption key /// New ElGamal encryption key
pub new_pk: pod::ElGamalPK, // 32 bytes pub new_pk: pod::ElGamalPubkey, // 32 bytes
/// New encrypted available balance /// 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 /// Proof that the current and new ciphertexts are consistent
pub proof: UpdateAccountPkProof, // 160 bytes pub proof: UpdateAccountPkProof, // 160 bytes
@ -53,10 +53,10 @@ impl UpdateAccountPkData {
#[cfg(not(target_arch = "bpf"))] #[cfg(not(target_arch = "bpf"))]
pub fn new( pub fn new(
current_balance: u64, current_balance: u64,
current_ct: ElGamalCT, current_ct: ElGamalCiphertext,
current_pk: ElGamalPK, current_pk: ElGamalPubkey,
current_sk: &ElGamalSK, current_sk: &ElGamalSK,
new_pk: ElGamalPK, new_pk: ElGamalPubkey,
new_sk: &ElGamalSK, new_sk: &ElGamalSK,
) -> Self { ) -> Self {
let new_ct = new_pk.encrypt(current_balance); let new_ct = new_pk.encrypt(current_balance);
@ -107,8 +107,8 @@ impl UpdateAccountPkProof {
current_balance: u64, current_balance: u64,
current_sk: &ElGamalSK, current_sk: &ElGamalSK,
new_sk: &ElGamalSK, new_sk: &ElGamalSK,
current_ct: &ElGamalCT, current_ct: &ElGamalCiphertext,
new_ct: &ElGamalCT, new_ct: &ElGamalCiphertext,
) -> Self { ) -> Self {
let mut transcript = Self::transcript_new(); 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(); let mut transcript = Self::transcript_new();
// add a domain separator to record the start of the protocol // 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 // A zeroed cipehrtext should be considered as an account balance of 0
let balance: u64 = 0; let balance: u64 = 0;
let zeroed_ct_as_current_ct: ElGamalCT = pod::ElGamalCT::zeroed().try_into().unwrap(); let zeroed_ct_as_current_ct: ElGamalCiphertext =
let new_ct: ElGamalCT = new_pk.encrypt(balance); pod::ElGamalCiphertext::zeroed().try_into().unwrap();
let new_ct: ElGamalCiphertext = new_pk.encrypt(balance);
let proof = UpdateAccountPkProof::new( let proof = UpdateAccountPkProof::new(
balance, balance,
&current_sk, &current_sk,
@ -244,8 +249,9 @@ mod test {
); );
assert!(proof.verify(&zeroed_ct_as_current_ct, &new_ct).is_ok()); assert!(proof.verify(&zeroed_ct_as_current_ct, &new_ct).is_ok());
let current_ct: ElGamalCT = pod::ElGamalCT::zeroed().try_into().unwrap(); let current_ct: ElGamalCiphertext = pod::ElGamalCiphertext::zeroed().try_into().unwrap();
let zeroed_ct_as_new_ct: ElGamalCT = pod::ElGamalCT::zeroed().try_into().unwrap(); let zeroed_ct_as_new_ct: ElGamalCiphertext =
pod::ElGamalCiphertext::zeroed().try_into().unwrap();
let proof = UpdateAccountPkProof::new( let proof = UpdateAccountPkProof::new(
balance, balance,
&current_sk, &current_sk,
@ -255,8 +261,10 @@ mod test {
); );
assert!(proof.verify(&current_ct, &zeroed_ct_as_new_ct).is_ok()); assert!(proof.verify(&current_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_current_ct: ElGamalCiphertext =
let zeroed_ct_as_new_ct: ElGamalCT = pod::ElGamalCT::zeroed().try_into().unwrap(); pod::ElGamalCiphertext::zeroed().try_into().unwrap();
let zeroed_ct_as_new_ct: ElGamalCiphertext =
pod::ElGamalCiphertext::zeroed().try_into().unwrap();
let proof = UpdateAccountPkProof::new( let proof = UpdateAccountPkProof::new(
balance, balance,
&current_sk, &current_sk,

View File

@ -6,7 +6,7 @@ use {
use { use {
crate::{ crate::{
encryption::{ encryption::{
elgamal::{ElGamalCT, ElGamalPK, ElGamalSK}, elgamal::{ElGamalCiphertext, ElGamalPubkey, ElGamalSK},
pedersen::{PedersenBase, PedersenOpen}, pedersen::{PedersenBase, PedersenOpen},
}, },
errors::ProofError, errors::ProofError,
@ -32,7 +32,7 @@ use {
pub struct WithdrawData { pub struct WithdrawData {
/// The source account available balance *after* the withdraw (encrypted by /// The source account available balance *after* the withdraw (encrypted by
/// `source_pk` /// `source_pk`
pub final_balance_ct: pod::ElGamalCT, // 64 bytes pub final_balance_ct: pod::ElGamalCiphertext, // 64 bytes
/// Proof that the account is solvent /// Proof that the account is solvent
pub proof: WithdrawProof, // 736 bytes pub proof: WithdrawProof, // 736 bytes
@ -42,10 +42,10 @@ impl WithdrawData {
#[cfg(not(target_arch = "bpf"))] #[cfg(not(target_arch = "bpf"))]
pub fn new( pub fn new(
amount: u64, amount: u64,
source_pk: ElGamalPK, source_pk: ElGamalPubkey,
source_sk: &ElGamalSK, source_sk: &ElGamalSK,
current_balance: u64, current_balance: u64,
current_balance_ct: ElGamalCT, current_balance_ct: ElGamalCiphertext,
) -> Self { ) -> Self {
// subtract withdraw amount from current balance // subtract withdraw amount from current balance
// //
@ -95,7 +95,11 @@ impl WithdrawProof {
Transcript::new(b"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(); let mut transcript = Self::transcript_new();
// add a domain separator to record the start of the protocol // 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(); let mut transcript = Self::transcript_new();
// Add a domain separator to record the start of the protocol // Add a domain separator to record the start of the protocol

View File

@ -1,12 +1,12 @@
use super::pod; use super::pod;
pub use target_arch::*; 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 { fn from((comm, decrypt_handle): (pod::PedersenComm, pod::PedersenDecHandle)) -> Self {
let mut buf = [0_u8; 64]; let mut buf = [0_u8; 64];
buf[..32].copy_from_slice(&comm.0); buf[..32].copy_from_slice(&comm.0);
buf[32..].copy_from_slice(&decrypt_handle.0); buf[32..].copy_from_slice(&decrypt_handle.0);
pod::ElGamalCT(buf) pod::ElGamalCiphertext(buf)
} }
} }
@ -15,7 +15,7 @@ mod target_arch {
use { use {
super::pod, super::pod,
crate::{ crate::{
encryption::elgamal::{ElGamalCT, ElGamalPK}, encryption::elgamal::{ElGamalCiphertext, ElGamalPubkey},
encryption::pedersen::{PedersenComm, PedersenDecHandle}, encryption::pedersen::{PedersenComm, PedersenDecHandle},
errors::ProofError, errors::ProofError,
range_proof::RangeProof, range_proof::RangeProof,
@ -36,41 +36,41 @@ mod target_arch {
} }
} }
impl From<ElGamalCT> for pod::ElGamalCT { impl From<ElGamalCiphertext> for pod::ElGamalCiphertext {
fn from(ct: ElGamalCT) -> Self { fn from(ct: ElGamalCiphertext) -> Self {
Self(ct.to_bytes()) Self(ct.to_bytes())
} }
} }
impl TryFrom<pod::ElGamalCT> for ElGamalCT { impl TryFrom<pod::ElGamalCiphertext> for ElGamalCiphertext {
type Error = ProofError; type Error = ProofError;
fn try_from(ct: pod::ElGamalCT) -> Result<Self, Self::Error> { fn try_from(ct: pod::ElGamalCiphertext) -> Result<Self, Self::Error> {
Self::from_bytes(&ct.0).ok_or(ProofError::InconsistentCTData) 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 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self.0) write!(f, "{:?}", self.0)
} }
} }
impl From<ElGamalPK> for pod::ElGamalPK { impl From<ElGamalPubkey> for pod::ElGamalPubkey {
fn from(pk: ElGamalPK) -> Self { fn from(pk: ElGamalPubkey) -> Self {
Self(pk.to_bytes()) Self(pk.to_bytes())
} }
} }
impl TryFrom<pod::ElGamalPK> for ElGamalPK { impl TryFrom<pod::ElGamalPubkey> for ElGamalPubkey {
type Error = ProofError; type Error = ProofError;
fn try_from(pk: pod::ElGamalPK) -> Result<Self, Self::Error> { fn try_from(pk: pod::ElGamalPubkey) -> Result<Self, Self::Error> {
Self::from_bytes(&pk.0).ok_or(ProofError::InconsistentCTData) 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 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self.0) write!(f, "{:?}", self.0)
} }

View File

@ -3,7 +3,7 @@ pub use target_arch::*;
#[cfg(not(target_arch = "bpf"))] #[cfg(not(target_arch = "bpf"))]
mod target_arch { mod target_arch {
use { 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}, curve25519_dalek::{constants::RISTRETTO_BASEPOINT_COMPRESSED, scalar::Scalar},
std::convert::TryInto, std::convert::TryInto,
}; };
@ -13,69 +13,78 @@ mod target_arch {
// returns `Some(x0*ct0 + x1*ct1)` or `None` if the input was invalid // returns `Some(x0*ct0 + x1*ct1)` or `None` if the input was invalid
fn add_ciphertexts( fn add_ciphertexts(
scalar_0: Scalar, scalar_0: Scalar,
ct_0: pod::ElGamalCT, ct_0: pod::ElGamalCiphertext,
scalar_1: Scalar, scalar_1: Scalar,
ct_1: pod::ElGamalCT, ct_1: pod::ElGamalCiphertext,
) -> Option<pod::ElGamalCT> { ) -> Option<pod::ElGamalCiphertext> {
let ct_0: ElGamalCT = ct_0.try_into().ok()?; let ct_0: ElGamalCiphertext = ct_0.try_into().ok()?;
let ct_1: ElGamalCT = ct_1.try_into().ok()?; let ct_1: ElGamalCiphertext = ct_1.try_into().ok()?;
let ct_sum = ct_0 * scalar_0 + ct_1 * scalar_1; 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( pub(crate) fn combine_lo_hi(
ct_lo: pod::ElGamalCT, ct_lo: pod::ElGamalCiphertext,
ct_hi: pod::ElGamalCT, ct_hi: pod::ElGamalCiphertext,
) -> Option<pod::ElGamalCT> { ) -> Option<pod::ElGamalCiphertext> {
add_ciphertexts(Scalar::one(), ct_lo, Scalar::from(TWO_32), ct_hi) add_ciphertexts(Scalar::one(), ct_lo, Scalar::from(TWO_32), ct_hi)
} }
pub fn add(ct_0: pod::ElGamalCT, ct_1: pod::ElGamalCT) -> Option<pod::ElGamalCT> { pub fn add(
ct_0: pod::ElGamalCiphertext,
ct_1: pod::ElGamalCiphertext,
) -> Option<pod::ElGamalCiphertext> {
add_ciphertexts(Scalar::one(), ct_0, Scalar::one(), ct_1) add_ciphertexts(Scalar::one(), ct_0, Scalar::one(), ct_1)
} }
pub fn add_with_lo_hi( pub fn add_with_lo_hi(
ct_0: pod::ElGamalCT, ct_0: pod::ElGamalCiphertext,
ct_1_lo: pod::ElGamalCT, ct_1_lo: pod::ElGamalCiphertext,
ct_1_hi: pod::ElGamalCT, ct_1_hi: pod::ElGamalCiphertext,
) -> Option<pod::ElGamalCT> { ) -> Option<pod::ElGamalCiphertext> {
let ct_1 = combine_lo_hi(ct_1_lo, ct_1_hi)?; let ct_1 = combine_lo_hi(ct_1_lo, ct_1_hi)?;
add_ciphertexts(Scalar::one(), ct_0, Scalar::one(), ct_1) add_ciphertexts(Scalar::one(), ct_0, Scalar::one(), ct_1)
} }
pub fn subtract(ct_0: pod::ElGamalCT, ct_1: pod::ElGamalCT) -> Option<pod::ElGamalCT> { pub fn subtract(
ct_0: pod::ElGamalCiphertext,
ct_1: pod::ElGamalCiphertext,
) -> Option<pod::ElGamalCiphertext> {
add_ciphertexts(Scalar::one(), ct_0, -Scalar::one(), ct_1) add_ciphertexts(Scalar::one(), ct_0, -Scalar::one(), ct_1)
} }
pub fn subtract_with_lo_hi( pub fn subtract_with_lo_hi(
ct_0: pod::ElGamalCT, ct_0: pod::ElGamalCiphertext,
ct_1_lo: pod::ElGamalCT, ct_1_lo: pod::ElGamalCiphertext,
ct_1_hi: pod::ElGamalCT, ct_1_hi: pod::ElGamalCiphertext,
) -> Option<pod::ElGamalCT> { ) -> Option<pod::ElGamalCiphertext> {
let ct_1 = combine_lo_hi(ct_1_lo, ct_1_hi)?; let ct_1 = combine_lo_hi(ct_1_lo, ct_1_hi)?;
add_ciphertexts(Scalar::one(), ct_0, -Scalar::one(), ct_1) add_ciphertexts(Scalar::one(), ct_0, -Scalar::one(), ct_1)
} }
pub fn add_to(ct: pod::ElGamalCT, amount: u64) -> Option<pod::ElGamalCT> { pub fn add_to(ct: pod::ElGamalCiphertext, amount: u64) -> Option<pod::ElGamalCiphertext> {
let mut amount_as_ct = [0_u8; 64]; let mut amount_as_ct = [0_u8; 64];
amount_as_ct[..32].copy_from_slice(RISTRETTO_BASEPOINT_COMPRESSED.as_bytes()); amount_as_ct[..32].copy_from_slice(RISTRETTO_BASEPOINT_COMPRESSED.as_bytes());
add_ciphertexts( add_ciphertexts(
Scalar::one(), Scalar::one(),
ct, ct,
Scalar::from(amount), Scalar::from(amount),
pod::ElGamalCT(amount_as_ct), pod::ElGamalCiphertext(amount_as_ct),
) )
} }
pub fn subtract_from(ct: pod::ElGamalCT, amount: u64) -> Option<pod::ElGamalCT> { pub fn subtract_from(
ct: pod::ElGamalCiphertext,
amount: u64,
) -> Option<pod::ElGamalCiphertext> {
let mut amount_as_ct = [0_u8; 64]; let mut amount_as_ct = [0_u8; 64];
amount_as_ct[..32].copy_from_slice(RISTRETTO_BASEPOINT_COMPRESSED.as_bytes()); amount_as_ct[..32].copy_from_slice(RISTRETTO_BASEPOINT_COMPRESSED.as_bytes());
add_ciphertexts( add_ciphertexts(
Scalar::one(), Scalar::one(),
ct, ct,
-Scalar::from(amount), -Scalar::from(amount),
pod::ElGamalCT(amount_as_ct), pod::ElGamalCiphertext(amount_as_ct),
) )
} }
} }
@ -85,35 +94,44 @@ mod target_arch {
mod target_arch { mod target_arch {
use crate::zk_token_elgamal::pod; use crate::zk_token_elgamal::pod;
pub fn add(ct_0: pod::ElGamalCT, ct_1: pod::ElGamalCT) -> Option<pod::ElGamalCT> { pub fn add(
ct_0: pod::ElGamalCiphertext,
ct_1: pod::ElGamalCiphertext,
) -> Option<pod::ElGamalCiphertext> {
None None
} }
pub fn add_with_lo_hi( pub fn add_with_lo_hi(
ct_0: pod::ElGamalCT, ct_0: pod::ElGamalCiphertext,
ct_1_lo: pod::ElGamalCT, ct_1_lo: pod::ElGamalCiphertext,
ct_1_hi: pod::ElGamalCT, ct_1_hi: pod::ElGamalCiphertext,
) -> Option<pod::ElGamalCT> { ) -> Option<pod::ElGamalCiphertext> {
None None
} }
pub fn subtract(ct_0: pod::ElGamalCT, ct_1: pod::ElGamalCT) -> Option<pod::ElGamalCT> { pub fn subtract(
ct_0: pod::ElGamalCiphertext,
ct_1: pod::ElGamalCiphertext,
) -> Option<pod::ElGamalCiphertext> {
None None
} }
pub fn subtract_with_lo_hi( pub fn subtract_with_lo_hi(
ct_0: pod::ElGamalCT, ct_0: pod::ElGamalCiphertext,
ct_1_lo: pod::ElGamalCT, ct_1_lo: pod::ElGamalCiphertext,
ct_1_hi: pod::ElGamalCT, ct_1_hi: pod::ElGamalCiphertext,
) -> Option<pod::ElGamalCT> { ) -> Option<pod::ElGamalCiphertext> {
None None
} }
pub fn add_to(ct: pod::ElGamalCT, amount: u64) -> Option<pod::ElGamalCT> { pub fn add_to(ct: pod::ElGamalCiphertext, amount: u64) -> Option<pod::ElGamalCiphertext> {
None None
} }
pub fn subtract_from(ct: pod::ElGamalCT, amount: u64) -> Option<pod::ElGamalCT> { pub fn subtract_from(
ct: pod::ElGamalCiphertext,
amount: u64,
) -> Option<pod::ElGamalCiphertext> {
None None
} }
} }
@ -123,7 +141,7 @@ mod tests {
use { use {
crate::{ crate::{
encryption::{ encryption::{
elgamal::{ElGamal, ElGamalCT}, elgamal::{ElGamal, ElGamalCiphertext},
pedersen::{Pedersen, PedersenOpen}, pedersen::{Pedersen, PedersenOpen},
}, },
zk_token_elgamal::{ops, pod}, zk_token_elgamal::{ops, pod},
@ -136,8 +154,8 @@ mod tests {
#[test] #[test]
fn test_zero_ct() { fn test_zero_ct() {
let spendable_balance = pod::ElGamalCT::zeroed(); let spendable_balance = pod::ElGamalCiphertext::zeroed();
let spendable_ct: ElGamalCT = spendable_balance.try_into().unwrap(); let spendable_ct: ElGamalCiphertext = spendable_balance.try_into().unwrap();
// spendable_ct should be an encryption of 0 for any public key when // spendable_ct should be an encryption of 0 for any public key when
// `PedersenOpen::default()` is used // `PedersenOpen::default()` is used
@ -151,22 +169,23 @@ mod tests {
// homomorphism should work like any other ciphertext // homomorphism should work like any other ciphertext
let open = PedersenOpen::random(&mut OsRng); let open = PedersenOpen::random(&mut OsRng);
let transfer_amount_ct = pk.encrypt_with(55_u64, &open); 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 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); assert_eq!(expected, sum);
} }
#[test] #[test]
fn test_add_to() { 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 added_ct = ops::add_to(spendable_balance, 55).unwrap();
let (pk, _) = ElGamal::keygen(); 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); assert_eq!(expected, added_ct);
} }
@ -176,11 +195,11 @@ mod tests {
let amount = 77_u64; let amount = 77_u64;
let (pk, _) = ElGamal::keygen(); let (pk, _) = ElGamal::keygen();
let open = PedersenOpen::random(&mut OsRng); 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 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); assert_eq!(expected, subtracted_ct);
} }
@ -228,15 +247,16 @@ mod tests {
let source_open = PedersenOpen::random(&mut OsRng); let source_open = PedersenOpen::random(&mut OsRng);
let dest_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(); 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 // program arithmetic for the source account
// 1. Combine commitments and handles // 1. Combine commitments and handles
let source_lo_ct: pod::ElGamalCT = (comm_lo, handle_source_lo).into(); let source_lo_ct: pod::ElGamalCiphertext = (comm_lo, handle_source_lo).into();
let source_hi_ct: pod::ElGamalCT = (comm_hi, handle_source_hi).into(); let source_hi_ct: pod::ElGamalCiphertext = (comm_hi, handle_source_hi).into();
// 2. Combine lo and hi ciphertexts // 2. Combine lo and hi ciphertexts
let source_combined_ct = ops::combine_lo_hi(source_lo_ct, source_hi_ct).unwrap(); let source_combined_ct = ops::combine_lo_hi(source_lo_ct, source_hi_ct).unwrap();
@ -248,15 +268,15 @@ mod tests {
// test // test
let final_source_open = let final_source_open =
source_open - (open_lo.clone() + open_hi.clone() * Scalar::from(ops::TWO_32)); 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(); source_pk.encrypt_with(22_u64, &final_source_open).into();
assert_eq!(expected_source, final_source_spendable); assert_eq!(expected_source, final_source_spendable);
// same for the destination account // same for the destination account
// 1. Combine commitments and handles // 1. Combine commitments and handles
let dest_lo_ct: pod::ElGamalCT = (comm_lo, handle_dest_lo).into(); let dest_lo_ct: pod::ElGamalCiphertext = (comm_lo, handle_dest_lo).into();
let dest_hi_ct: pod::ElGamalCT = (comm_hi, handle_dest_hi).into(); let dest_hi_ct: pod::ElGamalCiphertext = (comm_hi, handle_dest_hi).into();
// 2. Combine lo and hi ciphertexts // 2. Combine lo and hi ciphertexts
let dest_combined_ct = ops::combine_lo_hi(dest_lo_ct, dest_hi_ct).unwrap(); 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_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 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(); dest_pk.encrypt_with(132_u64, &final_dest_open).into();
assert_eq!(expected_dest_ct, final_dest_pending); assert_eq!(expected_dest_ct, final_dest_pending);
} }

View File

@ -10,11 +10,11 @@ pub struct CompressedRistretto(pub [u8; 32]);
#[derive(Clone, Copy, Pod, Zeroable, PartialEq)] #[derive(Clone, Copy, Pod, Zeroable, PartialEq)]
#[repr(transparent)] #[repr(transparent)]
pub struct ElGamalCT(pub [u8; 64]); pub struct ElGamalCiphertext(pub [u8; 64]);
#[derive(Clone, Copy, Pod, Zeroable, PartialEq)] #[derive(Clone, Copy, Pod, Zeroable, PartialEq)]
#[repr(transparent)] #[repr(transparent)]
pub struct ElGamalPK(pub [u8; 32]); pub struct ElGamalPubkey(pub [u8; 32]);
#[derive(Clone, Copy, Pod, Zeroable, PartialEq)] #[derive(Clone, Copy, Pod, Zeroable, PartialEq)]
#[repr(transparent)] #[repr(transparent)]