@nuggetslife/vc 0.0.10 → 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 +11 -11
- 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/Cargo.toml
CHANGED
|
@@ -10,12 +10,15 @@ crate-type = ["cdylib"]
|
|
|
10
10
|
# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
|
|
11
11
|
base64 = "0.22.1"
|
|
12
12
|
bs58 = "0.5.1"
|
|
13
|
+
chrono = "0.4.38"
|
|
13
14
|
hex = "0.4.3"
|
|
15
|
+
lru = "0.14.0"
|
|
14
16
|
# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
|
|
15
|
-
napi = { version = "2.
|
|
16
|
-
napi-derive = "2.12
|
|
17
|
+
napi = { version = "2.16.10", default-features = false, features = ["full"] }
|
|
18
|
+
napi-derive = "2.16.12"
|
|
17
19
|
serde = { version = "1.0.203", features = ["derive"] }
|
|
18
20
|
serde_json = "1.0.117"
|
|
21
|
+
tokio = { version = "1.40.0", features = ["sync"] }
|
|
19
22
|
vc = {path = "../rs"}
|
|
20
23
|
|
|
21
24
|
[build-dependencies]
|
package/index.d.ts
CHANGED
|
@@ -3,6 +3,68 @@
|
|
|
3
3
|
|
|
4
4
|
/* auto-generated by NAPI-RS */
|
|
5
5
|
|
|
6
|
+
export interface BoundSignatureSuiteOptions {
|
|
7
|
+
key?: KeyPairOptions
|
|
8
|
+
verificationMethod?: string
|
|
9
|
+
date?: string
|
|
10
|
+
commitment?: Uint8Array
|
|
11
|
+
blinded?: Array<number>
|
|
12
|
+
}
|
|
13
|
+
export interface BoundCreateProofOptions {
|
|
14
|
+
document: any
|
|
15
|
+
contexts?: any
|
|
16
|
+
}
|
|
17
|
+
export interface BoundVerifyProofOptions {
|
|
18
|
+
document: any
|
|
19
|
+
blindingFactor: Uint8Array
|
|
20
|
+
blindedMessages: Array<Uint8Array>
|
|
21
|
+
contexts?: any
|
|
22
|
+
}
|
|
23
|
+
export interface BoundDeriveProofOptions {
|
|
24
|
+
document: any
|
|
25
|
+
revealDocument: any
|
|
26
|
+
blindingFactor: Uint8Array
|
|
27
|
+
blindedMessages: Array<Uint8Array>
|
|
28
|
+
contexts?: any
|
|
29
|
+
nonce?: string
|
|
30
|
+
}
|
|
31
|
+
export interface BoundVerifyDerivedProofOptions {
|
|
32
|
+
document: any
|
|
33
|
+
contexts?: any
|
|
34
|
+
}
|
|
35
|
+
export interface SignatureSuiteOptions {
|
|
36
|
+
key?: KeyPairOptions
|
|
37
|
+
verificationMethod?: string
|
|
38
|
+
date?: string
|
|
39
|
+
}
|
|
40
|
+
export interface CreateProofOptions {
|
|
41
|
+
document: any
|
|
42
|
+
contexts?: any
|
|
43
|
+
}
|
|
44
|
+
export interface VerifyProofOptions {
|
|
45
|
+
document: any
|
|
46
|
+
contexts?: any
|
|
47
|
+
}
|
|
48
|
+
export interface SuiteSignOptions {
|
|
49
|
+
document: any
|
|
50
|
+
proof: any
|
|
51
|
+
verifyData: Array<Uint8Array>
|
|
52
|
+
}
|
|
53
|
+
export interface VerifySignatureOptions {
|
|
54
|
+
document: any
|
|
55
|
+
proof: any
|
|
56
|
+
verifyData: Array<Uint8Array>
|
|
57
|
+
}
|
|
58
|
+
export interface DeriveProofOptions {
|
|
59
|
+
document: any
|
|
60
|
+
revealDocument: any
|
|
61
|
+
contexts?: any
|
|
62
|
+
nonce?: string
|
|
63
|
+
}
|
|
64
|
+
export interface VerifyDerivedProofOptions {
|
|
65
|
+
document: any
|
|
66
|
+
contexts?: any
|
|
67
|
+
}
|
|
6
68
|
export interface KeyPairOptions {
|
|
7
69
|
id?: string
|
|
8
70
|
controller?: string
|
|
@@ -94,7 +156,150 @@ export interface KeyPairVerifierOptions {
|
|
|
94
156
|
data: Array<Uint8Array>
|
|
95
157
|
signature: Uint8Array
|
|
96
158
|
}
|
|
97
|
-
export
|
|
159
|
+
export interface BoundKeyPairOptions {
|
|
160
|
+
id?: string
|
|
161
|
+
controller?: string
|
|
162
|
+
publicKeyBase58?: string
|
|
163
|
+
privateKeyBase58?: string
|
|
164
|
+
commitment: Uint8Array
|
|
165
|
+
blinded: Array<number>
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Sign a document with BbsBlsSignature2020 and embed the proof.
|
|
169
|
+
*
|
|
170
|
+
* Input: `{ document, keyPair: {id, controller, publicKeyBase58, privateKeyBase58}, contexts? }`
|
|
171
|
+
* Output: signed document JSON with embedded proof
|
|
172
|
+
*/
|
|
173
|
+
export declare function ldSign(options: any): Promise<any>
|
|
174
|
+
/**
|
|
175
|
+
* Verify a document with an embedded proof (auto-detects proof type).
|
|
176
|
+
*
|
|
177
|
+
* Input: `{ document, contexts? }`
|
|
178
|
+
* Output: `{ verified: boolean, error?: string }`
|
|
179
|
+
*/
|
|
180
|
+
export declare function ldVerify(options: any): Promise<any>
|
|
181
|
+
/**
|
|
182
|
+
* Derive a selective disclosure proof from a signed document.
|
|
183
|
+
*
|
|
184
|
+
* Input: `{ document, revealDocument, nonce?, contexts? }`
|
|
185
|
+
* Output: derived document JSON with embedded proof
|
|
186
|
+
*/
|
|
187
|
+
export declare function ldDeriveProof(options: any): Promise<any>
|
|
188
|
+
/**
|
|
189
|
+
* Standalone deriveProof function matching the JS reference's
|
|
190
|
+
* `deriveProof(proofDocument, revealDocument, { suite, documentLoader, nonce })`.
|
|
191
|
+
*
|
|
192
|
+
* Input: proofDocument (signed doc), revealDocument (frame), options `{ contexts?, nonce? }`
|
|
193
|
+
* Output: derived document JSON with embedded proof
|
|
194
|
+
*/
|
|
195
|
+
export declare function deriveProof(proofDocument: any, revealDocument: any, options: any): Promise<any>
|
|
196
|
+
/**
|
|
197
|
+
* Create a blind signature commitment (holder side).
|
|
198
|
+
*
|
|
199
|
+
* Input: issuerDID (for resolving public key), messages (blinded messages as Uint8Array[]),
|
|
200
|
+
* blinded (indices), nonce, knownMessageCount, options `{ contexts? }`
|
|
201
|
+
* Output: `{ commitment, challengeHash, blindingFactor, proofOfHiddenMessages }` (all Uint8Array)
|
|
202
|
+
*/
|
|
203
|
+
export declare function createCommitment(publicKey: Uint8Array, messages: Array<Uint8Array>, blinded: Array<number>, nonce: Uint8Array, knownMessageCount: number): Promise<any>
|
|
204
|
+
/**
|
|
205
|
+
* Verify a blind signature commitment (issuer side).
|
|
206
|
+
*
|
|
207
|
+
* Returns true if the commitment proof is valid.
|
|
208
|
+
*/
|
|
209
|
+
export declare function verifyCommitment(publicKey: Uint8Array, commitment: Uint8Array, proofOfHiddenMessages: Uint8Array, challengeHash: Uint8Array, blinded: Array<number>, nonce: Uint8Array, knownMessageCount: number): Promise<boolean>
|
|
210
|
+
/**
|
|
211
|
+
* Unblind a blind signature (holder side).
|
|
212
|
+
*
|
|
213
|
+
* Takes the blind signature from the issuer and the holder's blinding factor,
|
|
214
|
+
* returns the unblinded standard signature.
|
|
215
|
+
*/
|
|
216
|
+
export declare function unblindSignature(blindSignature: Uint8Array, blindingFactor: Uint8Array): Promise<Uint8Array>
|
|
217
|
+
/**
|
|
218
|
+
* Derive a selective disclosure proof from a holder-bound signed document.
|
|
219
|
+
*
|
|
220
|
+
* Input: proofDocument (signed doc), revealDocument (frame),
|
|
221
|
+
* options `{ blindingFactor: Uint8Array, blindedMessages: Uint8Array[], contexts?, nonce? }`
|
|
222
|
+
* Output: derived document JSON with embedded proof
|
|
223
|
+
*/
|
|
224
|
+
export declare function deriveProofHolderBound(proofDocument: any, revealDocument: any, options: any): Promise<any>
|
|
225
|
+
export declare class BbsBlsHolderBoundSignature2022 {
|
|
226
|
+
type: string
|
|
227
|
+
constructor(options?: BoundSignatureSuiteOptions | undefined | null)
|
|
228
|
+
/**
|
|
229
|
+
* Create a blind sign commitment context.
|
|
230
|
+
*
|
|
231
|
+
* Returns `{ knownMessageCount, nonce }` — the holder uses these to create a blind commitment.
|
|
232
|
+
* Matches JS `BbsBlsHolderBoundSignature2022.createBlindSignCommitmentContext()`.
|
|
233
|
+
*/
|
|
234
|
+
createBlindSignCommitmentContext(options: BoundCreateProofOptions): Promise<any>
|
|
235
|
+
/** Create a proof for a document using BbsBlsHolderBoundSignature2022 (blind signing). */
|
|
236
|
+
createProof(options: BoundCreateProofOptions): Promise<any>
|
|
237
|
+
/**
|
|
238
|
+
* Verify a holder-bound signed document.
|
|
239
|
+
*
|
|
240
|
+
* Returns `{ verified: boolean, error?: string }`.
|
|
241
|
+
*/
|
|
242
|
+
verifyProof(options: BoundVerifyProofOptions): Promise<any>
|
|
243
|
+
/** Ensure both BBS and holder-bound suite contexts are present. */
|
|
244
|
+
ensureSuiteContext(document: any): any
|
|
245
|
+
/** Returns the proof types this suite matches. */
|
|
246
|
+
get proofType(): Array<string>
|
|
247
|
+
}
|
|
248
|
+
export declare class BbsBlsHolderBoundSignatureProof2022 {
|
|
249
|
+
type: string
|
|
250
|
+
constructor()
|
|
251
|
+
/** Derive a selective disclosure proof from a holder-bound signed document. */
|
|
252
|
+
deriveProof(options: BoundDeriveProofOptions): Promise<any>
|
|
253
|
+
/**
|
|
254
|
+
* Verify a derived (selective disclosure) holder-bound proof.
|
|
255
|
+
*
|
|
256
|
+
* Returns `{ verified: boolean, error?: string }`.
|
|
257
|
+
*/
|
|
258
|
+
verifyProof(options: BoundVerifyDerivedProofOptions): Promise<any>
|
|
259
|
+
/** Returns the proof types this suite produces. */
|
|
260
|
+
get proofType(): Array<string>
|
|
261
|
+
/** Returns the proof types from which this suite can derive. */
|
|
262
|
+
get supportedDerivedProofType(): Array<string>
|
|
263
|
+
}
|
|
264
|
+
export declare class BbsBlsSignature2020 {
|
|
265
|
+
type: string
|
|
266
|
+
constructor(options?: SignatureSuiteOptions | undefined | null)
|
|
267
|
+
/** Generate a BbsBlsSignature2020 suite from a seed (async key generation). */
|
|
268
|
+
static generate(options: SignatureSuiteOptions): Promise<BbsBlsSignature2020>
|
|
269
|
+
/**
|
|
270
|
+
* Create a proof for a document using BbsBlsSignature2020.
|
|
271
|
+
*
|
|
272
|
+
* Returns just the proof object (matching JS reference behavior).
|
|
273
|
+
*/
|
|
274
|
+
createProof(options: CreateProofOptions): Promise<any>
|
|
275
|
+
/**
|
|
276
|
+
* Verify a document with an embedded proof.
|
|
277
|
+
*
|
|
278
|
+
* Returns `{ verified: boolean, error?: string }`.
|
|
279
|
+
*/
|
|
280
|
+
verifyProof(options: VerifyProofOptions): Promise<any>
|
|
281
|
+
/** Ensure the BBS suite context is present in the document's @context. */
|
|
282
|
+
ensureSuiteContext(document: any): any
|
|
283
|
+
sign(options: SuiteSignOptions): Promise<any>
|
|
284
|
+
verifySignature(options: VerifySignatureOptions): Promise<boolean>
|
|
285
|
+
}
|
|
286
|
+
export declare class BbsBlsSignatureProof2020 {
|
|
287
|
+
type: string
|
|
288
|
+
constructor()
|
|
289
|
+
/** Derive a selective disclosure proof from a signed document. */
|
|
290
|
+
deriveProof(options: DeriveProofOptions): Promise<any>
|
|
291
|
+
/**
|
|
292
|
+
* Verify a derived (selective disclosure) proof.
|
|
293
|
+
*
|
|
294
|
+
* Returns `{ verified: boolean, error?: string }`.
|
|
295
|
+
*/
|
|
296
|
+
verifyProof(options: VerifyDerivedProofOptions): Promise<any>
|
|
297
|
+
/** Returns the proof types this suite produces. */
|
|
298
|
+
get proofType(): Array<string>
|
|
299
|
+
/** Returns the proof types from which this suite can derive. */
|
|
300
|
+
get supportedDerivedProofType(): Array<string>
|
|
301
|
+
}
|
|
302
|
+
export declare class Bls12381G2KeyPair {
|
|
98
303
|
id?: string
|
|
99
304
|
controller?: string
|
|
100
305
|
privateKeyInner?: Array<number>
|
|
@@ -117,9 +322,104 @@ export class Bls12381G2KeyPair {
|
|
|
117
322
|
static fingerprintFromPublicKey(options: FingerPrintFromPublicKeyOptions): string
|
|
118
323
|
verifyFingerprint(fingerprint: string): void
|
|
119
324
|
}
|
|
120
|
-
export class KeyPairSigner {
|
|
325
|
+
export declare class KeyPairSigner {
|
|
121
326
|
sign(options: KeyPairSignerOptions): Promise<Uint8Array>
|
|
122
327
|
}
|
|
123
|
-
export class KeyPairVerifier {
|
|
328
|
+
export declare class KeyPairVerifier {
|
|
124
329
|
verify(options: KeyPairVerifierOptions): Promise<boolean>
|
|
125
330
|
}
|
|
331
|
+
export declare class BoundBls12381G2KeyPair {
|
|
332
|
+
constructor(options: BoundKeyPairOptions)
|
|
333
|
+
static from(options: BoundKeyPairOptions): BoundBls12381G2KeyPair
|
|
334
|
+
get commitment(): Uint8Array
|
|
335
|
+
get blinded(): Array<number>
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* JSON-LD processor — drop-in replacement for the jsonld.js API.
|
|
339
|
+
*
|
|
340
|
+
* Holds a `DocumentLoader` and `ContextResolver` internally so they are
|
|
341
|
+
* created once and reused across all method calls.
|
|
342
|
+
*
|
|
343
|
+
* ```js
|
|
344
|
+
* const jsonld = new JsonLd({ contexts: { "https://example.org/ctx": {...} } });
|
|
345
|
+
* const expanded = await jsonld.expand(doc);
|
|
346
|
+
* const compacted = await jsonld.compact(expanded, ctx);
|
|
347
|
+
* ```
|
|
348
|
+
*/
|
|
349
|
+
export declare class JsonLd {
|
|
350
|
+
/**
|
|
351
|
+
* Create a new JSON-LD processor.
|
|
352
|
+
*
|
|
353
|
+
* Accepts optional `{ contexts?: Record<string, any> }` to register
|
|
354
|
+
* additional URL → document mappings in the document loader (on top
|
|
355
|
+
* of the built-in nuggets contexts).
|
|
356
|
+
*/
|
|
357
|
+
constructor(options?: any | undefined | null)
|
|
358
|
+
/**
|
|
359
|
+
* Expand a JSON-LD document.
|
|
360
|
+
*
|
|
361
|
+
* `options` can include: `base`, `expandContext`, `keepFreeFloatingNodes`,
|
|
362
|
+
* `processingMode`.
|
|
363
|
+
*
|
|
364
|
+
* Returns an array of expanded JSON-LD objects.
|
|
365
|
+
*/
|
|
366
|
+
expand(input: any, options?: any | undefined | null): Promise<any>
|
|
367
|
+
/**
|
|
368
|
+
* Compact a JSON-LD document using a context.
|
|
369
|
+
*
|
|
370
|
+
* `ctx` — the compaction context (object, array, or string URL).
|
|
371
|
+
* `options` can include: `base`, `compactArrays`, `graph`,
|
|
372
|
+
* `skipExpansion`, `processingMode`.
|
|
373
|
+
*
|
|
374
|
+
* Returns the compacted JSON-LD object.
|
|
375
|
+
*/
|
|
376
|
+
compact(input: any, ctx: any, options?: any | undefined | null): Promise<any>
|
|
377
|
+
/**
|
|
378
|
+
* Flatten a JSON-LD document.
|
|
379
|
+
*
|
|
380
|
+
* `ctx` — optional context for compacting the flattened result.
|
|
381
|
+
* Pass `null` to get the flattened expanded form.
|
|
382
|
+
* `options` can include: `base`, `expandContext`, `processingMode`.
|
|
383
|
+
*
|
|
384
|
+
* Returns flattened array (no context) or compacted object (with context).
|
|
385
|
+
*/
|
|
386
|
+
flatten(input: any, ctx?: any | undefined | null, options?: any | undefined | null): Promise<any>
|
|
387
|
+
/**
|
|
388
|
+
* Frame a JSON-LD document.
|
|
389
|
+
*
|
|
390
|
+
* `frame` — the framing template.
|
|
391
|
+
* `options` can include: `base`, `embed`, `explicit`, `requireAll`,
|
|
392
|
+
* `omitDefault`, `omitGraph`, `processingMode`.
|
|
393
|
+
*
|
|
394
|
+
* Returns the framed JSON-LD object.
|
|
395
|
+
*/
|
|
396
|
+
frame(input: any, frame: any, options?: any | undefined | null): Promise<any>
|
|
397
|
+
/**
|
|
398
|
+
* Convert a JSON-LD document to an RDF dataset.
|
|
399
|
+
*
|
|
400
|
+
* `options` can include: `base`, `expandContext`, `skipExpansion`,
|
|
401
|
+
* `format` (`"application/n-quads"` for string output), `processingMode`.
|
|
402
|
+
*
|
|
403
|
+
* Returns an array of quads or an N-Quads string (depending on `format`).
|
|
404
|
+
*/
|
|
405
|
+
toRDF(input: any, options?: any | undefined | null): Promise<any>
|
|
406
|
+
/**
|
|
407
|
+
* Convert an RDF dataset to a JSON-LD document.
|
|
408
|
+
*
|
|
409
|
+
* `dataset` — N-Quads string or array of quads.
|
|
410
|
+
* `options` can include: `useRdfType`, `useNativeTypes`, `rdfDirection`.
|
|
411
|
+
*
|
|
412
|
+
* Returns an array of JSON-LD objects.
|
|
413
|
+
*/
|
|
414
|
+
fromRDF(dataset: any, options?: any | undefined | null): any
|
|
415
|
+
/**
|
|
416
|
+
* Canonize (normalize) a JSON-LD document.
|
|
417
|
+
*
|
|
418
|
+
* `options` can include: `base`, `expandContext`, `skipExpansion`,
|
|
419
|
+
* `inputFormat` (`"application/n-quads"`), `format`, `algorithm`,
|
|
420
|
+
* `processingMode`.
|
|
421
|
+
*
|
|
422
|
+
* Returns the canonical N-Quads string.
|
|
423
|
+
*/
|
|
424
|
+
canonize(input: any, options?: any | undefined | null): Promise<any>
|
|
425
|
+
}
|
package/index.js
CHANGED
|
@@ -310,8 +310,22 @@ if (!nativeBinding) {
|
|
|
310
310
|
throw new Error(`Failed to load native binding`)
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
-
const { Bls12381G2KeyPair, KeyPairSigner, KeyPairVerifier } = nativeBinding
|
|
313
|
+
const { BbsBlsHolderBoundSignature2022, BbsBlsHolderBoundSignatureProof2022, BbsBlsSignature2020, BbsBlsSignatureProof2020, Bls12381G2KeyPair, KeyPairSigner, KeyPairVerifier, BoundBls12381G2KeyPair, JsonLd, ldSign, ldVerify, ldDeriveProof, deriveProof, createCommitment, verifyCommitment, unblindSignature, deriveProofHolderBound } = nativeBinding
|
|
314
314
|
|
|
315
|
+
module.exports.BbsBlsHolderBoundSignature2022 = BbsBlsHolderBoundSignature2022
|
|
316
|
+
module.exports.BbsBlsHolderBoundSignatureProof2022 = BbsBlsHolderBoundSignatureProof2022
|
|
317
|
+
module.exports.BbsBlsSignature2020 = BbsBlsSignature2020
|
|
318
|
+
module.exports.BbsBlsSignatureProof2020 = BbsBlsSignatureProof2020
|
|
315
319
|
module.exports.Bls12381G2KeyPair = Bls12381G2KeyPair
|
|
316
320
|
module.exports.KeyPairSigner = KeyPairSigner
|
|
317
321
|
module.exports.KeyPairVerifier = KeyPairVerifier
|
|
322
|
+
module.exports.BoundBls12381G2KeyPair = BoundBls12381G2KeyPair
|
|
323
|
+
module.exports.JsonLd = JsonLd
|
|
324
|
+
module.exports.ldSign = ldSign
|
|
325
|
+
module.exports.ldVerify = ldVerify
|
|
326
|
+
module.exports.ldDeriveProof = ldDeriveProof
|
|
327
|
+
module.exports.deriveProof = deriveProof
|
|
328
|
+
module.exports.createCommitment = createCommitment
|
|
329
|
+
module.exports.verifyCommitment = verifyCommitment
|
|
330
|
+
module.exports.unblindSignature = unblindSignature
|
|
331
|
+
module.exports.deriveProofHolderBound = deriveProofHolderBound
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuggetslife/vc",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.15",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"types": "index.d.ts",
|
|
6
6
|
"napi": {
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
"defaults": false,
|
|
10
10
|
"additional": [
|
|
11
11
|
"aarch64-apple-darwin",
|
|
12
|
-
"x86_64-apple-darwin",
|
|
13
12
|
"aarch64-unknown-linux-gnu",
|
|
14
13
|
"aarch64-unknown-linux-musl",
|
|
15
14
|
"x86_64-unknown-linux-gnu",
|
|
@@ -19,10 +18,11 @@
|
|
|
19
18
|
},
|
|
20
19
|
"license": "MIT",
|
|
21
20
|
"devDependencies": {
|
|
21
|
+
"@mattrglobal/bls12381-key-pair": "^1.2.1",
|
|
22
|
+
"@mattrglobal/jsonld-signatures-bbs": "^1.2.0",
|
|
22
23
|
"@napi-rs/cli": "^2.18.3",
|
|
23
|
-
"ava": "^6.0.1",
|
|
24
24
|
"@types/node": "^20.14.9",
|
|
25
|
-
"
|
|
25
|
+
"ava": "^6.0.1"
|
|
26
26
|
},
|
|
27
27
|
"ava": {
|
|
28
28
|
"timeout": "3m"
|
|
@@ -41,11 +41,11 @@
|
|
|
41
41
|
},
|
|
42
42
|
"packageManager": "yarn@4.3.1",
|
|
43
43
|
"optionalDependencies": {
|
|
44
|
-
"@nuggetslife/vc-darwin-arm64": "0.0.
|
|
45
|
-
"@nuggetslife/vc-
|
|
46
|
-
"@nuggetslife/vc-linux-arm64-
|
|
47
|
-
"@nuggetslife/vc-linux-
|
|
48
|
-
"@nuggetslife/vc-linux-x64-
|
|
49
|
-
|
|
50
|
-
}
|
|
44
|
+
"@nuggetslife/vc-darwin-arm64": "0.0.15",
|
|
45
|
+
"@nuggetslife/vc-linux-arm64-gnu": "0.0.15",
|
|
46
|
+
"@nuggetslife/vc-linux-arm64-musl": "0.0.15",
|
|
47
|
+
"@nuggetslife/vc-linux-x64-gnu": "0.0.15",
|
|
48
|
+
"@nuggetslife/vc-linux-x64-musl": "0.0.15"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {}
|
|
51
51
|
}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
#![allow(dead_code)]
|
|
2
|
+
use napi::bindgen_prelude::*;
|
|
3
|
+
use serde_json::json;
|
|
4
|
+
use types::{BoundCreateProofOptions, BoundSignatureSuiteOptions, BoundVerifyProofOptions};
|
|
5
|
+
|
|
6
|
+
use super::bls_12381_g2_keypair::Bls12381G2KeyPair;
|
|
7
|
+
use crate::ld_signatures::{create_document_loader, parse_contexts};
|
|
8
|
+
|
|
9
|
+
pub mod types;
|
|
10
|
+
|
|
11
|
+
const BBS_CONTEXT_URL: &str = "https://w3id.org/security/bbs/v1";
|
|
12
|
+
const BBS_BOUND_CONTEXT_URL: &str = "https://schemas.nuggets.life/bbsBoundv1.json";
|
|
13
|
+
|
|
14
|
+
#[napi]
|
|
15
|
+
pub struct BbsBlsHolderBoundSignature2022 {
|
|
16
|
+
key: Bls12381G2KeyPair,
|
|
17
|
+
verification_method: Option<String>,
|
|
18
|
+
date: String,
|
|
19
|
+
commitment: Option<Vec<u8>>,
|
|
20
|
+
blinded: Option<Vec<usize>>,
|
|
21
|
+
#[napi(js_name = "type")]
|
|
22
|
+
pub type_: String,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
#[napi]
|
|
26
|
+
impl BbsBlsHolderBoundSignature2022 {
|
|
27
|
+
#[napi(constructor)]
|
|
28
|
+
pub fn new(options: Option<BoundSignatureSuiteOptions>) -> Self {
|
|
29
|
+
match options {
|
|
30
|
+
Some(opts) => {
|
|
31
|
+
let key = match opts.key {
|
|
32
|
+
Some(kp_opts) => Bls12381G2KeyPair::new(Some(
|
|
33
|
+
super::bls_12381_g2_keypair::types::KeyPairOptions {
|
|
34
|
+
id: kp_opts.id,
|
|
35
|
+
controller: kp_opts.controller,
|
|
36
|
+
public_key_base58: kp_opts.public_key_base58,
|
|
37
|
+
private_key_base58: kp_opts.private_key_base58,
|
|
38
|
+
},
|
|
39
|
+
)),
|
|
40
|
+
None => Bls12381G2KeyPair::new(None),
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
Self {
|
|
44
|
+
verification_method: match opts.verification_method {
|
|
45
|
+
Some(vm) => Some(vm),
|
|
46
|
+
None => key.id.clone(),
|
|
47
|
+
},
|
|
48
|
+
key,
|
|
49
|
+
date: match opts.date {
|
|
50
|
+
Some(d) => d,
|
|
51
|
+
None => chrono::Utc::now().to_rfc3339(),
|
|
52
|
+
},
|
|
53
|
+
commitment: opts.commitment.map(|c| c.to_vec()),
|
|
54
|
+
blinded: opts
|
|
55
|
+
.blinded
|
|
56
|
+
.map(|b| b.iter().map(|&i| i as usize).collect()),
|
|
57
|
+
type_: String::from("sec:BbsBlsHolderBoundSignature2022"),
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
None => {
|
|
61
|
+
let key = Bls12381G2KeyPair::new(None);
|
|
62
|
+
Self {
|
|
63
|
+
verification_method: None,
|
|
64
|
+
key,
|
|
65
|
+
date: chrono::Utc::now().to_rfc3339(),
|
|
66
|
+
commitment: None,
|
|
67
|
+
blinded: None,
|
|
68
|
+
type_: String::from("sec:BbsBlsHolderBoundSignature2022"),
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/// Create a blind sign commitment context.
|
|
75
|
+
///
|
|
76
|
+
/// Returns `{ knownMessageCount, nonce }` — the holder uses these to create a blind commitment.
|
|
77
|
+
/// Matches JS `BbsBlsHolderBoundSignature2022.createBlindSignCommitmentContext()`.
|
|
78
|
+
#[napi]
|
|
79
|
+
pub async fn create_blind_sign_commitment_context(
|
|
80
|
+
&self,
|
|
81
|
+
options: BoundCreateProofOptions,
|
|
82
|
+
) -> Result<serde_json::Value> {
|
|
83
|
+
let additional_contexts = options
|
|
84
|
+
.contexts
|
|
85
|
+
.as_ref()
|
|
86
|
+
.map(|v| parse_contexts(&json!({ "contexts": v })))
|
|
87
|
+
.unwrap_or_default();
|
|
88
|
+
let (loader, cr) = create_document_loader(additional_contexts);
|
|
89
|
+
|
|
90
|
+
let rust_key =
|
|
91
|
+
vc::jsonld::signatures::bbs::bls_12381_g2_keypair::Bls12381G2KeyPair::new(Some(
|
|
92
|
+
vc::jsonld::signatures::bbs::bls_12381_g2_keypair::types::KeyPairOptions {
|
|
93
|
+
id: self.key.id.clone(),
|
|
94
|
+
controller: self.key.controller.clone(),
|
|
95
|
+
public_key_base58: self.key.public_key(),
|
|
96
|
+
private_key_base58: self.key.private_key(),
|
|
97
|
+
},
|
|
98
|
+
));
|
|
99
|
+
|
|
100
|
+
// Commitment/blinded not needed for counting messages — use empty placeholders.
|
|
101
|
+
let bound_key = vc::jsonld::signatures::bbs::bound_keypair::BoundBls12381G2KeyPair::new(
|
|
102
|
+
rust_key,
|
|
103
|
+
vec![],
|
|
104
|
+
vec![],
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
let suite = vc::jsonld::signatures::bbs::holder_bound::BbsBlsHolderBoundSignature2022::new(
|
|
108
|
+
vc::jsonld::signatures::bbs::holder_bound::HolderBoundSignatureSuiteOptions {
|
|
109
|
+
key: bound_key,
|
|
110
|
+
verification_method: self.verification_method.clone(),
|
|
111
|
+
date: None,
|
|
112
|
+
},
|
|
113
|
+
)
|
|
114
|
+
.await;
|
|
115
|
+
|
|
116
|
+
let purpose = vc::jsonld::signatures::AssertionProofPurpose::new();
|
|
117
|
+
suite
|
|
118
|
+
.create_blind_sign_commitment_context(&options.document, &purpose, loader, cr)
|
|
119
|
+
.await
|
|
120
|
+
.map_err(|e| {
|
|
121
|
+
napi::Error::from_reason(format!("createBlindSignCommitmentContext failed: {e}"))
|
|
122
|
+
})
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/// Create a proof for a document using BbsBlsHolderBoundSignature2022 (blind signing).
|
|
126
|
+
#[napi]
|
|
127
|
+
pub async fn create_proof(
|
|
128
|
+
&self,
|
|
129
|
+
options: BoundCreateProofOptions,
|
|
130
|
+
) -> Result<serde_json::Value> {
|
|
131
|
+
let additional_contexts = options
|
|
132
|
+
.contexts
|
|
133
|
+
.as_ref()
|
|
134
|
+
.map(|v| parse_contexts(&json!({ "contexts": v })))
|
|
135
|
+
.unwrap_or_default();
|
|
136
|
+
let (loader, cr) = create_document_loader(additional_contexts);
|
|
137
|
+
|
|
138
|
+
let commitment = self
|
|
139
|
+
.commitment
|
|
140
|
+
.as_ref()
|
|
141
|
+
.ok_or_else(|| napi::Error::from_reason("No commitment set on suite"))?;
|
|
142
|
+
let blinded = self
|
|
143
|
+
.blinded
|
|
144
|
+
.as_ref()
|
|
145
|
+
.ok_or_else(|| napi::Error::from_reason("No blinded indices set on suite"))?;
|
|
146
|
+
|
|
147
|
+
let rust_key =
|
|
148
|
+
vc::jsonld::signatures::bbs::bls_12381_g2_keypair::Bls12381G2KeyPair::new(Some(
|
|
149
|
+
vc::jsonld::signatures::bbs::bls_12381_g2_keypair::types::KeyPairOptions {
|
|
150
|
+
id: self.key.id.clone(),
|
|
151
|
+
controller: self.key.controller.clone(),
|
|
152
|
+
public_key_base58: self.key.public_key(),
|
|
153
|
+
private_key_base58: self.key.private_key(),
|
|
154
|
+
},
|
|
155
|
+
));
|
|
156
|
+
|
|
157
|
+
let bound_key = vc::jsonld::signatures::bbs::bound_keypair::BoundBls12381G2KeyPair::new(
|
|
158
|
+
rust_key,
|
|
159
|
+
commitment.clone(),
|
|
160
|
+
blinded.clone(),
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
let suite = vc::jsonld::signatures::bbs::holder_bound::BbsBlsHolderBoundSignature2022::new(
|
|
164
|
+
vc::jsonld::signatures::bbs::holder_bound::HolderBoundSignatureSuiteOptions {
|
|
165
|
+
key: bound_key,
|
|
166
|
+
verification_method: self.verification_method.clone(),
|
|
167
|
+
date: None,
|
|
168
|
+
},
|
|
169
|
+
)
|
|
170
|
+
.await;
|
|
171
|
+
|
|
172
|
+
let purpose = vc::jsonld::signatures::AssertionProofPurpose::new();
|
|
173
|
+
let signed =
|
|
174
|
+
vc::jsonld::signatures::sign_holder_bound(options.document, &suite, &purpose, loader, cr)
|
|
175
|
+
.await
|
|
176
|
+
.map_err(|e| napi::Error::from_reason(format!("createProof failed: {e}")))?;
|
|
177
|
+
|
|
178
|
+
signed
|
|
179
|
+
.get("proof")
|
|
180
|
+
.cloned()
|
|
181
|
+
.ok_or_else(|| napi::Error::from_reason("createProof: no proof in signed document"))
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/// Verify a holder-bound signed document.
|
|
185
|
+
///
|
|
186
|
+
/// Returns `{ verified: boolean, error?: string }`.
|
|
187
|
+
#[napi]
|
|
188
|
+
pub async fn verify_proof(
|
|
189
|
+
&self,
|
|
190
|
+
options: BoundVerifyProofOptions,
|
|
191
|
+
) -> Result<serde_json::Value> {
|
|
192
|
+
let additional_contexts = options
|
|
193
|
+
.contexts
|
|
194
|
+
.as_ref()
|
|
195
|
+
.map(|v| parse_contexts(&json!({ "contexts": v })))
|
|
196
|
+
.unwrap_or_default();
|
|
197
|
+
let (loader, cr) = create_document_loader(additional_contexts);
|
|
198
|
+
|
|
199
|
+
let blinding_factor = options.blinding_factor.to_vec();
|
|
200
|
+
let blinded_messages: Vec<Vec<u8>> =
|
|
201
|
+
options.blinded_messages.iter().map(|m| m.to_vec()).collect();
|
|
202
|
+
|
|
203
|
+
let purpose = vc::jsonld::signatures::AssertionProofPurpose::new();
|
|
204
|
+
let result = vc::jsonld::signatures::verify_holder_bound(
|
|
205
|
+
&options.document,
|
|
206
|
+
blinding_factor,
|
|
207
|
+
blinded_messages,
|
|
208
|
+
&purpose,
|
|
209
|
+
loader,
|
|
210
|
+
cr,
|
|
211
|
+
)
|
|
212
|
+
.await
|
|
213
|
+
.map_err(|e| napi::Error::from_reason(format!("verifyProof failed: {e}")))?;
|
|
214
|
+
|
|
215
|
+
Ok(json!({
|
|
216
|
+
"verified": result.verified,
|
|
217
|
+
"error": result.error,
|
|
218
|
+
}))
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/// Ensure both BBS and holder-bound suite contexts are present.
|
|
222
|
+
#[napi]
|
|
223
|
+
pub fn ensure_suite_context(
|
|
224
|
+
&self,
|
|
225
|
+
document: serde_json::Value,
|
|
226
|
+
) -> Result<serde_json::Value> {
|
|
227
|
+
let mut doc = document;
|
|
228
|
+
|
|
229
|
+
for context_url in &[BBS_CONTEXT_URL, BBS_BOUND_CONTEXT_URL] {
|
|
230
|
+
let has_context = match doc.get("@context") {
|
|
231
|
+
Some(serde_json::Value::String(s)) => s == *context_url,
|
|
232
|
+
Some(serde_json::Value::Array(arr)) => {
|
|
233
|
+
arr.iter().any(|v| v.as_str() == Some(*context_url))
|
|
234
|
+
}
|
|
235
|
+
_ => false,
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
if !has_context {
|
|
239
|
+
if let Some(obj) = doc.as_object_mut() {
|
|
240
|
+
let existing = obj
|
|
241
|
+
.get("@context")
|
|
242
|
+
.cloned()
|
|
243
|
+
.unwrap_or(serde_json::Value::Null);
|
|
244
|
+
let mut new_context = match existing {
|
|
245
|
+
serde_json::Value::Array(arr) => serde_json::Value::Array(arr),
|
|
246
|
+
other => serde_json::Value::Array(vec![other]),
|
|
247
|
+
};
|
|
248
|
+
if let serde_json::Value::Array(arr) = &mut new_context {
|
|
249
|
+
arr.push(serde_json::Value::String(context_url.to_string()));
|
|
250
|
+
}
|
|
251
|
+
obj.insert("@context".to_string(), new_context);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
Ok(doc)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/// Returns the proof types this suite matches.
|
|
260
|
+
#[napi(getter)]
|
|
261
|
+
pub fn proof_type() -> Vec<String> {
|
|
262
|
+
vec![
|
|
263
|
+
"BbsBlsHolderBoundSignature2022".to_string(),
|
|
264
|
+
"sec:BbsBlsHolderBoundSignature2022".to_string(),
|
|
265
|
+
"https://w3id.org/security#BbsBlsHolderBoundSignature2022".to_string(),
|
|
266
|
+
]
|
|
267
|
+
}
|
|
268
|
+
}
|