@bsv/sdk 1.9.23 → 1.9.29
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/primitives/AESGCM.js +160 -76
- package/dist/cjs/src/primitives/AESGCM.js.map +1 -1
- package/dist/cjs/src/primitives/Hash.js +70 -5
- package/dist/cjs/src/primitives/Hash.js.map +1 -1
- package/dist/cjs/src/primitives/Point.js +41 -18
- package/dist/cjs/src/primitives/Point.js.map +1 -1
- package/dist/cjs/src/primitives/SymmetricKey.js +20 -19
- package/dist/cjs/src/primitives/SymmetricKey.js.map +1 -1
- package/dist/cjs/src/primitives/hex.js +1 -3
- package/dist/cjs/src/primitives/hex.js.map +1 -1
- package/dist/cjs/src/primitives/utils.js +10 -0
- package/dist/cjs/src/primitives/utils.js.map +1 -1
- package/dist/cjs/src/totp/totp.js +3 -1
- package/dist/cjs/src/totp/totp.js.map +1 -1
- package/dist/cjs/src/wallet/ProtoWallet.js +4 -2
- package/dist/cjs/src/wallet/ProtoWallet.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/primitives/AESGCM.js +158 -75
- package/dist/esm/src/primitives/AESGCM.js.map +1 -1
- package/dist/esm/src/primitives/Hash.js +68 -6
- package/dist/esm/src/primitives/Hash.js.map +1 -1
- package/dist/esm/src/primitives/Point.js +41 -18
- package/dist/esm/src/primitives/Point.js.map +1 -1
- package/dist/esm/src/primitives/SymmetricKey.js +20 -19
- package/dist/esm/src/primitives/SymmetricKey.js.map +1 -1
- package/dist/esm/src/primitives/hex.js +1 -3
- package/dist/esm/src/primitives/hex.js.map +1 -1
- package/dist/esm/src/primitives/utils.js +9 -0
- package/dist/esm/src/primitives/utils.js.map +1 -1
- package/dist/esm/src/totp/totp.js +3 -1
- package/dist/esm/src/totp/totp.js.map +1 -1
- package/dist/esm/src/wallet/ProtoWallet.js +4 -2
- package/dist/esm/src/wallet/ProtoWallet.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/primitives/AESGCM.d.ts +59 -9
- package/dist/types/src/primitives/AESGCM.d.ts.map +1 -1
- package/dist/types/src/primitives/Hash.d.ts +47 -0
- package/dist/types/src/primitives/Hash.d.ts.map +1 -1
- package/dist/types/src/primitives/Point.d.ts +1 -0
- package/dist/types/src/primitives/Point.d.ts.map +1 -1
- package/dist/types/src/primitives/SymmetricKey.d.ts.map +1 -1
- package/dist/types/src/primitives/hex.d.ts.map +1 -1
- package/dist/types/src/primitives/utils.d.ts +1 -0
- package/dist/types/src/primitives/utils.d.ts.map +1 -1
- package/dist/types/src/totp/totp.d.ts.map +1 -1
- package/dist/types/src/wallet/ProtoWallet.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +3 -3
- package/dist/umd/bundle.js.map +1 -1
- package/docs/reference/primitives.md +206 -60
- package/package.json +1 -1
- package/src/primitives/AESGCM.ts +225 -103
- package/src/primitives/Hash.ts +72 -7
- package/src/primitives/Point.ts +67 -20
- package/src/primitives/SymmetricKey.ts +28 -20
- package/src/primitives/__tests/AESGCM.test.ts +254 -354
- package/src/primitives/__tests/ECDSA.test.ts +27 -0
- package/src/primitives/__tests/Hash.test.ts +62 -10
- package/src/primitives/__tests/Point.test.ts +52 -0
- package/src/primitives/__tests/utils.test.ts +24 -1
- package/src/primitives/hex.ts +1 -3
- package/src/primitives/utils.ts +10 -0
- package/src/totp/__tests/totp.test.ts +21 -0
- package/src/totp/totp.ts +9 -1
- package/src/wallet/ProtoWallet.ts +8 -3
- package/src/wallet/__tests/ProtoWallet.test.ts +55 -34
package/src/primitives/Point.ts
CHANGED
|
@@ -44,14 +44,17 @@ export const biModInv = (a: bigint): bigint => { // binary‑ext GCD
|
|
|
44
44
|
export const biModSqr = (a: bigint): bigint => biModMul(a, a)
|
|
45
45
|
|
|
46
46
|
export const biModPow = (base: bigint, exp: bigint): bigint => {
|
|
47
|
-
let result =
|
|
47
|
+
let result = 1n
|
|
48
48
|
base = biMod(base)
|
|
49
|
-
|
|
50
|
-
while (
|
|
51
|
-
if ((
|
|
49
|
+
|
|
50
|
+
while (exp > 0n) {
|
|
51
|
+
if ((exp & 1n) !== 0n) {
|
|
52
|
+
result = biModMul(result, base)
|
|
53
|
+
}
|
|
52
54
|
base = biModMul(base, base)
|
|
53
|
-
|
|
55
|
+
exp >>= 1n
|
|
54
56
|
}
|
|
57
|
+
|
|
55
58
|
return result
|
|
56
59
|
}
|
|
57
60
|
|
|
@@ -59,7 +62,12 @@ export const P_PLUS1_DIV4 = (P_BIGINT + 1n) >> 2n
|
|
|
59
62
|
|
|
60
63
|
export const biModSqrt = (a: bigint): bigint | null => {
|
|
61
64
|
const r = biModPow(a, P_PLUS1_DIV4)
|
|
62
|
-
|
|
65
|
+
|
|
66
|
+
if (biModMul(r, r) !== biMod(a)) {
|
|
67
|
+
return null
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return r
|
|
63
71
|
}
|
|
64
72
|
|
|
65
73
|
const toBigInt = (x: BigNumber | number | number[] | string): bigint => {
|
|
@@ -220,6 +228,13 @@ export default class Point extends BasePoint {
|
|
|
220
228
|
y: BigNumber | null
|
|
221
229
|
inf: boolean
|
|
222
230
|
|
|
231
|
+
static _assertOnCurve (p: Point): Point {
|
|
232
|
+
if (!p.validate()) {
|
|
233
|
+
throw new Error('Invalid point')
|
|
234
|
+
}
|
|
235
|
+
return p
|
|
236
|
+
}
|
|
237
|
+
|
|
223
238
|
/**
|
|
224
239
|
* Creates a point object from a given Array. These numbers can represent coordinates in hex format, or points
|
|
225
240
|
* in multiple established formats.
|
|
@@ -238,7 +253,6 @@ export default class Point extends BasePoint {
|
|
|
238
253
|
*/
|
|
239
254
|
static fromDER (bytes: number[]): Point {
|
|
240
255
|
const len = 32
|
|
241
|
-
// uncompressed, hybrid-odd, hybrid-even
|
|
242
256
|
if (
|
|
243
257
|
(bytes[0] === 0x04 || bytes[0] === 0x06 || bytes[0] === 0x07) &&
|
|
244
258
|
bytes.length - 1 === 2 * len
|
|
@@ -258,12 +272,14 @@ export default class Point extends BasePoint {
|
|
|
258
272
|
bytes.slice(1 + len, 1 + 2 * len)
|
|
259
273
|
)
|
|
260
274
|
|
|
261
|
-
return res
|
|
275
|
+
return Point._assertOnCurve(res)
|
|
262
276
|
} else if (
|
|
263
277
|
(bytes[0] === 0x02 || bytes[0] === 0x03) &&
|
|
264
278
|
bytes.length - 1 === len
|
|
265
279
|
) {
|
|
266
|
-
return Point.
|
|
280
|
+
return Point._assertOnCurve(
|
|
281
|
+
Point.fromX(bytes.slice(1, 1 + len), bytes[0] === 0x03)
|
|
282
|
+
)
|
|
267
283
|
}
|
|
268
284
|
throw new Error('Unknown point format')
|
|
269
285
|
}
|
|
@@ -287,7 +303,7 @@ export default class Point extends BasePoint {
|
|
|
287
303
|
*/
|
|
288
304
|
static fromString (str: string): Point {
|
|
289
305
|
const bytes = toArray(str, 'hex')
|
|
290
|
-
return Point.fromDER(bytes)
|
|
306
|
+
return Point._assertOnCurve(Point.fromDER(bytes))
|
|
291
307
|
}
|
|
292
308
|
|
|
293
309
|
/**
|
|
@@ -308,16 +324,22 @@ export default class Point extends BasePoint {
|
|
|
308
324
|
static fromX (x: BigNumber | number | number[] | string, odd: boolean): Point {
|
|
309
325
|
let xBigInt = toBigInt(x)
|
|
310
326
|
xBigInt = biMod(xBigInt)
|
|
327
|
+
|
|
311
328
|
const y2 = biModAdd(biModMul(biModSqr(xBigInt), xBigInt), 7n)
|
|
312
329
|
const y = biModSqrt(y2)
|
|
313
|
-
if (y === null)
|
|
330
|
+
if (y === null) {
|
|
331
|
+
throw new Error('Invalid point')
|
|
332
|
+
}
|
|
333
|
+
|
|
314
334
|
let yBig = y
|
|
315
335
|
if ((yBig & BI_ONE) !== (odd ? BI_ONE : BI_ZERO)) {
|
|
316
336
|
yBig = biModSub(P_BIGINT, yBig)
|
|
317
337
|
}
|
|
338
|
+
|
|
318
339
|
const xBN = new BigNumber(xBigInt.toString(16), 16)
|
|
319
340
|
const yBN = new BigNumber(yBig.toString(16), 16)
|
|
320
|
-
|
|
341
|
+
|
|
342
|
+
return Point._assertOnCurve(new Point(xBN, yBN))
|
|
321
343
|
}
|
|
322
344
|
|
|
323
345
|
/**
|
|
@@ -339,33 +361,45 @@ export default class Point extends BasePoint {
|
|
|
339
361
|
if (typeof obj === 'string') {
|
|
340
362
|
obj = JSON.parse(obj)
|
|
341
363
|
}
|
|
342
|
-
|
|
343
|
-
|
|
364
|
+
|
|
365
|
+
let res = new Point(obj[0], obj[1], isRed)
|
|
366
|
+
res = Point._assertOnCurve(res)
|
|
367
|
+
|
|
368
|
+
if (typeof obj[2] !== 'object' || obj[2] === null) {
|
|
344
369
|
return res
|
|
345
370
|
}
|
|
346
371
|
|
|
347
|
-
const
|
|
348
|
-
|
|
372
|
+
const pre = obj[2]
|
|
373
|
+
|
|
374
|
+
const obj2point = (p): Point => {
|
|
375
|
+
const pt = new Point(p[0], p[1], isRed)
|
|
376
|
+
return Point._assertOnCurve(pt)
|
|
349
377
|
}
|
|
350
378
|
|
|
351
|
-
const pre = obj[2]
|
|
352
379
|
res.precomputed = {
|
|
353
380
|
beta: null,
|
|
381
|
+
|
|
354
382
|
doubles:
|
|
355
383
|
typeof pre.doubles === 'object' && pre.doubles !== null
|
|
356
384
|
? {
|
|
357
385
|
step: pre.doubles.step,
|
|
358
|
-
points: [res].concat(
|
|
386
|
+
points: [res].concat(
|
|
387
|
+
pre.doubles.points.map(obj2point)
|
|
388
|
+
)
|
|
359
389
|
}
|
|
360
390
|
: undefined,
|
|
391
|
+
|
|
361
392
|
naf:
|
|
362
393
|
typeof pre.naf === 'object' && pre.naf !== null
|
|
363
394
|
? {
|
|
364
395
|
wnd: pre.naf.wnd,
|
|
365
|
-
points: [res].concat(
|
|
396
|
+
points: [res].concat(
|
|
397
|
+
pre.naf.points.map(obj2point)
|
|
398
|
+
)
|
|
366
399
|
}
|
|
367
400
|
: undefined
|
|
368
401
|
}
|
|
402
|
+
|
|
369
403
|
return res
|
|
370
404
|
}
|
|
371
405
|
|
|
@@ -426,7 +460,20 @@ export default class Point extends BasePoint {
|
|
|
426
460
|
* const isValid = aPoint.validate();
|
|
427
461
|
*/
|
|
428
462
|
validate (): boolean {
|
|
429
|
-
|
|
463
|
+
if (this.inf || this.x == null || this.y == null) return false
|
|
464
|
+
|
|
465
|
+
try {
|
|
466
|
+
const xBig = BigInt('0x' + this.x.fromRed().toString(16))
|
|
467
|
+
const yBig = BigInt('0x' + this.y.fromRed().toString(16))
|
|
468
|
+
|
|
469
|
+
// compute y² and x³ + 7 using bigint-secure field ops
|
|
470
|
+
const lhs = biModMul(yBig, yBig)
|
|
471
|
+
const rhs = biModAdd(biModMul(biModMul(xBig, xBig), xBig), 7n)
|
|
472
|
+
|
|
473
|
+
return lhs === rhs
|
|
474
|
+
} catch {
|
|
475
|
+
return false
|
|
476
|
+
}
|
|
430
477
|
}
|
|
431
478
|
|
|
432
479
|
/**
|
|
@@ -41,19 +41,27 @@ export default class SymmetricKey extends BigNumber {
|
|
|
41
41
|
* const encryptedMessage = key.encrypt('plainText', 'utf8');
|
|
42
42
|
*/
|
|
43
43
|
encrypt (msg: number[] | string, enc?: 'hex'): string | number[] {
|
|
44
|
-
const iv = Random(32)
|
|
45
|
-
|
|
46
|
-
const keyBytes = this.toArray('be', 32)
|
|
47
|
-
|
|
44
|
+
const iv = new Uint8Array(Random(32))
|
|
45
|
+
const msgBytes = new Uint8Array(toArray(msg, enc))
|
|
46
|
+
const keyBytes = new Uint8Array(this.toArray('be', 32))
|
|
47
|
+
|
|
48
|
+
const { result, authenticationTag } = AESGCM(
|
|
49
|
+
msgBytes,
|
|
50
|
+
iv,
|
|
51
|
+
keyBytes
|
|
52
|
+
)
|
|
53
|
+
|
|
48
54
|
const totalLength = iv.length + result.length + authenticationTag.length
|
|
49
|
-
const combined = new
|
|
55
|
+
const combined = new Uint8Array(totalLength)
|
|
50
56
|
let offset = 0
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
|
|
58
|
+
combined.set(iv, offset)
|
|
59
|
+
offset += iv.length
|
|
60
|
+
combined.set(result, offset)
|
|
61
|
+
offset += result.length
|
|
62
|
+
combined.set(authenticationTag, offset)
|
|
63
|
+
|
|
64
|
+
return encode(Array.from(combined), enc)
|
|
57
65
|
}
|
|
58
66
|
|
|
59
67
|
/**
|
|
@@ -73,30 +81,30 @@ export default class SymmetricKey extends BigNumber {
|
|
|
73
81
|
* @throws {Error} Will throw an error if the decryption fails, likely due to message tampering or incorrect decryption key.
|
|
74
82
|
*/
|
|
75
83
|
decrypt (msg: number[] | string, enc?: 'hex' | 'utf8'): string | number[] {
|
|
76
|
-
|
|
84
|
+
const msgBytes = new Uint8Array(toArray(msg, enc))
|
|
77
85
|
|
|
78
86
|
const ivLength = 32
|
|
79
87
|
const tagLength = 16
|
|
80
88
|
|
|
81
|
-
if (
|
|
89
|
+
if (msgBytes.length < ivLength + tagLength) {
|
|
82
90
|
throw new Error('Ciphertext too short')
|
|
83
91
|
}
|
|
84
92
|
|
|
85
|
-
const iv =
|
|
86
|
-
const tagStart =
|
|
87
|
-
const ciphertext =
|
|
88
|
-
const messageTag =
|
|
93
|
+
const iv = msgBytes.slice(0, ivLength)
|
|
94
|
+
const tagStart = msgBytes.length - tagLength
|
|
95
|
+
const ciphertext = msgBytes.slice(ivLength, tagStart)
|
|
96
|
+
const messageTag = msgBytes.slice(tagStart)
|
|
89
97
|
|
|
98
|
+
const keyBytes = new Uint8Array(this.toArray('be', 32))
|
|
90
99
|
const result = AESGCMDecrypt(
|
|
91
100
|
ciphertext,
|
|
92
|
-
[],
|
|
93
101
|
iv,
|
|
94
102
|
messageTag,
|
|
95
|
-
|
|
103
|
+
keyBytes
|
|
96
104
|
)
|
|
97
105
|
if (result === null) {
|
|
98
106
|
throw new Error('Decryption failed!')
|
|
99
107
|
}
|
|
100
|
-
return encode(result, enc)
|
|
108
|
+
return encode(Array.from(result), enc)
|
|
101
109
|
}
|
|
102
110
|
}
|