@dwn-protocol/id-sdk 0.2.5 → 0.2.6
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/package.json +2 -3
- package/src/agent/app-data-store.ts +0 -365
- package/src/agent/did-manager.ts +0 -393
- package/src/agent/dwn-manager.ts +0 -548
- package/src/agent/identity-manager.ts +0 -165
- package/src/agent/index.ts +0 -19
- package/src/agent/json-rpc.ts +0 -107
- package/src/agent/key-manager.ts +0 -302
- package/src/agent/kms-local.ts +0 -412
- package/src/agent/outbox.ts +0 -128
- package/src/agent/rpc-client.ts +0 -223
- package/src/agent/store-managed-did.ts +0 -295
- package/src/agent/store-managed-identity.ts +0 -243
- package/src/agent/store-managed-key.ts +0 -754
- package/src/agent/sync-manager.ts +0 -631
- package/src/agent/test-managed-agent.ts +0 -299
- package/src/agent/types/agent.ts +0 -145
- package/src/agent/types/managed-key.ts +0 -442
- package/src/agent/utils.ts +0 -190
- package/src/common/convert.ts +0 -424
- package/src/common/index.ts +0 -9
- package/src/common/multicodec.ts +0 -176
- package/src/common/object.ts +0 -43
- package/src/common/stores.ts +0 -125
- package/src/common/stream-node.ts +0 -381
- package/src/common/stream.ts +0 -406
- package/src/common/type-utils.ts +0 -117
- package/src/common/types.ts +0 -48
- package/src/credentials/credential-bbs.ts +0 -419
- package/src/credentials/credential.ts +0 -324
- package/src/credentials/index.ts +0 -5
- package/src/credentials/presentation.ts +0 -182
- package/src/credentials/status-list.ts +0 -365
- package/src/credentials/utils.ts +0 -58
- package/src/credentials/validators.ts +0 -52
- package/src/crypto/algorithms-api/aes/base.ts +0 -49
- package/src/crypto/algorithms-api/aes/ctr.ts +0 -51
- package/src/crypto/algorithms-api/aes/index.ts +0 -2
- package/src/crypto/algorithms-api/crypto-algorithm.ts +0 -127
- package/src/crypto/algorithms-api/crypto-key.ts +0 -56
- package/src/crypto/algorithms-api/ec/base.ts +0 -39
- package/src/crypto/algorithms-api/ec/ecdh.ts +0 -53
- package/src/crypto/algorithms-api/ec/ecdsa.ts +0 -37
- package/src/crypto/algorithms-api/ec/eddsa.ts +0 -30
- package/src/crypto/algorithms-api/ec/index.ts +0 -4
- package/src/crypto/algorithms-api/errors.ts +0 -29
- package/src/crypto/algorithms-api/index.ts +0 -6
- package/src/crypto/algorithms-api/pbkdf/index.ts +0 -1
- package/src/crypto/algorithms-api/pbkdf/pbkdf2.ts +0 -91
- package/src/crypto/crypto-algorithms/aes-ctr.ts +0 -70
- package/src/crypto/crypto-algorithms/bbs.ts +0 -110
- package/src/crypto/crypto-algorithms/ecdh.ts +0 -115
- package/src/crypto/crypto-algorithms/ecdsa.ts +0 -111
- package/src/crypto/crypto-algorithms/eddsa.ts +0 -110
- package/src/crypto/crypto-algorithms/index.ts +0 -6
- package/src/crypto/crypto-algorithms/pbkdf2.ts +0 -54
- package/src/crypto/crypto-primitives/aes-ctr.ts +0 -131
- package/src/crypto/crypto-primitives/aes-gcm.ts +0 -138
- package/src/crypto/crypto-primitives/bbs.ts +0 -183
- package/src/crypto/crypto-primitives/concat-kdf.ts +0 -207
- package/src/crypto/crypto-primitives/ed25519.ts +0 -201
- package/src/crypto/crypto-primitives/index.ts +0 -10
- package/src/crypto/crypto-primitives/pbkdf2.ts +0 -78
- package/src/crypto/crypto-primitives/secp256k1.ts +0 -322
- package/src/crypto/crypto-primitives/x25519.ts +0 -101
- package/src/crypto/crypto-primitives/xchacha20-poly1305.ts +0 -46
- package/src/crypto/crypto-primitives/xchacha20.ts +0 -34
- package/src/crypto/index.ts +0 -8
- package/src/crypto/jose.ts +0 -948
- package/src/crypto/types/crypto-key.ts +0 -4
- package/src/crypto/types/iddwn-crypto.ts +0 -119
- package/src/crypto/utils.ts +0 -200
- package/src/did-api.ts +0 -72
- package/src/dids/dht.ts +0 -412
- package/src/dids/did-dht.ts +0 -436
- package/src/dids/did-ion.ts +0 -613
- package/src/dids/did-key.ts +0 -791
- package/src/dids/did-resolver.ts +0 -107
- package/src/dids/index.ts +0 -9
- package/src/dids/resolver-cache-level.ts +0 -82
- package/src/dids/resolver-cache-noop.ts +0 -25
- package/src/dids/types.ts +0 -278
- package/src/dids/utils.ts +0 -129
- package/src/dwn-api.ts +0 -584
- package/src/iddwn.ts +0 -241
- package/src/identity-agent/index.ts +0 -270
- package/src/index.ts +0 -26
- package/src/interfaces/metadata.ts +0 -163
- package/src/interfaces/queue.ts +0 -108
- package/src/interfaces/services.ts +0 -122
- package/src/interfaces/transactions.ts +0 -220
- package/src/protocol.ts +0 -68
- package/src/proxy-agent/index.ts +0 -255
- package/src/record.ts +0 -521
- package/src/service-options.ts +0 -62
- package/src/typings/decentralized-identity__ion-pow-sdk.d.ts +0 -7
- package/src/user-agent/index.ts +0 -295
- package/src/utils.ts +0 -29
- package/src/vc-api.ts +0 -505
|
@@ -1,419 +0,0 @@
|
|
|
1
|
-
import type { ICredential } from '@sphereon/ssi-types';
|
|
2
|
-
import type { BbsKeyPair } from '../crypto/crypto-primitives/bbs.js';
|
|
3
|
-
import type { VcDataModel } from './credential.js';
|
|
4
|
-
|
|
5
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
6
|
-
import { Bbs } from '../crypto/crypto-primitives/bbs.js';
|
|
7
|
-
import { Convert } from '../common/index.js';
|
|
8
|
-
import { DidDhtMethod, DidIonMethod, DidKeyMethod, DidResolver } from '../dids/index.js';
|
|
9
|
-
import { VcValidator } from './validators.js';
|
|
10
|
-
import { getCurrentXmlSchema112Timestamp } from './utils.js';
|
|
11
|
-
import { DEFAULT_CONTEXT, DEFAULT_VC_TYPE } from './credential.js';
|
|
12
|
-
|
|
13
|
-
const didResolver = new DidResolver({ didResolvers: [DidIonMethod, DidKeyMethod, DidDhtMethod] });
|
|
14
|
-
|
|
15
|
-
export const VC_DATA_FORMAT_LDP = 'application/vc+ld+json';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* BBS+ Data Integrity proof attached to a Verifiable Credential.
|
|
19
|
-
*/
|
|
20
|
-
export interface BbsDataIntegrityProof {
|
|
21
|
-
type: 'DataIntegrityProof';
|
|
22
|
-
cryptosuite: 'bbs-2023';
|
|
23
|
-
verificationMethod: string;
|
|
24
|
-
proofPurpose: 'assertionMethod';
|
|
25
|
-
proofValue: string;
|
|
26
|
-
created: string;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* A derived BBS+ selective disclosure proof.
|
|
31
|
-
*/
|
|
32
|
-
export interface BbsDerivedProof {
|
|
33
|
-
type: 'DataIntegrityProof';
|
|
34
|
-
cryptosuite: 'bbs-2023';
|
|
35
|
-
verificationMethod: string;
|
|
36
|
-
proofPurpose: 'assertionMethod';
|
|
37
|
-
proofValue: string;
|
|
38
|
-
nonce: string;
|
|
39
|
-
created: string;
|
|
40
|
-
disclosedIndices: number[];
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* VC with a BBS+ Data Integrity proof (full or derived).
|
|
45
|
-
*/
|
|
46
|
-
export interface BbsVerifiableCredential extends ICredential {
|
|
47
|
-
proof: BbsDataIntegrityProof | BbsDerivedProof;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Options for signing a credential with BBS+.
|
|
52
|
-
*/
|
|
53
|
-
export interface BbsSignOptions {
|
|
54
|
-
kid: string;
|
|
55
|
-
issuerDid: string;
|
|
56
|
-
subjectDid: string;
|
|
57
|
-
keyPair: BbsKeyPair;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Options for deriving a selective disclosure proof.
|
|
62
|
-
*/
|
|
63
|
-
export interface BbsDeriveProofOptions {
|
|
64
|
-
issuerPublicKey: Uint8Array;
|
|
65
|
-
revealedAttributes: string[];
|
|
66
|
-
nonce: string;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Options for creating a BBS+ credential.
|
|
71
|
-
*/
|
|
72
|
-
export interface BbsCredentialCreateOptions {
|
|
73
|
-
type?: string | string[];
|
|
74
|
-
issuer: string;
|
|
75
|
-
subject: string;
|
|
76
|
-
data: Record<string, any>;
|
|
77
|
-
issuanceDate?: string;
|
|
78
|
-
expirationDate?: string;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Serialized representation of a BBS+ signed credential
|
|
83
|
-
* containing the signed VC, the original message order, and the signature.
|
|
84
|
-
*/
|
|
85
|
-
export interface BbsSignedCredentialBundle {
|
|
86
|
-
credential: BbsVerifiableCredential;
|
|
87
|
-
messageKeys: string[];
|
|
88
|
-
signature: string;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Result of deriving a selective disclosure proof from a BBS+ credential.
|
|
93
|
-
*/
|
|
94
|
-
export interface BbsDerivedCredential {
|
|
95
|
-
credential: BbsVerifiableCredential;
|
|
96
|
-
disclosedKeys: string[];
|
|
97
|
-
disclosedIndices: number[];
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const ENCODER = new TextEncoder();
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Converts a credential subject's attributes into an ordered array of
|
|
104
|
-
* messages suitable for BBS+ multi-message signing.
|
|
105
|
-
* The `id` field (subject DID) is always the first message.
|
|
106
|
-
*/
|
|
107
|
-
function credentialSubjectToMessages(
|
|
108
|
-
credentialSubject: Record<string, any>
|
|
109
|
-
): { messages: Uint8Array[]; keys: string[] } {
|
|
110
|
-
const keys: string[] = [];
|
|
111
|
-
const messages: Uint8Array[] = [];
|
|
112
|
-
|
|
113
|
-
const sortedEntries = Object.entries(credentialSubject).sort(([a], [b]) => {
|
|
114
|
-
if (a === 'id') return -1;
|
|
115
|
-
if (b === 'id') return 1;
|
|
116
|
-
return a.localeCompare(b);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
for (const [key, value] of sortedEntries) {
|
|
120
|
-
keys.push(key);
|
|
121
|
-
const messageStr = typeof value === 'string' ? value : JSON.stringify(value);
|
|
122
|
-
messages.push(ENCODER.encode(`${key}=${messageStr}`));
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return { messages, keys };
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* `BbsCredential` provides methods for creating, signing, and deriving
|
|
130
|
-
* selective disclosure proofs from Verifiable Credentials using BBS+
|
|
131
|
-
* signatures on the BLS12-381 curve.
|
|
132
|
-
*
|
|
133
|
-
* Unlike JWT-based credentials that treat the payload as monolithic,
|
|
134
|
-
* BBS+ signs each credential attribute as a separate message, enabling
|
|
135
|
-
* zero-knowledge proofs that reveal only chosen attributes.
|
|
136
|
-
*
|
|
137
|
-
* Usage flow:
|
|
138
|
-
* 1. Issuer: `create()` -> `sign()` -> store full credential in holder's DWN
|
|
139
|
-
* 2. Holder: `deriveProof()` -> selectively disclose attributes to verifier
|
|
140
|
-
* 3. Verifier: `verifyProof()` -> verify the derived proof
|
|
141
|
-
*/
|
|
142
|
-
export class BbsCredential {
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Creates a VC data model suitable for BBS+ signing.
|
|
146
|
-
*/
|
|
147
|
-
public static create(options: BbsCredentialCreateOptions): VcDataModel {
|
|
148
|
-
const { type, issuer, subject, data, issuanceDate, expirationDate } = options;
|
|
149
|
-
|
|
150
|
-
const jsonData = JSON.parse(JSON.stringify(data));
|
|
151
|
-
if (typeof jsonData !== 'object') {
|
|
152
|
-
throw new Error('Expected data to be parseable into a JSON object');
|
|
153
|
-
}
|
|
154
|
-
if (!issuer || !subject) {
|
|
155
|
-
throw new Error('Issuer and subject must be defined');
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const credentialSubject = { id: subject, ...jsonData };
|
|
159
|
-
|
|
160
|
-
const vcDataModel: VcDataModel = {
|
|
161
|
-
'@context': [DEFAULT_CONTEXT, 'https://w3id.org/security/data-integrity/v2'],
|
|
162
|
-
type: Array.isArray(type)
|
|
163
|
-
? [DEFAULT_VC_TYPE, ...type]
|
|
164
|
-
: type ? [DEFAULT_VC_TYPE, type] : [DEFAULT_VC_TYPE],
|
|
165
|
-
id: `urn:uuid:${uuidv4()}`,
|
|
166
|
-
issuer,
|
|
167
|
-
issuanceDate: issuanceDate || getCurrentXmlSchema112Timestamp(),
|
|
168
|
-
credentialSubject,
|
|
169
|
-
...(expirationDate && { expirationDate }),
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
VcValidator.validateContext(vcDataModel['@context']);
|
|
173
|
-
VcValidator.validateVcType(vcDataModel.type);
|
|
174
|
-
VcValidator.validateCredentialSubject(vcDataModel.credentialSubject);
|
|
175
|
-
|
|
176
|
-
return vcDataModel;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Signs a VC with BBS+. Each attribute in `credentialSubject` becomes a
|
|
181
|
-
* separate BBS+ message, enabling per-attribute selective disclosure.
|
|
182
|
-
*
|
|
183
|
-
* @returns A bundle containing the signed credential, message key order,
|
|
184
|
-
* and base64url-encoded signature.
|
|
185
|
-
*/
|
|
186
|
-
public static async sign(
|
|
187
|
-
vcDataModel: VcDataModel,
|
|
188
|
-
signOptions: BbsSignOptions
|
|
189
|
-
): Promise<BbsSignedCredentialBundle> {
|
|
190
|
-
const { kid, issuerDid, keyPair } = signOptions;
|
|
191
|
-
|
|
192
|
-
const subject = vcDataModel.credentialSubject as Record<string, any>;
|
|
193
|
-
const { messages, keys } = credentialSubjectToMessages(
|
|
194
|
-
Array.isArray(subject) ? subject[0] : subject
|
|
195
|
-
);
|
|
196
|
-
|
|
197
|
-
const signature = await Bbs.sign({ keyPair, messages });
|
|
198
|
-
const signatureBase64Url = Convert.uint8Array(signature).toBase64Url();
|
|
199
|
-
|
|
200
|
-
const proof: BbsDataIntegrityProof = {
|
|
201
|
-
type: 'DataIntegrityProof',
|
|
202
|
-
cryptosuite: 'bbs-2023',
|
|
203
|
-
verificationMethod: `${issuerDid}#${kid}`,
|
|
204
|
-
proofPurpose: 'assertionMethod',
|
|
205
|
-
proofValue: signatureBase64Url,
|
|
206
|
-
created: getCurrentXmlSchema112Timestamp(),
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
const signedCredential: BbsVerifiableCredential = {
|
|
210
|
-
...vcDataModel,
|
|
211
|
-
proof,
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
return {
|
|
215
|
-
credential: signedCredential,
|
|
216
|
-
messageKeys: keys,
|
|
217
|
-
signature: signatureBase64Url,
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Verifies a full BBS+ signed credential (not a derived proof).
|
|
223
|
-
* Reconstructs the message array from `credentialSubject` and verifies
|
|
224
|
-
* the signature against the issuer's public key.
|
|
225
|
-
*
|
|
226
|
-
* @param credential - The BBS+ signed VC.
|
|
227
|
-
* @param issuerPublicKey - The issuer's 96-byte BLS12-381 G2 public key.
|
|
228
|
-
* @returns `true` if the signature is valid.
|
|
229
|
-
*/
|
|
230
|
-
public static async verify(
|
|
231
|
-
credential: BbsVerifiableCredential,
|
|
232
|
-
issuerPublicKey: Uint8Array
|
|
233
|
-
): Promise<boolean> {
|
|
234
|
-
const proof = credential.proof as BbsDataIntegrityProof;
|
|
235
|
-
if (proof.cryptosuite !== 'bbs-2023') {
|
|
236
|
-
throw new Error(`Unsupported cryptosuite: ${proof.cryptosuite}`);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
const signature = Convert.base64Url(proof.proofValue).toUint8Array();
|
|
240
|
-
|
|
241
|
-
const subject = credential.credentialSubject as Record<string, any>;
|
|
242
|
-
const { messages } = credentialSubjectToMessages(
|
|
243
|
-
Array.isArray(subject) ? subject[0] : subject
|
|
244
|
-
);
|
|
245
|
-
|
|
246
|
-
return Bbs.verify({
|
|
247
|
-
publicKey: issuerPublicKey,
|
|
248
|
-
signature,
|
|
249
|
-
messages,
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* Derives a zero-knowledge selective disclosure proof from a BBS+ signed
|
|
255
|
-
* credential. The resulting credential contains only the disclosed
|
|
256
|
-
* attributes and a proof that cryptographically demonstrates the holder
|
|
257
|
-
* possesses a valid signature over the full attribute set.
|
|
258
|
-
*
|
|
259
|
-
* @param bundle - The signed credential bundle from `sign()`.
|
|
260
|
-
* @param options - Specifies which attributes to reveal and a session nonce.
|
|
261
|
-
* @returns The derived credential with only disclosed attributes visible.
|
|
262
|
-
*/
|
|
263
|
-
public static async deriveProof(
|
|
264
|
-
bundle: BbsSignedCredentialBundle,
|
|
265
|
-
options: BbsDeriveProofOptions
|
|
266
|
-
): Promise<BbsDerivedCredential> {
|
|
267
|
-
const { issuerPublicKey, revealedAttributes, nonce } = options;
|
|
268
|
-
const { credential, messageKeys, signature: signatureBase64Url } = bundle;
|
|
269
|
-
|
|
270
|
-
const subject = credential.credentialSubject as Record<string, any>;
|
|
271
|
-
const flatSubject = Array.isArray(subject) ? subject[0] : subject;
|
|
272
|
-
const { messages } = credentialSubjectToMessages(flatSubject);
|
|
273
|
-
|
|
274
|
-
// The `id` field (subject DID) is always disclosed
|
|
275
|
-
const attributesToReveal = new Set(revealedAttributes);
|
|
276
|
-
attributesToReveal.add('id');
|
|
277
|
-
|
|
278
|
-
const revealedIndices: number[] = [];
|
|
279
|
-
for (let i = 0; i < messageKeys.length; i++) {
|
|
280
|
-
if (attributesToReveal.has(messageKeys[i])) {
|
|
281
|
-
revealedIndices.push(i);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
if (revealedIndices.length === 0) {
|
|
286
|
-
throw new Error('At least one attribute must be revealed');
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
const signatureBytes = Convert.base64Url(signatureBase64Url).toUint8Array();
|
|
290
|
-
const nonceBytes = ENCODER.encode(nonce);
|
|
291
|
-
|
|
292
|
-
const proof = await Bbs.createProof({
|
|
293
|
-
publicKey: issuerPublicKey,
|
|
294
|
-
signature: signatureBytes,
|
|
295
|
-
messages,
|
|
296
|
-
revealed: revealedIndices,
|
|
297
|
-
nonce: nonceBytes,
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
const proofBase64Url = Convert.uint8Array(proof).toBase64Url();
|
|
301
|
-
|
|
302
|
-
// Build the disclosed credential subject with only revealed attributes
|
|
303
|
-
const disclosedSubject: Record<string, any> = {};
|
|
304
|
-
const disclosedKeys: string[] = [];
|
|
305
|
-
for (const idx of revealedIndices) {
|
|
306
|
-
const key = messageKeys[idx];
|
|
307
|
-
disclosedSubject[key] = flatSubject[key];
|
|
308
|
-
disclosedKeys.push(key);
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
const derivedProof: BbsDerivedProof = {
|
|
312
|
-
type: 'DataIntegrityProof',
|
|
313
|
-
cryptosuite: 'bbs-2023',
|
|
314
|
-
verificationMethod: (credential.proof as BbsDataIntegrityProof).verificationMethod,
|
|
315
|
-
proofPurpose: 'assertionMethod',
|
|
316
|
-
proofValue: proofBase64Url,
|
|
317
|
-
nonce,
|
|
318
|
-
created: getCurrentXmlSchema112Timestamp(),
|
|
319
|
-
disclosedIndices: revealedIndices,
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
const derivedCredential: BbsVerifiableCredential = {
|
|
323
|
-
'@context': credential['@context'],
|
|
324
|
-
type: credential.type,
|
|
325
|
-
id: credential.id,
|
|
326
|
-
issuer: credential.issuer,
|
|
327
|
-
issuanceDate: credential.issuanceDate,
|
|
328
|
-
credentialSubject: disclosedSubject,
|
|
329
|
-
...(credential.expirationDate && { expirationDate: credential.expirationDate }),
|
|
330
|
-
proof: derivedProof,
|
|
331
|
-
};
|
|
332
|
-
|
|
333
|
-
return {
|
|
334
|
-
credential: derivedCredential,
|
|
335
|
-
disclosedKeys,
|
|
336
|
-
disclosedIndices: revealedIndices,
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
/**
|
|
341
|
-
* Verifies a BBS+ selective disclosure proof. Only the disclosed messages
|
|
342
|
-
* are checked against the proof — the verifier does not learn the values
|
|
343
|
-
* of undisclosed attributes.
|
|
344
|
-
*
|
|
345
|
-
* @param credential - The derived credential containing a selective disclosure proof.
|
|
346
|
-
* @param issuerPublicKey - The issuer's 96-byte BLS12-381 G2 public key.
|
|
347
|
-
* @returns `true` if the proof is valid.
|
|
348
|
-
*/
|
|
349
|
-
public static async verifyProof(
|
|
350
|
-
credential: BbsVerifiableCredential,
|
|
351
|
-
issuerPublicKey: Uint8Array
|
|
352
|
-
): Promise<boolean> {
|
|
353
|
-
const proof = credential.proof as BbsDerivedProof;
|
|
354
|
-
if (proof.cryptosuite !== 'bbs-2023') {
|
|
355
|
-
throw new Error(`Unsupported cryptosuite: ${proof.cryptosuite}`);
|
|
356
|
-
}
|
|
357
|
-
if (!proof.nonce) {
|
|
358
|
-
throw new Error('Derived proof must contain a nonce');
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
const proofBytes = Convert.base64Url(proof.proofValue).toUint8Array();
|
|
362
|
-
const nonceBytes = ENCODER.encode(proof.nonce);
|
|
363
|
-
|
|
364
|
-
const subject = credential.credentialSubject as Record<string, any>;
|
|
365
|
-
const flatSubject = Array.isArray(subject) ? subject[0] : subject;
|
|
366
|
-
const { messages } = credentialSubjectToMessages(flatSubject);
|
|
367
|
-
|
|
368
|
-
return Bbs.verifyProof({
|
|
369
|
-
publicKey: issuerPublicKey,
|
|
370
|
-
proof: proofBytes,
|
|
371
|
-
messages,
|
|
372
|
-
nonce: nonceBytes,
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
/**
|
|
377
|
-
* Resolves an issuer DID and attempts to extract the BBS+ public key
|
|
378
|
-
* from the DID document's verification methods.
|
|
379
|
-
*
|
|
380
|
-
* @param issuerDid - The DID of the credential issuer.
|
|
381
|
-
* @param kid - Optional key ID fragment to match a specific verification method.
|
|
382
|
-
* @returns The BLS12-381 G2 public key as Uint8Array, or null if not found.
|
|
383
|
-
*/
|
|
384
|
-
public static async resolveIssuerPublicKey(
|
|
385
|
-
issuerDid: string,
|
|
386
|
-
kid?: string
|
|
387
|
-
): Promise<Uint8Array | null> {
|
|
388
|
-
const resolution = await didResolver.resolve(issuerDid);
|
|
389
|
-
const didDocument = resolution?.didDocument;
|
|
390
|
-
if (!didDocument?.verificationMethod) return null;
|
|
391
|
-
|
|
392
|
-
for (const vm of didDocument.verificationMethod) {
|
|
393
|
-
const vmId = vm.id?.includes('#') ? vm.id.split('#')[1] : vm.id;
|
|
394
|
-
|
|
395
|
-
if (kid && vmId !== kid) continue;
|
|
396
|
-
|
|
397
|
-
if (
|
|
398
|
-
vm.type === 'Bls12381G2Key2020' ||
|
|
399
|
-
vm.type === 'JsonWebKey2020' ||
|
|
400
|
-
vm.type === 'Multikey'
|
|
401
|
-
) {
|
|
402
|
-
if (vm.publicKeyMultibase) {
|
|
403
|
-
// Multibase z-prefix = base58btc
|
|
404
|
-
if (vm.publicKeyMultibase.startsWith('z')) {
|
|
405
|
-
return Convert.base58Btc(vm.publicKeyMultibase.slice(1)).toUint8Array();
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
if (vm.publicKeyJwk) {
|
|
409
|
-
const jwk = vm.publicKeyJwk as any;
|
|
410
|
-
if (jwk.x) {
|
|
411
|
-
return Convert.base64Url(jwk.x).toUint8Array();
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
return null;
|
|
418
|
-
}
|
|
419
|
-
}
|