ecash-lib 1.2.2-rc9 → 1.4.0

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 (125) hide show
  1. package/README.md +2 -1
  2. package/dist/ecc.d.ts +12 -0
  3. package/dist/ecc.d.ts.map +1 -1
  4. package/dist/ecc.js +9 -47
  5. package/dist/ecc.js.map +1 -1
  6. package/dist/ffi/ecash_lib_wasm_bg_browser.wasm +0 -0
  7. package/dist/ffi/ecash_lib_wasm_bg_browser.wasm.d.ts +18 -4
  8. package/dist/ffi/ecash_lib_wasm_bg_nodejs.wasm +0 -0
  9. package/dist/ffi/ecash_lib_wasm_bg_nodejs.wasm.d.ts +18 -4
  10. package/dist/ffi/ecash_lib_wasm_browser.d.ts +95 -4
  11. package/dist/ffi/ecash_lib_wasm_browser.js +245 -14
  12. package/dist/ffi/ecash_lib_wasm_nodejs.d.ts +77 -0
  13. package/dist/ffi/ecash_lib_wasm_nodejs.js +247 -14
  14. package/dist/hash.d.ts +21 -1
  15. package/dist/hash.d.ts.map +1 -1
  16. package/dist/hash.js +16 -10
  17. package/dist/hash.js.map +1 -1
  18. package/dist/hdwallet.d.ts +33 -0
  19. package/dist/hdwallet.d.ts.map +1 -0
  20. package/dist/hdwallet.js +148 -0
  21. package/dist/hdwallet.js.map +1 -0
  22. package/dist/hmac.d.ts +13 -0
  23. package/dist/hmac.d.ts.map +1 -0
  24. package/dist/hmac.js +63 -0
  25. package/dist/hmac.js.map +1 -0
  26. package/dist/index.d.ts +3 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +3 -1
  29. package/dist/index.js.map +1 -1
  30. package/dist/initBrowser.d.ts.map +1 -1
  31. package/dist/initBrowser.js +3 -0
  32. package/dist/initBrowser.js.map +1 -1
  33. package/dist/initNodeJs.d.ts.map +1 -1
  34. package/dist/initNodeJs.js +3 -0
  35. package/dist/initNodeJs.js.map +1 -1
  36. package/dist/io/bytes.d.ts +5 -3
  37. package/dist/io/bytes.d.ts.map +1 -1
  38. package/dist/io/bytes.js +15 -7
  39. package/dist/io/bytes.js.map +1 -1
  40. package/dist/io/writer.d.ts +4 -3
  41. package/dist/io/writer.d.ts.map +1 -1
  42. package/dist/io/writerbytes.d.ts +4 -3
  43. package/dist/io/writerbytes.d.ts.map +1 -1
  44. package/dist/io/writerbytes.js +7 -6
  45. package/dist/io/writerbytes.js.map +1 -1
  46. package/dist/io/writerlength.d.ts +4 -3
  47. package/dist/io/writerlength.d.ts.map +1 -1
  48. package/dist/io/writerlength.js +3 -3
  49. package/dist/io/writerlength.js.map +1 -1
  50. package/dist/mnemonic.d.ts +14 -0
  51. package/dist/mnemonic.d.ts.map +1 -0
  52. package/dist/mnemonic.js +123 -0
  53. package/dist/mnemonic.js.map +1 -0
  54. package/dist/pbkdf2.d.ts +11 -0
  55. package/dist/pbkdf2.d.ts.map +1 -0
  56. package/dist/pbkdf2.js +36 -0
  57. package/dist/pbkdf2.js.map +1 -0
  58. package/dist/script.d.ts +4 -0
  59. package/dist/script.d.ts.map +1 -1
  60. package/dist/script.js +6 -0
  61. package/dist/script.js.map +1 -1
  62. package/package.json +1 -1
  63. package/src/address/address.ts +346 -0
  64. package/src/address/legacyaddr.ts +129 -0
  65. package/src/consts.ts +8 -0
  66. package/src/ecc.ts +61 -0
  67. package/src/ffi/ecash_lib_wasm_bg_browser.wasm +0 -0
  68. package/src/ffi/ecash_lib_wasm_bg_browser.wasm.d.ts +32 -0
  69. package/src/ffi/ecash_lib_wasm_bg_nodejs.wasm +0 -0
  70. package/src/ffi/ecash_lib_wasm_bg_nodejs.wasm.d.ts +32 -0
  71. package/src/ffi/ecash_lib_wasm_browser.d.ts +183 -0
  72. package/src/ffi/ecash_lib_wasm_browser.js +571 -0
  73. package/src/ffi/ecash_lib_wasm_nodejs.d.ts +127 -0
  74. package/src/ffi/ecash_lib_wasm_nodejs.js +498 -0
  75. package/src/hash.ts +46 -0
  76. package/src/hdwallet.ts +181 -0
  77. package/src/hmac.ts +74 -0
  78. package/src/index.ts +29 -0
  79. package/src/indexBrowser.ts +6 -0
  80. package/src/indexNodeJs.ts +6 -0
  81. package/src/initBrowser.ts +21 -0
  82. package/src/initNodeJs.ts +20 -0
  83. package/src/io/bytes.ts +80 -0
  84. package/src/io/hex.ts +69 -0
  85. package/src/io/int.ts +6 -0
  86. package/src/io/str.ts +16 -0
  87. package/src/io/varsize.ts +49 -0
  88. package/src/io/writer.ts +20 -0
  89. package/src/io/writerbytes.ts +87 -0
  90. package/src/io/writerlength.ts +44 -0
  91. package/src/mnemonic.ts +153 -0
  92. package/src/op.ts +162 -0
  93. package/src/opcode.ts +154 -0
  94. package/src/pbkdf2.ts +52 -0
  95. package/src/script.ts +195 -0
  96. package/src/sigHashType.ts +190 -0
  97. package/src/test/testRunner.ts +209 -0
  98. package/src/token/alp.ts +146 -0
  99. package/src/token/common.ts +32 -0
  100. package/src/token/empp.ts +29 -0
  101. package/src/token/slp.ts +212 -0
  102. package/src/tx.ts +180 -0
  103. package/src/txBuilder.ts +262 -0
  104. package/src/unsignedTx.ts +359 -0
  105. package/tsconfig.json +2 -1
  106. package/wordlists/english.json +2053 -0
  107. package/.nyc_output/0fc40ca6-d52c-45eb-b31b-2601ce70b887.json +0 -1
  108. package/.nyc_output/ac5be6db-4e40-41f8-8b84-7598d4747e57.json +0 -1
  109. package/.nyc_output/b316d46f-5ea0-4e98-884a-bfbf9cc1d0f8.json +0 -1
  110. package/.nyc_output/f965566b-9422-4874-b45e-9eefda9c769c.json +0 -1
  111. package/.nyc_output/processinfo/0fc40ca6-d52c-45eb-b31b-2601ce70b887.json +0 -1
  112. package/.nyc_output/processinfo/ac5be6db-4e40-41f8-8b84-7598d4747e57.json +0 -1
  113. package/.nyc_output/processinfo/b316d46f-5ea0-4e98-884a-bfbf9cc1d0f8.json +0 -1
  114. package/.nyc_output/processinfo/f965566b-9422-4874-b45e-9eefda9c769c.json +0 -1
  115. package/.nyc_output/processinfo/index.json +0 -1
  116. package/dist/address/cashaddr.d.ts +0 -78
  117. package/dist/address/cashaddr.d.ts.map +0 -1
  118. package/dist/address/cashaddr.js +0 -543
  119. package/dist/address/cashaddr.js.map +0 -1
  120. package/dist/cashaddr/cashaddr.d.ts +0 -23
  121. package/dist/cashaddr/cashaddr.d.ts.map +0 -1
  122. package/dist/cashaddr/cashaddr.js +0 -325
  123. package/dist/cashaddr/cashaddr.js.map +0 -1
  124. package/global.d.ts +0 -64
  125. package/test.log +0 -82
@@ -0,0 +1,44 @@
1
+ // Copyright (c) 2024 The Bitcoin developers
2
+ // Distributed under the MIT software license, see the accompanying
3
+ // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
+
5
+ import { Endian } from './bytes.js';
6
+ import { Int } from './int.js';
7
+ import { Writer } from './writer.js';
8
+
9
+ /**
10
+ * Writer implementation which only measures the length of the serialized
11
+ * output but doesn't actually store any byte data.
12
+ **/
13
+ export class WriterLength implements Writer {
14
+ public length: number;
15
+
16
+ public constructor() {
17
+ this.length = 0;
18
+ }
19
+
20
+ /** Write a single byte */
21
+ public putU8(_value: Int): void {
22
+ this.length++;
23
+ }
24
+
25
+ /** Write a 2-byte little-endian integer (uint16_t) */
26
+ public putU16(_value: Int, _endian?: Endian): void {
27
+ this.length += 2;
28
+ }
29
+
30
+ /** Write a 4-byte little-endian integer (uint32_t) */
31
+ public putU32(_value: Int, _endian?: Endian): void {
32
+ this.length += 4;
33
+ }
34
+
35
+ /** Write an 8-byte little-endian integer (uint64_t) */
36
+ public putU64(_value: Int, _endian?: Endian): void {
37
+ this.length += 8;
38
+ }
39
+
40
+ /** Write the given bytes */
41
+ public putBytes(bytes: Uint8Array): void {
42
+ this.length += bytes.length;
43
+ }
44
+ }
@@ -0,0 +1,153 @@
1
+ // Copyright (c) 2025 The Bitcoin developers
2
+ // Distributed under the MIT software license, see the accompanying
3
+ // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
+
5
+ import { sha256, sha512Hasher } from './hash';
6
+ import { strToBytes } from './indexNodeJs';
7
+ import { pbkdf2 } from './pbkdf2';
8
+
9
+ const BITS_PER_BYTE = 8;
10
+ const BITS_PER_WORD = 11;
11
+ const BITS_PER_CHECKSUM_BIT = 32;
12
+
13
+ // Calculate how many bits there are in the mnemonic
14
+ function calcNumChecksumBits(numEntropyBytes: number): number {
15
+ return (numEntropyBytes * BITS_PER_BYTE) / BITS_PER_CHECKSUM_BIT;
16
+ }
17
+
18
+ // Normalize according to unicode standard
19
+ function normalize(str?: string): string {
20
+ return (str || '').normalize('NFKD');
21
+ }
22
+
23
+ // Turn the password into a salt for seed generation
24
+ function salt(password?: string): string {
25
+ return 'mnemonic' + (password || '');
26
+ }
27
+
28
+ /** Word list to generate a seed phrase. */
29
+ export interface WordList {
30
+ /** Word separator of the seed phrase (Japanese has \u3000 as space) */
31
+ separator: string;
32
+ /** Words in the word list to generate a mnemonic phrase */
33
+ words: string[];
34
+ }
35
+
36
+ /** Derive the mnemonic from entropy */
37
+ export function entropyToMnemonic(
38
+ entropy: Uint8Array,
39
+ wordlist: WordList,
40
+ ): string {
41
+ if (entropy.length < 16 || entropy.length > 32) {
42
+ throw new TypeError('Entropy must be between 16 and 32 bytes long');
43
+ }
44
+ if (entropy.length % 4 !== 0) {
45
+ throw new TypeError('Entropy length must be divisible by 4');
46
+ }
47
+
48
+ const checksum = sha256(entropy);
49
+ const data = new Uint8Array(entropy.length + checksum.length);
50
+ data.set(entropy, 0);
51
+ data.set(checksum, entropy.length);
52
+
53
+ let nextBits = 0;
54
+ let numBits = 0;
55
+ let numLeftoverBits =
56
+ entropy.length * BITS_PER_BYTE + calcNumChecksumBits(entropy.length);
57
+ const words = [];
58
+ for (const byte of data) {
59
+ nextBits = (nextBits << BITS_PER_BYTE) | byte;
60
+ numBits += BITS_PER_BYTE;
61
+ if (numBits >= BITS_PER_WORD) {
62
+ const wordIdx = nextBits >> (numBits - BITS_PER_WORD);
63
+ words.push(wordlist.words[wordIdx]);
64
+ if (numLeftoverBits <= BITS_PER_WORD) {
65
+ break;
66
+ }
67
+ numBits -= BITS_PER_WORD;
68
+ numLeftoverBits -= BITS_PER_WORD;
69
+ nextBits &= 0x7ff >> (BITS_PER_WORD - numBits);
70
+ }
71
+ }
72
+
73
+ return words.join(wordlist.separator);
74
+ }
75
+
76
+ /** Recover the entropy from the mnemonic */
77
+ export function mnemonicToEntropy(
78
+ phrase: string,
79
+ wordlist: string[],
80
+ ): Uint8Array {
81
+ const words = normalize(phrase).split(' ');
82
+ if (words.length < 12 || words.length > 24) {
83
+ throw new Error(
84
+ 'Number of words in mnemonic phrase must be between 12 and 24',
85
+ );
86
+ }
87
+ if (words.length % 3 !== 0) {
88
+ throw new Error(
89
+ 'Number of words in mnemonic phrase must be divisible by 3',
90
+ );
91
+ }
92
+
93
+ const wordIndices = words.map(word => {
94
+ const idx = wordlist.indexOf(word);
95
+ if (idx === -1) {
96
+ throw new Error('Invalid mnemonic phrase word: ' + word);
97
+ }
98
+ return idx;
99
+ });
100
+
101
+ const numEntropyBytes = (wordIndices.length / 3) * 4;
102
+ let nextBits = 0;
103
+ let numBits = 0;
104
+ let idx = 0;
105
+ const entropy = new Uint8Array(numEntropyBytes);
106
+ let checksum = 0;
107
+ for (const wordIdx of wordIndices) {
108
+ nextBits = (nextBits << BITS_PER_WORD) | wordIdx;
109
+ numBits += BITS_PER_WORD;
110
+ while (numBits >= BITS_PER_BYTE) {
111
+ const byte = nextBits >> (numBits - BITS_PER_BYTE);
112
+ if (idx < entropy.length) {
113
+ entropy[idx] = byte;
114
+ } else {
115
+ checksum = (checksum << BITS_PER_BYTE) | byte;
116
+ }
117
+ idx++;
118
+ numBits -= BITS_PER_BYTE;
119
+ nextBits &= 0xffff >> (16 - numBits);
120
+ }
121
+ }
122
+ if (numBits != 0) {
123
+ checksum = (checksum << BITS_PER_BYTE) | nextBits;
124
+ }
125
+
126
+ const entropyHash = sha256(entropy);
127
+ const numChecksumBits = calcNumChecksumBits(numEntropyBytes);
128
+ const expectedChecksum =
129
+ entropyHash[0] >> (BITS_PER_BYTE - numChecksumBits);
130
+
131
+ if (checksum != expectedChecksum) {
132
+ const expected = expectedChecksum.toString(16);
133
+ const actual = checksum.toString(16);
134
+ throw new Error(
135
+ `Invalid checksum: expected ${expected}, got ${actual}`,
136
+ );
137
+ }
138
+
139
+ return entropy;
140
+ }
141
+
142
+ /** Derive the seed bytes from the mnemonic */
143
+ export function mnemonicToSeed(phrase: string, password?: string): Uint8Array {
144
+ return pbkdf2({
145
+ hashFactory: sha512Hasher,
146
+ password: strToBytes(normalize(phrase)),
147
+ salt: strToBytes(salt(normalize(password))),
148
+ blockLength: 128,
149
+ outputLength: 64,
150
+ dkLen: 64,
151
+ iterations: 2048,
152
+ });
153
+ }
package/src/op.ts ADDED
@@ -0,0 +1,162 @@
1
+ // Copyright (c) 2024 The Bitcoin developers
2
+ // Distributed under the MIT software license, see the accompanying
3
+ // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
+
5
+ import { Bytes } from './io/bytes.js';
6
+ import { Writer } from './io/writer.js';
7
+ import {
8
+ OP_0,
9
+ OP_1NEGATE,
10
+ OP_PUSHDATA1,
11
+ OP_PUSHDATA2,
12
+ OP_PUSHDATA4,
13
+ Opcode,
14
+ } from './opcode.js';
15
+
16
+ /**
17
+ * A single operation in Bitcoin script, either a singular non-pushop code or
18
+ * a `PushOp` with an opcode and data attached.
19
+ **/
20
+ export type Op = Opcode | PushOp;
21
+
22
+ /**
23
+ * An Op that pushes some data onto the stack, will use `opcode` to push the
24
+ * data
25
+ **/
26
+ export interface PushOp {
27
+ opcode: Opcode;
28
+ data: Uint8Array;
29
+ }
30
+
31
+ /** Returns true if the given object is a `PushOp` */
32
+ export function isPushOp(op: any): op is PushOp {
33
+ if (!op || typeof op !== 'object') {
34
+ return false;
35
+ }
36
+ if (!op.hasOwnProperty('opcode') || !op.hasOwnProperty('data')) {
37
+ return false;
38
+ }
39
+ return typeof op.opcode === 'number' && op.data instanceof Uint8Array;
40
+ }
41
+
42
+ /** Read a single Script operation from the bytes */
43
+ export function readOp(bytes: Bytes): Op {
44
+ const opcode = bytes.readU8();
45
+ let numBytes: number;
46
+ switch (opcode) {
47
+ case OP_PUSHDATA1:
48
+ numBytes = bytes.readU8();
49
+ break;
50
+ case OP_PUSHDATA2:
51
+ numBytes = bytes.readU16();
52
+ break;
53
+ case OP_PUSHDATA4:
54
+ numBytes = bytes.readU32();
55
+ break;
56
+ default:
57
+ if (opcode < 0x01 || opcode > 0x4b) {
58
+ // Non-push opcode
59
+ return opcode;
60
+ }
61
+ numBytes = opcode;
62
+ }
63
+ const data = bytes.readBytes(numBytes);
64
+ return { opcode, data };
65
+ }
66
+
67
+ /** Write a Script operation to the writer */
68
+ export function writeOp(op: Op, writer: Writer) {
69
+ if (typeof op == 'number') {
70
+ writer.putU8(op);
71
+ return;
72
+ }
73
+ if (!isPushOp(op)) {
74
+ throw `Unexpected op: ${op}`;
75
+ }
76
+ writer.putU8(op.opcode);
77
+ switch (op.opcode) {
78
+ case OP_PUSHDATA1:
79
+ writer.putU8(op.data.length);
80
+ break;
81
+ case OP_PUSHDATA2:
82
+ writer.putU16(op.data.length);
83
+ break;
84
+ case OP_PUSHDATA4:
85
+ writer.putU32(op.data.length);
86
+ break;
87
+ default:
88
+ if (op.opcode < 0 || op.opcode > 0x4b) {
89
+ throw `Not a pushop opcode: 0x${op.opcode.toString(16)}`;
90
+ }
91
+ if (op.opcode != op.data.length) {
92
+ throw (
93
+ `Inconsistent PushOp, claims to push ${op.opcode} bytes ` +
94
+ `but actually has ${op.data.length} bytes attached`
95
+ );
96
+ }
97
+ }
98
+ writer.putBytes(op.data);
99
+ }
100
+
101
+ /** Return an Op that minimally pushes the given bytes onto the stack */
102
+ export function pushBytesOp(data: Uint8Array): Op {
103
+ if (data.length == 0) {
104
+ return OP_0;
105
+ } else if (data.length == 1) {
106
+ if (data[0] >= 1 && data[0] <= 16) {
107
+ return data[0] + 0x50;
108
+ } else if (data[0] == 0x81) {
109
+ return OP_1NEGATE;
110
+ }
111
+ }
112
+ let opcode: Opcode;
113
+ if (data.length >= 0x01 && data.length <= 0x4b) {
114
+ opcode = data.length;
115
+ } else if (data.length >= 0x4c && data.length <= 0xff) {
116
+ opcode = OP_PUSHDATA1;
117
+ } else if (data.length >= 0x100 && data.length <= 0xffff) {
118
+ opcode = OP_PUSHDATA2;
119
+ } else if (data.length >= 0x10000 && data.length <= 0xffffffff) {
120
+ opcode = OP_PUSHDATA4;
121
+ } else {
122
+ throw 'Bytes way too large';
123
+ }
124
+ return { opcode, data };
125
+ }
126
+
127
+ /**
128
+ * Returns an Op that pushes the minimally encoded byte representation of a
129
+ * number to the stack. The bytes pushed to the stack can be used directly
130
+ * without the need for OP_BIN2NUM.
131
+ */
132
+ export function pushNumberOp(value: number | bigint): Op {
133
+ if (value == 0) {
134
+ return OP_0;
135
+ }
136
+
137
+ // Prepare number for encoding. The algorithm below replicates the one used
138
+ // in `src/script/script.h` intentionally to avoid discrepancies.
139
+ const auxValue = BigInt(value);
140
+ let bytes: number[] = [];
141
+ let negative = auxValue < 0;
142
+ let absvalue = negative ? ~auxValue + 1n : auxValue;
143
+
144
+ // Encode value in little endian byte order by iteratively pushing the
145
+ // least significant byte until shifting right 1 more byte produces 0
146
+ while (absvalue) {
147
+ bytes.push(Number(absvalue & 0xffn));
148
+ absvalue >>= 8n;
149
+ }
150
+
151
+ // The MSB will encode the sign which means that, if the previous encoding
152
+ // of the absolute value uses that bit, a new byte must be added to encode
153
+ // the sign. If bit is not set, then it must be set for negative numbers.
154
+ let last = bytes[bytes.length - 1];
155
+ if (last & 0x80) {
156
+ bytes.push(negative ? 0x80 : 0x00);
157
+ } else if (negative) {
158
+ bytes[bytes.length - 1] = last | 0x80;
159
+ }
160
+
161
+ return pushBytesOp(Uint8Array.from(bytes));
162
+ }
package/src/opcode.ts ADDED
@@ -0,0 +1,154 @@
1
+ // Copyright (c) 2024 The Bitcoin developers
2
+ // Distributed under the MIT software license, see the accompanying
3
+ // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
+
5
+ // Script opcodes, from /src/script/script.h
6
+
7
+ export type Opcode = number;
8
+
9
+ // push value
10
+ export const OP_0 = 0x00;
11
+ export const OP_FALSE = OP_0;
12
+ export const OP_PUSHDATA1 = 0x4c;
13
+ export const OP_PUSHDATA2 = 0x4d;
14
+ export const OP_PUSHDATA4 = 0x4e;
15
+ export const OP_1NEGATE = 0x4f;
16
+ export const OP_RESERVED = 0x50;
17
+ export const OP_1 = 0x51;
18
+ export const OP_TRUE = OP_1;
19
+ export const OP_2 = 0x52;
20
+ export const OP_3 = 0x53;
21
+ export const OP_4 = 0x54;
22
+ export const OP_5 = 0x55;
23
+ export const OP_6 = 0x56;
24
+ export const OP_7 = 0x57;
25
+ export const OP_8 = 0x58;
26
+ export const OP_9 = 0x59;
27
+ export const OP_10 = 0x5a;
28
+ export const OP_11 = 0x5b;
29
+ export const OP_12 = 0x5c;
30
+ export const OP_13 = 0x5d;
31
+ export const OP_14 = 0x5e;
32
+ export const OP_15 = 0x5f;
33
+ export const OP_16 = 0x60;
34
+
35
+ // control
36
+ export const OP_NOP = 0x61;
37
+ export const OP_VER = 0x62;
38
+ export const OP_IF = 0x63;
39
+ export const OP_NOTIF = 0x64;
40
+ export const OP_VERIF = 0x65;
41
+ export const OP_VERNOTIF = 0x66;
42
+ export const OP_ELSE = 0x67;
43
+ export const OP_ENDIF = 0x68;
44
+ export const OP_VERIFY = 0x69;
45
+ export const OP_RETURN = 0x6a;
46
+
47
+ // stack ops
48
+ export const OP_TOALTSTACK = 0x6b;
49
+ export const OP_FROMALTSTACK = 0x6c;
50
+ export const OP_2DROP = 0x6d;
51
+ export const OP_2DUP = 0x6e;
52
+ export const OP_3DUP = 0x6f;
53
+ export const OP_2OVER = 0x70;
54
+ export const OP_2ROT = 0x71;
55
+ export const OP_2SWAP = 0x72;
56
+ export const OP_IFDUP = 0x73;
57
+ export const OP_DEPTH = 0x74;
58
+ export const OP_DROP = 0x75;
59
+ export const OP_DUP = 0x76;
60
+ export const OP_NIP = 0x77;
61
+ export const OP_OVER = 0x78;
62
+ export const OP_PICK = 0x79;
63
+ export const OP_ROLL = 0x7a;
64
+ export const OP_ROT = 0x7b;
65
+ export const OP_SWAP = 0x7c;
66
+ export const OP_TUCK = 0x7d;
67
+
68
+ // splice ops
69
+ export const OP_CAT = 0x7e;
70
+ export const OP_SPLIT = 0x7f; // after monolith upgrade (May 2018)
71
+ export const OP_NUM2BIN = 0x80; // after monolith upgrade (May 2018)
72
+ export const OP_BIN2NUM = 0x81; // after monolith upgrade (May 2018)
73
+ export const OP_SIZE = 0x82;
74
+
75
+ // bit logic
76
+ export const OP_INVERT = 0x83;
77
+ export const OP_AND = 0x84;
78
+ export const OP_OR = 0x85;
79
+ export const OP_XOR = 0x86;
80
+ export const OP_EQUAL = 0x87;
81
+ export const OP_EQUALVERIFY = 0x88;
82
+ export const OP_RESERVED1 = 0x89;
83
+ export const OP_RESERVED2 = 0x8a;
84
+
85
+ // numeric
86
+ export const OP_1ADD = 0x8b;
87
+ export const OP_1SUB = 0x8c;
88
+ export const OP_2MUL = 0x8d;
89
+ export const OP_2DIV = 0x8e;
90
+ export const OP_NEGATE = 0x8f;
91
+ export const OP_ABS = 0x90;
92
+ export const OP_NOT = 0x91;
93
+ export const OP_0NOTEQUAL = 0x92;
94
+
95
+ export const OP_ADD = 0x93;
96
+ export const OP_SUB = 0x94;
97
+ export const OP_MUL = 0x95;
98
+ export const OP_DIV = 0x96;
99
+ export const OP_MOD = 0x97;
100
+ export const OP_LSHIFT = 0x98;
101
+ export const OP_RSHIFT = 0x99;
102
+
103
+ export const OP_BOOLAND = 0x9a;
104
+ export const OP_BOOLOR = 0x9b;
105
+ export const OP_NUMEQUAL = 0x9c;
106
+ export const OP_NUMEQUALVERIFY = 0x9d;
107
+ export const OP_NUMNOTEQUAL = 0x9e;
108
+ export const OP_LESSTHAN = 0x9f;
109
+ export const OP_GREATERTHAN = 0xa0;
110
+ export const OP_LESSTHANOREQUAL = 0xa1;
111
+ export const OP_GREATERTHANOREQUAL = 0xa2;
112
+ export const OP_MIN = 0xa3;
113
+ export const OP_MAX = 0xa4;
114
+
115
+ export const OP_WITHIN = 0xa5;
116
+
117
+ // crypto
118
+ export const OP_RIPEMD160 = 0xa6;
119
+ export const OP_SHA1 = 0xa7;
120
+ export const OP_SHA256 = 0xa8;
121
+ export const OP_HASH160 = 0xa9;
122
+ export const OP_HASH256 = 0xaa;
123
+ export const OP_CODESEPARATOR = 0xab;
124
+ export const OP_CHECKSIG = 0xac;
125
+ export const OP_CHECKSIGVERIFY = 0xad;
126
+ export const OP_CHECKMULTISIG = 0xae;
127
+ export const OP_CHECKMULTISIGVERIFY = 0xaf;
128
+
129
+ // expansion
130
+ export const OP_NOP1 = 0xb0;
131
+ export const OP_CHECKLOCKTIMEVERIFY = 0xb1;
132
+ export const OP_NOP2 = OP_CHECKLOCKTIMEVERIFY;
133
+ export const OP_CHECKSEQUENCEVERIFY = 0xb2;
134
+ export const OP_NOP3 = OP_CHECKSEQUENCEVERIFY;
135
+ export const OP_NOP4 = 0xb3;
136
+ export const OP_NOP5 = 0xb4;
137
+ export const OP_NOP6 = 0xb5;
138
+ export const OP_NOP7 = 0xb6;
139
+ export const OP_NOP8 = 0xb7;
140
+ export const OP_NOP9 = 0xb8;
141
+ export const OP_NOP10 = 0xb9;
142
+
143
+ // More crypto
144
+ export const OP_CHECKDATASIG = 0xba;
145
+ export const OP_CHECKDATASIGVERIFY = 0xbb;
146
+
147
+ // additional byte string operations
148
+ export const OP_REVERSEBYTES = 0xbc;
149
+
150
+ // multi-byte opcodes
151
+ export const OP_PREFIX_BEGIN = 0xf0;
152
+ export const OP_PREFIX_END = 0xf7;
153
+
154
+ export const OP_INVALIDOPCODE = 0xff;
package/src/pbkdf2.ts ADDED
@@ -0,0 +1,52 @@
1
+ // Copyright (c) 2025 The Bitcoin developers
2
+ // Distributed under the MIT software license, see the accompanying
3
+ // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
+
5
+ import { Hasher } from './hash';
6
+ import { Hmac } from './hmac';
7
+
8
+ export function pbkdf2(params: {
9
+ hashFactory: () => Hasher;
10
+ password: Uint8Array;
11
+ salt: Uint8Array;
12
+ blockLength: number;
13
+ outputLength: number;
14
+ dkLen: number;
15
+ iterations: number;
16
+ }): Uint8Array {
17
+ const arr = new Uint8Array(4);
18
+ const view = new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
19
+ const result = new Uint8Array(params.dkLen);
20
+ const prf = new Hmac(
21
+ params.hashFactory,
22
+ params.blockLength,
23
+ params.password,
24
+ );
25
+ const prfSalt = prf.clone();
26
+ prfSalt.update(params.salt);
27
+
28
+ for (
29
+ let idx = 1, pos = 0;
30
+ pos < params.dkLen;
31
+ idx++, pos += params.outputLength
32
+ ) {
33
+ const ti = result.subarray(pos, pos + params.outputLength);
34
+ view.setInt32(0, idx, false);
35
+ const prfSaltClone = prfSalt.clone();
36
+ prfSaltClone.update(arr);
37
+ let u = prfSaltClone.digest();
38
+ ti.set(u.subarray(0, ti.length));
39
+ for (let ui = 1; ui < params.iterations; ui++) {
40
+ const prfClone = prf.clone();
41
+ prfClone.update(u);
42
+ u = prfClone.digest();
43
+ for (let i = 0; i < ti.length; i++) {
44
+ ti[i] ^= u[i];
45
+ }
46
+ }
47
+ }
48
+
49
+ prf.free();
50
+ prfSalt.free();
51
+ return result;
52
+ }