Skip to main content

noxtls_crypto/pkc/primitive/
mod.rs

1// Copyright (c) 2019-2026, Argenox Technologies LLC
2// All rights reserved.
3//
4// SPDX-License-Identifier: GPL-2.0-only OR LicenseRef-Argenox-Commercial-License
5//
6// This file is part of the NoxTLS Library.
7//
8// This program is free software: you can redistribute it and/or modify
9// it under the terms of the GNU General Public License as published by the
10// Free Software Foundation; version 2 of the License.
11//
12// Alternatively, this file may be used under the terms of a commercial
13// license from Argenox Technologies LLC.
14//
15// See `noxtls/LICENSE` and `noxtls/LICENSE.md` in this repository for full details.
16// CONTACT: info@argenox.com
17
18//! Concrete public-key implementations (RSA, ECC, X25519/X448, Ed25519, ML-KEM, ML-DSA).
19//!
20//! Submodules are private; this module re-exports the supported API and provides
21//! [`ecc_generate_keypair_auto`] for unified ECC key generation.
22
23mod bignum;
24mod ed25519;
25mod mldsa;
26mod mlkem;
27mod p256;
28mod pq_selftest;
29mod rsa;
30mod x25519;
31mod x448;
32
33use crate::drbg::HmacDrbgSha256;
34#[cfg(not(feature = "hazardous-legacy-crypto"))]
35use noxtls_core::Error;
36use noxtls_core::Result;
37
38pub use ed25519::{
39    ed25519_generate_private_key_auto, ed25519_public_key_from_subject_public_key_info,
40    ed25519_verify, Ed25519PrivateKey, Ed25519PublicKey,
41};
42pub use mldsa::{
43    mldsa_generate_keypair_auto, mldsa_public_key_from_subject_public_key_info, mldsa_verify,
44    MlDsaPrivateKey, MlDsaPublicKey, OID_ID_MLDSA65,
45};
46pub use mlkem::{
47    mlkem_decapsulate, mlkem_encapsulate_auto, mlkem_generate_keypair_auto, MlKemPrivateKey,
48    MlKemPublicKey, MLKEM_CIPHERTEXT_LEN, MLKEM_PRIVATE_KEY_LEN, MLKEM_PUBLIC_KEY_LEN,
49    MLKEM_SHARED_SECRET_LEN,
50};
51pub use p256::{
52    p256_ecdh_shared_secret, p256_ecdsa_sign_digest, p256_ecdsa_sign_digest_auto,
53    p256_ecdsa_sign_sha256, p256_ecdsa_sign_sha256_auto, p256_ecdsa_verify_digest,
54    p256_ecdsa_verify_sha256, p256_generate_private_key_auto, P256PrivateKey, P256PublicKey,
55};
56pub use pq_selftest::run_pq_self_tests;
57#[cfg(feature = "hazardous-legacy-crypto")]
58pub use rsa::{rsa_generate_keypair_auto, rsa_generate_keypair_with_exponent_auto};
59pub use rsa::{
60    rsa_generate_keypair_secure_auto, rsa_generate_keypair_with_policy_auto,
61    rsaes_oaep_sha256_decrypt, rsaes_oaep_sha256_decrypt_crt_only, rsaes_oaep_sha256_encrypt_auto,
62    rsaes_pkcs1_v15_decrypt, rsaes_pkcs1_v15_decrypt_crt_only, rsaes_pkcs1_v15_encrypt_auto,
63    rsassa_pss_sha256_sign, rsassa_pss_sha256_sign_auto, rsassa_pss_sha256_verify,
64    rsassa_pss_sha384_sign, rsassa_pss_sha384_sign_auto, rsassa_pss_sha384_verify,
65    rsassa_sha1_sign, rsassa_sha1_verify, rsassa_sha256_sign, rsassa_sha256_verify,
66    rsassa_sha384_sign, rsassa_sha384_verify, rsassa_sha512_sign, rsassa_sha512_verify,
67    RsaKeySizePolicy, RsaPrivateKey, RsaPublicKey,
68};
69pub use x25519::{
70    x25519, x25519_basepoint, x25519_generate_private_key_auto, x25519_shared_secret,
71    X25519PrivateKey, X25519PublicKey,
72};
73#[cfg(feature = "hazardous-legacy-crypto")]
74pub use x448::x448_generate_private_key_auto;
75#[cfg(feature = "hazardous-legacy-crypto")]
76pub use x448::{x448, x448_basepoint, x448_shared_secret};
77pub use x448::{X448PrivateKey, X448PublicKey};
78
79/// Selects one supported elliptic-curve key algorithm for unified key generation.
80#[derive(Debug, Clone, Copy, Eq, PartialEq)]
81pub enum EccKeyAlgorithm {
82    /// NIST P-256 (secp256r1) key material.
83    P256,
84    /// Curve25519 X25519 key-exchange key material.
85    X25519,
86    /// Curve448 X448 key-exchange key material.
87    X448,
88    /// Ed25519 signing key material.
89    Ed25519,
90}
91
92/// Wraps one generated ECC private key variant.
93#[derive(Debug, Clone)]
94pub enum EccPrivateKey {
95    /// P-256 private scalar.
96    P256(P256PrivateKey),
97    /// X25519 private scalar.
98    X25519(X25519PrivateKey),
99    /// X448 private scalar.
100    X448(X448PrivateKey),
101    /// Ed25519 signing seed/key.
102    Ed25519(Ed25519PrivateKey),
103}
104
105/// Wraps one generated ECC public key variant.
106#[derive(Debug, Clone, Eq, PartialEq)]
107pub enum EccPublicKey {
108    /// P-256 public point.
109    P256(P256PublicKey),
110    /// X25519 public u-coordinate.
111    X25519(X25519PublicKey),
112    /// X448 public u-coordinate.
113    X448(X448PublicKey),
114    /// Ed25519 verifying key.
115    Ed25519(Ed25519PublicKey),
116}
117
118/// Generates one ECC private/public keypair for the selected algorithm using DRBG entropy.
119///
120/// # Arguments
121/// * `algorithm`: ECC algorithm to generate.
122/// * `drbg`: DRBG source used for private-key randomness.
123///
124/// # Returns
125/// `(private_key, public_key)` pair wrapped by enum variants matching `algorithm`.
126///
127/// # Errors
128///
129/// Returns any error produced by the algorithm-specific DRBG-driven generators (for example P-256 field validation, DRBG state errors, or malformed lengths from underlying calls).
130///
131/// # Panics
132///
133/// This function does not panic.
134pub fn ecc_generate_keypair_auto(
135    algorithm: EccKeyAlgorithm,
136    drbg: &mut HmacDrbgSha256,
137) -> Result<(EccPrivateKey, EccPublicKey)> {
138    match algorithm {
139        EccKeyAlgorithm::P256 => {
140            let private = p256_generate_private_key_auto(drbg)?;
141            let public = private.public_key()?;
142            Ok((EccPrivateKey::P256(private), EccPublicKey::P256(public)))
143        }
144        EccKeyAlgorithm::X25519 => {
145            let private = x25519_generate_private_key_auto(drbg)?;
146            let public = private.clone().public_key();
147            Ok((EccPrivateKey::X25519(private), EccPublicKey::X25519(public)))
148        }
149        #[cfg(feature = "hazardous-legacy-crypto")]
150        EccKeyAlgorithm::X448 => {
151            let private = x448_generate_private_key_auto(drbg)?;
152            let public = private.clone().public_key();
153            Ok((EccPrivateKey::X448(private), EccPublicKey::X448(public)))
154        }
155        #[cfg(not(feature = "hazardous-legacy-crypto"))]
156        EccKeyAlgorithm::X448 => Err(Error::StateError(
157            "x448 operations are disabled by default; enable `hazardous-legacy-crypto` to use non-constant-time x448 implementation",
158        )),
159        EccKeyAlgorithm::Ed25519 => {
160            let private = ed25519_generate_private_key_auto(drbg)?;
161            let public = private.verifying_key();
162            Ok((
163                EccPrivateKey::Ed25519(private),
164                EccPublicKey::Ed25519(public),
165            ))
166        }
167    }
168}