Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,8 @@ sp-consensus-qpow = { path = "./primitives/consensus/qpow", default-features = f
qp-plonky2 = { version = "1.5.4", default-features = false }
qp-plonky2-verifier = { version = "1.5.4", default-features = false }
qp-poseidon-core = { version = "3.0.2", default-features = false }
qp-rusty-crystals-dilithium = { version = "3.0.1", default-features = false }
qp-rusty-crystals-hdwallet = { version = "3.0.1" }
qp-rusty-crystals-dilithium = { version = "4.0.0", default-features = false, features = ["ml-dsa-65", "ml-dsa-87"] }
qp-rusty-crystals-hdwallet = { version = "4.0.0", features = ["ml-dsa-65"] }
qp-wormhole-aggregator = { version = "3.1.0", default-features = false }
qp-wormhole-circuit = { version = "3.1.0", default-features = false }
qp-wormhole-circuit-builder = { version = "3.1.0", default-features = false }
Expand Down
7 changes: 5 additions & 2 deletions client/cli/src/arg_enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,11 @@ pub enum NodeKeyType {
#[derive(Debug, Copy, Clone, PartialEq, Eq, ValueEnum)]
#[value(rename_all = "kebab-case")]
pub enum CryptoScheme {
/// Use dilithium.
Dilithium,
/// Use dilithium ML-DSA-87.
#[value(alias = "dilithium")]
Dilithium87,
/// Use dilithium ML-DSA-65.
Dilithium65,
}

/// The type of the output format.
Expand Down
4 changes: 2 additions & 2 deletions client/cli/src/commands/inspect_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ fn expect_public_from_phrase<Pair: sp_core::Pair>(
#[cfg(test)]
mod tests {
use super::*;
use qp_dilithium_crypto::DilithiumPair;
use qp_dilithium_crypto::Dilithium87Pair;
use sp_core::crypto::{ByteArray, Pair, Ss58AddressFormat};
use sp_runtime::traits::IdentifyAccount;

Expand Down Expand Up @@ -205,7 +205,7 @@ mod tests {

let uri = SecretUri::from_str(seed_phrase).expect("Valid URI");
let password: Option<&str> = uri.password.as_ref().map(|s| s.expose_secret().as_ref());
let pair: DilithiumPair =
let pair: Dilithium87Pair =
Pair::from_string(uri.phrase.expose_secret().as_str(), password).expect("Valid");
let public = pair.public();
let public_hex = array_bytes::bytes2hex("0x", public.as_slice());
Expand Down
7 changes: 5 additions & 2 deletions client/cli/src/commands/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,11 @@ macro_rules! with_crypto_scheme {
$method:ident<$($generics:ty),*>( $( $params:expr ),* $(,)?) $(,)?
) => {
match $scheme {
$crate::CryptoScheme::Dilithium => {
$method::<qp_dilithium_crypto::DilithiumPair, $($generics),*>($($params),*)
$crate::CryptoScheme::Dilithium87 => {
$method::<qp_dilithium_crypto::Dilithium87Pair, $($generics),*>($($params),*)
}
$crate::CryptoScheme::Dilithium65 => {
$method::<qp_dilithium_crypto::Dilithium65Pair, $($generics),*>($($params),*)
}
}
};
Expand Down
2 changes: 1 addition & 1 deletion client/cli/src/commands/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ mod test {
fn sign_then_verify_roundtrip() {
// Derive public key from mnemonic
let mnemonic_pair =
utils::pair_from_suri::<qp_dilithium_crypto::types::DilithiumPair>(MNEMONIC, None)
utils::pair_from_suri::<qp_dilithium_crypto::types::Dilithium87Pair>(MNEMONIC, None)
.expect("Must derive pair from mnemonic");
let public_hex = format!("0x{}", hex::encode(mnemonic_pair.public().as_ref()));
// Sign via the sign command
Expand Down
2 changes: 1 addition & 1 deletion client/cli/src/params/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ impl BlockNumberOrHash {
#[derive(Debug, Clone, Args)]
pub struct CryptoSchemeFlag {
/// cryptography scheme
#[arg(long, value_name = "SCHEME", value_enum, ignore_case = true, default_value_t = CryptoScheme::Dilithium)]
#[arg(long, value_name = "SCHEME", value_enum, ignore_case = true, default_value_t = CryptoScheme::Dilithium87)]
pub scheme: CryptoScheme,
}

Expand Down
6 changes: 3 additions & 3 deletions client/litep2p/src/crypto/dilithium.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ impl Keypair {
/// Derive the internal keypair from the seed.
fn derive_internal(&self) -> ml_dsa_87::Keypair {
let mut seed_copy = self.seed;
let sensitive_seed = SensitiveBytes32::from(&mut seed_copy);
ml_dsa_87::Keypair::generate(sensitive_seed)
let mut sensitive_seed = SensitiveBytes32::from(&mut seed_copy);
ml_dsa_87::Keypair::generate(&mut sensitive_seed)
}

/// Convert the keypair into a byte array.
Expand Down Expand Up @@ -121,7 +121,7 @@ impl Keypair {

/// Get the public key of this keypair.
pub fn public(&self) -> PublicKey {
PublicKey(self.derive_internal().public)
PublicKey(self.derive_internal().public().clone())
}

/// Get the secret key (seed) of this keypair.
Expand Down
4 changes: 2 additions & 2 deletions docs/RUNTIME_SURFACE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ genesis logic, and the workspace primitive crates pulled in.
- **Build:** `no_std` WASM via `substrate-wasm-builder` (`runtime/build.rs`); native `std` build for the node/client
- **Block time target:** 12s (`TARGET_BLOCK_TIME_MS = 12_000`)
- **Consensus:** QPoW (quantum-resistant Proof of Work, Poseidon2-based)
- **Signatures:** Dilithium (ML-DSA-87) post-quantum signature scheme
- **Signatures:** Dilithium post-quantum signature schemes (ML-DSA-87 and ML-DSA-65)
- **SS58 prefix:** 189

---
Expand Down Expand Up @@ -273,7 +273,7 @@ Related transaction-payment RPC surface (patched for WASM + node builds):

| Crate | Path | Role in runtime |
| --- | --- | --- |
| `qp-dilithium-crypto` | `primitives/dilithium-crypto` | ML-DSA-87 post-quantum signatures; `DilithiumSignatureScheme` = the chain's `Signature`/`AccountId`. |
| `qp-dilithium-crypto` | `primitives/dilithium-crypto` | ML-DSA-87/ML-DSA-65 post-quantum signatures; `DilithiumSignatureScheme` = the chain's `Signature`/`AccountId`. |
| `qp-header` | `primitives/header` | Custom block `Header` (Poseidon block hash + Blake2 state trie); `ZkTreeRootProvider` trait. |
| `qp-high-security` | `primitives/high-security` | `HighSecurityInspector` trait shared by multisig, reversible-transfers, tx-extensions (breaks circular dep). |
| `qp-scheduler` | `primitives/scheduler` | `BlockNumberOrTimestamp`, `DispatchTime`, `ScheduleNamed` trait for delayed dispatch. |
Expand Down
4 changes: 2 additions & 2 deletions node/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl frame_benchmarking_cli::ExtrinsicBuilder for TransferKeepAliveBuilder {
/// Note: Should only be used for benchmarking.
pub fn create_benchmark_extrinsic(
client: &FullClient,
sender: qp_dilithium_crypto::DilithiumPair,
sender: qp_dilithium_crypto::Dilithium87Pair,
call: runtime::RuntimeCall,
nonce: u32,
) -> runtime::UncheckedExtrinsic {
Expand Down Expand Up @@ -154,7 +154,7 @@ pub fn create_benchmark_extrinsic(
runtime::UncheckedExtrinsic::new_signed(
call,
sender.public().into_account().into(),
runtime::Signature::Dilithium(signature),
runtime::Signature::Dilithium87(signature),
tx_ext,
)
}
Expand Down
44 changes: 22 additions & 22 deletions node/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ use crate::{
};
#[cfg(feature = "runtime-benchmarks")]
use frame_benchmarking_cli::{BenchmarkCmd, ExtrinsicFactory, SUBSTRATE_REFERENCE_HARDWARE};
use qp_dilithium_crypto::{traits::WormholeAddress, DilithiumPair};
use qp_dilithium_crypto::{traits::WormholeAddress, Dilithium87Pair};
use qp_rusty_crystals_hdwallet::{
derive_key_from_mnemonic, derive_wormhole_from_mnemonic, generate_mnemonic, mnemonic_to_seed,
wormhole::WormholePair, SensitiveBytes32, QUANTUS_DILITHIUM_CHAIN_ID,
wormhole::WormholePair, SensitiveBytes32, SensitiveBytes64, QUANTUS_DILITHIUM_CHAIN_ID,
QUANTUS_WORMHOLE_CHAIN_ID,
};
use quantus_runtime::Block;
Expand Down Expand Up @@ -112,22 +112,21 @@ pub fn generate_quantus_key(
// Use provided mnemonic. The caller already knows it, so it is
// deliberately NOT placed in `secret_phrase` for echoing back.
if no_derivation {
// Get raw seed from mnemonic (mnemonic_to_seed zeroizes its owned copy).
let mut seed64 =
mnemonic_to_seed(words_phrase.to_string(), None).map_err(|e| {
eprintln!("Error processing provided words: {:?}", e);
sc_cli::Error::Input("Failed to process provided words".into())
})?;
seed_for_pair = Zeroizing::new(seed64.to_vec());
seed64.zeroize();
// Get raw seed from mnemonic (writes into `seed64`, which zeroizes on drop).
let mut seed64 = SensitiveBytes64::zeroed();
mnemonic_to_seed(words_phrase.to_string(), None, &mut seed64).map_err(|e| {
eprintln!("Error processing provided words: {:?}", e);
sc_cli::Error::Input("Failed to process provided words".into())
})?;
seed_for_pair = Zeroizing::new(seed64.as_bytes().to_vec());
} else {
println!("Deriving HD path: {}", path);
let keypair =
derive_key_from_mnemonic(words_phrase, None, &path).map_err(|e| {
eprintln!("Error deriving from mnemonic: {:?}", e);
sc_cli::Error::Input("Failed to derive from mnemonic".into())
})?;
let dilithium_pair = DilithiumPair::from_keypair(keypair);
let dilithium_pair = Dilithium87Pair::from_keypair(keypair);
let account_id = AccountId32::from(dilithium_pair.public());
return Ok(QuantusKeyDetails {
address: account_id
Expand Down Expand Up @@ -172,13 +171,13 @@ pub fn generate_quantus_key(
words_to_print = Some(new_words.clone());

if no_derivation {
// Get raw seed from mnemonic (consumes and zeroizes `new_words`).
let mut seed64 = mnemonic_to_seed(new_words, None).map_err(|e| {
// Get raw seed from mnemonic (writes into `seed64`, which zeroizes on drop).
let mut seed64 = SensitiveBytes64::zeroed();
mnemonic_to_seed(new_words, None, &mut seed64).map_err(|e| {
eprintln!("Error converting mnemonic to seed: {:?}", e);
sc_cli::Error::Input("Failed to convert mnemonic to seed".into())
})?;
seed_for_pair = Zeroizing::new(seed64.to_vec());
seed64.zeroize();
seed_for_pair = Zeroizing::new(seed64.as_bytes().to_vec());
} else {
println!("Deriving HD path: {}", path);
let keypair =
Expand All @@ -188,7 +187,7 @@ pub fn generate_quantus_key(
})?;
let mut new_words = new_words;
new_words.zeroize();
let dilithium_pair = DilithiumPair::from_keypair(keypair);
let dilithium_pair = Dilithium87Pair::from_keypair(keypair);
let account_id = AccountId32::from(dilithium_pair.public());
return Ok(QuantusKeyDetails {
address: account_id
Expand All @@ -203,8 +202,8 @@ pub fn generate_quantus_key(
}
};

let dilithium_pair = DilithiumPair::from_seed(&seed_for_pair).map_err(|e| {
eprintln!("Error creating DilithiumPair: {:?}", e);
let dilithium_pair = Dilithium87Pair::from_seed(&seed_for_pair).map_err(|e| {
eprintln!("Error creating Dilithium87Pair: {:?}", e);
sc_cli::Error::Input("Failed to create keypair".into())
})?;

Expand Down Expand Up @@ -244,14 +243,15 @@ pub fn generate_quantus_key(
};

let wormhole_pair = if no_derivation {
let mut seed64 = mnemonic_to_seed(words_phrase.to_string(), None).map_err(|e| {
let mut seed64 = SensitiveBytes64::zeroed();
mnemonic_to_seed(words_phrase.to_string(), None, &mut seed64).map_err(|e| {
eprintln!("Error processing provided words: {:?}", e);
sc_cli::Error::Input("Failed to process provided words".into())
})?;
let mut seed32 = [0u8; 32];
seed32.copy_from_slice(&seed64[..32]);
seed64.zeroize();
WormholePair::generate_new(SensitiveBytes32::from(&mut seed32))
seed32.copy_from_slice(&seed64.as_bytes()[..32]);
let mut sensitive_seed = SensitiveBytes32::from(&mut seed32);
WormholePair::generate_new(&mut sensitive_seed)
} else {
println!("Deriving wormhole HD path: {}", path);
derive_wormhole_from_mnemonic(&words_phrase, None, &path).map_err(|e| {
Expand Down
8 changes: 5 additions & 3 deletions primitives/dilithium-crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
extern crate alloc;

pub mod pair;
mod scheme_macro;
pub mod traits;
pub mod types;

Expand All @@ -13,8 +14,9 @@ pub const SECRET_KEY_BYTES: usize = ml_dsa_87::SECRETKEYBYTES;
pub const SIGNATURE_BYTES: usize = ml_dsa_87::SIGNBYTES;

pub use pair::{create_keypair, crystal_alice, crystal_charlie, dilithium_bob, generate};
pub use traits::verify;
pub use types::{
DilithiumPair, DilithiumPublic, DilithiumSignature, DilithiumSignatureScheme,
DilithiumSignatureWithPublic, DilithiumSigner, WrappedPublicBytes, WrappedSignatureBytes,
verify_ml_dsa_65, verify_ml_dsa_87, Dilithium65CryptoTag, Dilithium65Pair, Dilithium65Public,
Dilithium65Signature, Dilithium65SignatureWithPublic, Dilithium87CryptoTag, Dilithium87Pair,
Dilithium87Public, Dilithium87Signature, Dilithium87SignatureWithPublic,
DilithiumSignatureScheme, DilithiumSigner, WrappedPublicBytes, WrappedSignatureBytes,
};
Loading
Loading