@bitcoin-js/tiny-secp256k1-asmjs 2.2.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.
- package/LICENSE +21 -0
- package/README.md +355 -0
- package/lib/cjs/index.cjs +387 -0
- package/lib/cjs/rand.browser.cjs +20 -0
- package/lib/cjs/rand.cjs +8 -0
- package/lib/cjs/secp256k1.asm.cjs +33218 -0
- package/lib/cjs/validate.cjs +144 -0
- package/lib/cjs/validate_error.cjs +26 -0
- package/lib/cjs/wasm_loader.cjs +7 -0
- package/lib/cjs/wasm_path_cjs.cjs +12 -0
- package/lib/index.d.ts +33 -0
- package/lib/index.js +361 -0
- package/lib/rand.browser.d.ts +1 -0
- package/lib/rand.browser.js +16 -0
- package/lib/rand.d.ts +1 -0
- package/lib/rand.js +4 -0
- package/lib/secp256k1.asm.js +33218 -0
- package/lib/validate.d.ts +25 -0
- package/lib/validate.js +124 -0
- package/lib/validate_error.d.ts +9 -0
- package/lib/validate_error.js +22 -0
- package/lib/wasm_loader.d.ts +41 -0
- package/lib/wasm_loader.js +5 -0
- package/lib/wasm_path.d.ts +1 -0
- package/lib/wasm_path.js +5 -0
- package/package.json +63 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateSigrPMinusN = exports.validateSignatureNonzeroRS = exports.validateSignatureCustom = exports.validateSignature = exports.validateExtraData = exports.validateHash = exports.validateTweak = exports.validateXOnlyPoint = exports.validatePoint = exports.validatePrivate = exports.validateParity = exports.isPointCompressed = exports.isDERPoint = exports.isXOnlyPoint = exports.isPoint = exports.isPrivate = exports.isZero = exports.SIGNATURE_SIZE = exports.EXTRA_DATA_SIZE = exports.HASH_SIZE = exports.TWEAK_SIZE = exports.X_ONLY_PUBLIC_KEY_SIZE = exports.PUBLIC_KEY_UNCOMPRESSED_SIZE = exports.PUBLIC_KEY_COMPRESSED_SIZE = exports.PRIVATE_KEY_SIZE = void 0;
|
|
4
|
+
const validate_error_js_1 = require("./validate_error.cjs");
|
|
5
|
+
exports.PRIVATE_KEY_SIZE = 32;
|
|
6
|
+
exports.PUBLIC_KEY_COMPRESSED_SIZE = 33;
|
|
7
|
+
exports.PUBLIC_KEY_UNCOMPRESSED_SIZE = 65;
|
|
8
|
+
exports.X_ONLY_PUBLIC_KEY_SIZE = 32;
|
|
9
|
+
exports.TWEAK_SIZE = 32;
|
|
10
|
+
exports.HASH_SIZE = 32;
|
|
11
|
+
exports.EXTRA_DATA_SIZE = 32;
|
|
12
|
+
exports.SIGNATURE_SIZE = 64;
|
|
13
|
+
const BN32_ZERO = new Uint8Array(32);
|
|
14
|
+
const BN32_N = new Uint8Array([
|
|
15
|
+
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
16
|
+
254, 186, 174, 220, 230, 175, 72, 160, 59, 191, 210, 94, 140, 208, 54, 65, 65,
|
|
17
|
+
]);
|
|
18
|
+
// Difference between field and order
|
|
19
|
+
const BN32_P_MINUS_N = new Uint8Array([
|
|
20
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 69, 81, 35, 25, 80, 183, 95,
|
|
21
|
+
196, 64, 45, 161, 114, 47, 201, 186, 238,
|
|
22
|
+
]);
|
|
23
|
+
function isUint8Array(value) {
|
|
24
|
+
return value instanceof Uint8Array;
|
|
25
|
+
}
|
|
26
|
+
function cmpBN32(data1, data2) {
|
|
27
|
+
for (let i = 0; i < 32; ++i) {
|
|
28
|
+
if (data1[i] !== data2[i]) {
|
|
29
|
+
return data1[i] < data2[i] ? -1 : 1;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return 0;
|
|
33
|
+
}
|
|
34
|
+
function isZero(x) {
|
|
35
|
+
return cmpBN32(x, BN32_ZERO) === 0;
|
|
36
|
+
}
|
|
37
|
+
exports.isZero = isZero;
|
|
38
|
+
function isPrivate(x) {
|
|
39
|
+
return (isUint8Array(x) &&
|
|
40
|
+
x.length === exports.PRIVATE_KEY_SIZE &&
|
|
41
|
+
cmpBN32(x, BN32_ZERO) > 0 &&
|
|
42
|
+
cmpBN32(x, BN32_N) < 0);
|
|
43
|
+
}
|
|
44
|
+
exports.isPrivate = isPrivate;
|
|
45
|
+
function isPoint(p) {
|
|
46
|
+
return (isUint8Array(p) &&
|
|
47
|
+
(p.length === exports.PUBLIC_KEY_COMPRESSED_SIZE ||
|
|
48
|
+
p.length === exports.PUBLIC_KEY_UNCOMPRESSED_SIZE ||
|
|
49
|
+
p.length === exports.X_ONLY_PUBLIC_KEY_SIZE));
|
|
50
|
+
}
|
|
51
|
+
exports.isPoint = isPoint;
|
|
52
|
+
function isXOnlyPoint(p) {
|
|
53
|
+
return isUint8Array(p) && p.length === exports.X_ONLY_PUBLIC_KEY_SIZE;
|
|
54
|
+
}
|
|
55
|
+
exports.isXOnlyPoint = isXOnlyPoint;
|
|
56
|
+
function isDERPoint(p) {
|
|
57
|
+
return (isUint8Array(p) &&
|
|
58
|
+
(p.length === exports.PUBLIC_KEY_COMPRESSED_SIZE ||
|
|
59
|
+
p.length === exports.PUBLIC_KEY_UNCOMPRESSED_SIZE));
|
|
60
|
+
}
|
|
61
|
+
exports.isDERPoint = isDERPoint;
|
|
62
|
+
function isPointCompressed(p) {
|
|
63
|
+
return isUint8Array(p) && p.length === exports.PUBLIC_KEY_COMPRESSED_SIZE;
|
|
64
|
+
}
|
|
65
|
+
exports.isPointCompressed = isPointCompressed;
|
|
66
|
+
function isTweak(tweak) {
|
|
67
|
+
return (isUint8Array(tweak) &&
|
|
68
|
+
tweak.length === exports.TWEAK_SIZE &&
|
|
69
|
+
cmpBN32(tweak, BN32_N) < 0);
|
|
70
|
+
}
|
|
71
|
+
function isHash(h) {
|
|
72
|
+
return isUint8Array(h) && h.length === exports.HASH_SIZE;
|
|
73
|
+
}
|
|
74
|
+
function isExtraData(e) {
|
|
75
|
+
return e === undefined || (isUint8Array(e) && e.length === exports.EXTRA_DATA_SIZE);
|
|
76
|
+
}
|
|
77
|
+
function isSignature(signature) {
|
|
78
|
+
return (isUint8Array(signature) &&
|
|
79
|
+
signature.length === 64 &&
|
|
80
|
+
cmpBN32(signature.subarray(0, 32), BN32_N) < 0 &&
|
|
81
|
+
cmpBN32(signature.subarray(32, 64), BN32_N) < 0);
|
|
82
|
+
}
|
|
83
|
+
function isSigrLessThanPMinusN(signature) {
|
|
84
|
+
return (isUint8Array(signature) &&
|
|
85
|
+
signature.length === 64 &&
|
|
86
|
+
cmpBN32(signature.subarray(0, 32), BN32_P_MINUS_N) < 0);
|
|
87
|
+
}
|
|
88
|
+
function validateParity(p) {
|
|
89
|
+
if (p !== 0 && p !== 1)
|
|
90
|
+
(0, validate_error_js_1.throwError)(validate_error_js_1.ERROR_BAD_PARITY);
|
|
91
|
+
}
|
|
92
|
+
exports.validateParity = validateParity;
|
|
93
|
+
function validatePrivate(d) {
|
|
94
|
+
if (!isPrivate(d))
|
|
95
|
+
(0, validate_error_js_1.throwError)(validate_error_js_1.ERROR_BAD_PRIVATE);
|
|
96
|
+
}
|
|
97
|
+
exports.validatePrivate = validatePrivate;
|
|
98
|
+
function validatePoint(p) {
|
|
99
|
+
if (!isPoint(p))
|
|
100
|
+
(0, validate_error_js_1.throwError)(validate_error_js_1.ERROR_BAD_POINT);
|
|
101
|
+
}
|
|
102
|
+
exports.validatePoint = validatePoint;
|
|
103
|
+
function validateXOnlyPoint(p) {
|
|
104
|
+
if (!isXOnlyPoint(p))
|
|
105
|
+
(0, validate_error_js_1.throwError)(validate_error_js_1.ERROR_BAD_POINT);
|
|
106
|
+
}
|
|
107
|
+
exports.validateXOnlyPoint = validateXOnlyPoint;
|
|
108
|
+
function validateTweak(tweak) {
|
|
109
|
+
if (!isTweak(tweak))
|
|
110
|
+
(0, validate_error_js_1.throwError)(validate_error_js_1.ERROR_BAD_TWEAK);
|
|
111
|
+
}
|
|
112
|
+
exports.validateTweak = validateTweak;
|
|
113
|
+
function validateHash(h) {
|
|
114
|
+
if (!isHash(h))
|
|
115
|
+
(0, validate_error_js_1.throwError)(validate_error_js_1.ERROR_BAD_HASH);
|
|
116
|
+
}
|
|
117
|
+
exports.validateHash = validateHash;
|
|
118
|
+
function validateExtraData(e) {
|
|
119
|
+
if (!isExtraData(e))
|
|
120
|
+
(0, validate_error_js_1.throwError)(validate_error_js_1.ERROR_BAD_EXTRA_DATA);
|
|
121
|
+
}
|
|
122
|
+
exports.validateExtraData = validateExtraData;
|
|
123
|
+
function validateSignature(signature) {
|
|
124
|
+
if (!isSignature(signature))
|
|
125
|
+
(0, validate_error_js_1.throwError)(validate_error_js_1.ERROR_BAD_SIGNATURE);
|
|
126
|
+
}
|
|
127
|
+
exports.validateSignature = validateSignature;
|
|
128
|
+
function validateSignatureCustom(validatorFn) {
|
|
129
|
+
if (!validatorFn())
|
|
130
|
+
(0, validate_error_js_1.throwError)(validate_error_js_1.ERROR_BAD_SIGNATURE);
|
|
131
|
+
}
|
|
132
|
+
exports.validateSignatureCustom = validateSignatureCustom;
|
|
133
|
+
function validateSignatureNonzeroRS(signature) {
|
|
134
|
+
if (isZero(signature.subarray(0, 32)))
|
|
135
|
+
(0, validate_error_js_1.throwError)(validate_error_js_1.ERROR_BAD_SIGNATURE);
|
|
136
|
+
if (isZero(signature.subarray(32, 64)))
|
|
137
|
+
(0, validate_error_js_1.throwError)(validate_error_js_1.ERROR_BAD_SIGNATURE);
|
|
138
|
+
}
|
|
139
|
+
exports.validateSignatureNonzeroRS = validateSignatureNonzeroRS;
|
|
140
|
+
function validateSigrPMinusN(signature) {
|
|
141
|
+
if (!isSigrLessThanPMinusN(signature))
|
|
142
|
+
(0, validate_error_js_1.throwError)(validate_error_js_1.ERROR_BAD_RECOVERY_ID);
|
|
143
|
+
}
|
|
144
|
+
exports.validateSigrPMinusN = validateSigrPMinusN;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.throwError = exports.ERROR_BAD_RECOVERY_ID = exports.ERROR_BAD_PARITY = exports.ERROR_BAD_EXTRA_DATA = exports.ERROR_BAD_SIGNATURE = exports.ERROR_BAD_HASH = exports.ERROR_BAD_TWEAK = exports.ERROR_BAD_POINT = exports.ERROR_BAD_PRIVATE = void 0;
|
|
4
|
+
exports.ERROR_BAD_PRIVATE = 0;
|
|
5
|
+
exports.ERROR_BAD_POINT = 1;
|
|
6
|
+
exports.ERROR_BAD_TWEAK = 2;
|
|
7
|
+
exports.ERROR_BAD_HASH = 3;
|
|
8
|
+
exports.ERROR_BAD_SIGNATURE = 4;
|
|
9
|
+
exports.ERROR_BAD_EXTRA_DATA = 5;
|
|
10
|
+
exports.ERROR_BAD_PARITY = 6;
|
|
11
|
+
exports.ERROR_BAD_RECOVERY_ID = 7;
|
|
12
|
+
const ERRORS_MESSAGES = {
|
|
13
|
+
[exports.ERROR_BAD_PRIVATE.toString()]: "Expected Private",
|
|
14
|
+
[exports.ERROR_BAD_POINT.toString()]: "Expected Point",
|
|
15
|
+
[exports.ERROR_BAD_TWEAK.toString()]: "Expected Tweak",
|
|
16
|
+
[exports.ERROR_BAD_HASH.toString()]: "Expected Hash",
|
|
17
|
+
[exports.ERROR_BAD_SIGNATURE.toString()]: "Expected Signature",
|
|
18
|
+
[exports.ERROR_BAD_EXTRA_DATA.toString()]: "Expected Extra Data (32 bytes)",
|
|
19
|
+
[exports.ERROR_BAD_PARITY.toString()]: "Expected Parity (1 | 0)",
|
|
20
|
+
[exports.ERROR_BAD_RECOVERY_ID.toString()]: "Bad Recovery Id",
|
|
21
|
+
};
|
|
22
|
+
function throwError(errcode) {
|
|
23
|
+
const message = ERRORS_MESSAGES[errcode.toString()] || `Unknow error code: ${errcode}`;
|
|
24
|
+
throw new TypeError(message);
|
|
25
|
+
}
|
|
26
|
+
exports.throwError = throwError;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// Suppress TS2792: Cannot find module './secp256k1.asm.cjs'.
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
const wasm = require("./secp256k1.asm.cjs");
|
|
7
|
+
exports.default = wasm;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.path = void 0;
|
|
4
|
+
const nodePath = require("path");
|
|
5
|
+
function path(wasmFilename) {
|
|
6
|
+
// Since we know this file will only be used by cjs
|
|
7
|
+
// and we know that wasm file will always be in the parent dir
|
|
8
|
+
// We can translate to the parent directory without problem
|
|
9
|
+
const pathname = nodePath.join(__dirname, "..", wasmFilename);
|
|
10
|
+
return pathname;
|
|
11
|
+
}
|
|
12
|
+
exports.path = path;
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare function __initializeContext(): void;
|
|
2
|
+
export declare function isPoint(p: Uint8Array): boolean;
|
|
3
|
+
export declare function isPointCompressed(p: Uint8Array): boolean;
|
|
4
|
+
export declare function isXOnlyPoint(p: Uint8Array): boolean;
|
|
5
|
+
export declare function isPrivate(d: Uint8Array): boolean;
|
|
6
|
+
export declare function pointAdd(pA: Uint8Array, pB: Uint8Array, compressed?: boolean): Uint8Array | null;
|
|
7
|
+
export declare function pointAddScalar(p: Uint8Array, tweak: Uint8Array, compressed?: boolean): Uint8Array | null;
|
|
8
|
+
export declare function pointCompress(p: Uint8Array, compressed?: boolean): Uint8Array;
|
|
9
|
+
export declare function pointFromScalar(d: Uint8Array, compressed?: boolean): Uint8Array | null;
|
|
10
|
+
export declare function xOnlyPointFromScalar(d: Uint8Array): Uint8Array;
|
|
11
|
+
export declare function xOnlyPointFromPoint(p: Uint8Array): Uint8Array;
|
|
12
|
+
export declare function pointMultiply(p: Uint8Array, tweak: Uint8Array, compressed?: boolean): Uint8Array | null;
|
|
13
|
+
export declare function privateAdd(d: Uint8Array, tweak: Uint8Array): Uint8Array | null;
|
|
14
|
+
export declare function privateSub(d: Uint8Array, tweak: Uint8Array): Uint8Array | null;
|
|
15
|
+
export declare function privateNegate(d: Uint8Array): Uint8Array;
|
|
16
|
+
export interface XOnlyPointAddTweakResult {
|
|
17
|
+
parity: 1 | 0;
|
|
18
|
+
xOnlyPubkey: Uint8Array;
|
|
19
|
+
}
|
|
20
|
+
export declare function xOnlyPointAddTweak(p: Uint8Array, tweak: Uint8Array): XOnlyPointAddTweakResult | null;
|
|
21
|
+
export declare type TweakParity = 1 | 0;
|
|
22
|
+
export declare function xOnlyPointAddTweakCheck(point: Uint8Array, tweak: Uint8Array, resultToCheck: Uint8Array, tweakParity?: TweakParity): boolean;
|
|
23
|
+
export declare function sign(h: Uint8Array, d: Uint8Array, e?: Uint8Array): Uint8Array;
|
|
24
|
+
export interface RecoverableSignature {
|
|
25
|
+
signature: Uint8Array;
|
|
26
|
+
recoveryId: RecoveryIdType;
|
|
27
|
+
}
|
|
28
|
+
export declare function signRecoverable(h: Uint8Array, d: Uint8Array, e?: Uint8Array): RecoverableSignature;
|
|
29
|
+
export declare function signSchnorr(h: Uint8Array, d: Uint8Array, e?: Uint8Array): Uint8Array;
|
|
30
|
+
export declare function verify(h: Uint8Array, Q: Uint8Array, signature: Uint8Array, strict?: boolean): boolean;
|
|
31
|
+
export declare type RecoveryIdType = 0 | 1 | 2 | 3;
|
|
32
|
+
export declare function recover(h: Uint8Array, signature: Uint8Array, recoveryId: RecoveryIdType, compressed?: boolean): Uint8Array | null;
|
|
33
|
+
export declare function verifySchnorr(h: Uint8Array, Q: Uint8Array, signature: Uint8Array): boolean;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import { compare } from "uint8array-tools";
|
|
2
|
+
import * as validate from "./validate.js";
|
|
3
|
+
import wasm from "./wasm_loader.js";
|
|
4
|
+
const WASM_BUFFER = new Uint8Array(wasm.memory.buffer);
|
|
5
|
+
const WASM_PRIVATE_KEY_PTR = wasm.PRIVATE_INPUT.value;
|
|
6
|
+
const WASM_PUBLIC_KEY_INPUT_PTR = wasm.PUBLIC_KEY_INPUT.value;
|
|
7
|
+
const WASM_PUBLIC_KEY_INPUT_PTR2 = wasm.PUBLIC_KEY_INPUT2.value;
|
|
8
|
+
const WASM_X_ONLY_PUBLIC_KEY_INPUT_PTR = wasm.X_ONLY_PUBLIC_KEY_INPUT.value;
|
|
9
|
+
const WASM_X_ONLY_PUBLIC_KEY_INPUT2_PTR = wasm.X_ONLY_PUBLIC_KEY_INPUT2.value;
|
|
10
|
+
const WASM_TWEAK_INPUT_PTR = wasm.TWEAK_INPUT.value;
|
|
11
|
+
const WASM_HASH_INPUT_PTR = wasm.HASH_INPUT.value;
|
|
12
|
+
const WASM_EXTRA_DATA_INPUT_PTR = wasm.EXTRA_DATA_INPUT.value;
|
|
13
|
+
const WASM_SIGNATURE_INPUT_PTR = wasm.SIGNATURE_INPUT.value;
|
|
14
|
+
const PRIVATE_KEY_INPUT = WASM_BUFFER.subarray(WASM_PRIVATE_KEY_PTR, WASM_PRIVATE_KEY_PTR + validate.PRIVATE_KEY_SIZE);
|
|
15
|
+
const PUBLIC_KEY_INPUT = WASM_BUFFER.subarray(WASM_PUBLIC_KEY_INPUT_PTR, WASM_PUBLIC_KEY_INPUT_PTR + validate.PUBLIC_KEY_UNCOMPRESSED_SIZE);
|
|
16
|
+
const PUBLIC_KEY_INPUT2 = WASM_BUFFER.subarray(WASM_PUBLIC_KEY_INPUT_PTR2, WASM_PUBLIC_KEY_INPUT_PTR2 + validate.PUBLIC_KEY_UNCOMPRESSED_SIZE);
|
|
17
|
+
const X_ONLY_PUBLIC_KEY_INPUT = WASM_BUFFER.subarray(WASM_X_ONLY_PUBLIC_KEY_INPUT_PTR, WASM_X_ONLY_PUBLIC_KEY_INPUT_PTR + validate.X_ONLY_PUBLIC_KEY_SIZE);
|
|
18
|
+
const X_ONLY_PUBLIC_KEY_INPUT2 = WASM_BUFFER.subarray(WASM_X_ONLY_PUBLIC_KEY_INPUT2_PTR, WASM_X_ONLY_PUBLIC_KEY_INPUT2_PTR + validate.X_ONLY_PUBLIC_KEY_SIZE);
|
|
19
|
+
const TWEAK_INPUT = WASM_BUFFER.subarray(WASM_TWEAK_INPUT_PTR, WASM_TWEAK_INPUT_PTR + validate.TWEAK_SIZE);
|
|
20
|
+
const HASH_INPUT = WASM_BUFFER.subarray(WASM_HASH_INPUT_PTR, WASM_HASH_INPUT_PTR + validate.HASH_SIZE);
|
|
21
|
+
const EXTRA_DATA_INPUT = WASM_BUFFER.subarray(WASM_EXTRA_DATA_INPUT_PTR, WASM_EXTRA_DATA_INPUT_PTR + validate.EXTRA_DATA_SIZE);
|
|
22
|
+
const SIGNATURE_INPUT = WASM_BUFFER.subarray(WASM_SIGNATURE_INPUT_PTR, WASM_SIGNATURE_INPUT_PTR + validate.SIGNATURE_SIZE);
|
|
23
|
+
function assumeCompression(compressed, p) {
|
|
24
|
+
if (compressed === undefined) {
|
|
25
|
+
return p !== undefined ? p.length : validate.PUBLIC_KEY_COMPRESSED_SIZE;
|
|
26
|
+
}
|
|
27
|
+
return compressed
|
|
28
|
+
? validate.PUBLIC_KEY_COMPRESSED_SIZE
|
|
29
|
+
: validate.PUBLIC_KEY_UNCOMPRESSED_SIZE;
|
|
30
|
+
}
|
|
31
|
+
function _isPoint(p) {
|
|
32
|
+
try {
|
|
33
|
+
PUBLIC_KEY_INPUT.set(p);
|
|
34
|
+
return wasm.isPoint(p.length) === 1;
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
PUBLIC_KEY_INPUT.fill(0);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export function __initializeContext() {
|
|
41
|
+
wasm.initializeContext();
|
|
42
|
+
}
|
|
43
|
+
export function isPoint(p) {
|
|
44
|
+
return validate.isDERPoint(p) && _isPoint(p);
|
|
45
|
+
}
|
|
46
|
+
export function isPointCompressed(p) {
|
|
47
|
+
return validate.isPointCompressed(p) && _isPoint(p);
|
|
48
|
+
}
|
|
49
|
+
export function isXOnlyPoint(p) {
|
|
50
|
+
return validate.isXOnlyPoint(p) && _isPoint(p);
|
|
51
|
+
}
|
|
52
|
+
export function isPrivate(d) {
|
|
53
|
+
return validate.isPrivate(d);
|
|
54
|
+
}
|
|
55
|
+
export function pointAdd(pA, pB, compressed) {
|
|
56
|
+
validate.validatePoint(pA);
|
|
57
|
+
validate.validatePoint(pB);
|
|
58
|
+
const outputlen = assumeCompression(compressed, pA);
|
|
59
|
+
try {
|
|
60
|
+
PUBLIC_KEY_INPUT.set(pA);
|
|
61
|
+
PUBLIC_KEY_INPUT2.set(pB);
|
|
62
|
+
return wasm.pointAdd(pA.length, pB.length, outputlen) === 1
|
|
63
|
+
? PUBLIC_KEY_INPUT.slice(0, outputlen)
|
|
64
|
+
: null;
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
PUBLIC_KEY_INPUT.fill(0);
|
|
68
|
+
PUBLIC_KEY_INPUT2.fill(0);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export function pointAddScalar(p, tweak, compressed) {
|
|
72
|
+
validate.validatePoint(p);
|
|
73
|
+
validate.validateTweak(tweak);
|
|
74
|
+
const outputlen = assumeCompression(compressed, p);
|
|
75
|
+
try {
|
|
76
|
+
PUBLIC_KEY_INPUT.set(p);
|
|
77
|
+
TWEAK_INPUT.set(tweak);
|
|
78
|
+
return wasm.pointAddScalar(p.length, outputlen) === 1
|
|
79
|
+
? PUBLIC_KEY_INPUT.slice(0, outputlen)
|
|
80
|
+
: null;
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
PUBLIC_KEY_INPUT.fill(0);
|
|
84
|
+
TWEAK_INPUT.fill(0);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export function pointCompress(p, compressed) {
|
|
88
|
+
validate.validatePoint(p);
|
|
89
|
+
const outputlen = assumeCompression(compressed, p);
|
|
90
|
+
try {
|
|
91
|
+
PUBLIC_KEY_INPUT.set(p);
|
|
92
|
+
wasm.pointCompress(p.length, outputlen);
|
|
93
|
+
return PUBLIC_KEY_INPUT.slice(0, outputlen);
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
PUBLIC_KEY_INPUT.fill(0);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export function pointFromScalar(d, compressed) {
|
|
100
|
+
validate.validatePrivate(d);
|
|
101
|
+
const outputlen = assumeCompression(compressed);
|
|
102
|
+
try {
|
|
103
|
+
PRIVATE_KEY_INPUT.set(d);
|
|
104
|
+
return wasm.pointFromScalar(outputlen) === 1
|
|
105
|
+
? PUBLIC_KEY_INPUT.slice(0, outputlen)
|
|
106
|
+
: null;
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
PRIVATE_KEY_INPUT.fill(0);
|
|
110
|
+
PUBLIC_KEY_INPUT.fill(0);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
export function xOnlyPointFromScalar(d) {
|
|
114
|
+
validate.validatePrivate(d);
|
|
115
|
+
try {
|
|
116
|
+
PRIVATE_KEY_INPUT.set(d);
|
|
117
|
+
wasm.xOnlyPointFromScalar();
|
|
118
|
+
return X_ONLY_PUBLIC_KEY_INPUT.slice(0, validate.X_ONLY_PUBLIC_KEY_SIZE);
|
|
119
|
+
}
|
|
120
|
+
finally {
|
|
121
|
+
PRIVATE_KEY_INPUT.fill(0);
|
|
122
|
+
X_ONLY_PUBLIC_KEY_INPUT.fill(0);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
export function xOnlyPointFromPoint(p) {
|
|
126
|
+
validate.validatePoint(p);
|
|
127
|
+
try {
|
|
128
|
+
PUBLIC_KEY_INPUT.set(p);
|
|
129
|
+
wasm.xOnlyPointFromPoint(p.length);
|
|
130
|
+
return X_ONLY_PUBLIC_KEY_INPUT.slice(0, validate.X_ONLY_PUBLIC_KEY_SIZE);
|
|
131
|
+
}
|
|
132
|
+
finally {
|
|
133
|
+
PUBLIC_KEY_INPUT.fill(0);
|
|
134
|
+
X_ONLY_PUBLIC_KEY_INPUT.fill(0);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
export function pointMultiply(p, tweak, compressed) {
|
|
138
|
+
validate.validatePoint(p);
|
|
139
|
+
validate.validateTweak(tweak);
|
|
140
|
+
const outputlen = assumeCompression(compressed, p);
|
|
141
|
+
try {
|
|
142
|
+
PUBLIC_KEY_INPUT.set(p);
|
|
143
|
+
TWEAK_INPUT.set(tweak);
|
|
144
|
+
return wasm.pointMultiply(p.length, outputlen) === 1
|
|
145
|
+
? PUBLIC_KEY_INPUT.slice(0, outputlen)
|
|
146
|
+
: null;
|
|
147
|
+
}
|
|
148
|
+
finally {
|
|
149
|
+
PUBLIC_KEY_INPUT.fill(0);
|
|
150
|
+
TWEAK_INPUT.fill(0);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
export function privateAdd(d, tweak) {
|
|
154
|
+
validate.validatePrivate(d);
|
|
155
|
+
validate.validateTweak(tweak);
|
|
156
|
+
try {
|
|
157
|
+
PRIVATE_KEY_INPUT.set(d);
|
|
158
|
+
TWEAK_INPUT.set(tweak);
|
|
159
|
+
return wasm.privateAdd() === 1
|
|
160
|
+
? PRIVATE_KEY_INPUT.slice(0, validate.PRIVATE_KEY_SIZE)
|
|
161
|
+
: null;
|
|
162
|
+
}
|
|
163
|
+
finally {
|
|
164
|
+
PRIVATE_KEY_INPUT.fill(0);
|
|
165
|
+
TWEAK_INPUT.fill(0);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
export function privateSub(d, tweak) {
|
|
169
|
+
validate.validatePrivate(d);
|
|
170
|
+
validate.validateTweak(tweak);
|
|
171
|
+
// We can not pass zero tweak to WASM, because WASM use `secp256k1_ec_seckey_negate` for tweak negate.
|
|
172
|
+
// (zero is not valid seckey)
|
|
173
|
+
if (validate.isZero(tweak)) {
|
|
174
|
+
return new Uint8Array(d);
|
|
175
|
+
}
|
|
176
|
+
try {
|
|
177
|
+
PRIVATE_KEY_INPUT.set(d);
|
|
178
|
+
TWEAK_INPUT.set(tweak);
|
|
179
|
+
return wasm.privateSub() === 1
|
|
180
|
+
? PRIVATE_KEY_INPUT.slice(0, validate.PRIVATE_KEY_SIZE)
|
|
181
|
+
: null;
|
|
182
|
+
}
|
|
183
|
+
finally {
|
|
184
|
+
PRIVATE_KEY_INPUT.fill(0);
|
|
185
|
+
TWEAK_INPUT.fill(0);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
export function privateNegate(d) {
|
|
189
|
+
validate.validatePrivate(d);
|
|
190
|
+
try {
|
|
191
|
+
PRIVATE_KEY_INPUT.set(d);
|
|
192
|
+
wasm.privateNegate();
|
|
193
|
+
return PRIVATE_KEY_INPUT.slice(0, validate.PRIVATE_KEY_SIZE);
|
|
194
|
+
}
|
|
195
|
+
finally {
|
|
196
|
+
PRIVATE_KEY_INPUT.fill(0);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
export function xOnlyPointAddTweak(p, tweak) {
|
|
200
|
+
validate.validateXOnlyPoint(p);
|
|
201
|
+
validate.validateTweak(tweak);
|
|
202
|
+
try {
|
|
203
|
+
X_ONLY_PUBLIC_KEY_INPUT.set(p);
|
|
204
|
+
TWEAK_INPUT.set(tweak);
|
|
205
|
+
const parity = wasm.xOnlyPointAddTweak();
|
|
206
|
+
return parity !== -1
|
|
207
|
+
? {
|
|
208
|
+
parity,
|
|
209
|
+
xOnlyPubkey: X_ONLY_PUBLIC_KEY_INPUT.slice(0, validate.X_ONLY_PUBLIC_KEY_SIZE),
|
|
210
|
+
}
|
|
211
|
+
: null;
|
|
212
|
+
}
|
|
213
|
+
finally {
|
|
214
|
+
X_ONLY_PUBLIC_KEY_INPUT.fill(0);
|
|
215
|
+
TWEAK_INPUT.fill(0);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
export function xOnlyPointAddTweakCheck(point, tweak, resultToCheck, tweakParity) {
|
|
219
|
+
validate.validateXOnlyPoint(point);
|
|
220
|
+
validate.validateXOnlyPoint(resultToCheck);
|
|
221
|
+
validate.validateTweak(tweak);
|
|
222
|
+
const hasParity = tweakParity !== undefined;
|
|
223
|
+
if (hasParity)
|
|
224
|
+
validate.validateParity(tweakParity);
|
|
225
|
+
try {
|
|
226
|
+
X_ONLY_PUBLIC_KEY_INPUT.set(point);
|
|
227
|
+
X_ONLY_PUBLIC_KEY_INPUT2.set(resultToCheck);
|
|
228
|
+
TWEAK_INPUT.set(tweak);
|
|
229
|
+
if (hasParity) {
|
|
230
|
+
return wasm.xOnlyPointAddTweakCheck(tweakParity) === 1;
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
wasm.xOnlyPointAddTweak();
|
|
234
|
+
const newKey = X_ONLY_PUBLIC_KEY_INPUT.slice(0, validate.X_ONLY_PUBLIC_KEY_SIZE);
|
|
235
|
+
return compare(newKey, resultToCheck) === 0;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
finally {
|
|
239
|
+
X_ONLY_PUBLIC_KEY_INPUT.fill(0);
|
|
240
|
+
X_ONLY_PUBLIC_KEY_INPUT2.fill(0);
|
|
241
|
+
TWEAK_INPUT.fill(0);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
export function sign(h, d, e) {
|
|
245
|
+
validate.validateHash(h);
|
|
246
|
+
validate.validatePrivate(d);
|
|
247
|
+
validate.validateExtraData(e);
|
|
248
|
+
try {
|
|
249
|
+
HASH_INPUT.set(h);
|
|
250
|
+
PRIVATE_KEY_INPUT.set(d);
|
|
251
|
+
if (e !== undefined)
|
|
252
|
+
EXTRA_DATA_INPUT.set(e);
|
|
253
|
+
wasm.sign(e === undefined ? 0 : 1);
|
|
254
|
+
return SIGNATURE_INPUT.slice(0, validate.SIGNATURE_SIZE);
|
|
255
|
+
}
|
|
256
|
+
finally {
|
|
257
|
+
HASH_INPUT.fill(0);
|
|
258
|
+
PRIVATE_KEY_INPUT.fill(0);
|
|
259
|
+
if (e !== undefined)
|
|
260
|
+
EXTRA_DATA_INPUT.fill(0);
|
|
261
|
+
SIGNATURE_INPUT.fill(0);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
export function signRecoverable(h, d, e) {
|
|
265
|
+
validate.validateHash(h);
|
|
266
|
+
validate.validatePrivate(d);
|
|
267
|
+
validate.validateExtraData(e);
|
|
268
|
+
try {
|
|
269
|
+
HASH_INPUT.set(h);
|
|
270
|
+
PRIVATE_KEY_INPUT.set(d);
|
|
271
|
+
if (e !== undefined)
|
|
272
|
+
EXTRA_DATA_INPUT.set(e);
|
|
273
|
+
const recoveryId = wasm.signRecoverable(e === undefined ? 0 : 1);
|
|
274
|
+
const signature = SIGNATURE_INPUT.slice(0, validate.SIGNATURE_SIZE);
|
|
275
|
+
return {
|
|
276
|
+
signature,
|
|
277
|
+
recoveryId,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
finally {
|
|
281
|
+
HASH_INPUT.fill(0);
|
|
282
|
+
PRIVATE_KEY_INPUT.fill(0);
|
|
283
|
+
if (e !== undefined)
|
|
284
|
+
EXTRA_DATA_INPUT.fill(0);
|
|
285
|
+
SIGNATURE_INPUT.fill(0);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
export function signSchnorr(h, d, e) {
|
|
289
|
+
validate.validateHash(h);
|
|
290
|
+
validate.validatePrivate(d);
|
|
291
|
+
validate.validateExtraData(e);
|
|
292
|
+
try {
|
|
293
|
+
HASH_INPUT.set(h);
|
|
294
|
+
PRIVATE_KEY_INPUT.set(d);
|
|
295
|
+
if (e !== undefined)
|
|
296
|
+
EXTRA_DATA_INPUT.set(e);
|
|
297
|
+
wasm.signSchnorr(e === undefined ? 0 : 1);
|
|
298
|
+
return SIGNATURE_INPUT.slice(0, validate.SIGNATURE_SIZE);
|
|
299
|
+
}
|
|
300
|
+
finally {
|
|
301
|
+
HASH_INPUT.fill(0);
|
|
302
|
+
PRIVATE_KEY_INPUT.fill(0);
|
|
303
|
+
if (e !== undefined)
|
|
304
|
+
EXTRA_DATA_INPUT.fill(0);
|
|
305
|
+
SIGNATURE_INPUT.fill(0);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
export function verify(h, Q, signature, strict = false) {
|
|
309
|
+
validate.validateHash(h);
|
|
310
|
+
validate.validatePoint(Q);
|
|
311
|
+
validate.validateSignature(signature);
|
|
312
|
+
try {
|
|
313
|
+
HASH_INPUT.set(h);
|
|
314
|
+
PUBLIC_KEY_INPUT.set(Q);
|
|
315
|
+
SIGNATURE_INPUT.set(signature);
|
|
316
|
+
return wasm.verify(Q.length, strict === true ? 1 : 0) === 1 ? true : false;
|
|
317
|
+
}
|
|
318
|
+
finally {
|
|
319
|
+
HASH_INPUT.fill(0);
|
|
320
|
+
PUBLIC_KEY_INPUT.fill(0);
|
|
321
|
+
SIGNATURE_INPUT.fill(0);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
export function recover(h, signature, recoveryId, compressed = false) {
|
|
325
|
+
validate.validateHash(h);
|
|
326
|
+
validate.validateSignature(signature);
|
|
327
|
+
validate.validateSignatureNonzeroRS(signature);
|
|
328
|
+
if (recoveryId & 2) {
|
|
329
|
+
validate.validateSigrPMinusN(signature);
|
|
330
|
+
}
|
|
331
|
+
validate.validateSignatureCustom(() => isXOnlyPoint(signature.subarray(0, 32)));
|
|
332
|
+
const outputlen = assumeCompression(compressed);
|
|
333
|
+
try {
|
|
334
|
+
HASH_INPUT.set(h);
|
|
335
|
+
SIGNATURE_INPUT.set(signature);
|
|
336
|
+
return wasm.recover(outputlen, recoveryId) === 1
|
|
337
|
+
? PUBLIC_KEY_INPUT.slice(0, outputlen)
|
|
338
|
+
: null;
|
|
339
|
+
}
|
|
340
|
+
finally {
|
|
341
|
+
HASH_INPUT.fill(0);
|
|
342
|
+
SIGNATURE_INPUT.fill(0);
|
|
343
|
+
PUBLIC_KEY_INPUT.fill(0);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
export function verifySchnorr(h, Q, signature) {
|
|
347
|
+
validate.validateHash(h);
|
|
348
|
+
validate.validateXOnlyPoint(Q);
|
|
349
|
+
validate.validateSignature(signature);
|
|
350
|
+
try {
|
|
351
|
+
HASH_INPUT.set(h);
|
|
352
|
+
X_ONLY_PUBLIC_KEY_INPUT.set(Q);
|
|
353
|
+
SIGNATURE_INPUT.set(signature);
|
|
354
|
+
return wasm.verifySchnorr() === 1 ? true : false;
|
|
355
|
+
}
|
|
356
|
+
finally {
|
|
357
|
+
HASH_INPUT.fill(0);
|
|
358
|
+
X_ONLY_PUBLIC_KEY_INPUT.fill(0);
|
|
359
|
+
SIGNATURE_INPUT.fill(0);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function generateInt32(): number;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
function get4RandomBytes() {
|
|
2
|
+
const bytes = new Uint8Array(4);
|
|
3
|
+
if (typeof crypto === "undefined") {
|
|
4
|
+
throw new Error("The crypto object is unavailable. This may occur if your environment does not support the Web Cryptography API.");
|
|
5
|
+
}
|
|
6
|
+
crypto.getRandomValues(bytes);
|
|
7
|
+
return bytes;
|
|
8
|
+
}
|
|
9
|
+
// Only to be used to initialize the context for rust-secp256k1
|
|
10
|
+
export function generateInt32() {
|
|
11
|
+
const array = get4RandomBytes();
|
|
12
|
+
return ((array[0] << (3 * 8)) +
|
|
13
|
+
(array[1] << (2 * 8)) +
|
|
14
|
+
(array[2] << (1 * 8)) +
|
|
15
|
+
array[3]);
|
|
16
|
+
}
|
package/lib/rand.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function generateInt32(): number;
|
package/lib/rand.js
ADDED