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}