identity_jose/jwk/conversion/
to_jwk.rs

1// Copyright 2020-2025 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use std::convert::Infallible;
5
6use crate::error::Error;
7use crate::jwk::Jwk;
8use fastcrypto::ed25519::Ed25519KeyPair;
9use fastcrypto::traits::KeyPair;
10use iota_interaction::types::crypto::PublicKey;
11
12use super::ed25519;
13use super::secp256k1;
14use super::secp256r1;
15
16/// Helper trait to convert an arbitrary key type to `Jwk`.
17pub trait ToJwk {
18  /// Error type used
19  type Error;
20
21  /// Converts instance to `Jwk`.
22  fn to_jwk(&self) -> Result<Jwk, Self::Error>;
23}
24
25impl ToJwk for PublicKey {
26  type Error = Error;
27
28  fn to_jwk(&self) -> Result<Jwk, Self::Error> {
29    let jwk = match self {
30      PublicKey::Ed25519(pk) => ed25519::pk_to_jwk(pk),
31      PublicKey::Secp256r1(pk) => secp256r1::pk_to_jwk(pk),
32      PublicKey::Secp256k1(pk) => secp256k1::pk_to_jwk(pk),
33      _ => return Err(Error::KeyConversion("unsupported key type".to_string())),
34    };
35
36    Ok(jwk)
37  }
38}
39
40impl ToJwk for Ed25519KeyPair {
41  type Error = Infallible;
42
43  fn to_jwk(&self) -> Result<Jwk, Self::Error> {
44    Ok(ed25519::encode_jwk(self.copy()))
45  }
46}
47
48#[cfg(test)]
49mod tests {
50  use super::ToJwk;
51
52  use fastcrypto::traits::KeyPair as _;
53
54  mod iota_public_key {
55    use super::*;
56
57    use iota_interaction::types::crypto::IotaKeyPair;
58
59    #[test]
60    fn can_convert_from_ed25519_public_key_to_jwk() {
61      let public_key =
62        IotaKeyPair::Ed25519(fastcrypto::ed25519::Ed25519KeyPair::generate(&mut rand::thread_rng())).public();
63      let result = public_key.to_jwk();
64
65      assert!(result.is_ok());
66    }
67
68    #[test]
69    fn can_convert_from_secp256r1_public_key_to_jwk() {
70      let public_key = IotaKeyPair::Secp256r1(fastcrypto::secp256r1::Secp256r1KeyPair::generate(
71        &mut rand::thread_rng(),
72      ))
73      .public();
74      let result = public_key.to_jwk();
75
76      assert!(result.is_ok());
77    }
78
79    #[test]
80    fn can_convert_from_secp256k1_public_key_to_jwk() {
81      let public_key = IotaKeyPair::Secp256k1(fastcrypto::secp256k1::Secp256k1KeyPair::generate(
82        &mut rand::thread_rng(),
83      ))
84      .public();
85      let result = public_key.to_jwk();
86
87      assert!(result.is_ok());
88    }
89  }
90
91  #[test]
92  fn can_convert_from_ed25519_keypair_to_jwk() {
93    let keypair = fastcrypto::ed25519::Ed25519KeyPair::generate(&mut rand::thread_rng());
94    let result = keypair.to_jwk();
95
96    assert!(result.is_ok());
97  }
98}