@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.
Files changed (61) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/primitives/Schnorr.js +92 -0
  3. package/dist/cjs/src/primitives/Schnorr.js.map +1 -0
  4. package/dist/cjs/src/primitives/index.js +3 -1
  5. package/dist/cjs/src/primitives/index.js.map +1 -1
  6. package/dist/cjs/src/totp/totp.js +1 -1
  7. package/dist/cjs/src/totp/totp.js.map +1 -1
  8. package/dist/cjs/src/transaction/Beef.js +292 -155
  9. package/dist/cjs/src/transaction/Beef.js.map +1 -1
  10. package/dist/cjs/src/transaction/BeefParty.js +46 -26
  11. package/dist/cjs/src/transaction/BeefParty.js.map +1 -1
  12. package/dist/cjs/src/transaction/BeefTx.js +31 -16
  13. package/dist/cjs/src/transaction/BeefTx.js.map +1 -1
  14. package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
  15. package/dist/cjs/src/transaction/Transaction.js +12 -6
  16. package/dist/cjs/src/transaction/Transaction.js.map +1 -1
  17. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  18. package/dist/esm/src/primitives/Schnorr.js +87 -0
  19. package/dist/esm/src/primitives/Schnorr.js.map +1 -0
  20. package/dist/esm/src/primitives/index.js +1 -0
  21. package/dist/esm/src/primitives/index.js.map +1 -1
  22. package/dist/esm/src/totp/totp.js +1 -1
  23. package/dist/esm/src/totp/totp.js.map +1 -1
  24. package/dist/esm/src/transaction/Beef.js +294 -157
  25. package/dist/esm/src/transaction/Beef.js.map +1 -1
  26. package/dist/esm/src/transaction/BeefParty.js +47 -27
  27. package/dist/esm/src/transaction/BeefParty.js.map +1 -1
  28. package/dist/esm/src/transaction/BeefTx.js +35 -20
  29. package/dist/esm/src/transaction/BeefTx.js.map +1 -1
  30. package/dist/esm/src/transaction/MerklePath.js.map +1 -1
  31. package/dist/esm/src/transaction/Transaction.js +12 -6
  32. package/dist/esm/src/transaction/Transaction.js.map +1 -1
  33. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  34. package/dist/types/src/primitives/Schnorr.d.ts +65 -0
  35. package/dist/types/src/primitives/Schnorr.d.ts.map +1 -0
  36. package/dist/types/src/primitives/index.d.ts +1 -0
  37. package/dist/types/src/primitives/index.d.ts.map +1 -1
  38. package/dist/types/src/transaction/Beef.d.ts +131 -90
  39. package/dist/types/src/transaction/Beef.d.ts.map +1 -1
  40. package/dist/types/src/transaction/BeefParty.d.ts +34 -23
  41. package/dist/types/src/transaction/BeefParty.d.ts.map +1 -1
  42. package/dist/types/src/transaction/BeefTx.d.ts +11 -6
  43. package/dist/types/src/transaction/BeefTx.d.ts.map +1 -1
  44. package/dist/types/src/transaction/MerklePath.d.ts.map +1 -1
  45. package/dist/types/src/transaction/Transaction.d.ts +8 -2
  46. package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
  47. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  48. package/dist/umd/bundle.js +1 -1
  49. package/docs/primitives.md +120 -9
  50. package/docs/transaction.md +141 -9
  51. package/package.json +1 -1
  52. package/src/primitives/Schnorr.ts +95 -0
  53. package/src/primitives/__tests/Schnorr.test.ts +272 -0
  54. package/src/primitives/index.ts +1 -0
  55. package/src/totp/totp.ts +1 -1
  56. package/src/transaction/Beef.ts +493 -378
  57. package/src/transaction/BeefParty.ts +71 -58
  58. package/src/transaction/BeefTx.ts +133 -143
  59. package/src/transaction/MerklePath.ts +11 -11
  60. package/src/transaction/Transaction.ts +42 -36
  61. package/src/transaction/__tests/Beef.test.ts +55 -10
@@ -8,15 +8,16 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
8
8
 
9
9
  | | | |
10
10
  | --- | --- | --- |
11
- | [BasePoint](#class-basepoint) | [Point](#class-point) | [SHA1HMAC](#class-sha1hmac) |
12
- | [BigNumber](#class-bignumber) | [PointInFiniteField](#class-pointinfinitefield) | [SHA256](#class-sha256) |
13
- | [Curve](#class-curve) | [Polynomial](#class-polynomial) | [SHA256HMAC](#class-sha256hmac) |
14
- | [DRBG](#class-drbg) | [PrivateKey](#class-privatekey) | [SHA512](#class-sha512) |
15
- | [JacobianPoint](#class-jacobianpoint) | [PublicKey](#class-publickey) | [SHA512HMAC](#class-sha512hmac) |
16
- | [K256](#class-k256) | [RIPEMD160](#class-ripemd160) | [Signature](#class-signature) |
17
- | [KeyShares](#class-keyshares) | [Reader](#class-reader) | [SymmetricKey](#class-symmetrickey) |
18
- | [Mersenne](#class-mersenne) | [ReductionContext](#class-reductioncontext) | [TransactionSignature](#class-transactionsignature) |
19
- | [MontgomoryMethod](#class-montgomorymethod) | [SHA1](#class-sha1) | [Writer](#class-writer) |
11
+ | [BasePoint](#class-basepoint) | [PointInFiniteField](#class-pointinfinitefield) | [SHA256HMAC](#class-sha256hmac) |
12
+ | [BigNumber](#class-bignumber) | [Polynomial](#class-polynomial) | [SHA512](#class-sha512) |
13
+ | [Curve](#class-curve) | [PrivateKey](#class-privatekey) | [SHA512HMAC](#class-sha512hmac) |
14
+ | [DRBG](#class-drbg) | [PublicKey](#class-publickey) | [Schnorr](#class-schnorr) |
15
+ | [JacobianPoint](#class-jacobianpoint) | [RIPEMD160](#class-ripemd160) | [Signature](#class-signature) |
16
+ | [K256](#class-k256) | [Reader](#class-reader) | [SymmetricKey](#class-symmetrickey) |
17
+ | [KeyShares](#class-keyshares) | [ReductionContext](#class-reductioncontext) | [TransactionSignature](#class-transactionsignature) |
18
+ | [Mersenne](#class-mersenne) | [SHA1](#class-sha1) | [Writer](#class-writer) |
19
+ | [MontgomoryMethod](#class-montgomorymethod) | [SHA1HMAC](#class-sha1hmac) | |
20
+ | [Point](#class-point) | [SHA256](#class-sha256) | |
20
21
 
21
22
  Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables)
22
23
 
@@ -7349,6 +7350,116 @@ public hasLowS(): boolean
7349
7350
 
7350
7351
  Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables)
7351
7352
 
7353
+ ---
7354
+ ### Class: Schnorr
7355
+
7356
+ Class representing the Schnorr Zero-Knowledge Proof (ZKP) protocol.
7357
+
7358
+ This class provides methods to generate and verify proofs that demonstrate knowledge of a secret without revealing it.
7359
+ Specifically, it allows one party to prove to another that they know the private key corresponding to a public key
7360
+ and have correctly computed a shared secret, without disclosing the private key itself.
7361
+
7362
+ The protocol involves two main methods:
7363
+ - `generateProof`: Generates a proof linking a public key `A` and a shared secret `S`, proving knowledge of the corresponding private key `a`.
7364
+ - `verifyProof`: Verifies the provided proof, ensuring its validity without revealing any secret information.
7365
+
7366
+ The class utilizes elliptic curve cryptography (ECC) and the SHA-256 hash function to compute challenges within the proof.
7367
+
7368
+ Example
7369
+
7370
+ ```typescript
7371
+ const schnorr = new Schnorr();
7372
+ const a = PrivateKey.fromRandom(); // Prover's private key
7373
+ const A = a.toPublicKey(); // Prover's public key
7374
+ const b = PrivateKey.fromRandom(); // Other party's private key
7375
+ const B = b.toPublicKey(); // Other party's public key
7376
+ const S = B.mul(a); // Shared secret
7377
+
7378
+ // Prover generates the proof
7379
+ const proof = schnorr.generateProof(a, A, B, S);
7380
+
7381
+ // Verifier verifies the proof
7382
+ const isValid = schnorr.verifyProof(A.point, B.point, S.point, proof);
7383
+ console.log(`Proof is valid: ${isValid}`);
7384
+ ```
7385
+ ```ts
7386
+ export default class Schnorr {
7387
+ constructor()
7388
+ generateProof(aArg: PrivateKey, AArg: PublicKey, BArg: PublicKey, S: Point): {
7389
+ R: Point;
7390
+ SPrime: Point;
7391
+ z: BigNumber;
7392
+ }
7393
+ verifyProof(A: Point, B: Point, S: Point, proof: {
7394
+ R: Point;
7395
+ SPrime: Point;
7396
+ z: BigNumber;
7397
+ }): boolean
7398
+ }
7399
+ ```
7400
+
7401
+ <details>
7402
+
7403
+ <summary>Class Schnorr Details</summary>
7404
+
7405
+ #### Method generateProof
7406
+
7407
+ Generates a proof that demonstrates the link between public key A and shared secret S
7408
+
7409
+ ```ts
7410
+ generateProof(aArg: PrivateKey, AArg: PublicKey, BArg: PublicKey, S: Point): {
7411
+ R: Point;
7412
+ SPrime: Point;
7413
+ z: BigNumber;
7414
+ }
7415
+ ```
7416
+
7417
+ Returns
7418
+
7419
+ Proof (R, S', z)
7420
+
7421
+ Argument Details
7422
+
7423
+ + **a**
7424
+ + Private key corresponding to public key A
7425
+ + **A**
7426
+ + Public key
7427
+ + **B**
7428
+ + Other party's public key
7429
+ + **S**
7430
+ + Shared secret
7431
+
7432
+ #### Method verifyProof
7433
+
7434
+ Verifies the proof of the link between public key A and shared secret S
7435
+
7436
+ ```ts
7437
+ verifyProof(A: Point, B: Point, S: Point, proof: {
7438
+ R: Point;
7439
+ SPrime: Point;
7440
+ z: BigNumber;
7441
+ }): boolean
7442
+ ```
7443
+
7444
+ Returns
7445
+
7446
+ True if the proof is valid, false otherwise
7447
+
7448
+ Argument Details
7449
+
7450
+ + **A**
7451
+ + Public key
7452
+ + **B**
7453
+ + Other party's public key
7454
+ + **S**
7455
+ + Shared secret
7456
+ + **proof**
7457
+ + Proof (R, S', z)
7458
+
7459
+ </details>
7460
+
7461
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables)
7462
+
7352
7463
  ---
7353
7464
  ## Functions
7354
7465
 
@@ -857,7 +857,7 @@ export default class BeefTx {
857
857
  _rawTx?: number[];
858
858
  _txid?: string;
859
859
  inputTxids: string[] = [];
860
- degree: number = 0;
860
+ isValid?: boolean = undefined;
861
861
  get bumpIndex(): number | undefined
862
862
  set bumpIndex(v: number | undefined)
863
863
  get hasProof(): boolean
@@ -888,6 +888,16 @@ Argument Details
888
888
  + **bumpIndex**
889
889
  + If transaction already has a proof in the beef to which it will be added.
890
890
 
891
+ #### Property isValid
892
+
893
+ true if `hasProof` or all inputs chain to `hasProof`.
894
+
895
+ Typically set by sorting transactions by proven dependency chains.
896
+
897
+ ```ts
898
+ isValid?: boolean = undefined
899
+ ```
900
+
891
901
  </details>
892
902
 
893
903
  Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables)
@@ -900,9 +910,13 @@ export class Beef {
900
910
  bumps: MerklePath[] = [];
901
911
  txs: BeefTx[] = [];
902
912
  version: BeefVersion = undefined;
913
+ atomicTxid: string | undefined = undefined;
903
914
  constructor(version?: BeefVersion)
904
915
  get magic(): number
905
916
  findTxid(txid: string): BeefTx | undefined
917
+ findBump(txid: string): MerklePath | undefined
918
+ findTransactionForSigning(txid: string): Transaction | undefined
919
+ findAtomicTransaction(txid: string): Transaction | undefined
906
920
  mergeBump(bump: MerklePath): number
907
921
  mergeRawTx(rawTx: number[], bumpIndex?: number): BeefTx
908
922
  mergeTransaction(tx: Transaction): BeefTx
@@ -917,9 +931,16 @@ export class Beef {
917
931
  static fromReader(br: Reader): Beef
918
932
  static fromBinary(bin: number[]): Beef
919
933
  static fromString(s: string, enc?: "hex" | "utf8" | "base64"): Beef
920
- sortTxs(): string[]
934
+ sortTxs(): {
935
+ missingInputs: string[];
936
+ notValid: string[];
937
+ valid: string[];
938
+ withMissingInputs: string[];
939
+ txidOnly: string[];
940
+ }
921
941
  clone(): Beef
922
942
  trimKnownTxids(knownTxids: string[])
943
+ getValidTxids(): string[]
923
944
  toLogString(): string
924
945
  }
925
946
  ```
@@ -938,6 +959,55 @@ Returns
938
959
 
939
960
  a shallow copy of this beef
940
961
 
962
+ #### Method findAtomicTransaction
963
+
964
+ Builds the proof tree rooted at a specific `Transaction`.
965
+
966
+ To succeed, the Beef must contain all the required transaction and merkle path data.
967
+
968
+ ```ts
969
+ findAtomicTransaction(txid: string): Transaction | undefined
970
+ ```
971
+
972
+ Returns
973
+
974
+ Transaction with input `SourceTransaction` and `MerklePath` populated from this Beef.
975
+
976
+ Argument Details
977
+
978
+ + **txid**
979
+ + The id of the target transaction.
980
+
981
+ #### Method findBump
982
+
983
+ ```ts
984
+ findBump(txid: string): MerklePath | undefined
985
+ ```
986
+
987
+ Returns
988
+
989
+ `MerklePath` with level zero hash equal to txid or undefined.
990
+
991
+ #### Method findTransactionForSigning
992
+
993
+ Finds a Transaction in this `Beef`
994
+ and adds any missing input SourceTransactions from this `Beef`.
995
+
996
+ The result is suitable for signing.
997
+
998
+ ```ts
999
+ findTransactionForSigning(txid: string): Transaction | undefined
1000
+ ```
1001
+
1002
+ Returns
1003
+
1004
+ Transaction with all available input `SourceTransaction`s from this Beef.
1005
+
1006
+ Argument Details
1007
+
1008
+ + **txid**
1009
+ + The id of the target transaction.
1010
+
941
1011
  #### Method findTxid
942
1012
 
943
1013
  ```ts
@@ -989,6 +1059,16 @@ Argument Details
989
1059
  + **enc**
990
1060
  + The encoding of the string value from which BEEF should be constructed
991
1061
 
1062
+ #### Method getValidTxids
1063
+
1064
+ ```ts
1065
+ getValidTxids(): string[]
1066
+ ```
1067
+
1068
+ Returns
1069
+
1070
+ array of transaction txids that either have a proof or whose inputs chain back to a proven transaction.
1071
+
992
1072
  #### Method isValid
993
1073
 
994
1074
  Sorts `txs` and checks structural validity of beef.
@@ -1074,15 +1154,26 @@ Argument Details
1074
1154
 
1075
1155
  #### Method sortTxs
1076
1156
 
1077
- Sort the `txs` by input txid dependency order.
1157
+ Sort the `txs` by input txid dependency order:
1158
+ - Oldest Tx Anchored by Path
1159
+ - Newer Txs depending on Older parents
1160
+ - Newest Tx
1161
+
1162
+ with proof (MerklePath) last, longest chain of dependencies first
1078
1163
 
1079
1164
  ```ts
1080
- sortTxs(): string[]
1165
+ sortTxs(): {
1166
+ missingInputs: string[];
1167
+ notValid: string[];
1168
+ valid: string[];
1169
+ withMissingInputs: string[];
1170
+ txidOnly: string[];
1171
+ }
1081
1172
  ```
1082
1173
 
1083
1174
  Returns
1084
1175
 
1085
- array of input txids of unproven transactions that aren't included in txs.
1176
+ `{ missingInputs, notValid, valid, withMissingInputs }`
1086
1177
 
1087
1178
  #### Method toBinary
1088
1179
 
@@ -1219,8 +1310,8 @@ export default class Transaction {
1219
1310
  id(enc: "hex"): string;
1220
1311
  id(enc?: "hex"): number[] | string
1221
1312
  async verify(chainTracker: ChainTracker | "scripts only" = defaultChainTracker(), feeModel?: FeeModel): Promise<boolean>
1222
- toBEEF(): number[]
1223
- toAtomicBEEF(): number[]
1313
+ toBEEF(allowPartial?: boolean): number[]
1314
+ toAtomicBEEF(allowPartial?: boolean): number[]
1224
1315
  }
1225
1316
  ```
1226
1317
 
@@ -1554,25 +1645,43 @@ and then the BEEF data containing only the subject transaction and its dependenc
1554
1645
  This format ensures that the BEEF structure is atomic and contains no unrelated transactions.
1555
1646
 
1556
1647
  ```ts
1557
- toAtomicBEEF(): number[]
1648
+ toAtomicBEEF(allowPartial?: boolean): number[]
1558
1649
  ```
1559
1650
 
1560
1651
  Returns
1561
1652
 
1562
1653
  - The serialized Atomic BEEF structure.
1563
1654
 
1655
+ Argument Details
1656
+
1657
+ + **allowPartial**
1658
+ + If true, error will not be thrown if there are any missing sourceTransactions.
1659
+
1660
+ Throws
1661
+
1662
+ Error if there are any missing sourceTransactions unless `allowPartial` is true.
1663
+
1564
1664
  #### Method toBEEF
1565
1665
 
1566
1666
  Serializes this transaction, together with its inputs and the respective merkle proofs, into the BEEF (BRC-62) format. This enables efficient verification of its compliance with the rules of SPV.
1567
1667
 
1568
1668
  ```ts
1569
- toBEEF(): number[]
1669
+ toBEEF(allowPartial?: boolean): number[]
1570
1670
  ```
1571
1671
 
1572
1672
  Returns
1573
1673
 
1574
1674
  The serialized BEEF structure
1575
1675
 
1676
+ Argument Details
1677
+
1678
+ + **allowPartial**
1679
+ + If true, error will not be thrown if there are any missing sourceTransactions.
1680
+
1681
+ Throws
1682
+
1683
+ Error if there are any missing sourceTransactions unless `allowPartial` is true.
1684
+
1576
1685
  #### Method toBinary
1577
1686
 
1578
1687
  Converts the transaction to a binary array format.
@@ -1716,6 +1825,7 @@ export class BeefParty extends Beef {
1716
1825
  getKnownTxidsForParty(party: string): string[]
1717
1826
  getTrimmedBeefForParty(party: string): Beef
1718
1827
  addKnownTxidsForParty(party: string, knownTxids: string[])
1828
+ mergeBeefFromParty(party: string, beef: number[] | Beef)
1719
1829
  }
1720
1830
  ```
1721
1831
 
@@ -1794,6 +1904,18 @@ Returns
1794
1904
 
1795
1905
  `true` if `party` has already beed added to this `BeefParty`.
1796
1906
 
1907
+ #### Method mergeBeefFromParty
1908
+
1909
+ Merge a `beef` received from a specific `party`.
1910
+
1911
+ Updates this `BeefParty` to track all the txids
1912
+ corresponding to transactions for which `party`
1913
+ has raw transaction and validity proof data.
1914
+
1915
+ ```ts
1916
+ mergeBeefFromParty(party: string, beef: number[] | Beef)
1917
+ ```
1918
+
1797
1919
  </details>
1798
1920
 
1799
1921
  Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables)
@@ -1925,6 +2047,7 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
1925
2047
 
1926
2048
  | |
1927
2049
  | --- |
2050
+ | [ATOMIC_BEEF](#variable-atomic_beef) |
1928
2051
  | [BEEF_MAGIC](#variable-beef_magic) |
1929
2052
  | [BEEF_MAGIC_TXID_ONLY_EXTENSION](#variable-beef_magic_txid_only_extension) |
1930
2053
  | [BEEF_MAGIC_V2](#variable-beef_magic_v2) |
@@ -1960,3 +2083,12 @@ BEEF_MAGIC_TXID_ONLY_EXTENSION = 4022206465
1960
2083
  Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables)
1961
2084
 
1962
2085
  ---
2086
+ ### Variable: ATOMIC_BEEF
2087
+
2088
+ ```ts
2089
+ ATOMIC_BEEF = 16843009
2090
+ ```
2091
+
2092
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables)
2093
+
2094
+ ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsv/sdk",
3
- "version": "1.1.29",
3
+ "version": "1.1.32",
4
4
  "type": "module",
5
5
  "description": "BSV Blockchain Software Development Kit",
6
6
  "main": "dist/cjs/mod.js",
@@ -0,0 +1,95 @@
1
+ import BigNumber from './BigNumber.js'
2
+ import Curve from './Curve.js'
3
+ import Point from './Point.js'
4
+ import { sha256 } from './Hash.js'
5
+ import { PrivateKey, PublicKey } from './index.js'
6
+
7
+ /**
8
+ * Class representing the Schnorr Zero-Knowledge Proof (ZKP) protocol.
9
+ *
10
+ * This class provides methods to generate and verify proofs that demonstrate knowledge of a secret without revealing it.
11
+ * Specifically, it allows one party to prove to another that they know the private key corresponding to a public key
12
+ * and have correctly computed a shared secret, without disclosing the private key itself.
13
+ *
14
+ * The protocol involves two main methods:
15
+ * - `generateProof`: Generates a proof linking a public key `A` and a shared secret `S`, proving knowledge of the corresponding private key `a`.
16
+ * - `verifyProof`: Verifies the provided proof, ensuring its validity without revealing any secret information.
17
+ *
18
+ * The class utilizes elliptic curve cryptography (ECC) and the SHA-256 hash function to compute challenges within the proof.
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const schnorr = new Schnorr();
23
+ * const a = PrivateKey.fromRandom(); // Prover's private key
24
+ * const A = a.toPublicKey(); // Prover's public key
25
+ * const b = PrivateKey.fromRandom(); // Other party's private key
26
+ * const B = b.toPublicKey(); // Other party's public key
27
+ * const S = B.mul(a); // Shared secret
28
+ *
29
+ * // Prover generates the proof
30
+ * const proof = schnorr.generateProof(a, A, B, S);
31
+ *
32
+ * // Verifier verifies the proof
33
+ * const isValid = schnorr.verifyProof(A.point, B.point, S.point, proof);
34
+ * console.log(`Proof is valid: ${isValid}`);
35
+ * ```
36
+ */
37
+ export default class Schnorr {
38
+ private readonly curve: Curve
39
+
40
+ constructor () {
41
+ this.curve = new Curve()
42
+ }
43
+
44
+ /**
45
+ * Generates a proof that demonstrates the link between public key A and shared secret S
46
+ * @param a Private key corresponding to public key A
47
+ * @param A Public key
48
+ * @param B Other party's public key
49
+ * @param S Shared secret
50
+ * @returns Proof (R, S', z)
51
+ */
52
+ generateProof (aArg: PrivateKey, AArg: PublicKey, BArg: PublicKey, S: Point): { R: Point, SPrime: Point, z: BigNumber } {
53
+ const r = PrivateKey.fromRandom()
54
+ const R = r.toPublicKey()
55
+ const SPrime = BArg.mul(r)
56
+ const e = this.computeChallenge(AArg, BArg, S, SPrime, R)
57
+ const z = r.add(e.mul(aArg)).umod(this.curve.n)
58
+ return { R, SPrime, z }
59
+ }
60
+
61
+ /**
62
+ * Verifies the proof of the link between public key A and shared secret S
63
+ * @param A Public key
64
+ * @param B Other party's public key
65
+ * @param S Shared secret
66
+ * @param proof Proof (R, S', z)
67
+ * @returns True if the proof is valid, false otherwise
68
+ */
69
+ verifyProof (A: Point, B: Point, S: Point, proof: { R: Point, SPrime: Point, z: BigNumber }): boolean {
70
+ const { R, SPrime, z } = proof
71
+ const e = this.computeChallenge(A, B, S, SPrime, R)
72
+
73
+ // Check zG = R + eA
74
+ const zG = this.curve.g.mul(z)
75
+ const RpluseA = R.add(A.mul(e))
76
+ if (!zG.eq(RpluseA)) {
77
+ return false
78
+ }
79
+
80
+ // Check zB = S' + eS
81
+ const zB = B.mul(z)
82
+ const SprimeeS = SPrime.add(S.mul(e))
83
+ if (!zB.eq(SprimeeS)) {
84
+ return false
85
+ }
86
+
87
+ return true
88
+ }
89
+
90
+ private computeChallenge (A: Point, B: Point, S: Point, SPrime: Point, R: Point): BigNumber {
91
+ const message = [...A.encode(true), ...B.encode(true), ...S.encode(true), ...SPrime.encode(true), ...R.encode(true)] as number[]
92
+ const hash = sha256(message)
93
+ return new BigNumber(hash).umod(this.curve.n)
94
+ }
95
+ }