Skip to main content

Crate ed25519_heapless

Crate ed25519_heapless 

Source
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 / verificationSigningKey via signature::Signer (deterministic) and RandomizedSigner (hedged + blinded); VerifyingKey via signature::Verifier. Twisted Edwards form, SHA-512 challenge, NAF double-scalar multiplication.
  • X25519 key agreement — the KEM x25519_kem::X25519Kem (kem::Kem), with an Unblinded default and a Blinded personality. 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 timing
  • fixed-bigint — enables the fixed-bigint backend
  • no_std compatible 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 hazmat convention (cf. signature::hazmat). Prefer the KEM (x25519_kem) and the signature traits; 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§

Curve25519Field
Variable-time field over F_{2^255 − 19}.
Curve25519FieldCt
Constant-time field over F_{2^255 − 19}. Same lazy fast paths as Curve25519Field but the conditional in lazy add / sub is done branchlessly with subtle::ConditionallySelectable.
Field
Montgomery context over modulus T, with algorithm choice driven by the personality marker P (defaults to Nct = variable-time fast path).
Residue
A value in Field<T, P>, stored implicitly in Montgomery form.
SigningKey
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 typed T so the struct stays generic over the backend without forcing T: Zeroize on the struct definition.
VerifyingKey
Verifying key wrapper that implements signature crate traits.

Enums§

CurveSetupError
Reasons the Curve25519Field::curve25519 / Curve25519FieldCt::curve25519 factories can refuse to construct a field. Both arms are unreachable for any well-formed backend: BackendTooNarrow is a backend-selection bug, and InvalidModulus would require modmath::Field::new to reject p = 2^255 − 19. It propagates into crate::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 to false on Err.
SignError
Errors from sign setup. FieldSetup covers the upstream CurveSetupError from p-field or q-field construction; both arms of CurveSetupError are unreachable for any well-formed backend, but the Result shape 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§

SignBackend
Aggregate bound bundle for the constant-time sign path: CT field arithmetic on Curve25519, byte (de)serialization, branchless selection, and Zeroize for secret-intermediate wiping.
UnsignedModularInt
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) and const_num_traits::ToBytes (owned bytes with AsRef<[u8]>), which any conforming backend implements without ed25519 knowing the backend type.
VerifyBackend
Carrier bound bundle for the verify path. Verify is variable-time on public data, so — unlike SignBackend — it needs neither Copy nor subtle: a Clone heap carrier (e.g. num-bigint) satisfies it. This is the Clone / consume-self / by-reference subset of UnsignedModularInt that verify’s own code exercises, minus the Montgomery-only ops (those live on the field’s VerifyField impl, not here). Any UnsignedModularInt carrier also satisfies it, so the fixed-width Copy verify path is unaffected.
VerifyField
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 (SchoolbookFieldRef carries no subtle bound).

Type Aliases§

FieldCt
Alias for the Ct variant of Field. Equivalent to Field<T, Ct>. Reads naturally at construction sites and sidesteps the type-inference ambiguity that bare Field::new(modulus) hits — FieldCt::new(modulus) resolves unambiguously because the alias fixes P = Ct at the type level. Symmetric with FieldNct.
FieldNct
Alias for the Nct variant of Field. Equivalent to Field<T, Nct> (matches the default personality). Provided for symmetry with FieldCt and to side-step the construction-site type-ambiguity pitfall — FieldNct::new(modulus) resolves unambiguously without the type-annotation/turbofish friction of Field::new(modulus).
ResidueCt
Alias for the Ct variant of Residue. Equivalent to Residue<'f, T, Ct>. Symmetric with ResidueNct.
ResidueNct
Alias for the Nct variant of Residue. Equivalent to Residue<'f, T, Nct>. Symmetric with ResidueCt.