@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,183 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
generateBls12381G2KeyPair,
|
|
3
|
-
blsSign,
|
|
4
|
-
blsVerify,
|
|
5
|
-
blsCreateProof,
|
|
6
|
-
blsVerifyProof,
|
|
7
|
-
} from '@mattrglobal/bbs-signatures';
|
|
8
|
-
|
|
9
|
-
export interface BbsKeyPair {
|
|
10
|
-
publicKey: Uint8Array;
|
|
11
|
-
secretKey: Uint8Array;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* The `Bbs` class provides an interface for BBS+ signature operations
|
|
16
|
-
* using the BLS12-381 pairing-friendly curve.
|
|
17
|
-
*
|
|
18
|
-
* BBS+ signatures enable multi-message signing where each attribute of
|
|
19
|
-
* a credential is signed as a separate message. This allows a holder
|
|
20
|
-
* to derive a zero-knowledge proof that selectively discloses only
|
|
21
|
-
* chosen attributes without revealing the full signed message set.
|
|
22
|
-
*
|
|
23
|
-
* Example usage:
|
|
24
|
-
*
|
|
25
|
-
* ```ts
|
|
26
|
-
* const keyPair = await Bbs.generateKeyPair();
|
|
27
|
-
* const messages = [
|
|
28
|
-
* new TextEncoder().encode('age=25'),
|
|
29
|
-
* new TextEncoder().encode('country=US'),
|
|
30
|
-
* ];
|
|
31
|
-
* const signature = await Bbs.sign({ keyPair, messages });
|
|
32
|
-
*
|
|
33
|
-
* const proof = await Bbs.createProof({
|
|
34
|
-
* publicKey: keyPair.publicKey,
|
|
35
|
-
* signature,
|
|
36
|
-
* messages,
|
|
37
|
-
* revealed: [1],
|
|
38
|
-
* nonce: new TextEncoder().encode('unique-nonce'),
|
|
39
|
-
* });
|
|
40
|
-
*
|
|
41
|
-
* const isValid = await Bbs.verifyProof({
|
|
42
|
-
* publicKey: keyPair.publicKey,
|
|
43
|
-
* proof,
|
|
44
|
-
* messages: [messages[1]],
|
|
45
|
-
* nonce: new TextEncoder().encode('unique-nonce'),
|
|
46
|
-
* });
|
|
47
|
-
* ```
|
|
48
|
-
*/
|
|
49
|
-
export class Bbs {
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Generates a BLS12-381 G2 key pair suitable for BBS+ signatures.
|
|
53
|
-
*
|
|
54
|
-
* @returns A Promise resolving to a `BbsKeyPair` with 96-byte public key and 32-byte secret key.
|
|
55
|
-
*/
|
|
56
|
-
public static async generateKeyPair(): Promise<BbsKeyPair> {
|
|
57
|
-
const keyPair = await generateBls12381G2KeyPair();
|
|
58
|
-
return {
|
|
59
|
-
publicKey: keyPair.publicKey,
|
|
60
|
-
secretKey: keyPair.secretKey,
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Signs a set of messages using BBS+ producing a single 112-byte signature.
|
|
66
|
-
* Each message is treated as a distinct attribute that can later be
|
|
67
|
-
* individually disclosed or hidden via `createProof`.
|
|
68
|
-
*
|
|
69
|
-
* @param options.keyPair - The BLS12-381 key pair (publicKey + secretKey).
|
|
70
|
-
* @param options.messages - Array of messages (Uint8Array) to sign.
|
|
71
|
-
* @returns A Promise resolving to the BBS+ signature as a Uint8Array.
|
|
72
|
-
*/
|
|
73
|
-
public static async sign(options: {
|
|
74
|
-
keyPair: BbsKeyPair;
|
|
75
|
-
messages: Uint8Array[];
|
|
76
|
-
}): Promise<Uint8Array> {
|
|
77
|
-
const { keyPair, messages } = options;
|
|
78
|
-
|
|
79
|
-
if (!messages || messages.length === 0) {
|
|
80
|
-
throw new Error('At least one message is required for BBS+ signing');
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const signature = await blsSign({
|
|
84
|
-
keyPair: {
|
|
85
|
-
publicKey: keyPair.publicKey,
|
|
86
|
-
secretKey: keyPair.secretKey,
|
|
87
|
-
},
|
|
88
|
-
messages,
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
return signature;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Verifies a BBS+ signature against the full set of original messages.
|
|
96
|
-
*
|
|
97
|
-
* @param options.publicKey - The 96-byte BLS12-381 G2 public key.
|
|
98
|
-
* @param options.signature - The 112-byte BBS+ signature.
|
|
99
|
-
* @param options.messages - The complete set of messages that were signed.
|
|
100
|
-
* @returns A Promise resolving to `true` if the signature is valid.
|
|
101
|
-
*/
|
|
102
|
-
public static async verify(options: {
|
|
103
|
-
publicKey: Uint8Array;
|
|
104
|
-
signature: Uint8Array;
|
|
105
|
-
messages: Uint8Array[];
|
|
106
|
-
}): Promise<boolean> {
|
|
107
|
-
const { publicKey, signature, messages } = options;
|
|
108
|
-
|
|
109
|
-
const result = await blsVerify({
|
|
110
|
-
publicKey,
|
|
111
|
-
signature,
|
|
112
|
-
messages,
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
return result.verified;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Derives a zero-knowledge proof from a BBS+ signature that selectively
|
|
120
|
-
* discloses only the messages at the specified indices. The prover
|
|
121
|
-
* demonstrates knowledge of the full signature without revealing
|
|
122
|
-
* hidden messages.
|
|
123
|
-
*
|
|
124
|
-
* @param options.publicKey - The issuer's 96-byte BLS12-381 G2 public key.
|
|
125
|
-
* @param options.signature - The original 112-byte BBS+ signature.
|
|
126
|
-
* @param options.messages - The complete set of messages that were signed.
|
|
127
|
-
* @param options.revealed - Array of zero-based indices indicating which messages to disclose.
|
|
128
|
-
* @param options.nonce - A unique nonce to bind the proof to a specific verification session.
|
|
129
|
-
* @returns A Promise resolving to the derived proof as a Uint8Array.
|
|
130
|
-
*/
|
|
131
|
-
public static async createProof(options: {
|
|
132
|
-
publicKey: Uint8Array;
|
|
133
|
-
signature: Uint8Array;
|
|
134
|
-
messages: Uint8Array[];
|
|
135
|
-
revealed: number[];
|
|
136
|
-
nonce: Uint8Array;
|
|
137
|
-
}): Promise<Uint8Array> {
|
|
138
|
-
const { publicKey, signature, messages, revealed, nonce } = options;
|
|
139
|
-
|
|
140
|
-
if (!nonce || nonce.length === 0) {
|
|
141
|
-
throw new Error('A nonce is required for proof creation to prevent replay attacks');
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const proof = await blsCreateProof({
|
|
145
|
-
signature,
|
|
146
|
-
publicKey,
|
|
147
|
-
messages,
|
|
148
|
-
nonce,
|
|
149
|
-
revealed,
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
return proof;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Verifies a BBS+ zero-knowledge selective disclosure proof.
|
|
157
|
-
* Only the disclosed messages (those at the `revealed` indices during
|
|
158
|
-
* proof creation) should be provided.
|
|
159
|
-
*
|
|
160
|
-
* @param options.publicKey - The issuer's 96-byte BLS12-381 G2 public key.
|
|
161
|
-
* @param options.proof - The derived proof from `createProof`.
|
|
162
|
-
* @param options.messages - Only the disclosed messages, in order of their original indices.
|
|
163
|
-
* @param options.nonce - The same nonce used during proof creation.
|
|
164
|
-
* @returns A Promise resolving to `true` if the proof is valid.
|
|
165
|
-
*/
|
|
166
|
-
public static async verifyProof(options: {
|
|
167
|
-
publicKey: Uint8Array;
|
|
168
|
-
proof: Uint8Array;
|
|
169
|
-
messages: Uint8Array[];
|
|
170
|
-
nonce: Uint8Array;
|
|
171
|
-
}): Promise<boolean> {
|
|
172
|
-
const { publicKey, proof, messages, nonce } = options;
|
|
173
|
-
|
|
174
|
-
const result = await blsVerifyProof({
|
|
175
|
-
proof,
|
|
176
|
-
publicKey,
|
|
177
|
-
messages,
|
|
178
|
-
nonce,
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
return result.verified;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import { sha256 } from '@noble/hashes/sha256';
|
|
2
|
-
import { Convert, universalTypeOf } from '../../common/index.js';
|
|
3
|
-
import { TypedArray, concatBytes } from '@noble/hashes/utils';
|
|
4
|
-
|
|
5
|
-
import { NotSupportedError } from '../algorithms-api/errors.js';
|
|
6
|
-
|
|
7
|
-
export type ConcatKdfOtherInfo = {
|
|
8
|
-
/**
|
|
9
|
-
* The algorithm the derived secret keying material will be used with.
|
|
10
|
-
*/
|
|
11
|
-
algorithmId: string;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Information related to party U (initiator) involved in the key agreement
|
|
15
|
-
* transaction. It could be a public key, identifier, or any other data.
|
|
16
|
-
*/
|
|
17
|
-
partyUInfo: string | TypedArray;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Information related to party V (receiver) involved in the key
|
|
21
|
-
* agreement transaction. Similar to partyUInfo, it could be a
|
|
22
|
-
* public key, identifier, etc.
|
|
23
|
-
*/
|
|
24
|
-
partyVInfo: string | TypedArray;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Optional field. It is usually used to ensure the uniqueness of the
|
|
28
|
-
* derived keying material when the input keying material is used in
|
|
29
|
-
* multiple key-derivation key-agreement transactions. It is usually
|
|
30
|
-
* a public value such as the keyDataLen.
|
|
31
|
-
*/
|
|
32
|
-
suppPubInfo?: number;
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Optional field. It is used when it is desired to secretively
|
|
36
|
-
* bind additional information into the derived keying material.
|
|
37
|
-
* It is a secret value agreed upon by the entities who are party
|
|
38
|
-
* to the key agreement.
|
|
39
|
-
*/
|
|
40
|
-
suppPrivInfo?: string | TypedArray;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* An implementation of the Concatenation Key Derivation Function (ConcatKDF)
|
|
45
|
-
* as specified in NIST.800-56A, a single-step key-derivation function (SSKDF).
|
|
46
|
-
* ConcatKDF produces a derived key from a secret key (like a shared secret
|
|
47
|
-
* from ECDH), and other optional public information. This implementation
|
|
48
|
-
* specifically uses SHA-256 as the pseudorandom function (PRF).
|
|
49
|
-
*
|
|
50
|
-
* @see {@link https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar3.pdf | NIST.800-56A}
|
|
51
|
-
* @see {@link https://datatracker.ietf.org/doc/html/rfc7518#section-4.6.2 | RFC 7518 Section 4.6.2}
|
|
52
|
-
*
|
|
53
|
-
* Note: This implementation allows for only a single round / repetition
|
|
54
|
-
* using the function K(1) = H(counter || Z || OtherInfo), where:
|
|
55
|
-
* K(1) is the derived key material after one round
|
|
56
|
-
* H is the SHA-256 hashing function
|
|
57
|
-
* counter is a 32-bit, big-endian bit string counter set to 0x00000001
|
|
58
|
-
* Z is the shared secret value obtained from a key agreement protocol
|
|
59
|
-
* OtherInfo is a bit string used to ensure that the derived keying
|
|
60
|
-
* material is adequately "bound" to the key-agreement transaction.
|
|
61
|
-
*
|
|
62
|
-
* Additional Information:
|
|
63
|
-
*
|
|
64
|
-
* Z, or "shared secret":
|
|
65
|
-
* The shared secret value obtained from a key agreement protocol, such as
|
|
66
|
-
* Diffie-Hellman, ECDH (Elliptic Curve Diffie-Hellman). Importantly, this
|
|
67
|
-
* shared secret is not directly used as the encryption or authentication
|
|
68
|
-
* key, but as an input to a key derivation function (KDF), such as Concat
|
|
69
|
-
* KDF, to generate the actual key. This adds an extra layer of security, as
|
|
70
|
-
* even if the shared secret gets compromised, the actual encryption or
|
|
71
|
-
* authentication key stays safe. This shared secret 'Z' value is kept
|
|
72
|
-
* confidential between the two parties in the key agreement protocol.
|
|
73
|
-
*/
|
|
74
|
-
export class ConcatKdf {
|
|
75
|
-
/**
|
|
76
|
-
* Derives a key of a specified length from the input parameters.
|
|
77
|
-
*
|
|
78
|
-
* @param options - Input parameters for key derivation.
|
|
79
|
-
* @param options.keyDataLen - The desired length of the derived key in bits.
|
|
80
|
-
* @param options.sharedSecret - The shared secret key to derive from.
|
|
81
|
-
* @param options.otherInfo - Additional public information to use in key derivation.
|
|
82
|
-
* @returns The derived key as a Uint8Array.
|
|
83
|
-
*
|
|
84
|
-
* @throws {NotSupportedError} If the keyDataLen would require multiple rounds.
|
|
85
|
-
*/
|
|
86
|
-
public static async deriveKey(options: {
|
|
87
|
-
keyDataLen: number;
|
|
88
|
-
otherInfo: ConcatKdfOtherInfo,
|
|
89
|
-
sharedSecret: Uint8Array,
|
|
90
|
-
}): Promise<Uint8Array> {
|
|
91
|
-
const { keyDataLen, sharedSecret } = options;
|
|
92
|
-
|
|
93
|
-
// RFC 7518 Section 4.6.2 specifies using SHA-256 for ECDH key agreement:
|
|
94
|
-
// "Key derivation is performed using the Concat KDF, as defined in
|
|
95
|
-
// Section 5.8.1 of [NIST.800-56A], where the Digest Method is SHA-256."
|
|
96
|
-
// Reference: https://tools.ietf.org/html/rfc7518#section-4.6.2
|
|
97
|
-
const hashLen = 256;
|
|
98
|
-
|
|
99
|
-
// This implementation only supports single round Concat KDF.
|
|
100
|
-
const roundCount = Math.ceil(keyDataLen / hashLen);
|
|
101
|
-
if (roundCount !== 1) {
|
|
102
|
-
throw new NotSupportedError(`Concat KDF with ${roundCount} rounds not supported.`);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Initialize a 32-bit, big-endian bit string counter as 0x00000001.
|
|
106
|
-
const counter = new Uint8Array(4);
|
|
107
|
-
new DataView(counter.buffer).setUint32(0, roundCount);
|
|
108
|
-
|
|
109
|
-
// Compute the OtherInfo bit-string.
|
|
110
|
-
const otherInfo = ConcatKdf.computeOtherInfo(options.otherInfo);
|
|
111
|
-
|
|
112
|
-
// Compute K(i) = H(counter || Z || OtherInfo)
|
|
113
|
-
// return concatBytes(counter, sharedSecretZ, otherInfo);
|
|
114
|
-
const derivedKeyingMaterial = sha256(concatBytes(counter, sharedSecret, otherInfo));
|
|
115
|
-
|
|
116
|
-
// Return the bit string of derived keying material of length keyDataLen bits.
|
|
117
|
-
return derivedKeyingMaterial.slice(0, keyDataLen / 8);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Computes the OtherInfo parameter as specified in NIST.800-56A.
|
|
122
|
-
* OtherInfo binds the derived key material to the context of the
|
|
123
|
-
* key agreement transaction.
|
|
124
|
-
*
|
|
125
|
-
* This implementation follows the recommended format for OtherInfo
|
|
126
|
-
* specified in section 5.8.1.2.1 of the NIST.800-56A publication.
|
|
127
|
-
*
|
|
128
|
-
* OtherInfo is a bit string equal to the following concatenation:
|
|
129
|
-
* AlgorithmID || PartyUInfo || PartyVInfo {|| SuppPubInfo }{|| SuppPrivInfo }
|
|
130
|
-
*
|
|
131
|
-
* SuppPubInfo is the key length in bits, big endian encoded as a
|
|
132
|
-
* 32-bit number. For example, 128 would be [0, 0, 0, 128] and
|
|
133
|
-
* 256 would be [0, 0, 1, 0].
|
|
134
|
-
*
|
|
135
|
-
* @param options - Input data to construct OtherInfo.
|
|
136
|
-
|
|
137
|
-
* @returns OtherInfo as a Uint8Array.
|
|
138
|
-
*/
|
|
139
|
-
private static computeOtherInfo(options:
|
|
140
|
-
ConcatKdfOtherInfo
|
|
141
|
-
): Uint8Array {
|
|
142
|
-
// Required sub-fields.
|
|
143
|
-
const algorithmId = ConcatKdf.toDataLenData({ data: options.algorithmId });
|
|
144
|
-
const partyUInfo = ConcatKdf.toDataLenData({ data: options.partyUInfo });
|
|
145
|
-
const partyVInfo = ConcatKdf.toDataLenData({ data: options.partyVInfo });
|
|
146
|
-
// Optional sub-fields.
|
|
147
|
-
const suppPubInfo = ConcatKdf.toDataLenData({ data: options.suppPubInfo, variableLength: false });
|
|
148
|
-
const suppPrivInfo = ConcatKdf.toDataLenData({ data: options.suppPrivInfo });
|
|
149
|
-
|
|
150
|
-
// Concatenate AlgorithmID || PartyUInfo || PartyVInfo || SuppPubInfo || SuppPrivInfo.
|
|
151
|
-
const otherInfo = concatBytes(algorithmId, partyUInfo, partyVInfo, suppPubInfo, suppPrivInfo);
|
|
152
|
-
|
|
153
|
-
return otherInfo;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Encodes input data as a length-prefixed byte string, or
|
|
158
|
-
* as a fixed-length bit string if specified.
|
|
159
|
-
*
|
|
160
|
-
* If variableLength = true, return the data in the form Datalen || Data,
|
|
161
|
-
* where Data is a variable-length string of zero or more (eight-bit)
|
|
162
|
-
* bytes, and Datalen is a fixed-length, big-endian counter that
|
|
163
|
-
* indicates the length (in bytes) of Data.
|
|
164
|
-
*
|
|
165
|
-
* If variableLength = false, return the data formatted as a
|
|
166
|
-
* fixed-length bit string.
|
|
167
|
-
*
|
|
168
|
-
* @param options - Input data and options for the conversion.
|
|
169
|
-
* @param options.data - The input data to encode. Must be a type convertible to Uint8Array by the Convert class.
|
|
170
|
-
* @param options.variableLength - Whether to output the data as variable length. Default is true.
|
|
171
|
-
* @returns The input data encoded as a Uint8Array.
|
|
172
|
-
*
|
|
173
|
-
* @throws {TypeError} If fixed-length data is not a number.
|
|
174
|
-
*/
|
|
175
|
-
private static toDataLenData(options: {
|
|
176
|
-
data: unknown,
|
|
177
|
-
variableLength?: boolean
|
|
178
|
-
}): Uint8Array {
|
|
179
|
-
const { data, variableLength = true } = options;
|
|
180
|
-
let encodedData: Uint8Array;
|
|
181
|
-
const dataType = universalTypeOf(data);
|
|
182
|
-
|
|
183
|
-
// Return an emtpy octet sequence if data is not specified.
|
|
184
|
-
if (dataType === 'Undefined') {
|
|
185
|
-
return new Uint8Array(0);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if (variableLength) {
|
|
189
|
-
const dataU8A = (dataType === 'Uint8Array')
|
|
190
|
-
? data as Uint8Array
|
|
191
|
-
: new Convert(data, dataType).toUint8Array();
|
|
192
|
-
const bufferLength = dataU8A.length;
|
|
193
|
-
encodedData = new Uint8Array(4 + bufferLength);
|
|
194
|
-
new DataView(encodedData.buffer).setUint32(0, bufferLength);
|
|
195
|
-
encodedData.set(dataU8A, 4);
|
|
196
|
-
|
|
197
|
-
} else {
|
|
198
|
-
if (typeof data !== 'number') {
|
|
199
|
-
throw TypeError('Fixed length input must be a number.');
|
|
200
|
-
}
|
|
201
|
-
encodedData = new Uint8Array(4);
|
|
202
|
-
new DataView(encodedData.buffer).setUint32(0, data);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
return encodedData;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
import type { BytesKeyPair } from '../types/crypto-key.js';
|
|
2
|
-
|
|
3
|
-
import { ed25519, edwardsToMontgomeryPub, edwardsToMontgomeryPriv } from '@noble/curves/ed25519';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* The `Ed25519` class provides an interface for generating Ed25519 key pairs,
|
|
7
|
-
* computing public keys from private keys, and signing and verifying messages.
|
|
8
|
-
*
|
|
9
|
-
* The class uses the '@noble/curves' package for the cryptographic operations.
|
|
10
|
-
*
|
|
11
|
-
* The methods of this class are all asynchronous and return Promises. They all use
|
|
12
|
-
* the Uint8Array type for keys, signatures, and data, providing a consistent
|
|
13
|
-
* interface for working with binary data.
|
|
14
|
-
*
|
|
15
|
-
* Example usage:
|
|
16
|
-
*
|
|
17
|
-
* ```ts
|
|
18
|
-
* const keyPair = await Ed25519.generateKeyPair();
|
|
19
|
-
* const message = new TextEncoder().encode('Hello, world!');
|
|
20
|
-
* const signature = await Ed25519.sign({
|
|
21
|
-
* key: keyPair.privateKey,
|
|
22
|
-
* data: message
|
|
23
|
-
* });
|
|
24
|
-
* const isValid = await Ed25519.verify({
|
|
25
|
-
* key: keyPair.publicKey,
|
|
26
|
-
* signature,
|
|
27
|
-
* data: message
|
|
28
|
-
* });
|
|
29
|
-
* console.log(isValid); // true
|
|
30
|
-
* ```
|
|
31
|
-
*/
|
|
32
|
-
export class Ed25519 {
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Converts an Ed25519 private key to its X25519 counterpart.
|
|
36
|
-
*
|
|
37
|
-
* Similar to the public key conversion, this method aids in transitioning
|
|
38
|
-
* from signing to encryption operations. By converting an Ed25519 private
|
|
39
|
-
* key to X25519 format, one can use the same key pair for both digital
|
|
40
|
-
* signatures and key exchange operations.
|
|
41
|
-
*
|
|
42
|
-
* @param options - The options for the conversion.
|
|
43
|
-
* @param options.privateKey - The Ed25519 private key to convert, represented as a Uint8Array.
|
|
44
|
-
* @returns A Promise that resolves to the X25519 private key as a Uint8Array.
|
|
45
|
-
*/
|
|
46
|
-
public static async convertPrivateKeyToX25519(options: {
|
|
47
|
-
privateKey: Uint8Array
|
|
48
|
-
}): Promise<Uint8Array> {
|
|
49
|
-
const { privateKey } = options;
|
|
50
|
-
|
|
51
|
-
// Converts Ed25519 private key to X25519 private key.
|
|
52
|
-
const montgomeryPrivateKey = edwardsToMontgomeryPriv(privateKey);
|
|
53
|
-
|
|
54
|
-
return montgomeryPrivateKey;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Converts an Ed25519 public key to its X25519 counterpart.
|
|
59
|
-
*
|
|
60
|
-
* This method is useful when transitioning from signing to encryption
|
|
61
|
-
* operations, as Ed25519 and X25519 keys share the same mathematical
|
|
62
|
-
* foundation but serve different purposes. Ed25519 keys are used for
|
|
63
|
-
* digital signatures, while X25519 keys are used for key exchange in
|
|
64
|
-
* encryption protocols like Diffie-Hellman.
|
|
65
|
-
*
|
|
66
|
-
* @param options - The options for the conversion.
|
|
67
|
-
* @param options.publicKey - The Ed25519 public key to convert, represented as a Uint8Array.
|
|
68
|
-
* @returns A Promise that resolves to the X25519 public key as a Uint8Array.
|
|
69
|
-
*/
|
|
70
|
-
public static async convertPublicKeyToX25519(options: {
|
|
71
|
-
publicKey: Uint8Array
|
|
72
|
-
}): Promise<Uint8Array> {
|
|
73
|
-
const { publicKey } = options;
|
|
74
|
-
|
|
75
|
-
// Verify Edwards public key is valid.
|
|
76
|
-
const isValid = await Ed25519.validatePublicKey({ key: publicKey });
|
|
77
|
-
if (!isValid) {
|
|
78
|
-
throw new Error('Ed25519: Invalid public key.');
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Converts Ed25519 public key to X25519 public key.
|
|
82
|
-
const montgomeryPublicKey = edwardsToMontgomeryPub(publicKey);
|
|
83
|
-
|
|
84
|
-
return montgomeryPublicKey;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Generates an Ed25519 key pair.
|
|
89
|
-
*
|
|
90
|
-
* @returns A Promise that resolves to an object containing the private and public keys as Uint8Array.
|
|
91
|
-
*/
|
|
92
|
-
public static async generateKeyPair(): Promise<BytesKeyPair> {
|
|
93
|
-
// Generate the private key and compute its public key.
|
|
94
|
-
const privateKey = ed25519.utils.randomPrivateKey();
|
|
95
|
-
const publicKey = ed25519.getPublicKey(privateKey);
|
|
96
|
-
|
|
97
|
-
const keyPair = {
|
|
98
|
-
privateKey : privateKey,
|
|
99
|
-
publicKey : publicKey
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
return keyPair;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Computes the public key from a given private key.
|
|
107
|
-
*
|
|
108
|
-
* @param options - The options for the public key computation.
|
|
109
|
-
* @param options.privateKey - The 32-byte private key from which to compute the public key.
|
|
110
|
-
* @returns A Promise that resolves to the computed 32-byte public key as a Uint8Array.
|
|
111
|
-
*/
|
|
112
|
-
public static async getPublicKey(options: {
|
|
113
|
-
privateKey: Uint8Array
|
|
114
|
-
}): Promise<Uint8Array> {
|
|
115
|
-
let { privateKey } = options;
|
|
116
|
-
|
|
117
|
-
// Compute public key.
|
|
118
|
-
const publicKey = ed25519.getPublicKey(privateKey);
|
|
119
|
-
|
|
120
|
-
return publicKey;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Generates a RFC8032 EdDSA signature of given data with a given private key.
|
|
125
|
-
*
|
|
126
|
-
* @param options - The options for the signing operation.
|
|
127
|
-
* @param options.key - The private key to use for signing.
|
|
128
|
-
* @param options.data - The data to sign.
|
|
129
|
-
* @returns A Promise that resolves to the signature as a Uint8Array.
|
|
130
|
-
*/
|
|
131
|
-
public static async sign(options: {
|
|
132
|
-
data: Uint8Array,
|
|
133
|
-
key: Uint8Array
|
|
134
|
-
}): Promise<Uint8Array> {
|
|
135
|
-
const { key, data } = options;
|
|
136
|
-
|
|
137
|
-
// Signature operation.
|
|
138
|
-
const signature = ed25519.sign(data, key);
|
|
139
|
-
|
|
140
|
-
return signature;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Validates a given public key to ensure that it corresponds to a
|
|
145
|
-
* valid point on the Ed25519 elliptic curve.
|
|
146
|
-
*
|
|
147
|
-
* This method decodes the Edwards points from the key bytes and
|
|
148
|
-
* asserts their validity on the curve. If the points are not valid,
|
|
149
|
-
* the method returns false. If the points are valid, the method
|
|
150
|
-
* returns true.
|
|
151
|
-
*
|
|
152
|
-
* Note: This method does not check whether the key corresponds to a
|
|
153
|
-
* known or authorized entity, or whether it has been compromised.
|
|
154
|
-
* It only checks the mathematical validity of the key.
|
|
155
|
-
*
|
|
156
|
-
* @param options - The options for the key validation.
|
|
157
|
-
* @param options.key - The key to validate, represented as a Uint8Array.
|
|
158
|
-
* @returns A Promise that resolves to a boolean indicating whether the key
|
|
159
|
-
* corresponds to a valid point on the Edwards curve.
|
|
160
|
-
*/
|
|
161
|
-
public static async validatePublicKey(options: {
|
|
162
|
-
key: Uint8Array
|
|
163
|
-
}): Promise<boolean> {
|
|
164
|
-
const { key } = options;
|
|
165
|
-
|
|
166
|
-
try {
|
|
167
|
-
// Decode Edwards points from key bytes.
|
|
168
|
-
const point = ed25519.ExtendedPoint.fromHex(key);
|
|
169
|
-
|
|
170
|
-
// Check if points are on the Twisted Edwards curve.
|
|
171
|
-
point.assertValidity();
|
|
172
|
-
|
|
173
|
-
} catch(error: any) {
|
|
174
|
-
return false;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
return true;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Verifies a RFC8032 EdDSA signature of given data with a given public key.
|
|
182
|
-
*
|
|
183
|
-
* @param options - The options for the verification operation.
|
|
184
|
-
* @param options.key - The public key to use for verification.
|
|
185
|
-
* @param options.signature - The signature to verify.
|
|
186
|
-
* @param options.data - The data that was signed.
|
|
187
|
-
* @returns A Promise that resolves to a boolean indicating whether the signature is valid.
|
|
188
|
-
*/
|
|
189
|
-
public static async verify(options: {
|
|
190
|
-
data: Uint8Array,
|
|
191
|
-
key: Uint8Array,
|
|
192
|
-
signature: Uint8Array
|
|
193
|
-
}): Promise<boolean> {
|
|
194
|
-
const { key, signature, data } = options;
|
|
195
|
-
|
|
196
|
-
// Verify operation.
|
|
197
|
-
const isValid = ed25519.verify(signature, data, key);
|
|
198
|
-
|
|
199
|
-
return isValid;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export * from './bbs.js';
|
|
2
|
-
export * from './pbkdf2.js';
|
|
3
|
-
export * from './x25519.js';
|
|
4
|
-
export * from './aes-ctr.js';
|
|
5
|
-
export * from './aes-gcm.js';
|
|
6
|
-
export * from './ed25519.js';
|
|
7
|
-
export * from './concat-kdf.js';
|
|
8
|
-
export * from './secp256k1.js';
|
|
9
|
-
export * from './xchacha20.js';
|
|
10
|
-
export * from './xchacha20-poly1305.js';
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { crypto } from '@noble/hashes/crypto';
|
|
2
|
-
|
|
3
|
-
import { isWebCryptoSupported } from '../utils.js';
|
|
4
|
-
|
|
5
|
-
type DeriveKeyOptions = {
|
|
6
|
-
hash: 'SHA-256' | 'SHA-384' | 'SHA-512',
|
|
7
|
-
password: Uint8Array,
|
|
8
|
-
salt: Uint8Array,
|
|
9
|
-
iterations: number,
|
|
10
|
-
length: number
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export class Pbkdf2 {
|
|
14
|
-
public static async deriveKey(options: DeriveKeyOptions): Promise<Uint8Array> {
|
|
15
|
-
if (isWebCryptoSupported()) {
|
|
16
|
-
return Pbkdf2.deriveKeyWithWebCrypto(options);
|
|
17
|
-
} else {
|
|
18
|
-
return Pbkdf2.deriveKeyWithNodeCrypto(options);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
private static async deriveKeyWithNodeCrypto(options: DeriveKeyOptions): Promise<Uint8Array> {
|
|
23
|
-
const { password, salt, iterations } = options;
|
|
24
|
-
|
|
25
|
-
// Map the hash string to the node:crypto equivalent.
|
|
26
|
-
const hashToNodeCryptoMap = {
|
|
27
|
-
'SHA-256' : 'sha256',
|
|
28
|
-
'SHA-384' : 'sha384',
|
|
29
|
-
'SHA-512' : 'sha512'
|
|
30
|
-
};
|
|
31
|
-
const hash = hashToNodeCryptoMap[options.hash];
|
|
32
|
-
|
|
33
|
-
// Convert length from bits to bytes.
|
|
34
|
-
const length = options.length / 8;
|
|
35
|
-
|
|
36
|
-
// Dynamically import the `crypto` package.
|
|
37
|
-
const { pbkdf2 } = await import('node:crypto');
|
|
38
|
-
|
|
39
|
-
return new Promise((resolve) => {
|
|
40
|
-
pbkdf2(
|
|
41
|
-
password,
|
|
42
|
-
salt,
|
|
43
|
-
iterations,
|
|
44
|
-
length,
|
|
45
|
-
hash,
|
|
46
|
-
(err, derivedKey) => {
|
|
47
|
-
if (!err) {
|
|
48
|
-
resolve(new Uint8Array(derivedKey));
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
);
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
private static async deriveKeyWithWebCrypto(options: DeriveKeyOptions): Promise<Uint8Array> {
|
|
56
|
-
const { hash, password, salt, iterations, length } = options;
|
|
57
|
-
|
|
58
|
-
// Import the password as a raw key for use with the Web Crypto API.
|
|
59
|
-
const webCryptoKey = await crypto.subtle.importKey(
|
|
60
|
-
'raw',
|
|
61
|
-
password,
|
|
62
|
-
{ name: 'PBKDF2' },
|
|
63
|
-
false,
|
|
64
|
-
['deriveBits']
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
const derivedKeyBuffer = await crypto.subtle.deriveBits(
|
|
68
|
-
{ name: 'PBKDF2', hash, salt, iterations },
|
|
69
|
-
webCryptoKey,
|
|
70
|
-
length
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
// Convert from ArrayBuffer to Uint8Array.
|
|
74
|
-
const derivedKey = new Uint8Array(derivedKeyBuffer);
|
|
75
|
-
|
|
76
|
-
return derivedKey;
|
|
77
|
-
}
|
|
78
|
-
}
|