smartledger-bsv 3.2.2 → 3.3.1

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 (41) hide show
  1. package/CHANGELOG.md +147 -0
  2. package/architecture_demo.js +247 -0
  3. package/bsv-gdaf.min.js +37 -0
  4. package/bsv-ltp.min.js +37 -0
  5. package/bsv-shamir.min.js +12 -0
  6. package/bsv.bundle.js +9 -9
  7. package/build/bsv-smartcontract.min.js +10 -8
  8. package/build/bsv.bundle.js +9 -9
  9. package/build/bsv.min.js +10 -8
  10. package/build/webpack.gdaf.config.js +54 -0
  11. package/build/webpack.ltp.config.js +17 -0
  12. package/bundle-entry.js +77 -1
  13. package/complete_ltp_demo.js +511 -0
  14. package/gdaf-entry.js +54 -0
  15. package/index.js +259 -0
  16. package/lib/crypto/shamir.js +360 -0
  17. package/lib/gdaf/attestation-signer.js +461 -0
  18. package/lib/gdaf/attestation-verifier.js +600 -0
  19. package/lib/gdaf/did-resolver.js +382 -0
  20. package/lib/gdaf/index.js +471 -0
  21. package/lib/gdaf/schema-validator.js +682 -0
  22. package/lib/gdaf/smartledger-anchor.js +486 -0
  23. package/lib/gdaf/zk-prover.js +507 -0
  24. package/lib/ltp/anchor.js +438 -0
  25. package/lib/ltp/claim.js +1026 -0
  26. package/lib/ltp/index.js +470 -0
  27. package/lib/ltp/obligation.js +945 -0
  28. package/lib/ltp/proof.js +828 -0
  29. package/lib/ltp/registry.js +702 -0
  30. package/lib/ltp/right.js +765 -0
  31. package/lib/smart_contract/API_REFERENCE.md +1 -1
  32. package/lib/smart_contract/EXAMPLES.md +2 -2
  33. package/lib/smart_contract/QUICK_START.md +2 -2
  34. package/lib/smart_contract/README.md +1 -1
  35. package/ltp-entry.js +92 -0
  36. package/package.json +44 -4
  37. package/shamir-entry.js +173 -0
  38. package/shamir_demo.js +121 -0
  39. package/simple_demo.js +204 -0
  40. package/test_shamir.js +221 -0
  41. package/test_standalone_shamir.html +83 -0
package/gdaf-entry.js ADDED
@@ -0,0 +1,54 @@
1
+ 'use strict'
2
+
3
+ /**
4
+ * GDAF (Global Digital Attestation Framework) Standalone Bundle
5
+ *
6
+ * Entry point for creating standalone distribution of the Global Digital
7
+ * Attestation Framework. This module can be built with webpack to create
8
+ * a standalone bundle for browser use.
9
+ */
10
+
11
+ // Core BSV dependencies for GDAF
12
+ var PublicKey = require('./lib/publickey')
13
+ var PrivateKey = require('./lib/privatekey')
14
+ var Address = require('./lib/address')
15
+ var Transaction = require('./lib/transaction')
16
+ var Script = require('./lib/script')
17
+ var Hash = require('./lib/crypto/hash')
18
+ var ECDSA = require('./lib/crypto/ecdsa')
19
+ var Signature = require('./lib/crypto/signature')
20
+
21
+ // GDAF modules
22
+ var GDAF = require('./lib/gdaf')
23
+
24
+ // Create minimal BSV context for GDAF
25
+ var bsvContext = {
26
+ PublicKey: PublicKey,
27
+ PrivateKey: PrivateKey,
28
+ Address: Address,
29
+ Transaction: Transaction,
30
+ Script: Script,
31
+ crypto: {
32
+ Hash: Hash,
33
+ ECDSA: ECDSA,
34
+ Signature: Signature
35
+ }
36
+ }
37
+
38
+ // Export GDAF with BSV context
39
+ module.exports = {
40
+ GDAF: GDAF,
41
+ bsv: bsvContext,
42
+
43
+ // Direct access to GDAF classes for convenience
44
+ DIDResolver: require('./lib/gdaf/did-resolver'),
45
+ AttestationSigner: require('./lib/gdaf/attestation-signer'),
46
+ AttestationVerifier: require('./lib/gdaf/attestation-verifier'),
47
+ ZKProver: require('./lib/gdaf/zk-prover'),
48
+ SmartLedgerAnchor: require('./lib/gdaf/smartledger-anchor'),
49
+ SchemaValidator: require('./lib/gdaf/schema-validator'),
50
+
51
+ // Utility functions
52
+ version: '1.0.0',
53
+ description: 'SmartLedger BSV Global Digital Attestation Framework'
54
+ }
package/index.js CHANGED
@@ -48,6 +48,7 @@ bsv.crypto.Hash = require('./lib/crypto/hash')
48
48
  bsv.crypto.Random = require('./lib/crypto/random')
49
49
  bsv.crypto.Point = require('./lib/crypto/point')
50
50
  bsv.crypto.Signature = require('./lib/crypto/signature')
51
+ bsv.crypto.Shamir = require('./lib/crypto/shamir')
51
52
 
52
53
  // SmartLedger security enhancements
53
54
  bsv.crypto.SmartVerify = require('./lib/crypto/smartledger_verify')
@@ -82,8 +83,14 @@ bsv.PrivateKey = require('./lib/privatekey')
82
83
  bsv.PublicKey = require('./lib/publickey')
83
84
  bsv.Script = require('./lib/script')
84
85
  bsv.Transaction = require('./lib/transaction')
86
+ bsv.Input = require('./lib/transaction').Input
87
+ bsv.Output = require('./lib/transaction').Output
88
+ bsv.UnspentOutput = require('./lib/transaction').UnspentOutput
85
89
  bsv.Message = require('./lib/message')
90
+ bsv.Mnemonic = require('./lib/mnemonic')
91
+ bsv.ECIES = require('./lib/ecies')
86
92
  bsv.Signature = require('./lib/crypto/signature')
93
+ bsv.Shamir = require('./lib/crypto/shamir')
87
94
 
88
95
  // SmartLedger security modules (top-level access)
89
96
  bsv.SmartLedger = {
@@ -119,5 +126,257 @@ if (typeof window === 'undefined' && typeof require === 'function') {
119
126
  }
120
127
  }
121
128
 
129
+ // Global Digital Attestation Framework (GDAF)
130
+ bsv.GDAF = require('./lib/gdaf')
131
+
132
+ // GDAF Direct Access Methods (for easier developer experience)
133
+ bsv.createDID = function(publicKey) {
134
+ var gdaf = new bsv.GDAF()
135
+ return gdaf.createDID(publicKey)
136
+ }
137
+
138
+ bsv.resolveDID = function(did) {
139
+ var gdaf = new bsv.GDAF()
140
+ return gdaf.resolveDID(did)
141
+ }
142
+
143
+ bsv.createEmailCredential = function(issuerDID, subjectDID, email, issuerPrivateKey) {
144
+ var gdaf = new bsv.GDAF()
145
+ return gdaf.createEmailCredential(issuerDID, subjectDID, email, issuerPrivateKey)
146
+ }
147
+
148
+ bsv.createAgeCredential = function(issuerDID, subjectDID, ageThreshold, birthDate, issuerPrivateKey) {
149
+ var gdaf = new bsv.GDAF()
150
+ return gdaf.createAgeCredential(issuerDID, subjectDID, ageThreshold, birthDate, issuerPrivateKey)
151
+ }
152
+
153
+ bsv.createKYCCredential = function(issuerDID, subjectDID, level, piiHashes, issuerPrivateKey) {
154
+ var gdaf = new bsv.GDAF()
155
+ return gdaf.createKYCCredential(issuerDID, subjectDID, level, piiHashes, issuerPrivateKey)
156
+ }
157
+
158
+ bsv.verifyCredential = function(credential, options) {
159
+ var gdaf = new bsv.GDAF()
160
+ return gdaf.verifyCredential(credential, options)
161
+ }
162
+
163
+ bsv.validateCredential = function(credential, schema) {
164
+ var gdaf = new bsv.GDAF()
165
+ return gdaf.validateCredential(credential, schema)
166
+ }
167
+
168
+ bsv.generateSelectiveProof = function(credential, revealedFields, nonce) {
169
+ var gdaf = new bsv.GDAF()
170
+ return gdaf.generateSelectiveProof(credential, revealedFields, nonce)
171
+ }
172
+
173
+ bsv.generateAgeProof = function(ageCredential, minimumAge, nonce) {
174
+ var gdaf = new bsv.GDAF()
175
+ return gdaf.generateAgeProof(ageCredential, minimumAge, nonce)
176
+ }
177
+
178
+ bsv.verifyAgeProof = function(proof, minimumAge, issuerDID) {
179
+ var gdaf = new bsv.GDAF()
180
+ return gdaf.verifyAgeProof(proof, minimumAge, issuerDID)
181
+ }
182
+
183
+ bsv.createPresentation = function(credentials, holderDID, holderPrivateKey, options) {
184
+ var gdaf = new bsv.GDAF()
185
+ return gdaf.createPresentation(credentials, holderDID, holderPrivateKey, options)
186
+ }
187
+
188
+ bsv.getCredentialSchemas = function() {
189
+ var gdaf = new bsv.GDAF()
190
+ return gdaf.getAllSchemas()
191
+ }
192
+
193
+ bsv.createCredentialTemplate = function(credentialType) {
194
+ var gdaf = new bsv.GDAF()
195
+ return gdaf.createTemplate(credentialType)
196
+ }
197
+
198
+ // Legal Token Protocol (LTP) - Primitives-Only Interface
199
+ bsv.LTP = require('./lib/ltp')
200
+
201
+ // LTP Right Token Primitives
202
+ bsv.prepareRightToken = function(type, issuerDID, subjectDID, claim, issuerPrivateKey, options) {
203
+ return bsv.LTP.Right.prepareRightToken(type, issuerDID, subjectDID, claim, issuerPrivateKey, options)
204
+ }
205
+
206
+ bsv.prepareRightTokenVerification = function(token, options) {
207
+ return bsv.LTP.Right.prepareRightTokenVerification(token, options)
208
+ }
209
+
210
+ bsv.prepareRightTokenTransfer = function(token, newOwnerDID, currentOwnerKey, options) {
211
+ return bsv.LTP.Right.prepareRightTokenTransfer(token, newOwnerDID, currentOwnerKey, options)
212
+ }
213
+
214
+ bsv.prepareRightTypeValidation = function(type) {
215
+ return bsv.LTP.Right.prepareRightTypeValidation(type)
216
+ }
217
+
218
+ // LTP Obligation Token Primitives
219
+ bsv.prepareObligationToken = function(type, issuerDID, obligorDID, obligation, issuerPrivateKey, options) {
220
+ return bsv.LTP.Obligation.prepareObligationToken(type, issuerDID, obligorDID, obligation, issuerPrivateKey, options)
221
+ }
222
+
223
+ bsv.prepareObligationVerification = function(token, options) {
224
+ return bsv.LTP.Obligation.prepareObligationVerification(token, options)
225
+ }
226
+
227
+ bsv.prepareObligationFulfillment = function(token, fulfillment, obligorKey, options) {
228
+ return bsv.LTP.Obligation.prepareObligationFulfillment(token, fulfillment, obligorKey, options)
229
+ }
230
+
231
+ bsv.prepareObligationBreachAssessment = function(token, breach, assessor) {
232
+ return bsv.LTP.Obligation.prepareObligationBreachAssessment(token, breach, assessor)
233
+ }
234
+
235
+ bsv.prepareObligationMonitoringReport = function(obligations, criteria) {
236
+ return bsv.LTP.Obligation.prepareObligationMonitoringReport(obligations, criteria)
237
+ }
238
+
239
+ // LTP Claim Validation Primitives
240
+ bsv.prepareClaimValidation = function(claim, schemaName) {
241
+ return bsv.LTP.Claim.prepareClaimValidation(claim, schemaName)
242
+ }
243
+
244
+ bsv.prepareClaimAttestation = function(claim, schemaName, attestor) {
245
+ return bsv.LTP.Claim.prepareClaimAttestation(claim, schemaName, attestor)
246
+ }
247
+
248
+ bsv.prepareClaimDispute = function(claimHash, disputant, dispute) {
249
+ return bsv.LTP.Claim.prepareClaimDispute(claimHash, disputant, dispute)
250
+ }
251
+
252
+ bsv.prepareBulkClaimValidation = function(claims, schemaName) {
253
+ return bsv.LTP.Claim.prepareBulkClaimValidation(claims, schemaName)
254
+ }
255
+
256
+ bsv.prepareClaimTemplate = function(schemaName, options) {
257
+ return bsv.LTP.Claim.prepareClaimTemplate(schemaName, options)
258
+ }
259
+
260
+ // LTP Proof Generation Primitives
261
+ bsv.prepareSignatureProof = function(token, privateKey, options) {
262
+ return bsv.LTP.Proof.prepareSignatureProof(token, privateKey, options)
263
+ }
264
+
265
+ bsv.prepareSignatureVerification = function(token, publicKey) {
266
+ return bsv.LTP.Proof.prepareSignatureVerification(token, publicKey)
267
+ }
268
+
269
+ bsv.prepareSelectiveDisclosure = function(token, revealedFields, nonce) {
270
+ return bsv.LTP.Proof.prepareSelectiveDisclosure(token, revealedFields, nonce)
271
+ }
272
+
273
+ bsv.prepareSelectiveDisclosureVerification = function(proof, expectedNonce) {
274
+ return bsv.LTP.Proof.prepareSelectiveDisclosureVerification(proof, expectedNonce)
275
+ }
276
+
277
+ bsv.prepareLegalValidityProof = function(token, jurisdiction, nonce) {
278
+ return bsv.LTP.Proof.prepareLegalValidityProof(token, jurisdiction, nonce)
279
+ }
280
+
281
+ bsv.prepareZeroKnowledgeProof = function(token, statement, nonce) {
282
+ return bsv.LTP.Proof.prepareZeroKnowledgeProof(token, statement, nonce)
283
+ }
284
+
285
+ // LTP Registry Management Primitives
286
+ bsv.prepareRegistry = function(config) {
287
+ return bsv.LTP.Registry.prepareRegistry(config)
288
+ }
289
+
290
+ bsv.prepareTokenRegistration = function(token, registryConfig, options) {
291
+ return bsv.LTP.Registry.prepareTokenRegistration(token, registryConfig, options)
292
+ }
293
+
294
+ bsv.prepareTokenApproval = function(tokenId, approver, registryConfig) {
295
+ return bsv.LTP.Registry.prepareTokenApproval(tokenId, approver, registryConfig)
296
+ }
297
+
298
+ bsv.prepareTokenRevocation = function(tokenId, revocation, registryConfig) {
299
+ return bsv.LTP.Registry.prepareTokenRevocation(tokenId, revocation, registryConfig)
300
+ }
301
+
302
+ bsv.prepareTokenStatusQuery = function(tokenId, registryConfig) {
303
+ return bsv.LTP.Registry.prepareTokenStatusQuery(tokenId, registryConfig)
304
+ }
305
+
306
+ bsv.prepareTokenSearch = function(criteria, registryConfig) {
307
+ return bsv.LTP.Registry.prepareTokenSearch(criteria, registryConfig)
308
+ }
309
+
310
+ bsv.prepareStatisticsQuery = function(registryConfig) {
311
+ return bsv.LTP.Registry.prepareStatisticsQuery(registryConfig)
312
+ }
313
+
314
+ bsv.prepareAuditLogQuery = function(registryConfig, options) {
315
+ return bsv.LTP.Registry.prepareAuditLogQuery(registryConfig, options)
316
+ }
317
+
318
+ // LTP Blockchain Anchoring Primitives
319
+ bsv.prepareTokenCommitment = function(token, options) {
320
+ return bsv.LTP.Anchor.prepareTokenCommitment(token, options)
321
+ }
322
+
323
+ bsv.prepareBatchCommitment = function(tokens, options) {
324
+ return bsv.LTP.Anchor.prepareBatchCommitment(tokens, options)
325
+ }
326
+
327
+ bsv.verifyTokenAnchor = function(token, txid, txData) {
328
+ return bsv.LTP.Anchor.verifyTokenAnchor(token, txid, txData)
329
+ }
330
+
331
+ bsv.formatRevocation = function(tokenId, revocationData) {
332
+ return bsv.LTP.Anchor.formatRevocation(tokenId, revocationData)
333
+ }
334
+
335
+ // LTP Static Data Access (unchanged)
336
+ bsv.getRightTypes = function() {
337
+ return bsv.LTP.Right.getRightTypes()
338
+ }
339
+
340
+ bsv.getObligationTypes = function() {
341
+ return bsv.LTP.Obligation.getObligationTypes()
342
+ }
343
+
344
+ bsv.getObligationPriority = function() {
345
+ return bsv.LTP.Obligation.getObligationPriority()
346
+ }
347
+
348
+ bsv.getObligationStatus = function() {
349
+ return bsv.LTP.Obligation.getObligationStatus()
350
+ }
351
+
352
+ bsv.getClaimSchemas = function() {
353
+ return bsv.LTP.Claim.getSchemas()
354
+ }
355
+
356
+ bsv.getClaimSchemaNames = function() {
357
+ return bsv.LTP.Claim.getSchemaNames()
358
+ }
359
+
360
+ bsv.getClaimSchema = function(schemaName) {
361
+ return bsv.LTP.Claim.getSchema(schemaName)
362
+ }
363
+
364
+ bsv.createClaimTemplate = function(schemaName) {
365
+ return bsv.LTP.Claim.createTemplate(schemaName)
366
+ }
367
+
368
+ // LTP Utility Functions
369
+ bsv.canonicalizeClaim = function(claim) {
370
+ return bsv.LTP.Claim.canonicalize(claim)
371
+ }
372
+
373
+ bsv.hashClaim = function(claim) {
374
+ return bsv.LTP.Claim.hash(claim)
375
+ }
376
+
377
+ bsv.addCustomClaimSchema = function(name, schema) {
378
+ return bsv.LTP.Claim.addSchema(name, schema)
379
+ }
380
+
122
381
  // Internal usage, exposed for testing/advanced tweaking
123
382
  bsv.Transaction.sighash = require('./lib/transaction/sighash')
@@ -0,0 +1,360 @@
1
+ 'use strict'
2
+
3
+ var BN = require('./bn')
4
+ var Random = require('./random')
5
+ var Hash = require('./hash')
6
+ var _ = require('../util/_')
7
+
8
+ /**
9
+ * Shamir Secret Sharing implementation for secure secret distribution
10
+ * Based on Shamir's Secret Sharing algorithm using finite field arithmetic
11
+ *
12
+ * Features:
13
+ * - Split secrets into N shares with K threshold
14
+ * - Reconstruct secret from any K shares
15
+ * - Cryptographically secure random polynomial generation
16
+ * - Support for arbitrary secret sizes via byte-level processing
17
+ * - Compatible with BSV cryptographic primitives
18
+ */
19
+
20
+ /**
21
+ * Prime number for finite field operations
22
+ * Using a large prime that's suitable for byte operations (2^31 - 1)
23
+ */
24
+ var PRIME = new BN(2147483647) // Mersenne prime 2^31 - 1
25
+
26
+ /**
27
+ * Shamir Secret Sharing constructor
28
+ * @param {Object} options - Configuration options
29
+ */
30
+ function Shamir(options) {
31
+ if (!(this instanceof Shamir)) {
32
+ return new Shamir(options)
33
+ }
34
+
35
+ this.options = options || {}
36
+ return this
37
+ }
38
+
39
+ /**
40
+ * Split a secret into shares using Shamir's Secret Sharing
41
+ * @param {Buffer|String} secret - The secret to split
42
+ * @param {Number} threshold - Minimum number of shares needed to reconstruct
43
+ * @param {Number} shares - Total number of shares to generate
44
+ * @param {Object} options - Additional options
45
+ * @returns {Array} Array of share objects with {x, y} coordinates
46
+ */
47
+ Shamir.split = function(secret, threshold, shares, options) {
48
+ options = options || {}
49
+
50
+ if (!secret) {
51
+ throw new Error('Secret is required')
52
+ }
53
+
54
+ if (threshold < 2) {
55
+ throw new Error('Threshold must be at least 2')
56
+ }
57
+
58
+ if (shares < threshold) {
59
+ throw new Error('Number of shares must be at least threshold')
60
+ }
61
+
62
+ if (threshold > 255 || shares > 255) {
63
+ throw new Error('Threshold and shares must be <= 255')
64
+ }
65
+
66
+ // Convert secret to buffer if string
67
+ var secretBuffer = Buffer.isBuffer(secret) ? secret : Buffer.from(secret, 'utf8')
68
+
69
+ // Process each byte of the secret
70
+ var allShares = []
71
+
72
+ for (var i = 0; i < secretBuffer.length; i++) {
73
+ var byte = secretBuffer[i]
74
+ var byteShares = Shamir._splitByte(byte, threshold, shares)
75
+ allShares.push(byteShares)
76
+ }
77
+
78
+ // Combine shares across bytes
79
+ var result = []
80
+ for (var j = 0; j < shares; j++) {
81
+ var shareData = {
82
+ id: j + 1,
83
+ threshold: threshold,
84
+ shares: shares,
85
+ length: secretBuffer.length,
86
+ bytes: []
87
+ }
88
+
89
+ for (var k = 0; k < allShares.length; k++) {
90
+ shareData.bytes.push(allShares[k][j])
91
+ }
92
+
93
+ result.push(shareData)
94
+ }
95
+
96
+ return result
97
+ }
98
+
99
+ /**
100
+ * Combine shares to reconstruct the original secret
101
+ * @param {Array} shares - Array of share objects
102
+ * @returns {Buffer} The reconstructed secret
103
+ */
104
+ Shamir.combine = function(shares) {
105
+ if (!shares || shares.length === 0) {
106
+ throw new Error('Shares array is required')
107
+ }
108
+
109
+ // Validate shares
110
+ var threshold = shares[0].threshold
111
+ var totalShares = shares[0].shares
112
+ var secretLength = shares[0].length
113
+
114
+ if (shares.length < threshold) {
115
+ throw new Error('Insufficient shares: need ' + threshold + ', got ' + shares.length)
116
+ }
117
+
118
+ // Verify all shares have same parameters
119
+ for (var i = 0; i < shares.length; i++) {
120
+ if (shares[i].threshold !== threshold || shares[i].shares !== totalShares) {
121
+ throw new Error('Shares have inconsistent parameters')
122
+ }
123
+ if (shares[i].length !== secretLength) {
124
+ throw new Error('Shares have different secret lengths')
125
+ }
126
+ }
127
+
128
+ var reconstructedBytes = []
129
+
130
+ // Reconstruct each byte
131
+ for (var j = 0; j < secretLength; j++) {
132
+ var byteShares = []
133
+ for (var k = 0; k < Math.min(shares.length, threshold); k++) {
134
+ byteShares.push(shares[k].bytes[j])
135
+ }
136
+
137
+ var byte = Shamir._combineByte(byteShares)
138
+ reconstructedBytes.push(byte)
139
+ }
140
+
141
+ // Create buffer from reconstructed bytes
142
+ return Buffer.from(reconstructedBytes)
143
+ }
144
+
145
+ /**
146
+ * Split a single byte using polynomial interpolation
147
+ * @private
148
+ */
149
+ Shamir._splitByte = function(secretByte, threshold, shares) {
150
+ // Convert byte to big number
151
+ var secret = new BN(secretByte)
152
+
153
+ // Generate random polynomial coefficients
154
+ var coefficients = [secret] // a0 = secret
155
+
156
+ for (var i = 1; i < threshold; i++) {
157
+ var coeff = Shamir._randomFieldElement()
158
+ coefficients.push(coeff)
159
+ }
160
+
161
+ // Generate shares by evaluating polynomial at different points
162
+ var result = []
163
+ for (var x = 1; x <= shares; x++) {
164
+ var y = Shamir._evaluatePolynomial(coefficients, new BN(x))
165
+ result.push({
166
+ x: x,
167
+ y: y.toString(16)
168
+ })
169
+ }
170
+
171
+ return result
172
+ }
173
+
174
+ /**
175
+ * Combine shares for a single byte using Lagrange interpolation
176
+ * @private
177
+ */
178
+ Shamir._combineByte = function(shares) {
179
+ if (shares.length === 0) {
180
+ throw new Error('No shares provided')
181
+ }
182
+
183
+ var result = new BN(0)
184
+
185
+ for (var i = 0; i < shares.length; i++) {
186
+ var xi = new BN(shares[i].x)
187
+ var yi = new BN(shares[i].y, 16)
188
+
189
+ // Calculate Lagrange basis polynomial
190
+ var numerator = new BN(1)
191
+ var denominator = new BN(1)
192
+
193
+ for (var j = 0; j < shares.length; j++) {
194
+ if (i !== j) {
195
+ var xj = new BN(shares[j].x)
196
+ // For Lagrange interpolation at x=0 (to get the constant term)
197
+ var numFactor = new BN(0).sub(xj)
198
+ if (numFactor.lt(new BN(0))) {
199
+ numFactor = numFactor.add(PRIME)
200
+ }
201
+ numerator = numerator.mul(numFactor).mod(PRIME)
202
+
203
+ var denFactor = xi.sub(xj)
204
+ if (denFactor.lt(new BN(0))) {
205
+ denFactor = denFactor.add(PRIME)
206
+ }
207
+ denominator = denominator.mul(denFactor).mod(PRIME)
208
+ }
209
+ }
210
+
211
+ // Calculate modular inverse of denominator
212
+ var inverse = Shamir._modInverse(denominator, PRIME)
213
+ var lagrange = numerator.mul(inverse).mod(PRIME)
214
+
215
+ // Add to result
216
+ result = result.add(yi.mul(lagrange)).mod(PRIME)
217
+ }
218
+
219
+ // Convert back to byte (0-255) - ensure positive result
220
+ var finalResult = result.mod(PRIME).mod(new BN(256))
221
+ return finalResult.toNumber()
222
+ }
223
+
224
+ /**
225
+ * Evaluate polynomial at given point
226
+ * @private
227
+ */
228
+ Shamir._evaluatePolynomial = function(coefficients, x) {
229
+ var result = new BN(0)
230
+ var xPower = new BN(1)
231
+
232
+ for (var i = 0; i < coefficients.length; i++) {
233
+ result = result.add(coefficients[i].mul(xPower)).mod(PRIME)
234
+ xPower = xPower.mul(x).mod(PRIME)
235
+ }
236
+
237
+ return result
238
+ }
239
+
240
+ /**
241
+ * Generate random field element
242
+ * @private
243
+ */
244
+ Shamir._randomFieldElement = function() {
245
+ var bytes = Random.getRandomBuffer(32)
246
+ var num = new BN(bytes)
247
+ return num.mod(PRIME.sub(new BN(1))).add(new BN(1))
248
+ }
249
+
250
+ /**
251
+ * Calculate modular inverse using extended Euclidean algorithm
252
+ * @private
253
+ */
254
+ Shamir._modInverse = function(a, m) {
255
+ if (a.lt(new BN(0))) {
256
+ a = a.mod(m).add(m)
257
+ }
258
+
259
+ var g = Shamir._extendedGCD(a, m)
260
+
261
+ if (!g.gcd.eq(new BN(1))) {
262
+ throw new Error('Modular inverse does not exist')
263
+ }
264
+
265
+ return g.x.mod(m).add(m).mod(m)
266
+ }
267
+
268
+ /**
269
+ * Extended Euclidean algorithm
270
+ * @private
271
+ */
272
+ Shamir._extendedGCD = function(a, b) {
273
+ if (a.eq(new BN(0))) {
274
+ return { gcd: b, x: new BN(0), y: new BN(1) }
275
+ }
276
+
277
+ var g = Shamir._extendedGCD(b.mod(a), a)
278
+
279
+ return {
280
+ gcd: g.gcd,
281
+ x: g.y.sub(b.div(a).mul(g.x)),
282
+ y: g.x
283
+ }
284
+ }
285
+
286
+ /**
287
+ * Verify share integrity
288
+ * @param {Object} share - Share to verify
289
+ * @returns {Boolean} True if share is valid
290
+ */
291
+ Shamir.verifyShare = function(share) {
292
+ try {
293
+ if (!share || typeof share !== 'object') {
294
+ return false
295
+ }
296
+
297
+ if (!share.id || !share.threshold || !share.shares || !share.bytes || typeof share.length !== 'number') {
298
+ return false
299
+ }
300
+
301
+ if (share.threshold < 2 || share.shares < share.threshold) {
302
+ return false
303
+ }
304
+
305
+ if (!Array.isArray(share.bytes) || share.bytes.length !== share.length) {
306
+ return false
307
+ }
308
+
309
+ // Verify each byte share
310
+ for (var i = 0; i < share.bytes.length; i++) {
311
+ var byteShare = share.bytes[i]
312
+ if (!byteShare.x || !byteShare.y) {
313
+ return false
314
+ }
315
+
316
+ if (byteShare.x < 1 || byteShare.x > share.shares) {
317
+ return false
318
+ }
319
+
320
+ // Verify y is valid hex
321
+ try {
322
+ var testHex = byteShare.y
323
+ if (!/^[0-9a-fA-F]+$/.test(testHex)) {
324
+ return false
325
+ }
326
+ new BN(testHex, 16)
327
+ } catch (e) {
328
+ return false
329
+ }
330
+ }
331
+
332
+ return true
333
+ } catch (e) {
334
+ return false
335
+ }
336
+ }
337
+
338
+ /**
339
+ * Generate test vectors for validation
340
+ * @returns {Object} Test data
341
+ */
342
+ Shamir.generateTestVectors = function() {
343
+ var secret = 'Hello, Bitcoin SV!'
344
+ var threshold = 3
345
+ var shares = 5
346
+
347
+ var splitShares = Shamir.split(secret, threshold, shares)
348
+ var reconstructed = Shamir.combine(splitShares.slice(0, threshold))
349
+
350
+ return {
351
+ secret: secret,
352
+ threshold: threshold,
353
+ totalShares: shares,
354
+ shares: splitShares,
355
+ reconstructed: reconstructed.toString('utf8'),
356
+ valid: reconstructed.toString('utf8') === secret
357
+ }
358
+ }
359
+
360
+ module.exports = Shamir