@nuggetslife/vc 0.0.9 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.toml +5 -2
- package/index.d.ts +303 -3
- package/index.js +15 -1
- package/package.json +16 -8
- package/prepublish.sh +7 -0
- package/src/bls_signatures/bbs_bls_holder_bound_signature_2022/mod.rs +268 -0
- package/src/bls_signatures/bbs_bls_holder_bound_signature_2022/types.rs +26 -0
- package/src/bls_signatures/bbs_bls_holder_bound_signature_proof_2022/mod.rs +100 -0
- package/src/bls_signatures/bbs_bls_holder_bound_signature_proof_2022/types.rs +17 -0
- package/src/bls_signatures/bbs_bls_signature_2020/mod.rs +329 -0
- package/src/bls_signatures/bbs_bls_signature_2020/types.rs +37 -0
- package/src/bls_signatures/bbs_bls_signature_proof_2020/mod.rs +92 -0
- package/src/bls_signatures/bbs_bls_signature_proof_2020/types.rs +13 -0
- package/src/bls_signatures/bls_12381_g2_keypair/mod.rs +470 -0
- package/src/{types.rs → bls_signatures/bls_12381_g2_keypair/types.rs} +0 -11
- package/src/{validators.rs → bls_signatures/bls_12381_g2_keypair/validators.rs} +1 -1
- package/src/bls_signatures/bound_bls_12381_g2_keypair/mod.rs +70 -0
- package/src/bls_signatures/bound_bls_12381_g2_keypair/types.rs +11 -0
- package/src/bls_signatures/mod.rs +6 -0
- package/src/jsonld.rs +200 -0
- package/src/ld_signatures.rs +311 -0
- package/src/lib.rs +3 -463
- package/test-data/bbs.json +92 -0
- package/test-data/citizenVocab.json +57 -0
- package/test-data/controllerDocument.json +5 -0
- package/test-data/credentialsContext.json +315 -0
- package/test-data/deriveProofFrame.json +15 -0
- package/test-data/inputDocument.json +29 -0
- package/test-data/keyPair.json +6 -0
- package/test-data/suiteContext.json +82 -0
- package/test.mjs +1088 -22
- package/test_jsonld_crossverify.mjs +256 -0
package/src/lib.rs
CHANGED
|
@@ -3,466 +3,6 @@
|
|
|
3
3
|
#[macro_use]
|
|
4
4
|
extern crate napi_derive;
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
use napi::bindgen_prelude::*;
|
|
10
|
-
use types::{
|
|
11
|
-
Bls12381G2KeyPair, BlsCurveName, FingerPrintFromPublicKeyOptions, GenerateKeyPairOptions,
|
|
12
|
-
JsonWebKey, JwkKeyPairOptions, JwkKty, KeyPairFromFingerPrintOptions, KeyPairOptions,
|
|
13
|
-
};
|
|
14
|
-
use validators::{assert_bls_12381_g2_private_jwk, assert_bls_12381_g2_public_jwk};
|
|
15
|
-
use vc::bbs_signatures::bls12381::{
|
|
16
|
-
bls_generate_g2_key, bls_sign, bls_verify, BlsBbsSignRequest, BlsBbsVerifyRequest, BlsKeyPair,
|
|
17
|
-
BLS12381G2_MULTICODEC_IDENTIFIER, DEFAULT_BLS12381_G2_PUBLIC_KEY_LENGTH,
|
|
18
|
-
MULTIBASE_ENCODED_BASE58_IDENTIFIER, VARIABLE_INTEGER_TRAILING_BYTE,
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
pub mod types;
|
|
22
|
-
pub mod validators;
|
|
23
|
-
|
|
24
|
-
#[napi]
|
|
25
|
-
impl Bls12381G2KeyPair {
|
|
26
|
-
#[napi(constructor)]
|
|
27
|
-
pub async fn new(options: Option<KeyPairOptions>) -> Self {
|
|
28
|
-
match options {
|
|
29
|
-
Some(o) => {
|
|
30
|
-
// The provided publicKey needs to be 384 bits / 5.85 = 65.6
|
|
31
|
-
// which means the base58 encoded publicKey can be either 65 or 66 chars
|
|
32
|
-
// 5.85 = log base 2 (58) which is equivalent to the number of bits
|
|
33
|
-
// encoded per character of a base58 encoded string.
|
|
34
|
-
// if let Some(ref pubkey_bs58) = o.public_key_base58 {
|
|
35
|
-
// if pubkey_bs58.len() != 131 && pubkey_bs58.len() != 132 {
|
|
36
|
-
// panic!(
|
|
37
|
-
// "public_key_base58 invalid length. expected 131 or 132. got {}",
|
|
38
|
-
// pubkey_bs58.len()
|
|
39
|
-
// )
|
|
40
|
-
// }
|
|
41
|
-
// };
|
|
42
|
-
|
|
43
|
-
// Validates the size of the private key if one is included
|
|
44
|
-
// This is done by 256 bits / 5.85 = 43.7 which means
|
|
45
|
-
// the base58 encoded privateKey can be either 43 or 44 chars
|
|
46
|
-
// if let Some(ref privkey_bs58) = o.private_key_base58 {
|
|
47
|
-
// if privkey_bs58.len() != 43 && privkey_bs58.len() != 44 {
|
|
48
|
-
// panic!(
|
|
49
|
-
// "private_key_base58 invalid length. expected 43 or 44. got {}",
|
|
50
|
-
// privkey_bs58.len()
|
|
51
|
-
// )
|
|
52
|
-
// }
|
|
53
|
-
// };
|
|
54
|
-
|
|
55
|
-
let private_key_inner = o
|
|
56
|
-
.private_key_base58
|
|
57
|
-
.map(|v| bs58::decode(v).into_vec().unwrap());
|
|
58
|
-
let public_key_inner = o
|
|
59
|
-
.public_key_base58
|
|
60
|
-
.map(|v| bs58::decode(v).into_vec().unwrap());
|
|
61
|
-
|
|
62
|
-
Self {
|
|
63
|
-
id: o.id,
|
|
64
|
-
controller: o.controller,
|
|
65
|
-
private_key_inner,
|
|
66
|
-
public_key_inner,
|
|
67
|
-
type_: String::from("Bls12381G2Key2020"),
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
None => Self {
|
|
71
|
-
id: None,
|
|
72
|
-
controller: None,
|
|
73
|
-
private_key_inner: None,
|
|
74
|
-
public_key_inner: None,
|
|
75
|
-
type_: String::from("Bls12381G2Key2020"),
|
|
76
|
-
},
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
#[napi(factory)]
|
|
81
|
-
pub async fn generate(options: Option<GenerateKeyPairOptions>) -> Self {
|
|
82
|
-
match options {
|
|
83
|
-
Some(o) => {
|
|
84
|
-
let seed: Option<Vec<u8>> = o.seed.map(|s| s.into());
|
|
85
|
-
let kp = bls_generate_g2_key(seed).await;
|
|
86
|
-
let public_key_base58 = kp.public_key.map(|v| bs58::encode(v).into_string());
|
|
87
|
-
let private_key_base58 = kp.secret_key.map(|v| bs58::encode(v).into_string());
|
|
88
|
-
|
|
89
|
-
Self::new(Some(KeyPairOptions {
|
|
90
|
-
id: o.id,
|
|
91
|
-
controller: o.controller,
|
|
92
|
-
private_key_base58,
|
|
93
|
-
public_key_base58,
|
|
94
|
-
}))
|
|
95
|
-
.await
|
|
96
|
-
}
|
|
97
|
-
None => {
|
|
98
|
-
let kp = bls_generate_g2_key(None).await;
|
|
99
|
-
let public_key_base58 = kp.public_key.map(|v| bs58::encode(v).into_string());
|
|
100
|
-
let private_key_base58 = kp.secret_key.map(|v| bs58::encode(v).into_string());
|
|
101
|
-
|
|
102
|
-
Self::new(Some(KeyPairOptions {
|
|
103
|
-
id: None,
|
|
104
|
-
controller: None,
|
|
105
|
-
private_key_base58,
|
|
106
|
-
public_key_base58,
|
|
107
|
-
}))
|
|
108
|
-
.await
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
#[napi(factory)]
|
|
114
|
-
pub async fn from(options: KeyPairOptions) -> Self {
|
|
115
|
-
Bls12381G2KeyPair::new(Some(options)).await
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
#[napi(factory)]
|
|
119
|
-
pub async fn from_jwk(options: JwkKeyPairOptions) -> Result<Bls12381G2KeyPair> {
|
|
120
|
-
let JwkKeyPairOptions {
|
|
121
|
-
id,
|
|
122
|
-
controller,
|
|
123
|
-
private_key_jwk,
|
|
124
|
-
public_key_jwk,
|
|
125
|
-
} = options;
|
|
126
|
-
|
|
127
|
-
if let Some(jwk) = private_key_jwk {
|
|
128
|
-
assert_bls_12381_g2_private_jwk(&jwk)?;
|
|
129
|
-
let public_key_base58 = Some(convert_base64_url_to_base58(jwk.x)?);
|
|
130
|
-
let d = jwk
|
|
131
|
-
.d
|
|
132
|
-
.ok_or(napi::Error::from_reason("jwk.d value is none"))?;
|
|
133
|
-
let private_key_base58 = Some(convert_base64_url_to_base58(d)?);
|
|
134
|
-
|
|
135
|
-
let kp = Bls12381G2KeyPair::new(Some(KeyPairOptions {
|
|
136
|
-
id,
|
|
137
|
-
controller,
|
|
138
|
-
public_key_base58,
|
|
139
|
-
private_key_base58,
|
|
140
|
-
}))
|
|
141
|
-
.await;
|
|
142
|
-
|
|
143
|
-
Ok(kp)
|
|
144
|
-
} else if let Some(jwk) = public_key_jwk {
|
|
145
|
-
assert_bls_12381_g2_public_jwk(&jwk)?;
|
|
146
|
-
let public_key_base58 = Some(convert_base64_url_to_base58(jwk.x)?);
|
|
147
|
-
let kp = Bls12381G2KeyPair::new(Some(KeyPairOptions {
|
|
148
|
-
id,
|
|
149
|
-
controller,
|
|
150
|
-
public_key_base58,
|
|
151
|
-
private_key_base58: None,
|
|
152
|
-
}))
|
|
153
|
-
.await;
|
|
154
|
-
|
|
155
|
-
Ok(kp)
|
|
156
|
-
} else {
|
|
157
|
-
Err(napi::Error::from_reason("The JWK provided is not a valid"))
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
#[napi(factory)]
|
|
162
|
-
pub async fn from_fingerprint(
|
|
163
|
-
options: KeyPairFromFingerPrintOptions,
|
|
164
|
-
) -> Result<Bls12381G2KeyPair> {
|
|
165
|
-
let KeyPairFromFingerPrintOptions {
|
|
166
|
-
id,
|
|
167
|
-
controller,
|
|
168
|
-
fingerprint,
|
|
169
|
-
} = options;
|
|
170
|
-
let mut chars = fingerprint.chars();
|
|
171
|
-
let head = chars
|
|
172
|
-
.next()
|
|
173
|
-
.ok_or(napi::Error::from_reason("fingerprint string is empty"))?
|
|
174
|
-
.to_string();
|
|
175
|
-
|
|
176
|
-
if head != MULTIBASE_ENCODED_BASE58_IDENTIFIER {
|
|
177
|
-
return Err(napi::Error::from_reason(
|
|
178
|
-
format!("Unsupported fingerprint type: expected first character to be `z` indicating base58 encoding, received {head}")
|
|
179
|
-
));
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
let rest = chars.collect::<String>();
|
|
183
|
-
let buffer = bs58::decode(rest).into_vec().map_err(|err| {
|
|
184
|
-
napi::Error::from_reason(format!(
|
|
185
|
-
"failed to decode bs58 fingerprint to bytes. error: {err}"
|
|
186
|
-
))
|
|
187
|
-
})?;
|
|
188
|
-
|
|
189
|
-
if buffer.len() != BLS12381G2_MULTICODEC_IDENTIFIER as usize {
|
|
190
|
-
return Err(napi::Error::from_reason(
|
|
191
|
-
format!("Unsupported public key length: expected `${DEFAULT_BLS12381_G2_PUBLIC_KEY_LENGTH}` received {}", buffer.len())
|
|
192
|
-
));
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
if buffer[0] != DEFAULT_BLS12381_G2_PUBLIC_KEY_LENGTH {
|
|
196
|
-
return Err(napi::Error::from_reason(
|
|
197
|
-
format!("Unsupported public key identifier: expected second character to be {BLS12381G2_MULTICODEC_IDENTIFIER} indicating BLS12381G2 key pair, received {}", buffer[0])
|
|
198
|
-
));
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
if buffer[1] != VARIABLE_INTEGER_TRAILING_BYTE {
|
|
202
|
-
return Err(napi::Error::from_reason(
|
|
203
|
-
format!("Missing variable integer trailing byte: expected third character to be {BLS12381G2_MULTICODEC_IDENTIFIER} indicating BLS12381G2 key pair, received {}", buffer[1])
|
|
204
|
-
));
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
let pubkey_base58 = bs58::encode(buffer).into_string();
|
|
208
|
-
let opts = FingerPrintFromPublicKeyOptions {
|
|
209
|
-
public_key_base58: pubkey_base58.clone(),
|
|
210
|
-
};
|
|
211
|
-
let fingerprint = Bls12381G2KeyPair::fingerprint_from_public_key(opts).map_err(|err| {
|
|
212
|
-
napi::Error::from_reason(format!("fingerprint_from_public_key failed. error: {err}"))
|
|
213
|
-
})?;
|
|
214
|
-
let mapped_controller = match controller {
|
|
215
|
-
Some(v) => v,
|
|
216
|
-
None => {
|
|
217
|
-
format!("did:key:{fingerprint}",)
|
|
218
|
-
}
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
let mapped_id = match id {
|
|
222
|
-
Some(v) => v,
|
|
223
|
-
None => {
|
|
224
|
-
format!("#{fingerprint}",)
|
|
225
|
-
}
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
let kp = Bls12381G2KeyPair::new(Some(KeyPairOptions {
|
|
229
|
-
id: Some(mapped_id),
|
|
230
|
-
controller: Some(mapped_controller),
|
|
231
|
-
public_key_base58: Some(pubkey_base58),
|
|
232
|
-
private_key_base58: None,
|
|
233
|
-
}))
|
|
234
|
-
.await;
|
|
235
|
-
|
|
236
|
-
Ok(kp)
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
#[napi(getter)]
|
|
240
|
-
pub fn public_key(&self) -> Option<String> {
|
|
241
|
-
self
|
|
242
|
-
.public_key_inner
|
|
243
|
-
.clone()
|
|
244
|
-
.map(|b| bs58::encode(b).into_string())
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
#[napi(getter)]
|
|
248
|
-
pub fn public_key_buffer(&self) -> Buffer {
|
|
249
|
-
self.public_key_inner.clone().unwrap().into()
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
#[napi(getter)]
|
|
253
|
-
pub fn private_key_buffer(&self) -> Buffer {
|
|
254
|
-
self.private_key_inner.clone().unwrap().into()
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
#[napi]
|
|
258
|
-
pub fn public_key_jwk(&self) -> Result<JsonWebKey> {
|
|
259
|
-
let Some(ref public_key_inner) = self.public_key_inner else {
|
|
260
|
-
return Err(napi::Error::from_reason("no public_key_inner"));
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
Ok(JsonWebKey {
|
|
264
|
-
kid: self.id.to_owned(),
|
|
265
|
-
kty: JwkKty::EC.into(),
|
|
266
|
-
crv: BlsCurveName::G2.into(),
|
|
267
|
-
x: URL_SAFE_NO_PAD.encode(public_key_inner),
|
|
268
|
-
use_: None,
|
|
269
|
-
key_ops: None,
|
|
270
|
-
alg: None,
|
|
271
|
-
d: None,
|
|
272
|
-
y: None,
|
|
273
|
-
ext: None,
|
|
274
|
-
})
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
#[napi(getter)]
|
|
278
|
-
pub fn private_key(&self) -> Option<String> {
|
|
279
|
-
self
|
|
280
|
-
.private_key_inner
|
|
281
|
-
.clone()
|
|
282
|
-
.map(|b| bs58::encode(b).into_string())
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
#[napi]
|
|
286
|
-
pub fn private_key_jwk(&self) -> Result<JsonWebKey> {
|
|
287
|
-
let Some(ref public_key_inner) = self.public_key_inner else {
|
|
288
|
-
return Err(napi::Error::from_reason("no public_key_inner"));
|
|
289
|
-
};
|
|
290
|
-
|
|
291
|
-
let Some(ref private_key_inner) = self.private_key_inner else {
|
|
292
|
-
return Err(napi::Error::from_reason("no private_key_inner"));
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
Ok(JsonWebKey {
|
|
296
|
-
kid: self.id.to_owned(),
|
|
297
|
-
kty: JwkKty::EC.into(),
|
|
298
|
-
crv: BlsCurveName::G2.into(),
|
|
299
|
-
x: URL_SAFE_NO_PAD.encode(public_key_inner),
|
|
300
|
-
d: Some(URL_SAFE_NO_PAD.encode(private_key_inner)),
|
|
301
|
-
use_: None,
|
|
302
|
-
key_ops: None,
|
|
303
|
-
alg: None,
|
|
304
|
-
y: None,
|
|
305
|
-
ext: None,
|
|
306
|
-
})
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
#[napi]
|
|
310
|
-
pub fn signer(&self) -> KeyPairSigner {
|
|
311
|
-
KeyPairSigner { key: self.clone() }
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
#[napi]
|
|
315
|
-
pub fn verifier(&self) -> KeyPairVerifier {
|
|
316
|
-
KeyPairVerifier { key: self.clone() }
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
#[napi]
|
|
320
|
-
pub fn fingerprint(&self) -> Result<String> {
|
|
321
|
-
let Some(public_key_base58) = self.public_key() else {
|
|
322
|
-
return Err(napi::Error::from_reason("no public key"));
|
|
323
|
-
};
|
|
324
|
-
Bls12381G2KeyPair::fingerprint_from_public_key(FingerPrintFromPublicKeyOptions {
|
|
325
|
-
public_key_base58,
|
|
326
|
-
})
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
#[napi]
|
|
330
|
-
pub fn fingerprint_from_public_key(options: FingerPrintFromPublicKeyOptions) -> Result<String> {
|
|
331
|
-
let FingerPrintFromPublicKeyOptions { public_key_base58 } = options;
|
|
332
|
-
let mut key_bytes = bs58::decode(public_key_base58).into_vec().map_err(|err| {
|
|
333
|
-
napi::Error::from_reason(format!(
|
|
334
|
-
"failed to decode public_key_base58 value. error: {err}"
|
|
335
|
-
))
|
|
336
|
-
})?;
|
|
337
|
-
|
|
338
|
-
let mut buffer = vec![
|
|
339
|
-
BLS12381G2_MULTICODEC_IDENTIFIER,
|
|
340
|
-
VARIABLE_INTEGER_TRAILING_BYTE,
|
|
341
|
-
];
|
|
342
|
-
buffer.append(&mut key_bytes);
|
|
343
|
-
|
|
344
|
-
Ok(format!(
|
|
345
|
-
"{}{}",
|
|
346
|
-
MULTIBASE_ENCODED_BASE58_IDENTIFIER,
|
|
347
|
-
bs58::encode(buffer).into_string()
|
|
348
|
-
))
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
#[napi]
|
|
352
|
-
pub fn verify_fingerprint(&self, fingerprint: String) -> Result<()> {
|
|
353
|
-
// fingerprint should have `z` prefix indicating
|
|
354
|
-
// that it's multi-base encoded
|
|
355
|
-
let mut chars = fingerprint.chars();
|
|
356
|
-
let head = chars
|
|
357
|
-
.next()
|
|
358
|
-
.ok_or(napi::Error::from_reason("fingerprint string is empty"))?
|
|
359
|
-
.to_string();
|
|
360
|
-
|
|
361
|
-
let rest = chars.collect::<String>();
|
|
362
|
-
|
|
363
|
-
if head != MULTIBASE_ENCODED_BASE58_IDENTIFIER {
|
|
364
|
-
return Err(napi::Error::from_reason(
|
|
365
|
-
"`fingerprint` must be a multibase encoded string.",
|
|
366
|
-
));
|
|
367
|
-
};
|
|
368
|
-
|
|
369
|
-
let fingerprint_buffer = bs58::decode(rest).into_vec().map_err(|err| {
|
|
370
|
-
napi::Error::from_reason(format!("failed to decode bs58 value: error: {err}"))
|
|
371
|
-
})?;
|
|
372
|
-
|
|
373
|
-
let public_key_inner = self
|
|
374
|
-
.public_key_inner
|
|
375
|
-
.clone()
|
|
376
|
-
.ok_or(napi::Error::from_reason("public key buffer is missing"))?;
|
|
377
|
-
|
|
378
|
-
let leader = hex::encode(&fingerprint_buffer[..2]);
|
|
379
|
-
let leader_match = if leader == "eb01" { true } else { false };
|
|
380
|
-
let bytes_match = if &public_key_inner == &fingerprint_buffer[2..] {
|
|
381
|
-
true
|
|
382
|
-
} else {
|
|
383
|
-
false
|
|
384
|
-
};
|
|
385
|
-
|
|
386
|
-
if leader_match && bytes_match {
|
|
387
|
-
Ok(())
|
|
388
|
-
} else {
|
|
389
|
-
Err(napi::Error::from_reason(
|
|
390
|
-
"The fingerprint does not match the public key",
|
|
391
|
-
))
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
pub fn convert_base64_url_to_base58(value: String) -> Result<String> {
|
|
397
|
-
let decoded = URL_SAFE.decode(value).map_err(|err| {
|
|
398
|
-
napi::Error::from_reason(format!("failed to decode base64 url_safe. error {err}"))
|
|
399
|
-
})?;
|
|
400
|
-
Ok(bs58::encode(decoded).into_string())
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
#[napi]
|
|
404
|
-
pub struct KeyPairSigner {
|
|
405
|
-
key: Bls12381G2KeyPair,
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
#[napi(object)]
|
|
409
|
-
pub struct KeyPairSignerOptions {
|
|
410
|
-
pub data: Vec<Uint8Array>,
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
#[napi]
|
|
414
|
-
impl KeyPairSigner {
|
|
415
|
-
#[napi]
|
|
416
|
-
pub async fn sign(&self, options: KeyPairSignerOptions) -> Result<Uint8Array> {
|
|
417
|
-
if self.key.private_key_inner.is_none() {
|
|
418
|
-
return Err(napi::Error::from_reason("No private key to sign with."));
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
let messages: Vec<Vec<u8>> = options.data.into_iter().map(|x| x.to_vec()).collect();
|
|
422
|
-
let key_pair = BlsKeyPair {
|
|
423
|
-
public_key: self.key.public_key_inner.clone(),
|
|
424
|
-
secret_key: self.key.private_key_inner.clone(),
|
|
425
|
-
};
|
|
426
|
-
let sig = bls_sign(BlsBbsSignRequest { messages, key_pair })
|
|
427
|
-
.await
|
|
428
|
-
.map_err(|err| napi::Error::from_reason(format!("bls_signed failed: {err}")))?;
|
|
429
|
-
|
|
430
|
-
Ok(Uint8Array::from(sig))
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
#[napi]
|
|
435
|
-
pub struct KeyPairVerifier {
|
|
436
|
-
key: Bls12381G2KeyPair,
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
#[napi(object)]
|
|
440
|
-
pub struct KeyPairVerifierOptions {
|
|
441
|
-
pub data: Vec<Uint8Array>,
|
|
442
|
-
pub signature: Uint8Array,
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
#[napi]
|
|
446
|
-
impl KeyPairVerifier {
|
|
447
|
-
#[napi]
|
|
448
|
-
pub async fn verify(&self, options: KeyPairVerifierOptions) -> Result<bool> {
|
|
449
|
-
let KeyPairVerifierOptions { data, signature } = options;
|
|
450
|
-
let Some(public_key) = self.key.public_key_inner.clone() else {
|
|
451
|
-
return Err(napi::Error::from_reason(
|
|
452
|
-
"key.public_key is required for verify",
|
|
453
|
-
));
|
|
454
|
-
};
|
|
455
|
-
let signature = signature.to_vec();
|
|
456
|
-
let messages = data.into_iter().map(|a| a.to_vec()).collect::<Vec<_>>();
|
|
457
|
-
|
|
458
|
-
let verified = bls_verify(BlsBbsVerifyRequest {
|
|
459
|
-
public_key,
|
|
460
|
-
signature,
|
|
461
|
-
messages,
|
|
462
|
-
})
|
|
463
|
-
.await
|
|
464
|
-
.map_err(|err| napi::Error::from_reason(format!("bls_verify failed: {err}")))?;
|
|
465
|
-
|
|
466
|
-
Ok(verified)
|
|
467
|
-
}
|
|
468
|
-
}
|
|
6
|
+
pub mod bls_signatures;
|
|
7
|
+
pub mod jsonld;
|
|
8
|
+
pub mod ld_signatures;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
{
|
|
2
|
+
"@context": {
|
|
3
|
+
"@version": 1.1,
|
|
4
|
+
"id": "@id",
|
|
5
|
+
"type": "@type",
|
|
6
|
+
"BbsBlsSignature2020": {
|
|
7
|
+
"@id": "https://w3id.org/security#BbsBlsSignature2020",
|
|
8
|
+
"@context": {
|
|
9
|
+
"@version": 1.1,
|
|
10
|
+
"@protected": true,
|
|
11
|
+
"id": "@id",
|
|
12
|
+
"type": "@type",
|
|
13
|
+
"challenge": "https://w3id.org/security#challenge",
|
|
14
|
+
"created": {
|
|
15
|
+
"@id": "http://purl.org/dc/terms/created",
|
|
16
|
+
"@type": "http://www.w3.org/2001/XMLSchema#dateTime"
|
|
17
|
+
},
|
|
18
|
+
"domain": "https://w3id.org/security#domain",
|
|
19
|
+
"proofValue": "https://w3id.org/security#proofValue",
|
|
20
|
+
"nonce": "https://w3id.org/security#nonce",
|
|
21
|
+
"proofPurpose": {
|
|
22
|
+
"@id": "https://w3id.org/security#proofPurpose",
|
|
23
|
+
"@type": "@vocab",
|
|
24
|
+
"@context": {
|
|
25
|
+
"@version": 1.1,
|
|
26
|
+
"@protected": true,
|
|
27
|
+
"id": "@id",
|
|
28
|
+
"type": "@type",
|
|
29
|
+
"assertionMethod": {
|
|
30
|
+
"@id": "https://w3id.org/security#assertionMethod",
|
|
31
|
+
"@type": "@id",
|
|
32
|
+
"@container": "@set"
|
|
33
|
+
},
|
|
34
|
+
"authentication": {
|
|
35
|
+
"@id": "https://w3id.org/security#authenticationMethod",
|
|
36
|
+
"@type": "@id",
|
|
37
|
+
"@container": "@set"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"verificationMethod": {
|
|
42
|
+
"@id": "https://w3id.org/security#verificationMethod",
|
|
43
|
+
"@type": "@id"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"BbsBlsSignatureProof2020": {
|
|
48
|
+
"@id": "https://w3id.org/security#BbsBlsSignatureProof2020",
|
|
49
|
+
"@context": {
|
|
50
|
+
"@version": 1.1,
|
|
51
|
+
"@protected": true,
|
|
52
|
+
"id": "@id",
|
|
53
|
+
"type": "@type",
|
|
54
|
+
|
|
55
|
+
"challenge": "https://w3id.org/security#challenge",
|
|
56
|
+
"created": {
|
|
57
|
+
"@id": "http://purl.org/dc/terms/created",
|
|
58
|
+
"@type": "http://www.w3.org/2001/XMLSchema#dateTime"
|
|
59
|
+
},
|
|
60
|
+
"domain": "https://w3id.org/security#domain",
|
|
61
|
+
"nonce": "https://w3id.org/security#nonce",
|
|
62
|
+
"proofPurpose": {
|
|
63
|
+
"@id": "https://w3id.org/security#proofPurpose",
|
|
64
|
+
"@type": "@vocab",
|
|
65
|
+
"@context": {
|
|
66
|
+
"@version": 1.1,
|
|
67
|
+
"@protected": true,
|
|
68
|
+
"id": "@id",
|
|
69
|
+
"type": "@type",
|
|
70
|
+
"sec": "https://w3id.org/security#",
|
|
71
|
+
"assertionMethod": {
|
|
72
|
+
"@id": "https://w3id.org/security#assertionMethod",
|
|
73
|
+
"@type": "@id",
|
|
74
|
+
"@container": "@set"
|
|
75
|
+
},
|
|
76
|
+
"authentication": {
|
|
77
|
+
"@id": "https://w3id.org/security#authenticationMethod",
|
|
78
|
+
"@type": "@id",
|
|
79
|
+
"@container": "@set"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"proofValue": "https://w3id.org/security#proofValue",
|
|
84
|
+
"verificationMethod": {
|
|
85
|
+
"@id": "https://w3id.org/security#verificationMethod",
|
|
86
|
+
"@type": "@id"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"Bls12381G2Key2020": "https://w3id.org/security#Bls12381G2Key2020"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"@context": {
|
|
3
|
+
"@version": 1.1,
|
|
4
|
+
"@protected": true,
|
|
5
|
+
|
|
6
|
+
"name": "http://schema.org/name",
|
|
7
|
+
"description": "http://schema.org/description",
|
|
8
|
+
"identifier": "http://schema.org/identifier",
|
|
9
|
+
"image": { "@id": "http://schema.org/image", "@type": "@id" },
|
|
10
|
+
|
|
11
|
+
"PermanentResidentCard": {
|
|
12
|
+
"@id": "https://w3id.org/citizenship#PermanentResidentCard",
|
|
13
|
+
"@context": {
|
|
14
|
+
"@version": 1.1,
|
|
15
|
+
"@protected": true,
|
|
16
|
+
|
|
17
|
+
"id": "@id",
|
|
18
|
+
"type": "@type",
|
|
19
|
+
|
|
20
|
+
"description": "http://schema.org/description",
|
|
21
|
+
"name": "http://schema.org/name",
|
|
22
|
+
"identifier": "http://schema.org/identifier",
|
|
23
|
+
"image": { "@id": "http://schema.org/image", "@type": "@id" }
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
"PermanentResident": {
|
|
28
|
+
"@id": "https://w3id.org/citizenship#PermanentResident",
|
|
29
|
+
"@context": {
|
|
30
|
+
"@version": 1.1,
|
|
31
|
+
"@protected": true,
|
|
32
|
+
|
|
33
|
+
"id": "@id",
|
|
34
|
+
"type": "@type",
|
|
35
|
+
|
|
36
|
+
"ctzn": "https://w3id.org/citizenship#",
|
|
37
|
+
"schema": "http://schema.org/",
|
|
38
|
+
"xsd": "http://www.w3.org/2001/XMLSchema#",
|
|
39
|
+
|
|
40
|
+
"birthCountry": "ctzn:birthCountry",
|
|
41
|
+
"birthDate": { "@id": "schema:birthDate", "@type": "xsd:dateTime" },
|
|
42
|
+
"commuterClassification": "ctzn:commuterClassification",
|
|
43
|
+
"familyName": "schema:familyName",
|
|
44
|
+
"gender": "schema:gender",
|
|
45
|
+
"givenName": "schema:givenName",
|
|
46
|
+
"lprCategory": "ctzn:lprCategory",
|
|
47
|
+
"lprNumber": "ctzn:lprNumber",
|
|
48
|
+
"residentSince": {
|
|
49
|
+
"@id": "ctzn:residentSince",
|
|
50
|
+
"@type": "xsd:dateTime"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
"Person": "http://schema.org/Person"
|
|
56
|
+
}
|
|
57
|
+
}
|