pub trait P384Ec {
// Required methods
fn generate_keypair(
rng: &mut dyn Rng,
) -> Result<(P384Scalar, P384AffinePoint), CryptoError>;
fn public_key(k: P384Scalar) -> Result<P384AffinePoint, CryptoError>;
fn validate_point(p: &P384AffinePoint) -> bool;
fn ecdh_shared_secret(
k: P384Scalar,
peer: P384AffinePoint,
) -> Result<[u8; 48], CryptoError>;
fn ecdsa_sign(
k: P384Scalar,
digest: &[u8; 48],
rng: &mut dyn Rng,
) -> Result<P384Signature, CryptoError>;
fn ecdsa_verify(
q: P384AffinePoint,
digest: &[u8; 48],
sig: &P384Signature,
) -> Result<(), CryptoError>;
}Expand description
High-level P-384 operations for TLS 1.3.
Each method corresponds to one operation a TLS 1.3 stack
performs, so a hardware backend can implement it end-to-end where the
peripheral natively supports the whole operation. Everything below
this layer (field arithmetic, point encoding, hashing, HKDF) stays in
software in embassy-crypto, composing with Sha256,
HmacSha256, Aes128Gcm and Aes128Cmac.
§Entropy
Methods that need fresh randomness take rng and must draw their
nonce/ephemeral scalar from it, using rejection sampling until the
value lands in [1, n-1]. Hardware whose operation mandates an
internal entropy source (e.g. peripherals that generate the ECDSA
nonce on-chip from a TRNG) may ignore rng; such implementations must
document this. For deterministic known-answer tests, callers inject a
deterministic Rng.
§Contract
- All private/ephemeral scalars and signature components are canonical
(
[1, n-1]); non-canonical inputs returnCryptoError::InvalidKeyorCryptoError::InvalidInput. - All points are valid on-curve affine points in canonical big-endian
encoding. Callers must run
P384Ec::validate_pointon untrusted peer public keys (TLS 1.3 RFC 8446 4.4.3.2, BLE Core Spec Vol 6 5.8.4.4) beforeP384Ec::ecdh_shared_secretorP384Ec::ecdsa_verify. - No secret-dependent timing w.r.t. private keys, nonces, or ephemeral
scalars.
P384Ec::ecdsa_verifymay be variable-time. - Implementations wipe nonce/scalar copies they materialize in RAM.
Required Methods§
Sourcefn generate_keypair(
rng: &mut dyn Rng,
) -> Result<(P384Scalar, P384AffinePoint), CryptoError>
fn generate_keypair( rng: &mut dyn Rng, ) -> Result<(P384Scalar, P384AffinePoint), CryptoError>
Generate a fresh keypair: d uniform in [1, n-1], Q = d * G.
Used for TLS 1.3 ECDHE keygen.
Sourcefn public_key(k: P384Scalar) -> Result<P384AffinePoint, CryptoError>
fn public_key(k: P384Scalar) -> Result<P384AffinePoint, CryptoError>
Derive the public key k * G from a known private scalar.
No RNG: used for persistent keys (e.g. a TLS static ECDSA identity
loaded from flash, or deriving a BLE public key from a stored
secret) where the caller already holds k.
Sourcefn validate_point(p: &P384AffinePoint) -> bool
fn validate_point(p: &P384AffinePoint) -> bool
Validate that p is a non-identity point on the P-384 curve.
ECDH shared secret: X coordinate of k * peer, big-endian.
This is the TLS 1.3 ecdhe_shared_secret (fed into HKDF via
HmacSha256) and the BLE LE-SC DHKey.
Sourcefn ecdsa_sign(
k: P384Scalar,
digest: &[u8; 48],
rng: &mut dyn Rng,
) -> Result<P384Signature, CryptoError>
fn ecdsa_sign( k: P384Scalar, digest: &[u8; 48], rng: &mut dyn Rng, ) -> Result<P384Signature, CryptoError>
ECDSA sign a pre-hashed message (ecdsa_secp384r1_sha384).
The nonce is drawn from rng unless the hardware mandates an
internal entropy source. Returns a low-S normalized signature.
Sourcefn ecdsa_verify(
q: P384AffinePoint,
digest: &[u8; 48],
sig: &P384Signature,
) -> Result<(), CryptoError>
fn ecdsa_verify( q: P384AffinePoint, digest: &[u8; 48], sig: &P384Signature, ) -> Result<(), CryptoError>
ECDSA verify a pre-hashed message. All inputs public; may be
variable-time. Err(CryptoError::InvalidSignature) on failure.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".