mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-10 07:08:05 -05:00
crypto: Add MiMC VDF.
This commit is contained in:
13
Cargo.lock
generated
13
Cargo.lock
generated
@@ -1203,6 +1203,8 @@ dependencies = [
|
||||
"libsqlite3-sys",
|
||||
"log",
|
||||
"native-tls",
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"pasta_curves",
|
||||
"plotters",
|
||||
"rand",
|
||||
@@ -2624,6 +2626,17 @@ dependencies = [
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
|
||||
@@ -118,8 +118,8 @@ crypto_api_chachapoly = {version = "0.5.0", optional = true}
|
||||
incrementalmerkletree = {version = "0.3.0", optional = true}
|
||||
halo2_proofs = {version = "0.2.0", optional = true}
|
||||
halo2_gadgets = {version = "0.2.0", optional = true}
|
||||
#halo2_proofs = {git = "https://github.com/zcash/halo2.git", rev = "a898d65ae3ad3d41987666f6a03cfc15edae01c4", optional = true}
|
||||
#halo2_gadgets = {git = "https://github.com/zcash/halo2.git", rev = "a898d65ae3ad3d41987666f6a03cfc15edae01c4", optional = true}
|
||||
num-bigint = {version = "0.4.3", optional = true}
|
||||
num-traits = {version = "0.2.15", optional = true}
|
||||
|
||||
# Smart contract runtime
|
||||
drk-sdk = {path = "src/sdk", optional = true}
|
||||
@@ -138,9 +138,6 @@ sled = {version = "0.34.7", optional = true}
|
||||
clap = {version = "3.2.20", features = ["derive"]}
|
||||
halo2_proofs = {version = "0.2.0", features = ["dev-graph", "gadget-traces", "sanity-checks"]}
|
||||
halo2_gadgets = {version = "0.2.0", features = ["dev-graph", "test-dependencies"]}
|
||||
#halo2_proofs = {git = "https://github.com/zcash/halo2.git", rev = "a898d65ae3ad3d41987666f6a03cfc15edae01c4", features = ["dev-graph", "gadget-traces", "sanity-checks"]}
|
||||
#halo2_gadgets = {git = "https://github.com/zcash/halo2.git", rev = "a898d65ae3ad3d41987666f6a03cfc15edae01c4", features = ["dev-graph", "test-dependencies"]}
|
||||
|
||||
plotters = "0.3.3"
|
||||
|
||||
[features]
|
||||
@@ -241,6 +238,8 @@ crypto = [
|
||||
"incrementalmerkletree",
|
||||
"halo2_proofs",
|
||||
"halo2_gadgets",
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"subtle",
|
||||
"lazy_static",
|
||||
"group",
|
||||
|
||||
88
src/crypto/mimc_vdf.rs
Normal file
88
src/crypto/mimc_vdf.rs
Normal file
@@ -0,0 +1,88 @@
|
||||
//! https://vitalik.ca/general/2018/07/21/starks_part_3.html
|
||||
|
||||
use num_bigint::BigUint;
|
||||
use num_traits::Num;
|
||||
|
||||
/// Modulus of prime field 2^256 - 2^32 * 351 + 1
|
||||
pub const MODULUS: &str =
|
||||
"115792089237316195423570985008687907853269984665640564039457584006405596119041";
|
||||
|
||||
/// An exponent to perform inverse of x^3 on prime field based on Fermat's Little Theorem
|
||||
pub const L_FERMAT_EXPONENT: &str =
|
||||
"77194726158210796949047323339125271902179989777093709359638389337603730746027";
|
||||
|
||||
/// Calculates set of round constants to perform MiMC-calculation on.
|
||||
fn calculate_round_constants() -> [u64; 64] {
|
||||
let mut round_constants = [0u64; 64];
|
||||
for i in 0usize..64 {
|
||||
round_constants[i] = (i.pow(7) ^ 42) as u64;
|
||||
}
|
||||
|
||||
round_constants
|
||||
}
|
||||
|
||||
/// Executes `num_steps` of MiMC-calculation in forward direction for the given `input`
|
||||
fn forward_mimc(num_steps: u64, input: &BigUint) -> BigUint {
|
||||
let modulus = BigUint::from_str_radix(MODULUS, 10).unwrap();
|
||||
let round_constants = calculate_round_constants();
|
||||
|
||||
let mut result = input.clone();
|
||||
let three = BigUint::from(3_u64);
|
||||
for i in 1..num_steps {
|
||||
result = (result.modpow(&three, &modulus) +
|
||||
BigUint::from(round_constants[i as usize % round_constants.len()])) %
|
||||
&modulus;
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Executes `num_steps` of MiMC-calculation in backward direction for the given `input`.
|
||||
///
|
||||
/// The properties of MiMC-scheme guarantees that calculation in backward direction is
|
||||
/// always slower than in forward for correctly chosen parameters.
|
||||
fn backward_mimc(num_steps: u64, input: &BigUint) -> BigUint {
|
||||
let modulus = BigUint::from_str_radix(MODULUS, 10).unwrap();
|
||||
let l_fermat_exp = BigUint::from_str_radix(L_FERMAT_EXPONENT, 10).unwrap();
|
||||
let round_constants = calculate_round_constants();
|
||||
|
||||
let mut result = input.clone();
|
||||
for i in (1..num_steps).rev() {
|
||||
let round_constant = BigUint::from(round_constants[i as usize % round_constants.len()]);
|
||||
result = BigUint::from(&result - &round_constant).modpow(&l_fermat_exp, &modulus);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Performs an Eval() step of the MiMC-based VDF
|
||||
pub fn eval(seed: &BigUint, num_steps: u64) -> BigUint {
|
||||
let witness = backward_mimc(num_steps, &seed);
|
||||
|
||||
witness
|
||||
}
|
||||
|
||||
/// Performs a Verify() step for the MiMC-based VDF result
|
||||
pub fn verify(seed: &BigUint, num_steps: u64, witness: &BigUint) -> bool {
|
||||
let result = forward_mimc(num_steps, witness);
|
||||
|
||||
result == *seed
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn mimc_vdf_eval_and_verify() {
|
||||
let steps = 1000;
|
||||
let challenge = blake3::hash(b"69420").to_hex();
|
||||
let challenge = BigUint::from_str_radix(&challenge, 16).unwrap();
|
||||
|
||||
let witness = eval(&challenge, steps);
|
||||
assert!(verify(&challenge, steps, &witness));
|
||||
assert_eq!(false, verify(&(&challenge - 1_u64), steps, &witness));
|
||||
assert_eq!(false, verify(&challenge, steps - 1, &witness));
|
||||
assert_eq!(false, verify(&challenge, steps, &(&witness - 1_u64)));
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,9 @@ pub mod token_list;
|
||||
pub mod types;
|
||||
pub mod util;
|
||||
|
||||
/// VDF (Verifiable Delay Function) using MiMC
|
||||
pub mod mimc_vdf;
|
||||
|
||||
pub use burn_proof::BurnRevealedValues;
|
||||
pub use mint_proof::MintRevealedValues;
|
||||
pub use proof::Proof;
|
||||
|
||||
Reference in New Issue
Block a user