Wrap a struct around the discrete log precompute hashmap
This commit is contained in:
@ -23,8 +23,11 @@ pub struct DiscreteLog {
|
|||||||
pub target: RistrettoPoint,
|
pub target: RistrettoPoint,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct DecodeU32Precomputation(HashMap<[u8; 32], u32>);
|
||||||
|
|
||||||
/// Builds a HashMap of 2^18 elements
|
/// Builds a HashMap of 2^18 elements
|
||||||
pub fn decode_u32_precomputation(generator: RistrettoPoint) -> HashMap<[u8; 32], u32> {
|
fn decode_u32_precomputation(generator: RistrettoPoint) -> DecodeU32Precomputation {
|
||||||
let mut hashmap = HashMap::new();
|
let mut hashmap = HashMap::new();
|
||||||
|
|
||||||
let two12_scalar = Scalar::from(TWO14);
|
let two12_scalar = Scalar::from(TWO14);
|
||||||
@ -46,12 +49,12 @@ pub fn decode_u32_precomputation(generator: RistrettoPoint) -> HashMap<[u8; 32],
|
|||||||
});
|
});
|
||||||
println!(" [8/8] completed");
|
println!(" [8/8] completed");
|
||||||
|
|
||||||
hashmap
|
DecodeU32Precomputation(hashmap)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pre-compute HashMap needed for decryption. The HashMap is independent of (works for) any key.
|
/// Pre-compute HashMap needed for decryption. The HashMap is independent of (works for) any key.
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn decode_u32_precomputation_for_G() -> HashMap<[u8; 32], u32> {
|
pub fn decode_u32_precomputation_for_G() -> DecodeU32Precomputation {
|
||||||
decode_u32_precomputation(G)
|
decode_u32_precomputation(G)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,22 +62,21 @@ pub fn decode_u32_precomputation_for_G() -> HashMap<[u8; 32], u32> {
|
|||||||
impl DiscreteLog {
|
impl DiscreteLog {
|
||||||
/// Solves the discrete log problem under the assumption that the solution
|
/// Solves the discrete log problem under the assumption that the solution
|
||||||
/// is a 32-bit number.
|
/// is a 32-bit number.
|
||||||
pub fn decode_u32(self) -> Option<u32> {
|
pub(crate) fn decode_u32(self) -> Option<u32> {
|
||||||
let hashmap = decode_u32_precomputation(self.generator);
|
self.decode_u32_online(&decode_u32_precomputation(self.generator))
|
||||||
self.decode_u32_online(&hashmap)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Solves the discrete log instance using the pre-computed HashMap by enumerating through 2^14
|
/// Solves the discrete log instance using the pre-computed HashMap by enumerating through 2^14
|
||||||
/// possible solutions
|
/// possible solutions
|
||||||
pub fn decode_u32_online(self, hashmap: &HashMap<[u8; 32], u32>) -> Option<u32> {
|
pub fn decode_u32_online(self, hashmap: &DecodeU32Precomputation) -> Option<u32> {
|
||||||
// iterator for 0G, -1G, -2G, ...
|
// iterator for 0G, -1G, -2G, ...
|
||||||
let ristretto_iter = RistrettoIterator::new(self.target, -self.generator);
|
let ristretto_iter = RistrettoIterator::new(self.target, -self.generator);
|
||||||
|
|
||||||
let mut decoded = None;
|
let mut decoded = None;
|
||||||
ristretto_iter.zip(0..TWO14).for_each(|(elem, x_lo)| {
|
ristretto_iter.zip(0..TWO14).for_each(|(elem, x_lo)| {
|
||||||
let key = elem.compress().to_bytes();
|
let key = elem.compress().to_bytes();
|
||||||
if hashmap.contains_key(&key) {
|
if hashmap.0.contains_key(&key) {
|
||||||
let x_hi = hashmap[&key];
|
let x_hi = hashmap.0[&key];
|
||||||
decoded = Some(x_lo + TWO14 * x_hi);
|
decoded = Some(x_lo + TWO14 * x_hi);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use {
|
use {
|
||||||
crate::encryption::{
|
crate::encryption::{
|
||||||
discrete_log::DiscreteLog,
|
discrete_log::{DecodeU32Precomputation, DiscreteLog},
|
||||||
pedersen::{
|
pedersen::{
|
||||||
Pedersen, PedersenBase, PedersenCommitment, PedersenDecryptHandle, PedersenOpening,
|
Pedersen, PedersenBase, PedersenCommitment, PedersenDecryptHandle, PedersenOpening,
|
||||||
},
|
},
|
||||||
@ -19,7 +19,7 @@ use {
|
|||||||
signature::Signature,
|
signature::Signature,
|
||||||
signer::{Signer, SignerError},
|
signer::{Signer, SignerError},
|
||||||
},
|
},
|
||||||
std::{collections::HashMap, convert::TryInto},
|
std::convert::TryInto,
|
||||||
subtle::{Choice, ConstantTimeEq},
|
subtle::{Choice, ConstantTimeEq},
|
||||||
zeroize::Zeroize,
|
zeroize::Zeroize,
|
||||||
};
|
};
|
||||||
@ -120,7 +120,7 @@ impl ElGamal {
|
|||||||
fn decrypt_u32_online(
|
fn decrypt_u32_online(
|
||||||
secret: &ElGamalSecretKey,
|
secret: &ElGamalSecretKey,
|
||||||
ct: &ElGamalCiphertext,
|
ct: &ElGamalCiphertext,
|
||||||
hashmap: &HashMap<[u8; 32], u32>,
|
hashmap: &DecodeU32Precomputation,
|
||||||
) -> Option<u32> {
|
) -> Option<u32> {
|
||||||
let discrete_log_instance = Self::decrypt(secret, ct);
|
let discrete_log_instance = Self::decrypt(secret, ct);
|
||||||
discrete_log_instance.decode_u32_online(hashmap)
|
discrete_log_instance.decode_u32_online(hashmap)
|
||||||
@ -337,7 +337,7 @@ impl ElGamalSecretKey {
|
|||||||
pub fn decrypt_u32_online(
|
pub fn decrypt_u32_online(
|
||||||
&self,
|
&self,
|
||||||
ct: &ElGamalCiphertext,
|
ct: &ElGamalCiphertext,
|
||||||
hashmap: &HashMap<[u8; 32], u32>,
|
hashmap: &DecodeU32Precomputation,
|
||||||
) -> Option<u32> {
|
) -> Option<u32> {
|
||||||
ElGamal::decrypt_u32_online(self, ct, hashmap)
|
ElGamal::decrypt_u32_online(self, ct, hashmap)
|
||||||
}
|
}
|
||||||
@ -429,7 +429,7 @@ impl ElGamalCiphertext {
|
|||||||
pub fn decrypt_u32_online(
|
pub fn decrypt_u32_online(
|
||||||
&self,
|
&self,
|
||||||
secret: &ElGamalSecretKey,
|
secret: &ElGamalSecretKey,
|
||||||
hashmap: &HashMap<[u8; 32], u32>,
|
hashmap: &DecodeU32Precomputation,
|
||||||
) -> Option<u32> {
|
) -> Option<u32> {
|
||||||
ElGamal::decrypt_u32_online(secret, self, hashmap)
|
ElGamal::decrypt_u32_online(secret, self, hashmap)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user