@bsv/sdk 1.1.13 → 1.1.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/dist/cjs/package.json +1 -1
- package/dist/cjs/src/compat/BIP39.js +272 -0
- package/dist/cjs/src/compat/BIP39.js.map +1 -0
- package/dist/cjs/src/index.js +5 -0
- package/dist/cjs/src/index.js.map +1 -0
- package/dist/cjs/src/primitives/Polynomial.js +81 -0
- package/dist/cjs/src/primitives/Polynomial.js.map +1 -0
- package/dist/cjs/src/primitives/PrivateKey.js +165 -0
- package/dist/cjs/src/primitives/PrivateKey.js.map +1 -1
- package/dist/cjs/src/primitives/index.js +5 -1
- package/dist/cjs/src/primitives/index.js.map +1 -1
- package/dist/cjs/src/script/templates/P2PKH.js.map +1 -1
- package/dist/cjs/src/script/templates/P2PKHT.js +99 -0
- package/dist/cjs/src/script/templates/P2PKHT.js.map +1 -0
- package/dist/cjs/src/script/templates/RPuzzle.js.map +1 -1
- package/dist/cjs/src/totp/converters.js +14 -0
- package/dist/cjs/src/totp/converters.js.map +1 -0
- package/dist/cjs/src/totp/pike-totp.js +75 -0
- package/dist/cjs/src/totp/pike-totp.js.map +1 -0
- package/dist/cjs/src/totp/types.js +3 -0
- package/dist/cjs/src/totp/types.js.map +1 -0
- package/dist/cjs/src/transaction/broadcasters/ARC.js +4 -4
- package/dist/cjs/src/transaction/broadcasters/ARC.js.map +1 -1
- package/dist/cjs/src/transaction/broadcasters/BRC22.js +25 -0
- package/dist/cjs/src/transaction/broadcasters/BRC22.js.map +1 -0
- package/dist/cjs/src/transaction/broadcasters/DefaultBroadcaster.js.map +1 -1
- package/dist/cjs/src/transaction/broadcasters/WhatsOnChainBroadcaster.js +3 -3
- package/dist/cjs/src/transaction/broadcasters/WhatsOnChainBroadcaster.js.map +1 -1
- package/dist/cjs/src/transaction/chaintrackers/DefaultChainTracker.js.map +1 -1
- package/dist/cjs/src/transaction/chaintrackers/WhatsOnChain.js +2 -2
- package/dist/cjs/src/transaction/chaintrackers/WhatsOnChain.js.map +1 -1
- package/dist/cjs/src/transaction/fee-models/SatoshisPerKilobyte.js.map +1 -1
- package/dist/cjs/src/transaction/http/DefaultHttpClient.js +2 -2
- package/dist/cjs/src/transaction/http/DefaultHttpClient.js.map +1 -1
- package/dist/cjs/src/transaction/http/FetchHttpClient.js +2 -2
- package/dist/cjs/src/transaction/http/FetchHttpClient.js.map +1 -1
- package/dist/cjs/src/transaction/http/NodejsHttpClient.js +2 -2
- package/dist/cjs/src/transaction/http/NodejsHttpClient.js.map +1 -1
- package/dist/cjs/src/transaction/http/index.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/compat/BIP39.js +272 -0
- package/dist/esm/src/compat/BIP39.js.map +1 -0
- package/dist/esm/src/primitives/Polynomial.js +77 -0
- package/dist/esm/src/primitives/Polynomial.js.map +1 -0
- package/dist/esm/src/primitives/PrivateKey.js +143 -0
- package/dist/esm/src/primitives/PrivateKey.js.map +1 -1
- package/dist/esm/src/primitives/index.js +2 -1
- package/dist/esm/src/primitives/index.js.map +1 -1
- package/dist/esm/src/script/templates/P2PKH.js.map +1 -1
- package/dist/esm/src/script/templates/P2PKHT.js +96 -0
- package/dist/esm/src/script/templates/P2PKHT.js.map +1 -0
- package/dist/esm/src/script/templates/RPuzzle.js.map +1 -1
- package/dist/esm/src/totp/converters.js +9 -0
- package/dist/esm/src/totp/converters.js.map +1 -0
- package/dist/esm/src/totp/pike-totp.js +67 -0
- package/dist/esm/src/totp/pike-totp.js.map +1 -0
- package/dist/esm/src/totp/types.js +2 -0
- package/dist/esm/src/totp/types.js.map +1 -0
- package/dist/esm/src/transaction/broadcasters/ARC.js +7 -7
- package/dist/esm/src/transaction/broadcasters/ARC.js.map +1 -1
- package/dist/esm/src/transaction/broadcasters/DefaultBroadcaster.js +1 -1
- package/dist/esm/src/transaction/broadcasters/DefaultBroadcaster.js.map +1 -1
- package/dist/esm/src/transaction/broadcasters/WhatsOnChainBroadcaster.js +4 -4
- package/dist/esm/src/transaction/broadcasters/WhatsOnChainBroadcaster.js.map +1 -1
- package/dist/esm/src/transaction/chaintrackers/DefaultChainTracker.js +1 -1
- package/dist/esm/src/transaction/chaintrackers/DefaultChainTracker.js.map +1 -1
- package/dist/esm/src/transaction/chaintrackers/WhatsOnChain.js +3 -3
- package/dist/esm/src/transaction/chaintrackers/WhatsOnChain.js.map +1 -1
- package/dist/esm/src/transaction/fee-models/SatoshisPerKilobyte.js.map +1 -1
- package/dist/esm/src/transaction/http/DefaultHttpClient.js +2 -2
- package/dist/esm/src/transaction/http/DefaultHttpClient.js.map +1 -1
- package/dist/esm/src/transaction/http/FetchHttpClient.js +2 -2
- package/dist/esm/src/transaction/http/FetchHttpClient.js.map +1 -1
- package/dist/esm/src/transaction/http/NodejsHttpClient.js +2 -2
- package/dist/esm/src/transaction/http/NodejsHttpClient.js.map +1 -1
- package/dist/esm/src/transaction/http/index.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/compat/BIP39.d.ts +132 -0
- package/dist/types/src/compat/BIP39.d.ts.map +1 -0
- package/dist/types/src/primitives/Polynomial.d.ts +32 -0
- package/dist/types/src/primitives/Polynomial.d.ts.map +1 -0
- package/dist/types/src/primitives/PrivateKey.d.ts +72 -0
- package/dist/types/src/primitives/PrivateKey.d.ts.map +1 -1
- package/dist/types/src/primitives/index.d.ts +2 -1
- package/dist/types/src/primitives/index.d.ts.map +1 -1
- package/dist/types/src/script/templates/P2PKH.d.ts.map +1 -1
- package/dist/types/src/script/templates/P2PKHT.d.ts +37 -0
- package/dist/types/src/script/templates/P2PKHT.d.ts.map +1 -0
- package/dist/types/src/totp/converters.d.ts +3 -0
- package/dist/types/src/totp/converters.d.ts.map +1 -0
- package/dist/types/src/totp/pike-totp.d.ts +25 -0
- package/dist/types/src/totp/pike-totp.d.ts.map +1 -0
- package/dist/types/src/totp/types.d.ts +11 -0
- package/dist/types/src/totp/types.d.ts.map +1 -0
- package/dist/types/src/transaction/broadcasters/ARC.d.ts +1 -1
- package/dist/types/src/transaction/broadcasters/ARC.d.ts.map +1 -1
- package/dist/types/src/transaction/broadcasters/DefaultBroadcaster.d.ts +1 -1
- package/dist/types/src/transaction/broadcasters/DefaultBroadcaster.d.ts.map +1 -1
- package/dist/types/src/transaction/broadcasters/WhatsOnChainBroadcaster.d.ts +1 -1
- package/dist/types/src/transaction/broadcasters/WhatsOnChainBroadcaster.d.ts.map +1 -1
- package/dist/types/src/transaction/chaintrackers/DefaultChainTracker.d.ts +1 -1
- package/dist/types/src/transaction/chaintrackers/DefaultChainTracker.d.ts.map +1 -1
- package/dist/types/src/transaction/chaintrackers/WhatsOnChain.d.ts +2 -2
- package/dist/types/src/transaction/chaintrackers/WhatsOnChain.d.ts.map +1 -1
- package/dist/types/src/transaction/fee-models/SatoshisPerKilobyte.d.ts.map +1 -1
- package/dist/types/src/transaction/http/DefaultHttpClient.d.ts.map +1 -1
- package/dist/types/src/transaction/http/FetchHttpClient.d.ts +7 -9
- package/dist/types/src/transaction/http/FetchHttpClient.d.ts.map +1 -1
- package/dist/types/src/transaction/http/HttpClient.d.ts +5 -5
- package/dist/types/src/transaction/http/HttpClient.d.ts.map +1 -1
- package/dist/types/src/transaction/http/NodejsHttpClient.d.ts +5 -6
- package/dist/types/src/transaction/http/NodejsHttpClient.d.ts.map +1 -1
- package/dist/types/src/transaction/http/index.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/docs/primitives.md +231 -16
- package/docs/transaction.md +38 -37
- package/package.json +1 -1
- package/src/compat/__tests/BSM.test.ts +37 -37
- package/src/compat/__tests/ECIES.test.ts +71 -71
- package/src/compat/__tests/HD.test.ts +362 -362
- package/src/compat/__tests/Mnemonic.test.ts +147 -148
- package/src/compat/__tests/Mnemonic.vectors.ts +170 -170
- package/src/messages/__tests/EncryptedMessage.test.ts +16 -16
- package/src/primitives/Point.ts +29 -10
- package/src/primitives/Polynomial.ts +89 -0
- package/src/primitives/PrivateKey.ts +147 -1
- package/src/primitives/PublicKey.ts +17 -2
- package/src/primitives/__tests/AESGCM.test.ts +20 -20
- package/src/primitives/__tests/Hash.test.ts +2 -2
- package/src/primitives/__tests/PBKDF2.vectors.ts +93 -93
- package/src/primitives/__tests/PrivateKey.split.test.ts +70 -0
- package/src/primitives/__tests/PublicKey.test.ts +14 -1
- package/src/primitives/__tests/bug-31.test.ts +24 -26
- package/src/primitives/__tests/utils.test.ts +13 -13
- package/src/primitives/index.ts +2 -1
- package/src/script/__tests/Script.test.ts +1 -1
- package/src/script/__tests/SpendComplex.test.ts +6 -6
- package/src/script/__tests/script.invalid.vectors.ts +1464 -1464
- package/src/script/__tests/script.valid.vectors.ts +1962 -1962
- package/src/script/__tests/spend.valid.vectors.ts +1369 -1369
- package/src/script/templates/P2PKH.ts +6 -6
- package/src/script/templates/RPuzzle.ts +1 -1
- package/src/transaction/__tests/Transaction.test.ts +5 -5
- package/src/transaction/__tests/bump.invalid.vectors.ts +1 -1
- package/src/transaction/__tests/bump.valid.vectors.ts +3 -3
- package/src/transaction/broadcasters/ARC.ts +20 -21
- package/src/transaction/broadcasters/DefaultBroadcaster.ts +3 -3
- package/src/transaction/broadcasters/WhatsOnChainBroadcaster.ts +10 -10
- package/src/transaction/broadcasters/__tests/WhatsOnChainBroadcaster.test.ts +7 -10
- package/src/transaction/chaintrackers/DefaultChainTracker.ts +3 -3
- package/src/transaction/chaintrackers/WhatsOnChain.ts +10 -12
- package/src/transaction/chaintrackers/__tests/WhatsOnChainChainTracker.test.ts +13 -17
- package/src/transaction/fee-models/SatoshisPerKilobyte.ts +2 -2
- package/src/transaction/http/DefaultHttpClient.ts +13 -13
- package/src/transaction/http/FetchHttpClient.ts +14 -16
- package/src/transaction/http/HttpClient.ts +22 -23
- package/src/transaction/http/NodejsHttpClient.ts +23 -25
- package/src/transaction/http/index.ts +6 -6
|
@@ -6,7 +6,58 @@ import Curve from './Curve.js'
|
|
|
6
6
|
import { sign, verify } from './ECDSA.js'
|
|
7
7
|
import { sha256, sha256hmac } from './Hash.js'
|
|
8
8
|
import Random from './Random.js'
|
|
9
|
-
import { fromBase58Check, toArray, toBase58Check } from './utils.js'
|
|
9
|
+
import { fromBase58Check, toArray, toBase58, toBase58Check } from './utils.js'
|
|
10
|
+
import Polynomial, { PointInFiniteField } from './Polynomial.js'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @class KeyShares
|
|
14
|
+
*
|
|
15
|
+
* This class is used to store the shares of a private key.
|
|
16
|
+
*
|
|
17
|
+
* @param shares - An array of shares
|
|
18
|
+
* @param threshold - The number of shares required to recombine the private key
|
|
19
|
+
*
|
|
20
|
+
* @returns KeyShares
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* const key = PrivateKey.fromShares(shares)
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
export class KeyShares {
|
|
28
|
+
points: PointInFiniteField[]
|
|
29
|
+
threshold: number
|
|
30
|
+
integrity: string
|
|
31
|
+
|
|
32
|
+
constructor (points: PointInFiniteField[], threshold: number, integrity: string) {
|
|
33
|
+
this.points = points
|
|
34
|
+
this.threshold = threshold
|
|
35
|
+
this.integrity = integrity
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static fromBackupFormat (shares: string[]): KeyShares {
|
|
39
|
+
let threshold = 0
|
|
40
|
+
let integrity = ''
|
|
41
|
+
const points = shares.map((share, idx) => {
|
|
42
|
+
const shareParts = share.split('.')
|
|
43
|
+
if (shareParts.length !== 4) throw Error('Invalid share format in share ' + idx + '. Expected format: "x.y.t.i" - received ' + share)
|
|
44
|
+
const [x, y, t, i] = shareParts
|
|
45
|
+
if (!t) throw Error('Threshold not found in share ' + idx)
|
|
46
|
+
if (!i) throw Error('Integrity not found in share ' + idx)
|
|
47
|
+
const tInt = parseInt(t)
|
|
48
|
+
if (idx !== 0 && threshold !== tInt) throw Error('Threshold mismatch in share ' + idx)
|
|
49
|
+
if (idx !== 0 && integrity !== i) throw Error('Integrity mismatch in share ' + idx)
|
|
50
|
+
threshold = tInt
|
|
51
|
+
integrity = i
|
|
52
|
+
return PointInFiniteField.fromString([x, y].join('.'))
|
|
53
|
+
})
|
|
54
|
+
return new KeyShares(points, threshold, integrity)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
toBackupFormat () {
|
|
58
|
+
return this.points.map(share => share.toString() + '.' + this.threshold + '.' + this.integrity)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
10
61
|
|
|
11
62
|
/**
|
|
12
63
|
* Represents a Private Key, which is a secret that can be used to generate signatures in a cryptographic system.
|
|
@@ -256,4 +307,99 @@ export default class PrivateKey extends BigNumber {
|
|
|
256
307
|
const curve = new Curve()
|
|
257
308
|
return new PrivateKey(this.add(new BigNumber(hmac)).mod(curve.n).toArray())
|
|
258
309
|
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Splits the private key into shares using Shamir's Secret Sharing Scheme.
|
|
313
|
+
*
|
|
314
|
+
* @param threshold The minimum number of shares required to reconstruct the private key.
|
|
315
|
+
* @param totalShares The total number of shares to generate.
|
|
316
|
+
* @param prime The prime number to be used in Shamir's Secret Sharing Scheme.
|
|
317
|
+
* @returns An array of shares.
|
|
318
|
+
*
|
|
319
|
+
* @example
|
|
320
|
+
* const key = PrivateKey.fromRandom()
|
|
321
|
+
* const shares = key.toKeyShares(2, 5)
|
|
322
|
+
*/
|
|
323
|
+
toKeyShares (threshold: number, totalShares: number): KeyShares {
|
|
324
|
+
if (typeof threshold !== 'number' || typeof totalShares !== 'number') throw new Error('threshold and totalShares must be numbers')
|
|
325
|
+
if (threshold < 2) throw new Error('threshold must be at least 2')
|
|
326
|
+
if (totalShares < 2) throw new Error('totalShares must be at least 2')
|
|
327
|
+
if (threshold > totalShares) throw new Error('threshold should be less than or equal to totalShares')
|
|
328
|
+
|
|
329
|
+
const poly = Polynomial.fromPrivateKey(this, threshold)
|
|
330
|
+
|
|
331
|
+
const points = []
|
|
332
|
+
for (let i = 0; i < totalShares; i++) {
|
|
333
|
+
const x = new BigNumber(PrivateKey.fromRandom().toArray())
|
|
334
|
+
const y = poly.valueAt(x)
|
|
335
|
+
points.push(new PointInFiniteField(x, y))
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const integrity = (this.toPublicKey().toHash('hex') as string).slice(0, 8)
|
|
339
|
+
|
|
340
|
+
return new KeyShares(points, threshold, integrity)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* @method toBackupShares
|
|
345
|
+
*
|
|
346
|
+
* Creates a backup of the private key by splitting it into shares.
|
|
347
|
+
*
|
|
348
|
+
*
|
|
349
|
+
* @param threshold The number of shares which will be required to reconstruct the private key.
|
|
350
|
+
* @param totalShares The number of shares to generate for distribution.
|
|
351
|
+
* @returns
|
|
352
|
+
*/
|
|
353
|
+
toBackupShares (threshold: number, totalShares: number): string[] {
|
|
354
|
+
return this.toKeyShares(threshold, totalShares).toBackupFormat()
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
*
|
|
359
|
+
* @method fromBackupShares
|
|
360
|
+
*
|
|
361
|
+
* Creates a private key from backup shares.
|
|
362
|
+
*
|
|
363
|
+
* @param shares
|
|
364
|
+
* @returns PrivateKey
|
|
365
|
+
*/
|
|
366
|
+
static fromBackupShares (shares: string[]): PrivateKey {
|
|
367
|
+
return PrivateKey.fromKeyShares(KeyShares.fromBackupFormat(shares))
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Combines shares to reconstruct the private key.
|
|
372
|
+
*
|
|
373
|
+
* @param shares An array of points (shares) to be used to reconstruct the private key.
|
|
374
|
+
* @param threshold The minimum number of shares required to reconstruct the private key.
|
|
375
|
+
*
|
|
376
|
+
* @returns The reconstructed private key.
|
|
377
|
+
*
|
|
378
|
+
* @example
|
|
379
|
+
* const share1 = '2NWeap6SDBTL5jVnvk9yUxyfLqNrDs2Bw85KNDfLJwRT.4yLtSm327NApsbuP7QXVW3CWDuBRgmS6rRiFkAkTukic'
|
|
380
|
+
* const share2 = '7NbgGA8iAsxg2s6mBLkLFtGKQrnc4aCbooHJJV31cWs4.GUgXtudthawE3Eevc1waT3Atr1Ft7j1XxdUguVo3B7x3'
|
|
381
|
+
* const reconstructedKey = PrivateKey.fromKeyShares({ shares: [share1, share2], threshold: 2, integrity: '23409547' })
|
|
382
|
+
*
|
|
383
|
+
**/
|
|
384
|
+
static fromKeyShares (keyShares: KeyShares): PrivateKey {
|
|
385
|
+
const { points, threshold, integrity } = keyShares
|
|
386
|
+
if (threshold < 2 || threshold > 99) throw new Error('threshold should be between 2 and 99')
|
|
387
|
+
if (points.length < threshold) throw new Error(`At least ${threshold} shares are required to reconstruct the private key`)
|
|
388
|
+
// check to see if two points have the same x value
|
|
389
|
+
for (let i = 0; i < threshold; i++) {
|
|
390
|
+
for (let j = i + 1; j < threshold; j++) {
|
|
391
|
+
if (points[i].x.eq(points[j].x)) {
|
|
392
|
+
throw new Error('Duplicate share detected, each must be unique.')
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
const poly = new Polynomial(points, threshold)
|
|
397
|
+
const privateKey = new PrivateKey(poly.valueAt(new BigNumber(0)).toArray())
|
|
398
|
+
const integrityHash = privateKey.toPublicKey().toHash('hex').slice(0, 8)
|
|
399
|
+
if (integrityHash !== integrity) {
|
|
400
|
+
throw new Error('Integrity hash mismatch')
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
return privateKey
|
|
404
|
+
}
|
|
259
405
|
}
|
|
@@ -51,6 +51,21 @@ export default class PublicKey extends Point {
|
|
|
51
51
|
return new PublicKey(p.x, p.y)
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Static factory method to create a PublicKey instance from a number array.
|
|
56
|
+
*
|
|
57
|
+
* @param bytes - A number array representing a public key.
|
|
58
|
+
*
|
|
59
|
+
* @returns Returns the PublicKey created from the number array.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* const myPubKey = PublicKey.fromString("03....")
|
|
63
|
+
*/
|
|
64
|
+
static fromDER (bytes: number[]): PublicKey {
|
|
65
|
+
const p = Point.fromDER(bytes)
|
|
66
|
+
return new PublicKey(p.x, p.y)
|
|
67
|
+
}
|
|
68
|
+
|
|
54
69
|
/**
|
|
55
70
|
* @constructor
|
|
56
71
|
* @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.
|
|
@@ -121,8 +136,8 @@ export default class PublicKey extends Point {
|
|
|
121
136
|
* @example
|
|
122
137
|
* const derPublicKey = myPubKey.toDER()
|
|
123
138
|
*/
|
|
124
|
-
toDER (): string {
|
|
125
|
-
return this.encode(true,
|
|
139
|
+
toDER (enc?: 'hex' | undefined): string {
|
|
140
|
+
return this.encode(true, enc) as string
|
|
126
141
|
}
|
|
127
142
|
|
|
128
143
|
/**
|
|
@@ -61,7 +61,7 @@ describe('AESGCM', () => {
|
|
|
61
61
|
it('should encrypt: Test Case 3', () => {
|
|
62
62
|
const output = AESGCM(toArray('d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956' +
|
|
63
63
|
'809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255', 'hex'), [], toArray('cafebabefacedbaddecaf888', 'hex'),
|
|
64
|
-
|
|
64
|
+
toArray('feffe9928665731c6d6a8f9467308308', 'hex'))
|
|
65
65
|
|
|
66
66
|
expect(toArray('42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8' +
|
|
67
67
|
'f6a5aac84aa051ba30b396a0aac973d58e091473f5985', 'hex')).toEqual(output.result)
|
|
@@ -71,7 +71,7 @@ describe('AESGCM', () => {
|
|
|
71
71
|
it('should encrypt: Test Case 4', () => {
|
|
72
72
|
const output = AESGCM(toArray('d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956' +
|
|
73
73
|
'809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', 'hex'), toArray('feedfacedeadbeeffeedfacedeadbeefabaddad2', 'hex'),
|
|
74
|
-
|
|
74
|
+
toArray('cafebabefacedbaddecaf888', 'hex'), toArray('feffe9928665731c6d6a8f9467308308', 'hex'))
|
|
75
75
|
expect(toArray('42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8' +
|
|
76
76
|
'f6a5aac84aa051ba30b396a0aac973d58e091', 'hex')).toEqual(output.result)
|
|
77
77
|
expect(toArray('5bc94fbc3221a5db94fae95ae7121a47', 'hex')).toEqual(output.authenticationTag)
|
|
@@ -80,7 +80,7 @@ describe('AESGCM', () => {
|
|
|
80
80
|
it('should encrypt: Test Case 5', () => {
|
|
81
81
|
const output = AESGCM(toArray('d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956' +
|
|
82
82
|
'809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', 'hex'), toArray('feedfacedeadbeeffeedfacedeadbeefabaddad2', 'hex'),
|
|
83
|
-
|
|
83
|
+
toArray('cafebabefacedbad', 'hex'), toArray('feffe9928665731c6d6a8f9467308308', 'hex'))
|
|
84
84
|
|
|
85
85
|
expect(toArray('61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b0' +
|
|
86
86
|
'97544d4896b424989b5e1ebac0f07c23f4598', 'hex')).toEqual(output.result)
|
|
@@ -90,7 +90,7 @@ describe('AESGCM', () => {
|
|
|
90
90
|
it('should encrypt: Test Case 6', () => {
|
|
91
91
|
const output = AESGCM(toArray('d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956' +
|
|
92
92
|
'809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', 'hex'), toArray('feedfacedeadbeeffeedfacedeadbeefabaddad2', 'hex'),
|
|
93
|
-
|
|
93
|
+
toArray('9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416' +
|
|
94
94
|
'aedbf5a0de6a57a637b39b', 'hex'), toArray('feffe9928665731c6d6a8f9467308308', 'hex'))
|
|
95
95
|
|
|
96
96
|
expect(toArray('8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccd' +
|
|
@@ -117,7 +117,7 @@ describe('AESGCM', () => {
|
|
|
117
117
|
it('should encrypt: Test Case 9', () => {
|
|
118
118
|
const output = AESGCM(toArray('d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956' +
|
|
119
119
|
'809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255', 'hex'), [], toArray('cafebabefacedbaddecaf888', 'hex'),
|
|
120
|
-
|
|
120
|
+
toArray('feffe9928665731c6d6a8f9467308308feffe9928665731c', 'hex'))
|
|
121
121
|
|
|
122
122
|
expect(toArray('3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac6' +
|
|
123
123
|
'19d18c84a3f4718e2448b2fe324d9ccda2710acade256', 'hex')).toEqual(output.result)
|
|
@@ -127,7 +127,7 @@ describe('AESGCM', () => {
|
|
|
127
127
|
it('should encrypt: Test Case 10', () => {
|
|
128
128
|
const output = AESGCM(toArray('d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956' +
|
|
129
129
|
'809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', 'hex'), toArray('feedfacedeadbeeffeedfacedeadbeefabaddad2', 'hex'),
|
|
130
|
-
|
|
130
|
+
toArray('cafebabefacedbaddecaf888', 'hex'), toArray('feffe9928665731c6d6a8f9467308308feffe9928665731c', 'hex'))
|
|
131
131
|
|
|
132
132
|
expect(toArray('3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac6' +
|
|
133
133
|
'19d18c84a3f4718e2448b2fe324d9ccda2710', 'hex')).toEqual(output.result)
|
|
@@ -137,7 +137,7 @@ describe('AESGCM', () => {
|
|
|
137
137
|
it('should encrypt: Test Case 11', () => {
|
|
138
138
|
const output = AESGCM(toArray('d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956' +
|
|
139
139
|
'809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', 'hex'), toArray('feedfacedeadbeeffeedfacedeadbeefabaddad2', 'hex'),
|
|
140
|
-
|
|
140
|
+
toArray('cafebabefacedbad', 'hex'), toArray('feffe9928665731c6d6a8f9467308308feffe9928665731c', 'hex'))
|
|
141
141
|
|
|
142
142
|
expect(toArray('0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66' +
|
|
143
143
|
'541d4d4dad1c9e93a19a58e8b473fa0f062f7', 'hex')).toEqual(output.result)
|
|
@@ -147,7 +147,7 @@ describe('AESGCM', () => {
|
|
|
147
147
|
it('should encrypt: Test Case 12', () => {
|
|
148
148
|
const output = AESGCM(toArray('d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956' +
|
|
149
149
|
'809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', 'hex'), toArray('feedfacedeadbeeffeedfacedeadbeefabaddad2', 'hex'),
|
|
150
|
-
|
|
150
|
+
toArray('9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b5254' +
|
|
151
151
|
'16aedbf5a0de6a57a637b39b', 'hex'), toArray('feffe9928665731c6d6a8f9467308308feffe9928665731c', 'hex'))
|
|
152
152
|
|
|
153
153
|
expect(toArray('d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f' +
|
|
@@ -175,8 +175,8 @@ describe('AESGCM', () => {
|
|
|
175
175
|
it('should encrypt: Test Case 15', () => {
|
|
176
176
|
const output = AESGCM(toArray('d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956' +
|
|
177
177
|
'809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255', 'hex'), [],
|
|
178
|
-
|
|
179
|
-
|
|
178
|
+
toArray('cafebabefacedbaddecaf888', 'hex'),
|
|
179
|
+
toArray('feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308', 'hex'))
|
|
180
180
|
|
|
181
181
|
expect(toArray('522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b' +
|
|
182
182
|
'08b1056828838c5f61e6393ba7a0abcc9f662898015ad', 'hex')).toEqual(output.result)
|
|
@@ -186,8 +186,8 @@ describe('AESGCM', () => {
|
|
|
186
186
|
it('should encrypt: Test Case 16', () => {
|
|
187
187
|
const output = AESGCM(toArray('d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956' +
|
|
188
188
|
'809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', 'hex'), toArray('feedfacedeadbeeffeedfacedeadbeefabaddad2', 'hex'),
|
|
189
|
-
|
|
190
|
-
|
|
189
|
+
toArray('cafebabefacedbaddecaf888', 'hex'),
|
|
190
|
+
toArray('feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308', 'hex'))
|
|
191
191
|
|
|
192
192
|
expect(toArray('522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b' +
|
|
193
193
|
'08b1056828838c5f61e6393ba7a0abcc9f662', 'hex')).toEqual(output.result)
|
|
@@ -197,9 +197,9 @@ describe('AESGCM', () => {
|
|
|
197
197
|
it('should encrypt: Test Case 17', () => {
|
|
198
198
|
const output = AESGCM(toArray('d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956' +
|
|
199
199
|
'809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', 'hex'),
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
200
|
+
toArray('feedfacedeadbeeffeedfacedeadbeefabaddad2', 'hex'),
|
|
201
|
+
toArray('cafebabefacedbad', 'hex'),
|
|
202
|
+
toArray('feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308', 'hex'))
|
|
203
203
|
|
|
204
204
|
expect(toArray('c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954' +
|
|
205
205
|
'cc2363bc73f7862ac430e64abe499f47c9b1f', 'hex')).toEqual(output.result)
|
|
@@ -209,10 +209,10 @@ describe('AESGCM', () => {
|
|
|
209
209
|
it('should encrypt: Test Case 18', () => {
|
|
210
210
|
const output = AESGCM(toArray('d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956' +
|
|
211
211
|
'809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', 'hex'),
|
|
212
|
-
|
|
213
|
-
|
|
212
|
+
toArray('feedfacedeadbeeffeedfacedeadbeefabaddad2', 'hex'),
|
|
213
|
+
toArray('9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416' +
|
|
214
214
|
'aedbf5a0de6a57a637b39b', 'hex'),
|
|
215
|
-
|
|
215
|
+
toArray('feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308', 'hex'))
|
|
216
216
|
|
|
217
217
|
expect(toArray('5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da' +
|
|
218
218
|
'3ebf1c5d82cdea2418997200ef82e44ae7e3f', 'hex')).toEqual(output.result)
|
|
@@ -248,8 +248,8 @@ describe('multiply', () => {
|
|
|
248
248
|
it('should commutatively multiply', () => {
|
|
249
249
|
expect(multiply(toArray('48692853686179295b477565726f6e5d', 'hex'),
|
|
250
250
|
toArray('7b5b54657374566563746f725d53475d', 'hex'))).toEqual(
|
|
251
|
-
|
|
252
|
-
|
|
251
|
+
multiply(toArray('7b5b54657374566563746f725d53475d', 'hex'),
|
|
252
|
+
toArray('48692853686179295b477565726f6e5d', 'hex')))
|
|
253
253
|
})
|
|
254
254
|
})
|
|
255
255
|
|
|
@@ -5,7 +5,7 @@ import PBKDF2Vectors from './PBKDF2.vectors'
|
|
|
5
5
|
import { toArray, toHex } from '../../../dist/cjs/src/primitives/utils'
|
|
6
6
|
|
|
7
7
|
describe('Hash', function () {
|
|
8
|
-
function test(Hash, cases): void {
|
|
8
|
+
function test (Hash, cases): void {
|
|
9
9
|
for (let i = 0; i < cases.length; i++) {
|
|
10
10
|
const msg = cases[i][0]
|
|
11
11
|
const res = cases[i][1]
|
|
@@ -92,7 +92,7 @@ describe('Hash', function () {
|
|
|
92
92
|
|
|
93
93
|
describe('PBKDF2 vectors', () => {
|
|
94
94
|
for (let i = 0; i < PBKDF2Vectors.length; i++) {
|
|
95
|
-
|
|
95
|
+
const v = PBKDF2Vectors[i]
|
|
96
96
|
let key, salt
|
|
97
97
|
if (v.keyUint8Array) {
|
|
98
98
|
key = v.keyUint8Array
|
|
@@ -1,119 +1,119 @@
|
|
|
1
1
|
export default [{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
key: 'password',
|
|
3
|
+
salt: 'salt',
|
|
4
|
+
iterations: 1,
|
|
5
|
+
dkLen: 32,
|
|
6
|
+
results: {
|
|
7
|
+
sha512: '867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252'
|
|
8
|
+
}
|
|
9
9
|
},
|
|
10
10
|
{
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
key: 'password',
|
|
12
|
+
salt: 'salt',
|
|
13
|
+
iterations: 2,
|
|
14
|
+
dkLen: 32,
|
|
15
|
+
results: {
|
|
16
|
+
sha512: 'e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f0040713f18aefdb866d53c'
|
|
17
|
+
}
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
key: 'password',
|
|
21
|
+
salt: 'salt',
|
|
22
|
+
iterations: 1,
|
|
23
|
+
dkLen: 64,
|
|
24
|
+
results: {
|
|
25
|
+
sha512: '867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252c02d470a285a0501bad999bfe943c08f050235d7d68b1da55e63f73b60a57fce'
|
|
26
|
+
}
|
|
27
27
|
},
|
|
28
28
|
{
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
key: 'password',
|
|
30
|
+
salt: 'salt',
|
|
31
|
+
iterations: 2,
|
|
32
|
+
dkLen: 64,
|
|
33
|
+
results: {
|
|
34
|
+
sha512: 'e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f0040713f18aefdb866d53cf76cab2868a39b9f7840edce4fef5a82be67335c77a6068e04112754f27ccf4e'
|
|
35
|
+
}
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
38
|
+
key: 'password',
|
|
39
|
+
salt: 'salt',
|
|
40
|
+
iterations: 4096,
|
|
41
|
+
dkLen: 32,
|
|
42
|
+
results: {
|
|
43
|
+
sha512: 'd197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f87f6902e072f457b5'
|
|
44
|
+
}
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
47
|
+
key: 'passwordPASSWORDpassword',
|
|
48
|
+
salt: 'saltSALTsaltSALTsaltSALTsaltSALTsalt',
|
|
49
|
+
iterations: 4096,
|
|
50
|
+
dkLen: 40,
|
|
51
|
+
results: {
|
|
52
|
+
sha512: '8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868c005174dc4ee71115b59f9e60cd953'
|
|
53
|
+
}
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
56
|
+
key: 'pass\u00000word',
|
|
57
|
+
salt: 'sa\u00000lt',
|
|
58
|
+
iterations: 4096,
|
|
59
|
+
dkLen: 16,
|
|
60
|
+
results: {
|
|
61
|
+
sha512: '336d14366099e8aac2c46c94a8f178d2'
|
|
62
|
+
}
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
65
|
+
keyHex: '63ffeeddccbbaa',
|
|
66
|
+
salt: 'salt',
|
|
67
|
+
iterations: 1,
|
|
68
|
+
dkLen: 32,
|
|
69
|
+
results: {
|
|
70
|
+
sha512: 'f69de451247225a7b30cc47632899572bb980f500d7c606ac9b1c04f928a3488'
|
|
71
|
+
}
|
|
72
72
|
},
|
|
73
73
|
{
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
74
|
+
description: 'Unicode salt, no truncation due to hex',
|
|
75
|
+
key: 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about',
|
|
76
|
+
saltHex: '6d6e656d6f6e6963e383a1e383bce38388e383abe382abe38299e3838fe38299e382a6e38299e382a1e381afe3829ae381afe38299e3818fe38299e3829de38299e381a1e381a1e38299e58d81e4babae58d81e889b2',
|
|
77
|
+
iterations: 2048,
|
|
78
|
+
dkLen: 64,
|
|
79
|
+
results: {
|
|
80
|
+
sha512: 'ba553eedefe76e67e2602dc20184c564010859faada929a090dd2c57aacb204ceefd15404ab50ef3e8dbeae5195aeae64b0def4d2eead1cdc728a33ced520ffd'
|
|
81
|
+
}
|
|
82
82
|
},
|
|
83
83
|
{
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
84
|
+
key: 'password',
|
|
85
|
+
salt: 'salt',
|
|
86
|
+
iterations: 1,
|
|
87
|
+
dkLen: 10,
|
|
88
|
+
results: {
|
|
89
|
+
sha512: '867f70cf1ade02cff375'
|
|
90
|
+
}
|
|
91
91
|
},
|
|
92
92
|
{
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
93
|
+
key: 'password',
|
|
94
|
+
salt: 'salt',
|
|
95
|
+
iterations: 1,
|
|
96
|
+
dkLen: 100,
|
|
97
|
+
results: {
|
|
98
|
+
sha512: '867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252c02d470a285a0501bad999bfe943c08f050235d7d68b1da55e63f73b60a57fce7b532e206c2967d4c7d2ffa460539fc4d4e5eec70125d74c6c7cf86d25284f297907fcea'
|
|
99
|
+
}
|
|
100
100
|
},
|
|
101
101
|
{
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
102
|
+
keyUint8Array: [112, 97, 115, 115, 119, 111, 114, 100],
|
|
103
|
+
salt: 'salt',
|
|
104
|
+
iterations: 1,
|
|
105
|
+
dkLen: 32,
|
|
106
|
+
results: {
|
|
107
|
+
sha512: '867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252'
|
|
108
|
+
}
|
|
109
109
|
},
|
|
110
110
|
{
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
111
|
+
key: 'password',
|
|
112
|
+
saltUint8Array: [115, 97, 108, 116],
|
|
113
|
+
iterations: 1,
|
|
114
|
+
dkLen: 32,
|
|
115
|
+
results: {
|
|
116
|
+
sha512: '867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252'
|
|
117
|
+
}
|
|
118
118
|
}
|
|
119
|
-
]
|
|
119
|
+
]
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import PrivateKey, { KeyShares } from '../../../dist/cjs/src/primitives/PrivateKey'
|
|
2
|
+
import { PointInFiniteField } from '../../../dist/cjs/src/primitives/Polynomial'
|
|
3
|
+
|
|
4
|
+
describe('PrivateKey', () => {
|
|
5
|
+
it('should split the private key into shares correctly', () => {
|
|
6
|
+
const privateKey = PrivateKey.fromRandom()
|
|
7
|
+
const threshold = 2
|
|
8
|
+
const totalShares = 5
|
|
9
|
+
|
|
10
|
+
// Split the private key
|
|
11
|
+
const shares = privateKey.toKeyShares(threshold, totalShares)
|
|
12
|
+
const backup = shares.toBackupFormat()
|
|
13
|
+
|
|
14
|
+
// Check the number of shares
|
|
15
|
+
expect(backup.length).toBe(totalShares)
|
|
16
|
+
|
|
17
|
+
// Check that each share is a BigNumber
|
|
18
|
+
shares.points.forEach(share => {
|
|
19
|
+
expect(share).toBeInstanceOf(PointInFiniteField)
|
|
20
|
+
})
|
|
21
|
+
expect(shares.threshold).toBe(threshold)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('should recombine the shares into a private key correctly', () => {
|
|
25
|
+
let x = 0
|
|
26
|
+
while (x < 3) {
|
|
27
|
+
const key = PrivateKey.fromRandom()
|
|
28
|
+
const allShares = key.toKeyShares(3, 5)
|
|
29
|
+
const backup = allShares.toBackupFormat()
|
|
30
|
+
const someShares = KeyShares.fromBackupFormat(backup.slice(0,3))
|
|
31
|
+
const rebuiltKey = PrivateKey.fromKeyShares(someShares)
|
|
32
|
+
expect(rebuiltKey.toWif()).toBe(key.toWif())
|
|
33
|
+
x++
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it('should throw an error for invalid threshold or totalShares', () => {
|
|
38
|
+
const k = PrivateKey.fromRandom()
|
|
39
|
+
expect(() => k.toKeyShares('12', 14)).toThrow('threshold and totalShares must be numbers')
|
|
40
|
+
expect(() => k.toKeyShares(4, '5')).toThrow('threshold and totalShares must be numbers')
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('should throw an error for invalid threshold', () => {
|
|
44
|
+
const k = PrivateKey.fromRandom()
|
|
45
|
+
expect(() => k.toKeyShares(1, 2)).toThrow('threshold must be at least 2')
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it('should throw an error for invalid totalShares', () => {
|
|
49
|
+
const k = PrivateKey.fromRandom()
|
|
50
|
+
expect(() => k.toKeyShares(2, -4)).toThrow('totalShares must be at least 2')
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('should throw an error for totalShares being less than threshold', () => {
|
|
54
|
+
const k = PrivateKey.fromRandom()
|
|
55
|
+
expect(() => k.toKeyShares(3, 2)).toThrow('threshold should be less than or equal to totalShares')
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('should throw an error if the same share is included twice during recovery', () => {
|
|
59
|
+
const backup = [ '45s4vLL2hFvqmxrarvbRT2vZoQYGZGocsmaEksZ64o5M.A7nZrGux15nEsQGNZ1mbfnMKugNnS6SYYEQwfhfbDZG8.3.2f804d43', '7aPzkiGZgvU4Jira5PN9Qf9o7FEg6uwy1zcxd17NBhh3.CCt7NH1sPFgceb6phTRkfviim2WvmUycJCQd2BxauxP9.3.2f804d43', '9GaS2Tw5sXqqbuigdjwGPwPsQuEFqzqUXo5MAQhdK3es.8MLh2wyE3huyq6hiBXjSkJRucgyKh4jVY6ESq5jNtXRE.3.2f804d43', 'GBmoNRbsMVsLmEK5A6G28fktUNonZkn9mDrJJ58FXgsf.HDBRkzVUCtZ38ApEu36fvZtDoDSQTv3TWmbnxwwR7kto.3.2f804d43', '2gHebXBgPd7daZbsj6w9TPDta3vQzqvbkLtJG596rdN1.E7ZaHyyHNDCwR6qxZvKkPPWWXzFCiKQFentJtvSSH5Bi.3.2f804d43' ]
|
|
60
|
+
const recovery = KeyShares.fromBackupFormat([backup[0], backup[1], backup[1]])
|
|
61
|
+
expect(() => PrivateKey.fromKeyShares(recovery)).toThrow('Duplicate share detected, each must be unique.')
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('should be able to create a backup array from a private key, and recover the same key back from the backup', () => {
|
|
65
|
+
const key = PrivateKey.fromRandom()
|
|
66
|
+
const backup = key.toBackupShares(3, 5)
|
|
67
|
+
const recoveredKey = PrivateKey.fromBackupShares(backup.slice(0, 3))
|
|
68
|
+
expect(recoveredKey.toWif()).toBe(key.toWif())
|
|
69
|
+
})
|
|
70
|
+
})
|
|
@@ -47,10 +47,23 @@ describe('PublicKey', () => {
|
|
|
47
47
|
})
|
|
48
48
|
|
|
49
49
|
test('toDER should return DER encoded string of public key', () => {
|
|
50
|
-
const derString = publicKey.
|
|
50
|
+
const derString = publicKey.toString()
|
|
51
51
|
expect(typeof derString).toBe('string')
|
|
52
52
|
expect(derString.length).toBe(66)
|
|
53
53
|
})
|
|
54
|
+
|
|
55
|
+
test('toDER should return DER encoded number[] of public key', () => {
|
|
56
|
+
const der = publicKey.toDER()
|
|
57
|
+
expect(typeof der).toBe('object')
|
|
58
|
+
expect(der.length).toBe(33)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
test('fromDER and fromString should result in the same public key', () => {
|
|
62
|
+
const key = PrivateKey.fromRandom()
|
|
63
|
+
const original = key.toPublicKey()
|
|
64
|
+
const backAndForth = PublicKey.fromString(PublicKey.fromDER(original.toDER()).toString())
|
|
65
|
+
expect(backAndForth.toString()).toEqual(original.toString())
|
|
66
|
+
})
|
|
54
67
|
})
|
|
55
68
|
describe('BRC42 vectors', () => {
|
|
56
69
|
for (let i = 0; i < BRC42Public.length; i++) {
|