@bsv/sdk 1.0.13 → 1.0.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.
- package/README.md +1 -1
- package/dist/cjs/package.json +2 -2
- package/dist/cjs/src/compat/BSM.js.map +1 -1
- package/dist/cjs/src/compat/ECIES.js +105 -76
- package/dist/cjs/src/compat/ECIES.js.map +1 -1
- package/dist/cjs/src/compat/HD.js +65 -65
- package/dist/cjs/src/compat/HD.js.map +1 -1
- package/dist/cjs/src/compat/Mnemonic.js +79 -79
- package/dist/cjs/src/compat/Mnemonic.js.map +1 -1
- package/dist/cjs/src/compat/bip-39-wordlist-en.js +2 -2
- package/dist/cjs/src/compat/bip-39-wordlist-en.js.map +1 -1
- package/dist/cjs/src/primitives/AESGCM.js.map +1 -1
- package/dist/cjs/src/primitives/BigNumber.js.map +1 -1
- package/dist/cjs/src/primitives/DRBG.js.map +1 -1
- package/dist/cjs/src/primitives/ECDSA.js.map +1 -1
- package/dist/cjs/src/primitives/Hash.js +26 -13
- package/dist/cjs/src/primitives/Hash.js.map +1 -1
- package/dist/cjs/src/primitives/PrivateKey.js +3 -2
- package/dist/cjs/src/primitives/PrivateKey.js.map +1 -1
- package/dist/cjs/src/primitives/PublicKey.js +1 -2
- package/dist/cjs/src/primitives/PublicKey.js.map +1 -1
- package/dist/cjs/src/primitives/Random.js +2 -2
- package/dist/cjs/src/primitives/Random.js.map +1 -1
- package/dist/cjs/src/primitives/Signature.js +141 -4
- package/dist/cjs/src/primitives/Signature.js.map +1 -1
- package/dist/cjs/src/primitives/SymmetricKey.js.map +1 -1
- package/dist/cjs/src/primitives/TransactionSignature.js.map +1 -1
- package/dist/cjs/src/primitives/utils.js +14 -9
- package/dist/cjs/src/primitives/utils.js.map +1 -1
- package/dist/cjs/src/script/Spend.js.map +1 -1
- package/dist/cjs/src/script/templates/P2PKH.js +1 -1
- package/dist/cjs/src/script/templates/P2PKH.js.map +1 -1
- package/dist/cjs/src/transaction/MerklePath.js +3 -3
- package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
- package/dist/cjs/src/transaction/Transaction.js +2 -2
- package/dist/cjs/src/transaction/Transaction.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/compat/BSM.js.map +1 -1
- package/dist/esm/src/compat/ECIES.js +105 -76
- package/dist/esm/src/compat/ECIES.js.map +1 -1
- package/dist/esm/src/compat/HD.js +65 -65
- package/dist/esm/src/compat/HD.js.map +1 -1
- package/dist/esm/src/compat/Mnemonic.js +79 -79
- package/dist/esm/src/compat/Mnemonic.js.map +1 -1
- package/dist/esm/src/compat/bip-39-wordlist-en.js +2 -2
- package/dist/esm/src/compat/bip-39-wordlist-en.js.map +1 -1
- package/dist/esm/src/primitives/AESGCM.js.map +1 -1
- package/dist/esm/src/primitives/BigNumber.js.map +1 -1
- package/dist/esm/src/primitives/DRBG.js.map +1 -1
- package/dist/esm/src/primitives/ECDSA.js.map +1 -1
- package/dist/esm/src/primitives/Hash.js +26 -13
- package/dist/esm/src/primitives/Hash.js.map +1 -1
- package/dist/esm/src/primitives/PrivateKey.js +3 -2
- package/dist/esm/src/primitives/PrivateKey.js.map +1 -1
- package/dist/esm/src/primitives/PublicKey.js +1 -2
- package/dist/esm/src/primitives/PublicKey.js.map +1 -1
- package/dist/esm/src/primitives/Random.js +2 -2
- package/dist/esm/src/primitives/Random.js.map +1 -1
- package/dist/esm/src/primitives/Signature.js +141 -4
- package/dist/esm/src/primitives/Signature.js.map +1 -1
- package/dist/esm/src/primitives/SymmetricKey.js.map +1 -1
- package/dist/esm/src/primitives/TransactionSignature.js.map +1 -1
- package/dist/esm/src/primitives/utils.js +14 -9
- package/dist/esm/src/primitives/utils.js.map +1 -1
- package/dist/esm/src/script/Spend.js.map +1 -1
- package/dist/esm/src/script/templates/P2PKH.js +1 -1
- package/dist/esm/src/script/templates/P2PKH.js.map +1 -1
- package/dist/esm/src/transaction/MerklePath.js +3 -3
- package/dist/esm/src/transaction/MerklePath.js.map +1 -1
- package/dist/esm/src/transaction/Transaction.js +2 -2
- package/dist/esm/src/transaction/Transaction.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/compat/ECIES.d.ts +36 -36
- package/dist/types/src/compat/ECIES.d.ts.map +1 -1
- package/dist/types/src/compat/HD.d.ts +65 -65
- package/dist/types/src/compat/HD.d.ts.map +1 -1
- package/dist/types/src/compat/Mnemonic.d.ts +79 -79
- package/dist/types/src/compat/Mnemonic.d.ts.map +1 -1
- package/dist/types/src/primitives/AESGCM.d.ts.map +1 -1
- package/dist/types/src/primitives/BigNumber.d.ts.map +1 -1
- package/dist/types/src/primitives/Hash.d.ts.map +1 -1
- package/dist/types/src/primitives/PrivateKey.d.ts.map +1 -1
- package/dist/types/src/primitives/PublicKey.d.ts.map +1 -1
- package/dist/types/src/primitives/Signature.d.ts +62 -0
- package/dist/types/src/primitives/Signature.d.ts.map +1 -1
- package/dist/types/src/primitives/SymmetricKey.d.ts.map +1 -1
- package/dist/types/src/primitives/TransactionSignature.d.ts.map +1 -1
- package/dist/types/src/primitives/utils.d.ts.map +1 -1
- package/dist/types/src/script/Spend.d.ts.map +1 -1
- package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/docs/compat.md +4 -4
- package/docs/primitives.md +288 -79
- package/mod.ts +8 -0
- package/package.json +5 -3
- package/src/compat/BSM.ts +12 -12
- package/src/compat/ECIES.ts +417 -418
- package/src/compat/HD.ts +228 -228
- package/src/compat/Mnemonic.ts +173 -173
- package/src/compat/__tests/BSM.test.ts +13 -2
- package/src/compat/bip-39-wordlist-en.ts +2052 -2052
- package/src/primitives/AESGCM.ts +30 -30
- package/src/primitives/BigNumber.ts +0 -1
- package/src/primitives/DRBG.ts +5 -5
- package/src/primitives/ECDSA.ts +1 -1
- package/src/primitives/Hash.ts +278 -293
- package/src/primitives/PrivateKey.ts +18 -19
- package/src/primitives/PublicKey.ts +9 -10
- package/src/primitives/Random.ts +4 -4
- package/src/primitives/Signature.ts +158 -14
- package/src/primitives/SymmetricKey.ts +3 -3
- package/src/primitives/TransactionSignature.ts +9 -9
- package/src/primitives/index.ts +1 -1
- package/src/primitives/utils.ts +60 -64
- package/src/script/Spend.ts +12 -12
- package/src/script/index.ts +1 -1
- package/src/script/templates/P2PKH.ts +1 -1
- package/src/transaction/MerklePath.ts +3 -3
- package/src/transaction/Transaction.ts +23 -23
|
@@ -75,7 +75,7 @@ export default class PrivateKey extends BigNumber {
|
|
|
75
75
|
* @param base - The base of number provided. By default is 10. Ignored if number is BigNumber.
|
|
76
76
|
*
|
|
77
77
|
* @param endian - The endianness provided. By default is 'big endian'. Ignored if number is BigNumber.
|
|
78
|
-
*
|
|
78
|
+
*
|
|
79
79
|
* @param modN - Optional. Default 'apply. If 'apply', apply modN to input to guarantee a valid PrivateKey. If 'error', if input is out of field throw Error('Input is out of field'). If 'nocheck', assumes input is in field.
|
|
80
80
|
*
|
|
81
81
|
* @example
|
|
@@ -100,7 +100,7 @@ export default class PrivateKey extends BigNumber {
|
|
|
100
100
|
const check = this.checkInField()
|
|
101
101
|
if (!check.inField) {
|
|
102
102
|
if (modN === 'error') {
|
|
103
|
-
throw new Error('Input is out of field')
|
|
103
|
+
throw new Error('Input is out of field')
|
|
104
104
|
}
|
|
105
105
|
// Force the PrivateKey BigNumber value to lie in the field limited by curve.n
|
|
106
106
|
BigNumber.move(this, check.modN)
|
|
@@ -112,7 +112,7 @@ export default class PrivateKey extends BigNumber {
|
|
|
112
112
|
* A utility function to check that the value of this PrivateKey lies in the field limited by curve.n
|
|
113
113
|
* @returns { inField, modN } where modN is this PrivateKey's current BigNumber value mod curve.n, and inField is true only if modN equals current BigNumber value.
|
|
114
114
|
*/
|
|
115
|
-
checkInField()
|
|
115
|
+
checkInField (): { inField: boolean, modN: BigNumber } {
|
|
116
116
|
const curve = new Curve()
|
|
117
117
|
const modN = this.mod(curve.n)
|
|
118
118
|
const inField = this.cmp(modN) === 0
|
|
@@ -122,7 +122,7 @@ export default class PrivateKey extends BigNumber {
|
|
|
122
122
|
/**
|
|
123
123
|
* @returns true if the PrivateKey's current BigNumber value lies in the field limited by curve.n
|
|
124
124
|
*/
|
|
125
|
-
isValid()
|
|
125
|
+
isValid (): boolean {
|
|
126
126
|
return this.checkInField().inField
|
|
127
127
|
}
|
|
128
128
|
|
|
@@ -184,41 +184,40 @@ export default class PrivateKey extends BigNumber {
|
|
|
184
184
|
|
|
185
185
|
/**
|
|
186
186
|
* Converts the private key to a Wallet Import Format (WIF) string.
|
|
187
|
-
*
|
|
187
|
+
*
|
|
188
188
|
* Base58Check encoding is used for encoding the private key.
|
|
189
|
-
* The prefix
|
|
190
|
-
*
|
|
189
|
+
* The prefix
|
|
190
|
+
*
|
|
191
191
|
* @method toWif
|
|
192
192
|
* @returns The WIF string.
|
|
193
|
-
*
|
|
193
|
+
*
|
|
194
194
|
* @param prefix defaults to [0x80] for mainnet, set it to [0xef] for testnet.
|
|
195
|
-
*
|
|
195
|
+
*
|
|
196
196
|
* @throws Error('Value is out of field') if current BigNumber value is out of field limited by curve.n
|
|
197
|
-
*
|
|
197
|
+
*
|
|
198
198
|
* @example
|
|
199
199
|
* const privateKey = PrivateKey.fromRandom();
|
|
200
200
|
* const wif = privateKey.toWif();
|
|
201
201
|
* const testnetWif = privateKey.toWif([0xef]);
|
|
202
202
|
*/
|
|
203
|
-
toWif (prefix
|
|
204
|
-
if (!this.isValid())
|
|
205
|
-
|
|
206
|
-
return toBase58Check([...this.toArray("be", 32), 1], prefix)
|
|
203
|
+
toWif (prefix: number[] = [0x80]): string {
|
|
204
|
+
if (!this.isValid()) { throw new Error('Value is out of field') }
|
|
205
|
+
return toBase58Check([...this.toArray('be', 32), 1], prefix)
|
|
207
206
|
}
|
|
208
207
|
|
|
209
208
|
/**
|
|
210
209
|
* Base58Check encodes the hash of the public key associated with this private key with a prefix to indicate locking script type.
|
|
211
210
|
* Defaults to P2PKH for mainnet, otherwise known as a "Bitcoin Address".
|
|
212
|
-
*
|
|
211
|
+
*
|
|
213
212
|
* @param prefix defaults to [0x00] for mainnet, set to [0x6f] for testnet.
|
|
214
|
-
*
|
|
215
|
-
* @returns Returns the address encoding associated with the hash of the public key associated with this private key.
|
|
216
|
-
*
|
|
213
|
+
*
|
|
214
|
+
* @returns Returns the address encoding associated with the hash of the public key associated with this private key.
|
|
215
|
+
*
|
|
217
216
|
* @example
|
|
218
217
|
* const address = pubkey.toAddress()
|
|
219
218
|
* const testnetAddress = pubkey.toAddress([0x6f])
|
|
220
219
|
*/
|
|
221
|
-
toAddress (prefix
|
|
220
|
+
toAddress (prefix: number[] = [0x00]): string {
|
|
222
221
|
return this.toPublicKey().toAddress(prefix)
|
|
223
222
|
}
|
|
224
223
|
|
|
@@ -3,10 +3,9 @@ import PrivateKey from './PrivateKey.js'
|
|
|
3
3
|
import Curve from './Curve.js'
|
|
4
4
|
import { verify } from './ECDSA.js'
|
|
5
5
|
import BigNumber from './BigNumber.js'
|
|
6
|
-
import { sha256, sha256hmac } from './Hash.js'
|
|
6
|
+
import { sha256, sha256hmac, hash160 } from './Hash.js'
|
|
7
7
|
import Signature from './Signature.js'
|
|
8
8
|
import { toArray, toBase58Check, toHex } from './utils.js'
|
|
9
|
-
import { hash160 } from './Hash.js'
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
11
|
* The PublicKey class extends the Point class. It is used in public-key cryptography to derive shared secret, verify message signatures, and encode the public key in the DER format.
|
|
@@ -128,14 +127,14 @@ export default class PublicKey extends Point {
|
|
|
128
127
|
|
|
129
128
|
/**
|
|
130
129
|
* Hash sha256 and ripemd160 of the public key.
|
|
131
|
-
*
|
|
130
|
+
*
|
|
132
131
|
* @returns Returns the hash of the public key.
|
|
133
|
-
*
|
|
132
|
+
*
|
|
134
133
|
* @example
|
|
135
134
|
* const publicKeyHash = pubkey.toHash()
|
|
136
135
|
*/
|
|
137
136
|
toHash (enc?: 'hex'): number[] | string {
|
|
138
|
-
const pkh = hash160(this.encode(true))
|
|
137
|
+
const pkh = hash160(this.encode(true))
|
|
139
138
|
if (enc === 'hex') {
|
|
140
139
|
return toHex(pkh)
|
|
141
140
|
}
|
|
@@ -145,16 +144,16 @@ export default class PublicKey extends Point {
|
|
|
145
144
|
/**
|
|
146
145
|
* Base58Check encodes the hash of the public key with a prefix to indicate locking script type.
|
|
147
146
|
* Defaults to P2PKH for mainnet, otherwise known as a "Bitcoin Address".
|
|
148
|
-
*
|
|
147
|
+
*
|
|
149
148
|
* @param prefix defaults to [0x00] for mainnet, set to [0x6f] for testnet.
|
|
150
|
-
*
|
|
151
|
-
* @returns Returns the address encoding associated with the hash of the public key.
|
|
152
|
-
*
|
|
149
|
+
*
|
|
150
|
+
* @returns Returns the address encoding associated with the hash of the public key.
|
|
151
|
+
*
|
|
153
152
|
* @example
|
|
154
153
|
* const address = pubkey.toAddress()
|
|
155
154
|
* const testnetAddress = pubkey.toAddress([0x6f])
|
|
156
155
|
*/
|
|
157
|
-
toAddress (prefix
|
|
156
|
+
toAddress (prefix: number[] = [0x00]): string {
|
|
158
157
|
return toBase58Check(this.toHash() as number[], prefix)
|
|
159
158
|
}
|
|
160
159
|
|
package/src/primitives/Random.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
class Rand {
|
|
2
2
|
_rand: Function
|
|
3
|
-
constructor() {
|
|
4
|
-
|
|
3
|
+
constructor () {
|
|
4
|
+
const noRand = () => {
|
|
5
5
|
throw new Error('No secure random number generator is available in this environment.')
|
|
6
6
|
}
|
|
7
7
|
if (typeof self === 'object') {
|
|
@@ -13,7 +13,7 @@ class Rand {
|
|
|
13
13
|
self.crypto.getRandomValues(arr)
|
|
14
14
|
return [...arr]
|
|
15
15
|
}
|
|
16
|
-
} else /*if (typeof window === 'object')*/ {
|
|
16
|
+
} else /* if (typeof window === 'object') */ {
|
|
17
17
|
this._rand = noRand
|
|
18
18
|
}
|
|
19
19
|
} else {
|
|
@@ -29,7 +29,7 @@ class Rand {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
generate(len: number): number[] {
|
|
32
|
+
generate (len: number): number[] {
|
|
33
33
|
return this._rand(len)
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -3,6 +3,8 @@ import PublicKey from './PublicKey.js'
|
|
|
3
3
|
import { verify } from './ECDSA.js'
|
|
4
4
|
import { sha256 } from './Hash.js'
|
|
5
5
|
import { toArray, toHex, toBase64 } from './utils.js'
|
|
6
|
+
import Point from './Point.js'
|
|
7
|
+
import Curve from './Curve.js'
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* Represents a digital signature.
|
|
@@ -39,7 +41,7 @@ export default class Signature {
|
|
|
39
41
|
* @example
|
|
40
42
|
* const signature = Signature.fromDER('30440220018c1f5502f8...', 'hex');
|
|
41
43
|
*/
|
|
42
|
-
static fromDER(data: number[] | string, enc?: 'hex' | 'base64'): Signature {
|
|
44
|
+
static fromDER (data: number[] | string, enc?: 'hex' | 'base64'): Signature {
|
|
43
45
|
const getLength = (buf, p): number => {
|
|
44
46
|
const initial = buf[p.place++]
|
|
45
47
|
if ((initial & 0x80) === 0) {
|
|
@@ -51,20 +53,12 @@ export default class Signature {
|
|
|
51
53
|
|
|
52
54
|
class Position {
|
|
53
55
|
place: number
|
|
54
|
-
constructor() {
|
|
56
|
+
constructor () {
|
|
55
57
|
this.place = 0
|
|
56
58
|
}
|
|
57
59
|
}
|
|
58
60
|
data = toArray(data, enc)
|
|
59
61
|
|
|
60
|
-
// Support compact signatures
|
|
61
|
-
if (data.length === 65) {
|
|
62
|
-
return new Signature(
|
|
63
|
-
new BigNumber(data.slice(1, 33)),
|
|
64
|
-
new BigNumber(data.slice(33, 65))
|
|
65
|
-
)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
62
|
const p = new Position()
|
|
69
63
|
if (data[p.place++] !== 0x30) {
|
|
70
64
|
throw new Error('Signature DER must start with 0x30')
|
|
@@ -108,6 +102,39 @@ export default class Signature {
|
|
|
108
102
|
)
|
|
109
103
|
}
|
|
110
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Takes an array of numbers or a string and returns a new Signature instance.
|
|
107
|
+
* This method will throw an error if the Compact encoding is invalid.
|
|
108
|
+
* If a string is provided, it is assumed to represent a hexadecimal sequence.
|
|
109
|
+
* compactByte value 27-31 means compressed public key.
|
|
110
|
+
* 32-35 means uncompressed public key.
|
|
111
|
+
* The range represents the recovery param which can be 0,1,2,3,4.
|
|
112
|
+
* We could support recovery functions in future if there's demand.
|
|
113
|
+
*
|
|
114
|
+
* @static
|
|
115
|
+
* @method fromCompact
|
|
116
|
+
* @param data - The sequence to decode from Compact encoding.
|
|
117
|
+
* @param enc - The encoding of the data string.
|
|
118
|
+
* @returns The decoded data in the form of Signature instance.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* const signature = Signature.fromCompact('1b18c1f5502f8...', 'hex');
|
|
122
|
+
*/
|
|
123
|
+
static fromCompact (data: number[] | string, enc?: 'hex' | 'base64'): Signature {
|
|
124
|
+
data = toArray(data, enc)
|
|
125
|
+
if (data.length !== 65) {
|
|
126
|
+
throw new Error('Invalid Compact Signature')
|
|
127
|
+
}
|
|
128
|
+
const compactByte = data[0]
|
|
129
|
+
if (compactByte < 27 || compactByte >= 35) {
|
|
130
|
+
throw new Error('Invalid Compact Byte')
|
|
131
|
+
}
|
|
132
|
+
return new Signature(
|
|
133
|
+
new BigNumber(data.slice(1, 33)),
|
|
134
|
+
new BigNumber(data.slice(33, 65))
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
|
|
111
138
|
/**
|
|
112
139
|
* Creates an instance of the Signature class.
|
|
113
140
|
*
|
|
@@ -120,7 +147,7 @@ export default class Signature {
|
|
|
120
147
|
* const s = new BigNumber('564745627577...');
|
|
121
148
|
* const signature = new Signature(r, s);
|
|
122
149
|
*/
|
|
123
|
-
constructor(r: BigNumber, s: BigNumber) {
|
|
150
|
+
constructor (r: BigNumber, s: BigNumber) {
|
|
124
151
|
this.r = r
|
|
125
152
|
this.s = s
|
|
126
153
|
}
|
|
@@ -142,7 +169,7 @@ export default class Signature {
|
|
|
142
169
|
* const publicKey = PublicKey.fromString('04188ca1050...');
|
|
143
170
|
* const isVerified = signature.verify(msg, publicKey);
|
|
144
171
|
*/
|
|
145
|
-
verify(msg: number[] | string, key: PublicKey, enc?: 'hex'): boolean {
|
|
172
|
+
verify (msg: number[] | string, key: PublicKey, enc?: 'hex'): boolean {
|
|
146
173
|
const msgHash = new BigNumber(sha256(msg, enc), 16)
|
|
147
174
|
return verify(msgHash, this, key)
|
|
148
175
|
}
|
|
@@ -162,7 +189,7 @@ export default class Signature {
|
|
|
162
189
|
* @example
|
|
163
190
|
* const der = signature.toString('base64');
|
|
164
191
|
*/
|
|
165
|
-
toString(enc?: 'hex' | 'base64') {
|
|
192
|
+
toString (enc?: 'hex' | 'base64') {
|
|
166
193
|
return this.toDER(enc)
|
|
167
194
|
}
|
|
168
195
|
|
|
@@ -180,7 +207,7 @@ export default class Signature {
|
|
|
180
207
|
* @example
|
|
181
208
|
* const der = signature.toDER('hex');
|
|
182
209
|
*/
|
|
183
|
-
toDER(enc?: 'hex' | 'base64'): number[] | string {
|
|
210
|
+
toDER (enc?: 'hex' | 'base64'): number[] | string {
|
|
184
211
|
const constructLength = (arr, len): void => {
|
|
185
212
|
if (len < 0x80) {
|
|
186
213
|
arr.push(len)
|
|
@@ -232,4 +259,121 @@ export default class Signature {
|
|
|
232
259
|
return res
|
|
233
260
|
}
|
|
234
261
|
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Converts an instance of Signature into Compact encoding.
|
|
265
|
+
*
|
|
266
|
+
* If the encoding parameter is set to 'hex', the function will return a hex string.
|
|
267
|
+
* If 'base64', it will return a base64 string.
|
|
268
|
+
* Otherwise, it will return an array of numbers.
|
|
269
|
+
*
|
|
270
|
+
* @method toCompact
|
|
271
|
+
* @param enc - The encoding to use for the output.
|
|
272
|
+
* @returns The current instance in DER encoding.
|
|
273
|
+
*
|
|
274
|
+
* @example
|
|
275
|
+
* const compact = signature.toCompact(3, true, 'base64');
|
|
276
|
+
*/
|
|
277
|
+
toCompact (recovery: number, compressed: boolean, enc?: 'hex' | 'base64'): number[] | string {
|
|
278
|
+
if (recovery < 0 || recovery > 3) throw new Error('Invalid recovery param')
|
|
279
|
+
if (typeof compressed !== 'boolean') throw new Error('Invalid compressed param')
|
|
280
|
+
let compactByte = 27 + recovery
|
|
281
|
+
if (compressed) {
|
|
282
|
+
compactByte += 4
|
|
283
|
+
}
|
|
284
|
+
let arr = [compactByte]
|
|
285
|
+
arr = arr.concat(this.r.toArray())
|
|
286
|
+
arr = arr.concat(this.s.toArray())
|
|
287
|
+
if (enc === 'hex') {
|
|
288
|
+
return toHex(arr)
|
|
289
|
+
} else if (enc === 'base64') {
|
|
290
|
+
return toBase64(arr)
|
|
291
|
+
} else {
|
|
292
|
+
return arr
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Recovers the public key from a signature.
|
|
298
|
+
* This method will return the public key if it finds a valid public key.
|
|
299
|
+
* If it does not find a valid public key, it will throw an error.
|
|
300
|
+
* The recovery factor is a number between 0 and 3.
|
|
301
|
+
* @method RecoverPublicKey
|
|
302
|
+
* @param recovery - The recovery factor.
|
|
303
|
+
* @param e - The message hash.
|
|
304
|
+
* @returns The public key associated with the signature.
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
* const publicKey = signature.RecoverPublicKey(0, msgHash);
|
|
308
|
+
*/
|
|
309
|
+
RecoverPublicKey (recovery: number, e: BigNumber): PublicKey {
|
|
310
|
+
const r = this.r
|
|
311
|
+
const s = this.s
|
|
312
|
+
|
|
313
|
+
// A set LSB signifies that the y-coordinate is odd
|
|
314
|
+
const isYOdd = !!(recovery & 1)
|
|
315
|
+
|
|
316
|
+
// The more significant bit specifies whether we should use the
|
|
317
|
+
// first or second candidate key.
|
|
318
|
+
const isSecondKey = recovery >> 1
|
|
319
|
+
|
|
320
|
+
const curve = new Curve()
|
|
321
|
+
const n = curve.n
|
|
322
|
+
const G = curve.g
|
|
323
|
+
|
|
324
|
+
// 1.1 LEt x = r + jn
|
|
325
|
+
const x = isSecondKey ? r.add(n) : r
|
|
326
|
+
const R = Point.fromX(x, isYOdd)
|
|
327
|
+
|
|
328
|
+
// 1.4 Check that nR is at infinity
|
|
329
|
+
const nR = R.mul(n)
|
|
330
|
+
if (!nR.isInfinity()) {
|
|
331
|
+
throw new Error('nR is not at infinity')
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Compute -e from e
|
|
335
|
+
const eNeg = e.neg().umod(n)
|
|
336
|
+
|
|
337
|
+
// 1.6.1 Compute Q = r^-1 (sR - eG)
|
|
338
|
+
// Q = r^-1 (sR + -eG)
|
|
339
|
+
const rInv = r.invm(n)
|
|
340
|
+
|
|
341
|
+
// const Q = R.multiplyTwo(s, G, eNeg).mul(rInv)
|
|
342
|
+
const Q = R.mul(s)
|
|
343
|
+
.add(G.mul(eNeg))
|
|
344
|
+
.mul(rInv)
|
|
345
|
+
|
|
346
|
+
const pubKey = new PublicKey(Q)
|
|
347
|
+
pubKey.validate()
|
|
348
|
+
|
|
349
|
+
return pubKey
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Calculates the recovery factor which will work for a particular public key and message hash.
|
|
354
|
+
* This method will return the recovery factor if it finds a valid recovery factor.
|
|
355
|
+
* If it does not find a valid recovery factor, it will throw an error.
|
|
356
|
+
* The recovery factor is a number between 0 and 3.
|
|
357
|
+
*
|
|
358
|
+
* @method CalculateRecoveryFactor
|
|
359
|
+
* @param msgHash - The message hash.
|
|
360
|
+
* @returns the recovery factor: number
|
|
361
|
+
* /
|
|
362
|
+
* @example
|
|
363
|
+
* const recovery = signature.CalculateRecoveryFactor(publicKey, msgHash);
|
|
364
|
+
*/
|
|
365
|
+
CalculateRecoveryFactor (pubkey: PublicKey, msgHash: BigNumber): number {
|
|
366
|
+
for (let recovery = 0; recovery < 4; recovery++) {
|
|
367
|
+
let Qprime
|
|
368
|
+
try {
|
|
369
|
+
Qprime = this.RecoverPublicKey(recovery, msgHash)
|
|
370
|
+
} catch (e) {
|
|
371
|
+
continue
|
|
372
|
+
}
|
|
373
|
+
if (pubkey.eq(Qprime)) {
|
|
374
|
+
return recovery
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
throw new Error('Unable to find valid recovery factor')
|
|
378
|
+
}
|
|
235
379
|
}
|
|
@@ -22,7 +22,7 @@ export default class SymmetricKey extends BigNumber {
|
|
|
22
22
|
* @example
|
|
23
23
|
* const symmetricKey = SymmetricKey.fromRandom();
|
|
24
24
|
*/
|
|
25
|
-
static fromRandom(): SymmetricKey {
|
|
25
|
+
static fromRandom (): SymmetricKey {
|
|
26
26
|
return new SymmetricKey(Random(32))
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -40,7 +40,7 @@ export default class SymmetricKey extends BigNumber {
|
|
|
40
40
|
* const key = new SymmetricKey(1234);
|
|
41
41
|
* const encryptedMessage = key.encrypt('plainText', 'utf8');
|
|
42
42
|
*/
|
|
43
|
-
encrypt(msg: number[] | string, enc?: 'hex'): string | number[] {
|
|
43
|
+
encrypt (msg: number[] | string, enc?: 'hex'): string | number[] {
|
|
44
44
|
const iv = Random(32)
|
|
45
45
|
msg = toArray(msg, enc)
|
|
46
46
|
const { result, authenticationTag } = AESGCM(
|
|
@@ -68,7 +68,7 @@ export default class SymmetricKey extends BigNumber {
|
|
|
68
68
|
*
|
|
69
69
|
* @throws {Error} Will throw an error if the decryption fails, likely due to message tampering or incorrect decryption key.
|
|
70
70
|
*/
|
|
71
|
-
decrypt(msg: number[] | string, enc?: 'hex' | 'utf8'): string | number[] {
|
|
71
|
+
decrypt (msg: number[] | string, enc?: 'hex' | 'utf8'): string | number[] {
|
|
72
72
|
msg = toArray(msg, enc) as number[]
|
|
73
73
|
const iv = msg.slice(0, 32)
|
|
74
74
|
const ciphertextWithTag = msg.slice(32)
|
|
@@ -15,7 +15,7 @@ export default class TransactionSignature extends Signature {
|
|
|
15
15
|
|
|
16
16
|
scope: number
|
|
17
17
|
|
|
18
|
-
static format(params: {
|
|
18
|
+
static format (params: {
|
|
19
19
|
sourceTXID: string
|
|
20
20
|
sourceOutputIndex: number
|
|
21
21
|
sourceSatoshis: number
|
|
@@ -48,7 +48,7 @@ export default class TransactionSignature extends Signature {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
const buf = writer.toArray()
|
|
51
|
-
const ret = Hash.hash256(buf)
|
|
51
|
+
const ret = Hash.hash256(buf)
|
|
52
52
|
return ret
|
|
53
53
|
}
|
|
54
54
|
|
|
@@ -60,11 +60,11 @@ export default class TransactionSignature extends Signature {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
const buf = writer.toArray()
|
|
63
|
-
const ret = Hash.hash256(buf)
|
|
63
|
+
const ret = Hash.hash256(buf)
|
|
64
64
|
return ret
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
function getOutputsHash(outputIndex?: number): number[] {
|
|
67
|
+
function getOutputsHash (outputIndex?: number): number[] {
|
|
68
68
|
const writer = new Writer()
|
|
69
69
|
|
|
70
70
|
if (typeof outputIndex === 'undefined') {
|
|
@@ -84,7 +84,7 @@ export default class TransactionSignature extends Signature {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
const buf = writer.toArray()
|
|
87
|
-
const ret = Hash.hash256(buf)
|
|
87
|
+
const ret = Hash.hash256(buf)
|
|
88
88
|
return ret
|
|
89
89
|
}
|
|
90
90
|
|
|
@@ -146,7 +146,7 @@ export default class TransactionSignature extends Signature {
|
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
// The format used in a tx
|
|
149
|
-
static fromChecksigFormat(buf: number[]): TransactionSignature {
|
|
149
|
+
static fromChecksigFormat (buf: number[]): TransactionSignature {
|
|
150
150
|
if (buf.length === 0) {
|
|
151
151
|
// allow setting a "blank" signature
|
|
152
152
|
const r = new BigNumber(1)
|
|
@@ -160,7 +160,7 @@ export default class TransactionSignature extends Signature {
|
|
|
160
160
|
return new TransactionSignature(tempSig.r, tempSig.s, scope)
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
constructor(r: BigNumber, s: BigNumber, scope: number) {
|
|
163
|
+
constructor (r: BigNumber, s: BigNumber, scope: number) {
|
|
164
164
|
super(r, s)
|
|
165
165
|
this.scope = scope
|
|
166
166
|
}
|
|
@@ -170,7 +170,7 @@ export default class TransactionSignature extends Signature {
|
|
|
170
170
|
* See also Ecdsa signature algorithm which enforces this.
|
|
171
171
|
* See also Bip 62, "low S values in signatures"
|
|
172
172
|
*/
|
|
173
|
-
public hasLowS(): boolean {
|
|
173
|
+
public hasLowS (): boolean {
|
|
174
174
|
if (
|
|
175
175
|
this.s.ltn(1) ||
|
|
176
176
|
this.s.gt(new BigNumber(
|
|
@@ -182,7 +182,7 @@ export default class TransactionSignature extends Signature {
|
|
|
182
182
|
return true
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
toChecksigFormat(): number[] {
|
|
185
|
+
toChecksigFormat (): number[] {
|
|
186
186
|
const derbuf = this.toDER() as number[]
|
|
187
187
|
return [...derbuf, this.scope]
|
|
188
188
|
}
|
package/src/primitives/index.ts
CHANGED
|
@@ -9,4 +9,4 @@ export * as ECDSA from './ECDSA.js'
|
|
|
9
9
|
export * as Utils from './utils.js'
|
|
10
10
|
export * as Hash from './Hash.js'
|
|
11
11
|
export { default as Random } from './Random.js'
|
|
12
|
-
export { default as TransactionSignature } from './TransactionSignature.js'
|
|
12
|
+
export { default as TransactionSignature } from './TransactionSignature.js'
|