Rename ElGamalKeypair fields
This commit is contained in:
@ -28,10 +28,12 @@ use {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Handle for the (twisted) ElGamal encryption scheme
|
/// A (twisted) ElGamal encryption keypair.
|
||||||
pub struct ElGamalKeypair {
|
pub struct ElGamalKeypair {
|
||||||
pub pk: ElGamalPubkey,
|
/// The public half of this keypair.
|
||||||
pub sk: ElGamalSecretKey,
|
pub public: ElGamalPubkey,
|
||||||
|
/// The secret half of this keypair.
|
||||||
|
pub secret: ElGamalSecretKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ElGamalKeypair {
|
impl ElGamalKeypair {
|
||||||
@ -61,17 +63,17 @@ impl ElGamalKeypair {
|
|||||||
let P = s.invert() * H;
|
let P = s.invert() * H;
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
pk: ElGamalPubkey(P),
|
public: ElGamalPubkey(P),
|
||||||
sk: ElGamalSecretKey(s),
|
secret: ElGamalSecretKey(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: &ElGamalPubkey, amount: T) -> ElGamalCiphertext {
|
pub fn encrypt<T: Into<Scalar>>(public: &ElGamalPubkey, amount: T) -> ElGamalCiphertext {
|
||||||
let (message_comm, open) = Pedersen::new(amount);
|
let (message_comm, open) = Pedersen::new(amount);
|
||||||
let decrypt_handle = pk.decrypt_handle(&open);
|
let decrypt_handle = public.decrypt_handle(&open);
|
||||||
|
|
||||||
ElGamalCiphertext {
|
ElGamalCiphertext {
|
||||||
message_comm,
|
message_comm,
|
||||||
@ -83,12 +85,12 @@ impl ElGamalKeypair {
|
|||||||
/// 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: &ElGamalPubkey,
|
public: &ElGamalPubkey,
|
||||||
amount: T,
|
amount: T,
|
||||||
open: &PedersenOpening,
|
open: &PedersenOpening,
|
||||||
) -> ElGamalCiphertext {
|
) -> ElGamalCiphertext {
|
||||||
let message_comm = Pedersen::with(amount, open);
|
let message_comm = Pedersen::with(amount, open);
|
||||||
let decrypt_handle = pk.decrypt_handle(open);
|
let decrypt_handle = public.decrypt_handle(open);
|
||||||
|
|
||||||
ElGamalCiphertext {
|
ElGamalCiphertext {
|
||||||
message_comm,
|
message_comm,
|
||||||
@ -100,8 +102,8 @@ impl ElGamalKeypair {
|
|||||||
///
|
///
|
||||||
/// The output of the function is of type `DiscreteLog`. The exact message
|
/// The output of the function is of type `DiscreteLog`. The exact message
|
||||||
/// can be recovered via the DiscreteLog's decode method.
|
/// can be recovered via the DiscreteLog's decode method.
|
||||||
pub fn decrypt(sk: &ElGamalSecretKey, ct: &ElGamalCiphertext) -> DiscreteLog {
|
pub fn decrypt(secret: &ElGamalSecretKey, ct: &ElGamalCiphertext) -> DiscreteLog {
|
||||||
let ElGamalSecretKey(s) = sk;
|
let ElGamalSecretKey(s) = secret;
|
||||||
let ElGamalCiphertext {
|
let ElGamalCiphertext {
|
||||||
message_comm,
|
message_comm,
|
||||||
decrypt_handle,
|
decrypt_handle,
|
||||||
@ -115,32 +117,32 @@ impl ElGamalKeypair {
|
|||||||
|
|
||||||
/// 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: &ElGamalSecretKey, ct: &ElGamalCiphertext) -> Option<u32> {
|
pub fn decrypt_u32(secret: &ElGamalSecretKey, ct: &ElGamalCiphertext) -> Option<u32> {
|
||||||
let discrete_log_instance = Self::decrypt(sk, ct);
|
let discrete_log_instance = Self::decrypt(secret, ct);
|
||||||
discrete_log_instance.decode_u32()
|
discrete_log_instance.decode_u32()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// On input a secret key, ciphertext, and hashmap, the function decrypts the
|
/// On input a secret key, ciphertext, and hashmap, the function decrypts the
|
||||||
/// ciphertext for a u32 value.
|
/// ciphertext for a u32 value.
|
||||||
pub fn decrypt_u32_online(
|
pub fn decrypt_u32_online(
|
||||||
sk: &ElGamalSecretKey,
|
secret: &ElGamalSecretKey,
|
||||||
ct: &ElGamalCiphertext,
|
ct: &ElGamalCiphertext,
|
||||||
hashmap: &HashMap<[u8; 32], u32>,
|
hashmap: &HashMap<[u8; 32], u32>,
|
||||||
) -> Option<u32> {
|
) -> Option<u32> {
|
||||||
let discrete_log_instance = Self::decrypt(sk, ct);
|
let discrete_log_instance = Self::decrypt(secret, ct);
|
||||||
discrete_log_instance.decode_u32_online(hashmap)
|
discrete_log_instance.decode_u32_online(hashmap)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_bytes(&self) -> [u8; 64] {
|
pub fn to_bytes(&self) -> [u8; 64] {
|
||||||
let mut bytes = self.pk.to_bytes().to_vec();
|
let mut bytes = self.public.to_bytes().to_vec();
|
||||||
bytes.extend(self.sk.to_bytes());
|
bytes.extend(self.secret.to_bytes());
|
||||||
bytes.try_into().expect("incorrect length")
|
bytes.try_into().expect("incorrect length")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
|
pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
|
||||||
Some(Self {
|
Some(Self {
|
||||||
pk: ElGamalPubkey::from_bytes(bytes[..32].try_into().ok()?)?,
|
public: ElGamalPubkey::from_bytes(bytes[..32].try_into().ok()?)?,
|
||||||
sk: ElGamalSecretKey::from_bytes(bytes[32..].try_into().ok()?)?,
|
secret: ElGamalSecretKey::from_bytes(bytes[32..].try_into().ok()?)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,22 +357,22 @@ impl ElGamalCiphertext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Utility method for code ergonomics.
|
/// Utility method for code ergonomics.
|
||||||
pub fn decrypt(&self, sk: &ElGamalSecretKey) -> DiscreteLog {
|
pub fn decrypt(&self, secret: &ElGamalSecretKey) -> DiscreteLog {
|
||||||
ElGamalKeypair::decrypt(sk, self)
|
ElGamalKeypair::decrypt(secret, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Utility method for code ergonomics.
|
/// Utility method for code ergonomics.
|
||||||
pub fn decrypt_u32(&self, sk: &ElGamalSecretKey) -> Option<u32> {
|
pub fn decrypt_u32(&self, secret: &ElGamalSecretKey) -> Option<u32> {
|
||||||
ElGamalKeypair::decrypt_u32(sk, self)
|
ElGamalKeypair::decrypt_u32(secret, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Utility method for code ergonomics.
|
/// Utility method for code ergonomics.
|
||||||
pub fn decrypt_u32_online(
|
pub fn decrypt_u32_online(
|
||||||
&self,
|
&self,
|
||||||
sk: &ElGamalSecretKey,
|
secret: &ElGamalSecretKey,
|
||||||
hashmap: &HashMap<[u8; 32], u32>,
|
hashmap: &HashMap<[u8; 32], u32>,
|
||||||
) -> Option<u32> {
|
) -> Option<u32> {
|
||||||
ElGamalKeypair::decrypt_u32_online(sk, self, hashmap)
|
ElGamalKeypair::decrypt_u32_online(secret, self, hashmap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,25 +460,31 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_encrypt_decrypt_correctness() {
|
fn test_encrypt_decrypt_correctness() {
|
||||||
let ElGamalKeypair { pk, sk } = ElGamalKeypair::default();
|
let ElGamalKeypair { public, secret } = ElGamalKeypair::default();
|
||||||
let msg: u32 = 57;
|
let msg: u32 = 57;
|
||||||
let ct = ElGamalKeypair::encrypt(&pk, msg);
|
let ct = ElGamalKeypair::encrypt(&public, msg);
|
||||||
|
|
||||||
let expected_instance = DiscreteLog {
|
let expected_instance = DiscreteLog {
|
||||||
generator: PedersenBase::default().G,
|
generator: PedersenBase::default().G,
|
||||||
target: Scalar::from(msg) * PedersenBase::default().G,
|
target: Scalar::from(msg) * PedersenBase::default().G,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(expected_instance, ElGamalKeypair::decrypt(&sk, &ct));
|
assert_eq!(expected_instance, ElGamalKeypair::decrypt(&secret, &ct));
|
||||||
|
|
||||||
// Commenting out for faster testing
|
// Commenting out for faster testing
|
||||||
// assert_eq!(msg, ElGamalKeypair::decrypt_u32(&sk, &ct).unwrap());
|
// assert_eq!(msg, ElGamalKeypair::decrypt_u32(&secret, &ct).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decrypt_handle() {
|
fn test_decrypt_handle() {
|
||||||
let ElGamalKeypair { pk: pk_1, sk: sk_1 } = ElGamalKeypair::default();
|
let ElGamalKeypair {
|
||||||
let ElGamalKeypair { pk: pk_2, sk: sk_2 } = ElGamalKeypair::default();
|
public: pk_1,
|
||||||
|
secret: sk_1,
|
||||||
|
} = ElGamalKeypair::default();
|
||||||
|
let ElGamalKeypair {
|
||||||
|
public: pk_2,
|
||||||
|
secret: sk_2,
|
||||||
|
} = ElGamalKeypair::default();
|
||||||
|
|
||||||
let msg: u32 = 77;
|
let msg: u32 = 77;
|
||||||
let (comm, open) = Pedersen::new(msg);
|
let (comm, open) = Pedersen::new(msg);
|
||||||
@ -502,7 +510,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_homomorphic_addition() {
|
fn test_homomorphic_addition() {
|
||||||
let ElGamalKeypair { pk, sk: _ } = ElGamalKeypair::default();
|
let ElGamalKeypair { public, secret: _ } = ElGamalKeypair::default();
|
||||||
let msg_0: u64 = 57;
|
let msg_0: u64 = 57;
|
||||||
let msg_1: u64 = 77;
|
let msg_1: u64 = 77;
|
||||||
|
|
||||||
@ -510,24 +518,24 @@ mod tests {
|
|||||||
let open_0 = PedersenOpening::random(&mut OsRng);
|
let open_0 = PedersenOpening::random(&mut OsRng);
|
||||||
let open_1 = PedersenOpening::random(&mut OsRng);
|
let open_1 = PedersenOpening::random(&mut OsRng);
|
||||||
|
|
||||||
let ct_0 = ElGamalKeypair::encrypt_with(&pk, msg_0, &open_0);
|
let ct_0 = ElGamalKeypair::encrypt_with(&public, msg_0, &open_0);
|
||||||
let ct_1 = ElGamalKeypair::encrypt_with(&pk, msg_1, &open_1);
|
let ct_1 = ElGamalKeypair::encrypt_with(&public, msg_1, &open_1);
|
||||||
|
|
||||||
let ct_sum = ElGamalKeypair::encrypt_with(&pk, msg_0 + msg_1, &(open_0 + open_1));
|
let ct_sum = ElGamalKeypair::encrypt_with(&public, msg_0 + msg_1, &(open_0 + open_1));
|
||||||
|
|
||||||
assert_eq!(ct_sum, ct_0 + ct_1);
|
assert_eq!(ct_sum, ct_0 + ct_1);
|
||||||
|
|
||||||
// Add to ElGamal ciphertext
|
// Add to ElGamal ciphertext
|
||||||
let open = PedersenOpening::random(&mut OsRng);
|
let open = PedersenOpening::random(&mut OsRng);
|
||||||
let ct = ElGamalKeypair::encrypt_with(&pk, msg_0, &open);
|
let ct = ElGamalKeypair::encrypt_with(&public, msg_0, &open);
|
||||||
let ct_sum = ElGamalKeypair::encrypt_with(&pk, msg_0 + msg_1, &open);
|
let ct_sum = ElGamalKeypair::encrypt_with(&public, msg_0 + msg_1, &open);
|
||||||
|
|
||||||
assert_eq!(ct_sum, ct.add_to_msg(msg_1));
|
assert_eq!(ct_sum, ct.add_to_msg(msg_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_homomorphic_subtraction() {
|
fn test_homomorphic_subtraction() {
|
||||||
let ElGamalKeypair { pk, sk: _ } = ElGamalKeypair::default();
|
let ElGamalKeypair { public, secret: _ } = ElGamalKeypair::default();
|
||||||
let msg_0: u64 = 77;
|
let msg_0: u64 = 77;
|
||||||
let msg_1: u64 = 55;
|
let msg_1: u64 = 55;
|
||||||
|
|
||||||
@ -535,58 +543,58 @@ mod tests {
|
|||||||
let open_0 = PedersenOpening::random(&mut OsRng);
|
let open_0 = PedersenOpening::random(&mut OsRng);
|
||||||
let open_1 = PedersenOpening::random(&mut OsRng);
|
let open_1 = PedersenOpening::random(&mut OsRng);
|
||||||
|
|
||||||
let ct_0 = ElGamalKeypair::encrypt_with(&pk, msg_0, &open_0);
|
let ct_0 = ElGamalKeypair::encrypt_with(&public, msg_0, &open_0);
|
||||||
let ct_1 = ElGamalKeypair::encrypt_with(&pk, msg_1, &open_1);
|
let ct_1 = ElGamalKeypair::encrypt_with(&public, msg_1, &open_1);
|
||||||
|
|
||||||
let ct_sub = ElGamalKeypair::encrypt_with(&pk, msg_0 - msg_1, &(open_0 - open_1));
|
let ct_sub = ElGamalKeypair::encrypt_with(&public, msg_0 - msg_1, &(open_0 - open_1));
|
||||||
|
|
||||||
assert_eq!(ct_sub, ct_0 - ct_1);
|
assert_eq!(ct_sub, ct_0 - ct_1);
|
||||||
|
|
||||||
// Subtract to ElGamal ciphertext
|
// Subtract to ElGamal ciphertext
|
||||||
let open = PedersenOpening::random(&mut OsRng);
|
let open = PedersenOpening::random(&mut OsRng);
|
||||||
let ct = ElGamalKeypair::encrypt_with(&pk, msg_0, &open);
|
let ct = ElGamalKeypair::encrypt_with(&public, msg_0, &open);
|
||||||
let ct_sub = ElGamalKeypair::encrypt_with(&pk, msg_0 - msg_1, &open);
|
let ct_sub = ElGamalKeypair::encrypt_with(&public, msg_0 - msg_1, &open);
|
||||||
|
|
||||||
assert_eq!(ct_sub, ct.sub_to_msg(msg_1));
|
assert_eq!(ct_sub, ct.sub_to_msg(msg_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_homomorphic_multiplication() {
|
fn test_homomorphic_multiplication() {
|
||||||
let ElGamalKeypair { pk, sk: _ } = ElGamalKeypair::default();
|
let ElGamalKeypair { public, secret: _ } = ElGamalKeypair::default();
|
||||||
let msg_0: u64 = 57;
|
let msg_0: u64 = 57;
|
||||||
let msg_1: u64 = 77;
|
let msg_1: u64 = 77;
|
||||||
|
|
||||||
let open = PedersenOpening::random(&mut OsRng);
|
let open = PedersenOpening::random(&mut OsRng);
|
||||||
|
|
||||||
let ct = ElGamalKeypair::encrypt_with(&pk, msg_0, &open);
|
let ct = ElGamalKeypair::encrypt_with(&public, msg_0, &open);
|
||||||
let scalar = Scalar::from(msg_1);
|
let scalar = Scalar::from(msg_1);
|
||||||
|
|
||||||
let ct_prod = ElGamalKeypair::encrypt_with(&pk, msg_0 * msg_1, &(open * scalar));
|
let ct_prod = ElGamalKeypair::encrypt_with(&public, msg_0 * msg_1, &(open * scalar));
|
||||||
|
|
||||||
assert_eq!(ct_prod, ct * scalar);
|
assert_eq!(ct_prod, ct * scalar);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_homomorphic_division() {
|
fn test_homomorphic_division() {
|
||||||
let ElGamalKeypair { pk, sk: _ } = ElGamalKeypair::default();
|
let ElGamalKeypair { public, secret: _ } = ElGamalKeypair::default();
|
||||||
let msg_0: u64 = 55;
|
let msg_0: u64 = 55;
|
||||||
let msg_1: u64 = 5;
|
let msg_1: u64 = 5;
|
||||||
|
|
||||||
let open = PedersenOpening::random(&mut OsRng);
|
let open = PedersenOpening::random(&mut OsRng);
|
||||||
|
|
||||||
let ct = ElGamalKeypair::encrypt_with(&pk, msg_0, &open);
|
let ct = ElGamalKeypair::encrypt_with(&public, msg_0, &open);
|
||||||
let scalar = Scalar::from(msg_1);
|
let scalar = Scalar::from(msg_1);
|
||||||
|
|
||||||
let ct_div = ElGamalKeypair::encrypt_with(&pk, msg_0 / msg_1, &(open / scalar));
|
let ct_div = ElGamalKeypair::encrypt_with(&public, msg_0 / msg_1, &(open / scalar));
|
||||||
|
|
||||||
assert_eq!(ct_div, ct / scalar);
|
assert_eq!(ct_div, ct / scalar);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_serde_ciphertext() {
|
fn test_serde_ciphertext() {
|
||||||
let ElGamalKeypair { pk, sk: _ } = ElGamalKeypair::default();
|
let ElGamalKeypair { public, secret: _ } = ElGamalKeypair::default();
|
||||||
let msg: u64 = 77;
|
let msg: u64 = 77;
|
||||||
let ct = pk.encrypt(msg);
|
let ct = public.encrypt(msg);
|
||||||
|
|
||||||
let encoded = bincode::serialize(&ct).unwrap();
|
let encoded = bincode::serialize(&ct).unwrap();
|
||||||
let decoded: ElGamalCiphertext = bincode::deserialize(&encoded).unwrap();
|
let decoded: ElGamalCiphertext = bincode::deserialize(&encoded).unwrap();
|
||||||
@ -596,29 +604,29 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_serde_pubkey() {
|
fn test_serde_pubkey() {
|
||||||
let ElGamalKeypair { pk, sk: _ } = ElGamalKeypair::default();
|
let ElGamalKeypair { public, secret: _ } = ElGamalKeypair::default();
|
||||||
|
|
||||||
let encoded = bincode::serialize(&pk).unwrap();
|
let encoded = bincode::serialize(&public).unwrap();
|
||||||
let decoded: ElGamalPubkey = bincode::deserialize(&encoded).unwrap();
|
let decoded: ElGamalPubkey = bincode::deserialize(&encoded).unwrap();
|
||||||
|
|
||||||
assert_eq!(pk, decoded);
|
assert_eq!(public, decoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_serde_secretkey() {
|
fn test_serde_secretkey() {
|
||||||
let ElGamalKeypair { pk: _, sk } = ElGamalKeypair::default();
|
let ElGamalKeypair { public: _, secret } = ElGamalKeypair::default();
|
||||||
|
|
||||||
let encoded = bincode::serialize(&sk).unwrap();
|
let encoded = bincode::serialize(&secret).unwrap();
|
||||||
let decoded: ElGamalSecretKey = bincode::deserialize(&encoded).unwrap();
|
let decoded: ElGamalSecretKey = bincode::deserialize(&encoded).unwrap();
|
||||||
|
|
||||||
assert_eq!(sk, decoded);
|
assert_eq!(secret, decoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tmp_file_path(name: &str) -> String {
|
fn tmp_file_path(name: &str) -> String {
|
||||||
use std::env;
|
use std::env;
|
||||||
let out_dir = env::var("FARF_DIR").unwrap_or_else(|_| "farf".to_string());
|
let out_dir = env::var("FARF_DIR").unwrap_or_else(|_| "farf".to_string());
|
||||||
let keypair = ElGamalKeypair::default();
|
let keypair = ElGamalKeypair::default();
|
||||||
format!("{}/tmp/{}-{}", out_dir, name, keypair.pk)
|
format!("{}/tmp/{}-{}", out_dir, name, keypair.public)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -155,7 +155,7 @@ mod test {
|
|||||||
let source = ElGamalKeypair::default();
|
let source = ElGamalKeypair::default();
|
||||||
|
|
||||||
// invalid ciphertexts
|
// invalid ciphertexts
|
||||||
let balance = source.pk.encrypt(0_u64);
|
let balance = source.public.encrypt(0_u64);
|
||||||
|
|
||||||
let zeroed_comm = Pedersen::with(0_u64, &PedersenOpening::default());
|
let zeroed_comm = Pedersen::with(0_u64, &PedersenOpening::default());
|
||||||
let handle = balance.decrypt_handle;
|
let handle = balance.decrypt_handle;
|
||||||
@ -165,7 +165,7 @@ mod test {
|
|||||||
decrypt_handle: handle,
|
decrypt_handle: handle,
|
||||||
};
|
};
|
||||||
|
|
||||||
let proof = CloseAccountProof::new(&source.sk, &zeroed_comm_ciphertext);
|
let proof = CloseAccountProof::new(&source.secret, &zeroed_comm_ciphertext);
|
||||||
assert!(proof.verify(&zeroed_comm_ciphertext).is_err());
|
assert!(proof.verify(&zeroed_comm_ciphertext).is_err());
|
||||||
|
|
||||||
let zeroed_handle_ciphertext = ElGamalCiphertext {
|
let zeroed_handle_ciphertext = ElGamalCiphertext {
|
||||||
@ -173,24 +173,24 @@ mod test {
|
|||||||
decrypt_handle: PedersenDecryptHandle::default(),
|
decrypt_handle: PedersenDecryptHandle::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let proof = CloseAccountProof::new(&source.sk, &zeroed_handle_ciphertext);
|
let proof = CloseAccountProof::new(&source.secret, &zeroed_handle_ciphertext);
|
||||||
assert!(proof.verify(&zeroed_handle_ciphertext).is_err());
|
assert!(proof.verify(&zeroed_handle_ciphertext).is_err());
|
||||||
|
|
||||||
// valid ciphertext, but encryption of non-zero amount
|
// valid ciphertext, but encryption of non-zero amount
|
||||||
let balance = source.pk.encrypt(55_u64);
|
let balance = source.public.encrypt(55_u64);
|
||||||
|
|
||||||
let proof = CloseAccountProof::new(&source.sk, &balance);
|
let proof = CloseAccountProof::new(&source.secret, &balance);
|
||||||
assert!(proof.verify(&balance).is_err());
|
assert!(proof.verify(&balance).is_err());
|
||||||
|
|
||||||
// all-zeroed ciphertext interpretted as a valid encryption of zero
|
// all-zeroed ciphertext interpretted as a valid encryption of zero
|
||||||
let zeroed_ct: ElGamalCiphertext = pod::ElGamalCiphertext::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.secret, &zeroed_ct);
|
||||||
assert!(proof.verify(&zeroed_ct).is_ok());
|
assert!(proof.verify(&zeroed_ct).is_ok());
|
||||||
|
|
||||||
// general case: valid encryption of zero
|
// general case: valid encryption of zero
|
||||||
let balance = source.pk.encrypt(0_u64);
|
let balance = source.public.encrypt(0_u64);
|
||||||
|
|
||||||
let proof = CloseAccountProof::new(&source.sk, &balance);
|
let proof = CloseAccountProof::new(&source.secret, &balance);
|
||||||
assert!(proof.verify(&balance).is_ok());
|
assert!(proof.verify(&balance).is_ok());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -471,11 +471,11 @@ mod test {
|
|||||||
fn test_transfer_correctness() {
|
fn test_transfer_correctness() {
|
||||||
// ElGamalKeypair keys for source, destination, and auditor accounts
|
// ElGamalKeypair keys for source, destination, and auditor accounts
|
||||||
let ElGamalKeypair {
|
let ElGamalKeypair {
|
||||||
pk: source_pk,
|
public: source_pk,
|
||||||
sk: source_sk,
|
secret: source_sk,
|
||||||
} = ElGamalKeypair::default();
|
} = ElGamalKeypair::default();
|
||||||
let dest_pk = ElGamalKeypair::default().pk;
|
let dest_pk = ElGamalKeypair::default().public;
|
||||||
let auditor_pk = ElGamalKeypair::default().pk;
|
let auditor_pk = ElGamalKeypair::default().public;
|
||||||
|
|
||||||
// create source account spendable ciphertext
|
// create source account spendable ciphertext
|
||||||
let spendable_balance: u64 = 77;
|
let spendable_balance: u64 = 77;
|
||||||
@ -502,14 +502,14 @@ mod test {
|
|||||||
fn test_source_dest_ciphertext() {
|
fn test_source_dest_ciphertext() {
|
||||||
// ElGamalKeypair keys for source, destination, and auditor accounts
|
// ElGamalKeypair keys for source, destination, and auditor accounts
|
||||||
let ElGamalKeypair {
|
let ElGamalKeypair {
|
||||||
pk: source_pk,
|
public: source_pk,
|
||||||
sk: source_sk,
|
secret: source_sk,
|
||||||
} = ElGamalKeypair::default();
|
} = ElGamalKeypair::default();
|
||||||
let ElGamalKeypair {
|
let ElGamalKeypair {
|
||||||
pk: dest_pk,
|
public: dest_pk,
|
||||||
sk: dest_sk,
|
secret: dest_sk,
|
||||||
} = ElGamalKeypair::default();
|
} = ElGamalKeypair::default();
|
||||||
let auditor_pk = ElGamalKeypair::default().pk;
|
let auditor_pk = ElGamalKeypair::default().public;
|
||||||
|
|
||||||
// create source account spendable ciphertext
|
// create source account spendable ciphertext
|
||||||
let spendable_balance: u64 = 77;
|
let spendable_balance: u64 = 77;
|
||||||
|
@ -224,16 +224,18 @@ mod test {
|
|||||||
|
|
||||||
// If current_ct and new_ct encrypt same values, then the proof verification should succeed
|
// If current_ct and new_ct encrypt same values, then the proof verification should succeed
|
||||||
let balance: u64 = 77;
|
let balance: u64 = 77;
|
||||||
let current_ct = current.pk.encrypt(balance);
|
let current_ct = current.public.encrypt(balance);
|
||||||
let new_ct = new.pk.encrypt(balance);
|
let new_ct = new.public.encrypt(balance);
|
||||||
|
|
||||||
let proof = UpdateAccountPkProof::new(balance, ¤t.sk, &new.sk, ¤t_ct, &new_ct);
|
let proof =
|
||||||
|
UpdateAccountPkProof::new(balance, ¤t.secret, &new.secret, ¤t_ct, &new_ct);
|
||||||
assert!(proof.verify(¤t_ct, &new_ct).is_ok());
|
assert!(proof.verify(¤t_ct, &new_ct).is_ok());
|
||||||
|
|
||||||
// If current_ct and new_ct encrypt different values, then the proof verification should fail
|
// If current_ct and new_ct encrypt different values, then the proof verification should fail
|
||||||
let new_ct = new.pk.encrypt(55_u64);
|
let new_ct = new.public.encrypt(55_u64);
|
||||||
|
|
||||||
let proof = UpdateAccountPkProof::new(balance, ¤t.sk, &new.sk, ¤t_ct, &new_ct);
|
let proof =
|
||||||
|
UpdateAccountPkProof::new(balance, ¤t.secret, &new.secret, ¤t_ct, &new_ct);
|
||||||
assert!(proof.verify(¤t_ct, &new_ct).is_err());
|
assert!(proof.verify(¤t_ct, &new_ct).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,23 +248,23 @@ mod test {
|
|||||||
let balance: u64 = 0;
|
let balance: u64 = 0;
|
||||||
let zeroed_ct_as_current_ct: ElGamalCiphertext =
|
let zeroed_ct_as_current_ct: ElGamalCiphertext =
|
||||||
pod::ElGamalCiphertext::zeroed().try_into().unwrap();
|
pod::ElGamalCiphertext::zeroed().try_into().unwrap();
|
||||||
let new_ct: ElGamalCiphertext = new.pk.encrypt(balance);
|
let new_ct: ElGamalCiphertext = new.public.encrypt(balance);
|
||||||
let proof = UpdateAccountPkProof::new(
|
let proof = UpdateAccountPkProof::new(
|
||||||
balance,
|
balance,
|
||||||
¤t.sk,
|
¤t.secret,
|
||||||
&new.sk,
|
&new.secret,
|
||||||
&zeroed_ct_as_current_ct,
|
&zeroed_ct_as_current_ct,
|
||||||
&new_ct,
|
&new_ct,
|
||||||
);
|
);
|
||||||
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 = current.pk.encrypt(balance);
|
let current_ct = current.public.encrypt(balance);
|
||||||
let zeroed_ct_as_new_ct: ElGamalCiphertext =
|
let zeroed_ct_as_new_ct: ElGamalCiphertext =
|
||||||
pod::ElGamalCiphertext::zeroed().try_into().unwrap();
|
pod::ElGamalCiphertext::zeroed().try_into().unwrap();
|
||||||
let proof = UpdateAccountPkProof::new(
|
let proof = UpdateAccountPkProof::new(
|
||||||
balance,
|
balance,
|
||||||
¤t.sk,
|
¤t.secret,
|
||||||
&new.sk,
|
&new.secret,
|
||||||
¤t_ct,
|
¤t_ct,
|
||||||
&zeroed_ct_as_new_ct,
|
&zeroed_ct_as_new_ct,
|
||||||
);
|
);
|
||||||
@ -274,8 +276,8 @@ mod test {
|
|||||||
pod::ElGamalCiphertext::zeroed().try_into().unwrap();
|
pod::ElGamalCiphertext::zeroed().try_into().unwrap();
|
||||||
let proof = UpdateAccountPkProof::new(
|
let proof = UpdateAccountPkProof::new(
|
||||||
balance,
|
balance,
|
||||||
¤t.sk,
|
¤t.secret,
|
||||||
&new.sk,
|
&new.secret,
|
||||||
&zeroed_ct_as_current_ct,
|
&zeroed_ct_as_current_ct,
|
||||||
&zeroed_ct_as_new_ct,
|
&zeroed_ct_as_new_ct,
|
||||||
);
|
);
|
||||||
@ -290,7 +292,7 @@ mod test {
|
|||||||
let new = ElGamalKeypair::default();
|
let new = ElGamalKeypair::default();
|
||||||
|
|
||||||
let balance = 0_u64;
|
let balance = 0_u64;
|
||||||
let balance_ciphertext = new.pk.encrypt(balance);
|
let balance_ciphertext = new.public.encrypt(balance);
|
||||||
|
|
||||||
let zeroed_comm = Pedersen::with(0_u64, &PedersenOpening::default());
|
let zeroed_comm = Pedersen::with(0_u64, &PedersenOpening::default());
|
||||||
let handle = balance_ciphertext.decrypt_handle;
|
let handle = balance_ciphertext.decrypt_handle;
|
||||||
@ -300,12 +302,12 @@ mod test {
|
|||||||
message_comm: zeroed_comm,
|
message_comm: zeroed_comm,
|
||||||
decrypt_handle: handle,
|
decrypt_handle: handle,
|
||||||
};
|
};
|
||||||
let new_ct: ElGamalCiphertext = new.pk.encrypt(balance);
|
let new_ct: ElGamalCiphertext = new.public.encrypt(balance);
|
||||||
|
|
||||||
let proof = UpdateAccountPkProof::new(
|
let proof = UpdateAccountPkProof::new(
|
||||||
balance,
|
balance,
|
||||||
¤t.sk,
|
¤t.secret,
|
||||||
&new.sk,
|
&new.secret,
|
||||||
&zeroed_comm_ciphertext,
|
&zeroed_comm_ciphertext,
|
||||||
&new_ct,
|
&new_ct,
|
||||||
);
|
);
|
||||||
@ -318,8 +320,8 @@ mod test {
|
|||||||
|
|
||||||
let proof = UpdateAccountPkProof::new(
|
let proof = UpdateAccountPkProof::new(
|
||||||
balance,
|
balance,
|
||||||
¤t.sk,
|
¤t.secret,
|
||||||
&new.sk,
|
&new.secret,
|
||||||
&zeroed_handle_ciphertext,
|
&zeroed_handle_ciphertext,
|
||||||
&new_ct,
|
&new_ct,
|
||||||
);
|
);
|
||||||
@ -330,12 +332,12 @@ mod test {
|
|||||||
message_comm: zeroed_comm,
|
message_comm: zeroed_comm,
|
||||||
decrypt_handle: handle,
|
decrypt_handle: handle,
|
||||||
};
|
};
|
||||||
let current_ct: ElGamalCiphertext = current.pk.encrypt(balance);
|
let current_ct: ElGamalCiphertext = current.public.encrypt(balance);
|
||||||
|
|
||||||
let proof = UpdateAccountPkProof::new(
|
let proof = UpdateAccountPkProof::new(
|
||||||
balance,
|
balance,
|
||||||
¤t.sk,
|
¤t.secret,
|
||||||
&new.sk,
|
&new.secret,
|
||||||
¤t_ct,
|
¤t_ct,
|
||||||
&zeroed_comm_ciphertext,
|
&zeroed_comm_ciphertext,
|
||||||
);
|
);
|
||||||
@ -348,8 +350,8 @@ mod test {
|
|||||||
|
|
||||||
let proof = UpdateAccountPkProof::new(
|
let proof = UpdateAccountPkProof::new(
|
||||||
balance,
|
balance,
|
||||||
¤t.sk,
|
¤t.secret,
|
||||||
&new.sk,
|
&new.secret,
|
||||||
¤t_ct,
|
¤t_ct,
|
||||||
&zeroed_handle_ciphertext,
|
&zeroed_handle_ciphertext,
|
||||||
);
|
);
|
||||||
|
@ -179,17 +179,17 @@ mod test {
|
|||||||
#[ignore]
|
#[ignore]
|
||||||
fn test_withdraw_correctness() {
|
fn test_withdraw_correctness() {
|
||||||
// generate and verify proof for the proper setting
|
// generate and verify proof for the proper setting
|
||||||
let ElGamalKeypair { pk, sk } = ElGamalKeypair::default();
|
let ElGamalKeypair { public, secret } = ElGamalKeypair::default();
|
||||||
|
|
||||||
let current_balance: u64 = 77;
|
let current_balance: u64 = 77;
|
||||||
let current_balance_ct = pk.encrypt(current_balance);
|
let current_balance_ct = public.encrypt(current_balance);
|
||||||
|
|
||||||
let withdraw_amount: u64 = 55;
|
let withdraw_amount: u64 = 55;
|
||||||
|
|
||||||
let data = WithdrawData::new(
|
let data = WithdrawData::new(
|
||||||
withdraw_amount,
|
withdraw_amount,
|
||||||
pk,
|
public,
|
||||||
&sk,
|
&secret,
|
||||||
current_balance,
|
current_balance,
|
||||||
current_balance_ct,
|
current_balance_ct,
|
||||||
);
|
);
|
||||||
@ -197,7 +197,13 @@ mod test {
|
|||||||
|
|
||||||
// generate and verify proof with wrong balance
|
// generate and verify proof with wrong balance
|
||||||
let wrong_balance: u64 = 99;
|
let wrong_balance: u64 = 99;
|
||||||
let data = WithdrawData::new(withdraw_amount, pk, &sk, wrong_balance, current_balance_ct);
|
let data = WithdrawData::new(
|
||||||
|
withdraw_amount,
|
||||||
|
public,
|
||||||
|
&secret,
|
||||||
|
wrong_balance,
|
||||||
|
current_balance_ct,
|
||||||
|
);
|
||||||
assert!(data.verify().is_err());
|
assert!(data.verify().is_err());
|
||||||
|
|
||||||
// TODO: test for ciphertexts that encrypt numbers outside the 0, 2^64 range
|
// TODO: test for ciphertexts that encrypt numbers outside the 0, 2^64 range
|
||||||
|
@ -252,21 +252,21 @@ mod tests {
|
|||||||
|
|
||||||
// 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
|
||||||
let pk = ElGamalKeypair::default().pk;
|
let public = ElGamalKeypair::default().public;
|
||||||
let balance: u64 = 0;
|
let balance: u64 = 0;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
spendable_ct,
|
spendable_ct,
|
||||||
pk.encrypt_with(balance, &PedersenOpening::default())
|
public.encrypt_with(balance, &PedersenOpening::default())
|
||||||
);
|
);
|
||||||
|
|
||||||
// homomorphism should work like any other ciphertext
|
// homomorphism should work like any other ciphertext
|
||||||
let open = PedersenOpening::random(&mut OsRng);
|
let open = PedersenOpening::random(&mut OsRng);
|
||||||
let transfer_amount_ct = pk.encrypt_with(55_u64, &open);
|
let transfer_amount_ct = public.encrypt_with(55_u64, &open);
|
||||||
let transfer_amount_pod: pod::ElGamalCiphertext = 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::ElGamalCiphertext = pk.encrypt_with(55_u64, &open).into();
|
let expected: pod::ElGamalCiphertext = public.encrypt_with(55_u64, &open).into();
|
||||||
assert_eq!(expected, sum);
|
assert_eq!(expected, sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,9 +276,10 @@ mod tests {
|
|||||||
|
|
||||||
let added_ct = ops::add_to(&spendable_balance, 55).unwrap();
|
let added_ct = ops::add_to(&spendable_balance, 55).unwrap();
|
||||||
|
|
||||||
let pk = ElGamalKeypair::default().pk;
|
let public = ElGamalKeypair::default().public;
|
||||||
let expected: pod::ElGamalCiphertext =
|
let expected: pod::ElGamalCiphertext = public
|
||||||
pk.encrypt_with(55_u64, &PedersenOpening::default()).into();
|
.encrypt_with(55_u64, &PedersenOpening::default())
|
||||||
|
.into();
|
||||||
|
|
||||||
assert_eq!(expected, added_ct);
|
assert_eq!(expected, added_ct);
|
||||||
}
|
}
|
||||||
@ -286,13 +287,13 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_subtract_from() {
|
fn test_subtract_from() {
|
||||||
let amount = 77_u64;
|
let amount = 77_u64;
|
||||||
let pk = ElGamalKeypair::default().pk;
|
let public = ElGamalKeypair::default().public;
|
||||||
let open = PedersenOpening::random(&mut OsRng);
|
let open = PedersenOpening::random(&mut OsRng);
|
||||||
let encrypted_amount: pod::ElGamalCiphertext = pk.encrypt_with(amount, &open).into();
|
let encrypted_amount: pod::ElGamalCiphertext = public.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::ElGamalCiphertext = pk.encrypt_with(22_u64, &open).into();
|
let expected: pod::ElGamalCiphertext = public.encrypt_with(22_u64, &open).into();
|
||||||
|
|
||||||
assert_eq!(expected, subtracted_ct);
|
assert_eq!(expected, subtracted_ct);
|
||||||
}
|
}
|
||||||
@ -312,9 +313,9 @@ mod tests {
|
|||||||
let (amount_lo, amount_hi) = split_u64_into_u32(transfer_amount);
|
let (amount_lo, amount_hi) = split_u64_into_u32(transfer_amount);
|
||||||
|
|
||||||
// generate public keys
|
// generate public keys
|
||||||
let source_pk = ElGamalKeypair::default().pk;
|
let source_pk = ElGamalKeypair::default().public;
|
||||||
let dest_pk = ElGamalKeypair::default().pk;
|
let dest_pk = ElGamalKeypair::default().public;
|
||||||
let auditor_pk = ElGamalKeypair::default().pk;
|
let auditor_pk = ElGamalKeypair::default().public;
|
||||||
|
|
||||||
// commitments associated with TransferRangeProof
|
// commitments associated with TransferRangeProof
|
||||||
let (comm_lo, open_lo) = Pedersen::new(amount_lo);
|
let (comm_lo, open_lo) = Pedersen::new(amount_lo);
|
||||||
|
Reference in New Issue
Block a user