@ocap/mcrypto 1.29.13 → 1.29.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,7 +9,7 @@ var AesCrypter = class extends crypter_default {
9
9
  encrypt(message, secret, encoding = "hex") {
10
10
  const keyBuffer = sha3_default.hash256(secret, 1, "buffer");
11
11
  const key = Uint8Array.from(keyBuffer);
12
- const cipher = crypto.createCipheriv("aes-256-ecb", key, null);
12
+ const cipher = crypto.createCipheriv("aes-256-ecb", key, "");
13
13
  cipher.setAutoPadding(true);
14
14
  const output = cipher.update(Uint8Array.from(toBuffer(message)));
15
15
  return encode(Uint8Array.from(Buffer.concat([Uint8Array.from(output), Uint8Array.from(cipher.final())])), encoding);
@@ -17,7 +17,7 @@ var AesCrypter = class extends crypter_default {
17
17
  decrypt(message, secret, encoding = "hex") {
18
18
  const keyBuffer = sha3_default.hash256(secret, 1, "buffer");
19
19
  const key = Uint8Array.from(keyBuffer);
20
- const decipher = crypto.createDecipheriv("aes-256-ecb", key, null);
20
+ const decipher = crypto.createDecipheriv("aes-256-ecb", key, "");
21
21
  decipher.setAutoPadding(true);
22
22
  const output = decipher.update(Uint8Array.from(toBuffer(message)));
23
23
  return encode(Uint8Array.from(Buffer.concat([Uint8Array.from(output), Uint8Array.from(decipher.final())])), encoding);
package/esm/index.d.mts CHANGED
@@ -39,7 +39,7 @@ interface SignerType {
39
39
  sign(data: BytesType, sk: BytesType, encoding?: 'Uint8Array'): Uint8Array;
40
40
  sign(data: BytesType, sk: BytesType, encoding?: EncodingType): BytesType;
41
41
  /** extra is JSON string for passkey signer containing {authenticatorData, clientDataJSON} */
42
- verify(data: BytesType, pk: BytesType, signature: BytesType, extra?: string): boolean;
42
+ verify(data: BytesType, signature: BytesType, pk: BytesType, extra?: string): boolean;
43
43
  ethHash?(data: string): string;
44
44
  ethSign?(data: string, sk: string): string;
45
45
  ethVerify?(data: string, pk: string, signature: BytesType): boolean;
@@ -25,6 +25,16 @@ declare class Ed25519Signer extends _default$1 {
25
25
  * @memberof Ed25519Signer
26
26
  */
27
27
  genKeyPair(encoding?: EncodingType, userSeed?: BytesType): KeyPairType;
28
+ /**
29
+ * Validate that a 64-byte key (in seed|pk format) has a matching embedded public key.
30
+ * Note: Cross-platform keys (e.g. Elixir) may use private_scalar|pk format where
31
+ * the first 32 bytes are NOT a seed, so this check only applies to seed|pk format keys.
32
+ *
33
+ * @param {Uint8Array} skBytes - 64-byte key to validate
34
+ * @returns {boolean} true if embedded pk matches seed-derived pk
35
+ * @throws {Error} if the key is not 64 bytes
36
+ */
37
+ validateKeyPair(sk: BytesType): boolean;
28
38
  /**
29
39
  * Get publicKey from secretKey
30
40
  *
@@ -41,6 +41,23 @@ var Ed25519Signer = class extends signer_default {
41
41
  };
42
42
  }
43
43
  /**
44
+ * Validate that a 64-byte key (in seed|pk format) has a matching embedded public key.
45
+ * Note: Cross-platform keys (e.g. Elixir) may use private_scalar|pk format where
46
+ * the first 32 bytes are NOT a seed, so this check only applies to seed|pk format keys.
47
+ *
48
+ * @param {Uint8Array} skBytes - 64-byte key to validate
49
+ * @returns {boolean} true if embedded pk matches seed-derived pk
50
+ * @throws {Error} if the key is not 64 bytes
51
+ */
52
+ validateKeyPair(sk) {
53
+ const skBytes = toUint8Array(sk);
54
+ if (skBytes.byteLength !== 64) throw new Error("validateKeyPair requires a 64-byte key");
55
+ const seed = skBytes.slice(0, 32);
56
+ const derivedPk = ed.getPublicKey(seed);
57
+ const embeddedPk = skBytes.slice(32, 64);
58
+ return derivedPk.length === embeddedPk.length && derivedPk.every((b, i) => b === embeddedPk[i]);
59
+ }
60
+ /**
44
61
  * Get publicKey from secretKey
45
62
  *
46
63
  * @param {hex|buffer|base58|Uint8Array} sk - can be either a hex encoded string or a buffer
@@ -57,23 +57,31 @@ var Secp256k1Signer = class extends signer_default {
57
57
  * Sign a message and get the signature hex
58
58
  */
59
59
  sign(message, sk, encoding = "hex") {
60
- let msg = message;
61
- try {
62
- msg = toUint8Array(message);
63
- } catch (_err) {}
60
+ const msg = toUint8Array(message);
64
61
  return encode(`0x${secp256k1.keyFromPrivate(toBuffer(sk)).sign(stripHexPrefix(msg), { canonical: true }).toDER("hex")}`, encoding);
65
62
  }
66
63
  /**
67
64
  * Verify if a signature is valid
68
65
  */
69
66
  verify(message, signature, pk) {
70
- let msg = message;
71
- try {
72
- msg = toUint8Array(message);
73
- } catch (_err) {}
67
+ 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
+ }
81
+ }
74
82
  let pkBuffer = toBuffer(pk);
75
83
  if (this.pkHasFormatPrefix === false && pkBuffer[0] !== 4 && pkBuffer.byteLength === 64) pkBuffer = Buffer.concat([Uint8Array.from([4]), Uint8Array.from(pkBuffer)]);
76
- return secp256k1.keyFromPublic(pkBuffer).verify(stripHexPrefix(msg), stripHexPrefix(toHex(signature)));
84
+ return secp256k1.keyFromPublic(pkBuffer).verify(stripHexPrefix(msg), sigHex);
77
85
  }
78
86
  };
79
87
  var secp256k1_default = new Secp256k1Signer();
@@ -12,7 +12,7 @@ var AesCrypter = class extends require_protocols_crypter.default {
12
12
  encrypt(message, secret, encoding = "hex") {
13
13
  const keyBuffer = require_hasher_sha3.default.hash256(secret, 1, "buffer");
14
14
  const key = Uint8Array.from(keyBuffer);
15
- const cipher = node_crypto.default.createCipheriv("aes-256-ecb", key, null);
15
+ const cipher = node_crypto.default.createCipheriv("aes-256-ecb", key, "");
16
16
  cipher.setAutoPadding(true);
17
17
  const output = cipher.update(Uint8Array.from((0, _ocap_util.toBuffer)(message)));
18
18
  return require_encode.encode(Uint8Array.from(Buffer.concat([Uint8Array.from(output), Uint8Array.from(cipher.final())])), encoding);
@@ -20,7 +20,7 @@ var AesCrypter = class extends require_protocols_crypter.default {
20
20
  decrypt(message, secret, encoding = "hex") {
21
21
  const keyBuffer = require_hasher_sha3.default.hash256(secret, 1, "buffer");
22
22
  const key = Uint8Array.from(keyBuffer);
23
- const decipher = node_crypto.default.createDecipheriv("aes-256-ecb", key, null);
23
+ const decipher = node_crypto.default.createDecipheriv("aes-256-ecb", key, "");
24
24
  decipher.setAutoPadding(true);
25
25
  const output = decipher.update(Uint8Array.from((0, _ocap_util.toBuffer)(message)));
26
26
  return require_encode.encode(Uint8Array.from(Buffer.concat([Uint8Array.from(output), Uint8Array.from(decipher.final())])), encoding);
package/lib/index.d.cts CHANGED
@@ -39,7 +39,7 @@ interface SignerType {
39
39
  sign(data: BytesType, sk: BytesType, encoding?: 'Uint8Array'): Uint8Array;
40
40
  sign(data: BytesType, sk: BytesType, encoding?: EncodingType): BytesType;
41
41
  /** extra is JSON string for passkey signer containing {authenticatorData, clientDataJSON} */
42
- verify(data: BytesType, pk: BytesType, signature: BytesType, extra?: string): boolean;
42
+ verify(data: BytesType, signature: BytesType, pk: BytesType, extra?: string): boolean;
43
43
  ethHash?(data: string): string;
44
44
  ethSign?(data: string, sk: string): string;
45
45
  ethVerify?(data: string, pk: string, signature: BytesType): boolean;
@@ -45,6 +45,23 @@ var Ed25519Signer = class extends require_protocols_signer.default {
45
45
  };
46
46
  }
47
47
  /**
48
+ * Validate that a 64-byte key (in seed|pk format) has a matching embedded public key.
49
+ * Note: Cross-platform keys (e.g. Elixir) may use private_scalar|pk format where
50
+ * the first 32 bytes are NOT a seed, so this check only applies to seed|pk format keys.
51
+ *
52
+ * @param {Uint8Array} skBytes - 64-byte key to validate
53
+ * @returns {boolean} true if embedded pk matches seed-derived pk
54
+ * @throws {Error} if the key is not 64 bytes
55
+ */
56
+ validateKeyPair(sk) {
57
+ const skBytes = (0, _ocap_util.toUint8Array)(sk);
58
+ if (skBytes.byteLength !== 64) throw new Error("validateKeyPair requires a 64-byte key");
59
+ const seed = skBytes.slice(0, 32);
60
+ const derivedPk = _noble_ed25519.getPublicKey(seed);
61
+ const embeddedPk = skBytes.slice(32, 64);
62
+ return derivedPk.length === embeddedPk.length && derivedPk.every((b, i) => b === embeddedPk[i]);
63
+ }
64
+ /**
48
65
  * Get publicKey from secretKey
49
66
  *
50
67
  * @param {hex|buffer|base58|Uint8Array} sk - can be either a hex encoded string or a buffer
@@ -25,6 +25,16 @@ declare class Ed25519Signer extends _default$1 {
25
25
  * @memberof Ed25519Signer
26
26
  */
27
27
  genKeyPair(encoding?: EncodingType, userSeed?: BytesType): KeyPairType;
28
+ /**
29
+ * Validate that a 64-byte key (in seed|pk format) has a matching embedded public key.
30
+ * Note: Cross-platform keys (e.g. Elixir) may use private_scalar|pk format where
31
+ * the first 32 bytes are NOT a seed, so this check only applies to seed|pk format keys.
32
+ *
33
+ * @param {Uint8Array} skBytes - 64-byte key to validate
34
+ * @returns {boolean} true if embedded pk matches seed-derived pk
35
+ * @throws {Error} if the key is not 64 bytes
36
+ */
37
+ validateKeyPair(sk: BytesType): boolean;
28
38
  /**
29
39
  * Get publicKey from secretKey
30
40
  *
@@ -61,23 +61,31 @@ var Secp256k1Signer = class extends require_protocols_signer.default {
61
61
  * Sign a message and get the signature hex
62
62
  */
63
63
  sign(message, sk, encoding = "hex") {
64
- let msg = message;
65
- try {
66
- msg = (0, _ocap_util.toUint8Array)(message);
67
- } catch (_err) {}
64
+ const msg = (0, _ocap_util.toUint8Array)(message);
68
65
  return require_encode.encode(`0x${secp256k1.keyFromPrivate((0, _ocap_util.toBuffer)(sk)).sign((0, _ocap_util.stripHexPrefix)(msg), { canonical: true }).toDER("hex")}`, encoding);
69
66
  }
70
67
  /**
71
68
  * Verify if a signature is valid
72
69
  */
73
70
  verify(message, signature, pk) {
74
- let msg = message;
75
- try {
76
- msg = (0, _ocap_util.toUint8Array)(message);
77
- } catch (_err) {}
71
+ const msg = (0, _ocap_util.toUint8Array)(message);
72
+ const sigHex = (0, _ocap_util.stripHexPrefix)((0, _ocap_util.toHex)(signature));
73
+ const sigBuf = Buffer.from(sigHex, "hex");
74
+ if (sigBuf.length > 6 && sigBuf[0] === 48) {
75
+ const sLenIndex = 4 + sigBuf[3] + 1;
76
+ if (sLenIndex < sigBuf.length) {
77
+ const sLen = sigBuf[sLenIndex];
78
+ const sStart = sLenIndex + 1;
79
+ if (sStart + sLen <= sigBuf.length) {
80
+ const sValue = new _ocap_util.BN(sigBuf.slice(sStart, sStart + sLen));
81
+ const halfOrder = secp256k1.curve.n.shrn(1);
82
+ if (sValue.cmp(halfOrder) > 0) return false;
83
+ }
84
+ }
85
+ }
78
86
  let pkBuffer = (0, _ocap_util.toBuffer)(pk);
79
87
  if (this.pkHasFormatPrefix === false && pkBuffer[0] !== 4 && pkBuffer.byteLength === 64) pkBuffer = Buffer.concat([Uint8Array.from([4]), Uint8Array.from(pkBuffer)]);
80
- return secp256k1.keyFromPublic(pkBuffer).verify((0, _ocap_util.stripHexPrefix)(msg), (0, _ocap_util.stripHexPrefix)((0, _ocap_util.toHex)(signature)));
88
+ return secp256k1.keyFromPublic(pkBuffer).verify((0, _ocap_util.stripHexPrefix)(msg), sigHex);
81
89
  }
82
90
  };
83
91
  var secp256k1_default = new Secp256k1Signer();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ocap/mcrypto",
3
- "version": "1.29.13",
3
+ "version": "1.29.15",
4
4
  "type": "module",
5
5
  "description": "Crypto lib that provides signer,crypter,hasher interface",
6
6
  "keywords": [
@@ -48,7 +48,7 @@
48
48
  "esm"
49
49
  ],
50
50
  "devDependencies": {
51
- "@ocap/e2e-test": "1.29.13",
51
+ "@ocap/e2e-test": "1.29.15",
52
52
  "@types/crypto-js": "^4.2.2",
53
53
  "@types/elliptic": "^6.4.18",
54
54
  "@types/node": "^22.7.5",
@@ -76,9 +76,9 @@
76
76
  "dependencies": {
77
77
  "@noble/ed25519": "^3.0.0",
78
78
  "@noble/hashes": "^2.0.1",
79
- "@ocap/util": "1.29.13",
79
+ "@ocap/util": "1.29.15",
80
80
  "@simplewebauthn/server": "^13.0.0",
81
- "bn.js": "5.2.2",
81
+ "bn.js": "5.2.3",
82
82
  "crypto-js": "^4.2.0",
83
83
  "elliptic": "^6.6.1",
84
84
  "eth-lib": "^0.2.8",
@@ -86,7 +86,7 @@
86
86
  "randombytes": "^2.1.0"
87
87
  },
88
88
  "resolutions": {
89
- "bn.js": "5.2.2",
89
+ "bn.js": "5.2.3",
90
90
  "elliptic": "6.5.3"
91
91
  }
92
92
  }