Expand description
Curve25519 primitives for embedded targets, generic over bigint backends.
Provides two operations on top of a shared field machinery, exposed through standard RustCrypto traits:
- Ed25519 signing / verification —
SigningKeyviasignature::Signer(deterministic) andRandomizedSigner(hedged + blinded);VerifyingKeyviasignature::Verifier. Twisted Edwards form, SHA-512 challenge, NAF double-scalar multiplication. - X25519 key agreement — the KEM
x25519_kem::X25519Kem(kem::Kem), with anUnblindeddefault and aBlindedpersonality. Montgomery x-only ladder, RFC 7748.
Raw scalar-mult primitives (x25519, x25519_blinded, …) and the
amortized-field sign/verify live in hazmat — reach there only for
static-static DH or custom protocols. There is no top-level free-function API.
Both curves live in F_p where p = 2^255 - 19, so they share the same
UnsignedModularInt trait, MontgomeryCtx, and lazy-reduction helpers.
§Usage
use ed25519_heapless::VerifyingKey;
use signature::Verifier;
use fixed_bigint::FixedUInt;
type T = FixedUInt<u32, 16>;
let valid = VerifyingKey::<T>::from_bytes(public_key)
.verify(message, &signature)
.is_ok();§Features
std(default) — enables logging and timingfixed-bigint— enables thefixed-bigintbackendno_stdcompatible with--no-default-features
§Constant-time scope
Ed25519 verification operates on public data only; constant-time isn’t a
requirement there. For X25519 the secret scalar is sensitive: the ladder’s
conditional swap is branchless, but the underlying field arithmetic
(MontgomeryCtx, lazy_field) has not been audited as constant-time and
may exhibit data-dependent timing on some backends. Suitable for embedded
bring-up; not yet hardened against side-channel adversaries.
Modules§
- hazmat
- Low-level primitives with no safe trait wrapper — the RustCrypto
hazmatconvention (cf.signature::hazmat). Prefer the KEM (x25519_kem) and thesignaturetraits; reach here only for the raw scalar-mult (static-static DH, custom protocols) or the amortized-field sign/verify. - x25519_
kem - X25519 as a key-encapsulation mechanism (
kem::Kem).
Structs§
- Curve25519
Field - Variable-time field over
F_{2^255 − 19}. - Curve25519
Field Ct - Constant-time field over
F_{2^255 − 19}. Same lazy fast paths asCurve25519Fieldbut the conditional in lazyadd/subis done branchlessly withsubtle::ConditionallySelectable. - Field
- Montgomery context over modulus
T, with algorithm choice driven by the personality markerP(defaults toNct= variable-time fast path). - Residue
- A value in
Field<T, P>, stored implicitly in Montgomery form. - Signing
Key - Ed25519 signing key. Holds the expanded clamped-scalar bytes and
nonce-prefix (
Zeroizing-wiped on drop) plus the cached encoded public key. The clamped scalar is stored as raw bytes rather than as a typedTso the struct stays generic over the backend without forcingT: Zeroizeon the struct definition. - Verifying
Key - Verifying key wrapper that implements
signaturecrate traits.
Enums§
- Curve
Setup Error - Reasons the
Curve25519Field::curve25519/Curve25519FieldCt::curve25519factories can refuse to construct a field. Both arms are unreachable for any well-formed backend:BackendTooNarrowis a backend-selection bug, andInvalidModuluswould requiremodmath::Field::newto rejectp = 2^255 − 19. It propagates intocrate::SignError::FieldSetup(via [crate::sign] /crate::SigningKey::from_seed) and is the error the x25519 entry points return. [crate::verify] builds the field through the factory and fails closed tofalseonErr. - Sign
Error - Errors from sign setup.
FieldSetupcovers the upstreamCurveSetupErrorfrom p-field or q-field construction; both arms ofCurveSetupErrorare unreachable for any well-formed backend, but theResultshape keeps the panic-fmt symbol out of the linked binary.
Constants§
- A24_
BYTES - X25519 constants (RFC 7748). The scalar-mult primitives live in
hazmat. A24 = (A - 2) / 4 = 121665, where A = 486662 is the Montgomery curve coefficient (RFC 7748 §4.1). - BASE_
U_ BYTES - X25519 constants (RFC 7748). The scalar-mult primitives live in
hazmat. The u-coordinate of the X25519 base point. u = 9 (RFC 7748). - BLINDING_
MODULUS_ BYTES - X25519 constants (RFC 7748). The scalar-mult primitives live in
hazmat. Universal blinding modulus:lcm(curve_order, twist_order) = 8·ℓ·ℓ'whereℓis the curve subgroup order andℓ'is the twist subgroup order. Annihilates every point on Curve25519 and its twist, so the blinded path matches the unblinded path for every 32-byte u-coordinate the X25519 ladder accepts.8·ℓalone would only work for curve points; using the LCM costs ~2× ladder iterations but eliminates the twist-conformance gap. - D_BYTES
- G_
T_ BYTES - G_
X_ BYTES - G_
Y_ BYTES - MODP_
SQRT_ M1_ BYTES - P_BYTES
- Q_BYTES
Traits§
- Sign
Backend - Aggregate bound bundle for the constant-time sign path: CT field
arithmetic on Curve25519, byte (de)serialization, branchless
selection, and
Zeroizefor secret-intermediate wiping. - Unsigned
Modular Int - Bound bundle for the generic bigint backend Ed25519 verify + X25519
build on. Pure marker trait: no methods, just a named alias for the
supertrait union. Byte (de)serialization goes through
const_num_traits::FromByteSlice(fallible slice-in) andconst_num_traits::ToBytes(owned bytes withAsRef<[u8]>), which any conforming backend implements without ed25519 knowing the backend type. - Verify
Backend - Carrier bound bundle for the verify path. Verify is variable-time on
public data, so — unlike
SignBackend— it needs neitherCopynorsubtle: aCloneheap carrier (e.g. num-bigint) satisfies it. This is theClone/ consume-self / by-reference subset ofUnsignedModularIntthat verify’s own code exercises, minus the Montgomery-only ops (those live on the field’sVerifyFieldimpl, not here). AnyUnsignedModularIntcarrier also satisfies it, so the fixed-widthCopyverify path is unaffected. - Verify
Field - The field-operation surface the Ed25519 verify path consumes,
abstracted over personality so [
crate::verify] runs on either the non-constant-time field (Curve25519Field, the default) or the constant-time field (Curve25519FieldCt).
Functions§
- curve25519_
schoolbook - Build the variable-time Nct schoolbook verify field over the Curve25519
prime for a
Clone(non-Copy) heap carrier — the entry point for a verify-only heap-backed build (e.g.num-bigint). Pairs with [crate::verify_with_field]; the returned field can never reach a constant-time path (SchoolbookFieldRefcarries nosubtlebound).
Type Aliases§
- FieldCt
- Alias for the Ct variant of
Field. Equivalent toField<T, Ct>. Reads naturally at construction sites and sidesteps the type-inference ambiguity that bareField::new(modulus)hits —FieldCt::new(modulus)resolves unambiguously because the alias fixesP = Ctat the type level. Symmetric withFieldNct. - Field
Nct - Alias for the Nct variant of
Field. Equivalent toField<T, Nct>(matches the default personality). Provided for symmetry withFieldCtand to side-step the construction-site type-ambiguity pitfall —FieldNct::new(modulus)resolves unambiguously without the type-annotation/turbofish friction ofField::new(modulus). - Residue
Ct - Alias for the Ct variant of
Residue. Equivalent toResidue<'f, T, Ct>. Symmetric withResidueNct. - Residue
Nct - Alias for the Nct variant of
Residue. Equivalent toResidue<'f, T, Nct>. Symmetric withResidueCt.