@bsv/sdk 1.1.29 → 1.1.32
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/Schnorr.js +92 -0
- package/dist/cjs/src/primitives/Schnorr.js.map +1 -0
- package/dist/cjs/src/primitives/index.js +3 -1
- package/dist/cjs/src/primitives/index.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 +292 -155
- package/dist/cjs/src/transaction/Beef.js.map +1 -1
- package/dist/cjs/src/transaction/BeefParty.js +46 -26
- package/dist/cjs/src/transaction/BeefParty.js.map +1 -1
- package/dist/cjs/src/transaction/BeefTx.js +31 -16
- package/dist/cjs/src/transaction/BeefTx.js.map +1 -1
- package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
- package/dist/cjs/src/transaction/Transaction.js +12 -6
- package/dist/cjs/src/transaction/Transaction.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/primitives/Schnorr.js +87 -0
- package/dist/esm/src/primitives/Schnorr.js.map +1 -0
- package/dist/esm/src/primitives/index.js +1 -0
- package/dist/esm/src/primitives/index.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 +294 -157
- package/dist/esm/src/transaction/Beef.js.map +1 -1
- package/dist/esm/src/transaction/BeefParty.js +47 -27
- package/dist/esm/src/transaction/BeefParty.js.map +1 -1
- package/dist/esm/src/transaction/BeefTx.js +35 -20
- package/dist/esm/src/transaction/BeefTx.js.map +1 -1
- package/dist/esm/src/transaction/MerklePath.js.map +1 -1
- package/dist/esm/src/transaction/Transaction.js +12 -6
- package/dist/esm/src/transaction/Transaction.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/primitives/Schnorr.d.ts +65 -0
- package/dist/types/src/primitives/Schnorr.d.ts.map +1 -0
- package/dist/types/src/primitives/index.d.ts +1 -0
- package/dist/types/src/primitives/index.d.ts.map +1 -1
- package/dist/types/src/transaction/Beef.d.ts +131 -90
- package/dist/types/src/transaction/Beef.d.ts.map +1 -1
- package/dist/types/src/transaction/BeefParty.d.ts +34 -23
- package/dist/types/src/transaction/BeefParty.d.ts.map +1 -1
- package/dist/types/src/transaction/BeefTx.d.ts +11 -6
- package/dist/types/src/transaction/BeefTx.d.ts.map +1 -1
- package/dist/types/src/transaction/MerklePath.d.ts.map +1 -1
- package/dist/types/src/transaction/Transaction.d.ts +8 -2
- package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +1 -1
- package/docs/primitives.md +120 -9
- package/docs/transaction.md +141 -9
- package/package.json +1 -1
- package/src/primitives/Schnorr.ts +95 -0
- package/src/primitives/__tests/Schnorr.test.ts +272 -0
- package/src/primitives/index.ts +1 -0
- package/src/totp/totp.ts +1 -1
- package/src/transaction/Beef.ts +493 -378
- package/src/transaction/BeefParty.ts +71 -58
- package/src/transaction/BeefTx.ts +133 -143
- package/src/transaction/MerklePath.ts +11 -11
- package/src/transaction/Transaction.ts +42 -36
- package/src/transaction/__tests/Beef.test.ts +55 -10
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import Schnorr from '../../../dist/cjs/src/primitives/Schnorr.js'
|
|
2
|
+
import BigNumber from '../../../dist/cjs/src/primitives/BigNumber.js'
|
|
3
|
+
import Curve from '../../../dist/cjs/src/primitives/Curve.js'
|
|
4
|
+
import PrivateKey from '../../../dist/cjs/src/primitives/PrivateKey.js'
|
|
5
|
+
|
|
6
|
+
describe('Schnorr Zero-Knowledge Proof', () => {
|
|
7
|
+
let schnorr: Schnorr
|
|
8
|
+
let curve: Curve
|
|
9
|
+
|
|
10
|
+
beforeAll(() => {
|
|
11
|
+
schnorr = new Schnorr()
|
|
12
|
+
curve = new Curve()
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it('should verify a valid proof', () => {
|
|
16
|
+
// Generate private keys
|
|
17
|
+
const a = PrivateKey.fromRandom()
|
|
18
|
+
const b = PrivateKey.fromRandom()
|
|
19
|
+
|
|
20
|
+
// Compute public keys
|
|
21
|
+
const A = a.toPublicKey()
|
|
22
|
+
const B = b.toPublicKey()
|
|
23
|
+
|
|
24
|
+
// Compute shared secret S = B * a
|
|
25
|
+
const S = B.mul(a)
|
|
26
|
+
|
|
27
|
+
// Generate proof
|
|
28
|
+
const proof = schnorr.generateProof(a, A, B, S)
|
|
29
|
+
|
|
30
|
+
// Verify proof
|
|
31
|
+
const result = schnorr.verifyProof(A, B, S, proof)
|
|
32
|
+
expect(result).toBe(true)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('should fail verification if proof is tampered (R modified)', () => {
|
|
36
|
+
// Generate private keys
|
|
37
|
+
const a = PrivateKey.fromRandom()
|
|
38
|
+
const b = PrivateKey.fromRandom()
|
|
39
|
+
|
|
40
|
+
// Compute public keys
|
|
41
|
+
const A = a.toPublicKey()
|
|
42
|
+
const B = b.toPublicKey()
|
|
43
|
+
|
|
44
|
+
// Compute shared secret S = B * a
|
|
45
|
+
const S = B.mul(a)
|
|
46
|
+
|
|
47
|
+
// Generate proof
|
|
48
|
+
const proof = schnorr.generateProof(a, A, B, S)
|
|
49
|
+
|
|
50
|
+
// Tamper with R
|
|
51
|
+
const tamperedR = proof.R.add(curve.g)
|
|
52
|
+
const tamperedProof = { ...proof, R: tamperedR }
|
|
53
|
+
|
|
54
|
+
// Verify proof
|
|
55
|
+
const result = schnorr.verifyProof(A, B, S, tamperedProof)
|
|
56
|
+
expect(result).toBe(false)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('should fail verification if proof is tampered (z modified)', () => {
|
|
60
|
+
// Generate private keys
|
|
61
|
+
const a = PrivateKey.fromRandom()
|
|
62
|
+
const b = PrivateKey.fromRandom()
|
|
63
|
+
|
|
64
|
+
// Compute public keys
|
|
65
|
+
const A = a.toPublicKey()
|
|
66
|
+
const B = b.toPublicKey()
|
|
67
|
+
|
|
68
|
+
// Compute shared secret S = B * a
|
|
69
|
+
const S = B.mul(a)
|
|
70
|
+
|
|
71
|
+
// Generate proof
|
|
72
|
+
const proof = schnorr.generateProof(a, A, B, S)
|
|
73
|
+
|
|
74
|
+
// Tamper with z
|
|
75
|
+
const tamperedZ = proof.z.add(new BigNumber(1)).umod(curve.n)
|
|
76
|
+
const tamperedProof = { ...proof, z: tamperedZ }
|
|
77
|
+
|
|
78
|
+
// Verify proof
|
|
79
|
+
const result = schnorr.verifyProof(A, B, S, tamperedProof)
|
|
80
|
+
expect(result).toBe(false)
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
it('should fail verification if proof is tampered (S\' modified)', () => {
|
|
84
|
+
// Generate private keys
|
|
85
|
+
const a = PrivateKey.fromRandom()
|
|
86
|
+
const b = PrivateKey.fromRandom()
|
|
87
|
+
|
|
88
|
+
// Compute public keys
|
|
89
|
+
const A = a.toPublicKey()
|
|
90
|
+
const B = b.toPublicKey()
|
|
91
|
+
|
|
92
|
+
// Compute shared secret S = B * a
|
|
93
|
+
const S = B.mul(a)
|
|
94
|
+
|
|
95
|
+
// Generate proof
|
|
96
|
+
const proof = schnorr.generateProof(a, A, B, S)
|
|
97
|
+
|
|
98
|
+
// Tamper with S'
|
|
99
|
+
const tamperedSPrime = proof.SPrime.add(curve.g)
|
|
100
|
+
const tamperedProof = { ...proof, SPrime: tamperedSPrime }
|
|
101
|
+
|
|
102
|
+
// Verify proof
|
|
103
|
+
const result = schnorr.verifyProof(A, B, S, tamperedProof)
|
|
104
|
+
expect(result).toBe(false)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('should fail verification if inputs are tampered (A modified)', () => {
|
|
108
|
+
// Generate private keys
|
|
109
|
+
const a = PrivateKey.fromRandom()
|
|
110
|
+
const b = PrivateKey.fromRandom()
|
|
111
|
+
|
|
112
|
+
// Compute public keys
|
|
113
|
+
const A = a.toPublicKey()
|
|
114
|
+
const B = b.toPublicKey()
|
|
115
|
+
|
|
116
|
+
// Compute shared secret S = B * a
|
|
117
|
+
const S = B.mul(a)
|
|
118
|
+
|
|
119
|
+
// Generate proof
|
|
120
|
+
const proof = schnorr.generateProof(a, A, B, S)
|
|
121
|
+
|
|
122
|
+
// Tamper with A
|
|
123
|
+
const tamperedA = A.add(curve.g)
|
|
124
|
+
|
|
125
|
+
// Verify proof
|
|
126
|
+
const result = schnorr.verifyProof(tamperedA, B, S, proof)
|
|
127
|
+
expect(result).toBe(false)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('should fail verification if inputs are tampered (B modified)', () => {
|
|
131
|
+
// Generate private keys
|
|
132
|
+
const a = PrivateKey.fromRandom()
|
|
133
|
+
const b = PrivateKey.fromRandom()
|
|
134
|
+
|
|
135
|
+
// Compute public keys
|
|
136
|
+
const A = a.toPublicKey()
|
|
137
|
+
const B = b.toPublicKey()
|
|
138
|
+
|
|
139
|
+
// Compute shared secret S = B * a
|
|
140
|
+
const S = B.mul(a)
|
|
141
|
+
|
|
142
|
+
// Generate proof
|
|
143
|
+
const proof = schnorr.generateProof(a, A, B, S)
|
|
144
|
+
|
|
145
|
+
// Tamper with B
|
|
146
|
+
const tamperedB = B.add(curve.g)
|
|
147
|
+
|
|
148
|
+
// Verify proof
|
|
149
|
+
const result = schnorr.verifyProof(A, tamperedB, S, proof)
|
|
150
|
+
expect(result).toBe(false)
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
it('should fail verification if inputs are tampered (S modified)', () => {
|
|
154
|
+
// Generate private keys
|
|
155
|
+
const a = PrivateKey.fromRandom()
|
|
156
|
+
const b = PrivateKey.fromRandom()
|
|
157
|
+
|
|
158
|
+
// Compute public keys
|
|
159
|
+
const A = a.toPublicKey()
|
|
160
|
+
const B = b.toPublicKey()
|
|
161
|
+
|
|
162
|
+
// Compute shared secret S = B * a
|
|
163
|
+
const S = B.mul(a)
|
|
164
|
+
|
|
165
|
+
// Generate proof
|
|
166
|
+
const proof = schnorr.generateProof(a, A, B, S)
|
|
167
|
+
|
|
168
|
+
// Tamper with S
|
|
169
|
+
const tamperedS = S.add(curve.g)
|
|
170
|
+
|
|
171
|
+
// Verify proof
|
|
172
|
+
const result = schnorr.verifyProof(A, B, tamperedS, proof)
|
|
173
|
+
expect(result).toBe(false)
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
it('should fail verification if using wrong private key', () => {
|
|
177
|
+
// Generate private keys
|
|
178
|
+
const a = PrivateKey.fromRandom()
|
|
179
|
+
const wrongA = PrivateKey.fromRandom()
|
|
180
|
+
const b = PrivateKey.fromRandom()
|
|
181
|
+
|
|
182
|
+
// Compute public keys
|
|
183
|
+
const A = a.toPublicKey()
|
|
184
|
+
const B = b.toPublicKey()
|
|
185
|
+
|
|
186
|
+
// Compute shared secret S = B * a
|
|
187
|
+
const S = B.mul(a)
|
|
188
|
+
|
|
189
|
+
// Generate proof using wrong private key
|
|
190
|
+
const proof = schnorr.generateProof(wrongA, A, B, S)
|
|
191
|
+
|
|
192
|
+
// Verify proof
|
|
193
|
+
const result = schnorr.verifyProof(A, B, S, proof)
|
|
194
|
+
expect(result).toBe(false)
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
it('should fail verification if using wrong public key', () => {
|
|
198
|
+
// Generate private keys
|
|
199
|
+
const a = PrivateKey.fromRandom()
|
|
200
|
+
const b = PrivateKey.fromRandom()
|
|
201
|
+
const wrongB = PrivateKey.fromRandom()
|
|
202
|
+
|
|
203
|
+
// Compute public keys
|
|
204
|
+
const A = a.toPublicKey()
|
|
205
|
+
const B = b.toPublicKey()
|
|
206
|
+
const wrongBPublic = wrongB.toPublicKey()
|
|
207
|
+
|
|
208
|
+
// Compute shared secret S = B * a
|
|
209
|
+
const S = B.mul(a)
|
|
210
|
+
|
|
211
|
+
// Generate proof
|
|
212
|
+
const proof = schnorr.generateProof(a, A, B, S)
|
|
213
|
+
|
|
214
|
+
// Verify proof with wrong B
|
|
215
|
+
const result = schnorr.verifyProof(A, wrongBPublic, S, proof)
|
|
216
|
+
expect(result).toBe(false)
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
it('should fail verification if shared secret S is incorrect', () => {
|
|
220
|
+
// Generate private keys
|
|
221
|
+
const a = PrivateKey.fromRandom()
|
|
222
|
+
const b = PrivateKey.fromRandom()
|
|
223
|
+
|
|
224
|
+
// Compute public keys
|
|
225
|
+
const A = a.toPublicKey()
|
|
226
|
+
const B = b.toPublicKey()
|
|
227
|
+
|
|
228
|
+
// Intentionally compute incorrect shared secret
|
|
229
|
+
const S = B.mul(a).add(curve.g)
|
|
230
|
+
|
|
231
|
+
// Generate proof with correct S
|
|
232
|
+
const proof = schnorr.generateProof(a, A, B, B.mul(a))
|
|
233
|
+
|
|
234
|
+
// Verify proof with incorrect S
|
|
235
|
+
const result = schnorr.verifyProof(A, B, S, proof)
|
|
236
|
+
expect(result).toBe(false)
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
it('should verify a valid proof with fixed keys', () => {
|
|
240
|
+
// Use fixed private keys for determinism
|
|
241
|
+
const a = new PrivateKey(new BigNumber('123456789abcdef123456789abcdef123456789abcdef123456789abcdef', 16))
|
|
242
|
+
const b = new PrivateKey(new BigNumber('abcdef123456789abcdef123456789abcdef123456789abcdef123456789', 16))
|
|
243
|
+
|
|
244
|
+
// Compute public keys
|
|
245
|
+
const A = a.toPublicKey()
|
|
246
|
+
const B = b.toPublicKey()
|
|
247
|
+
|
|
248
|
+
// Compute shared secret S = B * a
|
|
249
|
+
const S = B.mul(a)
|
|
250
|
+
|
|
251
|
+
// Generate proof
|
|
252
|
+
const proof = schnorr.generateProof(a, A, B, S)
|
|
253
|
+
|
|
254
|
+
// Verify proof
|
|
255
|
+
const result = schnorr.verifyProof(A, B, S, proof)
|
|
256
|
+
expect(result).toBe(true)
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
it('should throw an error if inputs are invalid', () => {
|
|
260
|
+
const a = PrivateKey.fromRandom()
|
|
261
|
+
const b = PrivateKey.fromRandom()
|
|
262
|
+
const A = a.toPublicKey()
|
|
263
|
+
const B = b.toPublicKey()
|
|
264
|
+
const S = B.mul(a)
|
|
265
|
+
const proof = schnorr.generateProof(a, A, B, S)
|
|
266
|
+
|
|
267
|
+
expect(() => schnorr.verifyProof(null as any, B, S, proof)).toThrow()
|
|
268
|
+
expect(() => schnorr.verifyProof(A, null as any, S, proof)).toThrow()
|
|
269
|
+
expect(() => schnorr.verifyProof(A, B, null as any, proof)).toThrow()
|
|
270
|
+
expect(() => schnorr.verifyProof(A, B, S, null as any)).toThrow()
|
|
271
|
+
})
|
|
272
|
+
})
|
package/src/primitives/index.ts
CHANGED
|
@@ -11,3 +11,4 @@ export * as Hash from './Hash.js'
|
|
|
11
11
|
export { default as Random } from './Random.js'
|
|
12
12
|
export { default as TransactionSignature } from './TransactionSignature.js'
|
|
13
13
|
export { default as Polynomial, PointInFiniteField } from './Polynomial.js'
|
|
14
|
+
export { default as Schnorr } from './Schnorr.js'
|
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
|
|