ssi_jwk/
bbs.rs

1use ssi_bbs::{BBSplusPublicKey, BBSplusSecretKey};
2
3use crate::{Base64urlUInt, ECParams, Error, Params, JWK};
4
5impl JWK {
6    pub fn generate_bls12381g2_with(rng: &mut (impl rand::CryptoRng + rand::RngCore)) -> Self {
7        ssi_bbs::generate_secret_key(rng).into()
8    }
9
10    pub fn generate_bls12381g2() -> Self {
11        let mut rng = rand::rngs::OsRng {};
12        Self::generate_bls12381g2_with(&mut rng)
13    }
14}
15
16pub fn bls12381g2_parse(bytes: &[u8]) -> Result<JWK, ssi_bbs::Error> {
17    Ok(BBSplusPublicKey::from_bytes(bytes)?.into())
18}
19
20impl<'a> TryFrom<&'a JWK> for BBSplusPublicKey {
21    type Error = Error;
22
23    fn try_from(value: &'a JWK) -> Result<Self, Self::Error> {
24        (&value.params).try_into()
25    }
26}
27
28impl TryFrom<JWK> for BBSplusPublicKey {
29    type Error = Error;
30
31    fn try_from(value: JWK) -> Result<Self, Self::Error> {
32        value.params.try_into()
33    }
34}
35
36impl<'a> From<&'a BBSplusPublicKey> for ECParams {
37    fn from(value: &'a BBSplusPublicKey) -> Self {
38        let (x, y) = value.to_coordinates();
39        Self {
40            curve: Some("BLS12381G2".to_owned()),
41            x_coordinate: Some(Base64urlUInt(x.to_vec())),
42            y_coordinate: Some(Base64urlUInt(y.to_vec())),
43            ecc_private_key: None,
44        }
45    }
46}
47
48impl From<BBSplusPublicKey> for ECParams {
49    fn from(value: BBSplusPublicKey) -> Self {
50        (&value).into()
51    }
52}
53
54impl<'a> From<&'a BBSplusPublicKey> for Params {
55    fn from(value: &'a BBSplusPublicKey) -> Self {
56        Self::EC(value.into())
57    }
58}
59
60impl From<BBSplusPublicKey> for Params {
61    fn from(value: BBSplusPublicKey) -> Self {
62        Self::EC(value.into())
63    }
64}
65
66impl<'a> From<&'a BBSplusPublicKey> for JWK {
67    fn from(value: &'a BBSplusPublicKey) -> Self {
68        Params::from(value).into()
69    }
70}
71
72impl From<BBSplusPublicKey> for JWK {
73    fn from(value: BBSplusPublicKey) -> Self {
74        Params::from(value).into()
75    }
76}
77
78impl<'a> TryFrom<&'a Params> for BBSplusPublicKey {
79    type Error = Error;
80
81    fn try_from(value: &'a Params) -> Result<Self, Self::Error> {
82        match value {
83            Params::EC(params) => match params.curve.as_deref() {
84                Some("BLS12381G2") => {
85                    let x: &[u8; 96] = params
86                        .x_coordinate
87                        .as_ref()
88                        .ok_or(Error::MissingPoint)?
89                        .0
90                        .as_slice()
91                        .try_into()
92                        .map_err(|_| Error::InvalidCoordinates)?;
93                    let y: &[u8; 96] = params
94                        .y_coordinate
95                        .as_ref()
96                        .ok_or(Error::MissingPoint)?
97                        .0
98                        .as_slice()
99                        .try_into()
100                        .map_err(|_| Error::InvalidCoordinates)?;
101
102                    BBSplusPublicKey::from_coordinates(x, y).map_err(|_| Error::InvalidCoordinates)
103                }
104                Some(other) => Err(Error::CurveNotImplemented(other.to_owned())),
105                None => Err(Error::MissingCurve),
106            },
107            _ => Err(Error::UnsupportedKeyType),
108        }
109    }
110}
111
112impl TryFrom<Params> for BBSplusPublicKey {
113    type Error = Error;
114
115    fn try_from(value: Params) -> Result<Self, Self::Error> {
116        (&value).try_into()
117    }
118}
119
120impl<'a> TryFrom<&'a JWK> for BBSplusSecretKey {
121    type Error = Error;
122
123    fn try_from(value: &'a JWK) -> Result<Self, Self::Error> {
124        (&value.params).try_into()
125    }
126}
127
128impl TryFrom<JWK> for BBSplusSecretKey {
129    type Error = Error;
130
131    fn try_from(value: JWK) -> Result<Self, Self::Error> {
132        value.params.try_into()
133    }
134}
135
136impl<'a> TryFrom<&'a Params> for BBSplusSecretKey {
137    type Error = Error;
138
139    fn try_from(value: &'a Params) -> Result<Self, Self::Error> {
140        match value {
141            Params::EC(params) => match params.curve.as_deref() {
142                Some("BLS12381G2") => {
143                    let p = params
144                        .ecc_private_key
145                        .as_ref()
146                        .ok_or(Error::MissingPrivateKey)?
147                        .0
148                        .as_slice();
149
150                    BBSplusSecretKey::from_bytes(p).map_err(|_| Error::InvalidCoordinates)
151                }
152                Some(other) => Err(Error::CurveNotImplemented(other.to_owned())),
153                None => Err(Error::MissingCurve),
154            },
155            _ => Err(Error::UnsupportedKeyType),
156        }
157    }
158}
159
160impl TryFrom<Params> for BBSplusSecretKey {
161    type Error = Error;
162
163    fn try_from(value: Params) -> Result<Self, Self::Error> {
164        (&value).try_into()
165    }
166}
167
168impl<'a> From<&'a BBSplusSecretKey> for ECParams {
169    fn from(value: &'a BBSplusSecretKey) -> Self {
170        let pk = value.public_key();
171        let mut params: ECParams = pk.into();
172        params.ecc_private_key = Some(Base64urlUInt(value.to_bytes().to_vec()));
173        params
174    }
175}
176
177impl From<BBSplusSecretKey> for ECParams {
178    fn from(value: BBSplusSecretKey) -> Self {
179        (&value).into()
180    }
181}
182
183impl<'a> From<&'a BBSplusSecretKey> for Params {
184    fn from(value: &'a BBSplusSecretKey) -> Self {
185        Self::EC(value.into())
186    }
187}
188
189impl From<BBSplusSecretKey> for Params {
190    fn from(value: BBSplusSecretKey) -> Self {
191        Self::EC(value.into())
192    }
193}
194
195impl<'a> From<&'a BBSplusSecretKey> for JWK {
196    fn from(value: &'a BBSplusSecretKey) -> Self {
197        Params::from(value).into()
198    }
199}
200
201impl From<BBSplusSecretKey> for JWK {
202    fn from(value: BBSplusSecretKey) -> Self {
203        Params::from(value).into()
204    }
205}