@bsv/sdk 1.1.23 → 1.1.25
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/Curve.js +7 -7
- package/dist/cjs/src/primitives/Curve.js.map +1 -1
- package/dist/cjs/src/primitives/ECDSA.js +394 -71
- package/dist/cjs/src/primitives/ECDSA.js.map +1 -1
- package/dist/cjs/src/primitives/Point.js +103 -23
- package/dist/cjs/src/primitives/Point.js.map +1 -1
- package/dist/cjs/src/primitives/TransactionSignature.js +4 -3
- package/dist/cjs/src/primitives/TransactionSignature.js.map +1 -1
- package/dist/cjs/src/primitives/utils.js +14 -15
- package/dist/cjs/src/primitives/utils.js.map +1 -1
- package/dist/cjs/src/script/Spend.js +4 -4
- package/dist/cjs/src/script/Spend.js.map +1 -1
- package/dist/cjs/src/totp/totp.js +1 -1
- package/dist/cjs/src/totp/totp.js.map +1 -1
- package/dist/cjs/src/transaction/Beef.js +492 -0
- package/dist/cjs/src/transaction/Beef.js.map +1 -0
- package/dist/cjs/src/transaction/BeefParty.js +97 -0
- package/dist/cjs/src/transaction/BeefParty.js.map +1 -0
- package/dist/cjs/src/transaction/BeefTx.js +123 -0
- package/dist/cjs/src/transaction/BeefTx.js.map +1 -0
- package/dist/cjs/src/transaction/Transaction.js +81 -66
- package/dist/cjs/src/transaction/Transaction.js.map +1 -1
- package/dist/cjs/src/transaction/index.js +7 -1
- package/dist/cjs/src/transaction/index.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/primitives/Curve.js +7 -7
- package/dist/esm/src/primitives/Curve.js.map +1 -1
- package/dist/esm/src/primitives/ECDSA.js +394 -71
- package/dist/esm/src/primitives/ECDSA.js.map +1 -1
- package/dist/esm/src/primitives/Point.js +103 -23
- package/dist/esm/src/primitives/Point.js.map +1 -1
- package/dist/esm/src/primitives/TransactionSignature.js +4 -3
- package/dist/esm/src/primitives/TransactionSignature.js.map +1 -1
- package/dist/esm/src/primitives/utils.js +14 -15
- package/dist/esm/src/primitives/utils.js.map +1 -1
- package/dist/esm/src/script/Spend.js +4 -4
- package/dist/esm/src/script/Spend.js.map +1 -1
- package/dist/esm/src/totp/totp.js +1 -1
- package/dist/esm/src/totp/totp.js.map +1 -1
- package/dist/esm/src/transaction/Beef.js +485 -0
- package/dist/esm/src/transaction/Beef.js.map +1 -0
- package/dist/esm/src/transaction/BeefParty.js +93 -0
- package/dist/esm/src/transaction/BeefParty.js.map +1 -0
- package/dist/esm/src/transaction/BeefTx.js +121 -0
- package/dist/esm/src/transaction/BeefTx.js.map +1 -0
- package/dist/esm/src/transaction/Transaction.js +81 -66
- package/dist/esm/src/transaction/Transaction.js.map +1 -1
- package/dist/esm/src/transaction/index.js +3 -0
- package/dist/esm/src/transaction/index.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/primitives/ECDSA.d.ts.map +1 -1
- package/dist/types/src/primitives/Point.d.ts +5 -0
- package/dist/types/src/primitives/Point.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/transaction/Beef.d.ts +143 -0
- package/dist/types/src/transaction/Beef.d.ts.map +1 -0
- package/dist/types/src/transaction/BeefParty.d.ts +62 -0
- package/dist/types/src/transaction/BeefParty.d.ts.map +1 -0
- package/dist/types/src/transaction/BeefTx.d.ts +35 -0
- package/dist/types/src/transaction/BeefTx.d.ts.map +1 -0
- package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
- package/dist/types/src/transaction/TransactionInput.d.ts +1 -1
- package/dist/types/src/transaction/TransactionInput.d.ts.map +1 -1
- package/dist/types/src/transaction/index.d.ts +3 -0
- package/dist/types/src/transaction/index.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/docs/primitives.md +373 -55
- package/docs/transaction.md +467 -1
- package/package.json +1 -1
- package/src/primitives/Curve.ts +7 -7
- package/src/primitives/ECDSA.ts +485 -75
- package/src/primitives/Point.ts +110 -25
- package/src/primitives/TransactionSignature.ts +4 -3
- package/src/primitives/utils.ts +15 -11
- package/src/script/Spend.ts +4 -4
- package/src/totp/totp.ts +1 -1
- package/src/transaction/Beef.ts +533 -0
- package/src/transaction/BeefParty.ts +100 -0
- package/src/transaction/BeefTx.ts +121 -0
- package/src/transaction/Transaction.ts +95 -69
- package/src/transaction/TransactionInput.ts +1 -1
- package/src/transaction/__tests/Beef.test.ts +290 -0
- package/src/transaction/__tests/Transaction.benchmarks.test.ts +222 -0
- package/src/transaction/index.ts +3 -0
package/src/primitives/Point.ts
CHANGED
|
@@ -17,6 +17,10 @@ import ReductionContext from './ReductionContext.js'
|
|
|
17
17
|
* @property inf - Flag to record if the point is at infinity in the Elliptic Curve.
|
|
18
18
|
*/
|
|
19
19
|
export default class Point extends BasePoint {
|
|
20
|
+
private static readonly red: any = new ReductionContext('k256')
|
|
21
|
+
private static readonly a: BigNumber = new BigNumber(0).toRed(Point.red)
|
|
22
|
+
private static readonly b: BigNumber = new BigNumber(7).toRed(Point.red)
|
|
23
|
+
private static readonly zero: BigNumber = new BigNumber(0).toRed(Point.red)
|
|
20
24
|
x: BigNumber | null
|
|
21
25
|
y: BigNumber | null
|
|
22
26
|
inf: boolean
|
|
@@ -59,7 +63,7 @@ export default class Point extends BasePoint {
|
|
|
59
63
|
|
|
60
64
|
return res
|
|
61
65
|
} else if ((bytes[0] === 0x02 || bytes[0] === 0x03) &&
|
|
62
|
-
|
|
66
|
+
bytes.length - 1 === len) {
|
|
63
67
|
return Point.fromX(bytes.slice(1, 1 + len), bytes[0] === 0x03)
|
|
64
68
|
}
|
|
65
69
|
throw new Error('Unknown point format')
|
|
@@ -87,6 +91,13 @@ export default class Point extends BasePoint {
|
|
|
87
91
|
return Point.fromDER(bytes)
|
|
88
92
|
}
|
|
89
93
|
|
|
94
|
+
static redSqrtOptimized (y2: BigNumber): BigNumber {
|
|
95
|
+
const red = Point.red
|
|
96
|
+
const p = red.m // The modulus
|
|
97
|
+
const exponent = p.addn(1).iushrn(2) // (p + 1) / 4
|
|
98
|
+
return y2.redPow(exponent)
|
|
99
|
+
}
|
|
100
|
+
|
|
90
101
|
/**
|
|
91
102
|
* Generates a point from an x coordinate and a boolean indicating whether the corresponding
|
|
92
103
|
* y coordinate is odd.
|
|
@@ -102,34 +113,108 @@ export default class Point extends BasePoint {
|
|
|
102
113
|
* const xCoordinate = new BigNumber('10');
|
|
103
114
|
* const point = Point.fromX(xCoordinate, true);
|
|
104
115
|
*/
|
|
105
|
-
|
|
106
116
|
static fromX (x: BigNumber | number | number[] | string, odd: boolean): Point {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
117
|
+
if (typeof BigInt === 'function') {
|
|
118
|
+
function mod (a: bigint, n: bigint): bigint {
|
|
119
|
+
return ((a % n) + n) % n
|
|
120
|
+
}
|
|
121
|
+
function modPow (base: bigint, exponent: bigint, modulus: bigint): bigint {
|
|
122
|
+
let result = BigInt(1)
|
|
123
|
+
base = mod(base, modulus)
|
|
124
|
+
while (exponent > BigInt(0)) {
|
|
125
|
+
if ((exponent & BigInt(1)) === BigInt(1)) {
|
|
126
|
+
result = mod(result * base, modulus)
|
|
127
|
+
}
|
|
128
|
+
exponent >>= BigInt(1)
|
|
129
|
+
base = mod(base * base, modulus)
|
|
130
|
+
}
|
|
131
|
+
return result
|
|
132
|
+
}
|
|
133
|
+
function sqrtMod (a: bigint, p: bigint): bigint | null {
|
|
134
|
+
const exponent = (p + BigInt(1)) >> BigInt(2) // Precomputed exponent
|
|
135
|
+
const sqrtCandidate = modPow(a, exponent, p)
|
|
136
|
+
if (mod(sqrtCandidate * sqrtCandidate, p) === mod(a, p)) {
|
|
137
|
+
return sqrtCandidate
|
|
138
|
+
} else {
|
|
139
|
+
// No square root exists
|
|
140
|
+
return null
|
|
141
|
+
}
|
|
142
|
+
}
|
|
118
143
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
144
|
+
// Curve parameters for secp256k1
|
|
145
|
+
const p = BigInt(
|
|
146
|
+
'0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F'
|
|
147
|
+
)
|
|
148
|
+
const a = BigInt(0)
|
|
149
|
+
const b = BigInt(7)
|
|
150
|
+
|
|
151
|
+
// Convert x to BigInt
|
|
152
|
+
let xBigInt: bigint
|
|
153
|
+
if (x instanceof BigNumber) {
|
|
154
|
+
xBigInt = BigInt('0x' + x.toString(16))
|
|
155
|
+
} else if (typeof x === 'string') {
|
|
156
|
+
xBigInt = BigInt('0x' + x)
|
|
157
|
+
} else if (Array.isArray(x)) {
|
|
158
|
+
xBigInt = BigInt(
|
|
159
|
+
'0x' +
|
|
160
|
+
Buffer.from(x).toString('hex').padStart(64, '0')
|
|
161
|
+
)
|
|
162
|
+
} else if (typeof x === 'number') {
|
|
163
|
+
xBigInt = BigInt(x)
|
|
164
|
+
} else {
|
|
165
|
+
throw new Error('Invalid x-coordinate type')
|
|
166
|
+
}
|
|
124
167
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
const isOdd = y.fromRed().isOdd()
|
|
128
|
-
if ((odd && !isOdd) || (!odd && isOdd)) {
|
|
129
|
-
y = y.redNeg()
|
|
130
|
-
}
|
|
168
|
+
// Ensure x is within field range
|
|
169
|
+
xBigInt = mod(xBigInt, p)
|
|
131
170
|
|
|
132
|
-
|
|
171
|
+
// Compute y^2 = x^3 + a x + b mod p
|
|
172
|
+
const y2 = mod(modPow(xBigInt, BigInt(3), p) + b, p)
|
|
173
|
+
|
|
174
|
+
// Compute modular square root y = sqrt(y2) mod p
|
|
175
|
+
let y = sqrtMod(y2, p)
|
|
176
|
+
|
|
177
|
+
if (y === null) {
|
|
178
|
+
throw new Error('Invalid point')
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Adjust y to match the oddness
|
|
182
|
+
const isYOdd = (y % BigInt(2)) === BigInt(1)
|
|
183
|
+
if ((odd && !isYOdd) || (!odd && isYOdd)) {
|
|
184
|
+
y = p - y
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Convert x and y to BigNumber
|
|
188
|
+
const xBN = new BigNumber(xBigInt.toString(16), 16)
|
|
189
|
+
const yBN = new BigNumber(y.toString(16), 16)
|
|
190
|
+
return new Point(xBN, yBN)
|
|
191
|
+
} else {
|
|
192
|
+
const red = new ReductionContext('k256')
|
|
193
|
+
const a = new BigNumber(0).toRed(red)
|
|
194
|
+
const b = new BigNumber(7).toRed(red)
|
|
195
|
+
const zero = new BigNumber(0).toRed(red)
|
|
196
|
+
if (!BigNumber.isBN(x)) {
|
|
197
|
+
x = new BigNumber(x as number, 16)
|
|
198
|
+
}
|
|
199
|
+
x = x as BigNumber
|
|
200
|
+
if (x.red == null) {
|
|
201
|
+
x = x.toRed(red)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const y2 = x.redSqr().redMul(x).redIAdd(x.redMul(a)).redIAdd(b)
|
|
205
|
+
let y = y2.redSqrt()
|
|
206
|
+
if (y.redSqr().redSub(y2).cmp(zero) !== 0) {
|
|
207
|
+
throw new Error('invalid point')
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// XXX Is there any way to tell if the number is odd without converting it
|
|
211
|
+
// to non-red form?
|
|
212
|
+
const isOdd = y.fromRed().isOdd()
|
|
213
|
+
if ((odd && !isOdd) || (!odd && isOdd)) {
|
|
214
|
+
y = y.redNeg()
|
|
215
|
+
}
|
|
216
|
+
return new Point(x, y)
|
|
217
|
+
}
|
|
133
218
|
}
|
|
134
219
|
|
|
135
220
|
/**
|
|
@@ -40,7 +40,7 @@ export default class TransactionSignature extends Signature {
|
|
|
40
40
|
const writer = new Writer()
|
|
41
41
|
for (const input of inputs) {
|
|
42
42
|
if (typeof input.sourceTXID === 'undefined') {
|
|
43
|
-
writer.
|
|
43
|
+
writer.write(input.sourceTransaction.hash() as number[])
|
|
44
44
|
} else {
|
|
45
45
|
writer.writeReverse(toArray(input.sourceTXID, 'hex'))
|
|
46
46
|
}
|
|
@@ -122,8 +122,9 @@ export default class TransactionSignature extends Signature {
|
|
|
122
122
|
writer.writeUInt32LE(params.sourceOutputIndex)
|
|
123
123
|
|
|
124
124
|
// scriptCode of the input (serialized as scripts inside CTxOuts)
|
|
125
|
-
|
|
126
|
-
writer.
|
|
125
|
+
const subscriptBin = params.subscript.toBinary()
|
|
126
|
+
writer.writeVarIntNum(subscriptBin.length)
|
|
127
|
+
writer.write(subscriptBin)
|
|
127
128
|
|
|
128
129
|
// value of the output spent by this input (8-byte little endian)
|
|
129
130
|
writer.writeUInt64LE(params.sourceSatoshis)
|
package/src/primitives/utils.ts
CHANGED
|
@@ -320,9 +320,13 @@ export class Writer {
|
|
|
320
320
|
}
|
|
321
321
|
|
|
322
322
|
toArray (): number[] {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
323
|
+
const totalLength = this.getLength()
|
|
324
|
+
const ret = new Array(totalLength)
|
|
325
|
+
let offset = 0
|
|
326
|
+
for (const buf of this.bufs) {
|
|
327
|
+
for (let i = 0; i < buf.length; i++) {
|
|
328
|
+
ret[offset++] = buf[i]
|
|
329
|
+
}
|
|
326
330
|
}
|
|
327
331
|
return ret
|
|
328
332
|
}
|
|
@@ -515,18 +519,18 @@ export class Reader {
|
|
|
515
519
|
}
|
|
516
520
|
|
|
517
521
|
public read (len = this.bin.length): number[] {
|
|
518
|
-
const
|
|
519
|
-
|
|
520
|
-
|
|
522
|
+
const start = this.pos
|
|
523
|
+
const end = this.pos + len
|
|
524
|
+
this.pos = end
|
|
525
|
+
return this.bin.slice(start, end)
|
|
521
526
|
}
|
|
522
527
|
|
|
523
528
|
public readReverse (len = this.bin.length): number[] {
|
|
524
|
-
const
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
for (let i = 0; i < buf2.length; i++) {
|
|
528
|
-
buf2[i] = bin[bin.length - 1 - i]
|
|
529
|
+
const buf2 = new Array(len)
|
|
530
|
+
for (let i = 0; i < len; i++) {
|
|
531
|
+
buf2[i] = this.bin[this.pos + len - 1 - i]
|
|
529
532
|
}
|
|
533
|
+
this.pos += len
|
|
530
534
|
return buf2
|
|
531
535
|
}
|
|
532
536
|
|
package/src/script/Spend.ts
CHANGED
|
@@ -207,9 +207,9 @@ export default class Spend {
|
|
|
207
207
|
}
|
|
208
208
|
|
|
209
209
|
const padDataToSize = (buf: number[], len: number): number[] => {
|
|
210
|
-
|
|
210
|
+
const b = buf
|
|
211
211
|
while (b.length < len) {
|
|
212
|
-
b
|
|
212
|
+
b.unshift(0)
|
|
213
213
|
}
|
|
214
214
|
return b
|
|
215
215
|
}
|
|
@@ -785,7 +785,7 @@ export default class Spend {
|
|
|
785
785
|
shifted = bn1.ushrn(n)
|
|
786
786
|
}
|
|
787
787
|
const bufShifted = padDataToSize(
|
|
788
|
-
|
|
788
|
+
shifted.toArray().slice(buf1.length * -1),
|
|
789
789
|
buf1.length
|
|
790
790
|
)
|
|
791
791
|
this.stack.push(bufShifted)
|
|
@@ -1016,7 +1016,7 @@ export default class Spend {
|
|
|
1016
1016
|
|
|
1017
1017
|
try {
|
|
1018
1018
|
sig = TransactionSignature.fromChecksigFormat(bufSig)
|
|
1019
|
-
pubkey = PublicKey.
|
|
1019
|
+
pubkey = PublicKey.fromDER(bufPubkey)
|
|
1020
1020
|
fSuccess = verifySignature(sig, pubkey, subscript)
|
|
1021
1021
|
} catch (e) {
|
|
1022
1022
|
// invalid sig or pubkey
|
package/src/totp/totp.ts
CHANGED
|
@@ -106,7 +106,7 @@ function generateHOTP (
|
|
|
106
106
|
options: Required<TOTPOptions>
|
|
107
107
|
): string {
|
|
108
108
|
const timePad = new BigNumber(counter).toArray('be', 8)
|
|
109
|
-
console.log({ timePad })
|
|
109
|
+
//console.log({ timePad })
|
|
110
110
|
const hmac = calcHMAC(secret, timePad, options.algorithm)
|
|
111
111
|
const signature = hmac.digest()
|
|
112
112
|
|