Skip to content

Commit

Permalink
[zk-sdk] Clean up (target_os = "solana") (anza-xyz#1257)
Browse files Browse the repository at this point in the history
* remove unnecessary `cfg(not(target_os = ...))` in `encryption` module

* move `encryption` constants out of the submodules

* clean up solana target in `sigma` module

* clean up solana target in `transcript` module

* cargo fmt
  • Loading branch information
samkim-crypto authored May 9, 2024
1 parent c84c478 commit be73f30
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 74 deletions.
2 changes: 1 addition & 1 deletion zk-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ edition = { workspace = true }
[dependencies]
base64 = { workspace = true }
bytemuck = { workspace = true }
merlin = { workspace = true }
num-derive = { workspace = true }
num-traits = { workspace = true }
solana-program = { workspace = true }
Expand All @@ -26,7 +27,6 @@ bincode = { workspace = true }
curve25519-dalek = { workspace = true, features = ["serde"] }
itertools = { workspace = true }
lazy_static = { workspace = true }
merlin = { workspace = true }
rand = { version = "0.7" }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
Expand Down
28 changes: 9 additions & 19 deletions zk-sdk/src/encryption/auth_encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@
//! This module is a simple wrapper of the `Aes128GcmSiv` implementation specialized for SPL
//! token-2022 where the plaintext is always `u64`.
use {
crate::errors::AuthenticatedEncryptionError,
crate::{
encryption::{AE_CIPHERTEXT_LEN, AE_KEY_LEN},
errors::AuthenticatedEncryptionError,
},
aes_gcm_siv::{
aead::{Aead, NewAead},
Aes128GcmSiv,
},
base64::{prelude::BASE64_STANDARD, Engine},
rand::{rngs::OsRng, Rng},
sha3::{Digest, Sha3_512},
solana_sdk::{
derivation_path::DerivationPath,
Expand All @@ -22,41 +30,24 @@ use {
subtle::ConstantTimeEq,
zeroize::Zeroize,
};
#[cfg(not(target_os = "solana"))]
use {
aes_gcm_siv::{
aead::{Aead, NewAead},
Aes128GcmSiv,
},
rand::{rngs::OsRng, Rng},
};

/// Byte length of an authenticated encryption secret key
pub const AE_KEY_LEN: usize = 16;

/// Byte length of an authenticated encryption nonce component
const NONCE_LEN: usize = 12;

/// Byte lenth of an authenticated encryption ciphertext component
const CIPHERTEXT_LEN: usize = 24;

/// Byte length of a complete authenticated encryption ciphertext component that includes the
/// ciphertext and nonce components
const AE_CIPHERTEXT_LEN: usize = 36;

struct AuthenticatedEncryption;
impl AuthenticatedEncryption {
/// Generates an authenticated encryption key.
///
/// This function is randomized. It internally samples a 128-bit key using `OsRng`.
#[cfg(not(target_os = "solana"))]
fn keygen() -> AeKey {
AeKey(OsRng.gen::<[u8; AE_KEY_LEN]>())
}

/// On input of an authenticated encryption key and an amount, the function returns a
/// corresponding authenticated encryption ciphertext.
#[cfg(not(target_os = "solana"))]
fn encrypt(key: &AeKey, balance: u64) -> AeCiphertext {
let mut plaintext = balance.to_le_bytes();
let nonce: Nonce = OsRng.gen::<[u8; NONCE_LEN]>();
Expand All @@ -76,7 +67,6 @@ impl AuthenticatedEncryption {

/// On input of an authenticated encryption key and a ciphertext, the function returns the
/// originally encrypted amount.
#[cfg(not(target_os = "solana"))]
fn decrypt(key: &AeKey, ciphertext: &AeCiphertext) -> Option<u64> {
let plaintext = Aes128GcmSiv::new(&key.0.into())
.decrypt(&ciphertext.nonce.into(), ciphertext.ciphertext.as_ref());
Expand Down
2 changes: 0 additions & 2 deletions zk-sdk/src/encryption/discrete_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
//! information on a discrete log solution depending on the execution time of the implementation.
//!
#![cfg(not(target_os = "solana"))]

#[cfg(not(target_arch = "wasm32"))]
use std::thread;
use {
Expand Down
45 changes: 8 additions & 37 deletions zk-sdk/src/encryption/elgamal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,11 @@ use {
crate::{
encryption::{
discrete_log::DiscreteLog,
pedersen::{
Pedersen, PedersenCommitment, PedersenOpening, G, H, PEDERSEN_COMMITMENT_LEN,
},
pedersen::{Pedersen, PedersenCommitment, PedersenOpening, G, H},
DECRYPT_HANDLE_LEN, ELGAMAL_CIPHERTEXT_LEN, ELGAMAL_KEYPAIR_LEN, ELGAMAL_PUBKEY_LEN,
ELGAMAL_SECRET_KEY_LEN, PEDERSEN_COMMITMENT_LEN,
},
errors::ElGamalError,
RISTRETTO_POINT_LEN, SCALAR_LEN,
},
base64::{prelude::BASE64_STANDARD, Engine},
core::ops::{Add, Mul, Sub},
Expand All @@ -31,7 +30,9 @@ use {
scalar::Scalar,
traits::Identity,
},
rand::rngs::OsRng,
serde::{Deserialize, Serialize},
sha3::{Digest, Sha3_512},
solana_sdk::{
derivation_path::DerivationPath,
signature::Signature,
Expand All @@ -40,43 +41,22 @@ use {
SeedDerivable, Signer, SignerError,
},
},
std::convert::TryInto,
subtle::{Choice, ConstantTimeEq},
zeroize::Zeroize,
};
#[cfg(not(target_os = "solana"))]
use {
rand::rngs::OsRng,
sha3::{Digest, Sha3_512},
std::{
convert::TryInto,
error, fmt,
io::{Read, Write},
path::Path,
},
subtle::{Choice, ConstantTimeEq},
zeroize::Zeroize,
};

/// Byte length of a decrypt handle
const DECRYPT_HANDLE_LEN: usize = RISTRETTO_POINT_LEN;

/// Byte length of an ElGamal ciphertext
const ELGAMAL_CIPHERTEXT_LEN: usize = PEDERSEN_COMMITMENT_LEN + DECRYPT_HANDLE_LEN;

/// Byte length of an ElGamal public key
const ELGAMAL_PUBKEY_LEN: usize = RISTRETTO_POINT_LEN;

/// Byte length of an ElGamal secret key
const ELGAMAL_SECRET_KEY_LEN: usize = SCALAR_LEN;

/// Byte length of an ElGamal keypair
pub const ELGAMAL_KEYPAIR_LEN: usize = ELGAMAL_PUBKEY_LEN + ELGAMAL_SECRET_KEY_LEN;

/// Algorithm handle for the twisted ElGamal encryption scheme
pub struct ElGamal;
impl ElGamal {
/// Generates an ElGamal keypair.
///
/// This function is randomized. It internally samples a scalar element using `OsRng`.
#[cfg(not(target_os = "solana"))]
#[allow(non_snake_case)]
fn keygen() -> ElGamalKeypair {
// secret scalar should be non-zero except with negligible probability
Expand All @@ -90,7 +70,6 @@ impl ElGamal {
/// Generates an ElGamal keypair from a scalar input that determines the ElGamal private key.
///
/// This function panics if the input scalar is zero, which is not a valid key.
#[cfg(not(target_os = "solana"))]
#[allow(non_snake_case)]
fn keygen_with_scalar(s: &Scalar) -> ElGamalKeypair {
let secret = ElGamalSecretKey(*s);
Expand All @@ -103,7 +82,6 @@ impl ElGamal {
/// corresponding ElGamal ciphertext.
///
/// This function is randomized. It internally samples a scalar element using `OsRng`.
#[cfg(not(target_os = "solana"))]
fn encrypt<T: Into<Scalar>>(public: &ElGamalPubkey, amount: T) -> ElGamalCiphertext {
let (commitment, opening) = Pedersen::new(amount);
let handle = public.decrypt_handle(&opening);
Expand All @@ -113,7 +91,6 @@ impl ElGamal {

/// On input a public key, amount, and Pedersen opening, the function returns the corresponding
/// ElGamal ciphertext.
#[cfg(not(target_os = "solana"))]
fn encrypt_with<T: Into<Scalar>>(
amount: T,
public: &ElGamalPubkey,
Expand All @@ -128,7 +105,6 @@ impl ElGamal {
/// On input an amount, the function returns a twisted ElGamal ciphertext where the associated
/// Pedersen opening is always zero. Since the opening is zero, any twisted ElGamal ciphertext
/// of this form is a valid ciphertext under any ElGamal public key.
#[cfg(not(target_os = "solana"))]
pub fn encode<T: Into<Scalar>>(amount: T) -> ElGamalCiphertext {
let commitment = Pedersen::encode(amount);
let handle = DecryptHandle(RistrettoPoint::identity());
Expand All @@ -141,7 +117,6 @@ impl ElGamal {
///
/// The output of this function is of type `DiscreteLog`. To recover, the originally encrypted
/// amount, use `DiscreteLog::decode`.
#[cfg(not(target_os = "solana"))]
fn decrypt(secret: &ElGamalSecretKey, ciphertext: &ElGamalCiphertext) -> DiscreteLog {
DiscreteLog::new(
*G,
Expand All @@ -154,7 +129,6 @@ impl ElGamal {
///
/// If the originally encrypted amount is not a positive 32-bit number, then the function
/// returns `None`.
#[cfg(not(target_os = "solana"))]
fn decrypt_u32(secret: &ElGamalSecretKey, ciphertext: &ElGamalCiphertext) -> Option<u64> {
let discrete_log_instance = Self::decrypt(secret, ciphertext);
discrete_log_instance.decode_u32()
Expand Down Expand Up @@ -194,7 +168,6 @@ impl ElGamalKeypair {
/// wallets, the signing key is not exposed in the API. Therefore, this function uses a signer
/// to sign a public seed and the resulting signature is then hashed to derive an ElGamal
/// keypair.
#[cfg(not(target_os = "solana"))]
#[allow(non_snake_case)]
pub fn new_from_signer(
signer: &dyn Signer,
Expand All @@ -208,7 +181,6 @@ impl ElGamalKeypair {
/// Generates the public and secret keys for ElGamal encryption.
///
/// This function is randomized. It internally samples a scalar element using `OsRng`.
#[cfg(not(target_os = "solana"))]
pub fn new_rand() -> Self {
ElGamal::keygen()
}
Expand Down Expand Up @@ -348,7 +320,6 @@ impl ElGamalPubkey {
/// Encrypts an amount under the public key.
///
/// This function is randomized. It internally samples a scalar element using `OsRng`.
#[cfg(not(target_os = "solana"))]
pub fn encrypt<T: Into<Scalar>>(&self, amount: T) -> ElGamalCiphertext {
ElGamal::encrypt(self, amount)
}
Expand Down
36 changes: 36 additions & 0 deletions zk-sdk/src/encryption/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,46 @@
//! - Basic type-wrapper around the AES-GCM-SIV symmetric authenticated encryption scheme
//! implemented by [aes-gcm-siv](https://docs.rs/aes-gcm-siv/latest/aes_gcm_siv/) crate.
use crate::{RISTRETTO_POINT_LEN, SCALAR_LEN};

#[cfg(not(target_os = "solana"))]
#[macro_use]
pub(crate) mod macros;
#[cfg(not(target_os = "solana"))]
pub mod auth_encryption;
#[cfg(not(target_os = "solana"))]
pub mod discrete_log;
#[cfg(not(target_os = "solana"))]
pub mod elgamal;
#[cfg(not(target_os = "solana"))]
pub mod grouped_elgamal;
#[cfg(not(target_os = "solana"))]
pub mod pedersen;

/// Byte length of an authenticated encryption secret key
pub const AE_KEY_LEN: usize = 16;

/// Byte length of a complete authenticated encryption ciphertext component that includes the
/// ciphertext and nonce components
pub const AE_CIPHERTEXT_LEN: usize = 36;

/// Byte length of a decrypt handle
pub const DECRYPT_HANDLE_LEN: usize = RISTRETTO_POINT_LEN;

/// Byte length of an ElGamal ciphertext
pub const ELGAMAL_CIPHERTEXT_LEN: usize = PEDERSEN_COMMITMENT_LEN + DECRYPT_HANDLE_LEN;

/// Byte length of an ElGamal public key
pub const ELGAMAL_PUBKEY_LEN: usize = RISTRETTO_POINT_LEN;

/// Byte length of an ElGamal secret key
pub const ELGAMAL_SECRET_KEY_LEN: usize = SCALAR_LEN;

/// Byte length of an ElGamal keypair
pub const ELGAMAL_KEYPAIR_LEN: usize = ELGAMAL_PUBKEY_LEN + ELGAMAL_SECRET_KEY_LEN;

/// Byte length of a Pedersen opening.
pub const PEDERSEN_OPENING_LEN: usize = SCALAR_LEN;

/// Byte length of a Pedersen commitment.
pub const PEDERSEN_COMMITMENT_LEN: usize = RISTRETTO_POINT_LEN;
13 changes: 2 additions & 11 deletions zk-sdk/src/encryption/pedersen.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,22 @@
//! Pedersen commitment implementation using the Ristretto prime-order group.
#[cfg(not(target_os = "solana"))]
use rand::rngs::OsRng;
use {
crate::{RISTRETTO_POINT_LEN, SCALAR_LEN},
crate::encryption::{PEDERSEN_COMMITMENT_LEN, PEDERSEN_OPENING_LEN},
core::ops::{Add, Mul, Sub},
curve25519_dalek::{
constants::{RISTRETTO_BASEPOINT_COMPRESSED, RISTRETTO_BASEPOINT_POINT},
ristretto::{CompressedRistretto, RistrettoPoint},
scalar::Scalar,
traits::MultiscalarMul,
},
rand::rngs::OsRng,
serde::{Deserialize, Serialize},
sha3::Sha3_512,
std::convert::TryInto,
subtle::{Choice, ConstantTimeEq},
zeroize::Zeroize,
};

/// Byte length of a Pedersen opening.
const PEDERSEN_OPENING_LEN: usize = SCALAR_LEN;

/// Byte length of a Pedersen commitment.
pub(crate) const PEDERSEN_COMMITMENT_LEN: usize = RISTRETTO_POINT_LEN;

lazy_static::lazy_static! {
/// Pedersen base point for encoding messages to be committed.
pub static ref G: RistrettoPoint = RISTRETTO_BASEPOINT_POINT;
Expand All @@ -39,7 +32,6 @@ impl Pedersen {
/// message and the corresponding opening.
///
/// This function is randomized. It internally samples a Pedersen opening using `OsRng`.
#[cfg(not(target_os = "solana"))]
#[allow(clippy::new_ret_no_self)]
pub fn new<T: Into<Scalar>>(amount: T) -> (PedersenCommitment, PedersenOpening) {
let opening = PedersenOpening::new_rand();
Expand Down Expand Up @@ -84,7 +76,6 @@ impl PedersenOpening {
&self.0
}

#[cfg(not(target_os = "solana"))]
pub fn new_rand() -> Self {
PedersenOpening(Scalar::random(&mut OsRng))
}
Expand Down
3 changes: 0 additions & 3 deletions zk-sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,10 @@
#![allow(clippy::arithmetic_side_effects, clippy::op_ref)]

pub mod elgamal_program;
#[cfg(not(target_os = "solana"))]
pub mod encryption;
pub mod errors;
mod range_proof;
#[cfg(not(target_os = "solana"))]
mod sigma_proofs;
#[cfg(not(target_os = "solana"))]
mod transcript;

/// Byte length of a compressed Ristretto point or scalar in Curve255519
Expand Down
8 changes: 8 additions & 0 deletions zk-sdk/src/sigma_proofs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,22 @@

pub mod errors;

#[cfg(not(target_os = "solana"))]
pub mod batched_grouped_ciphertext_validity;
#[cfg(not(target_os = "solana"))]
pub mod ciphertext_ciphertext_equality;
#[cfg(not(target_os = "solana"))]
pub mod ciphertext_commitment_equality;
#[cfg(not(target_os = "solana"))]
pub mod grouped_ciphertext_validity;
#[cfg(not(target_os = "solana"))]
pub mod percentage_with_cap;
#[cfg(not(target_os = "solana"))]
pub mod pubkey;
#[cfg(not(target_os = "solana"))]
pub mod zero_ciphertext;

#[cfg(not(target_os = "solana"))]
use {
crate::{sigma_proofs::errors::SigmaProofVerificationError, RISTRETTO_POINT_LEN, SCALAR_LEN},
curve25519_dalek::{ristretto::CompressedRistretto, scalar::Scalar},
Expand Down
Loading

0 comments on commit be73f30

Please sign in to comment.