diff --git a/zk-token-sdk/Cargo.toml b/zk-token-sdk/Cargo.toml index 35baa54c1a..58b4626d7b 100644 --- a/zk-token-sdk/Cargo.toml +++ b/zk-token-sdk/Cargo.toml @@ -23,6 +23,7 @@ byteorder = "1" cipher = "0.3" curve25519-dalek = { version = "3.2.0", features = ["serde"]} getrandom = { version = "0.1", features = ["dummy"] } +lazy_static = "1.4.0" merlin = "2" rand = "0.7" serde = { version = "1.0", features = ["derive"] } diff --git a/zk-token-sdk/src/encryption/decode_u32_precomputation_for_G.bincode b/zk-token-sdk/src/encryption/decode_u32_precomputation_for_G.bincode new file mode 100644 index 0000000000..eb8b2a15a6 Binary files /dev/null and b/zk-token-sdk/src/encryption/decode_u32_precomputation_for_G.bincode differ diff --git a/zk-token-sdk/src/encryption/discrete_log.rs b/zk-token-sdk/src/encryption/discrete_log.rs index 1279148d45..5f7c92879e 100644 --- a/zk-token-sdk/src/encryption/discrete_log.rs +++ b/zk-token-sdk/src/encryption/discrete_log.rs @@ -1,8 +1,7 @@ +#![cfg(not(target_arch = "bpf"))] + use { - curve25519_dalek::{ - constants::RISTRETTO_BASEPOINT_POINT as G, ristretto::RistrettoPoint, scalar::Scalar, - traits::Identity, - }, + curve25519_dalek::{ristretto::RistrettoPoint, scalar::Scalar, traits::Identity}, serde::{Deserialize, Serialize}, std::collections::HashMap, }; @@ -23,7 +22,7 @@ pub struct DiscreteLog { pub target: RistrettoPoint, } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Default)] pub struct DecodeU32Precomputation(HashMap<[u8; 32], u32>); /// Builds a HashMap of 2^18 elements @@ -52,10 +51,13 @@ fn decode_u32_precomputation(generator: RistrettoPoint) -> DecodeU32Precomputati DecodeU32Precomputation(hashmap) } -/// Pre-compute HashMap needed for decryption. The HashMap is independent of (works for) any key. -#[allow(non_snake_case)] -pub fn decode_u32_precomputation_for_G() -> DecodeU32Precomputation { - decode_u32_precomputation(G) +lazy_static::lazy_static! { + /// Pre-computed HashMap needed for decryption. The HashMap is independent of (works for) any key. + pub static ref DECODE_U32_PRECOMPUTATION_FOR_G: DecodeU32Precomputation = { + static DECODE_U32_PRECOMPUTATION_FOR_G_BINCODE: &[u8] = + include_bytes!("decode_u32_precomputation_for_G.bincode"); + bincode::deserialize(DECODE_U32_PRECOMPUTATION_FOR_G_BINCODE).unwrap_or_default() + }; } /// Solves the discrete log instance using a 18/14 bit offline/online split @@ -111,7 +113,24 @@ impl Iterator for RistrettoIterator { #[cfg(test)] mod tests { - use super::*; + use {super::*, curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT as G}; + + #[test] + #[allow(non_snake_case)] + fn test_serialize_decode_u32_precomputation_for_G() { + let decode_u32_precomputation_for_G = decode_u32_precomputation(G); + + if decode_u32_precomputation_for_G.0 != DECODE_U32_PRECOMPUTATION_FOR_G.0 { + use std::{fs::File, io::Write, path::PathBuf}; + let mut f = File::create(PathBuf::from( + "src/encryption/decode_u32_precomputation_for_G.bincode", + )) + .unwrap(); + f.write_all(&bincode::serialize(&decode_u32_precomputation_for_G).unwrap()) + .unwrap(); + panic!("Rebuild and run this test again"); + } + } /// Discrete log test for 16/16 split /// diff --git a/zk-token-sdk/src/instruction/transfer.rs b/zk-token-sdk/src/instruction/transfer.rs index f78d36dac4..1063c3b405 100644 --- a/zk-token-sdk/src/instruction/transfer.rs +++ b/zk-token-sdk/src/instruction/transfer.rs @@ -464,9 +464,7 @@ pub fn combine_u32_ciphertexts(ct_lo: ElGamalCiphertext, ct_hi: ElGamalCiphertex #[cfg(test)] mod test { use super::*; - use crate::encryption::{ - discrete_log::decode_u32_precomputation_for_G, elgamal::ElGamalKeypair, - }; + use crate::encryption::{discrete_log, elgamal::ElGamalKeypair}; #[test] fn test_transfer_correctness() { @@ -530,12 +528,10 @@ mod test { auditor_pk, ); - let decryption_data = decode_u32_precomputation_for_G(); - let source_ciphertext = transfer_data.source_ciphertext().unwrap(); assert_eq!( source_ciphertext - .decrypt_u32_online(&source_sk, &decryption_data) + .decrypt_u32_online(&source_sk, &discrete_log::DECODE_U32_PRECOMPUTATION_FOR_G) .unwrap(), 55_u32 ); @@ -543,7 +539,7 @@ mod test { let dest_ciphertext = transfer_data.dest_ciphertext().unwrap(); assert_eq!( dest_ciphertext - .decrypt_u32_online(&dest_sk, &decryption_data) + .decrypt_u32_online(&dest_sk, &discrete_log::DECODE_U32_PRECOMPUTATION_FOR_G) .unwrap(), 55_u32 );