generate fresh x25519, mlkem768 and mceliece keys on config migration

This commit is contained in:
Jędrzej Stuczyński
2026-02-25 14:28:32 +00:00
parent f6a796fe71
commit 901557ad04
13 changed files with 1581 additions and 481 deletions
Generated
+97 -65
View File
@@ -1351,10 +1351,11 @@ checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
[[package]]
name = "classic-mceliece-rust"
version = "3.2.0"
source = "git+https://github.com/georgio/classic-mceliece-rust#f2f27048b621df103bbe64369a18174ffec04ae1"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62a9b6d27e553269a76625911aa8cf6afaa8659f1b0c85b410cb5f51a87183d9"
dependencies = [
"rand 0.9.2",
"rand 0.8.5",
"sha3",
"zeroize",
]
@@ -1563,11 +1564,11 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "core-models"
version = "0.0.4"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
version = "0.0.5"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"hax-lib",
"pastey",
"pastey 0.2.1",
"rand 0.9.2",
]
@@ -3307,9 +3308,9 @@ dependencies = [
[[package]]
name = "hax-lib"
version = "0.3.5"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74d9ba66d1739c68e0219b2b2238b5c4145f491ebf181b9c6ab561a19352ae86"
checksum = "543f93241d32b3f00569201bfce9d7a93c92c6421b23c77864ac929dc947b9fc"
dependencies = [
"hax-lib-macros",
"num-bigint",
@@ -3318,9 +3319,9 @@ dependencies = [
[[package]]
name = "hax-lib-macros"
version = "0.3.5"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24ba777a231a58d1bce1d68313fa6b6afcc7966adef23d60f45b8a2b9b688bf1"
checksum = "f8755751e760b11021765bb04cb4a6c4e24742688d9f3aa14c2079638f537b0f"
dependencies = [
"hax-lib-macros-types",
"proc-macro-error2",
@@ -3331,9 +3332,9 @@ dependencies = [
[[package]]
name = "hax-lib-macros-types"
version = "0.3.5"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "867e19177d7425140b417cd27c2e05320e727ee682e98368f88b7194e80ad515"
checksum = "f177c9ae8ea456e2f71ff3c1ea47bf4464f772a05133fcbba56cd5ba169035a2"
dependencies = [
"proc-macro2",
"quote",
@@ -4121,6 +4122,8 @@ dependencies = [
"nym-credentials-interface",
"nym-crypto",
"nym-gateway",
"nym-kkt",
"nym-kkt-ciphersuite",
"nym-lp-transport",
"nym-registration-client",
"nym-test-utils",
@@ -4450,10 +4453,21 @@ version = "0.2.180"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
[[package]]
name = "libcrux-aesgcm"
version = "0.0.7"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"libcrux-intrinsics",
"libcrux-platform",
"libcrux-secrets",
"libcrux-traits",
]
[[package]]
name = "libcrux-chacha20poly1305"
version = "0.0.4"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
version = "0.0.6"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"libcrux-hacl-rs",
"libcrux-macros",
@@ -4464,8 +4478,8 @@ dependencies = [
[[package]]
name = "libcrux-curve25519"
version = "0.0.4"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
version = "0.0.6"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"libcrux-hacl-rs",
"libcrux-macros",
@@ -4475,8 +4489,8 @@ dependencies = [
[[package]]
name = "libcrux-ecdh"
version = "0.0.4"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
version = "0.0.6"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"libcrux-curve25519",
"libcrux-p256",
@@ -4486,8 +4500,8 @@ dependencies = [
[[package]]
name = "libcrux-ed25519"
version = "0.0.4"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
version = "0.0.6"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"libcrux-hacl-rs",
"libcrux-macros",
@@ -4499,15 +4513,15 @@ dependencies = [
[[package]]
name = "libcrux-hacl-rs"
version = "0.0.4"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"libcrux-macros",
]
[[package]]
name = "libcrux-hkdf"
version = "0.0.4"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
version = "0.0.6"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"libcrux-hacl-rs",
"libcrux-hmac",
@@ -4516,8 +4530,8 @@ dependencies = [
[[package]]
name = "libcrux-hmac"
version = "0.0.4"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
version = "0.0.6"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"libcrux-hacl-rs",
"libcrux-macros",
@@ -4526,8 +4540,8 @@ dependencies = [
[[package]]
name = "libcrux-intrinsics"
version = "0.0.4"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
version = "0.0.6"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"core-models",
"hax-lib",
@@ -4535,8 +4549,8 @@ dependencies = [
[[package]]
name = "libcrux-kem"
version = "0.0.4"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
version = "0.0.6"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"libcrux-curve25519",
"libcrux-ecdh",
@@ -4551,16 +4565,30 @@ dependencies = [
[[package]]
name = "libcrux-macros"
version = "0.0.3"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"quote",
"syn 2.0.106",
]
[[package]]
name = "libcrux-ml-dsa"
version = "0.0.7"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"core-models",
"hax-lib",
"libcrux-intrinsics",
"libcrux-macros",
"libcrux-platform",
"libcrux-sha3",
"tls_codec",
]
[[package]]
name = "libcrux-ml-kem"
version = "0.0.4"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
version = "0.0.7"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"hax-lib",
"libcrux-intrinsics",
@@ -4574,8 +4602,8 @@ dependencies = [
[[package]]
name = "libcrux-p256"
version = "0.0.4"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
version = "0.0.6"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"libcrux-hacl-rs",
"libcrux-macros",
@@ -4586,8 +4614,8 @@ dependencies = [
[[package]]
name = "libcrux-platform"
version = "0.0.2"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
version = "0.0.3"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"libc",
]
@@ -4595,7 +4623,7 @@ dependencies = [
[[package]]
name = "libcrux-poly1305"
version = "0.0.4"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"libcrux-hacl-rs",
"libcrux-macros",
@@ -4603,34 +4631,38 @@ dependencies = [
[[package]]
name = "libcrux-psq"
version = "0.0.5"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
version = "0.0.7"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"classic-mceliece-rust",
"libcrux-aesgcm",
"libcrux-chacha20poly1305",
"libcrux-ecdh",
"libcrux-ed25519",
"libcrux-hkdf",
"libcrux-hmac",
"libcrux-kem",
"libcrux-ml-dsa",
"libcrux-ml-kem",
"libcrux-sha2",
"libcrux-traits",
"rand 0.8.5",
"rand 0.9.2",
"tls_codec",
]
[[package]]
name = "libcrux-secrets"
version = "0.0.4"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
version = "0.0.5"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"hax-lib",
]
[[package]]
name = "libcrux-sha2"
version = "0.0.4"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
version = "0.0.6"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"libcrux-hacl-rs",
"libcrux-macros",
@@ -4639,8 +4671,8 @@ dependencies = [
[[package]]
name = "libcrux-sha3"
version = "0.0.4"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
version = "0.0.7"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"hax-lib",
"libcrux-intrinsics",
@@ -4650,8 +4682,8 @@ dependencies = [
[[package]]
name = "libcrux-traits"
version = "0.0.4"
source = "git+https://github.com/cryspen/libcrux#f63bb67ead59297560edf523a3b29b21489c17ea"
version = "0.0.6"
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
dependencies = [
"libcrux-secrets",
"rand 0.9.2",
@@ -5075,7 +5107,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3176f18d11a1ae46053e59ec89d46ba318ae1343615bd3f8c908bfc84edae35c"
dependencies = [
"byteorder",
"pastey",
"pastey 0.1.1",
"thiserror 2.0.12",
]
@@ -6198,6 +6230,7 @@ dependencies = [
"nym-sphinx-types",
"nym-test-utils",
"rand 0.8.5",
"rand 0.9.2",
"rand_chacha 0.3.1",
"serde",
"serde_bytes",
@@ -6792,16 +6825,17 @@ name = "nym-kkt"
version = "0.1.0"
dependencies = [
"anyhow",
"blake3",
"classic-mceliece-rust",
"criterion",
"libcrux-chacha20poly1305",
"libcrux-ecdh",
"libcrux-kem",
"libcrux-ml-kem",
"libcrux-psq",
"num_enum",
"nym-crypto",
"nym-kkt-ciphersuite",
"nym-kkt-context",
"nym-pemstore",
"rand 0.9.2",
"rand_chacha 0.9.0",
"strum",
@@ -6827,7 +6861,7 @@ version = "1.20.4"
dependencies = [
"num_enum",
"nym-kkt-ciphersuite",
"thiserror 2.0.18",
"thiserror 2.0.12",
]
[[package]]
@@ -6848,13 +6882,8 @@ dependencies = [
"anyhow",
"bs58",
"bytes",
"chacha20poly1305",
"criterion",
"dashmap",
"libcrux-kem",
"libcrux-psq",
"libcrux-traits",
"mock_instant",
"num_enum",
"nym-crypto",
"nym-kkt",
@@ -6863,14 +6892,8 @@ dependencies = [
"nym-lp-packet",
"nym-lp-transport",
"nym-test-utils",
"parking_lot",
"rand 0.8.5",
"rand 0.9.2",
"serde",
"sha2 0.10.9",
"snow",
"thiserror 2.0.12",
"tls_codec",
"tokio",
"tracing",
"zeroize",
@@ -6923,7 +6946,7 @@ dependencies = [
"num_enum",
"nym-crypto",
"nym-lp-common",
"thiserror 2.0.18",
"thiserror 2.0.12",
"tracing",
]
@@ -6935,7 +6958,7 @@ dependencies = [
"nym-kkt-context",
"nym-lp-packet",
"nym-test-utils",
"thiserror 2.0.18",
"thiserror 2.0.12",
"tokio",
"tracing",
]
@@ -7202,6 +7225,7 @@ dependencies = [
"opentelemetry",
"opentelemetry_sdk",
"rand 0.8.5",
"rand 0.9.2",
"rand_chacha 0.3.1",
"serde",
"serde_json",
@@ -7535,13 +7559,15 @@ dependencies = [
"nym-credentials-interface",
"nym-crypto",
"nym-ip-packet-client",
"nym-kkt",
"nym-lp",
"nym-lp-transport",
"nym-registration-common",
"nym-sdk",
"nym-test-utils",
"nym-validator-client",
"nym-wireguard-types",
"rand 0.8.5",
"rand 0.9.2",
"thiserror 2.0.12",
"tokio",
"tokio-util",
@@ -8860,6 +8886,12 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec"
[[package]]
name = "pastey"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b867cad97c0791bbd3aaa6472142568c6c9e8f71937e98379f584cfb0cf35bec"
[[package]]
name = "peg"
version = "0.8.5"
+1
View File
@@ -15,6 +15,7 @@ strum = { workspace = true }
nym-crypto = { path = "../crypto", features = ["hashing"] }
nym-kkt-ciphersuite = { workspace = true, features = ["digests"] }
nym-kkt-context = { path = "../nym-kkt-context" }
nym-pemstore = { workspace = true }
libcrux-kem = { workspace = true }
libcrux-ecdh = { workspace = true, features = ["codec"] }
-1
View File
@@ -21,7 +21,6 @@ where
libcrux_ml_kem::mlkem768::rand::generate_key_pair(rng)
}
// (decapsulation_key, encapsulation_key)
pub fn generate_keypair_mceliece<R>(rng: &mut R) -> libcrux_psq::classic_mceliece::KeyPair
where
R: RngCore + CryptoRng,
+309 -16
View File
@@ -2,19 +2,21 @@
// SPDX-License-Identifier: Apache-2.0
use crate::error::KKTError;
use libcrux_ml_kem::mlkem768::{MlKem768KeyPair, MlKem768PrivateKey, MlKem768PublicKey};
use libcrux_psq::classic_mceliece;
use libcrux_psq::handshake::types::PQEncapsulationKey;
use nym_kkt_ciphersuite::{KEM, mceliece};
use nym_kkt_ciphersuite::KEM;
use std::fmt::{Debug, Formatter};
use std::sync::Arc;
pub use libcrux_ml_kem::mlkem768::{MlKem768KeyPair, MlKem768PrivateKey, MlKem768PublicKey};
pub use libcrux_psq::classic_mceliece as mceliece;
pub use libcrux_psq::handshake::types::{DHKeyPair, DHPrivateKey, DHPublicKey};
/// Wrapper around keys used for the KEM exchange
/// with cheap clones thanks to Arc wrappers
#[derive(Clone)]
pub struct KEMKeys {
mc_eliece_pk: Arc<classic_mceliece::PublicKey>,
mc_eliece_sk: Arc<classic_mceliece::SecretKey>,
mc_eliece_pk: Arc<mceliece::PublicKey>,
mc_eliece_sk: Arc<mceliece::SecretKey>,
ml_kem768_pk: Arc<MlKem768PublicKey>,
ml_kem768_sk: Arc<MlKem768PrivateKey>,
}
@@ -29,7 +31,7 @@ impl Debug for KEMKeys {
}
impl KEMKeys {
pub fn new(mc_eliece: classic_mceliece::KeyPair, ml_kem768: MlKem768KeyPair) -> Self {
pub fn new(mc_eliece: mceliece::KeyPair, ml_kem768: MlKem768KeyPair) -> Self {
let (ml_kem768_sk, ml_kem768_pk) = ml_kem768.into_parts();
Self {
mc_eliece_pk: Arc::new(mc_eliece.pk),
@@ -55,7 +57,7 @@ impl KEMKeys {
}
}
pub fn mc_eliece_encapsulation_key(&self) -> &classic_mceliece::PublicKey {
pub fn mc_eliece_encapsulation_key(&self) -> &mceliece::PublicKey {
&self.mc_eliece_pk
}
@@ -63,7 +65,7 @@ impl KEMKeys {
self.ml_kem768_pk.as_ref()
}
pub fn mc_eliece_decapsulation_key(&self) -> &classic_mceliece::SecretKey {
pub fn mc_eliece_decapsulation_key(&self) -> &mceliece::SecretKey {
&self.mc_eliece_sk
}
@@ -74,7 +76,7 @@ impl KEMKeys {
#[derive(Clone)]
pub enum EncapsulationKey {
McEliece(Arc<classic_mceliece::PublicKey>),
McEliece(Arc<mceliece::PublicKey>),
MlKem768(Arc<MlKem768PublicKey>),
}
@@ -110,15 +112,16 @@ impl EncapsulationKey {
})?,
))),
KEM::McEliece => {
let boxed_array: Box<[u8; mceliece::PUBLIC_KEY_LENGTH]> = bytes
.into_boxed_slice()
.try_into()
.map_err(|_| KKTError::KEMError {
info: "mceliece key of invalid length",
})?;
let boxed_array: Box<[u8; nym_kkt_ciphersuite::mceliece::PUBLIC_KEY_LENGTH]> =
bytes
.into_boxed_slice()
.try_into()
.map_err(|_| KKTError::KEMError {
info: "mceliece key of invalid length",
})?;
Ok(EncapsulationKey::McEliece(Arc::new(
classic_mceliece::PublicKey::from(boxed_array),
mceliece::PublicKey::from(boxed_array),
)))
}
}
@@ -131,3 +134,293 @@ impl EncapsulationKey {
}
}
}
// storage helpers
pub mod storage_wrappers {
use nym_pemstore::traits::PemStorableKey;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum MalformedStoredKeyError {
#[error("{typ} stored key has an invalid length")]
InvalidKeyLength { typ: &'static str },
#[error("{typ} stored key is malformed: {message}")]
MalformedData { typ: &'static str, message: String },
#[error("attempted to take ownership of a stored {typ} key representation")]
IllegalStoredConversion { typ: &'static str },
}
pub trait StorableKey: Sized {
type StorableRepresentation<'a>: PemStorableKey
+ From<&'a Self>
+ TryInto<Self, Error = MalformedStoredKeyError>
+ Sized
where
Self: 'a;
fn to_storable(&self) -> Self::StorableRepresentation<'_> {
self.into()
}
fn from_storable(
repr: Self::StorableRepresentation<'_>,
) -> Result<Self, MalformedStoredKeyError> {
repr.try_into()
}
}
macro_rules! declare_key_wrappers {
($pub_key_type:ty, $private_key_type:ty) => {
pub enum StorablePublicKey<'a> {
Owned(Box<$pub_key_type>),
Borrowed(&'a $pub_key_type),
}
impl AsRef<$pub_key_type> for StorablePublicKey<'_> {
fn as_ref(&self) -> &$pub_key_type {
match self {
StorablePublicKey::Owned(k) => k,
StorablePublicKey::Borrowed(k) => k,
}
}
}
pub enum StorablePrivateKey<'a> {
Owned(Box<$private_key_type>),
Borrowed(&'a $private_key_type),
}
impl AsRef<$private_key_type> for StorablePrivateKey<'_> {
fn as_ref(&self) -> &$private_key_type {
match self {
StorablePrivateKey::Owned(k) => k,
StorablePrivateKey::Borrowed(k) => k,
}
}
}
impl<'a> From<&'a $pub_key_type> for StorablePublicKey<'a> {
fn from(value: &'a $pub_key_type) -> Self {
StorablePublicKey::Borrowed(value)
}
}
impl<'a> TryFrom<StorablePublicKey<'a>> for $pub_key_type {
type Error = MalformedStoredKeyError;
fn try_from(value: StorablePublicKey<'a>) -> Result<Self, Self::Error> {
match value {
StorablePublicKey::Owned(value) => Ok(*value),
StorablePublicKey::Borrowed(_) => {
Err(MalformedStoredKeyError::IllegalStoredConversion {
typ: <StorablePublicKey as PemStorableKey>::pem_type(),
})
}
}
}
}
impl<'a> From<&'a $private_key_type> for StorablePrivateKey<'a> {
fn from(value: &'a $private_key_type) -> Self {
StorablePrivateKey::Borrowed(value)
}
}
impl<'a> TryFrom<StorablePrivateKey<'a>> for $private_key_type {
type Error = MalformedStoredKeyError;
fn try_from(value: StorablePrivateKey<'a>) -> Result<Self, Self::Error> {
match value {
StorablePrivateKey::Owned(value) => Ok(*value),
StorablePrivateKey::Borrowed(_) => {
Err(MalformedStoredKeyError::IllegalStoredConversion {
typ: <StorablePrivateKey as PemStorableKey>::pem_type(),
})
}
}
}
}
impl $crate::keys::storage_wrappers::StorableKey for $pub_key_type {
type StorableRepresentation<'a> = StorablePublicKey<'a>;
}
impl $crate::keys::storage_wrappers::StorableKey for $private_key_type {
type StorableRepresentation<'a> = StorablePrivateKey<'a>;
}
};
}
pub mod mceliece {
use crate::keys::storage_wrappers::MalformedStoredKeyError;
use libcrux_psq::classic_mceliece;
use nym_pemstore::traits::PemStorableKey;
declare_key_wrappers!(classic_mceliece::PublicKey, classic_mceliece::SecretKey);
impl<'a> PemStorableKey for StorablePrivateKey<'a> {
type Error = MalformedStoredKeyError;
fn pem_type() -> &'static str {
"MCELIECE PRIVATE KEY"
}
fn to_bytes(&self) -> Vec<u8> {
self.as_ref().as_ref().to_vec()
}
fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Error> {
let bytes: Box<[u8; nym_kkt_ciphersuite::mceliece::SECRET_KEY_LENGTH]> =
bytes.to_vec().into_boxed_slice().try_into().map_err(|_| {
MalformedStoredKeyError::InvalidKeyLength {
typ: Self::pem_type(),
}
})?;
Ok(StorablePrivateKey::Owned(Box::new(
classic_mceliece::SecretKey::from(bytes),
)))
}
}
impl<'a> PemStorableKey for StorablePublicKey<'a> {
type Error = MalformedStoredKeyError;
fn pem_type() -> &'static str {
"MCELIECE PUBLIC KEY"
}
fn to_bytes(&self) -> Vec<u8> {
self.as_ref().as_ref().to_vec()
}
fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Error> {
let bytes: Box<[u8; nym_kkt_ciphersuite::mceliece::PUBLIC_KEY_LENGTH]> =
bytes.to_vec().into_boxed_slice().try_into().map_err(|_| {
MalformedStoredKeyError::InvalidKeyLength {
typ: Self::pem_type(),
}
})?;
Ok(StorablePublicKey::Owned(Box::new(
classic_mceliece::PublicKey::from(bytes),
)))
}
}
}
pub mod mlkem768 {
use crate::keys::storage_wrappers::MalformedStoredKeyError;
use libcrux_ml_kem::mlkem768::{MlKem768PrivateKey, MlKem768PublicKey};
use nym_pemstore::traits::PemStorableKey;
declare_key_wrappers!(MlKem768PublicKey, MlKem768PrivateKey);
impl<'a> PemStorableKey for StorablePrivateKey<'a> {
type Error = MalformedStoredKeyError;
fn pem_type() -> &'static str {
"MLKEM768 PRIVATE KEY"
}
fn to_bytes(&self) -> Vec<u8> {
self.as_ref().as_slice().to_vec()
}
fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Error> {
let inner = MlKem768PrivateKey::try_from(bytes).map_err(|message| {
MalformedStoredKeyError::MalformedData {
typ: Self::pem_type(),
message: message.to_string(),
}
})?;
Ok(StorablePrivateKey::Owned(Box::new(inner)))
}
}
impl<'a> PemStorableKey for StorablePublicKey<'a> {
type Error = MalformedStoredKeyError;
fn pem_type() -> &'static str {
"MLKEM768 PUBLIC KEY"
}
fn to_bytes(&self) -> Vec<u8> {
self.as_ref().as_slice().to_vec()
}
fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Error> {
let inner = MlKem768PublicKey::try_from(bytes).map_err(|message| {
MalformedStoredKeyError::MalformedData {
typ: Self::pem_type(),
message: message.to_string(),
}
})?;
Ok(StorablePublicKey::Owned(Box::new(inner)))
}
}
}
pub mod x25519 {
use crate::keys::storage_wrappers::MalformedStoredKeyError;
use libcrux_psq::handshake::types::{DHPrivateKey, DHPublicKey};
use nym_pemstore::traits::PemStorableKey;
declare_key_wrappers!(DHPublicKey, DHPrivateKey);
impl<'a> PemStorableKey for StorablePrivateKey<'a> {
type Error = MalformedStoredKeyError;
fn pem_type() -> &'static str {
"LP X25519 PRIVATE KEY"
}
fn to_bytes(&self) -> Vec<u8> {
self.as_ref().as_ref().to_vec()
}
fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Error> {
let bytes =
bytes
.try_into()
.map_err(|_| MalformedStoredKeyError::InvalidKeyLength {
typ: Self::pem_type(),
})?;
Ok(StorablePrivateKey::Owned(Box::new(
DHPrivateKey::from_bytes(&bytes).map_err(|err| {
MalformedStoredKeyError::MalformedData {
typ: Self::pem_type(),
message: format!("{err:?}"),
}
})?,
)))
}
}
impl<'a> PemStorableKey for StorablePublicKey<'a> {
type Error = MalformedStoredKeyError;
fn pem_type() -> &'static str {
"LP X25519 PUBLIC KEY"
}
fn to_bytes(&self) -> Vec<u8> {
self.as_ref().as_ref().to_vec()
}
fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Error> {
let bytes =
bytes
.try_into()
.map_err(|_| MalformedStoredKeyError::InvalidKeyLength {
typ: Self::pem_type(),
})?;
Ok(StorablePublicKey::Owned(Box::new(DHPublicKey::from_bytes(
&bytes,
))))
}
}
}
}
-15
View File
@@ -132,17 +132,6 @@ pub struct LpDebug {
/// Maximum concurrent connections
pub max_connections: usize,
/// Maximum acceptable age of ClientHello timestamp in seconds (default: 30)
///
/// ClientHello messages with timestamps older than this will be rejected
/// to prevent replay attacks. Value should be:
/// - Large enough to account for clock skew and network latency
/// - Small enough to limit replay attack window
///
/// Recommended: 30-60 seconds
#[serde(with = "humantime_serde")]
pub timestamp_tolerance: Duration,
/// Use mock ecash manager for testing (default: false)
///
/// When enabled, the LP listener will use a mock ecash verifier that
@@ -229,9 +218,6 @@ impl Default for LpConfig {
impl LpDebug {
pub const DEFAULT_MAX_CONNECTIONS: usize = 10000;
// 30 seconds - balances security vs clock skew tolerance
pub const DEFAULT_TIMESTAMP_TOLERANCE: Duration = Duration::from_secs(30);
// 90 seconds - handshakes should complete quickly
pub const DEFAULT_HANDSHAKE_TTL: Duration = Duration::from_secs(90);
@@ -249,7 +235,6 @@ impl Default for LpDebug {
fn default() -> Self {
LpDebug {
max_connections: Self::DEFAULT_MAX_CONNECTIONS,
timestamp_tolerance: Self::DEFAULT_TIMESTAMP_TOLERANCE,
use_mock_ecash: false,
handshake_ttl: Self::DEFAULT_HANDSHAKE_TTL,
session_ttl: Self::DEFAULT_SESSION_TTL,
+1
View File
@@ -34,6 +34,7 @@ human-repr = { workspace = true }
ipnetwork = { workspace = true }
indicatif = { workspace = true }
rand = { workspace = true }
rand09 = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true
thiserror.workspace = true
+2
View File
@@ -4,6 +4,7 @@
mod old_config_v1;
mod old_config_v10;
mod old_config_v11;
mod old_config_v12;
mod old_config_v2;
mod old_config_v3;
mod old_config_v4;
@@ -24,3 +25,4 @@ pub use old_config_v8::try_upgrade_config_v8;
pub use old_config_v9::try_upgrade_config_v9;
pub use old_config_v10::try_upgrade_config_v10;
pub use old_config_v11::try_upgrade_config_v11;
pub use old_config_v12::try_upgrade_config_v12;
+32 -383
View File
@@ -1,21 +1,9 @@
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use crate::config::authenticator::{Authenticator, AuthenticatorDebug};
use crate::config::gateway_tasks::{
ClientBandwidthDebug, StaleMessageDebug, UpgradeModeWatcher, ZkNymTicketHandlerDebug,
};
use crate::config::persistence::{
AuthenticatorPaths, GatewayTasksPaths, IpPacketRouterPaths, KeysPaths, NetworkRequesterPaths,
NymNodePaths, ReplayProtectionPaths, ServiceProvidersPaths, WireguardPaths,
};
use crate::config::service_providers::{
IpPacketRouter, IpPacketRouterDebug, NetworkRequester, NetworkRequesterDebug,
};
use crate::config::{
Config, GatewayTasksConfig, Host, Http, KeyRotation, KeyRotationDebug, Mixnet, MixnetDebug,
NodeModes, ReplayProtection, ReplayProtectionDebug, ServiceProvidersConfig, Verloc,
VerlocDebug, Wireguard, gateway_tasks, service_providers,
use crate::config::old_configs::old_config_v12::{
ConfigV12, DebugV12, GatewayTasksConfigDebugV12, GatewayTasksConfigV12, LpConfigV12,
UpgradeModeWatcherV12, WireguardV12,
};
use crate::error::NymNodeError;
use nym_bin_common::logging::LoggingSettings;
@@ -185,7 +173,7 @@ impl ConfigV11 {
pub async fn try_upgrade_config_v11<P: AsRef<Path>>(
path: P,
prev_config: Option<ConfigV11>,
) -> Result<Config, NymNodeError> {
) -> Result<ConfigV12, NymNodeError> {
debug!("attempting to load v11 config...");
let old_cfg = if let Some(prev_config) = prev_config {
@@ -197,144 +185,16 @@ pub async fn try_upgrade_config_v11<P: AsRef<Path>>(
// for future reference: when creating v12 migration,
// look at how v10 -> v11 is implemented
// you might be able to create a bunch of type aliases again to save you some headache
let cfg = Config {
let cfg = ConfigV12 {
save_path: old_cfg.save_path,
id: old_cfg.id,
modes: NodeModes {
mixnode: old_cfg.modes.mixnode,
entry: old_cfg.modes.entry,
exit: old_cfg.modes.exit,
},
host: Host {
public_ips: old_cfg.host.public_ips,
hostname: old_cfg.host.hostname,
location: old_cfg.host.location,
},
mixnet: Mixnet {
bind_address: old_cfg.mixnet.bind_address,
announce_port: old_cfg.mixnet.announce_port,
nym_api_urls: old_cfg.mixnet.nym_api_urls,
nyxd_urls: old_cfg.mixnet.nyxd_urls,
replay_protection: ReplayProtection {
storage_paths: ReplayProtectionPaths {
current_bloomfilters_directory: old_cfg
.mixnet
.replay_protection
.storage_paths
.current_bloomfilters_directory,
},
debug: ReplayProtectionDebug {
unsafe_disabled: old_cfg.mixnet.replay_protection.debug.unsafe_disabled,
maximum_replay_detection_deferral: old_cfg
.mixnet
.replay_protection
.debug
.maximum_replay_detection_deferral,
maximum_replay_detection_pending_packets: old_cfg
.mixnet
.replay_protection
.debug
.maximum_replay_detection_pending_packets,
false_positive_rate: old_cfg.mixnet.replay_protection.debug.false_positive_rate,
initial_expected_packets_per_second: old_cfg
.mixnet
.replay_protection
.debug
.initial_expected_packets_per_second,
bloomfilter_minimum_packets_per_second_size: old_cfg
.mixnet
.replay_protection
.debug
.bloomfilter_minimum_packets_per_second_size,
bloomfilter_size_multiplier: old_cfg
.mixnet
.replay_protection
.debug
.bloomfilter_size_multiplier,
bloomfilter_disk_flushing_rate: old_cfg
.mixnet
.replay_protection
.debug
.bloomfilter_disk_flushing_rate,
},
},
key_rotation: KeyRotation {
debug: KeyRotationDebug {
rotation_state_poling_interval: old_cfg
.mixnet
.key_rotation
.debug
.rotation_state_poling_interval,
},
},
debug: MixnetDebug {
maximum_forward_packet_delay: old_cfg.mixnet.debug.maximum_forward_packet_delay,
packet_forwarding_initial_backoff: old_cfg
.mixnet
.debug
.packet_forwarding_initial_backoff,
packet_forwarding_maximum_backoff: old_cfg
.mixnet
.debug
.packet_forwarding_maximum_backoff,
initial_connection_timeout: old_cfg.mixnet.debug.initial_connection_timeout,
maximum_connection_buffer_size: old_cfg.mixnet.debug.maximum_connection_buffer_size,
unsafe_disable_noise: old_cfg.mixnet.debug.unsafe_disable_noise,
use_legacy_packet_encoding: old_cfg.mixnet.debug.use_legacy_packet_encoding,
},
},
storage_paths: NymNodePaths {
keys: KeysPaths {
private_ed25519_identity_key_file: old_cfg
.storage_paths
.keys
.private_ed25519_identity_key_file,
public_ed25519_identity_key_file: old_cfg
.storage_paths
.keys
.public_ed25519_identity_key_file,
primary_x25519_sphinx_key_file: old_cfg
.storage_paths
.keys
.primary_x25519_sphinx_key_file,
private_x25519_noise_key_file: old_cfg
.storage_paths
.keys
.private_x25519_noise_key_file,
public_x25519_noise_key_file: old_cfg
.storage_paths
.keys
.public_x25519_noise_key_file,
secondary_x25519_sphinx_key_file: old_cfg
.storage_paths
.keys
.secondary_x25519_sphinx_key_file,
},
description: old_cfg.storage_paths.description,
},
http: Http {
bind_address: old_cfg.http.bind_address,
landing_page_assets_path: old_cfg.http.landing_page_assets_path,
access_token: old_cfg.http.access_token,
expose_system_info: old_cfg.http.expose_system_info,
expose_system_hardware: old_cfg.http.expose_system_hardware,
expose_crypto_hardware: old_cfg.http.expose_crypto_hardware,
node_load_cache_ttl: old_cfg.http.node_load_cache_ttl,
},
verloc: Verloc {
bind_address: old_cfg.verloc.bind_address,
announce_port: old_cfg.verloc.announce_port,
debug: VerlocDebug {
packets_per_node: old_cfg.verloc.debug.packets_per_node,
connection_timeout: old_cfg.verloc.debug.connection_timeout,
packet_timeout: old_cfg.verloc.debug.packet_timeout,
delay_between_packets: old_cfg.verloc.debug.delay_between_packets,
tested_nodes_batch_size: old_cfg.verloc.debug.tested_nodes_batch_size,
testing_interval: old_cfg.verloc.debug.testing_interval,
retry_timeout: old_cfg.verloc.debug.retry_timeout,
},
},
wireguard: Wireguard {
modes: old_cfg.modes,
host: old_cfg.host,
mixnet: old_cfg.mixnet,
storage_paths: old_cfg.storage_paths,
http: old_cfg.http,
verloc: old_cfg.verloc,
wireguard: WireguardV12 {
enabled: old_cfg.wireguard.enabled,
bind_address: old_cfg.wireguard.bind_address,
private_ipv4: old_cfg.wireguard.private_ipv4,
@@ -343,259 +203,48 @@ pub async fn try_upgrade_config_v11<P: AsRef<Path>>(
announced_metadata_port: old_cfg.wireguard.announced_metadata_port,
private_network_prefix_v4: old_cfg.wireguard.private_network_prefix_v4,
private_network_prefix_v6: old_cfg.wireguard.private_network_prefix_v6,
// \/ ADDED
use_userspace: false,
storage_paths: WireguardPaths {
private_diffie_hellman_key_file: old_cfg
.wireguard
.storage_paths
.private_diffie_hellman_key_file,
public_diffie_hellman_key_file: old_cfg
.wireguard
.storage_paths
.public_diffie_hellman_key_file,
},
// /\ ADDED
storage_paths: old_cfg.wireguard.storage_paths,
},
gateway_tasks: GatewayTasksConfig {
storage_paths: GatewayTasksPaths {
clients_storage: old_cfg.gateway_tasks.storage_paths.clients_storage,
stats_storage: old_cfg.gateway_tasks.storage_paths.stats_storage,
cosmos_mnemonic: old_cfg.gateway_tasks.storage_paths.cosmos_mnemonic,
bridge_client_params: old_cfg.gateway_tasks.storage_paths.bridge_client_params,
},
gateway_tasks: GatewayTasksConfigV12 {
storage_paths: old_cfg.gateway_tasks.storage_paths,
enforce_zk_nyms: old_cfg.gateway_tasks.enforce_zk_nyms,
ws_bind_address: old_cfg.gateway_tasks.ws_bind_address,
announce_ws_port: old_cfg.gateway_tasks.announce_ws_port,
announce_wss_port: old_cfg.gateway_tasks.announce_wss_port,
// \/ ADDED
upgrade_mode: UpgradeModeWatcher::new()
upgrade_mode: UpgradeModeWatcherV12::new()
.inspect_err(|_| {
error!(
"failed to set custom upgrade mode configuration - falling back to mainnet"
)
})
.unwrap_or(UpgradeModeWatcher::new_mainnet()),
lp: Default::default(),
.unwrap_or(UpgradeModeWatcherV12::new_mainnet()),
lp: LpConfigV12::default(),
// /\ ADDED
debug: gateway_tasks::Debug {
debug: GatewayTasksConfigDebugV12 {
message_retrieval_limit: old_cfg.gateway_tasks.debug.message_retrieval_limit,
maximum_open_connections: old_cfg.gateway_tasks.debug.maximum_open_connections,
minimum_mix_performance: old_cfg.gateway_tasks.debug.minimum_mix_performance,
max_request_timestamp_skew: old_cfg.gateway_tasks.debug.max_request_timestamp_skew,
stale_messages: StaleMessageDebug {
cleaner_run_interval: old_cfg
.gateway_tasks
.debug
.stale_messages
.cleaner_run_interval,
max_age: old_cfg.gateway_tasks.debug.stale_messages.max_age,
},
client_bandwidth: ClientBandwidthDebug {
max_flushing_rate: old_cfg
.gateway_tasks
.debug
.client_bandwidth
.max_flushing_rate,
max_delta_flushing_amount: old_cfg
.gateway_tasks
.debug
.client_bandwidth
.max_delta_flushing_amount,
},
zk_nym_tickets: ZkNymTicketHandlerDebug {
revocation_bandwidth_penalty: old_cfg
.gateway_tasks
.debug
.zk_nym_tickets
.revocation_bandwidth_penalty,
pending_poller: old_cfg.gateway_tasks.debug.zk_nym_tickets.pending_poller,
minimum_api_quorum: old_cfg
.gateway_tasks
.debug
.zk_nym_tickets
.minimum_api_quorum,
minimum_redemption_tickets: old_cfg
.gateway_tasks
.debug
.zk_nym_tickets
.minimum_redemption_tickets,
maximum_time_between_redemption: old_cfg
.gateway_tasks
.debug
.zk_nym_tickets
.maximum_time_between_redemption,
},
stale_messages: old_cfg.gateway_tasks.debug.stale_messages,
client_bandwidth: old_cfg.gateway_tasks.debug.client_bandwidth,
zk_nym_tickets: old_cfg.gateway_tasks.debug.zk_nym_tickets,
// \/ ADDED (be explicit about the value rather than using ..Default::default()
upgrade_mode_min_staleness_recheck: gateway_tasks::Debug::default()
upgrade_mode_min_staleness_recheck: GatewayTasksConfigDebugV12::default()
.upgrade_mode_min_staleness_recheck,
// /\ ADDED
},
},
service_providers: ServiceProvidersConfig {
storage_paths: ServiceProvidersPaths {
clients_storage: old_cfg.service_providers.storage_paths.clients_storage,
stats_storage: old_cfg.service_providers.storage_paths.stats_storage,
network_requester: NetworkRequesterPaths {
private_ed25519_identity_key_file: old_cfg
.service_providers
.storage_paths
.network_requester
.private_ed25519_identity_key_file,
public_ed25519_identity_key_file: old_cfg
.service_providers
.storage_paths
.network_requester
.public_ed25519_identity_key_file,
private_x25519_diffie_hellman_key_file: old_cfg
.service_providers
.storage_paths
.network_requester
.private_x25519_diffie_hellman_key_file,
public_x25519_diffie_hellman_key_file: old_cfg
.service_providers
.storage_paths
.network_requester
.public_x25519_diffie_hellman_key_file,
ack_key_file: old_cfg
.service_providers
.storage_paths
.network_requester
.ack_key_file,
reply_surb_database: old_cfg
.service_providers
.storage_paths
.network_requester
.reply_surb_database,
gateway_registrations: old_cfg
.service_providers
.storage_paths
.network_requester
.gateway_registrations,
},
ip_packet_router: IpPacketRouterPaths {
private_ed25519_identity_key_file: old_cfg
.service_providers
.storage_paths
.ip_packet_router
.private_ed25519_identity_key_file,
public_ed25519_identity_key_file: old_cfg
.service_providers
.storage_paths
.ip_packet_router
.public_ed25519_identity_key_file,
private_x25519_diffie_hellman_key_file: old_cfg
.service_providers
.storage_paths
.ip_packet_router
.private_x25519_diffie_hellman_key_file,
public_x25519_diffie_hellman_key_file: old_cfg
.service_providers
.storage_paths
.ip_packet_router
.public_x25519_diffie_hellman_key_file,
ack_key_file: old_cfg
.service_providers
.storage_paths
.ip_packet_router
.ack_key_file,
reply_surb_database: old_cfg
.service_providers
.storage_paths
.ip_packet_router
.reply_surb_database,
gateway_registrations: old_cfg
.service_providers
.storage_paths
.ip_packet_router
.gateway_registrations,
},
authenticator: AuthenticatorPaths {
private_ed25519_identity_key_file: old_cfg
.service_providers
.storage_paths
.authenticator
.private_ed25519_identity_key_file,
public_ed25519_identity_key_file: old_cfg
.service_providers
.storage_paths
.authenticator
.public_ed25519_identity_key_file,
private_x25519_diffie_hellman_key_file: old_cfg
.service_providers
.storage_paths
.authenticator
.private_x25519_diffie_hellman_key_file,
public_x25519_diffie_hellman_key_file: old_cfg
.service_providers
.storage_paths
.authenticator
.public_x25519_diffie_hellman_key_file,
ack_key_file: old_cfg
.service_providers
.storage_paths
.authenticator
.ack_key_file,
reply_surb_database: old_cfg
.service_providers
.storage_paths
.authenticator
.reply_surb_database,
gateway_registrations: old_cfg
.service_providers
.storage_paths
.authenticator
.gateway_registrations,
},
},
open_proxy: old_cfg.service_providers.open_proxy,
upstream_exit_policy_url: old_cfg.service_providers.upstream_exit_policy_url,
network_requester: NetworkRequester {
debug: NetworkRequesterDebug {
enabled: old_cfg.service_providers.network_requester.debug.enabled,
disable_poisson_rate: old_cfg
.service_providers
.network_requester
.debug
.disable_poisson_rate,
client_debug: old_cfg
.service_providers
.network_requester
.debug
.client_debug,
},
},
ip_packet_router: IpPacketRouter {
debug: IpPacketRouterDebug {
enabled: old_cfg.service_providers.ip_packet_router.debug.enabled,
disable_poisson_rate: old_cfg
.service_providers
.ip_packet_router
.debug
.disable_poisson_rate,
client_debug: old_cfg
.service_providers
.ip_packet_router
.debug
.client_debug,
},
},
authenticator: Authenticator {
debug: AuthenticatorDebug {
enabled: old_cfg.service_providers.authenticator.debug.enabled,
disable_poisson_rate: old_cfg
.service_providers
.authenticator
.debug
.disable_poisson_rate,
client_debug: old_cfg.service_providers.authenticator.debug.client_debug,
},
},
debug: service_providers::Debug {
message_retrieval_limit: old_cfg.service_providers.debug.message_retrieval_limit,
},
},
metrics: Default::default(),
logging: LoggingSettings {},
debug: Default::default(),
service_providers: old_cfg.service_providers,
metrics: old_cfg.metrics,
logging: old_cfg.logging,
// \/ FIXED
debug: DebugV12::default(),
// /\ FIXED
};
Ok(cfg)
}
File diff suppressed because it is too large Load Diff
+49
View File
@@ -20,6 +20,8 @@ pub const DEFAULT_X25519_PUBLIC_NOISE_KEY_FILENAME: &str = "x25519_noise.pub";
pub const DEFAULT_NYMNODE_DESCRIPTION_FILENAME: &str = "description.toml";
// Global/LP:
pub const DEFAULT_X25519_PRIVATE_LP_KEY_FILENAME: &str = "x25519_lp";
pub const DEFAULT_X25519_PUBLIC_LP_KEY_FILENAME: &str = "x25519_lp.pub";
pub const DEFAULT_MLKEM768_PRIVATE_KEY_FILENAME: &str = "mlkem768";
pub const DEFAULT_MLKEM768_PUBLIC_KEY_FILENAME: &str = "mlkem768.pub";
pub const DEFAULT_MCELIECE_PRIVATE_KEY_FILENAME: &str = "mceliece";
@@ -105,6 +107,26 @@ pub struct KeysPaths {
/// Path to file containing x25519 noise public key.
pub public_x25519_noise_key_file: PathBuf,
// >> LP KEYS START:
/// Path to file containing x25519 lp private key.
pub private_x25519_lp_key_file: PathBuf,
/// Path to file containing x25519 lp public key.
pub public_x25519_lp_key_file: PathBuf,
/// Path to file containing mlkem768 lp private key.
pub private_mlkem768_lp_key_file: PathBuf,
/// Path to file containing mlkem768 lp public key.
pub public_mlkem768_lp_key_file: PathBuf,
/// Path to file containing mceliece lp private key.
pub private_mceliece_lp_key_file: PathBuf,
/// Path to file containing mceliece lp public key.
pub public_mceliece_lp_key_file: PathBuf,
// >> LP KEYS END
}
impl KeysPaths {
@@ -122,6 +144,12 @@ impl KeysPaths {
.join(DEFAULT_SECONDARY_X25519_SPHINX_KEY_FILENAME),
private_x25519_noise_key_file: data_dir.join(DEFAULT_X25519_PRIVATE_NOISE_KEY_FILENAME),
public_x25519_noise_key_file: data_dir.join(DEFAULT_X25519_PUBLIC_NOISE_KEY_FILENAME),
private_x25519_lp_key_file: data_dir.join(DEFAULT_X25519_PRIVATE_LP_KEY_FILENAME),
public_x25519_lp_key_file: data_dir.join(DEFAULT_X25519_PUBLIC_LP_KEY_FILENAME),
private_mlkem768_lp_key_file: data_dir.join(DEFAULT_MLKEM768_PRIVATE_KEY_FILENAME),
public_mlkem768_lp_key_file: data_dir.join(DEFAULT_MLKEM768_PUBLIC_KEY_FILENAME),
private_mceliece_lp_key_file: data_dir.join(DEFAULT_MCELIECE_PRIVATE_KEY_FILENAME),
public_mceliece_lp_key_file: data_dir.join(DEFAULT_MCELIECE_PUBLIC_KEY_FILENAME),
}
}
@@ -138,6 +166,27 @@ impl KeysPaths {
&self.public_x25519_noise_key_file,
)
}
pub fn x25519_lp_key_paths(&self) -> nym_pemstore::KeyPairPath {
nym_pemstore::KeyPairPath::new(
&self.private_x25519_lp_key_file,
&self.public_x25519_lp_key_file,
)
}
pub fn mlkem768_key_paths(&self) -> nym_pemstore::KeyPairPath {
nym_pemstore::KeyPairPath::new(
&self.private_mlkem768_lp_key_file,
&self.public_mlkem768_lp_key_file,
)
}
pub fn mceliece_key_paths(&self) -> nym_pemstore::KeyPairPath {
nym_pemstore::KeyPairPath::new(
&self.private_mceliece_lp_key_file,
&self.public_mceliece_lp_key_file,
)
}
}
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
+2 -1
View File
@@ -18,7 +18,8 @@ async fn try_upgrade_config(path: &Path) -> Result<(), NymNodeError> {
let cfg = try_upgrade_config_v8(path, cfg).await.ok();
let cfg = try_upgrade_config_v9(path, cfg).await.ok();
let cfg = try_upgrade_config_v10(path, cfg).await.ok();
match try_upgrade_config_v11(path, cfg).await {
let cfg = try_upgrade_config_v11(path, cfg).await.ok();
match try_upgrade_config_v12(path, cfg).await {
Ok(cfg) => cfg.save(),
Err(e) => {
tracing::error!("Failed to finish upgrade: {e}");
+4
View File
@@ -5,6 +5,7 @@ use crate::node::http::error::NymNodeHttpError;
use crate::wireguard::error::WireguardError;
use nym_http_api_client::HttpClientError;
use nym_ip_packet_router::error::ClientCoreError;
use nym_kkt::keys::storage_wrappers::MalformedStoredKeyError;
use nym_validator_client::ValidatorClientError;
use nym_validator_client::nyxd::error::NyxdError;
use std::io;
@@ -231,6 +232,9 @@ pub enum NymNodeError {
#[error("failed upgrade")]
FailedUpgrade,
#[error(transparent)]
MalformedStoredKey(#[from] MalformedStoredKeyError),
}
impl From<EntryGatewayError> for NymNodeError {
+83
View File
@@ -6,6 +6,10 @@ use crate::error::{KeyIOFailure, NymNodeError};
use crate::node::key_rotation::key::{SphinxPrivateKey, SphinxPublicKey};
use crate::node::nym_apis_client::NymApisClient;
use nym_crypto::asymmetric::{ed25519, x25519};
use nym_kkt::keys::storage_wrappers::StorableKey;
use nym_kkt::keys::{
DHKeyPair, DHPrivateKey, MlKem768KeyPair, MlKem768PrivateKey, MlKem768PublicKey, mceliece,
};
use nym_node_requests::api::v1::node::models::NodeDescription;
use nym_pemstore::KeyPairPath;
use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair};
@@ -169,6 +173,34 @@ pub(crate) fn load_x25519_wireguard_keypair(
Ok(load_keypair(paths, "x25519-wireguard")?)
}
fn load_lp_key<S, P>(path: P, name: &'static str) -> Result<S, NymNodeError>
where
P: AsRef<Path>,
S: StorableKey,
{
let repr = load_key::<<S as StorableKey>::StorableRepresentation<'_>, _>(path, name)?;
Ok(S::from_storable(repr)?)
}
pub(crate) fn load_x25519_lp_keypair(paths: &KeyPairPath) -> Result<DHKeyPair, NymNodeError> {
let pk: DHPrivateKey = load_lp_key(&paths.private_key_path, "x25519-lp-private-key")?;
Ok(DHKeyPair::from(pk))
}
pub(crate) fn load_mlkem768_keypair(paths: &KeyPairPath) -> Result<MlKem768KeyPair, NymNodeError> {
let sk: MlKem768PrivateKey = load_lp_key(&paths.private_key_path, "mlkem768-private-key")?;
let pk: MlKem768PublicKey = load_lp_key(&paths.public_key_path, "mlkem768-public-key")?;
Ok(MlKem768KeyPair::from(sk, pk))
}
pub(crate) fn load_mceliece_keypair(
paths: &KeyPairPath,
) -> Result<mceliece::KeyPair, NymNodeError> {
let sk: mceliece::SecretKey = load_lp_key(&paths.private_key_path, "mceliece-private-key")?;
let pk: mceliece::PublicKey = load_lp_key(&paths.public_key_path, "mceliece-public-key")?;
Ok(mceliece::KeyPair { sk, pk })
}
pub(crate) fn store_ed25519_identity_keypair(
keys: &ed25519::KeyPair,
paths: &KeyPairPath,
@@ -183,6 +215,57 @@ pub(crate) fn store_x25519_noise_keypair(
Ok(store_keypair(keys, paths, "x25519-noise")?)
}
pub(crate) fn store_x25519_lp_keypair(
keys: &DHKeyPair,
paths: &KeyPairPath,
) -> Result<(), NymNodeError> {
store_key(
&keys.pk.to_storable(),
&paths.public_key_path,
"x25519-lp-public-key",
)?;
store_key(
&keys.sk().to_storable(),
&paths.private_key_path,
"x25519-lp-private-key",
)?;
Ok(())
}
pub(crate) fn store_mlkem768_keypair(
keys: &MlKem768KeyPair,
paths: &KeyPairPath,
) -> Result<(), NymNodeError> {
store_key(
&keys.public_key().to_storable(),
&paths.public_key_path,
"mlkem768-public-key",
)?;
store_key(
&keys.private_key().to_storable(),
&paths.private_key_path,
"mlkem768-private-key",
)?;
Ok(())
}
pub(crate) fn store_mceliece_keypair(
keys: &mceliece::KeyPair,
paths: &KeyPairPath,
) -> Result<(), NymNodeError> {
store_key(
&keys.pk.to_storable(),
&paths.public_key_path,
"mceliece-public-key",
)?;
store_key(
&keys.sk.to_storable(),
&paths.private_key_path,
"mceliece-private-key",
)?;
Ok(())
}
pub(crate) async fn get_current_rotation_id(
nym_apis: &[Url],
fallback_nyxd: &[Url],