Skip to main content

polymorph_webcrypto_guest/
x25519.rs

1//! `x25519` key creation (RFC 7748 §5, the X25519 function).
2//!
3//! Keys minted here drive [`AgreementSecretKey::agree`], whose result
4//! chains into the KDFs (see
5//! [`hkdf_sha2::prepare_from`](crate::hkdf_sha2::prepare_from)). Peer
6//! imports are deliberately permissive — a degenerate (small-order) peer
7//! surfaces at `agree`, the operation that computes the secret, as
8//! [`Error::InvalidKey`](crate::Error::InvalidKey).
9//!
10//! [`AgreementSecretKey::agree`]: crate::AgreementSecretKey::agree
11
12use crate::{bindings, AgreementKeyOptions, AgreementPublicKey, AgreementSecretKey, Error};
13
14/// Import a peer's raw 32-byte public key (RFC 7748's little-endian
15/// u-coordinate).
16pub async fn import_public_key_raw(raw: impl Into<Vec<u8>>) -> Result<AgreementPublicKey, Error> {
17    Ok(AgreementPublicKey::from_raw(
18        bindings::x25519::import_public_key_raw(raw.into()).await?,
19    ))
20}
21
22/// Import a peer's public key from an X.509 SubjectPublicKeyInfo (DER).
23pub async fn import_public_key_spki(spki: impl Into<Vec<u8>>) -> Result<AgreementPublicKey, Error> {
24    Ok(AgreementPublicKey::from_raw(
25        bindings::x25519::import_public_key_spki(spki.into()).await?,
26    ))
27}
28
29/// Import a peer's public key from an RFC 8037 OKP JWK (as JSON text).
30pub async fn import_public_key_jwk(jwk: impl Into<String>) -> Result<AgreementPublicKey, Error> {
31    Ok(AgreementPublicKey::from_raw(
32        bindings::x25519::import_public_key_jwk(jwk.into()).await?,
33    ))
34}
35
36/// Import a secret key from a PKCS#8 PrivateKeyInfo (DER).
37pub async fn import_secret_key_pkcs8(
38    pkcs8: impl Into<Vec<u8>>,
39    options: AgreementKeyOptions,
40) -> Result<AgreementSecretKey, Error> {
41    Ok(AgreementSecretKey::from_raw(
42        bindings::x25519::import_secret_key_pkcs8(pkcs8.into(), options.lower()).await?,
43    ))
44}
45
46/// Import a secret key from an RFC 8037 OKP private JWK (as JSON text).
47pub async fn import_secret_key_jwk(
48    jwk: impl Into<String>,
49    options: AgreementKeyOptions,
50) -> Result<AgreementSecretKey, Error> {
51    Ok(AgreementSecretKey::from_raw(
52        bindings::x25519::import_secret_key_jwk(jwk.into(), options.lower()).await?,
53    ))
54}
55
56/// Generate a fresh random keypair, returning both halves.
57pub async fn generate_key(
58    options: AgreementKeyOptions,
59) -> Result<(AgreementSecretKey, AgreementPublicKey), Error> {
60    let (secret, public) = bindings::x25519::generate_key(options.lower()).await?;
61    Ok((
62        AgreementSecretKey::from_raw(secret),
63        AgreementPublicKey::from_raw(public),
64    ))
65}