@ocap/mcrypto 1.18.166 → 1.19.1

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.
Files changed (42) hide show
  1. package/README.md +7 -7
  2. package/esm/crypter/aes-legacy.d.ts +8 -0
  3. package/esm/crypter/aes-legacy.js +26 -0
  4. package/esm/crypter/aes.d.ts +9 -0
  5. package/esm/crypter/aes.js +25 -0
  6. package/esm/crypter/rsa-browserify.d.ts +9 -0
  7. package/esm/crypter/rsa-browserify.js +33 -0
  8. package/esm/crypter/rsa.d.ts +11 -0
  9. package/esm/crypter/rsa.js +28 -0
  10. package/esm/encode.d.ts +8 -0
  11. package/esm/encode.js +19 -0
  12. package/esm/hasher/keccak.d.ts +13 -0
  13. package/esm/hasher/keccak.js +37 -0
  14. package/esm/hasher/sha2.d.ts +13 -0
  15. package/esm/hasher/sha2.js +43 -0
  16. package/esm/hasher/sha3.d.ts +13 -0
  17. package/esm/hasher/sha3.js +37 -0
  18. package/esm/index.d.ts +233 -0
  19. package/esm/index.js +219 -0
  20. package/esm/protocols/crypter.d.ts +2 -0
  21. package/esm/protocols/crypter.js +4 -0
  22. package/esm/protocols/hasher.d.ts +2 -0
  23. package/esm/protocols/hasher.js +4 -0
  24. package/esm/protocols/signer.d.ts +2 -0
  25. package/esm/protocols/signer.js +4 -0
  26. package/esm/signer/ed25519.d.ts +53 -0
  27. package/esm/signer/ed25519.js +82 -0
  28. package/esm/signer/ethereum.d.ts +16 -0
  29. package/esm/signer/ethereum.js +35 -0
  30. package/esm/signer/passkey.d.ts +27 -0
  31. package/esm/signer/passkey.js +59 -0
  32. package/esm/signer/secp256k1.d.ts +39 -0
  33. package/esm/signer/secp256k1.js +95 -0
  34. package/lib/crypter/rsa-browserify.js +1 -1
  35. package/lib/crypter/rsa.d.ts +0 -1
  36. package/lib/encode.d.ts +0 -1
  37. package/lib/encode.js +1 -2
  38. package/lib/index.d.ts +9 -7
  39. package/lib/index.js +9 -4
  40. package/lib/signer/passkey.d.ts +27 -0
  41. package/lib/signer/passkey.js +65 -0
  42. package/package.json +29 -14
package/esm/index.js ADDED
@@ -0,0 +1,219 @@
1
+ import randomBytes from 'randombytes';
2
+ import { encode } from './encode';
3
+ import keccak from './hasher/keccak';
4
+ import sha2 from './hasher/sha2';
5
+ import sha3 from './hasher/sha3';
6
+ import ed25519 from './signer/ed25519';
7
+ import ethereum from './signer/ethereum';
8
+ import secp256k1 from './signer/secp256k1';
9
+ import passkey from './signer/passkey';
10
+ /**
11
+ * Contains all supported signers, eg: `Ed25519` and `Secp256k1`
12
+ *
13
+ * @readonly
14
+ * @type {object}
15
+ * @name Signer
16
+ * @static
17
+ * @example
18
+ * const { Signer } = require('@ocap/mcrypto');
19
+ * const message = 'some message to sign';
20
+ *
21
+ * // Use Signer directly
22
+ * const keyPair = Signer.Ed25519.genKeyPair();
23
+ * const signature = Signer.Ed25519.sign(message, keyPair.secretKey);
24
+ * const result = Signer.Ed25519.verify(message, signature, keyPair.publicKey);
25
+ * assert.ok(result);
26
+ */
27
+ export const Signer = {
28
+ Ed25519: ed25519,
29
+ Secp256k1: secp256k1,
30
+ Ethereum: ethereum,
31
+ Passkey: passkey,
32
+ };
33
+ /**
34
+ * Contains all supported hasher, eg: `SHA2`,`SHA3` and `Keccak`, each of them supports `hash224`, `hash256`, `hash384`, `hash512`
35
+ *
36
+ * @readonly
37
+ * @type {object}
38
+ * @name Hasher
39
+ * @static
40
+ * @example
41
+ * const { Hasher } = require('@ocap/mcrypto');
42
+ *
43
+ * const message = 'message to hash';
44
+ * const hash = Hasher.SHA2.hash256(message);
45
+ */
46
+ export const Hasher = {
47
+ SHA2: sha2,
48
+ SHA3: sha3,
49
+ Keccak: keccak,
50
+ };
51
+ /**
52
+ * Contains type constants that represent can be used to compose different crypto method, each crypto method consist one of:
53
+ * FIXME: enum definition of forge-abi and abt-did-elixir are not exactly the same
54
+ *
55
+ * @readonly
56
+ * @type {object}
57
+ * @name types
58
+ * @static
59
+ * @example
60
+ * const { types } = require('@ocap/mcrypto');
61
+ *
62
+ * // types.RoleType.ROLE_ACCOUNT
63
+ * // types.KeyType.ED25519
64
+ * // types.HashType.SHA3
65
+ * // types.EncodingType.BASE58
66
+ */
67
+ export const types = {
68
+ /**
69
+ * Key-pair derivation algorithms
70
+ *
71
+ * @readonly
72
+ * @enum {number}
73
+ * @name types.KeyType
74
+ * @memberof types
75
+ * @static
76
+ */
77
+ KeyType: {
78
+ ED25519: 0,
79
+ SECP256K1: 1,
80
+ ETHEREUM: 2,
81
+ PASSKEY: 3,
82
+ },
83
+ /**
84
+ * Hashing algorithms
85
+ *
86
+ * @readonly
87
+ * @enum {number}
88
+ * @name types.HashType
89
+ * @memberof types
90
+ * @static
91
+ */
92
+ HashType: {
93
+ KECCAK: 0,
94
+ SHA3: 1,
95
+ KECCAK_384: 2,
96
+ SHA3_384: 3,
97
+ KECCAK_512: 4,
98
+ SHA3_512: 5,
99
+ SHA2: 6,
100
+ },
101
+ /**
102
+ * DID wallet role type
103
+ *
104
+ * @readonly
105
+ * @enum {number}
106
+ * @name types.RoleType
107
+ * @memberof types
108
+ * @static
109
+ */
110
+ RoleType: {
111
+ ROLE_ACCOUNT: 0,
112
+ ROLE_NODE: 1,
113
+ ROLE_DEVICE: 2,
114
+ ROLE_APPLICATION: 3,
115
+ ROLE_SMART_CONTRACT: 4,
116
+ ROLE_BOT: 5,
117
+ ROLE_ASSET: 6,
118
+ ROLE_STAKE: 7,
119
+ ROLE_VALIDATOR: 8,
120
+ ROLE_GROUP: 9,
121
+ ROLE_TX: 10,
122
+ ROLE_TETHER: 11,
123
+ ROLE_SWAP: 12,
124
+ ROLE_DELEGATION: 13,
125
+ ROLE_VC: 14,
126
+ ROLE_BLOCKLET: 15,
127
+ ROLE_STORE: 16,
128
+ ROLE_TOKEN: 17,
129
+ ROLE_FACTORY: 18,
130
+ ROLE_ROLLUP: 19,
131
+ ROLE_STORAGE: 20,
132
+ ROLE_PROFILE: 21,
133
+ ROLE_PASSKEY: 22,
134
+ ROLE_ANY: 63,
135
+ },
136
+ /**
137
+ * Address encoding algorithm, defaults to `base58btc`
138
+ *
139
+ * @readonly
140
+ * @enum {number}
141
+ * @name types.RoleType
142
+ * @memberof types
143
+ * @static
144
+ */
145
+ EncodingType: {
146
+ BASE16: 0,
147
+ BASE58: 1,
148
+ },
149
+ };
150
+ /**
151
+ * Get signer instance
152
+ *
153
+ * @function
154
+ * @param {number} type - algorithm used to derive key pair, possible values are
155
+ * - types.KeyType.ED25519
156
+ * - types.KeyType.SECP256k1
157
+ * - types.KeyType.ETHEREUM
158
+ * @returns {object} signer instance
159
+ * @example
160
+ * const { getSigner, types } = require('@ocap/mcrypto');
161
+ * const message = 'some message to sign';
162
+ *
163
+ * const signer = getSigner(types.KeyType.ED25519);
164
+ * const keyPair1 = signer.genKeyPair();
165
+ * const signature1 = signer.sign(message, keyPair1.secretKey);
166
+ * const result1 = signer.verify(message, signature1, keyPair1.publicKey);
167
+ * assert.ok(result1);
168
+ */
169
+ export function getSigner(type) {
170
+ if (typeof Signers[type] === 'undefined') {
171
+ throw new Error(`Unsupported signer type: ${type}`);
172
+ }
173
+ // @ts-ignore
174
+ return Signers[type];
175
+ }
176
+ /**
177
+ * Get hasher instance
178
+ *
179
+ * @function
180
+ * @param {number} type - algorithm used to hash data, possible values
181
+ * - types.HashType.KECCAK
182
+ * - types.HashType.KECCAK_384
183
+ * - types.HashType.KECCAK_512
184
+ * - types.HashType.SHA3
185
+ * - types.HashType.SHA3_384
186
+ * - types.HashType.SHA3_512
187
+ * @returns {object} hasher instance
188
+ * @example
189
+ * const { getHasher, types } = require('@ocap/mcrypto');
190
+ *
191
+ * const hashFn = getHasher(types.HashType.SHA3);
192
+ * const hash2 = hashFn(message);
193
+ */
194
+ export function getHasher(type) {
195
+ if (typeof Hashers[type] === 'undefined') {
196
+ throw new Error(`Unsupported hash type: ${type}`);
197
+ }
198
+ // @ts-ignore
199
+ return Hashers[type];
200
+ }
201
+ export function getRandomBytes(length = 32, encoding = 'hex') {
202
+ return encode(randomBytes(length), encoding);
203
+ }
204
+ export const Signers = Object.freeze({
205
+ [types.KeyType.ED25519]: Signer.Ed25519,
206
+ [types.KeyType.SECP256K1]: Signer.Secp256k1,
207
+ [types.KeyType.ETHEREUM]: Signer.Ethereum,
208
+ [types.KeyType.PASSKEY]: Signer.Passkey,
209
+ });
210
+ export const Hashers = Object.freeze({
211
+ [types.HashType.KECCAK]: Hasher.Keccak.hash256,
212
+ [types.HashType.KECCAK_384]: Hasher.Keccak.hash384,
213
+ [types.HashType.KECCAK_512]: Hasher.Keccak.hash512,
214
+ [types.HashType.SHA3]: Hasher.SHA3.hash256,
215
+ [types.HashType.SHA3_384]: Hasher.SHA3.hash384,
216
+ [types.HashType.SHA3_512]: Hasher.SHA3.hash512,
217
+ [types.HashType.SHA2]: Hasher.SHA2.hash256,
218
+ });
219
+ export const toTxHash = (buf) => Hasher.SHA2.hash256(buf, 1, 'hex').replace(/^0x/, '').toUpperCase();
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -0,0 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
2
+ // @ts-ignore
3
+ import Interface from 'interface';
4
+ export default Interface.create('encrypt', 'decrypt');
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -0,0 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
2
+ // @ts-ignore
3
+ import Interface from 'interface';
4
+ export default Interface.create('sha224', 'sha256', 'sha384', 'sha512');
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -0,0 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
2
+ // @ts-ignore
3
+ import Interface from 'interface';
4
+ export default Interface.create('genKeyPair', 'getPublicKey', 'sign', 'verify');
@@ -0,0 +1,53 @@
1
+ import { BytesType, EncodingType, KeyPairType } from '@ocap/util';
2
+ import BaseSigner from '../protocols/signer';
3
+ /**
4
+ * Signer implementation for ed25519, based on `tweetnacl`
5
+ *
6
+ * @class Ed25519Signer
7
+ */
8
+ declare class Ed25519Signer extends BaseSigner {
9
+ constructor();
10
+ /**
11
+ * @public
12
+ * @typedefKeyPairType
13
+ * @prop {string} publicKey - publicKey in hex format
14
+ * @prop {string} secretKey - secretKey in hex format
15
+ * @memberof Ed25519Signer
16
+ */
17
+ /**
18
+ * Generate random secret/public key pair
19
+ *
20
+ * @param {Buffer|Uint8Array} [userSeed=undefined]
21
+ * @param {string} [encoding='hex']
22
+ * @returns {KeyPairType}
23
+ * @memberof Ed25519Signer
24
+ */
25
+ genKeyPair(encoding?: EncodingType, userSeed?: BytesType): KeyPairType;
26
+ /**
27
+ * Get publicKey from secretKey
28
+ *
29
+ * @param {hex|buffer|base58|Uint8Array} sk - can be either a hex encoded string or a buffer
30
+ * @returns {string} hex encoded publicKey
31
+ */
32
+ getPublicKey(sk: BytesType, encoding?: EncodingType): BytesType;
33
+ /**
34
+ * Sign a message and get the signature hex
35
+ *
36
+ * @param {hex|base58|buffer|Uint8Array} message
37
+ * @param {hex|base58|buffer|Uint8Array} sk
38
+ * @returns {string} hex encoded signature
39
+ */
40
+ sign(message: BytesType, sk: BytesType, encoding?: EncodingType): BytesType;
41
+ /**
42
+ * Verify if a signature is valid
43
+ *
44
+ * @param {string|buffer} message
45
+ * @param {string|buffer} signature
46
+ * @param {string|buffer} pk
47
+ * @returns {bool}
48
+ */
49
+ verify(message: BytesType, signature: BytesType, pk: BytesType): boolean;
50
+ }
51
+ declare const _default: Ed25519Signer;
52
+ export default _default;
53
+ export { Ed25519Signer };
@@ -0,0 +1,82 @@
1
+ /* eslint-disable @typescript-eslint/no-useless-constructor */
2
+ import tweetnacl from 'tweetnacl';
3
+ import randomBytes from 'randombytes';
4
+ import { toUint8Array } from '@ocap/util';
5
+ import BaseSigner from '../protocols/signer';
6
+ import { encode } from '../encode';
7
+ const ed25519 = tweetnacl.sign;
8
+ /**
9
+ * Signer implementation for ed25519, based on `tweetnacl`
10
+ *
11
+ * @class Ed25519Signer
12
+ */
13
+ class Ed25519Signer extends BaseSigner {
14
+ constructor() {
15
+ super();
16
+ }
17
+ /**
18
+ * @public
19
+ * @typedefKeyPairType
20
+ * @prop {string} publicKey - publicKey in hex format
21
+ * @prop {string} secretKey - secretKey in hex format
22
+ * @memberof Ed25519Signer
23
+ */
24
+ /**
25
+ * Generate random secret/public key pair
26
+ *
27
+ * @param {Buffer|Uint8Array} [userSeed=undefined]
28
+ * @param {string} [encoding='hex']
29
+ * @returns {KeyPairType}
30
+ * @memberof Ed25519Signer
31
+ */
32
+ genKeyPair(encoding = 'hex', userSeed) {
33
+ const seed = userSeed ? toUint8Array(userSeed) : new Uint8Array(randomBytes(32));
34
+ if (seed.byteLength !== 32) {
35
+ throw new Error('Invalid seed to generate key pair');
36
+ }
37
+ const keyPair = ed25519.keyPair.fromSeed(seed);
38
+ keyPair.publicKey = encode(keyPair.publicKey, encoding);
39
+ keyPair.secretKey = encode(keyPair.secretKey, encoding);
40
+ return keyPair;
41
+ }
42
+ /**
43
+ * Get publicKey from secretKey
44
+ *
45
+ * @param {hex|buffer|base58|Uint8Array} sk - can be either a hex encoded string or a buffer
46
+ * @returns {string} hex encoded publicKey
47
+ */
48
+ getPublicKey(sk, encoding = 'hex') {
49
+ const skBytes = toUint8Array(sk);
50
+ const pk = ed25519.keyPair.fromSecretKey(skBytes).publicKey;
51
+ return encode(pk, encoding);
52
+ }
53
+ /**
54
+ * Sign a message and get the signature hex
55
+ *
56
+ * @param {hex|base58|buffer|Uint8Array} message
57
+ * @param {hex|base58|buffer|Uint8Array} sk
58
+ * @returns {string} hex encoded signature
59
+ */
60
+ sign(message, sk, encoding = 'hex') {
61
+ const skBytes = toUint8Array(sk);
62
+ const messageBytes = toUint8Array(message);
63
+ const signature = ed25519.detached(messageBytes, skBytes);
64
+ return encode(signature, encoding);
65
+ }
66
+ /**
67
+ * Verify if a signature is valid
68
+ *
69
+ * @param {string|buffer} message
70
+ * @param {string|buffer} signature
71
+ * @param {string|buffer} pk
72
+ * @returns {bool}
73
+ */
74
+ verify(message, signature, pk) {
75
+ const pkBytes = toUint8Array(pk);
76
+ const messageBytes = toUint8Array(message);
77
+ const signatureBytes = toUint8Array(signature);
78
+ return ed25519.detached.verify(messageBytes, signatureBytes, pkBytes);
79
+ }
80
+ }
81
+ export default new Ed25519Signer();
82
+ export { Ed25519Signer };
@@ -0,0 +1,16 @@
1
+ import { Secp256k1Signer } from './secp256k1';
2
+ /**
3
+ * Signer implementation for secp256k1, based on `elliptic`, and ethereum compatible
4
+ *
5
+ * @class EthereumSigner
6
+ */
7
+ declare class EthereumSigner extends Secp256k1Signer {
8
+ pkHasFormatPrefix: boolean;
9
+ constructor();
10
+ ethHash(data: string): string;
11
+ ethSign(data: string, privateKey: string): string;
12
+ ethRecover(data: string, signature: string): string;
13
+ }
14
+ declare const _default: EthereumSigner;
15
+ export default _default;
16
+ export { EthereumSigner };
@@ -0,0 +1,35 @@
1
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
2
+ // @ts-ignore
3
+ import Account from 'eth-lib/lib/account';
4
+ // @ts-ignore
5
+ import Hash from 'eth-lib/lib/hash';
6
+ import { isHexStrict, utf8ToHex, hexToBytes } from '@ocap/util';
7
+ import { Secp256k1Signer } from './secp256k1';
8
+ /**
9
+ * Signer implementation for secp256k1, based on `elliptic`, and ethereum compatible
10
+ *
11
+ * @class EthereumSigner
12
+ */
13
+ class EthereumSigner extends Secp256k1Signer {
14
+ constructor() {
15
+ super();
16
+ this.pkHasFormatPrefix = false;
17
+ }
18
+ ethHash(data) {
19
+ const messageHex = isHexStrict(data) ? data : utf8ToHex(data);
20
+ const messageBytes = hexToBytes(messageHex);
21
+ const messageBuffer = Buffer.from(messageBytes);
22
+ const preamble = `\x19Ethereum Signed Message:\n${messageBytes.length}`;
23
+ const preambleBuffer = Buffer.from(preamble);
24
+ const ethMessage = Buffer.concat([preambleBuffer, messageBuffer]);
25
+ return Hash.keccak256s(ethMessage);
26
+ }
27
+ ethSign(data, privateKey) {
28
+ return Account.sign(data, privateKey);
29
+ }
30
+ ethRecover(data, signature) {
31
+ return Account.recover(data, signature);
32
+ }
33
+ }
34
+ export default new EthereumSigner();
35
+ export { EthereumSigner };
@@ -0,0 +1,27 @@
1
+ import { BytesType, EncodingType, KeyPairType } from '@ocap/util';
2
+ import BaseSigner from '../protocols/signer';
3
+ /**
4
+ * Signer implementation for passkey, based on `@simplewebauthn/server`
5
+ * Since passkey supports only verification, we do not need to implement the sign method
6
+ * And passkeys can used multiple algorithms, we do not need to implement the algorithm selection
7
+ *
8
+ * @class PasskeySigner
9
+ */
10
+ declare class PasskeySigner extends BaseSigner {
11
+ constructor();
12
+ genKeyPair(encoding?: EncodingType, userSeed?: BytesType): KeyPairType;
13
+ getPublicKey(sk: BytesType, encoding?: EncodingType): BytesType;
14
+ sign(message: BytesType, sk: BytesType, encoding?: EncodingType): BytesType;
15
+ /**
16
+ * Verify if a signature is valid
17
+ *
18
+ * @param {string|buffer} challenge - the challenge sent to passkey, should be txHash when signing a transaction
19
+ * @param {string|buffer} signature - signature from passkey
20
+ * @param {string|buffer} pk - credentialPublicKey from passkey, must be parsed with `parseAuthenticatorData`
21
+ * @returns {bool}
22
+ */
23
+ verify(challenge: BytesType, signature: BytesType, pk: BytesType, extra: string): Promise<boolean>;
24
+ }
25
+ declare const _default: PasskeySigner;
26
+ export default _default;
27
+ export { PasskeySigner };
@@ -0,0 +1,59 @@
1
+ /* eslint-disable @typescript-eslint/no-useless-constructor */
2
+ import { toBuffer, fromBase64, toBase64 } from '@ocap/util';
3
+ import { decodeClientDataJSON, isoBase64URL, isoUint8Array, toHash, verifySignature, } from '@simplewebauthn/server/helpers';
4
+ import BaseSigner from '../protocols/signer';
5
+ /**
6
+ * Signer implementation for passkey, based on `@simplewebauthn/server`
7
+ * Since passkey supports only verification, we do not need to implement the sign method
8
+ * And passkeys can used multiple algorithms, we do not need to implement the algorithm selection
9
+ *
10
+ * @class PasskeySigner
11
+ */
12
+ class PasskeySigner extends BaseSigner {
13
+ constructor() {
14
+ super();
15
+ }
16
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
17
+ genKeyPair(encoding = 'hex', userSeed) {
18
+ throw new Error('Not supported');
19
+ }
20
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
21
+ getPublicKey(sk, encoding = 'hex') {
22
+ throw new Error('Not supported');
23
+ }
24
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
25
+ sign(message, sk, encoding = 'hex') {
26
+ throw new Error('Not supported');
27
+ }
28
+ /**
29
+ * Verify if a signature is valid
30
+ *
31
+ * @param {string|buffer} challenge - the challenge sent to passkey, should be txHash when signing a transaction
32
+ * @param {string|buffer} signature - signature from passkey
33
+ * @param {string|buffer} pk - credentialPublicKey from passkey, must be parsed with `parseAuthenticatorData`
34
+ * @returns {bool}
35
+ */
36
+ async verify(challenge, signature, pk, extra) {
37
+ const parsed = JSON.parse(extra);
38
+ if (!parsed.authenticatorData || !parsed.clientDataJSON) {
39
+ throw new Error('extra.authenticatorData or extra.clientDataJSON is required for passkey signature verification');
40
+ }
41
+ const authDataBuffer = toBuffer(fromBase64(parsed.authenticatorData));
42
+ const clientDataHash = await toHash(isoBase64URL.toBuffer(parsed.clientDataJSON));
43
+ const clientData = decodeClientDataJSON(parsed.clientDataJSON);
44
+ if (clientData.challenge !== toBase64(challenge)) {
45
+ throw new Error('challenge mismatch for passkey signature');
46
+ }
47
+ // FIXME: @wangshijun add more check here
48
+ // if (clientData.type !== 'ocap.tx.sign') {
49
+ // throw new Error('Invalid client data type');
50
+ // }
51
+ return verifySignature({
52
+ signature: isoBase64URL.toBuffer(typeof signature === 'string' ? signature : toBase64(signature)),
53
+ data: isoUint8Array.concat([authDataBuffer, clientDataHash]),
54
+ credentialPublicKey: pk,
55
+ });
56
+ }
57
+ }
58
+ export default new PasskeySigner();
59
+ export { PasskeySigner };
@@ -0,0 +1,39 @@
1
+ import { BytesType, KeyPairType, EncodingType } from '@ocap/util';
2
+ import Signer from '../protocols/signer';
3
+ /**
4
+ * Signer implementation for secp256k1, based on `elliptic`
5
+ *
6
+ * @class Secp256k1Signer
7
+ */
8
+ declare class Secp256k1Signer extends Signer {
9
+ pkCompressed: boolean;
10
+ pkHasFormatPrefix: boolean;
11
+ constructor();
12
+ isValidSK(sk: Uint8Array): boolean;
13
+ /**
14
+ * @public
15
+ * @typedefKeyPairType
16
+ * @prop {string} publicKey - publicKey in hex format
17
+ * @prop {string} secretKey - secretKey in hex format
18
+ * @memberof Secp256k1Signer
19
+ */
20
+ /**
21
+ * Generate random secret/public key pair
22
+ */
23
+ genKeyPair(encoding?: EncodingType): KeyPairType;
24
+ /**
25
+ * Get publicKey from secretKey
26
+ */
27
+ getPublicKey(sk: BytesType, encoding?: EncodingType): BytesType;
28
+ /**
29
+ * Sign a message and get the signature hex
30
+ */
31
+ sign(message: BytesType, sk: BytesType, encoding?: EncodingType): BytesType;
32
+ /**
33
+ * Verify if a signature is valid
34
+ */
35
+ verify(message: BytesType, signature: BytesType, pk: BytesType): boolean;
36
+ }
37
+ declare const _default: Secp256k1Signer;
38
+ export default _default;
39
+ export { Secp256k1Signer };
@@ -0,0 +1,95 @@
1
+ import elliptic from 'elliptic';
2
+ import { BN, stripHexPrefix, toHex, toBuffer, toUint8Array } from '@ocap/util';
3
+ import randomBytes from 'randombytes';
4
+ import Signer from '../protocols/signer';
5
+ import { encode } from '../encode';
6
+ /* eslint-disable class-methods-use-this */
7
+ /* eslint-disable no-useless-constructor */
8
+ const EC = elliptic.ec;
9
+ const secp256k1 = new EC('secp256k1');
10
+ /**
11
+ * Signer implementation for secp256k1, based on `elliptic`
12
+ *
13
+ * @class Secp256k1Signer
14
+ */
15
+ class Secp256k1Signer extends Signer {
16
+ constructor() {
17
+ super();
18
+ this.pkHasFormatPrefix = true;
19
+ this.pkCompressed = false;
20
+ }
21
+ isValidSK(sk) {
22
+ if (sk.byteLength !== 32) {
23
+ return false;
24
+ }
25
+ const bn = new BN(sk);
26
+ return bn.cmp(secp256k1.curve.n) < 0 && !bn.isZero();
27
+ }
28
+ /**
29
+ * @public
30
+ * @typedefKeyPairType
31
+ * @prop {string} publicKey - publicKey in hex format
32
+ * @prop {string} secretKey - secretKey in hex format
33
+ * @memberof Secp256k1Signer
34
+ */
35
+ /**
36
+ * Generate random secret/public key pair
37
+ */
38
+ genKeyPair(encoding = 'hex') {
39
+ let sk = null;
40
+ do {
41
+ sk = new Uint8Array(randomBytes(32));
42
+ } while (!this.isValidSK(sk));
43
+ const pk = this.getPublicKey(toHex(sk));
44
+ return { secretKey: encode(sk, encoding), publicKey: encode(pk, encoding) };
45
+ }
46
+ /**
47
+ * Get publicKey from secretKey
48
+ */
49
+ getPublicKey(sk, encoding = 'hex') {
50
+ if (!this.isValidSK(toUint8Array(sk))) {
51
+ throw new Error('Invalid secret key');
52
+ }
53
+ let pk = secp256k1.keyFromPrivate(toBuffer(sk)).getPublic(this.pkCompressed, 'hex');
54
+ if (this.pkHasFormatPrefix === false) {
55
+ pk = pk.slice(2);
56
+ }
57
+ return encode(`0x${pk}`, encoding);
58
+ }
59
+ /**
60
+ * Sign a message and get the signature hex
61
+ */
62
+ sign(message, sk, encoding = 'hex') {
63
+ let msg = message;
64
+ try {
65
+ msg = toUint8Array(message);
66
+ }
67
+ catch (err) {
68
+ // Do nothing;
69
+ }
70
+ const signature = secp256k1
71
+ .keyFromPrivate(toBuffer(sk))
72
+ .sign(stripHexPrefix(msg), { canonical: true })
73
+ .toDER('hex');
74
+ return encode(`0x${signature}`, encoding);
75
+ }
76
+ /**
77
+ * Verify if a signature is valid
78
+ */
79
+ verify(message, signature, pk) {
80
+ let msg = message;
81
+ try {
82
+ msg = toUint8Array(message);
83
+ }
84
+ catch (err) {
85
+ // Do nothing;
86
+ }
87
+ let pkBuffer = toBuffer(pk);
88
+ if (this.pkHasFormatPrefix === false && pkBuffer[0] !== 0x04 && pkBuffer.byteLength === 64) {
89
+ pkBuffer = Buffer.concat([Buffer.from([0x04]), pkBuffer]);
90
+ }
91
+ return secp256k1.keyFromPublic(pkBuffer).verify(stripHexPrefix(msg), stripHexPrefix(toHex(signature)));
92
+ }
93
+ }
94
+ export default new Secp256k1Signer();
95
+ export { Secp256k1Signer };
@@ -10,7 +10,7 @@ const ab2str = (buffer) => String.fromCharCode.apply(null, new Uint8Array(buffer
10
10
  const RSA_ALGORITHM = 'RSA-OAEP';
11
11
  // RSA-OAEP
12
12
  class RSABrowserCrypter {
13
- async genKeyPair(length = 2048) {
13
+ genKeyPair(length = 2048) {
14
14
  return crypto.generateKey({
15
15
  name: RSA_ALGORITHM,
16
16
  modulusLength: length,
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import crypto from 'crypto';
3
2
  import { BytesType, EncodingType } from '@ocap/util';
4
3
  import Crypter from '../protocols/crypter';
package/lib/encode.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import { BytesType, EncodingType } from '@ocap/util';
3
2
  export declare function encode(data: BytesType, encoding?: 'hex'): string;
4
3
  export declare function encode(data: BytesType, encoding?: 'base16'): string;