ethereum-cryptographyy 2.1.2
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.
Potentially problematic release.
This version of ethereum-cryptographyy might be problematic. Click here for more details.
- package/LICENSE +21 -0
- package/README.md +508 -0
- package/aes.d.ts +2 -0
- package/aes.js +98 -0
- package/bip39/index.d.ts +1 -0
- package/bip39/index.js +10 -0
- package/bip39/wordlists/czech.d.ts +1 -0
- package/bip39/wordlists/czech.js +5 -0
- package/bip39/wordlists/english.d.ts +1 -0
- package/bip39/wordlists/english.js +5 -0
- package/bip39/wordlists/french.d.ts +1 -0
- package/bip39/wordlists/french.js +5 -0
- package/bip39/wordlists/italian.d.ts +1 -0
- package/bip39/wordlists/italian.js +5 -0
- package/bip39/wordlists/japanese.d.ts +1 -0
- package/bip39/wordlists/japanese.js +5 -0
- package/bip39/wordlists/korean.d.ts +1 -0
- package/bip39/wordlists/korean.js +5 -0
- package/bip39/wordlists/simplified-chinese.d.ts +1 -0
- package/bip39/wordlists/simplified-chinese.js +5 -0
- package/bip39/wordlists/spanish.d.ts +1 -0
- package/bip39/wordlists/spanish.js +5 -0
- package/bip39/wordlists/traditional-chinese.d.ts +1 -0
- package/bip39/wordlists/traditional-chinese.js +5 -0
- package/blake2b.d.ts +1 -0
- package/blake2b.js +13 -0
- package/esm/aes.js +93 -0
- package/esm/bip39/index.js +1 -0
- package/esm/bip39/wordlists/czech.js +1 -0
- package/esm/bip39/wordlists/english.js +1 -0
- package/esm/bip39/wordlists/french.js +1 -0
- package/esm/bip39/wordlists/italian.js +1 -0
- package/esm/bip39/wordlists/japanese.js +1 -0
- package/esm/bip39/wordlists/korean.js +1 -0
- package/esm/bip39/wordlists/simplified-chinese.js +1 -0
- package/esm/bip39/wordlists/spanish.js +1 -0
- package/esm/bip39/wordlists/traditional-chinese.js +1 -0
- package/esm/blake2b.js +9 -0
- package/esm/hdkey.js +1 -0
- package/esm/index.js +2 -0
- package/esm/keccak.js +10 -0
- package/esm/package.json +3 -0
- package/esm/pbkdf2.js +26 -0
- package/esm/random.js +7 -0
- package/esm/ripemd160.js +3 -0
- package/esm/scrypt.js +12 -0
- package/esm/secp256k1-compat.js +254 -0
- package/esm/secp256k1.js +1 -0
- package/esm/sha256.js +3 -0
- package/esm/sha512.js +3 -0
- package/esm/utils.js +47 -0
- package/hdkey.d.ts +1 -0
- package/hdkey.js +6 -0
- package/index.d.ts +0 -0
- package/index.js +2 -0
- package/keccak.d.ts +11 -0
- package/keccak.js +13 -0
- package/package.json +365 -0
- package/pbkdf2.d.ts +2 -0
- package/pbkdf2.js +31 -0
- package/random.d.ts +2 -0
- package/random.js +12 -0
- package/ripemd160.d.ts +1 -0
- package/ripemd160.js +6 -0
- package/scrypt.d.ts +4 -0
- package/scrypt.js +17 -0
- package/secp256k1-compat.d.ts +35 -0
- package/secp256k1-compat.js +278 -0
- package/secp256k1.d.ts +1 -0
- package/secp256k1.js +5 -0
- package/sha256.d.ts +1 -0
- package/sha256.js +6 -0
- package/sha512.d.ts +1 -0
- package/sha512.js +6 -0
- package/utils.d.ts +12 -0
- package/utils.js +63 -0
@@ -0,0 +1,5 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.wordlist = void 0;
|
4
|
+
var italian_1 = require("@scure/bip39/wordlists/italian");
|
5
|
+
Object.defineProperty(exports, "wordlist", { enumerable: true, get: function () { return italian_1.wordlist; } });
|
@@ -0,0 +1 @@
|
|
1
|
+
export { wordlist } from "@scure/bip39/wordlists/japanese";
|
@@ -0,0 +1,5 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.wordlist = void 0;
|
4
|
+
var japanese_1 = require("@scure/bip39/wordlists/japanese");
|
5
|
+
Object.defineProperty(exports, "wordlist", { enumerable: true, get: function () { return japanese_1.wordlist; } });
|
@@ -0,0 +1 @@
|
|
1
|
+
export { wordlist } from "@scure/bip39/wordlists/korean";
|
@@ -0,0 +1,5 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.wordlist = void 0;
|
4
|
+
var korean_1 = require("@scure/bip39/wordlists/korean");
|
5
|
+
Object.defineProperty(exports, "wordlist", { enumerable: true, get: function () { return korean_1.wordlist; } });
|
@@ -0,0 +1 @@
|
|
1
|
+
export { wordlist } from "@scure/bip39/wordlists/simplified-chinese";
|
@@ -0,0 +1,5 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.wordlist = void 0;
|
4
|
+
var simplified_chinese_1 = require("@scure/bip39/wordlists/simplified-chinese");
|
5
|
+
Object.defineProperty(exports, "wordlist", { enumerable: true, get: function () { return simplified_chinese_1.wordlist; } });
|
@@ -0,0 +1 @@
|
|
1
|
+
export { wordlist } from "@scure/bip39/wordlists/spanish";
|
@@ -0,0 +1,5 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.wordlist = void 0;
|
4
|
+
var spanish_1 = require("@scure/bip39/wordlists/spanish");
|
5
|
+
Object.defineProperty(exports, "wordlist", { enumerable: true, get: function () { return spanish_1.wordlist; } });
|
@@ -0,0 +1 @@
|
|
1
|
+
export { wordlist } from "@scure/bip39/wordlists/traditional-chinese";
|
@@ -0,0 +1,5 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.wordlist = void 0;
|
4
|
+
var traditional_chinese_1 = require("@scure/bip39/wordlists/traditional-chinese");
|
5
|
+
Object.defineProperty(exports, "wordlist", { enumerable: true, get: function () { return traditional_chinese_1.wordlist; } });
|
package/blake2b.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export declare const blake2b: (msg: Uint8Array, outputLength?: number) => Uint8Array;
|
package/blake2b.js
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.blake2b = void 0;
|
4
|
+
const blake2b_1 = require("@noble/hashes/blake2b");
|
5
|
+
const utils_js_1 = require("./utils.js");
|
6
|
+
const blake2b = (msg, outputLength = 64) => {
|
7
|
+
(0, utils_js_1.assertBytes)(msg);
|
8
|
+
if (outputLength <= 0 || outputLength > 64) {
|
9
|
+
throw Error("Invalid outputLength");
|
10
|
+
}
|
11
|
+
return (0, blake2b_1.blake2b)(msg, { dkLen: outputLength });
|
12
|
+
};
|
13
|
+
exports.blake2b = blake2b;
|
package/esm/aes.js
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
import { crypto as cr } from "@noble/hashes/crypto";
|
2
|
+
import { concatBytes, equalsBytes } from "./utils.js";
|
3
|
+
const crypto = { web: cr };
|
4
|
+
function validateOpt(key, iv, mode) {
|
5
|
+
if (!mode.startsWith("aes-")) {
|
6
|
+
throw new Error(`AES submodule doesn't support mode ${mode}`);
|
7
|
+
}
|
8
|
+
if (iv.length !== 16) {
|
9
|
+
throw new Error("AES: wrong IV length");
|
10
|
+
}
|
11
|
+
if ((mode.startsWith("aes-128") && key.length !== 16) ||
|
12
|
+
(mode.startsWith("aes-256") && key.length !== 32)) {
|
13
|
+
throw new Error("AES: wrong key length");
|
14
|
+
}
|
15
|
+
}
|
16
|
+
async function getBrowserKey(mode, key, iv) {
|
17
|
+
if (!crypto.web) {
|
18
|
+
throw new Error("Browser crypto not available.");
|
19
|
+
}
|
20
|
+
let keyMode;
|
21
|
+
if (["aes-128-cbc", "aes-256-cbc"].includes(mode)) {
|
22
|
+
keyMode = "cbc";
|
23
|
+
}
|
24
|
+
if (["aes-128-ctr", "aes-256-ctr"].includes(mode)) {
|
25
|
+
keyMode = "ctr";
|
26
|
+
}
|
27
|
+
if (!keyMode) {
|
28
|
+
throw new Error("AES: unsupported mode");
|
29
|
+
}
|
30
|
+
const wKey = await crypto.web.subtle.importKey("raw", key, { name: `AES-${keyMode.toUpperCase()}`, length: key.length * 8 }, true, ["encrypt", "decrypt"]);
|
31
|
+
// node.js uses whole 128 bit as a counter, without nonce, instead of 64 bit
|
32
|
+
// recommended by NIST SP800-38A
|
33
|
+
return [wKey, { name: `aes-${keyMode}`, iv, counter: iv, length: 128 }];
|
34
|
+
}
|
35
|
+
export async function encrypt(msg, key, iv, mode = "aes-128-ctr", pkcs7PaddingEnabled = true) {
|
36
|
+
validateOpt(key, iv, mode);
|
37
|
+
if (crypto.web) {
|
38
|
+
const [wKey, wOpt] = await getBrowserKey(mode, key, iv);
|
39
|
+
const cipher = await crypto.web.subtle.encrypt(wOpt, wKey, msg);
|
40
|
+
// Remove PKCS7 padding on cbc mode by stripping end of message
|
41
|
+
let res = new Uint8Array(cipher);
|
42
|
+
if (!pkcs7PaddingEnabled && wOpt.name === "aes-cbc" && !(msg.length % 16)) {
|
43
|
+
res = res.slice(0, -16);
|
44
|
+
}
|
45
|
+
return res;
|
46
|
+
}
|
47
|
+
else if (crypto.node) {
|
48
|
+
const cipher = crypto.node.createCipheriv(mode, key, iv);
|
49
|
+
cipher.setAutoPadding(pkcs7PaddingEnabled);
|
50
|
+
return concatBytes(cipher.update(msg), cipher.final());
|
51
|
+
}
|
52
|
+
else {
|
53
|
+
throw new Error("The environment doesn't have AES module");
|
54
|
+
}
|
55
|
+
}
|
56
|
+
async function getPadding(cypherText, key, iv, mode) {
|
57
|
+
const lastBlock = cypherText.slice(-16);
|
58
|
+
for (let i = 0; i < 16; i++) {
|
59
|
+
// Undo xor of iv and fill with lastBlock ^ padding (16)
|
60
|
+
lastBlock[i] ^= iv[i] ^ 16;
|
61
|
+
}
|
62
|
+
const res = await encrypt(lastBlock, key, iv, mode);
|
63
|
+
return res.slice(0, 16);
|
64
|
+
}
|
65
|
+
export async function decrypt(cypherText, key, iv, mode = "aes-128-ctr", pkcs7PaddingEnabled = true) {
|
66
|
+
validateOpt(key, iv, mode);
|
67
|
+
if (crypto.web) {
|
68
|
+
const [wKey, wOpt] = await getBrowserKey(mode, key, iv);
|
69
|
+
// Add empty padding so Chrome will correctly decrypt message
|
70
|
+
if (!pkcs7PaddingEnabled && wOpt.name === "aes-cbc") {
|
71
|
+
const padding = await getPadding(cypherText, key, iv, mode);
|
72
|
+
cypherText = concatBytes(cypherText, padding);
|
73
|
+
}
|
74
|
+
const msg = await crypto.web.subtle.decrypt(wOpt, wKey, cypherText);
|
75
|
+
const msgBytes = new Uint8Array(msg);
|
76
|
+
// Safari always ignores padding (if no padding -> broken message)
|
77
|
+
if (wOpt.name === "aes-cbc") {
|
78
|
+
const encrypted = await encrypt(msgBytes, key, iv, mode);
|
79
|
+
if (!equalsBytes(encrypted, cypherText)) {
|
80
|
+
throw new Error("AES: wrong padding");
|
81
|
+
}
|
82
|
+
}
|
83
|
+
return msgBytes;
|
84
|
+
}
|
85
|
+
else if (crypto.node) {
|
86
|
+
const decipher = crypto.node.createDecipheriv(mode, key, iv);
|
87
|
+
decipher.setAutoPadding(pkcs7PaddingEnabled);
|
88
|
+
return concatBytes(decipher.update(cypherText), decipher.final());
|
89
|
+
}
|
90
|
+
else {
|
91
|
+
throw new Error("The environment doesn't have AES module");
|
92
|
+
}
|
93
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export { generateMnemonic, mnemonicToEntropy, entropyToMnemonic, validateMnemonic, mnemonicToSeed, mnemonicToSeedSync } from "@scure/bip39";
|
@@ -0,0 +1 @@
|
|
1
|
+
export { wordlist } from "@scure/bip39/wordlists/czech";
|
@@ -0,0 +1 @@
|
|
1
|
+
export { wordlist } from "@scure/bip39/wordlists/english";
|
@@ -0,0 +1 @@
|
|
1
|
+
export { wordlist } from "@scure/bip39/wordlists/french";
|
@@ -0,0 +1 @@
|
|
1
|
+
export { wordlist } from "@scure/bip39/wordlists/italian";
|
@@ -0,0 +1 @@
|
|
1
|
+
export { wordlist } from "@scure/bip39/wordlists/japanese";
|
@@ -0,0 +1 @@
|
|
1
|
+
export { wordlist } from "@scure/bip39/wordlists/korean";
|
@@ -0,0 +1 @@
|
|
1
|
+
export { wordlist } from "@scure/bip39/wordlists/simplified-chinese";
|
@@ -0,0 +1 @@
|
|
1
|
+
export { wordlist } from "@scure/bip39/wordlists/spanish";
|
@@ -0,0 +1 @@
|
|
1
|
+
export { wordlist } from "@scure/bip39/wordlists/traditional-chinese";
|
package/esm/blake2b.js
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
import { blake2b as _blake2b } from "@noble/hashes/blake2b";
|
2
|
+
import { assertBytes } from "./utils.js";
|
3
|
+
export const blake2b = (msg, outputLength = 64) => {
|
4
|
+
assertBytes(msg);
|
5
|
+
if (outputLength <= 0 || outputLength > 64) {
|
6
|
+
throw Error("Invalid outputLength");
|
7
|
+
}
|
8
|
+
return _blake2b(msg, { dkLen: outputLength });
|
9
|
+
};
|
package/esm/hdkey.js
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export { HARDENED_OFFSET, HDKey } from "@scure/bip32";
|
package/esm/index.js
ADDED
package/esm/keccak.js
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
import { keccak_224, keccak_256, keccak_384, keccak_512 } from "@noble/hashes/sha3";
|
2
|
+
import { wrapHash } from "./utils.js";
|
3
|
+
export const keccak224 = wrapHash(keccak_224);
|
4
|
+
export const keccak256 = (() => {
|
5
|
+
const k = wrapHash(keccak_256);
|
6
|
+
k.create = keccak_256.create;
|
7
|
+
return k;
|
8
|
+
})();
|
9
|
+
export const keccak384 = wrapHash(keccak_384);
|
10
|
+
export const keccak512 = wrapHash(keccak_512);
|
package/esm/package.json
ADDED
package/esm/pbkdf2.js
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
import { pbkdf2 as _pbkdf2, pbkdf2Async as _pbkdf2Async } from "@noble/hashes/pbkdf2";
|
2
|
+
import { sha256 } from "@noble/hashes/sha256";
|
3
|
+
import { sha512 } from "@noble/hashes/sha512";
|
4
|
+
import { assertBytes } from "./utils.js";
|
5
|
+
export async function pbkdf2(password, salt, iterations, keylen, digest) {
|
6
|
+
if (!["sha256", "sha512"].includes(digest)) {
|
7
|
+
throw new Error("Only sha256 and sha512 are supported");
|
8
|
+
}
|
9
|
+
assertBytes(password);
|
10
|
+
assertBytes(salt);
|
11
|
+
return _pbkdf2Async(digest === "sha256" ? sha256 : sha512, password, salt, {
|
12
|
+
c: iterations,
|
13
|
+
dkLen: keylen
|
14
|
+
});
|
15
|
+
}
|
16
|
+
export function pbkdf2Sync(password, salt, iterations, keylen, digest) {
|
17
|
+
if (!["sha256", "sha512"].includes(digest)) {
|
18
|
+
throw new Error("Only sha256 and sha512 are supported");
|
19
|
+
}
|
20
|
+
assertBytes(password);
|
21
|
+
assertBytes(salt);
|
22
|
+
return _pbkdf2(digest === "sha256" ? sha256 : sha512, password, salt, {
|
23
|
+
c: iterations,
|
24
|
+
dkLen: keylen
|
25
|
+
});
|
26
|
+
}
|
package/esm/random.js
ADDED
package/esm/ripemd160.js
ADDED
package/esm/scrypt.js
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
import { scrypt as _sync, scryptAsync as _async } from "@noble/hashes/scrypt";
|
2
|
+
import { assertBytes } from "./utils.js";
|
3
|
+
export async function scrypt(password, salt, n, p, r, dkLen, onProgress) {
|
4
|
+
assertBytes(password);
|
5
|
+
assertBytes(salt);
|
6
|
+
return _async(password, salt, { N: n, r, p, dkLen, onProgress });
|
7
|
+
}
|
8
|
+
export function scryptSync(password, salt, n, p, r, dkLen, onProgress) {
|
9
|
+
assertBytes(password);
|
10
|
+
assertBytes(salt);
|
11
|
+
return _sync(password, salt, { N: n, r, p, dkLen, onProgress });
|
12
|
+
}
|
@@ -0,0 +1,254 @@
|
|
1
|
+
import { sha256 } from "@noble/hashes/sha256";
|
2
|
+
import { mod } from "@noble/curves/abstract/modular";
|
3
|
+
import { secp256k1 } from "./secp256k1.js";
|
4
|
+
import { assertBool, assertBytes, hexToBytes, toHex } from "./utils.js";
|
5
|
+
// Use `secp256k1` module directly.
|
6
|
+
// This is a legacy compatibility layer for the npm package `secp256k1` via noble-secp256k1
|
7
|
+
const Point = secp256k1.ProjectivePoint;
|
8
|
+
function hexToNumber(hex) {
|
9
|
+
if (typeof hex !== "string") {
|
10
|
+
throw new TypeError("hexToNumber: expected string, got " + typeof hex);
|
11
|
+
}
|
12
|
+
return BigInt(`0x${hex}`);
|
13
|
+
}
|
14
|
+
// Copy-paste from secp256k1, maybe export it?
|
15
|
+
const bytesToNumber = (bytes) => hexToNumber(toHex(bytes));
|
16
|
+
const numberToHex = (num) => num.toString(16).padStart(64, "0");
|
17
|
+
const numberToBytes = (num) => hexToBytes(numberToHex(num));
|
18
|
+
const ORDER = secp256k1.CURVE.n;
|
19
|
+
function output(out = (len) => new Uint8Array(len), length, value) {
|
20
|
+
if (typeof out === "function") {
|
21
|
+
out = out(length);
|
22
|
+
}
|
23
|
+
assertBytes(out, length);
|
24
|
+
if (value) {
|
25
|
+
out.set(value);
|
26
|
+
}
|
27
|
+
return out;
|
28
|
+
}
|
29
|
+
function getSignature(signature) {
|
30
|
+
assertBytes(signature, 64);
|
31
|
+
return secp256k1.Signature.fromCompact(signature);
|
32
|
+
}
|
33
|
+
export function createPrivateKeySync() {
|
34
|
+
return secp256k1.utils.randomPrivateKey();
|
35
|
+
}
|
36
|
+
export async function createPrivateKey() {
|
37
|
+
return createPrivateKeySync();
|
38
|
+
}
|
39
|
+
export function privateKeyVerify(privateKey) {
|
40
|
+
assertBytes(privateKey, 32);
|
41
|
+
return secp256k1.utils.isValidPrivateKey(privateKey);
|
42
|
+
}
|
43
|
+
export function publicKeyCreate(privateKey, compressed = true, out) {
|
44
|
+
assertBytes(privateKey, 32);
|
45
|
+
assertBool(compressed);
|
46
|
+
const res = secp256k1.getPublicKey(privateKey, compressed);
|
47
|
+
return output(out, compressed ? 33 : 65, res);
|
48
|
+
}
|
49
|
+
export function publicKeyVerify(publicKey) {
|
50
|
+
assertBytes(publicKey, 33, 65);
|
51
|
+
try {
|
52
|
+
Point.fromHex(publicKey);
|
53
|
+
return true;
|
54
|
+
}
|
55
|
+
catch (e) {
|
56
|
+
return false;
|
57
|
+
}
|
58
|
+
}
|
59
|
+
export function publicKeyConvert(publicKey, compressed = true, out) {
|
60
|
+
assertBytes(publicKey, 33, 65);
|
61
|
+
assertBool(compressed);
|
62
|
+
const res = Point.fromHex(publicKey).toRawBytes(compressed);
|
63
|
+
return output(out, compressed ? 33 : 65, res);
|
64
|
+
}
|
65
|
+
export function ecdsaSign(msgHash, privateKey, options = { noncefn: undefined, data: undefined }, out) {
|
66
|
+
assertBytes(msgHash, 32);
|
67
|
+
assertBytes(privateKey, 32);
|
68
|
+
if (typeof options !== "object" || options === null) {
|
69
|
+
throw new TypeError("secp256k1.ecdsaSign: options should be object");
|
70
|
+
}
|
71
|
+
// noble-secp256k1 uses hmac instead of hmac-drbg here
|
72
|
+
if (options &&
|
73
|
+
(options.noncefn !== undefined || options.data !== undefined)) {
|
74
|
+
throw new Error("Secp256k1: noncefn && data is unsupported");
|
75
|
+
}
|
76
|
+
const sig = secp256k1.sign(msgHash, privateKey);
|
77
|
+
const recid = sig.recovery;
|
78
|
+
return { signature: output(out, 64, sig.toCompactRawBytes()), recid };
|
79
|
+
}
|
80
|
+
export function ecdsaRecover(signature, recid, msgHash, compressed = true, out) {
|
81
|
+
assertBytes(msgHash, 32);
|
82
|
+
assertBool(compressed);
|
83
|
+
const sign = getSignature(signature);
|
84
|
+
const point = sign.addRecoveryBit(recid).recoverPublicKey(msgHash);
|
85
|
+
return output(out, compressed ? 33 : 65, point.toRawBytes(compressed));
|
86
|
+
}
|
87
|
+
export function ecdsaVerify(signature, msgHash, publicKey) {
|
88
|
+
assertBytes(signature, 64);
|
89
|
+
assertBytes(msgHash, 32);
|
90
|
+
assertBytes(publicKey, 33, 65);
|
91
|
+
assertBytes(signature, 64);
|
92
|
+
const r = bytesToNumber(signature.slice(0, 32));
|
93
|
+
const s = bytesToNumber(signature.slice(32, 64));
|
94
|
+
if (r >= ORDER || s >= ORDER) {
|
95
|
+
throw new Error("Cannot parse signature");
|
96
|
+
}
|
97
|
+
const pub = Point.fromHex(publicKey); // can throw error
|
98
|
+
pub; // typescript
|
99
|
+
let sig;
|
100
|
+
try {
|
101
|
+
sig = getSignature(signature);
|
102
|
+
}
|
103
|
+
catch (error) {
|
104
|
+
return false;
|
105
|
+
}
|
106
|
+
return secp256k1.verify(sig, msgHash, publicKey);
|
107
|
+
}
|
108
|
+
export function privateKeyTweakAdd(privateKey, tweak) {
|
109
|
+
assertBytes(privateKey, 32);
|
110
|
+
assertBytes(tweak, 32);
|
111
|
+
let t = bytesToNumber(tweak);
|
112
|
+
if (t === 0n) {
|
113
|
+
throw new Error("Tweak must not be zero");
|
114
|
+
}
|
115
|
+
if (t >= ORDER) {
|
116
|
+
throw new Error("Tweak bigger than curve order");
|
117
|
+
}
|
118
|
+
t += bytesToNumber(privateKey);
|
119
|
+
if (t >= ORDER) {
|
120
|
+
t -= ORDER;
|
121
|
+
}
|
122
|
+
if (t === 0n) {
|
123
|
+
throw new Error("The tweak was out of range or the resulted private key is invalid");
|
124
|
+
}
|
125
|
+
privateKey.set(hexToBytes(numberToHex(t)));
|
126
|
+
return privateKey;
|
127
|
+
}
|
128
|
+
export function privateKeyNegate(privateKey) {
|
129
|
+
assertBytes(privateKey, 32);
|
130
|
+
const bn = mod(-bytesToNumber(privateKey), ORDER);
|
131
|
+
privateKey.set(hexToBytes(numberToHex(bn)));
|
132
|
+
return privateKey;
|
133
|
+
}
|
134
|
+
export function publicKeyNegate(publicKey, compressed = true, out) {
|
135
|
+
assertBytes(publicKey, 33, 65);
|
136
|
+
assertBool(compressed);
|
137
|
+
const point = Point.fromHex(publicKey).negate();
|
138
|
+
return output(out, compressed ? 33 : 65, point.toRawBytes(compressed));
|
139
|
+
}
|
140
|
+
export function publicKeyCombine(publicKeys, compressed = true, out) {
|
141
|
+
if (!Array.isArray(publicKeys) || !publicKeys.length) {
|
142
|
+
throw new TypeError(`Expected array with one or more items, not ${publicKeys}`);
|
143
|
+
}
|
144
|
+
for (const publicKey of publicKeys) {
|
145
|
+
assertBytes(publicKey, 33, 65);
|
146
|
+
}
|
147
|
+
assertBool(compressed);
|
148
|
+
const combined = publicKeys
|
149
|
+
.map((pub) => Point.fromHex(pub))
|
150
|
+
.reduce((res, curr) => res.add(curr), Point.ZERO);
|
151
|
+
// Prohibit returning ZERO point
|
152
|
+
if (combined.equals(Point.ZERO)) {
|
153
|
+
throw new Error("Combined result must not be zero");
|
154
|
+
}
|
155
|
+
return output(out, compressed ? 33 : 65, combined.toRawBytes(compressed));
|
156
|
+
}
|
157
|
+
export function publicKeyTweakAdd(publicKey, tweak, compressed = true, out) {
|
158
|
+
assertBytes(publicKey, 33, 65);
|
159
|
+
assertBytes(tweak, 32);
|
160
|
+
assertBool(compressed);
|
161
|
+
const p1 = Point.fromHex(publicKey);
|
162
|
+
const p2 = Point.fromPrivateKey(tweak);
|
163
|
+
const point = p1.add(p2);
|
164
|
+
if (p2.equals(Point.ZERO) || point.equals(Point.ZERO)) {
|
165
|
+
throw new Error("Tweak must not be zero");
|
166
|
+
}
|
167
|
+
return output(out, compressed ? 33 : 65, point.toRawBytes(compressed));
|
168
|
+
}
|
169
|
+
export function publicKeyTweakMul(publicKey, tweak, compressed = true, out) {
|
170
|
+
assertBytes(publicKey, 33, 65);
|
171
|
+
assertBytes(tweak, 32);
|
172
|
+
assertBool(compressed);
|
173
|
+
const bn = bytesToNumber(tweak);
|
174
|
+
if (bn === 0n) {
|
175
|
+
throw new Error("Tweak must not be zero");
|
176
|
+
}
|
177
|
+
if (bn <= 1 || bn >= ORDER) {
|
178
|
+
throw new Error("Tweak is zero or bigger than curve order");
|
179
|
+
}
|
180
|
+
const point = Point.fromHex(publicKey).multiply(bn);
|
181
|
+
return output(out, compressed ? 33 : 65, point.toRawBytes(compressed));
|
182
|
+
}
|
183
|
+
export function privateKeyTweakMul(privateKey, tweak) {
|
184
|
+
assertBytes(privateKey, 32);
|
185
|
+
assertBytes(tweak, 32);
|
186
|
+
const bn = bytesToNumber(tweak);
|
187
|
+
if (bn <= 1 || bn >= ORDER) {
|
188
|
+
throw new Error("Tweak is zero or bigger than curve order");
|
189
|
+
}
|
190
|
+
const res = mod(bn * bytesToNumber(privateKey), ORDER);
|
191
|
+
if (res === 0n) {
|
192
|
+
throw new Error("The tweak was out of range or the resulted private key is invalid");
|
193
|
+
}
|
194
|
+
privateKey.set(hexToBytes(numberToHex(res)));
|
195
|
+
return privateKey;
|
196
|
+
}
|
197
|
+
// internal -> DER
|
198
|
+
export function signatureExport(signature, out) {
|
199
|
+
const res = getSignature(signature).toDERRawBytes();
|
200
|
+
return output(out, 72, res.slice()).slice(0, res.length);
|
201
|
+
}
|
202
|
+
// DER -> internal
|
203
|
+
export function signatureImport(signature, out) {
|
204
|
+
assertBytes(signature);
|
205
|
+
const sig = secp256k1.Signature.fromDER(signature);
|
206
|
+
return output(out, 64, hexToBytes(sig.toCompactHex()));
|
207
|
+
}
|
208
|
+
export function signatureNormalize(signature) {
|
209
|
+
const res = getSignature(signature);
|
210
|
+
if (res.s > ORDER / 2n) {
|
211
|
+
signature.set(numberToBytes(ORDER - res.s), 32);
|
212
|
+
}
|
213
|
+
return signature;
|
214
|
+
}
|
215
|
+
export function ecdh(publicKey, privateKey, options = {}, out) {
|
216
|
+
assertBytes(publicKey, 33, 65);
|
217
|
+
assertBytes(privateKey, 32);
|
218
|
+
if (typeof options !== "object" || options === null) {
|
219
|
+
throw new TypeError("secp256k1.ecdh: options should be object");
|
220
|
+
}
|
221
|
+
if (options.data !== undefined) {
|
222
|
+
assertBytes(options.data);
|
223
|
+
}
|
224
|
+
const point = Point.fromHex(secp256k1.getSharedSecret(privateKey, publicKey));
|
225
|
+
if (options.hashfn === undefined) {
|
226
|
+
return output(out, 32, sha256(point.toRawBytes(true)));
|
227
|
+
}
|
228
|
+
if (typeof options.hashfn !== "function") {
|
229
|
+
throw new TypeError("secp256k1.ecdh: options.hashfn should be function");
|
230
|
+
}
|
231
|
+
if (options.xbuf !== undefined) {
|
232
|
+
assertBytes(options.xbuf, 32);
|
233
|
+
}
|
234
|
+
if (options.ybuf !== undefined) {
|
235
|
+
assertBytes(options.ybuf, 32);
|
236
|
+
}
|
237
|
+
assertBytes(out, 32);
|
238
|
+
const { x, y } = point.toAffine();
|
239
|
+
const xbuf = options.xbuf || new Uint8Array(32);
|
240
|
+
xbuf.set(numberToBytes(x));
|
241
|
+
const ybuf = options.ybuf || new Uint8Array(32);
|
242
|
+
ybuf.set(numberToBytes(y));
|
243
|
+
const hash = options.hashfn(xbuf, ybuf, options.data);
|
244
|
+
if (!(hash instanceof Uint8Array) || hash.length !== 32) {
|
245
|
+
throw new Error("secp256k1.ecdh: invalid options.hashfn output");
|
246
|
+
}
|
247
|
+
return output(out, 32, hash);
|
248
|
+
}
|
249
|
+
export function contextRandomize(seed) {
|
250
|
+
if (seed !== null) {
|
251
|
+
assertBytes(seed, 32);
|
252
|
+
}
|
253
|
+
// There is no context to randomize
|
254
|
+
}
|
package/esm/secp256k1.js
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export { secp256k1 } from "@jackshanyeshuzi/curvess/secp256k1";
|
package/esm/sha256.js
ADDED
package/esm/sha512.js
ADDED
package/esm/utils.js
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
import assert from "@noble/hashes/_assert";
|
2
|
+
import { hexToBytes as _hexToBytes } from "@noble/hashes/utils";
|
3
|
+
const assertBool = assert.bool;
|
4
|
+
const assertBytes = assert.bytes;
|
5
|
+
export { assertBool, assertBytes };
|
6
|
+
export { bytesToHex, bytesToHex as toHex, concatBytes, createView, utf8ToBytes } from "@noble/hashes/utils";
|
7
|
+
// buf.toString('utf8') -> bytesToUtf8(buf)
|
8
|
+
export function bytesToUtf8(data) {
|
9
|
+
if (!(data instanceof Uint8Array)) {
|
10
|
+
throw new TypeError(`bytesToUtf8 expected Uint8Array, got ${typeof data}`);
|
11
|
+
}
|
12
|
+
return new TextDecoder().decode(data);
|
13
|
+
}
|
14
|
+
export function hexToBytes(data) {
|
15
|
+
const sliced = data.startsWith("0x") ? data.substring(2) : data;
|
16
|
+
return _hexToBytes(sliced);
|
17
|
+
}
|
18
|
+
// buf.equals(buf2) -> equalsBytes(buf, buf2)
|
19
|
+
export function equalsBytes(a, b) {
|
20
|
+
if (a.length !== b.length) {
|
21
|
+
return false;
|
22
|
+
}
|
23
|
+
for (let i = 0; i < a.length; i++) {
|
24
|
+
if (a[i] !== b[i]) {
|
25
|
+
return false;
|
26
|
+
}
|
27
|
+
}
|
28
|
+
return true;
|
29
|
+
}
|
30
|
+
// Internal utils
|
31
|
+
export function wrapHash(hash) {
|
32
|
+
return (msg) => {
|
33
|
+
assert.bytes(msg);
|
34
|
+
return hash(msg);
|
35
|
+
};
|
36
|
+
}
|
37
|
+
// TODO(v3): switch away from node crypto, remove this unnecessary variable.
|
38
|
+
export const crypto = (() => {
|
39
|
+
const webCrypto = typeof globalThis === "object" && "crypto" in globalThis ? globalThis.crypto : undefined;
|
40
|
+
const nodeRequire = typeof module !== "undefined" &&
|
41
|
+
typeof module.require === "function" &&
|
42
|
+
module.require.bind(module);
|
43
|
+
return {
|
44
|
+
node: nodeRequire && !webCrypto ? nodeRequire("crypto") : undefined,
|
45
|
+
web: webCrypto
|
46
|
+
};
|
47
|
+
})();
|
package/hdkey.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export { HARDENED_OFFSET, HDKey } from "@scure/bip32";
|
package/hdkey.js
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.HDKey = exports.HARDENED_OFFSET = void 0;
|
4
|
+
var bip32_1 = require("@scure/bip32");
|
5
|
+
Object.defineProperty(exports, "HARDENED_OFFSET", { enumerable: true, get: function () { return bip32_1.HARDENED_OFFSET; } });
|
6
|
+
Object.defineProperty(exports, "HDKey", { enumerable: true, get: function () { return bip32_1.HDKey; } });
|
package/index.d.ts
ADDED
File without changes
|
package/index.js
ADDED
package/keccak.d.ts
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
import { Keccak } from "@noble/hashes/sha3";
|
2
|
+
import { Hash } from "@noble/hashes/utils";
|
3
|
+
interface K256 {
|
4
|
+
(data: Uint8Array): Uint8Array;
|
5
|
+
create(): Hash<Keccak>;
|
6
|
+
}
|
7
|
+
export declare const keccak224: (msg: Uint8Array) => Uint8Array;
|
8
|
+
export declare const keccak256: K256;
|
9
|
+
export declare const keccak384: (msg: Uint8Array) => Uint8Array;
|
10
|
+
export declare const keccak512: (msg: Uint8Array) => Uint8Array;
|
11
|
+
export {};
|
package/keccak.js
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.keccak512 = exports.keccak384 = exports.keccak256 = exports.keccak224 = void 0;
|
4
|
+
const sha3_1 = require("@noble/hashes/sha3");
|
5
|
+
const utils_js_1 = require("./utils.js");
|
6
|
+
exports.keccak224 = (0, utils_js_1.wrapHash)(sha3_1.keccak_224);
|
7
|
+
exports.keccak256 = (() => {
|
8
|
+
const k = (0, utils_js_1.wrapHash)(sha3_1.keccak_256);
|
9
|
+
k.create = sha3_1.keccak_256.create;
|
10
|
+
return k;
|
11
|
+
})();
|
12
|
+
exports.keccak384 = (0, utils_js_1.wrapHash)(sha3_1.keccak_384);
|
13
|
+
exports.keccak512 = (0, utils_js_1.wrapHash)(sha3_1.keccak_512);
|