diff --git a/doc/src/spec/crypto-schemes.md b/doc/src/spec/crypto-schemes.md index cb02ab150..b2f784dd6 100644 --- a/doc/src/spec/crypto-schemes.md +++ b/doc/src/spec/crypto-schemes.md @@ -36,7 +36,7 @@ DarkFi uses the elliptic curves Pallas and Vesta that form a 2-cycle. We denote Pallas by $ₚ$ and Vesta by $ᵥ$. Set the following values: $$ p = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001 $$ -$$ q = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 $$ +$$ v = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 $$ We now construct the base field for each curve $Kₚ$ and $Kᵥ$ as $Kₚ = 𝔽ₚ$ and $Kᵥ = 𝔽_q$. diff --git a/doc/theme/index.hbs b/doc/theme/index.bak.hbs similarity index 100% rename from doc/theme/index.hbs rename to doc/theme/index.bak.hbs diff --git a/script/research/zk/ecip-bench/src/circuit.rs b/script/research/zk/ecip-bench/src/circuit.rs index c5bfa7814..a0342c3e0 100644 --- a/script/research/zk/ecip-bench/src/circuit.rs +++ b/script/research/zk/ecip-bench/src/circuit.rs @@ -151,7 +151,7 @@ impl Circuit for EcipCircuit { assign_free_advice(layouter.namespace(|| "Witness s1"), config.advices[0], self.s1)?; let s1 = - ScalarVar::from_base(config.ecc_chip(), layouter.namespace(|| "mod_r_p(s1)"), &s1)?; + ScalarVar::from_base(config.ecc_chip(), layouter.namespace(|| "fp_mod_fv(s1)"), &s1)?; let (r, _) = g1.mul(layouter.namespace(|| "g1 * s1"), s1)?; @@ -168,7 +168,7 @@ impl Circuit for EcipCircuit { #[cfg(test)] mod tests { use super::*; - use darkfi_sdk::crypto::{pasta_prelude::Group, util::mod_r_p}; + use darkfi_sdk::crypto::{pasta_prelude::Group, util::fp_mod_fv}; use halo2_proofs::{ arithmetic::{CurveAffine, Field}, dev::MockProver, @@ -184,7 +184,7 @@ mod tests { let circuit = EcipCircuit { g1: Value::known(g1), s1: Value::known(s1) }; - let g1s1 = g1 * mod_r_p(s1); + let g1s1 = g1 * fp_mod_fv(s1); let g1s1_coords = g1s1.to_affine().coordinates().unwrap(); let public_inputs = vec![*g1s1_coords.x(), *g1s1_coords.y()]; diff --git a/src/consensus/lead_coin.rs b/src/consensus/lead_coin.rs index ff216303d..432d44616 100644 --- a/src/consensus/lead_coin.rs +++ b/src/consensus/lead_coin.rs @@ -20,7 +20,7 @@ use darkfi_sdk::{ crypto::{ pedersen::{pedersen_commitment_base, pedersen_commitment_u64}, poseidon_hash, - util::mod_r_p, + util::fp_mod_fv, MerkleNode, MerkleTree, SecretKey, }, pasta::{arithmetic::CurveAffine, group::Curve, pallas}, @@ -484,7 +484,7 @@ impl LeadCoinSecrets { let secret = if i == 0 { pedersen_commitment_u64(1, pallas::Scalar::random(&mut OsRng)) } else { - pedersen_commitment_u64(1, mod_r_p(prev_sk.inner())) + pedersen_commitment_u64(1, fp_mod_fv(prev_sk.inner())) }; let secret_coords = secret.to_affine().coordinates().unwrap(); diff --git a/src/contract/dao/src/client/vote.rs b/src/contract/dao/src/client/vote.rs index 9ce1187e5..fa1ab3e67 100644 --- a/src/contract/dao/src/client/vote.rs +++ b/src/contract/dao/src/client/vote.rs @@ -22,7 +22,7 @@ use darkfi_sdk::{ bridgetree::Hashable, crypto::{ note::ElGamalEncryptedNote, pasta_prelude::*, pedersen_commitment_u64, poseidon_hash, - util::mod_p_r_unsafe, Keypair, MerkleNode, Nullifier, PublicKey, SecretKey, + util::fv_mod_fp_unsafe, Keypair, MerkleNode, Nullifier, PublicKey, SecretKey, }, pasta::pallas, }; @@ -85,7 +85,7 @@ impl DaoVoteCall { // It's near zero chance it ever loops at all. // P(random 𝔽ᵥ ∉ 𝔽ₚ) = (q - p)/q = 2.99 × 10⁻⁵¹ loop { - let av_blind = mod_p_r_unsafe(all_vote_blind + value_blind); + let av_blind = fv_mod_fp_unsafe(all_vote_blind + value_blind); if av_blind.is_none().into() { value_blind = pallas::Scalar::random(&mut OsRng); @@ -193,7 +193,7 @@ impl DaoVoteCall { // Create a random blind b ∈ 𝔽ᵥ, such that b ∈ 𝔽ₚ let yes_vote_blind = loop { let blind = pallas::Scalar::random(&mut OsRng); - if mod_p_r_unsafe(blind).is_some().into() { + if fv_mod_fp_unsafe(blind).is_some().into() { break blind } }; @@ -206,8 +206,8 @@ impl DaoVoteCall { // Convert blinds to 𝔽ₚ, which should work fine since we selected them // to be convertable. - let yes_vote_blind = mod_p_r_unsafe(yes_vote_blind).unwrap(); - let all_vote_blind = mod_p_r_unsafe(all_vote_blind).unwrap(); + let yes_vote_blind = fv_mod_fp_unsafe(yes_vote_blind).unwrap(); + let all_vote_blind = fv_mod_fp_unsafe(all_vote_blind).unwrap(); let vote_option = pallas::Base::from(vote_option); let all_vote_value_fp = pallas::Base::from(all_vote_value); diff --git a/src/contract/dao/tests/integration.rs b/src/contract/dao/tests/integration.rs index 256fde6a6..86a9ef947 100644 --- a/src/contract/dao/tests/integration.rs +++ b/src/contract/dao/tests/integration.rs @@ -24,7 +24,7 @@ use darkfi_sdk::{ crypto::{ pasta_prelude::*, pedersen_commitment_u64, - util::{fp_to_u64, mod_r_p}, + util::{fp_mod_fv, fp_to_u64}, DAO_CONTRACT_ID, DARK_TOKEN_ID, }, pasta::pallas, @@ -283,9 +283,9 @@ fn integration_test() -> Result<()> { // all_vote_blind, // ] let vote_option = fp_to_u64(note[0]).unwrap(); - let yes_vote_blind = mod_r_p(note[1]); + let yes_vote_blind = fp_mod_fv(note[1]); let all_vote_value = fp_to_u64(note[2]).unwrap(); - let all_vote_blind = mod_r_p(note[3]); + let all_vote_blind = fp_mod_fv(note[3]); assert!(vote_option == 0 || vote_option == 1); total_yes_vote_blind += yes_vote_blind; diff --git a/src/sdk/python/src/pasta.rs b/src/sdk/python/src/pasta.rs index 4d02a9dfc..1e8acf6b2 100644 --- a/src/sdk/python/src/pasta.rs +++ b/src/sdk/python/src/pasta.rs @@ -291,8 +291,8 @@ pub fn nullifier_k() -> EpAffine { #[pyfunction] /// Convert Fp to Fq safely. -pub fn mod_r_p(x: &PyCell) -> PyResult { - Ok(Fq(util::mod_r_p(x.borrow().deref().0))) +pub fn fp_mod_fv(x: &PyCell) -> PyResult { + Ok(Fq(util::fp_mod_fv(x.borrow().deref().0))) } pub fn create_module(py: pyo3::Python<'_>) -> PyResult<&PyModule> { @@ -306,7 +306,7 @@ pub fn create_module(py: pyo3::Python<'_>) -> PyResult<&PyModule> { submod.add_class::()?; submod.add_function(wrap_pyfunction!(nullifier_k, submod)?)?; - submod.add_function(wrap_pyfunction!(mod_r_p, submod)?)?; + submod.add_function(wrap_pyfunction!(fp_mod_fv, submod)?)?; Ok(submod) } diff --git a/src/sdk/src/crypto/diffie_hellman.rs b/src/sdk/src/crypto/diffie_hellman.rs index 8eb3b4277..f28c7b0e4 100644 --- a/src/sdk/src/crypto/diffie_hellman.rs +++ b/src/sdk/src/crypto/diffie_hellman.rs @@ -19,14 +19,14 @@ use blake2b_simd::{Hash as Blake2bHash, Params as Blake2bParams}; use pasta_curves::group::{GroupEncoding, Wnaf}; -use super::{util::mod_r_p, PublicKey, SecretKey}; +use super::{util::fp_mod_fv, PublicKey, SecretKey}; pub const KDF_SAPLING_PERSONALIZATION: &[u8; 16] = b"DarkFiSaplingKDF"; /// Sapling key agreement for note encryption. /// Implements section 5.4.4.3 of the Zcash Protocol Specification pub fn sapling_ka_agree(esk: &SecretKey, pk_d: &PublicKey) -> PublicKey { - let esk_s = mod_r_p(esk.inner()); + let esk_s = fp_mod_fv(esk.inner()); // Windowed multiplication is constant time. Hence that is used here vs naive EC mult. // Decrypting notes is a an amortized operation, so you want successful rare-case note // decryptions to be indistinguishable from the usual case. diff --git a/src/sdk/src/crypto/ecvrf.rs b/src/sdk/src/crypto/ecvrf.rs index 6635808e1..8954f0ac7 100644 --- a/src/sdk/src/crypto/ecvrf.rs +++ b/src/sdk/src/crypto/ecvrf.rs @@ -33,7 +33,7 @@ use pasta_curves::{ }; use rand_core::{CryptoRng, RngCore}; -use super::{constants::NullifierK, util::mod_r_p, PublicKey, SecretKey}; +use super::{constants::NullifierK, util::fp_mod_fv, PublicKey, SecretKey}; /// Prefix domain used for `hash_to_curve` calls const VRF_DOMAIN: &str = "DarkFi_ECVRF"; @@ -57,7 +57,7 @@ impl VrfProof { message.extend_from_slice(alpha_string); let H = pallas::Point::hash_to_curve(VRF_DOMAIN)(&message); - let gamma = H * mod_r_p(x.inner()); + let gamma = H * fp_mod_fv(x.inner()); let k = pallas::Scalar::random(rng); let mut hasher = blake3::Hasher::new(); @@ -73,7 +73,7 @@ impl VrfProof { c_scalar[..blake3::OUT_LEN].copy_from_slice(c.as_bytes()); let c_scalar = pallas::Scalar::from_uniform_bytes(&c_scalar); - let s = k + c_scalar * mod_r_p(x.inner()); + let s = k + c_scalar * fp_mod_fv(x.inner()); Self { gamma, c, s } } diff --git a/src/sdk/src/crypto/keypair.rs b/src/sdk/src/crypto/keypair.rs index aceb3ffd0..cb882b52e 100644 --- a/src/sdk/src/crypto/keypair.rs +++ b/src/sdk/src/crypto/keypair.rs @@ -32,7 +32,7 @@ use pasta_curves::{ }; use rand_core::{CryptoRng, RngCore}; -use super::{constants::NullifierK, util::mod_r_p}; +use super::{constants::NullifierK, util::fp_mod_fv}; use crate::error::ContractError; /// Keypair structure holding a `SecretKey` and its respective `PublicKey` @@ -129,7 +129,7 @@ impl PublicKey { /// Derive a new `PublicKey` object given a `SecretKey` pub fn from_secret(s: SecretKey) -> Self { - let p = NullifierK.generator() * mod_r_p(s.inner()); + let p = NullifierK.generator() * fp_mod_fv(s.inner()); Self(p) } diff --git a/src/sdk/src/crypto/note.rs b/src/sdk/src/crypto/note.rs index cfac5206f..9b1c034b2 100644 --- a/src/sdk/src/crypto/note.rs +++ b/src/sdk/src/crypto/note.rs @@ -24,7 +24,7 @@ use rand_core::{CryptoRng, RngCore}; #[cfg(feature = "async")] use darkfi_serial::async_trait; -use super::{diffie_hellman, poseidon_hash, util::mod_r_p, PublicKey, SecretKey}; +use super::{diffie_hellman, poseidon_hash, util::fp_mod_fv, PublicKey, SecretKey}; use crate::error::ContractError; /// AEAD tag length in bytes @@ -96,7 +96,7 @@ impl ElGamalEncryptedNote { ) -> Self { // Derive shared secret using DH let ephem_public = PublicKey::from_secret(*ephem_secret); - let (ss_x, ss_y) = PublicKey::from(public.inner() * mod_r_p(ephem_secret.inner())).xy(); + let (ss_x, ss_y) = PublicKey::from(public.inner() * fp_mod_fv(ephem_secret.inner())).xy(); let shared_secret = poseidon_hash([ss_x, ss_y]); let mut blinds = [pallas::Base::ZERO; N]; @@ -115,7 +115,7 @@ impl ElGamalEncryptedNote { pub fn decrypt(&self, secret: &SecretKey) -> [pallas::Base; N] { // Derive shared secret using DH let (ss_x, ss_y) = - PublicKey::from(self.ephem_public.inner() * mod_r_p(secret.inner())).xy(); + PublicKey::from(self.ephem_public.inner() * fp_mod_fv(secret.inner())).xy(); let shared_secret = poseidon_hash([ss_x, ss_y]); let mut blinds = [pallas::Base::ZERO; N]; diff --git a/src/sdk/src/crypto/pedersen.rs b/src/sdk/src/crypto/pedersen.rs index d7be1b98c..e6d4a447e 100644 --- a/src/sdk/src/crypto/pedersen.rs +++ b/src/sdk/src/crypto/pedersen.rs @@ -26,7 +26,7 @@ use super::{ }, NullifierK, }, - util::mod_r_p, + util::fp_mod_fv, }; /// Pedersen commitment for a full-width base field element. @@ -36,7 +36,7 @@ pub fn pedersen_commitment_base(value: pallas::Base, blind: pallas::Scalar) -> p let V = NullifierK.generator(); let R = hasher(&VALUE_COMMITMENT_R_BYTES); - V * mod_r_p(value) + R * blind + V * fp_mod_fv(value) + R * blind } /// Pedersen commitment for a 64-bit value, in the base field. @@ -46,5 +46,5 @@ pub fn pedersen_commitment_u64(value: u64, blind: pallas::Scalar) -> pallas::Poi let V = hasher(&VALUE_COMMITMENT_V_BYTES); let R = hasher(&VALUE_COMMITMENT_R_BYTES); - V * mod_r_p(pallas::Base::from(value)) + R * blind + V * fp_mod_fv(pallas::Base::from(value)) + R * blind } diff --git a/src/sdk/src/crypto/schnorr.rs b/src/sdk/src/crypto/schnorr.rs index 3b5426d97..b9110c733 100644 --- a/src/sdk/src/crypto/schnorr.rs +++ b/src/sdk/src/crypto/schnorr.rs @@ -28,7 +28,7 @@ use rand_core::{CryptoRng, RngCore}; use super::{ constants::{NullifierK, DRK_SCHNORR_DOMAIN}, - util::{hash_to_scalar, mod_r_p}, + util::{fp_mod_fv, hash_to_scalar}, PublicKey, SecretKey, }; @@ -65,7 +65,7 @@ impl SchnorrSecret for SecretKey { let commit = NullifierK.generator() * mask; let challenge = hash_to_scalar(DRK_SCHNORR_DOMAIN, &commit.to_bytes(), message); - let response = mask + challenge * mod_r_p(self.inner()); + let response = mask + challenge * fp_mod_fv(self.inner()); Signature { commit, response } } diff --git a/src/sdk/src/crypto/util.rs b/src/sdk/src/crypto/util.rs index 4d7def6a5..ac5d16a99 100644 --- a/src/sdk/src/crypto/util.rs +++ b/src/sdk/src/crypto/util.rs @@ -39,16 +39,16 @@ pub fn hash_to_scalar(persona: &[u8], a: &[u8], b: &[u8]) -> pallas::Scalar { /// /// This requires no modular reduction because Pallas' base field is smaller than its /// scalar field. -pub fn mod_r_p(x: pallas::Base) -> pallas::Scalar { - pallas::Scalar::from_repr(x.to_repr()).unwrap() +pub fn fp_mod_fv(val: pallas::Base) -> pallas::Scalar { + pallas::Scalar::from_repr(val.to_repr()).unwrap() } /// Converts from pallas::Scalar to pallas::Base (aka $x \pmod{r_\mathbb{P}}$). /// /// This call is unsafe and liable to fail. Use with caution. /// The Pallas scalar field is bigger than the field we're converting to here. -pub fn mod_p_r_unsafe(x: pallas::Scalar) -> CtOption { - pallas::Base::from_repr(x.to_repr()) +pub fn fv_mod_fp_unsafe(val: pallas::Scalar) -> CtOption { + pallas::Base::from_repr(val.to_repr()) } /// Wrapper around poseidon in `halo2_gadgets` @@ -62,18 +62,20 @@ pub fn poseidon_hash(messages: [pallas::Base; N]) -> pallas::Bas .hash(messages) } -pub fn fp_to_u64(v: pallas::Base) -> Option { - let repr = v.to_repr(); +pub fn fp_to_u64(value: pallas::Base) -> Option { + let repr = value.to_repr(); if !repr[8..].iter().all(|&b| b == 0u8) { return None } let mut cur = Cursor::new(&repr[0..8]); - let val = ReadExt::read_u64(&mut cur).ok()?; - Some(val) + let uint = ReadExt::read_u64(&mut cur).ok()?; + Some(uint) } #[test] fn test_fp_to_u64() { + use super::pasta_prelude::Field; + let fp = pallas::Base::from(u64::MAX); assert_eq!(fp_to_u64(fp), Some(u64::MAX)); assert_eq!(fp_to_u64(fp + pallas::Base::ONE), None); diff --git a/tests/halo2_vk_ser.rs b/tests/halo2_vk_ser.rs index d3c2c170c..8512993db 100644 --- a/tests/halo2_vk_ser.rs +++ b/tests/halo2_vk_ser.rs @@ -18,7 +18,8 @@ use std::io::Cursor; use darkfi_sdk::crypto::{ - pedersen::pedersen_commitment_u64, util::mod_r_p, MerkleNode, MerkleTree, PublicKey, SecretKey, + pedersen::pedersen_commitment_u64, util::fp_mod_fv, MerkleNode, MerkleTree, PublicKey, + SecretKey, }; use halo2_gadgets::poseidon::{ primitives as poseidon, @@ -116,7 +117,7 @@ fn halo2_vk_ser() -> Result<()> { let ephem_secret = SecretKey::random(&mut OsRng); let pubkey = PublicKey::from_secret(ephem_secret).inner(); - let (ephem_x, ephem_y) = PublicKey::from(pubkey * mod_r_p(ephem_secret.inner())).xy(); + let (ephem_x, ephem_y) = PublicKey::from(pubkey * fp_mod_fv(ephem_secret.inner())).xy(); let prover_witnesses = vec![ Witness::Base(Value::known(pallas::Base::from(value))), Witness::Scalar(Value::known(value_blind)), diff --git a/tests/zkvm_opcodes.rs b/tests/zkvm_opcodes.rs index 7034a846c..ac32300a8 100644 --- a/tests/zkvm_opcodes.rs +++ b/tests/zkvm_opcodes.rs @@ -17,7 +17,8 @@ */ use darkfi_sdk::crypto::{ - pedersen::pedersen_commitment_u64, util::mod_r_p, MerkleNode, MerkleTree, PublicKey, SecretKey, + pedersen::pedersen_commitment_u64, util::fp_mod_fv, MerkleNode, MerkleTree, PublicKey, + SecretKey, }; use halo2_gadgets::poseidon::{ primitives as poseidon, @@ -78,7 +79,7 @@ fn zkvm_opcodes() -> Result<()> { let ephem_secret = SecretKey::random(&mut OsRng); let pubkey = PublicKey::from_secret(ephem_secret).inner(); - let (ephem_x, ephem_y) = PublicKey::from(pubkey * mod_r_p(ephem_secret.inner())).xy(); + let (ephem_x, ephem_y) = PublicKey::from(pubkey * fp_mod_fv(ephem_secret.inner())).xy(); let prover_witnesses = vec![ Witness::Base(Value::known(pallas::Base::from(value))),