Rename ElGamalCT to ElGamalCiphertext, ElGamalPK to ElGamalPubkey
This commit is contained in:
parent
f3e7e62813
commit
78799640ea
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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,
|
||||||
¤t_sk,
|
¤t_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,
|
||||||
¤t_sk,
|
¤t_sk,
|
||||||
|
@ -255,8 +261,10 @@ mod test {
|
||||||
);
|
);
|
||||||
assert!(proof.verify(¤t_ct, &zeroed_ct_as_new_ct).is_ok());
|
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_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,
|
||||||
¤t_sk,
|
¤t_sk,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
Loading…
Reference in New Issue