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"
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"] }

View File

@ -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
///

View File

@ -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
);