Skip to main content

polymorph_webcrypto_guest/
ed25519.rs

1//! `ed25519-verify` / `ed25519-sign` key creation.
2
3use crate::{bindings, Error, SigningKey, SigningKeyOptions, UnwrapInput, VerifyingKey};
4
5/// Import a 32-byte raw public key (RFC 8032 encoding). Material of any
6/// other length fails [`Error::InvalidKey`]; a non-canonical or
7/// small-order encoding is rejected here or at verification, per the WIT
8/// interface's verification criterion.
9pub async fn import_verifying_key_raw(raw: impl Into<Vec<u8>>) -> Result<VerifyingKey, Error> {
10    Ok(VerifyingKey::from_raw(
11        bindings::ed25519_verify::import_verifying_key_raw(raw.into()).await?,
12    ))
13}
14
15/// Import a public key as an X.509 SubjectPublicKeyInfo (DER, RFC 8410).
16/// The embedded point is subject to the same strict criterion as
17/// [`import_verifying_key_raw`].
18pub async fn import_verifying_key_spki(spki: impl Into<Vec<u8>>) -> Result<VerifyingKey, Error> {
19    Ok(VerifyingKey::from_raw(
20        bindings::ed25519_verify::import_verifying_key_spki(spki.into()).await?,
21    ))
22}
23
24/// Import a public key as an RFC 8037 OKP public JWK (`kty: "OKP"`,
25/// `crv: "Ed25519"`, `x`; as JSON text). An `alg` member, when present,
26/// must be `"Ed25519"` or `"EdDSA"`. The same strict point criterion as
27/// [`import_verifying_key_raw`] applies; see the WIT
28/// `mac-key.export-key-jwk` doc for the package-wide JWK contract.
29pub async fn import_verifying_key_jwk(jwk: impl Into<String>) -> Result<VerifyingKey, Error> {
30    Ok(VerifyingKey::from_raw(
31        bindings::ed25519_verify::import_verifying_key_jwk(jwk.into()).await?,
32    ))
33}
34
35/// Generate a fresh random signing key, returning both halves.
36pub async fn generate_key(options: SigningKeyOptions) -> Result<(SigningKey, VerifyingKey), Error> {
37    let (signing, verifying) = bindings::ed25519_sign::generate_key(options.lower()).await?;
38    Ok((
39        SigningKey::from_raw(signing),
40        VerifyingKey::from_raw(verifying),
41    ))
42}
43
44/// Import a signing key as a PKCS#8 PrivateKeyInfo (DER, RFC 8410: the
45/// 32-byte seed in a CurvePrivateKey). Returns only the signing key; the
46/// public half is imported separately (there is no derive from a private
47/// import — see the WIT `ed25519-sign` interface doc).
48pub async fn import_signing_key_pkcs8(
49    pkcs8: impl Into<Vec<u8>>,
50    options: SigningKeyOptions,
51) -> Result<SigningKey, Error> {
52    Ok(SigningKey::from_raw(
53        bindings::ed25519_sign::import_signing_key_pkcs8(pkcs8.into(), options.lower()).await?,
54    ))
55}
56
57/// Import a signing key as an RFC 8037 OKP private JWK (`kty: "OKP"`,
58/// `crv: "Ed25519"`, with `x` and `d` both required; as JSON text). An
59/// `alg` member, when present, must be `"Ed25519"` or `"EdDSA"`.
60///
61/// Security: implementations MAY reject a JWK whose `x` is not the
62/// public key of `d`, and never trust `x` for any operation.
63pub async fn import_signing_key_jwk(
64    jwk: impl Into<String>,
65    options: SigningKeyOptions,
66) -> Result<SigningKey, Error> {
67    Ok(SigningKey::from_raw(
68        bindings::ed25519_sign::import_signing_key_jwk(jwk.into(), options.lower()).await?,
69    ))
70}
71
72/// Mint a signing key from unwrapped key material read as a PKCS#8
73/// PrivateKeyInfo, subject to [`import_signing_key_pkcs8`]'s contract.
74/// Consumes the [`UnwrapInput`]; the minted key's usages and
75/// extractability come from `options` alone.
76pub async fn unwrap_signing_key_pkcs8(
77    input: UnwrapInput,
78    options: SigningKeyOptions,
79) -> Result<SigningKey, Error> {
80    Ok(SigningKey::from_raw(
81        bindings::ed25519_sign::unwrap_signing_key_pkcs8(input.into_raw(), options.lower()).await?,
82    ))
83}
84
85/// Mint a signing key from unwrapped key material read as an OKP private
86/// JWK, subject to [`import_signing_key_jwk`]'s contract plus the
87/// unwrap-path `use`/`key_ops` checks (see the WIT `README.md`, "JWK
88/// contract"). Consumes the [`UnwrapInput`]; see
89/// [`unwrap_signing_key_pkcs8`] for the options model.
90pub async fn unwrap_signing_key_jwk(
91    input: UnwrapInput,
92    options: SigningKeyOptions,
93) -> Result<SigningKey, Error> {
94    Ok(SigningKey::from_raw(
95        bindings::ed25519_sign::unwrap_signing_key_jwk(input.into_raw(), options.lower()).await?,
96    ))
97}