@bsv/sdk 1.9.2 → 1.9.4

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.
Files changed (93) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/kvstore/GlobalKVStore.js +116 -98
  3. package/dist/cjs/src/kvstore/GlobalKVStore.js.map +1 -1
  4. package/dist/cjs/src/kvstore/types.js.map +1 -1
  5. package/dist/cjs/src/overlay-tools/index.js +1 -0
  6. package/dist/cjs/src/overlay-tools/index.js.map +1 -1
  7. package/dist/cjs/src/overlay-tools/withDoubleSpendRetry.js +55 -0
  8. package/dist/cjs/src/overlay-tools/withDoubleSpendRetry.js.map +1 -0
  9. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  10. package/dist/esm/src/kvstore/GlobalKVStore.js +117 -99
  11. package/dist/esm/src/kvstore/GlobalKVStore.js.map +1 -1
  12. package/dist/esm/src/kvstore/types.js.map +1 -1
  13. package/dist/esm/src/overlay-tools/index.js +1 -0
  14. package/dist/esm/src/overlay-tools/index.js.map +1 -1
  15. package/dist/esm/src/overlay-tools/withDoubleSpendRetry.js +48 -0
  16. package/dist/esm/src/overlay-tools/withDoubleSpendRetry.js.map +1 -0
  17. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  18. package/dist/types/src/kvstore/GlobalKVStore.d.ts.map +1 -1
  19. package/dist/types/src/kvstore/types.d.ts +2 -0
  20. package/dist/types/src/kvstore/types.d.ts.map +1 -1
  21. package/dist/types/src/overlay-tools/index.d.ts +1 -0
  22. package/dist/types/src/overlay-tools/index.d.ts.map +1 -1
  23. package/dist/types/src/overlay-tools/withDoubleSpendRetry.d.ts +14 -0
  24. package/dist/types/src/overlay-tools/withDoubleSpendRetry.d.ts.map +1 -0
  25. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  26. package/dist/umd/bundle.js +2 -2
  27. package/dist/umd/bundle.js.map +1 -1
  28. package/docs/fast-docs.png +0 -0
  29. package/docs/index.md +49 -44
  30. package/docs/reference/kvstore.md +9 -0
  31. package/docs/reference/overlay-tools.md +32 -0
  32. package/docs/swagger.png +0 -0
  33. package/package.json +1 -1
  34. package/src/kvstore/GlobalKVStore.ts +134 -114
  35. package/src/kvstore/__tests/GlobalKVStore.test.ts +11 -1
  36. package/src/kvstore/types.ts +2 -0
  37. package/src/overlay-tools/index.ts +1 -0
  38. package/src/overlay-tools/withDoubleSpendRetry.ts +71 -0
  39. package/docs/MARKDOWN_VALIDATION_GUIDE.md +0 -175
  40. package/docs/concepts/beef.md +0 -92
  41. package/docs/concepts/chain-tracking.md +0 -134
  42. package/docs/concepts/decentralized-identity.md +0 -221
  43. package/docs/concepts/fees.md +0 -249
  44. package/docs/concepts/identity-certificates.md +0 -307
  45. package/docs/concepts/index.md +0 -77
  46. package/docs/concepts/key-management.md +0 -185
  47. package/docs/concepts/script-templates.md +0 -176
  48. package/docs/concepts/sdk-philosophy.md +0 -80
  49. package/docs/concepts/signatures.md +0 -194
  50. package/docs/concepts/spv-verification.md +0 -118
  51. package/docs/concepts/transaction-encoding.md +0 -167
  52. package/docs/concepts/transaction-structure.md +0 -67
  53. package/docs/concepts/trust-model.md +0 -139
  54. package/docs/concepts/verification.md +0 -250
  55. package/docs/concepts/wallet-integration.md +0 -101
  56. package/docs/guides/development-wallet-setup.md +0 -374
  57. package/docs/guides/direct-transaction-creation.md +0 -147
  58. package/docs/guides/http-client-configuration.md +0 -488
  59. package/docs/guides/index.md +0 -138
  60. package/docs/guides/large-transactions.md +0 -448
  61. package/docs/guides/multisig-transactions.md +0 -792
  62. package/docs/guides/security-best-practices.md +0 -494
  63. package/docs/guides/transaction-batching.md +0 -132
  64. package/docs/guides/transaction-signing-methods.md +0 -419
  65. package/docs/reference/arc-config.md +0 -698
  66. package/docs/reference/brc-100.md +0 -33
  67. package/docs/reference/configuration.md +0 -835
  68. package/docs/reference/debugging.md +0 -705
  69. package/docs/reference/errors.md +0 -597
  70. package/docs/reference/index.md +0 -111
  71. package/docs/reference/network-config.md +0 -914
  72. package/docs/reference/op-codes.md +0 -325
  73. package/docs/reference/transaction-signatures.md +0 -95
  74. package/docs/tutorials/advanced-transaction.md +0 -572
  75. package/docs/tutorials/aes-encryption.md +0 -949
  76. package/docs/tutorials/authfetch-tutorial.md +0 -986
  77. package/docs/tutorials/ecdh-key-exchange.md +0 -549
  78. package/docs/tutorials/elliptic-curve-fundamentals.md +0 -606
  79. package/docs/tutorials/error-handling.md +0 -1216
  80. package/docs/tutorials/first-transaction-low-level.md +0 -205
  81. package/docs/tutorials/first-transaction.md +0 -275
  82. package/docs/tutorials/hashes-and-hmacs.md +0 -788
  83. package/docs/tutorials/identity-management.md +0 -729
  84. package/docs/tutorials/index.md +0 -219
  85. package/docs/tutorials/key-management.md +0 -538
  86. package/docs/tutorials/protowallet-development.md +0 -743
  87. package/docs/tutorials/script-construction.md +0 -690
  88. package/docs/tutorials/spv-merkle-proofs.md +0 -685
  89. package/docs/tutorials/testnet-transactions-low-level.md +0 -359
  90. package/docs/tutorials/transaction-broadcasting.md +0 -538
  91. package/docs/tutorials/transaction-types.md +0 -420
  92. package/docs/tutorials/type-42.md +0 -568
  93. package/docs/tutorials/uhrp-storage.md +0 -599
@@ -1,549 +0,0 @@
1
- # ECDH Key Exchange
2
-
3
- **Duration**: 75 minutes
4
- **Prerequisites**: Basic TypeScript knowledge, [Elliptic Curve Fundamentals](./elliptic-curve-fundamentals.md) tutorial completed
5
-
6
- ## Learning Goals
7
-
8
- - Understand Elliptic Curve Diffie-Hellman (ECDH) key exchange principles
9
- - Implement secure key exchange using the BSV TypeScript SDK
10
- - Create shared secrets for encrypted communication
11
- - Apply ECDH in practical Bitcoin applications
12
- - Understand security considerations and best practices
13
-
14
- ## Introduction to ECDH
15
-
16
- Elliptic Curve Diffie-Hellman (ECDH) is a key agreement protocol that allows two parties to establish a shared secret over an unsecured communication channel. Unlike traditional encryption where you need to share a secret key beforehand, ECDH allows two parties who have never met to create a shared secret that only they know.
17
-
18
- The mathematical foundation of ECDH relies on the commutative property of elliptic curve point multiplication:
19
-
20
- - Alice computes: `(Alice's private key) × (Bob's public key)`
21
- - Bob computes: `(Bob's private key) × (Alice's public key)`
22
- - Both arrive at the same shared secret point
23
-
24
- ## Setting Up Your Environment
25
-
26
- ```typescript
27
- import { PrivateKey, PublicKey, Point, BigNumber } from '@bsv/sdk'
28
- ```
29
-
30
- ## Basic ECDH Key Exchange
31
-
32
- ### Step 1: Key Generation
33
-
34
- Let's start by generating key pairs for Alice and Bob:
35
-
36
- ```typescript
37
- function generateKeyPairs() {
38
- console.log('=== Generating Key Pairs ===')
39
-
40
- // Generate Alice's key pair
41
- const alicePrivKey = PrivateKey.fromRandom()
42
- const alicePubKey = alicePrivKey.toPublicKey()
43
-
44
- // Generate Bob's key pair
45
- const bobPrivKey = PrivateKey.fromRandom()
46
- const bobPubKey = bobPrivKey.toPublicKey()
47
-
48
- console.log('Alice private key:', alicePrivKey.toWif())
49
- console.log('Alice public key:', alicePubKey.toString())
50
- console.log('Bob private key:', bobPrivKey.toWif())
51
- console.log('Bob public key:', bobPubKey.toString())
52
-
53
- return { alicePrivKey, alicePubKey, bobPrivKey, bobPubKey }
54
- }
55
- ```
56
-
57
- ### Step 2: Deriving Shared Secrets
58
-
59
- Now both parties can derive the same shared secret:
60
-
61
- ```typescript
62
- function performECDH(alicePrivKey: PrivateKey, alicePubKey: PublicKey,
63
- bobPrivKey: PrivateKey, bobPubKey: PublicKey) {
64
- console.log('\n=== ECDH Key Exchange ===')
65
-
66
- // Alice creates a shared secret using Bob's public key and her private key
67
- const aliceSharedSecret = alicePrivKey.deriveSharedSecret(bobPubKey)
68
-
69
- // Bob creates the same shared secret using Alice's public key and his private key
70
- const bobSharedSecret = bobPrivKey.deriveSharedSecret(alicePubKey)
71
-
72
- // Verify they're identical
73
- const aliceSecretHex = aliceSharedSecret.getX().toHex()
74
- const bobSecretHex = bobSharedSecret.getX().toHex()
75
-
76
- console.log('Alice\'s shared secret (x-coordinate):', aliceSecretHex)
77
- console.log('Bob\'s shared secret (x-coordinate):', bobSecretHex)
78
- console.log('Secrets match:', aliceSecretHex === bobSecretHex)
79
-
80
- return aliceSharedSecret
81
- }
82
- ```
83
-
84
- ### Step 3: Complete Example
85
-
86
- ```typescript
87
- function basicECDHExample() {
88
- try {
89
- // Generate key pairs
90
- const { alicePrivKey, alicePubKey, bobPrivKey, bobPubKey } = generateKeyPairs()
91
-
92
- // Perform ECDH
93
- const sharedSecret = performECDH(alicePrivKey, alicePubKey, bobPrivKey, bobPubKey)
94
-
95
- // The shared secret is a point on the curve
96
- console.log('\nShared secret point:')
97
- console.log('X:', sharedSecret.getX().toHex())
98
- console.log('Y:', sharedSecret.getY().toHex())
99
-
100
- } catch (error) {
101
- console.error('ECDH Error:', error.message)
102
- }
103
- }
104
-
105
- // Run the example
106
- basicECDHExample()
107
- ```
108
-
109
- ## Security Validation
110
-
111
- The SDK includes built-in security checks to prevent twist attacks:
112
-
113
- ```typescript
114
- function demonstrateSecurityValidation() {
115
- console.log('\n=== Security Validation ===')
116
-
117
- const validPrivKey = PrivateKey.fromRandom()
118
-
119
- // This will work - valid public key
120
- const validPubKey = PrivateKey.fromRandom().toPublicKey()
121
- const validSecret = validPrivKey.deriveSharedSecret(validPubKey)
122
- console.log('Valid ECDH succeeded')
123
-
124
- // This will fail - invalid point (not on curve)
125
- try {
126
- const invalidPubKey = new PublicKey(new BigNumber(14), new BigNumber(16))
127
- validPrivKey.deriveSharedSecret(invalidPubKey)
128
- } catch (error) {
129
- console.log('Security check prevented invalid key usage:', error.message)
130
- }
131
- }
132
-
133
- demonstrateSecurityValidation()
134
- ```
135
-
136
- ## Practical Applications
137
-
138
- ### Secure Message Exchange
139
-
140
- Here's how to use ECDH for encrypting messages:
141
-
142
- ```typescript
143
- import { createHash, createCipheriv, createDecipheriv, randomBytes } from 'crypto'
144
-
145
- function deriveEncryptionKey(sharedSecret: Point): Buffer {
146
- // Use the x-coordinate of the shared secret as key material
147
- const keyMaterial = sharedSecret.getX().toArray('be', 32)
148
-
149
- // Hash to create a proper encryption key
150
- return createHash('sha256').update(Buffer.from(keyMaterial)).digest()
151
- }
152
-
153
- function encryptMessage(message: string, sharedSecret: Point): {
154
- encrypted: string,
155
- iv: string
156
- } {
157
- const key = deriveEncryptionKey(sharedSecret)
158
- const iv = randomBytes(16)
159
- const cipher = createCipheriv('aes-256-cbc', key, iv)
160
-
161
- let encrypted = cipher.update(message, 'utf8', 'hex')
162
- encrypted += cipher.final('hex')
163
-
164
- return {
165
- encrypted,
166
- iv: iv.toString('hex')
167
- }
168
- }
169
-
170
- function decryptMessage(encryptedData: { encrypted: string, iv: string },
171
- sharedSecret: Point): string {
172
- const key = deriveEncryptionKey(sharedSecret)
173
- const decipher = createDecipheriv('aes-256-cbc', key, Buffer.from(encryptedData.iv, 'hex'))
174
-
175
- let decrypted = decipher.update(encryptedData.encrypted, 'hex', 'utf8')
176
- decrypted += decipher.final('utf8')
177
-
178
- return decrypted
179
- }
180
-
181
- function secureMessagingExample() {
182
- console.log('\n=== Secure Messaging with ECDH ===')
183
-
184
- // Setup key pairs
185
- const alicePrivKey = PrivateKey.fromRandom()
186
- const bobPrivKey = PrivateKey.fromRandom()
187
- const alicePubKey = alicePrivKey.toPublicKey()
188
- const bobPubKey = bobPrivKey.toPublicKey()
189
-
190
- // Derive shared secret
191
- const sharedSecret = alicePrivKey.deriveSharedSecret(bobPubKey)
192
-
193
- // Alice encrypts a message
194
- const message = "Hello Bob! This is a secret message."
195
- const encryptedData = encryptMessage(message, sharedSecret)
196
-
197
- console.log('Original message:', message)
198
- console.log('Encrypted:', encryptedData.encrypted)
199
-
200
- // Bob decrypts the message using the same shared secret
201
- const bobSharedSecret = bobPrivKey.deriveSharedSecret(alicePubKey)
202
- const decryptedMessage = decryptMessage(encryptedData, bobSharedSecret)
203
-
204
- console.log('Decrypted message:', decryptedMessage)
205
- console.log('Messages match:', message === decryptedMessage)
206
- }
207
-
208
- secureMessagingExample()
209
- ```
210
-
211
- ### Key Exchange with Authentication
212
-
213
- Combine ECDH with digital signatures for authenticated key exchange:
214
-
215
- ```typescript
216
- function authenticatedKeyExchange() {
217
- console.log('\n=== Authenticated Key Exchange ===')
218
-
219
- // Generate long-term identity keys
220
- const aliceIdentityPrivKey = PrivateKey.fromRandom()
221
- const bobIdentityPrivKey = PrivateKey.fromRandom()
222
- const aliceIdentityPubKey = aliceIdentityPrivKey.toPublicKey()
223
- const bobIdentityPubKey = bobIdentityPrivKey.toPublicKey()
224
-
225
- // Generate ephemeral keys for this session
226
- const aliceEphemeralPrivKey = PrivateKey.fromRandom()
227
- const bobEphemeralPrivKey = PrivateKey.fromRandom()
228
- const aliceEphemeralPubKey = aliceEphemeralPrivKey.toPublicKey()
229
- const bobEphemeralPubKey = bobEphemeralPrivKey.toPublicKey()
230
-
231
- // Alice signs her ephemeral public key with her identity key
232
- const aliceSignature = aliceIdentityPrivKey.sign(
233
- Buffer.from(aliceEphemeralPubKey.toString(), 'utf8')
234
- )
235
-
236
- // Bob signs his ephemeral public key with his identity key
237
- const bobSignature = bobIdentityPrivKey.sign(
238
- Buffer.from(bobEphemeralPubKey.toString(), 'utf8')
239
- )
240
-
241
- // Verify signatures (in practice, you'd exchange these over the network)
242
- const aliceSignatureValid = aliceIdentityPubKey.verify(
243
- Buffer.from(aliceEphemeralPubKey.toString(), 'utf8'),
244
- aliceSignature
245
- )
246
-
247
- const bobSignatureValid = bobIdentityPubKey.verify(
248
- Buffer.from(bobEphemeralPubKey.toString(), 'utf8'),
249
- bobSignature
250
- )
251
-
252
- console.log('Alice signature valid:', aliceSignatureValid)
253
- console.log('Bob signature valid:', bobSignatureValid)
254
-
255
- if (aliceSignatureValid && bobSignatureValid) {
256
- // Perform ECDH with ephemeral keys
257
- const sharedSecret = aliceEphemeralPrivKey.deriveSharedSecret(bobEphemeralPubKey)
258
- console.log('Authenticated shared secret established')
259
- console.log('Secret (x-coordinate):', sharedSecret.getX().toHex().substring(0, 16) + '...')
260
- }
261
- }
262
-
263
- authenticatedKeyExchange()
264
- ```
265
-
266
- ## Advanced ECDH Patterns
267
-
268
- ### Multi-Party Key Agreement
269
-
270
- Extend ECDH to multiple parties:
271
-
272
- ```typescript
273
- function multiPartyKeyAgreement() {
274
- console.log('\n=== Multi-Party Key Agreement ===')
275
-
276
- // Generate keys for three parties
277
- const parties = ['Alice', 'Bob', 'Charlie'].map(name => ({
278
- name,
279
- privKey: PrivateKey.fromRandom(),
280
- pubKey: null as PublicKey | null
281
- }))
282
-
283
- // Generate public keys
284
- parties.forEach(party => {
285
- party.pubKey = party.privKey.toPublicKey()
286
- })
287
-
288
- // Each party computes pairwise shared secrets
289
- const sharedSecrets = new Map<string, Point>()
290
-
291
- for (let i = 0; i < parties.length; i++) {
292
- for (let j = i + 1; j < parties.length; j++) {
293
- const party1 = parties[i]
294
- const party2 = parties[j]
295
-
296
- const secret = party1.privKey.deriveSharedSecret(party2.pubKey!)
297
- const pairKey = `${party1.name}-${party2.name}`
298
- sharedSecrets.set(pairKey, secret)
299
-
300
- console.log(`${pairKey} shared secret:`, secret.getX().toHex().substring(0, 16) + '...')
301
- }
302
- }
303
-
304
- return sharedSecrets
305
- }
306
-
307
- multiPartyKeyAgreement()
308
- ```
309
-
310
- ### Key Derivation Functions
311
-
312
- Use proper key derivation for different purposes:
313
-
314
- ```typescript
315
- function keyDerivationExample() {
316
- console.log('\n=== Key Derivation Functions ===')
317
-
318
- const alicePrivKey = PrivateKey.fromRandom()
319
- const bobPrivKey = PrivateKey.fromRandom()
320
- const sharedSecret = alicePrivKey.deriveSharedSecret(bobPrivKey.toPublicKey())
321
-
322
- // Derive different keys for different purposes
323
- function deriveKey(purpose: string, length: number = 32): Buffer {
324
- const keyMaterial = sharedSecret.getX().toArray('be', 32)
325
- const hash = createHash('sha256')
326
- hash.update(Buffer.from(keyMaterial))
327
- hash.update(Buffer.from(purpose, 'utf8'))
328
- return hash.digest().slice(0, length)
329
- }
330
-
331
- const encryptionKey = deriveKey('encryption', 32)
332
- const macKey = deriveKey('authentication', 32)
333
- const ivKey = deriveKey('iv', 16)
334
-
335
- console.log('Encryption key:', encryptionKey.toString('hex'))
336
- console.log('MAC key:', macKey.toString('hex'))
337
- console.log('IV key:', ivKey.toString('hex'))
338
- }
339
-
340
- keyDerivationExample()
341
- ```
342
-
343
- ## Security Considerations
344
-
345
- ### Best Practices
346
-
347
- 1. **Key Validation**: Always validate public keys before use
348
- 2. **Ephemeral Keys**: Use ephemeral keys for forward secrecy
349
- 3. **Authentication**: Combine with signatures to prevent man-in-the-middle attacks
350
- 4. **Key Derivation**: Use proper KDFs to derive encryption keys from shared secrets
351
-
352
- ### Common Pitfalls
353
-
354
- ```typescript
355
- function securityPitfalls() {
356
- console.log('\n=== Security Pitfalls to Avoid ===')
357
-
358
- // ❌ DON'T: Use shared secret directly as encryption key
359
- console.log('❌ Never use the shared secret point directly for encryption')
360
-
361
- // ✅ DO: Use proper key derivation
362
- console.log('✅ Always use key derivation functions')
363
-
364
- // ❌ DON'T: Reuse ephemeral keys
365
- console.log('❌ Never reuse ephemeral keys across sessions')
366
-
367
- // ✅ DO: Generate fresh ephemeral keys for each session
368
- console.log('✅ Generate fresh keys for each exchange')
369
-
370
- // ❌ DON'T: Skip public key validation
371
- console.log('❌ Never skip public key validation')
372
-
373
- // ✅ DO: Always validate received public keys
374
- console.log('✅ SDK automatically validates keys in deriveSharedSecret()')
375
- }
376
-
377
- securityPitfalls()
378
- ```
379
-
380
- ## Performance Considerations
381
-
382
- ### Optimizing ECDH Operations
383
-
384
- ```typescript
385
- function performanceExample() {
386
- console.log('\n=== Performance Optimization ===')
387
-
388
- const iterations = 1000
389
-
390
- // Pre-generate keys
391
- const privateKeys = Array.from({ length: iterations }, () => PrivateKey.fromRandom())
392
- const publicKeys = privateKeys.map(pk => pk.toPublicKey())
393
-
394
- // Measure ECDH performance
395
- const startTime = Date.now()
396
-
397
- for (let i = 0; i < iterations; i++) {
398
- const sharedSecret = privateKeys[i].deriveSharedSecret(publicKeys[(i + 1) % iterations])
399
- // In practice, you'd process the shared secret here
400
- }
401
-
402
- const endTime = Date.now()
403
- const avgTime = (endTime - startTime) / iterations
404
-
405
- console.log(`Performed ${iterations} ECDH operations`)
406
- console.log(`Average time per operation: ${avgTime.toFixed(2)}ms`)
407
- }
408
-
409
- performanceExample()
410
- ```
411
-
412
- ## Error Handling
413
-
414
- ### Robust ECDH Implementation
415
-
416
- ```typescript
417
- function robustECDH(privateKey: PrivateKey, publicKey: PublicKey): Point | null {
418
- try {
419
- // Validate inputs
420
- if (!privateKey || !publicKey) {
421
- throw new Error('Invalid key parameters')
422
- }
423
-
424
- // Perform ECDH with built-in validation
425
- const sharedSecret = privateKey.deriveSharedSecret(publicKey)
426
-
427
- // Additional validation if needed
428
- if (sharedSecret.getX().isZero() || sharedSecret.getY().isZero()) {
429
- throw new Error('Invalid shared secret generated')
430
- }
431
-
432
- return sharedSecret
433
-
434
- } catch (error) {
435
- console.error('ECDH operation failed:', error.message)
436
- return null
437
- }
438
- }
439
-
440
- function errorHandlingExample() {
441
- console.log('\n=== Error Handling ===')
442
-
443
- const validPrivKey = PrivateKey.fromRandom()
444
- const validPubKey = PrivateKey.fromRandom().toPublicKey()
445
-
446
- // Test with valid keys
447
- const result1 = robustECDH(validPrivKey, validPubKey)
448
- console.log('Valid ECDH result:', result1 ? 'Success' : 'Failed')
449
-
450
- // Test with invalid key (will be caught by SDK validation)
451
- try {
452
- const invalidPubKey = new PublicKey(new BigNumber(1), new BigNumber(1))
453
- const result2 = robustECDH(validPrivKey, invalidPubKey)
454
- console.log('Invalid ECDH result:', result2 ? 'Success' : 'Failed')
455
- } catch (error) {
456
- console.log('Caught invalid key error:', error.message)
457
- }
458
- }
459
-
460
- errorHandlingExample()
461
- ```
462
-
463
- ## Testing Your ECDH Implementation
464
-
465
- ### Comprehensive Test Suite
466
-
467
- ```typescript
468
- function testECDHImplementation() {
469
- console.log('\n=== ECDH Test Suite ===')
470
-
471
- let passed = 0
472
- let total = 0
473
-
474
- function test(name: string, testFn: () => boolean) {
475
- total++
476
- try {
477
- if (testFn()) {
478
- console.log(`✅ ${name}`)
479
- passed++
480
- } else {
481
- console.log(`❌ ${name}`)
482
- }
483
- } catch (error) {
484
- console.log(`❌ ${name}: ${error.message}`)
485
- }
486
- }
487
-
488
- // Test 1: Basic ECDH symmetry
489
- test('Basic ECDH symmetry', () => {
490
- const privA = PrivateKey.fromRandom()
491
- const privB = PrivateKey.fromRandom()
492
- const secretA = privA.deriveSharedSecret(privB.toPublicKey())
493
- const secretB = privB.deriveSharedSecret(privA.toPublicKey())
494
- return secretA.getX().toHex() === secretB.getX().toHex()
495
- })
496
-
497
- // Test 2: Different key formats
498
- test('Different key formats', () => {
499
- const privA = PrivateKey.fromRandom()
500
- const privB = PrivateKey.fromRandom()
501
- const pubB = PublicKey.fromString(privB.toPublicKey().toDER('hex') as string)
502
- const secret1 = privA.deriveSharedSecret(privB.toPublicKey())
503
- const secret2 = privA.deriveSharedSecret(pubB)
504
- return secret1.getX().toHex() === secret2.getX().toHex()
505
- })
506
-
507
- // Test 3: Invalid key rejection
508
- test('Invalid key rejection', () => {
509
- const privKey = PrivateKey.fromRandom()
510
- const invalidPubKey = new PublicKey(new BigNumber(14), new BigNumber(16))
511
- try {
512
- privKey.deriveSharedSecret(invalidPubKey)
513
- return false // Should have thrown
514
- } catch (error) {
515
- return error.message.includes('not valid for ECDH')
516
- }
517
- })
518
-
519
- console.log(`\nTest Results: ${passed}/${total} passed`)
520
- return passed === total
521
- }
522
-
523
- testECDHImplementation()
524
- ```
525
-
526
- ## Conclusion
527
-
528
- In this tutorial, you've learned how to implement ECDH key exchange using the BSV TypeScript SDK. You now understand:
529
-
530
- - The mathematical principles behind ECDH
531
- - How to generate key pairs and derive shared secrets
532
- - Security considerations and validation
533
- - Practical applications including secure messaging
534
- - Advanced patterns like authenticated key exchange
535
- - Performance optimization and error handling
536
-
537
- The BSV TypeScript SDK provides robust ECDH implementation with built-in security validations, making it safe and easy to implement secure key exchange protocols.
538
-
539
- ## Next Steps
540
-
541
- - **[Script Construction](./script-construction.md)**: Learn to create custom Bitcoin scripts
542
- - **[Advanced Transaction Construction](./advanced-transaction.md)**: Build complex transactions
543
- - **[SPV and Merkle Proofs](./spv-merkle-proofs.md)**: Implement lightweight verification
544
-
545
- ## Further Reading
546
-
547
- - [RFC 3526 - Diffie-Hellman Key Agreement](https://tools.ietf.org/html/rfc3526)
548
- - [SEC 1: Elliptic Curve Cryptography](https://www.secg.org/sec1-v2.pdf)
549
- - [BSV TypeScript SDK Documentation](../reference/primitives.md)