@ocap/mcrypto 1.29.22 → 1.29.23

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.
@@ -0,0 +1,18 @@
1
+ //#region rolldown:runtime
2
+ var __defProp = Object.defineProperty;
3
+ var __exportAll = (all, symbols) => {
4
+ let target = {};
5
+ for (var name in all) {
6
+ __defProp(target, name, {
7
+ get: all[name],
8
+ enumerable: true
9
+ });
10
+ }
11
+ if (symbols) {
12
+ __defProp(target, Symbol.toStringTag, { value: "Module" });
13
+ }
14
+ return target;
15
+ };
16
+
17
+ //#endregion
18
+ export { __exportAll };
package/esm/index.d.mts CHANGED
@@ -5,6 +5,7 @@ import { Ed25519Signer } from "./signer/ed25519.mjs";
5
5
  import { Secp256k1Signer } from "./signer/secp256k1.mjs";
6
6
  import { EthereumSigner } from "./signer/ethereum.mjs";
7
7
  import { PasskeySigner } from "./signer/passkey.mjs";
8
+ import { webauthn_d_exports } from "./webauthn.mjs";
8
9
  import { BytesType, EncodingType, KeyPairType } from "@ocap/util";
9
10
  import { LiteralUnion } from "type-fest";
10
11
 
@@ -238,4 +239,4 @@ declare function getRandomBytes(length: number, encoding?: 'Uint8Array'): Uint8A
238
239
  declare function getRandomBytes(length: number, encoding?: EncodingType): BytesType;
239
240
  declare const toTxHash: (buf: Buffer | Uint8Array) => string;
240
241
  //#endregion
241
- export { AddressType, HashFnType, HashType, Hasher, KeyType, RoleType, Signer, SignerType, getHasher, getRandomBytes, getSigner, toTxHash, types };
242
+ export { AddressType, HashFnType, HashType, Hasher, KeyType, RoleType, Signer, SignerType, getHasher, getRandomBytes, getSigner, toTxHash, types, webauthn_d_exports as webauthn };
package/esm/index.mjs CHANGED
@@ -5,6 +5,7 @@ import sha3_default from "./hasher/sha3.mjs";
5
5
  import ed25519_default from "./signer/ed25519.mjs";
6
6
  import secp256k1_default from "./signer/secp256k1.mjs";
7
7
  import ethereum_default from "./signer/ethereum.mjs";
8
+ import { webauthn_exports } from "./webauthn.mjs";
8
9
  import passkey_default from "./signer/passkey.mjs";
9
10
  import randomBytes from "randombytes";
10
11
 
@@ -181,4 +182,4 @@ function getRandomBytes(length = 32, encoding = "hex") {
181
182
  const toTxHash = (buf) => Hasher.SHA2.hash256(buf, 1, "hex").replace(/^0x/, "").toUpperCase();
182
183
 
183
184
  //#endregion
184
- export { Hasher, Signer, getHasher, getRandomBytes, getSigner, toTxHash, types };
185
+ export { Hasher, Signer, getHasher, getRandomBytes, getSigner, toTxHash, types, webauthn_exports as webauthn };
@@ -3,7 +3,7 @@ import { Secp256k1Signer } from "./secp256k1.mjs";
3
3
  //#region src/signer/ethereum.d.ts
4
4
 
5
5
  /**
6
- * Signer implementation for secp256k1, based on `elliptic`, and ethereum compatible
6
+ * Signer implementation for secp256k1, based on `@noble/curves`, and ethereum compatible
7
7
  *
8
8
  * @class EthereumSigner
9
9
  */
@@ -1,11 +1,19 @@
1
1
  import { Secp256k1Signer } from "./secp256k1.mjs";
2
2
  import { hexToBytes, isHexStrict, utf8ToHex } from "@ocap/util";
3
- import Account from "eth-lib/lib/account.js";
4
- import Hash from "eth-lib/lib/hash.js";
3
+ import { keccak_256 } from "@noble/hashes/sha3.js";
4
+ import { bytesToHex } from "@noble/hashes/utils.js";
5
+ import { secp256k1 } from "@noble/curves/secp256k1";
5
6
 
6
7
  //#region src/signer/ethereum.ts
8
+ function toChecksumAddress(address) {
9
+ const addr = address.slice(2).toLowerCase();
10
+ const hash = bytesToHex(keccak_256(Buffer.from(addr)));
11
+ let result = "0x";
12
+ for (let i = 0; i < 40; i++) result += Number.parseInt(hash[i], 16) > 7 ? addr[i].toUpperCase() : addr[i];
13
+ return result;
14
+ }
7
15
  /**
8
- * Signer implementation for secp256k1, based on `elliptic`, and ethereum compatible
16
+ * Signer implementation for secp256k1, based on `@noble/curves`, and ethereum compatible
9
17
  *
10
18
  * @class EthereumSigner
11
19
  */
@@ -16,17 +24,25 @@ var EthereumSigner = class extends Secp256k1Signer {
16
24
  }
17
25
  ethHash(data) {
18
26
  const messageBytes = hexToBytes(isHexStrict(data) ? data : utf8ToHex(data));
19
- const messageBuffer = Buffer.from(messageBytes);
20
27
  const preamble = `\x19Ethereum Signed Message:\n${messageBytes.length}`;
21
- const preambleBuffer = Uint8Array.from(Buffer.from(preamble));
22
- const ethMessage = Buffer.concat([preambleBuffer, Uint8Array.from(messageBuffer)]);
23
- return Hash.keccak256s(ethMessage);
28
+ const ethMessage = Buffer.concat([Buffer.from(preamble), Buffer.from(messageBytes)]);
29
+ return `0x${bytesToHex(keccak_256(new Uint8Array(ethMessage)))}`;
24
30
  }
25
31
  ethSign(data, privateKey) {
26
- return Account.sign(data, privateKey);
32
+ const msgHash = Buffer.from(data.slice(2), "hex");
33
+ const sk = Buffer.from(privateKey.slice(2), "hex");
34
+ const sig = secp256k1.sign(msgHash, sk);
35
+ const v = (27 + sig.recovery).toString(16).padStart(2, "0");
36
+ return `0x${sig.toCompactHex()}${v}`;
27
37
  }
28
38
  ethRecover(data, signature) {
29
- return Account.recover(data, signature);
39
+ const sigHex = signature.slice(2);
40
+ const v = Number.parseInt(sigHex.slice(128, 130), 16);
41
+ const recovery = v < 2 ? v : 1 - v % 2;
42
+ const sig = secp256k1.Signature.fromCompact(sigHex.slice(0, 128)).addRecoveryBit(recovery);
43
+ const msgHash = Buffer.from(data.slice(2), "hex");
44
+ const pubKeyHex = sig.recoverPublicKey(msgHash).toHex(false).slice(2);
45
+ return toChecksumAddress(`0x${bytesToHex(keccak_256(Buffer.from(pubKeyHex, "hex"))).slice(-40)}`);
30
46
  }
31
47
  };
32
48
  var ethereum_default = new EthereumSigner();
@@ -4,7 +4,7 @@ import { BytesType, EncodingType, KeyPairType } from "@ocap/util";
4
4
  //#region src/signer/passkey.d.ts
5
5
 
6
6
  /**
7
- * Signer implementation for passkey, based on `@simplewebauthn/server`
7
+ * Signer implementation for passkey, based on `@noble/curves`
8
8
  * Since passkey supports only verification, we do not need to implement the sign method
9
9
  * And passkeys can used multiple algorithms, we do not need to implement the algorithm selection
10
10
  *
@@ -1,10 +1,10 @@
1
1
  import signer_default from "../protocols/signer.mjs";
2
+ import { decodeClientDataJSON, isoBase64URL, isoUint8Array, toHash, verifySignature } from "../webauthn.mjs";
2
3
  import { fromBase64, toBase64, toBuffer, toUint8Array } from "@ocap/util";
3
- import { decodeClientDataJSON, isoBase64URL, isoUint8Array, toHash, verifySignature } from "@simplewebauthn/server/helpers";
4
4
 
5
5
  //#region src/signer/passkey.ts
6
6
  /**
7
- * Signer implementation for passkey, based on `@simplewebauthn/server`
7
+ * Signer implementation for passkey, based on `@noble/curves`
8
8
  * Since passkey supports only verification, we do not need to implement the sign method
9
9
  * And passkeys can used multiple algorithms, we do not need to implement the algorithm selection
10
10
  *
@@ -4,7 +4,7 @@ import { BytesType, EncodingType, KeyPairType } from "@ocap/util";
4
4
  //#region src/signer/secp256k1.d.ts
5
5
 
6
6
  /**
7
- * Signer implementation for secp256k1, based on `elliptic`
7
+ * Signer implementation for secp256k1, based on `@noble/curves`
8
8
  *
9
9
  * @class Secp256k1Signer
10
10
  */
@@ -1,14 +1,13 @@
1
1
  import { encode } from "../encode.mjs";
2
2
  import signer_default from "../protocols/signer.mjs";
3
- import { BN, stripHexPrefix, toBuffer, toHex, toUint8Array } from "@ocap/util";
3
+ import { toHex, toUint8Array } from "@ocap/util";
4
4
  import randomBytes from "randombytes";
5
- import elliptic from "elliptic";
5
+ import { secp256k1 } from "@noble/curves/secp256k1";
6
+ import { bytesToHex } from "@noble/curves/abstract/utils";
6
7
 
7
8
  //#region src/signer/secp256k1.ts
8
- const EC = elliptic.ec;
9
- const secp256k1 = new EC("secp256k1");
10
9
  /**
11
- * Signer implementation for secp256k1, based on `elliptic`
10
+ * Signer implementation for secp256k1, based on `@noble/curves`
12
11
  *
13
12
  * @class Secp256k1Signer
14
13
  */
@@ -20,8 +19,7 @@ var Secp256k1Signer = class extends signer_default {
20
19
  }
21
20
  isValidSK(sk) {
22
21
  if (sk.byteLength !== 32) return false;
23
- const bn = new BN(sk);
24
- return bn.cmp(secp256k1.curve.n) < 0 && !bn.isZero();
22
+ return secp256k1.utils.isValidPrivateKey(sk);
25
23
  }
26
24
  /**
27
25
  * @public
@@ -49,7 +47,7 @@ var Secp256k1Signer = class extends signer_default {
49
47
  */
50
48
  getPublicKey(sk, encoding = "hex") {
51
49
  if (!this.isValidSK(toUint8Array(sk))) throw new Error("Invalid secret key");
52
- let pk = secp256k1.keyFromPrivate(toBuffer(sk)).getPublic(this.pkCompressed, "hex");
50
+ let pk = bytesToHex(secp256k1.getPublicKey(toUint8Array(sk), this.pkCompressed));
53
51
  if (this.pkHasFormatPrefix === false) pk = pk.slice(2);
54
52
  return encode(`0x${pk}`, encoding);
55
53
  }
@@ -58,30 +56,28 @@ var Secp256k1Signer = class extends signer_default {
58
56
  */
59
57
  sign(message, sk, encoding = "hex") {
60
58
  const msg = toUint8Array(message);
61
- return encode(`0x${secp256k1.keyFromPrivate(toBuffer(sk)).sign(stripHexPrefix(msg), { canonical: true }).toDER("hex")}`, encoding);
59
+ return encode(`0x${secp256k1.sign(msg, toUint8Array(sk)).toDERHex()}`, encoding);
62
60
  }
63
61
  /**
64
62
  * Verify if a signature is valid
65
63
  */
66
64
  verify(message, signature, pk) {
67
65
  const msg = toUint8Array(message);
68
- const sigHex = stripHexPrefix(toHex(signature));
69
- const sigBuf = Buffer.from(sigHex, "hex");
70
- if (sigBuf.length > 6 && sigBuf[0] === 48) {
71
- const sLenIndex = 4 + sigBuf[3] + 1;
72
- if (sLenIndex < sigBuf.length) {
73
- const sLen = sigBuf[sLenIndex];
74
- const sStart = sLenIndex + 1;
75
- if (sStart + sLen <= sigBuf.length) {
76
- const sValue = new BN(sigBuf.slice(sStart, sStart + sLen));
77
- const halfOrder = secp256k1.curve.n.shrn(1);
78
- if (sValue.cmp(halfOrder) > 0) return false;
79
- }
80
- }
66
+ const sigHex = toHex(signature).replace(/^0x/i, "");
67
+ let pkBytes = toUint8Array(pk);
68
+ if (this.pkHasFormatPrefix === false && pkBytes[0] !== 4 && pkBytes.byteLength === 64) {
69
+ const prefixed = new Uint8Array(65);
70
+ prefixed[0] = 4;
71
+ prefixed.set(pkBytes, 1);
72
+ pkBytes = prefixed;
73
+ }
74
+ try {
75
+ const sig = secp256k1.Signature.fromDER(sigHex);
76
+ if (sig.hasHighS()) return false;
77
+ return secp256k1.verify(sig, msg, pkBytes);
78
+ } catch {
79
+ return false;
81
80
  }
82
- let pkBuffer = toBuffer(pk);
83
- if (this.pkHasFormatPrefix === false && pkBuffer[0] !== 4 && pkBuffer.byteLength === 64) pkBuffer = Buffer.concat([Uint8Array.from([4]), Uint8Array.from(pkBuffer)]);
84
- return secp256k1.keyFromPublic(pkBuffer).verify(stripHexPrefix(msg), sigHex);
85
81
  }
86
82
  };
87
83
  var secp256k1_default = new Secp256k1Signer();
@@ -0,0 +1,210 @@
1
+ declare namespace webauthn_d_exports {
2
+ export { COSEALG, COSECRV, COSEKEYS, COSEKTY, GenerateAuthenticationOptionsOpts, GenerateRegistrationOptionsOpts, ParsedAuthenticatorData, RegistrationResponseJSON, VerifiedRegistrationResponse, cose, decodeClientDataJSON, generateAuthenticationOptions, generateChallenge, generateRegistrationOptions, isoBase64URL, isoCBOR, isoUint8Array, parseAuthenticatorData, toHash, verifyRegistrationResponse, verifySignature };
3
+ }
4
+ declare const COSEKEYS: {
5
+ readonly kty: 1;
6
+ readonly alg: 3;
7
+ readonly crv: -1;
8
+ readonly x: -2;
9
+ readonly y: -3;
10
+ readonly n: -1;
11
+ readonly e: -2;
12
+ };
13
+ declare const COSEKTY: {
14
+ readonly OKP: 1;
15
+ readonly EC2: 2;
16
+ readonly RSA: 3;
17
+ };
18
+ declare const COSEALG: {
19
+ readonly ES256: -7;
20
+ readonly EdDSA: -8;
21
+ readonly ES384: -35;
22
+ readonly ES512: -36;
23
+ readonly PS256: -37;
24
+ readonly PS384: -38;
25
+ readonly PS512: -39;
26
+ readonly ES256K: -47;
27
+ readonly RS256: -257;
28
+ readonly RS384: -258;
29
+ readonly RS512: -259;
30
+ readonly RS1: -65535;
31
+ };
32
+ declare const COSECRV: {
33
+ readonly P256: 1;
34
+ readonly P384: 2;
35
+ readonly P521: 3;
36
+ readonly ED25519: 6;
37
+ readonly SECP256K1: 8;
38
+ };
39
+ declare const cose: {
40
+ COSEKEYS: {
41
+ readonly kty: 1;
42
+ readonly alg: 3;
43
+ readonly crv: -1;
44
+ readonly x: -2;
45
+ readonly y: -3;
46
+ readonly n: -1;
47
+ readonly e: -2;
48
+ };
49
+ COSEKTY: {
50
+ readonly OKP: 1;
51
+ readonly EC2: 2;
52
+ readonly RSA: 3;
53
+ };
54
+ COSEALG: {
55
+ readonly ES256: -7;
56
+ readonly EdDSA: -8;
57
+ readonly ES384: -35;
58
+ readonly ES512: -36;
59
+ readonly PS256: -37;
60
+ readonly PS384: -38;
61
+ readonly PS512: -39;
62
+ readonly ES256K: -47;
63
+ readonly RS256: -257;
64
+ readonly RS384: -258;
65
+ readonly RS512: -259;
66
+ readonly RS1: -65535;
67
+ };
68
+ COSECRV: {
69
+ readonly P256: 1;
70
+ readonly P384: 2;
71
+ readonly P521: 3;
72
+ readonly ED25519: 6;
73
+ readonly SECP256K1: 8;
74
+ };
75
+ };
76
+ declare const isoBase64URL: {
77
+ toBuffer(base64url: string): Uint8Array;
78
+ fromBuffer(buffer: Uint8Array, to?: "base64url" | "base64"): string;
79
+ toUTF8String(base64url: string): string;
80
+ fromUTF8String(utf8String: string): string;
81
+ };
82
+ declare const isoUint8Array: {
83
+ concat(arrays: Uint8Array[]): Uint8Array;
84
+ areEqual(a: Uint8Array, b: Uint8Array): boolean;
85
+ toDataView(array: Uint8Array): DataView;
86
+ fromHex(hex: string): Uint8Array;
87
+ };
88
+ declare const isoCBOR: {
89
+ decodeFirst<T = any>(input: Uint8Array): T;
90
+ encode(input: any): Uint8Array;
91
+ };
92
+ declare function toHash(data: Uint8Array | string, algorithm?: number): Promise<Uint8Array>;
93
+ declare function decodeClientDataJSON(data: string): {
94
+ type: string;
95
+ challenge: string;
96
+ origin: string;
97
+ crossOrigin?: boolean;
98
+ };
99
+ interface ParsedAuthenticatorData {
100
+ rpIdHash: Uint8Array;
101
+ flagsBuf: Uint8Array;
102
+ flags: {
103
+ up: boolean;
104
+ uv: boolean;
105
+ be: boolean;
106
+ bs: boolean;
107
+ at: boolean;
108
+ ed: boolean;
109
+ flagsInt: number;
110
+ };
111
+ counter: number;
112
+ counterBuf: Uint8Array;
113
+ aaguid?: Uint8Array;
114
+ credentialID?: Uint8Array;
115
+ credentialPublicKey?: Uint8Array;
116
+ extensionsData?: any;
117
+ extensionsDataBuffer?: Uint8Array;
118
+ }
119
+ declare function parseAuthenticatorData(authData: Uint8Array): ParsedAuthenticatorData;
120
+ declare function verifySignature(opts: {
121
+ signature: Uint8Array;
122
+ data: Uint8Array;
123
+ credentialPublicKey: Uint8Array;
124
+ }): Promise<boolean>;
125
+ declare function generateChallenge(): Uint8Array;
126
+ type GenerateRegistrationOptionsOpts = {
127
+ rpName: string;
128
+ rpID: string;
129
+ userName: string;
130
+ userID?: Uint8Array;
131
+ challenge?: string | Uint8Array;
132
+ userDisplayName?: string;
133
+ timeout?: number;
134
+ attestationType?: 'direct' | 'enterprise' | 'none';
135
+ excludeCredentials?: {
136
+ id: string;
137
+ transports?: string[];
138
+ }[];
139
+ authenticatorSelection?: {
140
+ authenticatorAttachment?: string;
141
+ residentKey?: string;
142
+ requireResidentKey?: boolean;
143
+ userVerification?: string;
144
+ };
145
+ extensions?: Record<string, any>;
146
+ supportedAlgorithmIDs?: number[];
147
+ };
148
+ declare function generateRegistrationOptions(options: GenerateRegistrationOptionsOpts): Promise<Record<string, any>>;
149
+ type GenerateAuthenticationOptionsOpts = {
150
+ rpID: string;
151
+ allowCredentials?: {
152
+ id: string;
153
+ transports?: string[];
154
+ }[];
155
+ challenge?: string | Uint8Array;
156
+ timeout?: number;
157
+ userVerification?: 'required' | 'preferred' | 'discouraged';
158
+ extensions?: Record<string, any>;
159
+ };
160
+ declare function generateAuthenticationOptions(options: GenerateAuthenticationOptionsOpts): Promise<Record<string, any>>;
161
+ type RegistrationResponseJSON = {
162
+ id: string;
163
+ rawId: string;
164
+ type: string;
165
+ response: {
166
+ attestationObject: string;
167
+ clientDataJSON: string;
168
+ transports?: string[];
169
+ publicKey?: string;
170
+ publicKeyAlgorithm?: number;
171
+ authenticatorData?: string;
172
+ };
173
+ clientExtensionResults?: Record<string, any>;
174
+ };
175
+ type VerifiedRegistrationResponse = {
176
+ verified: false;
177
+ registrationInfo?: never;
178
+ } | {
179
+ verified: true;
180
+ registrationInfo: {
181
+ fmt: string;
182
+ aaguid: string;
183
+ credential: {
184
+ id: string;
185
+ publicKey: Uint8Array;
186
+ counter: number;
187
+ transports?: string[];
188
+ };
189
+ credentialType: 'public-key';
190
+ attestationObject: Uint8Array;
191
+ userVerified: boolean;
192
+ credentialDeviceType: 'singleDevice' | 'multiDevice';
193
+ credentialBackedUp: boolean;
194
+ origin: string;
195
+ rpID?: string;
196
+ authenticatorExtensionResults?: any;
197
+ };
198
+ };
199
+ declare function verifyRegistrationResponse(options: {
200
+ response: RegistrationResponseJSON;
201
+ expectedChallenge: string | ((challenge: string) => boolean | Promise<boolean>);
202
+ expectedOrigin: string | string[];
203
+ expectedRPID?: string | string[];
204
+ expectedType?: string | string[];
205
+ requireUserPresence?: boolean;
206
+ requireUserVerification?: boolean;
207
+ supportedAlgorithmIDs?: number[];
208
+ }): Promise<VerifiedRegistrationResponse>;
209
+ //#endregion
210
+ export { COSEALG, COSECRV, COSEKEYS, COSEKTY, GenerateAuthenticationOptionsOpts, GenerateRegistrationOptionsOpts, ParsedAuthenticatorData, RegistrationResponseJSON, VerifiedRegistrationResponse, cose, decodeClientDataJSON, generateAuthenticationOptions, generateChallenge, generateRegistrationOptions, isoBase64URL, isoCBOR, isoUint8Array, parseAuthenticatorData, toHash, verifyRegistrationResponse, verifySignature, webauthn_d_exports };