@bsv/sdk 1.0.4 → 1.0.5
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/dist/cjs/src/primitives/BigNumber.js +1 -1
- package/dist/cjs/src/primitives/BigNumber.js.map +1 -1
- package/dist/cjs/src/primitives/SymmetricKey.js +1 -1
- package/dist/cjs/src/primitives/SymmetricKey.js.map +1 -1
- package/dist/cjs/src/script/Spend.js +3 -2
- package/dist/cjs/src/script/Spend.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/primitives/BigNumber.js +1 -1
- package/dist/esm/src/primitives/BigNumber.js.map +1 -1
- package/dist/esm/src/primitives/SymmetricKey.js +1 -1
- package/dist/esm/src/primitives/SymmetricKey.js.map +1 -1
- package/dist/esm/src/script/Spend.js +3 -2
- package/dist/esm/src/script/Spend.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/primitives/SymmetricKey.d.ts.map +1 -1
- package/dist/types/src/script/Spend.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/docs/examples/EXAMPLE_BUILDING_CUSTOM_TX_BROADCASTER.md +89 -0
- package/docs/examples/EXAMPLE_COMPLEX_TX.md +164 -0
- package/docs/examples/EXAMPLE_ECIES.md +37 -0
- package/docs/examples/EXAMPLE_ENCRYPT_DECRYPT_MESSAGE.md +52 -0
- package/docs/examples/EXAMPLE_FEE_MODELING.md +199 -0
- package/docs/examples/EXAMPLE_HD_WALLETS.md +71 -0
- package/docs/examples/EXAMPLE_MESSAGE_SIGNING.md +63 -0
- package/docs/examples/EXAMPLE_PULSE_HEADERS.md +140 -0
- package/docs/examples/EXAMPLE_SCRIPT_TEMPLATES.md +170 -0
- package/docs/examples/EXAMPLE_SIMPLE_TX.md +64 -0
- package/docs/examples/EXAMPLE_TYPE_42.md +108 -0
- package/docs/examples/EXAMPLE_VERIFYING_BEEF.md +55 -0
- package/docs/examples/EXAMPLE_VERIFYING_SPENDS.md +69 -0
- package/docs/examples/GETTING_STARTED_NODE_CJS.md +73 -0
- package/docs/examples/GETTING_STARTED_REACT.md +121 -0
- package/docs/examples/README.md +19 -0
- package/docs/low-level/README.md +6 -0
- package/docs/low-level/TX_SIG.md +129 -0
- package/docs/low-level/TYPE_42.md +0 -0
- package/docs/primitives.md +585 -562
- package/docs/script.md +4 -4
- package/package.json +1 -1
- package/src/primitives/BigNumber.ts +2 -1
- package/src/primitives/Hash.ts +118 -64
- package/src/primitives/PrivateKey.ts +28 -1
- package/src/primitives/PublicKey.ts +24 -2
- package/src/primitives/SymmetricKey.ts +17 -3
- package/src/primitives/__tests/HMAC.test.ts +2 -2
- package/src/primitives/__tests/Hash.test.ts +2 -2
- package/src/primitives/index.ts +1 -0
- package/src/primitives/utils.ts +3 -3
- package/src/script/__tests/Script.test.ts +34 -0
- package/src/script/__tests/Spend.test.ts +7 -7
- package/src/script/templates/P2PKH.ts +13 -4
- package/src/transaction/__tests/Transaction.test.ts +1 -1
package/docs/script.md
CHANGED
|
@@ -611,7 +611,7 @@ This class provides methods to create Pay To Public Key Hash locking and unlocki
|
|
|
611
611
|
|
|
612
612
|
```ts
|
|
613
613
|
export default class P2PKH implements ScriptTemplate {
|
|
614
|
-
lock(pubkeyhash: number[]): LockingScript
|
|
614
|
+
lock(pubkeyhash: string | number[]): LockingScript
|
|
615
615
|
unlock(privateKey: PrivateKey, signOutputs: "all" | "none" | "single" = "all", anyoneCanPay: boolean = false): {
|
|
616
616
|
sign: (tx: Transaction, inputIndex: number) => Promise<UnlockingScript>;
|
|
617
617
|
estimateLength: () => Promise<106>;
|
|
@@ -625,10 +625,10 @@ export default class P2PKH implements ScriptTemplate {
|
|
|
625
625
|
|
|
626
626
|
#### Method lock
|
|
627
627
|
|
|
628
|
-
Creates a P2PKH locking script for a given public key hash
|
|
628
|
+
Creates a P2PKH locking script for a given public key hash or address string
|
|
629
629
|
|
|
630
630
|
```ts
|
|
631
|
-
lock(pubkeyhash: number[]): LockingScript
|
|
631
|
+
lock(pubkeyhash: string | number[]): LockingScript
|
|
632
632
|
```
|
|
633
633
|
|
|
634
634
|
Returns
|
|
@@ -638,7 +638,7 @@ Returns
|
|
|
638
638
|
Argument Details
|
|
639
639
|
|
|
640
640
|
+ **pubkeyhash**
|
|
641
|
-
+ An array representing the public key hash.
|
|
641
|
+
+ or address - An array or address representing the public key hash.
|
|
642
642
|
|
|
643
643
|
#### Method unlock
|
|
644
644
|
|
package/package.json
CHANGED
|
@@ -194,6 +194,7 @@ export default class BigNumber {
|
|
|
194
194
|
base: number | 'be' | 'le' | 'hex' = 10,
|
|
195
195
|
endian: 'be' | 'le' = 'be'
|
|
196
196
|
) {
|
|
197
|
+
|
|
197
198
|
this.negative = 0
|
|
198
199
|
this.words = []
|
|
199
200
|
this.length = 0
|
|
@@ -634,7 +635,7 @@ export default class BigNumber {
|
|
|
634
635
|
* @returns - Returns the BigNumber after stripping leading zeros.
|
|
635
636
|
*
|
|
636
637
|
* @example
|
|
637
|
-
* const bn = new BigNumber(
|
|
638
|
+
* const bn = new BigNumber("000000", 2, "be");
|
|
638
639
|
* bn.strip();
|
|
639
640
|
* // bn now represents 0
|
|
640
641
|
*/
|
package/src/primitives/Hash.ts
CHANGED
|
@@ -68,7 +68,11 @@ abstract class BaseHash {
|
|
|
68
68
|
throw new Error('Not implemented')
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
_digest(
|
|
71
|
+
_digest(): number[] {
|
|
72
|
+
throw new Error('Not implemented')
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
_digestHex(): string {
|
|
72
76
|
throw new Error('Not implemented')
|
|
73
77
|
}
|
|
74
78
|
|
|
@@ -85,7 +89,7 @@ abstract class BaseHash {
|
|
|
85
89
|
* @example
|
|
86
90
|
* sha256.update('Hello World', 'utf8');
|
|
87
91
|
*/
|
|
88
|
-
update(msg: number[] | string, enc?: 'hex'): this {
|
|
92
|
+
update(msg: number[] | string, enc?: 'hex' | 'utf8'): this {
|
|
89
93
|
// Convert message to array, pad it, and join into 32bit blocks
|
|
90
94
|
msg = toArray(msg, enc)
|
|
91
95
|
if (this.pending == null) {
|
|
@@ -117,18 +121,34 @@ abstract class BaseHash {
|
|
|
117
121
|
* Finalizes the hash computation and returns the hash value/result.
|
|
118
122
|
*
|
|
119
123
|
* @method digest
|
|
120
|
-
* @param enc - The encoding of the final hash. If 'hex' then a hex string will be provided, otherwise an array of numbers.
|
|
121
124
|
*
|
|
122
125
|
* @returns Returns the final hash value.
|
|
123
126
|
*
|
|
124
127
|
* @example
|
|
125
|
-
* const hash = sha256.digest(
|
|
128
|
+
* const hash = sha256.digest();
|
|
126
129
|
*/
|
|
127
|
-
digest(
|
|
130
|
+
digest(): number[] {
|
|
128
131
|
this.update(this._pad())
|
|
129
132
|
assert(this.pending === null)
|
|
130
133
|
|
|
131
|
-
return this._digest(
|
|
134
|
+
return this._digest()
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Finalizes the hash computation and returns the hash value/result as a hex string.
|
|
139
|
+
*
|
|
140
|
+
* @method digest
|
|
141
|
+
*
|
|
142
|
+
* @returns Returns the final hash value as a hex string.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* const hash = sha256.digestHex();
|
|
146
|
+
*/
|
|
147
|
+
digestHex(): string {
|
|
148
|
+
this.update(this._pad())
|
|
149
|
+
assert(this.pending === null)
|
|
150
|
+
|
|
151
|
+
return this._digestHex()
|
|
132
152
|
};
|
|
133
153
|
|
|
134
154
|
/**
|
|
@@ -189,7 +209,13 @@ function isSurrogatePair(msg: string, i: number): boolean {
|
|
|
189
209
|
return (msg.charCodeAt(i + 1) & 0xFC00) === 0xDC00
|
|
190
210
|
}
|
|
191
211
|
|
|
192
|
-
|
|
212
|
+
/**
|
|
213
|
+
*
|
|
214
|
+
* @param msg
|
|
215
|
+
* @param enc Optional. Encoding to use if msg is string. Default is 'utf8'.
|
|
216
|
+
* @returns array of byte values from msg. If msg is an array, a copy is returned.
|
|
217
|
+
*/
|
|
218
|
+
export function toArray(msg: number[] | string, enc?: 'hex' | 'utf8'): number[] {
|
|
193
219
|
if (Array.isArray(msg)) { return msg.slice() }
|
|
194
220
|
if (!(msg as unknown as boolean)) { return [] }
|
|
195
221
|
const res = []
|
|
@@ -563,12 +589,12 @@ export class RIPEMD160 extends BaseHash {
|
|
|
563
589
|
this.h[0] = T
|
|
564
590
|
}
|
|
565
591
|
|
|
566
|
-
_digest(
|
|
567
|
-
if (enc === 'hex') {
|
|
568
|
-
return toHex32(this.h, 'little')
|
|
569
|
-
} else {
|
|
592
|
+
_digest(): number[] {
|
|
570
593
|
return split32(this.h, 'little')
|
|
571
|
-
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
_digestHex(): string {
|
|
597
|
+
return toHex32(this.h, 'little')
|
|
572
598
|
}
|
|
573
599
|
}
|
|
574
600
|
|
|
@@ -667,12 +693,12 @@ export class SHA256 extends BaseHash {
|
|
|
667
693
|
this.h[7] = sum32(this.h[7], h)
|
|
668
694
|
};
|
|
669
695
|
|
|
670
|
-
_digest(
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
696
|
+
_digest(): number[] {
|
|
697
|
+
return split32(this.h, 'big')
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
_digestHex(): string {
|
|
701
|
+
return toHex32(this.h, 'big')
|
|
676
702
|
}
|
|
677
703
|
}
|
|
678
704
|
|
|
@@ -745,12 +771,12 @@ export class SHA1 extends BaseHash {
|
|
|
745
771
|
this.h[4] = sum32(this.h[4], e)
|
|
746
772
|
}
|
|
747
773
|
|
|
748
|
-
_digest(
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
774
|
+
_digest(): number[] {
|
|
775
|
+
return split32(this.h, 'big')
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
_digestHex(): string {
|
|
779
|
+
return toHex32(this.h, 'big')
|
|
754
780
|
}
|
|
755
781
|
}
|
|
756
782
|
|
|
@@ -956,11 +982,12 @@ export class SHA512 extends BaseHash {
|
|
|
956
982
|
sum64(this.h, 14, hh, hl);
|
|
957
983
|
}
|
|
958
984
|
|
|
959
|
-
_digest(
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
985
|
+
_digest() {
|
|
986
|
+
return split32(this.h, 'big');
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
_digestHex() {
|
|
990
|
+
return toHex32(this.h, 'big');
|
|
964
991
|
}
|
|
965
992
|
}
|
|
966
993
|
|
|
@@ -1151,15 +1178,28 @@ export class SHA256HMAC {
|
|
|
1151
1178
|
* Finalizes the HMAC computation and returns the resultant hash.
|
|
1152
1179
|
*
|
|
1153
1180
|
* @method digest
|
|
1154
|
-
* @param enc - If 'hex', then the output is encoded as hexadecimal. If undefined or not 'hex', then no encoding is performed.
|
|
1155
1181
|
* @returns Returns the digest of the hashed data. Can be a number array or a string.
|
|
1156
1182
|
*
|
|
1157
1183
|
* @example
|
|
1158
|
-
* let hashedMessage = myHMAC.digest(
|
|
1184
|
+
* let hashedMessage = myHMAC.digest();
|
|
1159
1185
|
*/
|
|
1160
|
-
digest(
|
|
1161
|
-
this.outer.update(this.inner.digest()
|
|
1162
|
-
return this.outer.digest(
|
|
1186
|
+
digest(): number[] {
|
|
1187
|
+
this.outer.update(this.inner.digest())
|
|
1188
|
+
return this.outer.digest()
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
/**
|
|
1192
|
+
* Finalizes the HMAC computation and returns the resultant hash as a hex string.
|
|
1193
|
+
*
|
|
1194
|
+
* @method digest
|
|
1195
|
+
* @returns Returns the digest of the hashed data as a hex string
|
|
1196
|
+
*
|
|
1197
|
+
* @example
|
|
1198
|
+
* let hashedMessage = myHMAC.digestHex();
|
|
1199
|
+
*/
|
|
1200
|
+
digestHex(): string {
|
|
1201
|
+
this.outer.update(this.inner.digest())
|
|
1202
|
+
return this.outer.digestHex()
|
|
1163
1203
|
}
|
|
1164
1204
|
}
|
|
1165
1205
|
|
|
@@ -1225,7 +1265,7 @@ export class SHA512HMAC {
|
|
|
1225
1265
|
* @example
|
|
1226
1266
|
* myHMAC.update('deadbeef', 'hex');
|
|
1227
1267
|
*/
|
|
1228
|
-
update(msg: number[] | string, enc?: 'hex'): SHA512HMAC {
|
|
1268
|
+
update(msg: number[] | string, enc?: 'hex' | 'utf8'): SHA512HMAC {
|
|
1229
1269
|
this.inner.update(msg, enc)
|
|
1230
1270
|
return this
|
|
1231
1271
|
}
|
|
@@ -1234,76 +1274,90 @@ export class SHA512HMAC {
|
|
|
1234
1274
|
* Finalizes the HMAC computation and returns the resultant hash.
|
|
1235
1275
|
*
|
|
1236
1276
|
* @method digest
|
|
1237
|
-
* @
|
|
1238
|
-
* @returns Returns the digest of the hashed data. Can be a number array or a string.
|
|
1277
|
+
* @returns Returns the digest of the hashed data as a number array.
|
|
1239
1278
|
*
|
|
1240
1279
|
* @example
|
|
1241
|
-
* let hashedMessage = myHMAC.digest(
|
|
1280
|
+
* let hashedMessage = myHMAC.digest();
|
|
1242
1281
|
*/
|
|
1243
|
-
digest(
|
|
1282
|
+
digest(): number[] {
|
|
1244
1283
|
this.outer.update(this.inner.digest() as number[])
|
|
1245
|
-
return this.outer.digest(
|
|
1284
|
+
return this.outer.digest()
|
|
1246
1285
|
}
|
|
1286
|
+
|
|
1287
|
+
/**
|
|
1288
|
+
* Finalizes the HMAC computation and returns the resultant hash as a hex string.
|
|
1289
|
+
*
|
|
1290
|
+
* @method digest
|
|
1291
|
+
* @returns Returns the digest of the hashed data as a hex string
|
|
1292
|
+
*
|
|
1293
|
+
* @example
|
|
1294
|
+
* let hashedMessage = myHMAC.digestHex();
|
|
1295
|
+
*/
|
|
1296
|
+
digestHex(): string {
|
|
1297
|
+
this.outer.update(this.inner.digest() as number[])
|
|
1298
|
+
return this.outer.digestHex()
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1247
1301
|
}
|
|
1248
1302
|
|
|
1249
1303
|
/**
|
|
1250
1304
|
* Computes RIPEMD160 hash of a given message.
|
|
1251
1305
|
* @function ripemd160
|
|
1252
1306
|
* @param msg - The message to compute the hash for.
|
|
1253
|
-
* @param enc - The encoding of
|
|
1307
|
+
* @param enc - The encoding of msg if string. Default is 'utf8'.
|
|
1254
1308
|
*
|
|
1255
1309
|
* @returns the computed RIPEMD160 hash of the message.
|
|
1256
1310
|
*
|
|
1257
1311
|
* @example
|
|
1258
1312
|
* const digest = ripemd160('Hello, world!');
|
|
1259
1313
|
*/
|
|
1260
|
-
export const ripemd160 = (msg: number[] | string, enc?: 'hex'): number[]
|
|
1261
|
-
return new RIPEMD160().update(msg, enc).digest(
|
|
1314
|
+
export const ripemd160 = (msg: number[] | string, enc?: 'hex' | 'utf8'): number[] => {
|
|
1315
|
+
return new RIPEMD160().update(msg, enc).digest()
|
|
1262
1316
|
}
|
|
1263
1317
|
|
|
1264
1318
|
/**
|
|
1265
1319
|
* Computes SHA1 hash of a given message.
|
|
1266
1320
|
* @function sha1
|
|
1267
1321
|
* @param msg - The message to compute the hash for.
|
|
1268
|
-
* @param enc - The encoding of
|
|
1322
|
+
* @param enc - The encoding of msg if string. Default is 'utf8'.
|
|
1269
1323
|
*
|
|
1270
1324
|
* @returns the computed SHA1 hash of the message.
|
|
1271
1325
|
*
|
|
1272
1326
|
* @example
|
|
1273
1327
|
* const digest = sha1('Hello, world!');
|
|
1274
1328
|
*/
|
|
1275
|
-
export const sha1 = (msg: number[] | string, enc?: 'hex'): number[]
|
|
1276
|
-
return new SHA1().update(msg, enc).digest(
|
|
1329
|
+
export const sha1 = (msg: number[] | string, enc?: 'hex' | 'utf8'): number[] => {
|
|
1330
|
+
return new SHA1().update(msg, enc).digest()
|
|
1277
1331
|
}
|
|
1278
1332
|
|
|
1279
1333
|
/**
|
|
1280
1334
|
* Computes SHA256 hash of a given message.
|
|
1281
1335
|
* @function sha256
|
|
1282
1336
|
* @param msg - The message to compute the hash for.
|
|
1283
|
-
* @param enc - The encoding of
|
|
1337
|
+
* @param enc - The encoding of msg if string. Default is 'utf8'.
|
|
1284
1338
|
*
|
|
1285
1339
|
* @returns the computed SHA256 hash of the message.
|
|
1286
1340
|
*
|
|
1287
1341
|
* @example
|
|
1288
1342
|
* const digest = sha256('Hello, world!');
|
|
1289
1343
|
*/
|
|
1290
|
-
export const sha256 = (msg: number[] | string, enc?: 'hex'): number[]
|
|
1291
|
-
return new SHA256().update(msg, enc).digest(
|
|
1344
|
+
export const sha256 = (msg: number[] | string, enc?: 'hex' | 'utf8'): number[] => {
|
|
1345
|
+
return new SHA256().update(msg, enc).digest()
|
|
1292
1346
|
}
|
|
1293
1347
|
|
|
1294
1348
|
/**
|
|
1295
1349
|
* Computes SHA512 hash of a given message.
|
|
1296
1350
|
* @function sha512
|
|
1297
1351
|
* @param msg - The message to compute the hash for.
|
|
1298
|
-
* @param enc - The encoding of
|
|
1352
|
+
* @param enc - The encoding of msg if string. Default is 'utf8'.
|
|
1299
1353
|
*
|
|
1300
1354
|
* @returns the computed SHA512 hash of the message.
|
|
1301
1355
|
*
|
|
1302
1356
|
* @example
|
|
1303
1357
|
* const digest = sha512('Hello, world!');
|
|
1304
1358
|
*/
|
|
1305
|
-
export const sha512 = (msg: number[] | string, enc?: 'hex'): number[]
|
|
1306
|
-
return new SHA512().update(msg, enc).digest(
|
|
1359
|
+
export const sha512 = (msg: number[] | string, enc?: 'hex' | 'utf8'): number[] => {
|
|
1360
|
+
return new SHA512().update(msg, enc).digest()
|
|
1307
1361
|
}
|
|
1308
1362
|
|
|
1309
1363
|
/**
|
|
@@ -1312,16 +1366,16 @@ export const sha512 = (msg: number[] | string, enc?: 'hex'): number[] | string =
|
|
|
1312
1366
|
* SHA256 hash of the resulting hash is computed.
|
|
1313
1367
|
* @function hash256
|
|
1314
1368
|
* @param msg - The message to compute the hash for.
|
|
1315
|
-
* @param enc -
|
|
1369
|
+
* @param enc - The encoding of msg if string. Default is 'utf8'.
|
|
1316
1370
|
*
|
|
1317
1371
|
* @returns the double hashed SHA256 output.
|
|
1318
1372
|
*
|
|
1319
1373
|
* @example
|
|
1320
1374
|
* const doubleHash = hash256('Hello, world!');
|
|
1321
1375
|
*/
|
|
1322
|
-
export const hash256 = (msg: number[] | string, enc?: 'hex'): number[]
|
|
1376
|
+
export const hash256 = (msg: number[] | string, enc?: 'hex' | 'utf8'): number[] => {
|
|
1323
1377
|
const first = new SHA256().update(msg, enc).digest()
|
|
1324
|
-
return new SHA256().update(first).digest(
|
|
1378
|
+
return new SHA256().update(first).digest()
|
|
1325
1379
|
}
|
|
1326
1380
|
|
|
1327
1381
|
/**
|
|
@@ -1329,16 +1383,16 @@ export const hash256 = (msg: number[] | string, enc?: 'hex'): number[] | string
|
|
|
1329
1383
|
*
|
|
1330
1384
|
* @function hash160
|
|
1331
1385
|
* @param msg - The message to compute the hash for.
|
|
1332
|
-
* @param enc - The encoding of
|
|
1386
|
+
* @param enc - The encoding of msg if string. Default is 'utf8'.
|
|
1333
1387
|
*
|
|
1334
1388
|
* @returns the RIPEMD160 hash of the SHA256 hash of the input message.
|
|
1335
1389
|
*
|
|
1336
1390
|
* @example
|
|
1337
1391
|
* const hash = hash160('Hello, world!');
|
|
1338
1392
|
*/
|
|
1339
|
-
export const hash160 = (msg: number[] | string, enc?: 'hex'): number[]
|
|
1393
|
+
export const hash160 = (msg: number[] | string, enc?: 'hex' | 'utf8'): number[] => {
|
|
1340
1394
|
const first = new SHA256().update(msg, enc).digest()
|
|
1341
|
-
return new RIPEMD160().update(first).digest(
|
|
1395
|
+
return new RIPEMD160().update(first).digest()
|
|
1342
1396
|
}
|
|
1343
1397
|
|
|
1344
1398
|
/**
|
|
@@ -1346,15 +1400,15 @@ export const hash160 = (msg: number[] | string, enc?: 'hex'): number[] | string
|
|
|
1346
1400
|
* @function sha256hmac
|
|
1347
1401
|
* @param key - The key used to compute the HMAC
|
|
1348
1402
|
* @param msg - The message to compute the hash for.
|
|
1349
|
-
* @param enc - The encoding of
|
|
1403
|
+
* @param enc - The encoding of msg if string. Default is 'utf8'.
|
|
1350
1404
|
*
|
|
1351
1405
|
* @returns the computed HMAC of the message.
|
|
1352
1406
|
*
|
|
1353
1407
|
* @example
|
|
1354
1408
|
* const digest = sha256hmac('deadbeef', 'ffff001d');
|
|
1355
1409
|
*/
|
|
1356
|
-
export const sha256hmac = (key: number[] | string, msg: number[] | string, enc?: 'hex'): number[]
|
|
1357
|
-
return new SHA256HMAC(key).update(msg, enc).digest(
|
|
1410
|
+
export const sha256hmac = (key: number[] | string, msg: number[] | string, enc?: 'hex'): number[] => {
|
|
1411
|
+
return new SHA256HMAC(key).update(msg, enc).digest()
|
|
1358
1412
|
}
|
|
1359
1413
|
|
|
1360
1414
|
/**
|
|
@@ -1362,15 +1416,15 @@ export const sha256hmac = (key: number[] | string, msg: number[] | string, enc?:
|
|
|
1362
1416
|
* @function sha512hmac
|
|
1363
1417
|
* @param key - The key used to compute the HMAC
|
|
1364
1418
|
* @param msg - The message to compute the hash for.
|
|
1365
|
-
* @param enc - The encoding of
|
|
1419
|
+
* @param enc - The encoding of msg if string. Default is 'utf8'.
|
|
1366
1420
|
*
|
|
1367
1421
|
* @returns the computed HMAC of the message.
|
|
1368
1422
|
*
|
|
1369
1423
|
* @example
|
|
1370
1424
|
* const digest = sha512hmac('deadbeef', 'ffff001d');
|
|
1371
1425
|
*/
|
|
1372
|
-
export const sha512hmac = (key: number[] | string, msg: number[] | string, enc?: 'hex'): number[]
|
|
1373
|
-
return new SHA512HMAC(key).update(msg, enc).digest(
|
|
1426
|
+
export const sha512hmac = (key: number[] | string, msg: number[] | string, enc?: 'hex'): number[] => {
|
|
1427
|
+
return new SHA512HMAC(key).update(msg, enc).digest()
|
|
1374
1428
|
}
|
|
1375
1429
|
|
|
1376
1430
|
/**
|
|
@@ -67,6 +67,33 @@ export default class PrivateKey extends BigNumber {
|
|
|
67
67
|
return new PrivateKey(decoded.data.slice(0, 32))
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
/**
|
|
71
|
+
* @constructor
|
|
72
|
+
*
|
|
73
|
+
* @param number - The number (various types accepted) to construct a BigNumber from. Default is 0.
|
|
74
|
+
*
|
|
75
|
+
* @param base - The base of number provided. By default is 10. Ignored if number is BigNumber.
|
|
76
|
+
*
|
|
77
|
+
* @param endian - The endianness provided. By default is 'big endian'. Ignored if number is BigNumber.
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* import PrivateKey from './PrivateKey';
|
|
81
|
+
* import BigNumber from './BigNumber';
|
|
82
|
+
* const privKey = new PrivateKey(new BigNumber('123456', 10, 'be'));
|
|
83
|
+
*/
|
|
84
|
+
constructor (
|
|
85
|
+
number: BigNumber | number | string | number[] = 0,
|
|
86
|
+
base: number | 'be' | 'le' | 'hex' = 10,
|
|
87
|
+
endian: 'be' | 'le' = 'be'
|
|
88
|
+
) {
|
|
89
|
+
if (number instanceof BigNumber) {
|
|
90
|
+
super()
|
|
91
|
+
number.copy(this)
|
|
92
|
+
} else {
|
|
93
|
+
super(number, base, endian)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
70
97
|
/**
|
|
71
98
|
* Signs a message using the private key.
|
|
72
99
|
*
|
|
@@ -81,7 +108,7 @@ export default class PrivateKey extends BigNumber {
|
|
|
81
108
|
* const privateKey = PrivateKey.fromRandom();
|
|
82
109
|
* const signature = privateKey.sign('Hello, World!');
|
|
83
110
|
*/
|
|
84
|
-
sign (msg: number[] | string, enc?: 'hex', forceLowS: boolean = true, customK?: Function | BigNumber): Signature {
|
|
111
|
+
sign (msg: number[] | string, enc?: 'hex' | 'utf8', forceLowS: boolean = true, customK?: Function | BigNumber): Signature {
|
|
85
112
|
const msgHash = new BigNumber(sha256(msg, enc), 16)
|
|
86
113
|
return sign(msgHash, this, forceLowS, customK)
|
|
87
114
|
}
|
|
@@ -52,6 +52,28 @@ export default class PublicKey extends Point {
|
|
|
52
52
|
return new PublicKey(p.x, p.y)
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* @constructor
|
|
57
|
+
* @param x - A point or the x-coordinate of the point. May be a number, a BigNumber, a string (which will be interpreted as hex), a number array, or null. If null, an "Infinity" point is constructed.
|
|
58
|
+
* @param y - If x is not a point, the y-coordinate of the point, similar to x.
|
|
59
|
+
* @param isRed - A boolean indicating if the point is a member of the field of integers modulo the k256 prime. Default is true.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* new PublicKey(point1);
|
|
63
|
+
* new PublicKey('abc123', 'def456');
|
|
64
|
+
*/
|
|
65
|
+
constructor (
|
|
66
|
+
x: Point | BigNumber | number | number[] | string | null,
|
|
67
|
+
y: BigNumber | number | number[] | string | null = null,
|
|
68
|
+
isRed: boolean = true
|
|
69
|
+
) {
|
|
70
|
+
if (x instanceof Point) {
|
|
71
|
+
super(x.getX(), x.getY())
|
|
72
|
+
} else {
|
|
73
|
+
super(x, y, isRed)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
55
77
|
/**
|
|
56
78
|
* Derive a shared secret from a public key and a private key for use in symmetric encryption.
|
|
57
79
|
* This method multiplies the public key (an instance of Point) with a private key.
|
|
@@ -78,7 +100,7 @@ export default class PublicKey extends Point {
|
|
|
78
100
|
*
|
|
79
101
|
* @param msg - The message to verify. It can be a string or an array of numbers.
|
|
80
102
|
* @param sig - The Signature of the message that needs verification.
|
|
81
|
-
* @param enc - The encoding of the message. It defaults to '
|
|
103
|
+
* @param enc - The encoding of the message. It defaults to 'utf8'.
|
|
82
104
|
*
|
|
83
105
|
* @returns Returns true if the signature is verified successfully, otherwise false.
|
|
84
106
|
*
|
|
@@ -87,7 +109,7 @@ export default class PublicKey extends Point {
|
|
|
87
109
|
* const mySignature = new Signature(...)
|
|
88
110
|
* const isVerified = myPubKey.verify(myMessage, mySignature)
|
|
89
111
|
*/
|
|
90
|
-
verify (msg: number[] | string, sig: Signature, enc?: 'hex'): boolean {
|
|
112
|
+
verify (msg: number[] | string, sig: Signature, enc?: 'hex' | 'utf8'): boolean {
|
|
91
113
|
const msgHash = new BigNumber(sha256(msg, enc), 16)
|
|
92
114
|
return verify(msgHash, sig, this)
|
|
93
115
|
}
|
|
@@ -12,6 +12,20 @@ import { toArray, encode } from './utils.js'
|
|
|
12
12
|
* @extends {BigNumber}
|
|
13
13
|
*/
|
|
14
14
|
export default class SymmetricKey extends BigNumber {
|
|
15
|
+
/**
|
|
16
|
+
* Generates a symmetric key randomly.
|
|
17
|
+
*
|
|
18
|
+
* @method fromRandom
|
|
19
|
+
* @static
|
|
20
|
+
* @returns The newly generated Symmetric Key.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* const symmetricKey = SymmetricKey.fromRandom();
|
|
24
|
+
*/
|
|
25
|
+
static fromRandom(): SymmetricKey {
|
|
26
|
+
return new SymmetricKey(Random(32))
|
|
27
|
+
}
|
|
28
|
+
|
|
15
29
|
/**
|
|
16
30
|
* Encrypts a given message using AES-GCM encryption.
|
|
17
31
|
* The generated Initialization Vector (IV) is attached to the encrypted message for decryption purposes.
|
|
@@ -26,14 +40,14 @@ export default class SymmetricKey extends BigNumber {
|
|
|
26
40
|
* const key = new SymmetricKey(1234);
|
|
27
41
|
* const encryptedMessage = key.encrypt('plainText', 'utf8');
|
|
28
42
|
*/
|
|
29
|
-
encrypt
|
|
43
|
+
encrypt(msg: number[] | string, enc?: 'hex'): string | number[] {
|
|
30
44
|
const iv = Random(32)
|
|
31
45
|
msg = toArray(msg, enc)
|
|
32
46
|
const { result, authenticationTag } = AESGCM(
|
|
33
47
|
msg,
|
|
34
48
|
[],
|
|
35
49
|
iv,
|
|
36
|
-
this.toArray()
|
|
50
|
+
this.toArray('be', 32)
|
|
37
51
|
)
|
|
38
52
|
return encode([...iv, ...result, ...authenticationTag], enc)
|
|
39
53
|
}
|
|
@@ -54,7 +68,7 @@ export default class SymmetricKey extends BigNumber {
|
|
|
54
68
|
*
|
|
55
69
|
* @throws {Error} Will throw an error if the decryption fails, likely due to message tampering or incorrect decryption key.
|
|
56
70
|
*/
|
|
57
|
-
decrypt
|
|
71
|
+
decrypt(msg: number[] | string, enc?: 'hex' | 'utf8'): string | number[] {
|
|
58
72
|
msg = toArray(msg, enc) as number[]
|
|
59
73
|
const iv = msg.slice(0, 32)
|
|
60
74
|
const ciphertextWithTag = msg.slice(32)
|
|
@@ -47,12 +47,12 @@ describe('HMAC', function () {
|
|
|
47
47
|
function test (opt): void {
|
|
48
48
|
it(`should not fail at ${opt.name as string}`, function (): void {
|
|
49
49
|
let h = new SHA256HMAC(opt.key)
|
|
50
|
-
expect(h.update(opt.msg, opt.msgEnc).
|
|
50
|
+
expect(h.update(opt.msg, opt.msgEnc).digestHex()).toEqual(opt.res)
|
|
51
51
|
h = h = new SHA256HMAC(opt.key)
|
|
52
52
|
expect(h
|
|
53
53
|
.update(opt.msg.slice(0, 10), opt.msgEnc)
|
|
54
54
|
.update(opt.msg.slice(10), opt.msgEnc)
|
|
55
|
-
.
|
|
55
|
+
.digestHex()).toEqual(opt.res)
|
|
56
56
|
})
|
|
57
57
|
}
|
|
58
58
|
})
|
|
@@ -11,13 +11,13 @@ describe('Hash', function () {
|
|
|
11
11
|
const res = cases[i][1]
|
|
12
12
|
const enc = cases[i][2]
|
|
13
13
|
|
|
14
|
-
let dgst = new Hash().update(msg, enc).
|
|
14
|
+
let dgst = new Hash().update(msg, enc).digestHex()
|
|
15
15
|
expect(dgst).toEqual(res)
|
|
16
16
|
|
|
17
17
|
// Split message
|
|
18
18
|
dgst = new Hash().update(msg.slice(0, 2), enc)
|
|
19
19
|
.update(msg.slice(2), enc)
|
|
20
|
-
.
|
|
20
|
+
.digestHex()
|
|
21
21
|
expect(dgst).toEqual(res)
|
|
22
22
|
}
|
|
23
23
|
}
|
package/src/primitives/index.ts
CHANGED
package/src/primitives/utils.ts
CHANGED
|
@@ -2,12 +2,12 @@ import BigNumber from './BigNumber.js'
|
|
|
2
2
|
import { hash256 } from './Hash.js'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Prepends a '0' to an odd character length word to ensure it has an even number of characters.
|
|
6
6
|
* @param {string} word - The input word.
|
|
7
|
-
* @returns {string} - The word with a leading '0' if it's
|
|
7
|
+
* @returns {string} - The word with a leading '0' if it's an odd character length; otherwise, the original word.
|
|
8
8
|
*/
|
|
9
9
|
export const zero2 = (word: string): string => {
|
|
10
|
-
if (word.length === 1) {
|
|
10
|
+
if (word.length % 2 === 1) {
|
|
11
11
|
return '0' + word
|
|
12
12
|
} else {
|
|
13
13
|
return word
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import Script from '../../../dist/cjs/src/script/Script'
|
|
2
|
+
import PrivateKey from '../../../dist/cjs/src/primitives/PrivateKey'
|
|
3
|
+
import P2PKH from '../../../dist/cjs/src/script/templates/P2PKH'
|
|
2
4
|
import OP from '../../../dist/cjs/src/script/OP'
|
|
3
5
|
import { toHex } from '../../../dist/cjs/src/primitives/utils'
|
|
4
6
|
import scriptFromVector from './scriptFromVector'
|
|
@@ -23,6 +25,38 @@ describe('Script', () => {
|
|
|
23
25
|
})
|
|
24
26
|
})
|
|
25
27
|
|
|
28
|
+
describe('fromAddress', () => {
|
|
29
|
+
it('should parse this mainnet Base58Check encoded address string and result in a P2PKH Script', () => {
|
|
30
|
+
const priv = PrivateKey.fromRandom()
|
|
31
|
+
const address = priv.toAddress()
|
|
32
|
+
const publicKey = priv.toPublicKey()
|
|
33
|
+
const pkh = publicKey.toHash()
|
|
34
|
+
const lockingScriptFromTemplate = new P2PKH().lock(pkh).toASM()
|
|
35
|
+
const script = new P2PKH().lock(address).toASM()
|
|
36
|
+
expect(script).toBe(lockingScriptFromTemplate)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('should parse this testnet Base58Check encoded address string and result in a P2PKH Script', () => {
|
|
40
|
+
const priv = PrivateKey.fromRandom()
|
|
41
|
+
const address = priv.toAddress([0x6f])
|
|
42
|
+
const publicKey = priv.toPublicKey()
|
|
43
|
+
const pkh = publicKey.toHash()
|
|
44
|
+
const lockingScriptFromTemplate = new P2PKH().lock(pkh).toASM()
|
|
45
|
+
const script = new P2PKH().lock(address).toASM()
|
|
46
|
+
expect(script).toBe(lockingScriptFromTemplate)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('should error when attempting to parse this strange Base58Check encoded string', () => {
|
|
50
|
+
const priv = PrivateKey.fromRandom()
|
|
51
|
+
const address = priv.toAddress([0x88])
|
|
52
|
+
function attemptToDeriveAddress() {
|
|
53
|
+
const script = new P2PKH().lock(address).toASM()
|
|
54
|
+
return script
|
|
55
|
+
}
|
|
56
|
+
expect(attemptToDeriveAddress).toThrow('only P2PKH is supported')
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
|
|
26
60
|
describe('fromBinary', () => {
|
|
27
61
|
it('should parse this buffer containing an OP code', () => {
|
|
28
62
|
const buf = Buffer.alloc(1)
|