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}