Avoid runtime discrete log table precomputation
This commit is contained in:
@ -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"] }
|
||||||
|
Binary file not shown.
@ -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
|
||||||
///
|
///
|
||||||
|
@ -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
|
||||||
);
|
);
|
||||||
|
Reference in New Issue
Block a user