@bsv/sdk 1.9.22 → 1.9.23
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/JacobianPoint.js +15 -1
- package/dist/cjs/src/primitives/JacobianPoint.js.map +1 -1
- package/dist/cjs/src/primitives/Point.js +5 -0
- package/dist/cjs/src/primitives/Point.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/primitives/JacobianPoint.js +15 -1
- package/dist/esm/src/primitives/JacobianPoint.js.map +1 -1
- package/dist/esm/src/primitives/Point.js +5 -0
- package/dist/esm/src/primitives/Point.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/primitives/JacobianPoint.d.ts.map +1 -1
- package/dist/types/src/primitives/Point.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +1 -1
- package/dist/umd/bundle.js.map +1 -1
- package/package.json +1 -1
- package/src/primitives/JacobianPoint.ts +18 -1
- package/src/primitives/Point.ts +4 -0
- package/src/primitives/__tests/Curve.unit.test.ts +63 -0
- package/src/primitives/__tests/utils.test.ts +17 -0
package/package.json
CHANGED
|
@@ -73,6 +73,14 @@ export default class JacobianPoint extends BasePoint {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
this.zOne = this.z === this.curve.one
|
|
76
|
+
|
|
77
|
+
// --- Canonicalize point at infinity ---
|
|
78
|
+
if (this.isInfinity()) {
|
|
79
|
+
this.x = this.curve.one
|
|
80
|
+
this.y = this.curve.one
|
|
81
|
+
this.z = new BigNumber(0).toRed(this.curve.red)
|
|
82
|
+
this.zOne = false
|
|
83
|
+
}
|
|
76
84
|
}
|
|
77
85
|
|
|
78
86
|
/**
|
|
@@ -361,9 +369,18 @@ export default class JacobianPoint extends BasePoint {
|
|
|
361
369
|
return true
|
|
362
370
|
}
|
|
363
371
|
|
|
372
|
+
p = p as JacobianPoint
|
|
373
|
+
|
|
374
|
+
// --- Infinity handling ---
|
|
375
|
+
if (this.isInfinity() && p.isInfinity()) {
|
|
376
|
+
return true
|
|
377
|
+
}
|
|
378
|
+
if (this.isInfinity() !== p.isInfinity()) {
|
|
379
|
+
return false
|
|
380
|
+
}
|
|
381
|
+
|
|
364
382
|
// x1 * z2^2 == x2 * z1^2
|
|
365
383
|
const z2 = this.z.redSqr()
|
|
366
|
-
p = p as JacobianPoint
|
|
367
384
|
const pz2 = p.z.redSqr()
|
|
368
385
|
if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0) {
|
|
369
386
|
return false
|
package/src/primitives/Point.ts
CHANGED
|
@@ -445,6 +445,10 @@ export default class Point extends BasePoint {
|
|
|
445
445
|
* const encodedPointHex = aPoint.encode(true, 'hex');
|
|
446
446
|
*/
|
|
447
447
|
encode (compact: boolean = true, enc?: 'hex'): number[] | string {
|
|
448
|
+
if (this.inf) {
|
|
449
|
+
if (enc === 'hex') return '00'
|
|
450
|
+
return [0x00]
|
|
451
|
+
}
|
|
448
452
|
const len = this.curve.p.byteLength()
|
|
449
453
|
const x = this.getX().toArray('be', len)
|
|
450
454
|
let res: number[]
|
|
@@ -212,3 +212,66 @@ describe('Point codec', () => {
|
|
|
212
212
|
makeShortTest(shortPointOddY)
|
|
213
213
|
)
|
|
214
214
|
})
|
|
215
|
+
|
|
216
|
+
describe('JacobianPoint – Infinity handling and equality (TOB-18)', () => {
|
|
217
|
+
function J(x: any, y: any, z: any) {
|
|
218
|
+
return new JPoint(x, y, z)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
it('Multiple infinity representations are canonicalized and equal', () => {
|
|
222
|
+
const inf1 = J(null, null, null)
|
|
223
|
+
const inf2 = J('0', '0', '0')
|
|
224
|
+
const inf3 = J(new BigNumber(0), new BigNumber(0), new BigNumber(0))
|
|
225
|
+
|
|
226
|
+
expect(inf1.isInfinity()).toBe(true)
|
|
227
|
+
expect(inf2.isInfinity()).toBe(true)
|
|
228
|
+
expect(inf3.isInfinity()).toBe(true)
|
|
229
|
+
|
|
230
|
+
expect(inf1.eq(inf2)).toBe(true)
|
|
231
|
+
expect(inf2.eq(inf3)).toBe(true)
|
|
232
|
+
expect(inf1.eq(inf3)).toBe(true)
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
it('Infinity must not equal a finite point', () => {
|
|
236
|
+
const inf = J(null, null, null)
|
|
237
|
+
|
|
238
|
+
const good = J(
|
|
239
|
+
new BigNumber('e7789226', 16),
|
|
240
|
+
new BigNumber('4b76b191', 16),
|
|
241
|
+
new BigNumber('cbf8d990', 16)
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
expect(inf.eq(good)).toBe(false)
|
|
245
|
+
expect(good.eq(inf)).toBe(false)
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
it('Infinity equals infinity (canonicalized)', () => {
|
|
249
|
+
const inf1 = J(null, null, null)
|
|
250
|
+
const inf2 = J('0', '0', '0')
|
|
251
|
+
|
|
252
|
+
expect(inf1.eq(inf2)).toBe(true)
|
|
253
|
+
expect(inf2.eq(inf1)).toBe(true)
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
it('Infinity is detected when z is zero in RED form', () => {
|
|
257
|
+
const redZero = new BigNumber(0).toRed(new Curve().red)
|
|
258
|
+
const p = J('1', '2', redZero)
|
|
259
|
+
|
|
260
|
+
expect(p.isInfinity()).toBe(true)
|
|
261
|
+
|
|
262
|
+
const clean = J(null, null, null)
|
|
263
|
+
expect(p.eq(clean)).toBe(true)
|
|
264
|
+
expect(clean.eq(p)).toBe(true)
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
it('eq() must handle mixed canonical and non-canonical infinity cases', () => {
|
|
268
|
+
const canonical = J(null, null, null)
|
|
269
|
+
const messy = J('1', '1', new BigNumber(0))
|
|
270
|
+
|
|
271
|
+
expect(messy.isInfinity()).toBe(true)
|
|
272
|
+
expect(canonical.eq(messy)).toBe(true)
|
|
273
|
+
expect(messy.eq(canonical)).toBe(true)
|
|
274
|
+
})
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
toBase58Check,
|
|
12
12
|
verifyNotNull
|
|
13
13
|
} from '../../primitives/utils'
|
|
14
|
+
import Point from '../../primitives/Point'
|
|
14
15
|
|
|
15
16
|
describe('utils', () => {
|
|
16
17
|
it('should convert to array', () => {
|
|
@@ -359,3 +360,19 @@ describe('toUTF8 strict UTF-8 decoding (TOB-21)', () => {
|
|
|
359
360
|
|
|
360
361
|
})
|
|
361
362
|
|
|
363
|
+
describe('Point.encode infinity handling', () => {
|
|
364
|
+
it('encodes infinity as 00 (array)', () => {
|
|
365
|
+
const p = new Point(null, null)
|
|
366
|
+
expect(p.encode()).toEqual([0x00])
|
|
367
|
+
})
|
|
368
|
+
|
|
369
|
+
it('encodes infinity as 00 (hex)', () => {
|
|
370
|
+
const p = new Point(null, null)
|
|
371
|
+
expect(p.encode(true, 'hex')).toBe('00')
|
|
372
|
+
})
|
|
373
|
+
|
|
374
|
+
it('does not throw for infinity', () => {
|
|
375
|
+
const p = new Point(null, null)
|
|
376
|
+
expect(() => p.encode()).not.toThrow()
|
|
377
|
+
})
|
|
378
|
+
})
|