Avoid runtime discrete log table precomputation

This commit is contained in:
Michael Vines
2021-10-27 10:19:02 -07:00
parent c1db2b4866
commit 15aea0fe47
4 changed files with 33 additions and 17 deletions

View File

@ -23,6 +23,7 @@ byteorder = "1"
cipher = "0.3" cipher = "0.3"
curve25519-dalek = { version = "3.2.0", features = ["serde"]} curve25519-dalek = { version = "3.2.0", features = ["serde"]}
getrandom = { version = "0.1", features = ["dummy"] } getrandom = { version = "0.1", features = ["dummy"] }
lazy_static = "1.4.0"
merlin = "2" merlin = "2"
rand = "0.7" rand = "0.7"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }

View File

@ -1,8 +1,7 @@
#![cfg(not(target_arch = "bpf"))]
use { use {
curve25519_dalek::{ curve25519_dalek::{ristretto::RistrettoPoint, scalar::Scalar, traits::Identity},
constants::RISTRETTO_BASEPOINT_POINT as G, ristretto::RistrettoPoint, scalar::Scalar,
traits::Identity,
},
serde::{Deserialize, Serialize}, serde::{Deserialize, Serialize},
std::collections::HashMap, std::collections::HashMap,
}; };
@ -23,7 +22,7 @@ pub struct DiscreteLog {
pub target: RistrettoPoint, pub target: RistrettoPoint,
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Default)]
pub struct DecodeU32Precomputation(HashMap<[u8; 32], u32>); pub struct DecodeU32Precomputation(HashMap<[u8; 32], u32>);
/// Builds a HashMap of 2^18 elements /// Builds a HashMap of 2^18 elements
@ -52,10 +51,13 @@ fn decode_u32_precomputation(generator: RistrettoPoint) -> DecodeU32Precomputati
DecodeU32Precomputation(hashmap) DecodeU32Precomputation(hashmap)
} }
/// Pre-compute HashMap needed for decryption. The HashMap is independent of (works for) any key. lazy_static::lazy_static! {
#[allow(non_snake_case)] /// Pre-computed HashMap needed for decryption. The HashMap is independent of (works for) any key.
pub fn decode_u32_precomputation_for_G() -> DecodeU32Precomputation { pub static ref DECODE_U32_PRECOMPUTATION_FOR_G: DecodeU32Precomputation = {
decode_u32_precomputation(G) 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 /// Solves the discrete log instance using a 18/14 bit offline/online split
@ -111,7 +113,24 @@ impl Iterator for RistrettoIterator {
#[cfg(test)] #[cfg(test)]
mod tests { 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 /// Discrete log test for 16/16 split
/// ///

View File

@ -464,9 +464,7 @@ pub fn combine_u32_ciphertexts(ct_lo: ElGamalCiphertext, ct_hi: ElGamalCiphertex
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
use crate::encryption::{ use crate::encryption::{discrete_log, elgamal::ElGamalKeypair};
discrete_log::decode_u32_precomputation_for_G, elgamal::ElGamalKeypair,
};
#[test] #[test]
fn test_transfer_correctness() { fn test_transfer_correctness() {
@ -530,12 +528,10 @@ mod test {
auditor_pk, auditor_pk,
); );
let decryption_data = decode_u32_precomputation_for_G();
let source_ciphertext = transfer_data.source_ciphertext().unwrap(); let source_ciphertext = transfer_data.source_ciphertext().unwrap();
assert_eq!( assert_eq!(
source_ciphertext source_ciphertext
.decrypt_u32_online(&source_sk, &decryption_data) .decrypt_u32_online(&source_sk, &discrete_log::DECODE_U32_PRECOMPUTATION_FOR_G)
.unwrap(), .unwrap(),
55_u32 55_u32
); );
@ -543,7 +539,7 @@ mod test {
let dest_ciphertext = transfer_data.dest_ciphertext().unwrap(); let dest_ciphertext = transfer_data.dest_ciphertext().unwrap();
assert_eq!( assert_eq!(
dest_ciphertext dest_ciphertext
.decrypt_u32_online(&dest_sk, &decryption_data) .decrypt_u32_online(&dest_sk, &discrete_log::DECODE_U32_PRECOMPUTATION_FOR_G)
.unwrap(), .unwrap(),
55_u32 55_u32
); );