Compare commits

..

753 Commits

Author SHA1 Message Date
Ed Hennis
b8fe98646a Merge branch 'ximinez/lending-number-simple' into ximinez/lending-number-enabled 2026-01-08 22:46:13 -04:00
Ed Hennis
7782785cc4 fixup! fixup! Review feedback from @shawnxie999 and @gregtatcam 2026-01-08 21:41:02 -05:00
Ed Hennis
04a98fb032 fixup! Review feedback from @shawnxie999 and @gregtatcam 2026-01-08 21:37:32 -05:00
Ed Hennis
c012f83e80 Merge branch 'ximinez/lending-number-simple' into ximinez/lending-number-enabled 2026-01-08 21:58:04 -04:00
Ed Hennis
4605bbfb6f Review feedback from @shawnxie999 and @gregtatcam
- Remove redundant "else" because of early return.
- Add a concept "Integral64" to use in the template parameter for
  normalizeToRange.
- Add documentation to STTakesAsset, associateAsset, and add explanation
  for how `STNumber` uses it.
- Assert that `numberToJson` is always outside of a Transaction context.
- Remove copy of `InitialFibSeqPct` and the assert in
  `Number::operator*=` that prompted me to add it.
- Add amendment gating to `STAmount::operator=`
2026-01-08 20:53:26 -05:00
Ed Hennis
a428a753ef Merge branch 'ximinez/lending-XLS-66-ongoing' into ximinez/lending-number-simple 2026-01-08 21:37:08 -04:00
Gregory Tsipenyuk
5dde3e0242 Check if a withdrawal amount exceeds any applicable receiving limit. (#6117)
- Check the trust line limit is not exceeded for a withdraw to a third party Destination account.
2026-01-09 00:44:13 +00:00
Ed Hennis
9b4decf53f Merge branch 'ximinez/lending-number-simple' into ximinez/lending-number-enabled 2026-01-08 20:14:16 -04:00
Ed Hennis
b11a7faf01 Merge branch 'ximinez/lending-XLS-66-ongoing' into ximinez/lending-number-simple 2026-01-08 20:13:09 -04:00
Vito Tumas
0dabf4eaf8 refactor: Rename raw state to theoretical state (#6187) 2026-01-09 00:11:02 +00:00
Ed Hennis
40cda31b44 Merge branch 'ximinez/lending-number-simple' into ximinez/lending-number-enabled 2026-01-08 19:41:09 -04:00
Ed Hennis
4303e67bea Merge branch 'ximinez/lending-XLS-66-ongoing' into ximinez/lending-number-simple 2026-01-08 19:40:03 -04:00
Vito Tumas
e763dc8a5e Fix bugs: frozen pseudo-account, and FLC cutoff (#6170)
- Fixes LoanManage tfBAD_LEDGER case by capping the amount of FLC to use to cover a loss at the amount of cover available.
- Check if the Vault pseudo-account is frozen in LoanBrokerSet
2026-01-08 22:12:29 +00:00
Ed Hennis
70c45af9f8 Merge branch 'ximinez/lending-number-simple' into ximinez/lending-number-enabled 2026-01-08 17:16:18 -04:00
Ed Hennis
7c341917a5 Merge branch 'ximinez/lending-XLS-66-ongoing' into ximinez/lending-number-simple 2026-01-08 17:15:19 -04:00
Ed Hennis
da323481e0 Merge branch 'ximinez/lending-number-simple' into ximinez/lending-number-enabled 2026-01-08 17:12:02 -04:00
Ed Hennis
81ae6f1ca9 Merge branch 'ximinez/lending-XLS-66-2' into ximinez/lending-XLS-66-ongoing 2026-01-08 17:11:00 -04:00
Ed Hennis
c2d273f9a2 Merge branch 'ximinez/develop-nolending' into ximinez/lending-XLS-66-2 2026-01-08 17:10:55 -04:00
Ed Hennis
0136bf89bd Merge branch 'ximinez/lending-XLS-66-ongoing' into ximinez/lending-number-simple 2026-01-08 17:10:49 -04:00
Ed Hennis
8ad4058a36 Fix typo 2026-01-08 16:10:14 -05:00
Ed Hennis
000b9139c7 Merge branch 'develop' into ximinez/develop-nolending 2026-01-08 17:07:36 -04:00
Ed Hennis
579311fffa Merge branch 'ximinez/lending-XLS-66-2' into ximinez/lending-XLS-66-ongoing 2026-01-08 17:05:47 -04:00
Ed Hennis
db0b80e5b1 Merge branch 'ximinez/develop-nolending' into ximinez/lending-XLS-66-2 2026-01-08 16:04:23 -05:00
Bart
e1d97bea12 ci: Use updated prepare-runner in actions and worfklows (#6188)
This change updates the XRPLF pre-commit workflow and prepare-runner action to their latest versions. For naming consistency the prepare-runner action changed the disable_ccache variable into enable_ccache, which matches our naming.
2026-01-08 15:02:59 -05:00
Ed Hennis
7cfb047344 Merge branch 'ximinez/lending-number-simple' into ximinez/lending-number-enabled 2026-01-08 13:21:07 -04:00
Ed Hennis
9526a30dbc Merge branch 'ximinez/lending-XLS-66-ongoing' into ximinez/lending-number-simple 2026-01-08 13:20:05 -04:00
Ed Hennis
2feb6b9a65 Merge branch 'ximinez/lending-number-simple' into ximinez/lending-number-enabled 2026-01-08 13:13:19 -04:00
Ed Hennis
1a192fea07 Merge branch 'ximinez/lending-XLS-66-2' into ximinez/lending-XLS-66-ongoing 2026-01-08 13:12:20 -04:00
Ed Hennis
5a95a7426e Merge branch 'ximinez/develop-nolending' into ximinez/lending-XLS-66-2 2026-01-08 13:12:16 -04:00
Ed Hennis
9c2c9afc9f Merge remote-tracking branch 'XRPLF/develop' into ximinez/develop-nolending
* XRPLF/develop:
  refactor: Fix typos, enable cspell pre-commit (5719)
  fix: Reorder Batch Preflight Errors (6176)
  refactor: Remove unused credentials signature hash prefix (6186)
  refactor: Fix spelling issues in all variables/functions (6184)
  refactor: Fix spelling issues in private/local variables and functions (6182)
  refactor: Fix typos in comments, configure cspell (6164)
  ci: Move variable into right place (6179)
  ci: Use ccache to cache build objects for speeding up building (6104)
2026-01-08 12:11:19 -05:00
Mayukha Vadari
53aa5ca903 refactor: Fix typos, enable cspell pre-commit (#5719)
This change fixes the last of the spelling issues, and enables the pre-commit (and CI) check for spelling. There are no functionality changes, but it does rename some enum values.
2026-01-08 10:34:49 -05:00
Denis Angell
510c0d82e9 fix: Reorder Batch Preflight Errors (#6176)
This change fixes https://github.com/XRPLF/rippled/issues/6058.
2026-01-08 13:48:39 +00:00
Mayukha Vadari
17565d21d4 refactor: Remove unused credentials signature hash prefix (#6186)
This change removes the unused credentials signature hash prefix from `HashPrefix.h`.
2026-01-08 08:29:59 -05:00
Ed Hennis
7265804170 Point back to the class documentation in mantissa() and exponent() 2026-01-07 19:43:07 -05:00
Ed Hennis
a06de68ce4 Bring back Number::Guard::doRound* functions
- Based on feedback from @shawnxie999.
2026-01-07 18:32:18 -05:00
Mayukha Vadari
07ff532d30 refactor: Fix spelling issues in all variables/functions (#6184)
This change fixes many typos in comments, variables, and public functions. There is no functionality change.
2026-01-07 21:30:35 +00:00
Ed Hennis
c88dd55d07 Add documentation and static_asserts for range
* Make `maxRep` public.
* Document why template normalize takes min/max params.
* Add a check to normalizeToRange to ensure there are no signed/unsigned
  conversion issues.
* static_assert that maxRep is >= maxMPTokenAmount and INITIAL_XRP at
  their definition points. If something ever changes so that it's not,
  we'll know immediately.
2026-01-07 14:47:52 -05:00
Mayukha Vadari
2c37ef7762 refactor: Fix spelling issues in private/local variables and functions (#6182)
This change fixes several typos in private/local variables and private functions. There is no functionality change.
2026-01-07 14:26:14 -05:00
Mayukha Vadari
3c9f5b6252 refactor: Fix typos in comments, configure cspell (#6164)
This change sets up a `cspell `configuration and fixes lots of typos in comments. There are no other code changes.
2026-01-07 12:10:19 -05:00
Bart
f80059e467 ci: Move variable into right place (#6179)
This change moves the `enable_ccache` variable in the `on-trigger.yml` file to the correct location.
2026-01-07 06:07:53 -05:00
Bart
d734c8dddd ci: Use ccache to cache build objects for speeding up building (#6104)
Right now, each pipeline invocation builds the source code from scratch. Although compiled Conan dependencies are cached in a remote server, the source build objects are not. We are able to further speed up our builds by leveraging `ccache`. This change enables caching of build objects using `ccache` on Linux, macOS, and Windows.
2026-01-07 01:34:21 +00:00
Ed Hennis
41f53f67f6 Merge branch 'ximinez/lending-number-simple' into ximinez/lending-number-enabled 2026-01-06 14:22:27 -05:00
Ed Hennis
c5c89c28a7 Merge branch 'ximinez/lending-XLS-66-ongoing' into ximinez/lending-number-simple 2026-01-06 14:21:22 -05:00
Ed Hennis
4f169ff71d Merge branch 'ximinez/lending-number-simple' into ximinez/lending-number-enabled 2026-01-06 14:19:52 -05:00
Ed Hennis
48c1c56f0c Merge branch 'ximinez/lending-XLS-66-2' into ximinez/lending-XLS-66-ongoing 2026-01-06 14:18:36 -05:00
Ed Hennis
9159969f5e Merge branch 'ximinez/develop-nolending' into ximinez/lending-XLS-66-2 2026-01-06 14:18:32 -05:00
Ed Hennis
fcc75cfc01 Merge remote-tracking branch 'XRPLF/develop' into ximinez/develop-nolending
* XRPLF/develop:
  test: add more tests for `ledger_entry` RPC (5858)
  refactor: Rename `rippled.cfg` to `xrpld.cfg` (6098)
  Revert "chore: Pin ruamel.yaml<0.19 in pre-commit-hooks (6166)" (6167)
  chore: Pin ruamel.yaml<0.19 in pre-commit-hooks (6166)
  fix: Remove cryptographic libs from libxrpl Conan package (6163)
2026-01-06 14:17:57 -05:00
Ed Hennis
fa6047f05d Merge branch 'ximinez/lending-XLS-66-ongoing' into ximinez/lending-number-simple 2026-01-06 14:01:41 -05:00
Vito Tumas
76272ffd0f Add minimum grace period validation (#6133) 2026-01-06 11:30:26 -05:00
Ed Hennis
6303dd5314 fixup! Document the Number mantissa range switching 2026-01-06 11:17:00 -05:00
Ed Hennis
16ab78d3df Document the Number mantissa range switching
- Prompted by review feedback from @gregtatcam.
- Should be pretty thorough.
- Tweaked how the MantissaRange class is instantiated, and added
  a couple more static_asserts.
2026-01-05 20:16:53 -05:00
Mayukha Vadari
44d21b8f6d test: add more tests for ledger_entry RPC (#5858)
This change adds some basic tests for all the `ledger_entry` helper functions, so each ledger entry type is covered. There are further some minor refactors in `parseAMM` to provide better error messages. Finally, to improve readability, alphabetization was applied in the helper functions.
2026-01-05 10:54:24 -05:00
Bart
3d1b3a49b3 refactor: Rename rippled.cfg to xrpld.cfg (#6098)
This change renames all occurrences of `rippled.cfg` to `xrpld.cfg`. It also provides a script to allow developers to replicate the changes in their local branch or fork to avoid conflicts. For the time being it maintains support for `rippled.cfg` as config file, if `xrpld.cfg` does not exist.
2026-01-05 14:55:12 +00:00
Ayaz Salikhov
0b87a26f04 Revert "chore: Pin ruamel.yaml<0.19 in pre-commit-hooks (#6166)" (#6167)
This reverts commit 0f23ad820c.
2026-01-05 14:01:14 +00:00
Ayaz Salikhov
0f23ad820c chore: Pin ruamel.yaml<0.19 in pre-commit-hooks (#6166)
See https://github.com/pre-commit/pre-commit-hooks/issues/1229 for more details.
2026-01-02 11:53:33 -05:00
Michael Legleux
b7139da4d0 fix: Remove cryptographic libs from libxrpl Conan package (#6163)
* fix: rm crypto libs and fix protobuf path

* update/rm comments
2025-12-23 16:38:35 -08:00
Ed Hennis
35a296d9a2 Merge branch 'ximinez/lending-XLS-66-2' into ximinez/lending-XLS-66-ongoing 2025-12-23 19:27:57 -05:00
Ed Hennis
b659cae66c Merge branch 'ximinez/develop-nolending' into ximinez/lending-XLS-66-2 2025-12-23 19:27:53 -05:00
Ed Hennis
82e36e69ad Merge branch 'ximinez/lending-number-simple' into ximinez/lending-number-enabled 2025-12-22 17:52:03 -05:00
Ed Hennis
381944e223 Merge branch 'develop' into ximinez/develop-nolending 2025-12-22 17:51:55 -05:00
Ed Hennis
59cafb0172 Merge branch 'ximinez/lending-XLS-66-ongoing' into ximinez/lending-number-simple 2025-12-22 17:39:34 -05:00
Ed Hennis
c81b26b09e Add a few minor changes (#6158)
- Updates or fixes a couple of things I noticed while reviewing changes
  to the spec.
- Rename sfPreviousPaymentDate to sfPreviousPaymentDueDate.
- Make the vault asset cap check added in #6124 a little more robust:
  1. Check in preflight if the vault is _already_ over the limit.
  2. Prevent overflow when checking with the loan value. (Subtract
     instead of adding, in case the values are near maxint. Both return
     the same result. Also add a unit test so each case is covered.
2025-12-22 17:38:39 -05:00
Bart
40198d9792 ci: Remove superfluous build directory creation (#6159)
This change modifies the build directory structure from `build/build/xxx` or `.build/build/xxx` to just `build/xxx`. Namely, the `conanfile.py` has the CMake generators build directory hardcoded to `build/generators`. We may as well leverage the top-level build directory without introducing another layer of directory nesting.
2025-12-22 16:30:23 -05:00
Gregory Tsipenyuk
c91b9a0223 fix: Enable LP Deposits when the broker is the asset issuer (#6119)
* Replace accountHolds with accountSpendable when checking
for account funds in VaultDeposit and LoanBrokerCoverDeposit
2025-12-19 21:51:45 +00:00
Ed Hennis
1cec46a007 Merge branch 'ximinez/lending-number-simple' into ximinez/lending-number-enabled 2025-12-19 14:09:00 -05:00
Ed Hennis
96a9800114 Merge branch 'ximinez/lending-XLS-66-ongoing' into ximinez/lending-number-simple 2025-12-19 14:08:00 -05:00
Ed Hennis
a38db36a68 Merge branch 'ximinez/lending-XLS-66-2' into ximinez/lending-XLS-66-ongoing 2025-12-19 13:22:18 -05:00
Ed Hennis
0e24d9d9b1 Merge branch 'ximinez/develop-nolending' into ximinez/lending-XLS-66-2 2025-12-19 13:22:14 -05:00
Ed Hennis
f9471521ce Merge branch 'ximinez/lending-number-simple' into ximinez/lending-number-enabled 2025-12-18 20:00:48 -05:00
Ed Hennis
42bb1f1673 Merge branch 'develop' into ximinez/develop-nolending 2025-12-18 20:00:39 -05:00
Ed Hennis
77944a6b2e Merge remote-tracking branch 'XRPLF/ximinez/lending-XLS-66-ongoing' into ximinez/lending-number-simple
* XRPLF/ximinez/lending-XLS-66-ongoing:
  Fix Overpayment ValueChange calculation in Lending Protocol (6114)
  Ensure vault asset cap is not exceeded (6124)
  Disallow pseudo accounts to be Destination for LoanBrokerCoverWithdraw (6106)
  Check permissions in LoanSet and LoanPay (6108)
  Fix some minor bugs in Lending Protocol (6101)
  Fix LoanBrokerSet debtMaximum limits (6116)
2025-12-18 19:49:32 -05:00
Ed Hennis
565e62fefb Merge branch 'ximinez/lending-XLS-66-ongoing' into ximinez/lending-number-simple 2025-12-18 19:40:11 -05:00
Vito Tumas
b9aa354782 Fix Overpayment ValueChange calculation in Lending Protocol (#6114)
- Adds loan state to LoanProperties.
- Cleans up computeLoanProperties.
- Fixes missing management fee from overpayment.
2025-12-19 00:14:28 +00:00
Bart
f059f0beda Set version to 3.2.0-b0 (#6153) 2025-12-17 18:21:01 -05:00
Vito Tumas
28fd66097b Ensure vault asset cap is not exceeded (#6124) 2025-12-17 22:38:10 +00:00
Jingchen
14790724af Disallow pseudo accounts to be Destination for LoanBrokerCoverWithdraw (#6106) 2025-12-17 16:34:29 +00:00
Jingchen
0aa4eed0f7 Check permissions in LoanSet and LoanPay (#6108) 2025-12-17 04:46:51 +00:00
Vito Tumas
3971411924 Fix some minor bugs in Lending Protocol (#6101)
- add nodiscard to unimpairLoan, and check result in LoanPay
- add a check to verify that issuer exists
- improve LoanManage error code for dust amounts
2025-12-17 01:30:41 +00:00
Vito Tumas
40c29bbfd6 Fix LoanBrokerSet debtMaximum limits (#6116) 2025-12-16 13:19:27 -05:00
Mayukha Vadari
41c1be2bac refactor: remove Json::Object and related files/classes (#5894)
`Json::Object` and related objects are not used at all, so this change removes `include/xrpl/json/Object.h` and all downstream files. There are a number of minor downstream changes as well.

Full list of deleted classes and functions:
* `Json::Collections`
* `Json::Object`
* `Json::Array`
* `Json::WriterObject`
* `Json::setArray`
* `Json::addObject`
* `Json::appendArray`
* `Json::appendObject`

The last helper function, `copyFrom`, seemed a bit more complex and was actually used in a few places, so it was moved to `LedgerToJson.h` instead of deleting it.
2025-12-15 13:40:08 -05:00
Ed Hennis
5ff1d7df76 Merge branch 'ximinez/lending-number-simple' into ximinez/lending-number-enabled 2025-12-12 21:16:40 -05:00
Ed Hennis
451b47484c Merge branch 'ximinez/lending-XLS-66-ongoing' into ximinez/lending-number-simple 2025-12-12 21:15:48 -05:00
Ed Hennis
f7a5f35d0e Merge branch 'ximinez/lending-XLS-66-2' into ximinez/lending-XLS-66-ongoing 2025-12-12 20:49:38 -05:00
Ed Hennis
d7c71bffd8 Merge branch 'ximinez/develop-nolending' into ximinez/lending-XLS-66-2 2025-12-12 20:49:34 -05:00
Ed Hennis
1a2cd2781e Merge branch 'ximinez/lending-number-simple' into ximinez/lending-number-enabled 2025-12-12 20:40:06 -05:00
Ed Hennis
db11d27e49 Merge branch 'develop' into ximinez/develop-nolending 2025-12-12 20:39:59 -05:00
Ed Hennis
71a81792ec Merge branch 'ximinez/lending-XLS-66-ongoing' into ximinez/lending-number-simple 2025-12-12 20:34:37 -05:00
Ed Hennis
3e9fc4dea7 Fix test errors 2025-12-12 19:49:25 -05:00
Bart
f816ffa55f ci: Update shared actions (#6147)
The latest update to `cleanup-workspace`, `get-nproc`, and `prepare-runner` moved the action to the repository root directory, and also includes some ccache changes. In response, this change updates the various shared actions to the latest commit hash.
2025-12-12 19:47:34 +00:00
Ed Hennis
3c871d2723 Number: Change LendingProtocol feature and dependencies to supported 2025-12-12 13:23:29 -05:00
liuyueyangxmu
cf748702af chore: Fix some typos in comments (#6082) 2025-12-12 11:06:17 -05:00
Ed Hennis
d1d74c89f2 Update rippled to xrpl 2025-12-11 19:45:43 -05:00
Ed Hennis
0f0e0bbc0c Merge remote-tracking branch 'XRPLF/ximinez/lending-XLS-66-ongoing' into ximinez/lending-number-simple
* XRPLF/ximinez/lending-XLS-66-ongoing:
  Update rippled to xrpl
  Change some instances of View info() to header()
  Update rippled to xrpl
  refactor: Rename `ripple` namespace to `xrpl` (5982)
  refactor: Move JobQueue and related classes into xrpl.core module (6121)
  refactor: Rename `rippled` binary to `xrpld` (5983)
  refactor: rename info() to header() (6138)
  refactor: rename `LedgerInfo` to `LedgerHeader` (6136)
  refactor: clean up `RPCHelpers` (5684)
  chore: Fix docs readme and cmake (6122)
  chore: Clean up .gitignore and .gitattributes (6001)
  chore: Use updated secp256k1 recipe (6118)
2025-12-11 19:43:27 -05:00
Ed Hennis
cf15e6876f Update rippled to xrpl 2025-12-11 19:05:11 -05:00
Ed Hennis
0f9078c5c5 Merge remote-tracking branch 'XRPLF/ximinez/lending-XLS-66-2' into ximinez/lending-XLS-66-ongoing
* XRPLF/ximinez/lending-XLS-66-2:
  Change some instances of View info() to header()
  Update rippled to xrpl
  refactor: Rename `ripple` namespace to `xrpl` (5982)
  refactor: Move JobQueue and related classes into xrpl.core module (6121)
  refactor: Rename `rippled` binary to `xrpld` (5983)
  refactor: rename info() to header() (6138)
  refactor: rename `LedgerInfo` to `LedgerHeader` (6136)
  refactor: clean up `RPCHelpers` (5684)
  chore: Fix docs readme and cmake (6122)
  chore: Clean up .gitignore and .gitattributes (6001)
  chore: Use updated secp256k1 recipe (6118)
2025-12-11 18:56:29 -05:00
Ed Hennis
416e12a1a4 Change some instances of View info() to header() 2025-12-11 18:52:04 -05:00
Ed Hennis
5eec3305c1 Update rippled to xrpl 2025-12-11 18:29:09 -05:00
Ed Hennis
629f3f50d7 Merge remote-tracking branch 'XRPLF/ximinez/develop-nolending' into ximinez/lending-XLS-66-2
* XRPLF/ximinez/develop-nolending:
  refactor: Rename `ripple` namespace to `xrpl` (5982)
  refactor: Move JobQueue and related classes into xrpl.core module (6121)
  refactor: Rename `rippled` binary to `xrpld` (5983)
  refactor: rename info() to header() (6138)
  refactor: rename `LedgerInfo` to `LedgerHeader` (6136)
  refactor: clean up `RPCHelpers` (5684)
  chore: Fix docs readme and cmake (6122)
  chore: Clean up .gitignore and .gitattributes (6001)
  chore: Use updated secp256k1 recipe (6118)
2025-12-11 16:45:47 -05:00
Ed Hennis
ca9828f7ac Merge remote-tracking branch 'XRPLF/develop' into ximinez/develop-nolending
* XRPLF/develop:
  refactor: Rename `ripple` namespace to `xrpl` (5982)
  refactor: Move JobQueue and related classes into xrpl.core module (6121)
  refactor: Rename `rippled` binary to `xrpld` (5983)
  refactor: rename info() to header() (6138)
  refactor: rename `LedgerInfo` to `LedgerHeader` (6136)
  refactor: clean up `RPCHelpers` (5684)
  chore: Fix docs readme and cmake (6122)
  chore: Clean up .gitignore and .gitattributes (6001)
  chore: Use updated secp256k1 recipe (6118)
2025-12-11 16:27:36 -05:00
Bart
1eb0fdac65 refactor: Rename ripple namespace to xrpl (#5982)
This change renames all occurrences of `namespace ripple` and `ripple::` to `namespace xrpl` and `xrpl::`, respectively, as well as the names of test suites. It also provides a script to allow developers to replicate the changes in their local branch or fork to avoid conflicts.
2025-12-11 16:51:49 +00:00
Pratik Mankawde
496efb71ca refactor: Move JobQueue and related classes into xrpl.core module (#6121) 2025-12-11 10:30:54 -05:00
Bart
9eb84a561e refactor: Rename rippled binary to xrpld (#5983)
Per [XLS-0095](https://xls.xrpl.org/xls/XLS-0095-rename-rippled-to-xrpld.html), we are taking steps to rename ripple(d) to xrpl(d).

This change modifies the binary name from `rippled` to `xrpld`, and creates a symlink named `rippled` that points to the `xrpld` binary.

Note that https://github.com/XRPLF/rippled/pull/5975 renamed any references to `rippled` in the CMake files and their contents, but explicitly maintained the `rippled` binary name by adding an exception. This change now undoes this exception and adds an explicit symlink instead.
2025-12-11 13:54:23 +00:00
Ed Hennis
40bfe3f0ef Refactor static normalize
- Use a single worker function that does all the work and explicit
  template instantiation for the class function. If this gives me any
  more trouble, I'm just going to move normalize into the header, but
  I was hoping to avoid that.
2025-12-10 17:16:59 -05:00
Mayukha Vadari
62efecbfb1 refactor: rename info() to header() (#6138)
This change renames all the `info()` functions to `header()`, since they return `LedgerHeader` structs. It also renames the underlying variables from `info_` to `header_`.
2025-12-10 16:04:37 -05:00
Mayukha Vadari
bff5954acf refactor: rename LedgerInfo to LedgerHeader (#6136)
This PR renames `LedgerInfo` to `LedgerHeader`. Namely, `LedgerInfo` was already an alias for `LedgerHeader`, and the comments next to the alias suggested that it would make sense to rename it, since that makes it clearer what it is.
2025-12-10 19:12:14 +00:00
Mayukha Vadari
42a432c5dc refactor: clean up RPCHelpers (#5684)
This PR cleans up `RPCHelpers.h` and `RPCHelpers.cpp`. It splits out all the fetch-ledger functions to a new set of files, `RPCLedgerHelpers.h`/`RPCLedgerHelpers.cpp`, and moves the general-API functions to `ApiVersion.h`. There is no functionality change.
2025-12-10 18:43:02 +00:00
Ed Hennis
aecd7ab4b1 Handle the edge case of constructing a Number from int64_t::min() 2025-12-09 20:15:39 -05:00
Ed Hennis
a035c478e7 Fix formatting 2025-12-09 18:41:16 -05:00
Ed Hennis
73b68b6150 Enforce LoanBroker values keep precision when rounded to the asset type
- Uncovered by associateAsset causing a test value to get rounded,
  causing tests which check that value to fail.
2025-12-09 18:38:22 -05:00
Ed Hennis
885aeb7ada Update LendingHelper tests with more precise values
- Fixes broken tests
2025-12-09 13:57:23 -05:00
Ed Hennis
692070dbf1 Add semi-automatic rounding of STNumbers based on Asset types
- Create a new SField metadata enum, sMD_NeedsAsset, which indicates
  the field should be associated with an Asset so it can be rounded.
- Add a new STTakesAsset intermediate class to handle the Asset
  association to a derived ST class. Currently only used in STNumber,
  but could be used by other types in the future.
- Add "associateAsset" which takes an SLE and an Asset, finds the
  sMD_NeedsAsset fields, and associates the Asset to them. In the case
  of STNumber, that both stores the Asset, and rounds the value
  immediately.
- Transactors only need to add a call to associateAsset _after_ all of
  the STNumbers have been set. Unfortunately, the inner workings of
  STObject do not do the association correctly with uninitialized
  fields.
- When serializing an STNumber that has an Asset, round it before
  serializing.
- Add an override of roundToAsset, which rounds a Number value in place
  to an Asset, but without any additional scale.
- Update and fix a bunch of Loan-related tests to accommodate the
  expanded Number class.
- (Not all tests are fixed yet.)
2025-12-08 18:38:30 -05:00
Bart
4565cc280b chore: Fix docs readme and cmake (#6122)
This change removes the unused `with_docs` option and fixes the README instructions on how to build the `docs` target.
2025-12-08 18:39:38 +00:00
Bart
9625514da8 chore: Clean up .gitignore and .gitattributes (#6001)
The .gitignore and .gitattributes files contain references to files and directories that the current build no longer produces, so this change removes obsolete entries in these files, and does some general reorganizing of the remaining entries.
2025-12-08 12:35:23 -05:00
Bart
a4c60b4160 chore: Use updated secp256k1 recipe (#6118)
This change updates the secp256k1 recipe that defines the SECP256K1_STATIC, so it no longer needs to be defined in the code here. Running the Conan update script also updated two other recipes in the lock file.
2025-12-08 11:27:55 -05:00
Ed Hennis
9798172086 Merge branch 'ximinez/lending-XLS-66-ongoing' into ximinez/lending-number-simple 2025-12-05 21:29:53 -05:00
Ed Hennis
5224636794 Merge branch 'ximinez/lending-XLS-66-2' into ximinez/lending-XLS-66-ongoing 2025-12-05 21:29:07 -05:00
Ed Hennis
065f7171eb Merge branch 'ximinez/develop-nolending' into ximinez/lending-XLS-66-2 2025-12-05 21:28:36 -05:00
Ed Hennis
d95e0e542f Merge branch 'develop' into ximinez/develop-nolending 2025-12-05 21:14:03 -05:00
Ed Hennis
6f5c8eef30 Merge branch 'ximinez/lending-XLS-66-ongoing' into ximinez/lending-number-simple 2025-12-05 21:13:59 -05:00
Ed Hennis
5ceb915be4 Merge branch 'ximinez/lending-XLS-66-2' into ximinez/lending-XLS-66-ongoing 2025-12-05 21:12:57 -05:00
Ed Hennis
af43572ee5 Review feedback from @shawnxie999: even more rounding
- Round the initial total value computation upward, unless there is
  0-interest.
- Rename getVaultScale to getAssetsTotalScale, and convert one incorrect
  computation to use it.
- Use adjustImpreciseNumber for LossUnrealized.
- Add some logging to computeLoanProperties.
2025-12-05 21:08:01 -05:00
Ed Hennis
b02b700532 Update src/xrpld/app/tx/detail/LoanManage.cpp
Co-authored-by: Shawn Xie <35279399+shawnxie999@users.noreply.github.com>
2025-12-05 19:29:54 -05:00
Bart
b986395ecc docs: Infer version of Conan dependency to export (#6112)
This change updates a script in the documentation to automatically infer the version of a patched Conan dependency from the conan.lock file.
2025-12-05 11:44:48 -05:00
Vito Tumas
354531f946 Fix Overpayment Calculation (#6087)
- Adds additional unit tests to cover math calculations.
- Removes unused methods.
2025-12-04 12:54:25 -05:00
Ed Hennis
6bc3ff15c2 Merge branch 'ximinez/lending-XLS-66-ongoing' into ximinez/lending-number-simple 2025-12-04 12:34:17 -05:00
Bart
020ea3f412 refactor: Update Conan dependencies: protobuf and grpc (#5589)
This PR updates protobuf and grpc to their latest versions. The latest protobuf version no longer requires patches, so we can use it directly from the official Conan Center Index, while the latest grpc still needed a patch, which was added to our own Conan Center Index fork in XRPLF/conan-center-index#8.
2025-12-04 10:34:37 -05:00
Bart
51f1fe5f9a ci: Re-enable linux and macos matrix (#6107)
This change re-enables the Linux and macOS builds that were accidentally disabled in #6089 during testing.
2025-12-04 14:40:00 +00:00
Bart
813bc4d949 refactor: Replaces secp256k1 source by Conan package (#6089)
This change substitutes the secp256k1 source code copy by the Conan recipe added in XRPLF/conan-center-index#24, which updates the version of the library to 0.7.0.
2025-12-04 08:32:45 -05:00
Ed Hennis
daf0316600 Small fixes for Loan merge
- Skip roundToScale work for 0 values.
- Expand a couple of test values to higher precision.
2025-12-03 20:01:06 -05:00
Ed Hennis
0650e6e89d Fix LCOV exclusion 2025-12-03 19:49:47 -05:00
Ed Hennis
947ad002e0 Review feedback from @Tapanito: overpayment value change
- In overpayment results, the management fee was being calculated twice:
  once as part of the value change, and as part of the fees paid.
  Exclude it from the value change.
2025-12-03 18:35:25 -05:00
Ed Hennis
43a6f10050 MPTTester::operator() parameter should be std::int64_t
- Originally defined as uint64_t, but the testIssuerLoan() test called
  it with a negative number, causing an overflow to a very large number
  that in some circumstances could be silently cast back to an int64_t,
  but might not be. I believe this is UB, and we don't want to rely on
  that.
2025-12-03 12:35:56 -05:00
Ed Hennis
e2e9582ff1 Test updates - show balances in runLoan() 2025-12-03 12:35:56 -05:00
Vito Tumas
803380c53c Fix overpayment asserts (#6084) 2025-12-03 12:35:56 -05:00
Ed Hennis
c953073c3a Merge remote-tracking branch 'XRPLF/ximinez/develop-nolending' into ximinez/lending-XLS-66-2
* XRPLF/ximinez/develop-nolending:
  Revert "Implement Lending Protocol (unsupported) (5270)"
  Implement Lending Protocol (unsupported) (5270)
  docs: Update CONTRIBUTING.md for XLS submission guidelines (6065)
  Placeholder
2025-12-03 12:30:43 -05:00
Ed Hennis
ad190a8d6f Review feedback from @dangell7: early return & coverage
- Exclude LogicError lines in ApplyView.cpp (specifically directory
  operations) from code coverage.
- Replace the ability to set the next page on a new directory page with
  an assert, because nothing uses it right now.
- Early return with success for batch inner transactions in preflight2.
2025-12-03 12:29:34 -05:00
Ed Hennis
7863cc71cc MPTTester::operator() parameter should be std::int64_t
- Originally defined as uint64_t, but the testIssuerLoan() test called
  it with a negative number, causing an overflow to a very large number
  that in some circumstances could be silently cast back to an int64_t,
  but might not be. I believe this is UB, and we don't want to rely on
  that.
2025-12-02 23:01:00 -05:00
Ed Hennis
2e7920cd1a Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-number-simple
* XRPLF/develop:
  Implement Lending Protocol (unsupported) (5270)
2025-12-02 21:34:14 -05:00
Ed Hennis
a538f0e438 Add test case line numbers for Number_test::test_limits()
- Aid tracking down tests that are only failing under certain
  configurations.
2025-12-02 17:14:56 -05:00
Ed Hennis
b772f6281e Revert "Implement Lending Protocol (unsupported) (#5270)"
This reverts commit 6c67f1f525.
2025-12-02 12:20:43 -05:00
Ed Hennis
bb6b847270 Merge remote-tracking branch 'upstream/develop' into ximinez/develop-nolending
* upstream/develop:
  Implement Lending Protocol (unsupported) (5270)
2025-12-02 12:20:06 -05:00
Ed Hennis
639d6a953c Refactor the "scaleNumber" conversion functions
- Rename to "fromNumber".
- Instead of returning a pair or tuple, returns a constructed object
  (IOUAmount, STAmount).
2025-12-01 20:22:15 -05:00
Ed Hennis
748888533e Remove trailing zeros from scientific notation Number strings
- Update tests. This has the happy side effect of making some of the string
  representations _more_ consistent between the small and large
  mantissa ranges.
2025-12-01 19:43:40 -05:00
Ed Hennis
8c43a0db93 Clean up some loose ends
- Get rid of commented and unused code.
- Add some asserts and static asserts.
- Use the range_ when possible.
2025-12-01 18:36:18 -05:00
Ed Hennis
cc05e407c2 Force small mantissas in testAMM() 2025-12-01 17:53:23 -05:00
Ed Hennis
ff39388b93 Merge branch 'develop' into ximinez/develop-nolending 2025-12-01 14:41:46 -05:00
Ed Hennis
aaaf43237c Merge branch 'develop' into ximinez/lending-number-simple 2025-12-01 14:41:41 -05:00
Ed Hennis
86e71daa86 Placeholder 2025-12-01 12:20:02 -05:00
Ed Hennis
8921f798f0 fixup! fixup! Update several unit tests to work with the new number rules 2025-11-28 22:27:57 -05:00
Ed Hennis
4ad3e9f8e8 fixup! Update several unit tests to work with the new number rules 2025-11-28 21:37:36 -05:00
Ed Hennis
3f87aeb6b5 Update several unit tests to work with the new number rules
- For AMM tests, just disable the SAV amendment because there are
  a boatload of results that depend on the old math. Those will be
  updated later.
2025-11-28 18:43:50 -05:00
Ed Hennis
db52b34f3f Merge branch 'develop' into ximinez/lending-number-simple 2025-11-28 15:53:18 -05:00
Ed Hennis
060ee70eb0 Merge branch 'develop' into ximinez/lending-XLS-66 2025-11-28 15:46:31 -05:00
Ed Hennis
ae919ad5b7 Start fixing the AMMExtended tests 2025-11-27 02:00:11 -05:00
Ed Hennis
bea3ce952e Merge branch 'develop' into ximinez/lending-XLS-66 2025-11-27 01:48:44 -05:00
Ed Hennis
eaaea43f80 Refactor Number internals away from int128 to uint64 & a sign flag 2025-11-27 01:47:31 -05:00
Ed Hennis
a87460b89f Restore the original Number interface
- ctors and accessors return `rep`. Very few things expose
  `internalrep`.
- An exception is "unchecked" and the new "normalized", which explicitly
  take an internalrep. But with those special control flags, it's easier
  to distinguish and control when they are used.
- The goal is to get as much of the non-number code back to the previous
  state as possible.
2025-11-26 18:32:26 -05:00
Ed Hennis
8035a46514 Merge branch 'develop' into ximinez/lending-XLS-66 2025-11-26 00:25:02 -05:00
Ed Hennis
315b511326 Merge branch 'develop' into ximinez/lending-XLS-66 2025-11-25 14:54:52 -05:00
Ed Hennis
40cd57355d Review feedback from @shawnxie999: MPT Clawback
- MPTs do not require the lsfMPTCanLock flag to be able to clawback
2025-11-25 14:46:46 -05:00
Ed Hennis
77e3bbdc89 Move the ValidPseudoAccounts class back to its original location
- The class didn't actually change much, if at all, but somehow got
  relocated.
- This should make the review easier, and reduce the footprint of the
  PR.
2025-11-25 13:29:05 -05:00
Ed Hennis
49ee70ea28 Fix formatting again 2025-11-25 12:22:15 -05:00
Vito Tumas
5773f2440a Add additional documentation to Lending Protocol (#6037)
- documents core equations of the lending protocol
2025-11-25 05:37:04 +00:00
Ed Hennis
59e6a8107a Merge branch 'develop' into ximinez/lending-number-simple 2025-11-24 21:49:58 -05:00
Ed Hennis
08a6bef7f3 Merge branch 'develop' into ximinez/lending-XLS-66 2025-11-24 21:48:57 -05:00
Ed Hennis
b8d830a812 Fix formatting 2025-11-24 21:38:21 -05:00
Ed Hennis
814fe018b7 Merge branch 'develop' into ximinez/lending-XLS-66 2025-11-24 21:30:08 -05:00
Ed Hennis
dedafbe326 Review feedback from @gregtatcam: typo 2025-11-24 20:54:31 -05:00
Ed Hennis
71bb08cd78 Review feedback from @Tapanito, @gregtatcam, and @shawnxie999
- Created a common doWithdraw function for VaultWithdraw and
  LoanBrokerCoverWithdraw. Added verifyDepositPreauth to it, so that
  both transactions will get the check.
- Add a missing null check to LoanBrokerSet, and add log messages to the
  existing checks.
2025-11-24 20:42:40 -05:00
Ed Hennis
25e72d7844 Update src/xrpld/app/tx/detail/LoanBrokerCoverClawback.cpp
Co-authored-by: Shawn Xie <35279399+shawnxie999@users.noreply.github.com>
2025-11-24 21:42:03 -04:00
Ed Hennis
005390e266 Fix formatting 2025-11-24 19:48:57 -05:00
Vito Tumas
24586ef394 Add deep freeze check to LoanBrokerDelete (#6053)
- Add logging for missing vault
- Fix unit test
2025-11-24 23:17:34 +00:00
Ed Hennis
3ef6508490 Fix build error with LoanBroker invariant 2025-11-24 17:55:29 -05:00
Ed Hennis
c5f5edebcc Address a couple of feedback items from @Tapanito and @shawnxie999:
- Call verifyDepositAuth in VaultWithdraw and LoanBrokerCoverWithdraw to
  a destination.
- Update a couple of impossible error returns to log a message, but
  exclude from coverage.
- Fail if the LoanBroker.LoanSequence overflows to 0.
2025-11-24 17:45:56 -05:00
Ed Hennis
bb3bd74457 Review feedback from @shawnxie999: removeEmptyHolding
- removeEmptyHolding will succeed if the account is the issuer
- If it encounters a trust line in that state, the line will always be
  deleted.
- If it encounters an MPTToken in that state, which should be
  impossible, the token will be deleted if it doesn't have a balance.
2025-11-24 17:44:58 -05:00
Ed Hennis
7e6647e769 Review feedback from @shawnxie999: broker owner count
Annotate loan broker owner set/delete owner count adjustment
2025-11-24 17:44:57 -05:00
Ed Hennis
b7b0a65735 Update src/xrpld/app/tx/detail/LoanBrokerCoverClawback.cpp
Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
2025-11-24 18:44:16 -04:00
Ed Hennis
e850b9f799 Update src/xrpld/app/tx/detail/LoanBrokerCoverDeposit.cpp
Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
2025-11-24 18:25:56 -04:00
Ed Hennis
4081c9b8e9 Update src/xrpld/app/tx/detail/LoanBrokerSet.cpp
Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
2025-11-24 18:20:00 -04:00
Ed Hennis
a7af773dd8 Add a LoanBroker invariant to compare CoverAvailable to balance
- Ensures that LoanBroker.CoverAvailable is never less than the
  pseudo-account balance for the Vault asset.
2025-11-24 16:24:35 -05:00
Ed Hennis
1ba010031d Review feedback from @gregtatcam: variable name
- Renamed "fee" to "overpaymentFee" in "computeOverpaymentComponents".
2025-11-23 23:32:23 -05:00
Ed Hennis
76766e93df Review feedback from @gregtatcam: readability 2025-11-23 23:14:26 -05:00
Ed Hennis
dd5464d921 From discussion with @gregtatcam: Revert "Payment"
- Revert Payment transactor (Payment.*) back to what is in "develop".
- Change LoanBrokerCoverWithdraw to do a direct transfer, whether it's
  too the account or the destination. Similar to VaultWithdraw, and as
  specified
- https://github.com/XRPLF/rippled/pull/5270#discussion_r2554560222
2025-11-23 23:06:44 -05:00
Ed Hennis
4c28e750ff Review feedback from @gregtatcam: compute vs. calculate
- Rename the LendingHelper functions that started with `calculate` to
  start with `compute`.
2025-11-23 21:41:38 -05:00
Ed Hennis
4ba2514bfa Review feedback from @gregtatcam: LoanDeltas
- Renamed to LoanStateDeltas, and document what it's for
2025-11-23 21:28:09 -05:00
Ed Hennis
27a7138f88 Review feedback from @gregtatcam: constructRoundedLoanState
- Rename the overload of constructRoundedLoanState that takes components
  as inputs to constructLoanState. The original function did no rounding
  or enforcement of the inputs being rounded.
- Left the overload constructRoundedLoanState(SLE::const_ref loan)
  alone, because Loan objects are assumed to be rounded.
2025-11-23 21:09:56 -05:00
Ed Hennis
36c1dd18ee Review feedback from @Tapanito: final payment
- Optimize final payment by checking and returning that case before
  doing any other computations. Removes some asserts that weren't really
  adding value.
2025-11-23 17:28:32 -05:00
Ed Hennis
deab24b580 Review feedback from @gregtatcam: full interest
- Found computed full interest downward, per spec.
2025-11-23 17:10:15 -05:00
Ed Hennis
58497541c7 Review feedback from @gregtatcam: LoanPay flags
- Used std::popcount instead of a loop to check for mutually exclusive
  flags
2025-11-23 15:29:48 -05:00
Ed Hennis
b8ad6d3950 Review feedback from @a1q123456: LoanDelete
- Update the ValidLoan invariant to guarantee that Loan fields are
  consistent for the paid off and not paid off state.
2025-11-23 14:58:45 -05:00
Ed Hennis
63724e4405 Review feedback from @gregtatcam: seconds per year
- Define a constexpr secondsInYear in LedgerHelpers.h
2025-11-23 00:03:52 -05:00
Ed Hennis
a3b2ce91de Review feedback from @gregtatcam: frozen broker pseudo-account
- LoanSet needs to fail if the broker pseudo-account is deep frozen,
  because it needs to be able to receive fees if the broker owner can't.
2025-11-22 23:45:39 -05:00
Ed Hennis
1ceff3dde7 Review feedback from @greptatcam: getStartDate
- Make getStartDate helper in LoanSet static.
2025-11-22 23:36:17 -05:00
Ed Hennis
2fb9a6a292 Review feedback from @Tapanito: tecKILLED logs
- Log messages explaining Loan-related tecKILLED returns.
2025-11-22 23:06:12 -05:00
Ed Hennis
e25bae5e78 Review feedback from @Tapanito
- Check for zero interest in loanAccruedInterest
- Fix a couple of errors from earlier commits
2025-11-22 22:56:40 -05:00
Ed Hennis
17eaa51378 Update src/xrpld/app/misc/detail/LendingHelpers.cpp
- Optimization to skip multiplication.

Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
2025-11-22 23:49:19 -04:00
Ed Hennis
2f410148f1 Update src/xrpld/app/misc/detail/LendingHelpers.cpp
- Log a warning if a full payment fails because it's the last payment.

Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
2025-11-22 23:40:19 -04:00
Ed Hennis
fa2dea84c2 Review feedback from @gregtatcam: STAmount
- Fix a couple of typos.
- Make fewer unneeded copies in roundToScale.
2025-11-22 22:30:06 -05:00
Ed Hennis
f8ee979ff4 Review feedback from @gregtatcam
- Add a comment explaining the formula in LoanManage::owedToVault
- Make owedToVault static
2025-11-22 21:48:46 -05:00
Ed Hennis
1c38bbdf45 Review feedback from @gregtatcam
- Remove unneeded proxy variables. Set the fields directly.
2025-11-22 21:33:30 -05:00
Ed Hennis
590f69cd4c Add comment to totalPaidToVaultForDebt in LoanPay.cpp
Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
2025-11-22 21:24:42 -05:00
Ed Hennis
4c9a96a17b Review feedback from @gregtatcam
- No need to subtract takeFromSender in rippleSendMultiMPT if the sender
  is the issuer.
2025-11-22 21:11:06 -05:00
Ed Hennis
b82481858a Review feedback from @gregtatcam
- Rename "accountCanSpend" to "accountSpendabled".
- Change some getIssuer() local vars to use references.
2025-11-22 20:57:34 -05:00
Ed Hennis
8bb162ce52 Review feedback from @gregtatcam
- Rewrite "Asset::native()" and "integral()" to use std::visit.
- Improve documentation for the LoanPay transaction flags:
  tfLoanFullPayment, tfLoanLatePayment
2025-11-22 19:36:50 -05:00
Ed Hennis
d353b0ec04 Review feedback
- Use a lambda to defensively guarantee that "tx" can not affect the
  "signerCount" in "LoanSet::calculateBaseFee" # Please enter the commit
  message for your changes. Lines starting
2025-11-22 16:14:54 -05:00
Ed Hennis
973a105959 Review feedback: test coverage, round debt total
- Add some test cases to improve coverage, and exclude some lines from
  coverage.
- Rounds the Broker.DebtTotal to the Vault scale any time it is
  modified. This should reduce rounding errors.
- Ensure that no debt is left for the Broker after the last loan is
  deleted. This ensures that any accumulated rounding errors are
  resolved.
2025-11-22 16:07:07 -05:00
Ed Hennis
1cec91e72d Move protocol.h values into namespace Lending 2025-11-21 17:20:43 -05:00
Ed Hennis
b76cd60a12 fixup! Restore code that needs to be amendment gated 2025-11-21 16:39:44 -05:00
Ed Hennis
cc9b6fc68c Restore code that needs to be amendment gated 2025-11-21 14:46:34 -05:00
Ed Hennis
92388c4491 Merge branch 'develop' into ximinez/lending-number-simple 2025-11-21 14:38:58 -05:00
Ed Hennis
66da6a8608 Merge branch 'develop' into ximinez/lending-XLS-66 2025-11-21 12:47:43 -05:00
Ed Hennis
8a1f244682 Updated overpayment processing
- Added a test for RIPD-4125
2025-11-20 00:17:33 -05:00
Ed Hennis
e45d847558 Merge branch 'develop' into ximinez/lending-number-simple 2025-11-18 22:51:51 -05:00
Ed Hennis
bd0b651891 Merge branch 'develop' into ximinez/lending-XLS-66 2025-11-18 22:39:17 -05:00
Ed Hennis
fd115cfc13 Address my review feedback on (#6017)
- Shortcut on issuer match in canTransfer.
- An asset can transfer if either trustline enabled rippling, so both
  must have it disabled for the transfer to fail with terNO_RIPPLE.
- Remove unnecessary asfDefaultRipple sets in unit tests.
- Add a new unit test helper class: testline, and a macro: THISLINE.
  When included as a parameter to Env::operator(), will include the line
  number of the transaction that didn't get the expected result. Works
  similarly to BEAST_EXPECT. I didn't do the same for the file name,
  because that can be deduced from the testcase name.
2025-11-18 18:31:10 -05:00
Bronek Kozicki
d8b944c218 Enforce assets are transferable (#6017)
- Includes unit tests for terNO_RIPPLE.
- Switch auth mode to weak when submitter is destination.
- Require rippling enabled for vault deposits or withdrawals.
2025-11-18 18:28:59 -05:00
Ed Hennis
546bfa89d8 For now, skip the larger mantissas in AMM transactions and tests 2025-11-16 20:59:17 -05:00
Ed Hennis
470c9c3936 Fix root2, and add tests for it 2025-11-16 00:18:51 -05:00
Vito Tumas
31d6ad727e Refactors method and struct names (#6039)
- remove unused method
- rename computeFee to computeManagementFee
- rename calculateRounded to constructRounded
- remove redundancies in LoanDeltas struct
- rename PaymentComponentsPlus to ExtendedPaymentComponents
- additional logging
2025-11-15 08:48:38 +00:00
Ed Hennis
9f50cc033e Merge branch 'develop' into ximinez/lending-number-simple 2025-11-15 03:13:10 -05:00
Ed Hennis
cfdcaf3f8d Merge branch 'develop' into ximinez/lending-XLS-66 2025-11-15 03:08:29 -05:00
Ed Hennis
a5f43fb59b Fix some build errors - unused variables, large constants 2025-11-15 02:59:56 -05:00
Ed Hennis
3451d15e12 Step 3: Automatically switch precision in the transaction engine
- Default Number outside of transaction processing to be "large" so RPC
  will work.
2025-11-15 02:55:48 -05:00
Ed Hennis
595a5ee220 Step 2.5cont: Make some updates to STNumber
- Added test cases min int64.
- Updated numberFromJson range checking to use the larger range
  available from Number.
2025-11-15 00:50:59 -05:00
Ed Hennis
c9ad49faf3 Step 2.5: Run the STNumber tests using both mantissa sizes
- Nothing really needed to be changed in the tests, but I added a couple
  of test cases for the min and max int64.
2025-11-14 19:41:26 -05:00
Ed Hennis
857eaffa55 refactor: Move the mantissa_scale enum into the MantissaRange struct 2025-11-14 19:06:44 -05:00
Ed Hennis
93109918ed Fix Number::power(), and a bunch of Number unit tests 2025-11-14 18:51:01 -05:00
Ed Hennis
fbcd4f33eb Add more edge case Number tests 2025-11-14 15:10:10 -05:00
Ed Hennis
b9fdf9e564 Add the testPoC_UnsignedUnderflowOnFullPayAfterEarlyPeriodic
- Updated to reflect that the issue in RIPD-3971 has been resolved by
  commit 4396b77c4b
2025-11-14 12:52:27 -05:00
Ed Hennis
6f1fe5047b Step 2 cont. Refactor the to_string(Number) test 2025-11-14 12:40:54 -05:00
Ed Hennis
4cf22b50de fixup! Step 2: Add the ability to change the mantissa range
- Fix cross-compiler build issues
2025-11-14 11:33:09 -05:00
Ed Hennis
606e3ec0b7 Step 2: Add the ability to change the mantissa range
- Update tests. Unfinished.
- TODO: Finish Number tests. Use both modes for STNumber tests. Move
  mantissa_scale into MantissaRange.
2025-11-14 02:34:56 -05:00
Ed Hennis
c65a311ad1 Remove a bunch of obsolete code, marked by "#if LOANCOMPLETE" 2025-11-13 14:26:47 -05:00
Ed Hennis
a868b1938d Fix Vault test failure due to default field not being in RPC Json 2025-11-13 14:21:41 -05:00
Ed Hennis
2f94838bbf Merge branch 'develop' into ximinez/lending-XLS-66 2025-11-13 12:18:42 -05:00
Ed Hennis
1c1cd1a391 Change Vault asset fields back to default
- Was unintentionally rolled back with `Number` changes.
2025-11-13 12:15:39 -05:00
Ed Hennis
2eca3dca89 Merge remote-tracking branch 'upstream/develop' into ximinez/lending-number-simple
* upstream/develop:
  chore: Clean up incorrect comments (6031)
  refactor: Retire MultiSignReserve and ExpandedSignerList amendments (5981)
2025-11-13 11:01:22 -05:00
Ed Hennis
2881aade2c Fix Vault unit tests for default fields with value 0.
- Field will be absent in RPC results instead of returning 0.
2025-11-13 01:53:36 -05:00
Ed Hennis
ad124ce7b2 Fix balance checking assertion in LoanPay when issuer is borrower
- Resolves RIPD-4096
2025-11-13 01:51:07 -05:00
Ed Hennis
4abb6d9dfe Turns out there's no to_string(__int128_t) 2025-11-13 00:51:37 -05:00
Ed Hennis
7cd48a7713 fixup! Continue with Step 1 2025-11-12 22:58:06 -05:00
Ed Hennis
d2d403da90 Continue with Step 1
- Track down and fix edge cases.
- Some refactoring and renaming for clarity and simplicity
2025-11-12 20:32:47 -05:00
Ed Hennis
a4aa72eada Fix revert issues 2025-11-12 19:19:06 -05:00
Ed Hennis
398170ef3d Revert "Add optional enforcement of valid integer range to Number"
This reverts commit 3cb447a4fe.
2025-11-12 19:15:14 -05:00
Ed Hennis
9b0b7b5a91 Revert "Make all STNumber fields "soeDEFAULT""
This reverts commit 24f37d73f6.
2025-11-12 19:15:07 -05:00
Ed Hennis
1b4e18a1a7 Revert "Add integer enforcement when converting to XRP/MPTAmount to Number"
This reverts commit b605a2cdcc.
2025-11-12 19:15:06 -05:00
Ed Hennis
814577758f Revert "Fix build error - avoid copy"
This reverts commit cb6df196dc.
2025-11-12 19:15:03 -05:00
Ed Hennis
694abd1c79 Revert "Catch up the consequences of Number changes"
This reverts commit 0175dd70db.
2025-11-12 19:15:00 -05:00
Ed Hennis
2e34506835 Revert "Add a distinction between a "valid" and a "representable" Number"
This reverts commit 8e56af20ee.
2025-11-12 19:14:54 -05:00
Ed Hennis
b7ed35cb04 Fix merge issue: references to retired features 2025-11-12 16:34:41 -05:00
Ed Hennis
343824332c Merge branch 'develop' into ximinez/lending-number-simple 2025-11-12 14:17:35 -05:00
Ed Hennis
8f772b9073 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-XLS-66
* XRPLF/develop:
  chore: Set version 3.1.0-b0 (5986)
  ci: Clean workspace on Windows self-hosted runners (6024)
  docs: fix spelling in comments (6002)
  fix: floating point representation errors in vault (5997)
  ci: Specify bash as the default shell in workflows (6021)
  refactor: Add `XRPL_RETIRE_FIX` and `XRPL_RETIRE_FEATURE` macros (6014)
  refactor: Retire DepositPreAuth and DepositAuth amendments (5978)
  chore: Move running of unit tests out of coverage target (6018)
  refactor: Retire PayChanRecipientOwnerDir amendment (5946)
2025-11-12 14:12:01 -05:00
Ed Hennis
ef66a1cc0e Disable inner Batch transactions for Vault and Loan types 2025-11-12 13:51:57 -05:00
Ed Hennis
a32b5723e5 fixup! fixup! Step 1: Convert Number to use 128-bit numbers internally 2025-11-12 12:16:18 -05:00
Ed Hennis
3048f55270 fixup! Step 1: Convert Number to use 128-bit numbers internally 2025-11-12 10:14:05 -05:00
Ed Hennis
d030fdaa2b Step 1: Convert Number to use 128-bit numbers internally
- Update the conversion points between Number and *Amount & STNumber.
- Tests probably don't pass.
2025-11-12 00:31:47 -05:00
Ed Hennis
6c375f1346 Convert sfNextPaymentDueDate from optional to default
- Simplifies some of the updates and checks
2025-11-11 12:02:58 -05:00
Ed Hennis
21eb13de0c Reorder payment options to do full early payment first
- Since all the special cases are now specified with flags, the order is
  less important.
- Avoids computing the periodic payment parts that are not needed for
  full payment computation.
- A late payment without the late payment flag will override everything
  else, though.
2025-11-10 23:28:25 -05:00
Ed Hennis
4396b77c4b Add tfLoanLatePayment flag; full payment is no longer a special case
- A regular payment that is late, or a tfLoanLatePayment that is not
  late will fail.
- Flags are mutually exclusive.
- Add a few interest computation shortcuts and overflow prevention
  checks that return 0 if there's no time to compute for.
2025-11-10 23:17:42 -05:00
Ed Hennis
8d22409ab5 review feedback: Use the specific type in the "SendMulti" functions 2025-11-10 21:20:42 -05:00
Ed Hennis
1c99243ec2 Fix service fee accounting when a borrower is the broker (#6016)
- Add unit-test to verify the fix.
2025-11-10 21:10:13 -05:00
Ed Hennis
7712cbdfcc Fix build issue - unused variable 2025-11-10 21:02:01 -05:00
Ed Hennis
abb05cc684 Merge branch 'develop' into ximinez/lending-XLS-66 2025-11-10 19:52:54 -05:00
Ed Hennis
2f064893bb test: Add a test case reproducing the issue in RIPD-3902 2025-11-10 19:50:15 -05:00
Ed Hennis
6ad4b29878 Always round cover minimum calculations up
- Addresses RIPD-4016.
- Add and update testRoundingAllowsUndercoverage() unit test from ticket.
2025-11-10 17:59:10 -05:00
Ed Hennis
73a857e69e Merge branch 'develop' into ximinez/lending-XLS-66 2025-11-10 15:35:09 -05:00
Ed Hennis
9e25b4753d fix: Check for empty or zero VaultID in LoanBrokerSet
- Resolves RIPD-4067.
2025-11-10 15:32:32 -05:00
Ed Hennis
0ae835b356 doc: Expand explanation for LoanBrokerCoverClawback::determineBrokerID 2025-11-10 13:16:10 -05:00
Ed Hennis
a9796d0210 Minor test fixes
- Don't deposit cover if the amount is 0.
- Handle missing next payment date in getCurrentState.
2025-11-09 20:27:59 -05:00
Ed Hennis
b5b31efe0b Fix RIPD-3901 - faulty assert
- Assert requires that an overpayment reduces the value of a loan. If
  the overall loan interest is low enough, it could leave it unchanged.
  Update the assert to require that the overpayment does not increase
  the value of the loan.
- Adds a unit test provided by @gregtatcam to demonstrate this issue.
2025-11-09 17:37:46 -05:00
Ed Hennis
e00fea9934 Update the test case for RIPD-3459 with more detailed output data 2025-11-08 22:47:50 -05:00
Ed Hennis
e3ea23cff5 Add test case to reproduce RIPD-3459
- Improve a few loan test helper functions.
- Make Loan.GracePeriod a default field.
2025-11-08 19:04:32 -05:00
Ed Hennis
ffc0d26d20 Merge remote-tracking branch 'mywork/ximinez/lending-number' into ximinez/lending-XLS-66
* mywork/ximinez/lending-number:
  Add a distinction between a "valid" and a "representable" Number
  chore: Point xrpld symlink to rippled (6012)
  Catch up the consequences of Number changes
  Fix build error - avoid copy
  Add integer enforcement when converting to XRP/MPTAmount to Number
  Make all STNumber fields "soeDEFAULT"
  Add optional enforcement of valid integer range to Number
2025-11-08 17:00:35 -05:00
Ed Hennis
fabc7bd916 Merge branch 'develop' into ximinez/lending-number 2025-11-07 19:11:47 -05:00
Ed Hennis
8e56af20ee Add a distinction between a "valid" and a "representable" Number
- "valid" means the value is <= Number::maxIntValue, which has been
  changed to maxMantissa / 100. A valid number could get bigger and be
  ok - such as when paying late interest on a loan.
- "representable" means the value is <= Number::maxMantissa. An
  unrepresentable number WILL be rounded or truncated.
- Adds a fourth level of enforcement: "compatible". It is used for
  converting XRP to Number (for AMM), and when doing explicit checks.
- "weak" will now throw if the number is unrepresentable.
2025-11-07 19:07:21 -05:00
Ed Hennis
972841ae29 Check for Grace Period overflow in LoanSet 2025-11-07 15:40:50 -05:00
Ed Hennis
77d5826297 Add Grace Period to testLoanNextPaymentDueDateOverflow
- Demonstrates that Grace Period can overflow.
- Expected to fail.
2025-11-07 15:37:32 -05:00
Gregory Tsipenyuk
ebfca636fc Implicitly authorize Vault and LoanBroker pseudo-accounts (#5976)
- Vault and LoanBroker pseudo-accounts can hold MPTs, regardless of MPTRequireAuth setting.
- Add requireAuth check in LoanBrokerCoverDeposit and LoanPay.
- Fail attempts to unauthorize pseudo-accounts by MPT issuers.
2025-11-07 05:39:34 +00:00
Ed Hennis
0175dd70db Catch up the consequences of Number changes
- Change the Number::maxIntValue to all 9's.
- Add integral() to Asset (copied from Lending)
- Add toNumber() functions to STAmount, MPTAmount, XRPAmount to allow
  explicit conversions with enforcement options.
- Add optional Number::EnforceInteger options to STAmount and STNumber
  ctors, conversions, etc. IOUs are never checked.
- Update Vault transactors, and helper functions, to check restrictions.
- Fix and add Vault tests.
2025-11-06 23:55:05 -05:00
Ed Hennis
cb6df196dc Fix build error - avoid copy 2025-11-06 23:55:05 -05:00
Ed Hennis
b605a2cdcc Add integer enforcement when converting to XRP/MPTAmount to Number 2025-11-06 23:55:05 -05:00
Ed Hennis
24f37d73f6 Make all STNumber fields "soeDEFAULT" 2025-11-06 23:55:05 -05:00
Ed Hennis
3cb447a4fe Add optional enforcement of valid integer range to Number 2025-11-06 23:55:05 -05:00
Ed Hennis
ecc429e521 Merge branch 'develop' into ximinez/lending-XLS-66 2025-11-06 23:50:30 -05:00
Ed Hennis
2cb0ca5ad2 Refactor loan test helpers into reusable functions
- Try to reproduce RIPD-3831
2025-11-06 23:49:10 -05:00
Gregory Tsipenyuk
c56387d124 Fix empty/zero broker ID in LoanBrokerSet and LoanSet (#5977)
- Add checks for empty/zero brokerID where needed
- Extend unit-tests.
2025-11-07 02:05:08 +00:00
Ed Hennis
fdb659dc72 fix: Use ".value()" instead of "->" when with STObject::Proxy objects
- Turns out that "Proxy::operator->" is not a safe substitute for
  "Proxy::value()." if the field is not required. The implementation
  is different such that "operator->" will return a null ptr if the
  field is not present. This includes default fields with a value of
  zero!
2025-11-06 20:14:52 -05:00
Ed Hennis
74e331f3e9 Handle zero rate in computePaymentFactor 2025-11-06 19:36:40 -05:00
Ed Hennis
2264713d52 fix: Improve rounding for IOU loans
- Scale the loan to the Vault, so that amounts moving to the vault are
  less likely to have rounding errors.
- Similar to LoanPay, when LoanManage defaults a loan, round the amounts
  to the Vault scale (because the Vault scale can change) before
  applying them to the Vault.
2025-11-06 19:25:37 -05:00
Ed Hennis
560ff824df Another arbitrary test case to try 2025-11-06 19:12:02 -05:00
Ed Hennis
07ec253f2e Add testDustManipulation test, which is expected to fail 2025-11-06 12:48:02 -05:00
Ed Hennis
d8243c7e68 Merge remote-tracking branch 'mywork/ximinez/lending-number' into ximinez/lending-XLS-66
* mywork/ximinez/lending-number:
  Catch up the consequences of Number changes
  Fix build error - avoid copy
  Add integer enforcement when converting to XRP/MPTAmount to Number
  Make all STNumber fields "soeDEFAULT"
  Add optional enforcement of valid integer range to Number
  fix: domain order book insertion #5998
  refactor: Retire fixTrustLinesToSelf amendment (#5989)
2025-11-05 19:29:27 -05:00
Ed Hennis
bd196c7609 Catch up the consequences of Number changes
- Change the Number::maxIntValue to all 9's.
- Add integral() to Asset (copied from Lending)
- Add toNumber() functions to STAmount, MPTAmount, XRPAmount to allow
  explicit conversions with enforcement options.
- Add optional Number::EnforceInteger options to STAmount and STNumber
  ctors, conversions, etc. IOUs are never checked.
- Update Vault transactors, and helper functions, to check restrictions.
- Fix and add Vault tests.
2025-11-05 19:16:09 -05:00
Ed Hennis
82f68496b8 Fix build error - avoid copy 2025-11-05 18:51:20 -05:00
Ed Hennis
16609ccaad Add integer enforcement when converting to XRP/MPTAmount to Number 2025-11-05 18:51:20 -05:00
Ed Hennis
93d99a671c Make all STNumber fields "soeDEFAULT" 2025-11-05 18:51:20 -05:00
Ed Hennis
d10a578663 Add optional enforcement of valid integer range to Number 2025-11-05 18:51:19 -05:00
Ed Hennis
165478b929 Remove the shortage code completely 2025-11-05 13:28:03 -05:00
Ed Hennis
95fdbe520f Partially revert aed8e2b166 Fill in payment computation shortages (#5941)
- Do not attempt to fill in payment computation shortages. Fixes, tests,
  and optimizations are left intact.
2025-11-05 12:48:14 -05:00
Ed Hennis
34db04ffc1 Update Lending files for the xrpl rename 2025-11-04 19:37:58 -05:00
Ed Hennis
65e6746b5c Merge branch 'develop' into ximinez/lending-XLS-66 2025-11-04 18:02:38 -05:00
Ed Hennis
aed8e2b166 Fill in payment computation shortages (#5941)
- Ensures a consistent fixed payment amount for the entire life of the
  loan, except the final payment, which is guaranteed to be the same or
  smaller.
- Convert some Loan structs to compute values that had need manual
  updates to stay consistent.
- Fail the transaction in `LoanPay` if it violates the Vault `assetsAvailable <=
  assetsTotal` invariant.
- Use constexpr to check that min mantissa value for Number and STAmount
  is a power of 10, and compute the max in terms of the min.
- Improve unit tests:
  - Use BrokerParameters and Loan Parameters instead of semi-global
    class values
  - In tests, check that the expected number of loan payments are made.
  - Add LoanBatch manual test to generate a set number of random loans,
    set them up, and pay them off.
  - Add LoanArbitrary manual test to run a single test with specific
    (hard-coded for now) parameters.
  - Add Number support to XRP_t.
2025-11-04 22:56:16 +00:00
Ed Hennis
7925cc4052 fix: Check the borrower's balance in LoanSet for reserve
- Previously, the submitting Account's balance was checked, which could
  have been the borrower or the lender.
2025-11-03 20:39:01 -05:00
Ed Hennis
245bac1769 Merge branch 'develop' into ximinez/lending-XLS-66 2025-11-03 18:04:04 -05:00
Ed Hennis
cdd6ad4ba4 test: Fix test set up, since the order of preclaim checks changed
- Need to have multisign set up to get to the fee check
2025-11-03 18:00:10 -05:00
Ed Hennis
89979022f2 Merge remote-tracking branch 'upstream/develop' into ximinez/lending-XLS-66
* upstream/develop:
  refactor: Retire ImmediateOfferKilled amendment (5973)
  ci: Update CI image hashes to use netstat (5987)
  chore: Remove version number in find_dependency for OpenSSL (5985)
  refactor: Modularize shamap and nodestore (5668)
  refactor: Retire fixMasterKeyAsRegularKey amendment (5959)
  refactor: Retire fixReducedOffersV1 amendment (5972)
  refactor: Retire fixAmendmentMajorityCalc amendment (5961)
  refactor: Clean up `TxMeta` (5845)
  fix: Address permission delegation vulnerability (5825)
2025-11-03 13:09:03 -05:00
Ed Hennis
4920e65b14 fix: LoanBrokerSet is malformed if Cover fields don't align
- sfCoverRateMinimum and sfCoverRateLiquidation must be both zero or
  both non-zero, because both are used in the default amount
  calculations, which is the only place they're really meaningful.
2025-11-03 12:31:20 -05:00
Bronek Kozicki
b472cc3493 Unit tests for multisigned LoanSet counterparty 2025-10-31 16:51:37 -04:00
Ed Hennis
27389cd7e8 Merge branch 'develop' into ximinez/lending-XLS-66 2025-10-31 13:51:23 -04:00
Ed Hennis
2b9f70b0bd Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-XLS-66
* XRPLF/develop:
  refactor: Improve txset handling (5951)
  Remove directory size limit (5935)
  fix: Change Credential sfSubjectNode to optional (5936)
  refactor: Add support for extra transaction signature validation (5851)
  refactor: Retire fixQualityUpperBound amendment (5960)
  refactor: Retire fix1623 amendment (5928)
  refactor: Retire fixTakerDryOfferRemoval amendment (5958)
  ci: Check whether test failures are caused by port exhaustion (5938)
  chore: Use new prepare-runner (5970)
2025-10-31 13:50:46 -04:00
Gregory Tsipenyuk
e8dddcbb7f Fix LoanBrokerDelete with empty or zero broker ID (RIPD-3858) (#5967) 2025-10-31 03:01:05 +00:00
Ed Hennis
7a758a42f9 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-XLS-66
* XRPLF/develop:
  refactor: Retire fixSTAmountCanonicalize code (5956)
2025-10-29 14:26:32 -04:00
Ed Hennis
298f6deac9 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-XLS-66
* XRPLF/develop:
  refactor: Retire fixRmSmallIncreasedQOffers amendment (5955)
  refactor: Sorts retired amendments to reduce conflicts (5966)
2025-10-29 13:45:08 -04:00
Ed Hennis
71565a909e Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-XLS-66
* XRPLF/develop:
  refactor: Retire fixCheckThreading amendment (5957)
  refactor: Retire fix1578 amendment (5927)
  refactor: Retire fix1571 amendment (5925)
  feat: Add public key to log messages (5678)
  Retire fix1781 amendment (5931)
  ci: Use nproc-2 to set parallelism for builds and tests (5939)
2025-10-29 12:57:37 -04:00
Ed Hennis
52490730b2 Check for null Vault SLE in LoanBrokerCoverDeposit 2025-10-29 12:51:12 -04:00
Ed Hennis
64e0ee4be9 Add POC unit test for null vault dereference 2025-10-29 12:25:03 -04:00
Ed Hennis
d0c60cdf59 Fix broken unit test case 2025-10-28 18:47:52 -04:00
Ed Hennis
0febc60cbe Ignore the contents of SigningPubKey when multisigning with a target 2025-10-28 18:37:15 -04:00
Ed Hennis
122d8f96b3 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-XLS-66
* XRPLF/develop:
  ci: Use commit hash so workflows are not canceled when merging multiple PRs (5950)
  ci: Only upload codecov reports in the original repo, not in forks (5953)
  ci: Only log into Conan when uploading packages (5952)
  fix: invariant error in fee-sized `VaultWithdraw` (5876)
  fix: account_tx limit parameter validation for malformed values (5891)
  refactor: Retire fix1543 amendment (5926)
  ci: Only run .exe files during test phase on Windows (5947)
  refactor: Migrate json unit tests to use doctest (5533)
  Change `fixMPTDeliveredAmount` to `Supported::yes` (5833)
  fix: Upload all test binaries (5932)
  chore: Better pre-commit failure message (5940)
2025-10-28 18:21:12 -04:00
Ed Hennis
ec60dcf90d Ensure payment does not exceed Loan balance
- Also disallow extra parameters on the ALWAYS_OR_UNREACHABLE macro,
  which should prevent me from mixing up XRPL_ASSERT and
  XRPL_ASSERT_PARTS.
2025-10-28 16:27:45 -04:00
Ed Hennis
310852ba2d refactor: Payment component calculation will target next true state
- Compute the next "true" state, round the values off, then compute the
  deltas needed to get the current state to that state. Plus some data
  integrity checks.
- Add `Number::zero`, which is longer to type, but more readable than
  `Number{}`.
- Prepare to improve Loan unit tests: track managementFeeRate in
  BrokerInfo, define a LoanParameters object for creation options and
  start adding support for it, track and verify loan state while making
  payments.
2025-10-28 16:27:44 -04:00
Ed Hennis
f4404eafbd Fix build error
- Use an explicit cast to std::int64_t in std::max call, because
  suffixes are inconsistent.
2025-10-26 21:52:01 -04:00
Ed Hennis
fe5bd82ed8 Merge branch 'develop' into ximinez/lending-XLS-66 2025-10-26 19:12:45 -04:00
Ed Hennis
da14c6f018 Prevent numerical overflow of payment due dates
- Addresses FIND-013 from audit.
- Bases the limit on the current ledger time, and ensures that
  "payments * interval <= limit". This allows a loan to potentially run through
  "the end of time" successfully, but not go a second over.
- Wrote several test cases, including a few that go right to "the end of
  time".
2025-10-26 18:57:16 -04:00
Ed Hennis
5ceefdfbd5 Add repro unit test for FIND-008, with modifications, from audit 2025-10-26 16:03:59 -04:00
Ed Hennis
b8b9e7a51e Add repro unit tests, with modifications, from audit
- FIND-005, FIND-009, and FIND-010.
- Add the finding number to existing tests - FIND-001, FIND-003,
  FIND-012, FIND-007.
- Tweak the interest rate failure log messages in LoanSet.
2025-10-26 15:31:32 -04:00
Ed Hennis
269fb44cd7 Add unit test from security audit (FIND-007)
- The issue identified in this finding had previously been fixed, but
  the test is useful to verify.
2025-10-26 13:51:46 -04:00
Ed Hennis
40ef91e7e0 Limit how many payments can be made in a single LoanPay
- Addresses FIND-005 from audit.
- Tuning values defined in Protocol.h. Optimal values TBD.
  - loanPaymentsPerFeeIncrement: calculateBaseFee estimates the number
    of payments included in the Amount and charges
    "baseFee * number / loanPaymentsPerFeeIncrement".
  - loanMaximumPaymentsPerTransaction: If the number of payments
    (including overpayments if applicable) hits this limit, stop
    processing more payments, but DO NOT FAIL.
- Fix the rounding in LoanSet for Guard 4 (sufficient computed payments)
- Tweak several test parameters to account for the new limits.
- Change payment component rounding for IOUs to "towards_zero".
- Add some safety limits to loan calculations to prevent nonsensical
  values.
2025-10-26 13:09:35 -04:00
Ed Hennis
fe4269cf8b Avoid negative payments: limit origination fee to the loan principal
- Addresses FIND-006 from audit.
- Removes the "minimum" check for sfLoanOriginationFee, and replaces it
  with a "valid range" check with the max value being
  sfPrincipalRequested.
- Reuses the test from the report, with some modifications.
- Also adds some more test cases for existing interest rate tests.
2025-10-24 18:33:57 -04:00
Ed Hennis
a3b82023d6 refactor: Pull computeOverpaymentComponents into a separate function 2025-10-24 16:00:32 -04:00
Ed Hennis
0950d41fce refactor: De-templatize and move LendingHelper functions from .h to .cpp
- Changes:
  1. Removed the `AssetType` template parameter from all functions in
     favor of just using the `Asset` class.
  2. Fully moved all `ripple::detail` functions from .h to .cpp.
  3. Moved all definitions of non `detail` functions from .h to .cpp,
     except roundPeriodicPayment, just because it's small and I want it
     to be visible. Left declarations in .h
  4. Moved `PaymentSpecialCase`, `PaymentComponents` and
     `computePaymentComponents` into `detail` and updated references.
2025-10-24 15:44:46 -04:00
Ed Hennis
45819477d3 refactor: change what values are tracked as Payment Components - Part 2
- PaymentComponents is an class used internally to break a payment value
  into principal, interest, and fees.
2025-10-24 15:09:35 -04:00
Ed Hennis
83e249eb8a refactor: change what values are tracked as Payment Components - Part 1
- This is an intermediate commit. It leaves the old variables in place,
  so I can do verifications that the new computations are correct. They
  will be removed in the next commit.
- PaymentComponents is an class used internally to break a payment value
  into principal, interest, and fees.
2025-10-24 15:09:35 -04:00
Bronek Kozicki
07fcbd5498 Add authorization check to LoanSet (#5875)
- Add tests for unauthorized borrower and lender
2025-10-24 13:27:27 -04:00
Gregory Tsipenyuk
88a770c71b Don't create empty holding for MPT or trust line issuer (#5877)
- Adds a check to the MPToken creation invariant to ensure none are created for the issuer.
- `addEmptyHolding()` will return success without doing anything for these scenarios. There is nothing to do, as with XRP.

---------

Co-authored-by: Ed Hennis <ed@ripple.com>
2025-10-24 12:32:26 -04:00
Ed Hennis
78ef800e30 Fix more problems introduced by 6adb2ec
- Renamed canSendToAccount to canWithdraw, because the semantics are
  a little different from a payment. Notably, if withdrawing to self,
  you can still include a destination tag.
- Simplified the interface to canWithdraw to just pass in the
  STTx.
- preflightDestinationAndTag is pretty pointless now, so removed it.
2025-10-24 01:19:45 -04:00
Ed Hennis
7f2f6b8791 Merge remote-tracking branch 'mywork/ximinez/crashed-tests' into ximinez/lending-XLS-66
* mywork/ximinez/crashed-tests:
  test: Count crashed test suites
2025-10-24 00:59:33 -04:00
Ed Hennis
7c45f6a673 Fix broken Vault unit tests introduced in 6adb2ec
- canSendToAccount will check if a destination tag is required _before_
  checking if the sender is the destination. This is the original
  VaultWithdraw behavior, and I want to stay consistent.
2025-10-24 00:30:06 -04:00
Ed Hennis
66b547f6fc Review feedback from @Tapanito
- Correct interest rounding calculation
- Fix some comments
- Don't explicitly break out of the multiple payment loop for the final
  payment. Assert that it will exit by the loop condition.
2025-10-23 19:27:11 -04:00
Ed Hennis
6adb2eca76 Review feedbak from @tequdev, plus helpers
- Fix LoanSet.calculateBaseFee with multisign.
- Cleanups.
- Add View helper functions for Loan and Vault transactions
  - preflightDestinationAndTag
  - checkDestinationAndTag
  - canSendToAccount
- Used the helpers in appropriate Loan and Vault transactions.
  - They could also be used in older transactions, I'll save that for
    later.
2025-10-23 18:11:32 -04:00
Gregory Tsipenyuk
f60e298627 Extend LoanBroaker and Loan unit-tests. (#5863)
- Add convenience functions to MPT test-framework.
2025-10-23 19:51:30 +00:00
Ed Hennis
9f5bc8f0da Fix more build errors 2025-10-23 14:28:03 -04:00
Ed Hennis
e306a7c75f Fix some build errors 2025-10-23 14:11:31 -04:00
Ed Hennis
59364be5f8 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-XLS-66
* XRPLF/develop:
  refactor: Retire fix1515 amendment (5920)
  Use "${ENVVAR}" instead of ${{ env.ENVVAR }} syntax in GitHub Actions (5923)
2025-10-23 13:25:59 -04:00
Ed Hennis
aa696ed61a Merge branch 'develop' into ximinez/crashed-tests 2025-10-23 13:24:37 -04:00
Ed Hennis
044b9b8217 *facepalm* 2025-10-23 12:54:31 -04:00
Ed Hennis
f78c5f65bc Allow issuers to send LoanPay
- Implement a new helper accountCanSend, which is like accountHolds, but
  returns a meaningful value for issuers, and will include the available
  credit on the other side of a trust line. (The sfHighLimit or
  sfLowLimit as appropriate.)
- Use this new helper when checking the available balance in LoanPay.
2025-10-23 01:46:43 -04:00
Ed Hennis
6ad7d1c076 Rewrite functionality calculations to use updated calculations 2025-10-23 01:02:03 -04:00
Ed Hennis
9814ec0309 Implement tfLoanFullPayment; use updated full payment calculations 2025-10-23 00:54:58 -04:00
Ed Hennis
b3593fac1c test: Count crashed test suites 2025-10-22 20:23:54 -04:00
Ed Hennis
30e2650ff9 Use a loan scale of 0 for integral asset types
- Loan scale is completely irrelevant to integral types (XRP, MPT), and
  the field is "soeDEFAULT", so when set to 0, it won't be stored on
  ledger, saving a little bit of space.
2025-10-22 17:15:34 -04:00
Ed Hennis
4aa6baef26 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-XLS-66
* XRPLF/develop:
  Moved fix1513 to retire state (5919)
2025-10-22 11:43:39 -04:00
Ed Hennis
dd938c4e7b Add missing header file 2025-10-22 10:56:36 -04:00
Ed Hennis
92144efbdf Check that the borrower has sufficient funds to make the LoanPay 2025-10-22 00:38:05 -04:00
Ed Hennis
5da586bffc Add support for explicit overpayment flag in LoanPay
- Uses the same name and value as for LoanSet: tfLoanOverpayment.
- Untested.
- Also create several placeholders for missing test cases.
2025-10-21 23:55:46 -04:00
Ed Hennis
70ae693821 Merge branch 'develop' into ximinez/lending-XLS-66 2025-10-21 22:20:17 -04:00
Ed Hennis
f6098fd80b Expand use of Asset::integral() 2025-10-21 20:01:55 -04:00
Gregory Tsipenyuk
8757022312 test: Add unit-test to verify correct behavior on broker deep freeze (#5904)
* Add unit-test to verify correct behavior on broker deep freeze
2025-10-21 23:23:27 +00:00
Ed Hennis
587cb2533c Fix build error - XRPL_ASSERT Antithesis expansion 2025-10-21 18:12:52 -04:00
Ed Hennis
92431e11c8 Fix build error - unused variables 2025-10-21 18:05:56 -04:00
Ed Hennis
dfc4933c3b Convert Loans to track management fee and use updated rounding
- Move management fee calculations out of transactors an into the
  appropriate functions in LendingHelpers.h.
- Rewrite how overpayments are handled. May changed based on numerical
  analysis.
- Update, fix, and clean up unit tests. Includes adding tolerances for
  some checks where an exact match is unlikely.
- Add "integral()" function to Asset to simplify a common check.
2025-10-21 17:47:13 -04:00
Ed Hennis
1bb306baf4 Fix formatting 2025-10-20 13:40:27 -04:00
Ed Hennis
98d1cf07ed Compare Numbers against beast::zero 2025-10-17 18:29:09 -04:00
Ed Hennis
baabf142e4 Fix some build errors 2025-10-17 18:29:09 -04:00
Ed Hennis
f9bd9f390a Remove some unused variables, increase rounding tolerance 2025-10-17 18:29:09 -04:00
Ed Hennis
d7196a8e56 Get remaining Loan unit tests working
- Rename some of the helper functions / lambdas.
- Update tracked interestOwed field better at final payoff.
- Add checks in LoanSet that the fields can be represented in the asset
  type, and update test that fails those checks
  (testLoanPayComputePeriodicPaymentValidRateInvariant)
- Also check that the computed periodic payment can be represented as
  the asset type, and doesn't round _UP_ to 0.
- Update asserts to account for more scenarios, including initial loan
  computation.
2025-10-17 18:29:09 -04:00
Ed Hennis
bda6bb46d1 Fix the singlePayment test helper lambda 2025-10-17 18:29:09 -04:00
Ed Hennis
ec20974cae Simplify rules for creating holdings in LoanSet
- Lender and borrower both signed the transaction. Duh.
2025-10-17 18:29:08 -04:00
Ed Hennis
1efc532b21 Implement Vito's new loan payment part rounding algorithm, and more
- Implement AccountSendMulti
- Document the derivations of loan components.
- Add "loanPrincipalFromPeriodicPayment" helper.
- Removed sfReferencePrincipal
- LoanSet and LoanPay can create MPTokens as a side effect
- LoanPay will send the fee to cover if the broker owner is deep frozen,
  and fail if both of them are deep frozen.
- LoanPay will check auth for the receivers, or create holdings for the
  submitting account if needed.
- LoanSet will fail if principal requested is not positive
- Handle overpayment in a separate function
- Add a test helper to check that balance changes went as expected
- Fix more tests
2025-10-17 18:29:08 -04:00
Ed Hennis
2dd239c59f Update payment component computation and rounding, and more tests
- Tests not expected to pass.
- Check in LoanSet if a loan with interest actually has interest.
  tecPRECISION_LOSS if not.
- Add checks in LoanPay for deep froze broker owner and pseudoaccount.
- Fix management fee calculations in LoanPay and associated LoanBroker
  and Vault data updates.
- Make state tracking next payment due date optional.
- Add a test case showing multiple payments combined.
- Update more tests to work with the new fields.
2025-10-17 18:29:08 -04:00
Ed Hennis
fc2163708a Update InvariantCheck, LoanManage, and LoanPay to make tests work
- Primarily updating tests, and fixing stuff that didn't work.
- Tests still not expected to pass.
- Add Json::Value::isMember(StaticString) so SFields can be used.
- Validate more fields in ValidLoan Invariant
2025-10-17 18:29:08 -04:00
Ed Hennis
eeec90ee74 Handle overpayment calculations 2025-10-17 18:29:08 -04:00
Ed Hennis
8d982758cb Ensure interest portion doesn't go negative
- Ensure principal part is not bigger than whole payment.
- Add some documentation.
2025-10-17 18:29:08 -04:00
Ed Hennis
1b31dbc4c9 Fix build errors 2025-10-17 18:29:07 -04:00
Ed Hennis
f8b63228b6 Cool idea: Charge one extra base fee per 25 payments 2025-10-17 18:29:07 -04:00
Ed Hennis
0b8cd2d7ca Cool idea: Make Loan.NextDueDate optional; clear it when complete
- Check "simple" loanMakePayment failure conditions early
2025-10-17 18:29:07 -04:00
Ed Hennis
a8de91c57d Add LoanPaymentParts::operator+=
- Builds, but tests are not expected to pass
2025-10-17 18:29:07 -04:00
Ed Hennis
97e2c10359 Continue progress updating the LoanHelpers
- May not build
2025-10-17 18:29:07 -04:00
Ed Hennis
96d0258f51 Update LoanPay
- Enable the rest of LoanPay.
- Start updating the helper functions.
- Tests are not expected to pass.
2025-10-17 18:29:07 -04:00
Ed Hennis
fb8dafa6a8 Refactor Number, add tests, update LoanManage, update LoanPay
- Loan tests are not expected to pass.
- Refactor Number to put rounding logic into reusable functions.
- Add Number tests to explicitly test rounding - may be redundant, but
  easy to reason about.  Verifies that the default rounding matches
  banker's rounding.
- Enable LoanManage. Apparently any remaining issues were fixed by the
  previous commit's cleanups.
- Partially enabled LoanPay.
2025-10-17 18:29:06 -04:00
Ed Hennis
3cc8e5564a Start converting LoanManage to handle pre-computed fields
- Tests are not expected to pass
2025-10-17 18:29:06 -04:00
Ed Hennis
e1939d0d20 Convert LoanSet to precomputed all values
- Tests are not expected to pass
2025-10-17 18:29:06 -04:00
Ed Hennis
2509293943 Disable blocks of code using #if LOANCOMPLETE to enable build
- Will add those back later as the appropriate helpers are updated.
- Tests are not expected to pass.
2025-10-17 18:29:06 -04:00
Ed Hennis
63edf035a6 Start converting Loans to use fixed payments and track value
- Not expected to build
2025-10-17 18:29:06 -04:00
Ed Hennis
d353f4a2e6 Remove conditional LoanDraw code 2025-10-17 18:29:06 -04:00
Ed Hennis
9f1ed7ed61 Merge branch 'develop' into ximinez/lending-XLS-66 2025-10-17 18:21:49 -04:00
Ed Hennis
d700f6876d Merge remote-tracking branch 'mywork/ximinez/lending-sttx-checksign' into ximinez/lending-XLS-66
* mywork/ximinez/lending-sttx-checksign:
  Review feedback from @a1q123456
  Add jtx, STObject, and RPC support for sig object fields
  Add support for extra transaction signature validation
2025-10-17 18:21:12 -04:00
Ed Hennis
9c28578262 Review feedback from @a1q123456
- Convert STTx::getSignature to be static.
- Make the STTx::checkSign that takes a signature object private, and
  change it and all the other relevant functions to take the signature
  object as a `const&`.
- Change `getBatchTransactionIDs` to return a `const&` to reduce the
  number of vector copies. Rename `batchTxnIds_` to CamelCase. Update
  the text of the internal comment.
2025-10-17 16:26:23 -04:00
Ed Hennis
134998d86f Merge branch 'develop' into ximinez/lending-XLS-66 2025-10-16 13:12:20 -04:00
Ed Hennis
307d5474b4 Merge branch 'develop' into ximinez/lending-sttx-checksign 2025-10-16 13:12:17 -04:00
Ed Hennis
1212902be6 Merge branch 'develop' into ximinez/lending-XLS-66 2025-10-16 10:48:57 -04:00
Ed Hennis
48d458afc3 Merge branch 'develop' into ximinez/lending-sttx-checksign 2025-10-16 10:48:52 -04:00
Ed Hennis
e6e9003821 Merge branch 'develop' into ximinez/lending-XLS-66 2025-10-10 13:47:05 -04:00
Ed Hennis
66dbc05a9f Update ValidVault to allow LoanPay to change LossUnrealized
- Making a payment on an impaired loan will unimpair the loan, which
  changes Vault.LossUnrealized.
- Add a step in unit tests to impair a loan before making a payment, to
  verify, and prevent future similar regressions.
- Resolves regression RIPD-3650
2025-10-10 13:15:28 -04:00
Ed Hennis
7f4cdefc24 Merge branch 'develop' into ximinez/lending-sttx-checksign 2025-10-10 13:01:41 -04:00
Ed Hennis
8152bcb1f3 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-XLS-66
* XRPLF/develop:
  refactor: Update Conan dependencies: OpenSSL (5873)
  Add vault invariants (5518)
  test: Add more tests for Simulate RPC metadata (5827)
  chore: Fix release build error (5864)
  refactor: Update CI strategy matrix to use new RHEL 9 and RHEL 10 images (5856)
  chore: exclude all `UNREACHABLE` blocks from codecov (5846)
  Set version to 3.0.0-b1 (5859)
2025-10-09 16:15:22 -04:00
Ed Hennis
53e82a1c11 Merge branch 'develop' into ximinez/lending-sttx-checksign 2025-10-09 15:14:55 -04:00
Ed Hennis
c179135e15 Fix the build and test errors introduced by the previous merge:
** Vault Invariants for Loan txs need to be fleshed out. **

- Give the appropriate Loan transactions vault modification privileges.
- Give the appropriate Loan transactions the ability to authorize
  (create in this case) MPTokens.
- Check that LoanManage does not leave Vault in an inconsistent state
  (AssetsAvailable > AssetsTotal). For IOU vaults, if the difference is
  dust, "round up".
2025-10-09 15:09:49 -04:00
Ed Hennis
5117ef831e Merge branch 'develop' into ximinez/lending-XLS-66 2025-10-09 14:15:26 -04:00
Gregory Tsipenyuk
f35d0dc829 Add convenience functions to MPT test-framework. (#5870) 2025-10-09 04:22:38 +00:00
Ed Hennis
311da8fdcf Merge branch 'develop' into ximinez/lending-sttx-checksign 2025-10-08 14:21:41 -04:00
Ed Hennis
7120cce996 Add jtx, STObject, and RPC support for sig object fields 2025-10-06 15:40:14 -04:00
Ed Hennis
23045fcbef Add support for extra transaction signature validation
- Restructures `STTx` signature checking code to be able to handle
  a `sigObject`, which may be the full transaction, or may be an object
  field containing a separate signature. Either way, the `sigObject` can
  be a single- or multi-sign signature.
- This is distinct from 550f90a75e (#5594), which changed the check in
  Transactor, which validates whether a given account is allowed to sign
  for the given transaction. This cryptographically checks the signature
  validity.
2025-10-03 14:56:39 -04:00
Ed Hennis
d576e9d214 Include exception messages in multi signature check result 2025-10-02 22:08:03 -04:00
Ed Hennis
5863f05343 Merge branch 'develop' into ximinez/lending-XLS-66 2025-10-02 11:03:17 -04:00
Ed Hennis
ce23d0aa54 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-XLS-66
* XRPLF/develop:
  fix: Transaction sig checking functions do not get a full context (5829)
2025-10-01 18:13:53 -04:00
Ed Hennis
aac25e8c79 fixup! Review feedback from @Bronek: Add an assert 2025-10-01 15:56:06 -04:00
Ed Hennis
1888784e8e Review feedback from @Bronek: Add an assert 2025-10-01 14:15:45 -04:00
Ed Hennis
681c179174 Merge branch 'develop' into ximinez/lending-XLS-66 2025-10-01 13:14:33 -04:00
Ed Hennis
05739c59cf Merge branch 'develop' into ximinez/lending-XLS-66 2025-09-30 22:29:07 -04:00
Ed Hennis
b127b24dae Addressed review feedback from @gregtatcam:
- All current items are done
- Mostly comments
- Restructured PaymentParts (formerly PeriodicPaymentParts) to bring
  along fees, and removed the computed / combined PeriodicPayment from
  places that should be using PaymentParts instead.
2025-09-30 22:25:53 -04:00
Ed Hennis
c2a0824da0 Merge remote-tracking branch 'mywork/ximinez/lending-tx-fix' into ximinez/lending-XLS-66
* mywork/ximinez/lending-tx-fix:
  fix: Transaction sig checking functions do not get a full context
  ci: Upload artifacts during build and test in a separate job (5817)
2025-09-30 16:28:10 -04:00
Ed Hennis
e1b234cc51 fix: Transaction sig checking functions do not get a full context
- Fixes a bug introduced by PR #5594, commit 550f90a75e, which
  introduced the concept of a "sigObject", in which the signature is
  checked without necessarily being the transaction.
- Fortunately, no code uses the "sigObject" as anything other than the
  transactor yet, so the bug is harmless for now.
- This fix removes the "PreclaimContext" from the parameter list, and
  adds only the individual parts needed by the function, none of which
  are the transaction.
2025-09-30 14:39:08 -04:00
Ed Hennis
03d8cf2c12 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-XLS-66
* XRPLF/develop:
  refactor: Add support for extra transaction signatures (5594)
  refactor: Restructure Transactor::preflight to reduce boilerplate (5592)
2025-09-29 21:49:58 -04:00
Ed Hennis
7a3f7aebcf Review feedback from @gregtatcam
* Write more comments explaining what's going on.
* Rename some variables.
* Do a final safety check for valid values in `LoanPay`.
2025-09-29 21:42:03 -04:00
Ed Hennis
f78d27e9b3 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  switch `fixIncludeKeyletFields` to `Supported::yes` (5819)
2025-09-29 13:38:43 -04:00
Ed Hennis
e38e911190 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-29 13:32:12 -04:00
Ed Hennis
44313d9a30 Merge branch 'develop' into ximinez/lending-refactoring-3 2025-09-29 13:32:08 -04:00
Ed Hennis
a3365545df Review feedback from @Bronek
- Exclude impossible logging from code coverage, too.
2025-09-28 19:10:12 -04:00
Ed Hennis
1d85727675 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-26 19:26:13 -04:00
Ed Hennis
da3c2beae0 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-26 19:26:06 -04:00
Ed Hennis
6b7136906f Merge branch 'develop' into ximinez/lending-refactoring-3 2025-09-26 19:26:02 -04:00
Ed Hennis
7612fd0ba6 Review feedback from @gregtatcam
- Amendment checking correctness.
- Sync some changes between LoanBrokerCoverWithdraw and CoverDeposit.
- Check for nulls.
- Add documentation.
2025-09-26 19:23:13 -04:00
Ed Hennis
0bd6b1ae49 Review feedback from @mvadari
- Clarify the purpose of the assert in calculateOwnerReserveFee
2025-09-26 16:05:15 -04:00
Ed Hennis
66216a3d41 Review feedback from @mvadari
- Add a test for preflightCheckSigningKey
2025-09-26 15:36:12 -04:00
Ed Hennis
4b90f97e52 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-26 13:41:43 -04:00
Ed Hennis
f1a2fe3d0a Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-26 13:41:35 -04:00
Ed Hennis
d76f31cb7c Merge branch 'develop' into ximinez/lending-refactoring-3 2025-09-26 13:41:31 -04:00
Ed Hennis
b5caa9c63d Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-26 12:09:25 -04:00
Ed Hennis
3931eb39d5 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-26 12:09:17 -04:00
Ed Hennis
322308f7d1 Merge branch 'develop' into ximinez/lending-refactoring-3 2025-09-26 12:09:13 -04:00
Ed Hennis
4c8f7968c4 Tweak payment rounding 2025-09-25 16:11:02 -04:00
Ed Hennis
6e2965f01a Add test cases for Vault prereq amendments being disabled 2025-09-25 15:26:30 -04:00
Ed Hennis
dba3af9318 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-25 13:27:17 -04:00
Ed Hennis
7304ee68d5 Merge branch 'develop' into ximinez/lending-refactoring-3 2025-09-25 13:27:13 -04:00
Ed Hennis
759d114ab8 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  docs: Add warning about using std::counting_semaphore (#5595)
  Revert "Update Conan dependencies: OpenSSL" (#5807)
  test: Add STInteger and STParsedJSON tests (#5726)
  Review feedback from @mvadari
2025-09-24 16:10:16 -04:00
Ed Hennis
3c93dbbc7c Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-24 15:49:59 -04:00
Ed Hennis
97819b23ba Merge branch 'develop' into ximinez/lending-refactoring-3 2025-09-24 15:49:56 -04:00
Ed Hennis
9bfa88cd86 Fix build error
- New code referenced `isEnabled`, which was renamed in an updated prereq PR
2025-09-24 15:38:53 -04:00
Ed Hennis
de5af71cb6 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-22 11:26:20 -04:00
Ed Hennis
67578b8f50 Review feedback from @mvadari
- Clean up some of the flag and extra feature checks for readability
2025-09-22 11:17:13 -04:00
Ed Hennis
e72a9d4bf2 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-20 17:12:32 -04:00
Ed Hennis
5b576b841c Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-20 17:12:26 -04:00
Ed Hennis
267b537a13 Review feedback from @Bronek
- Fix a moved assert message
- Rename `Transactor::isEnabled` to `checkExtraFeatures`, and finish
  cleaning up a few classes I missed on the first pass (Vault*
  & XChainBridge*).
2025-09-20 17:09:48 -04:00
Ed Hennis
543f1e702f Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-20 15:44:46 -04:00
Ed Hennis
f9dcce2d7e Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-20 15:44:39 -04:00
Ed Hennis
928af9633f Merge branch 'develop' into ximinez/lending-refactoring-3 2025-09-20 15:44:36 -04:00
Ed Hennis
9e84c37306 Refactor full payment into a function, and update some formatting 2025-09-18 14:54:49 -04:00
Ed Hennis
2aa626c205 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-18 14:08:42 -04:00
Ed Hennis
36c2fa1e56 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-18 14:08:35 -04:00
Ed Hennis
886b0a487c Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-18 14:08:31 -04:00
Ed Hennis
7849df5feb Merge branch 'develop' into ximinez/lending-refactoring-2 2025-09-18 14:08:27 -04:00
Ed Hennis
55baf35d9c Fix build errors due to private type access 2025-09-18 13:30:50 -04:00
Ed Hennis
90ca9ea71a Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  refactor: Modularise ledger (5493)
  chore: Add unit tests dir to code coverage excludes (5803)
  chore: Build and test all configs for daily scheduled run (5801)
  chore: Limits CI build and test parallelism to reduce resource contention (5799)
  fix(amendment): Add missing fields for keylets to ledger objects (5646)
  Rename mutable flags (5797)
  Set version to 2.6.1-rc1
  Downgrade to boost 1.83
  Set version to 2.5.1
  Fix: Don't flag consensus as stalled prematurely (5658)
2025-09-18 13:17:29 -04:00
Ed Hennis
47eb1e8db2 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-18 12:26:50 -04:00
Ed Hennis
540b76fe42 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-18 12:26:46 -04:00
Ed Hennis
d4135a9115 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-18 12:26:42 -04:00
Ed Hennis
4c6a34d3c1 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-18 12:26:38 -04:00
Ed Hennis
be5390b8c7 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-refactoring-1
* XRPLF/develop:
  refactor: Modularise ledger (5493)
  chore: Add unit tests dir to code coverage excludes (5803)
  chore: Build and test all configs for daily scheduled run (5801)
  chore: Limits CI build and test parallelism to reduce resource contention (5799)
  fix(amendment): Add missing fields for keylets to ledger objects (5646)
  Rename mutable flags (5797)
  Set version to 2.5.1
  Fix: Don't flag consensus as stalled prematurely (5658)
2025-09-18 12:03:29 -04:00
Ed Hennis
b5ddc812ea Review feedback from @gregtatcam:
- In progress
- Add explanatory comments, and start refactoring
  loanComputePaymentParts into functions for readability.
2025-09-17 19:37:59 -04:00
Ed Hennis
b9a2eb3399 Review feedback from @gregtatcam
- Remove a redundant struct LoanPaymentParts declaration.
- Add pointers to the XLS-66 spec for all of the LendingHeler formulas.
- Changed if/else if in LoanManage.
2025-09-17 16:54:50 -04:00
Ed Hennis
2c0c4567f4 Rewrite LoanManage flag check to skip if field not set or 0 2025-09-17 15:41:03 -04:00
Ed Hennis
d1c708ca01 Remove A BUNCH of unnecessary includes from the Loan/Lending files 2025-09-17 13:31:56 -04:00
Ed Hennis
ae27376863 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-17 10:49:29 -04:00
Ed Hennis
e237f968c7 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-17 10:49:20 -04:00
Ed Hennis
b02b58e3b5 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-17 10:49:15 -04:00
Ed Hennis
d10ac3b169 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-17 10:49:11 -04:00
Ed Hennis
c37f863201 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-17 10:49:07 -04:00
Ed Hennis
1fbd3fcfa4 Handle Flags not present in LoanManage
- Addresses RIPD-3418
2025-09-16 19:31:01 -04:00
Ed Hennis
70755ed1d3 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-16 19:04:59 -04:00
Ed Hennis
6926c511cb Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-16 19:04:53 -04:00
Ed Hennis
e01dd6d5b0 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-16 19:04:49 -04:00
Ed Hennis
0bfd404111 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-16 19:04:45 -04:00
Ed Hennis
5c072579d7 Review feedback from @yinyiqian1 and @Bronek
- Rewrite all of the templates in Units.h to use concepts.
- Restrict to_short_string to reasonably sized values.
- Rephrase some comments, and fix some typos.
2025-09-16 18:50:24 -04:00
Ed Hennis
c118121337 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-16 17:19:54 -04:00
Ed Hennis
8a4c607af9 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-16 17:19:47 -04:00
Ed Hennis
f85ce9c742 Remove or simplify Transactor::isEnabled overrides
- Remove the ones where the only condition was the required amendment
  specified in transactor.macro.
- Simplify the one that had other conditions, removing the required
  amendment from the conditions.
2025-09-16 17:15:57 -04:00
Ed Hennis
49e1f97476 Fix formatting 2025-09-16 17:10:28 -04:00
Ed Hennis
47aa95fcc4 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-16 15:07:11 -04:00
Ed Hennis
dc5b0918da Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-16 15:07:04 -04:00
Ed Hennis
cb991523f8 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-16 15:07:00 -04:00
Ed Hennis
9683344940 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-16 15:06:55 -04:00
Ed Hennis
5ac905be01 Fix issuer MPT balance sign on tests introduced by 5571 2025-09-16 14:51:18 -04:00
Ed Hennis
4d5afbea3a Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  Bugfix: Adds graceful peer disconnection (5669)
  Support DynamicMPT XLS-94d (5705)
  Only notify clio for PRs targeting the release and master branches (5794)
  refactor: Wrap GitHub CI conditionals in curly braces (5796)
2025-09-16 11:26:18 -04:00
Ed Hennis
9d08fe9a03 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-16 11:15:04 -04:00
Ed Hennis
84e97f0ef5 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3
* XRPLF/ximinez/lending-refactoring-2:
  Bugfix: Adds graceful peer disconnection (5669)
  Support DynamicMPT XLS-94d (5705)
  Only notify clio for PRs targeting the release and master branches (5794)
  refactor: Wrap GitHub CI conditionals in curly braces (5796)
2025-09-16 11:14:06 -04:00
Ed Hennis
4d24b5eac2 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-16 10:46:45 -04:00
Ed Hennis
935749fe1f Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-16 10:46:41 -04:00
Ed Hennis
49eb1cc54e Remove LoanDraw transaction (#5792) 2025-09-16 00:30:02 +00:00
Ed Hennis
dee972e9cd Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  Fix: EscrowTokenV1 (5571)
  fix: Skip processing transaction batch if the batch is empty (5670)
  ci: Fix conan secrets in `upload-conan-deps` (5785)
  Fix code coverage error (5765)
  docs: Add remote to `conan lock create` command (5770)
  refactor: clean up `CTID.h` (5681)
2025-09-15 11:25:13 -04:00
Ed Hennis
bdeed43304 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-15 11:13:45 -04:00
Ed Hennis
7eff303160 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-15 11:13:40 -04:00
Ed Hennis
aa1341f42e Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-15 11:13:36 -04:00
Ed Hennis
91031dbec4 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-15 11:13:32 -04:00
Ed Hennis
03da5da815 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-11 10:33:38 -04:00
Ed Hennis
fc860c1a1d Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-11 10:33:30 -04:00
Ed Hennis
2545bc5936 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-11 10:33:26 -04:00
Ed Hennis
9a9588eaf6 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-11 10:33:22 -04:00
Ed Hennis
abee3dd55c Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-11 10:33:17 -04:00
Ed Hennis
22d9ade2b0 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-10 20:36:49 -04:00
Ed Hennis
3ea0fa67cb Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-10 20:36:43 -04:00
Ed Hennis
1b295c7c00 Use Permission to check if a Transactor is enabled
- Adds a Permission::getTxFeature lookup function to find the
  controlling amendment for a Transactor, if any.
- Returns temDISABLED from preflight if there is an amendment and it's
  not enabled.
- Still need to go through and remove all the now-redundant isEnabled
  functions.
2025-09-10 20:33:01 -04:00
Ed Hennis
dd52a50acc Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  fixup! Make a few tweaks to the changes in 43fe49e7
  Fix Vault tests broken by negative MPT issuer balance
  Make a few tweaks to the changes in 43fe49e7
  fix: Add restrictions to Permission Delegation: fixDelegateV1_1 (5650)
  ci: Add missing dependencies to workflows (5783)
  ci: Use default conan install format (5784)
  Switch CI pipeline bookworm:gcc-13 from arm64 to amd64 (5779)
2025-09-10 20:01:15 -04:00
Ed Hennis
80a2d8f789 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-10 19:39:58 -04:00
Ed Hennis
e5f99e8ee7 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-10 19:39:55 -04:00
Ed Hennis
b925ed44a0 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-10 19:39:51 -04:00
Ed Hennis
14ff03821c Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-refactoring-1
* XRPLF/develop:
  fix: Add restrictions to Permission Delegation: fixDelegateV1_1 (5650)
  ci: Add missing dependencies to workflows (5783)
  ci: Use default conan install format (5784)
  Switch CI pipeline bookworm:gcc-13 from arm64 to amd64 (5779)
2025-09-10 19:34:05 -04:00
Ed Hennis
5ff6bc496a fixup! Make a few tweaks to the changes in 43fe49e7 2025-09-10 18:20:47 -04:00
Ed Hennis
7aaad4a8ef Fix Vault tests broken by negative MPT issuer balance 2025-09-10 17:00:05 -04:00
Ed Hennis
1897ac5ee7 Make a few tweaks to the changes in 43fe49e7
- This was the first merge after I got back from sabbatical. I made
  these same changes in "ximinez/lending-XLS-66" commit 9d052dc, but
  after seeing some test failures, I think they belong here.
2025-09-10 16:49:13 -04:00
Ed Hennis
5894cd2103 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-09 17:14:41 -04:00
Ed Hennis
2f89182fd3 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-09 17:14:34 -04:00
Ed Hennis
4191ddd702 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-09 17:14:30 -04:00
Ed Hennis
37888b97ba Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-09 17:14:27 -04:00
Ed Hennis
10f7e4a02a Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-09 17:14:23 -04:00
Ed Hennis
e5941d5b23 Simplify flag exclusion check in LoanManage 2025-09-09 16:29:35 -04:00
Ed Hennis
3f1a0f3a3d Fix some build errors from yesterday 2025-09-09 15:25:51 -04:00
Ed Hennis
fa2c595a59 Add more value validation in LoanSet
- Don't allow negative numbers.
- Don't send the origination fee if it's defined, but 0.
2025-09-08 17:57:56 -04:00
Ed Hennis
fc6fe9802e Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-08 11:42:09 -04:00
Ed Hennis
b3c40ad408 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-08 11:42:01 -04:00
Ed Hennis
779e94bc03 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-08 11:41:57 -04:00
Ed Hennis
f653ca03d9 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-08 11:41:53 -04:00
Ed Hennis
d46e477092 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-08 11:41:50 -04:00
Ed Hennis
24f58a2e94 Fix test loop 2025-09-05 23:46:48 -04:00
Ed Hennis
e3358ad124 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-05 20:29:04 -04:00
Ed Hennis
5102147709 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-05 20:28:58 -04:00
Ed Hennis
0a54c09de1 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-05 20:28:54 -04:00
Ed Hennis
d594ca1401 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-05 20:28:50 -04:00
Ed Hennis
5335c04616 Fix constexpr expression 2025-09-05 20:28:12 -04:00
Ed Hennis
6db14ccb13 More review feedback from @gregtatcam
- Also fix a few build errors that I missed earlier.
- Updated freeze check rules for LoanSet.
- Fixed the debt total calculation and check in LoanSet.
- Removed _some_ unnecessary includes.
2025-09-05 20:00:10 -04:00
Ed Hennis
582f56487d Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-05 17:44:28 -04:00
Ed Hennis
d47c039941 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-05 17:44:20 -04:00
Ed Hennis
bf4ae57da4 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-05 17:44:17 -04:00
Ed Hennis
83702e79bf Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-05 17:44:13 -04:00
Ed Hennis
6379363bad Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-05 17:44:10 -04:00
Ed Hennis
f0c96ccfe6 Review feedback from @yinyiqian1
- Rewrite to_short_string to call strHex directly instead of building
  the whole hex string first.
- Change PrettyAsset::scale_ back to a uint32 since the Number
  conversion elides any potential multiplication overflow.
- Clean ups.
2025-09-05 17:41:06 -04:00
Ed Hennis
4c726838d1 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-04 20:25:16 -04:00
Ed Hennis
47bcc67d56 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-04 20:25:09 -04:00
Ed Hennis
4b48f9612b Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-04 20:25:05 -04:00
Ed Hennis
7bba34832b Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-04 20:25:02 -04:00
Ed Hennis
76ae61feb5 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-04 20:24:58 -04:00
Ed Hennis
adb260fe17 Review feedback from @dangell7 and @gregtatcam
- Mostly adding comments.
- Fixed some function parameter names that weren't updated after
  a copy/paste.
- LoanBrokerCoverWithdraw does not need to check for freeze when sending
  to the issuer.
- Reorder the fund transfer cases in LoanBrokerCoverWithdraw to make it
  clearer that some transfers are direct, and some use the payment
  engine.
- Only look up the vault ID once in LoanBrokerSet
2025-09-04 20:21:30 -04:00
Ed Hennis
8444a944af Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-04 16:44:10 -04:00
Ed Hennis
6d20e59212 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-04 16:44:03 -04:00
Ed Hennis
c49cf6cec6 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-04 16:43:59 -04:00
Ed Hennis
e24f034b17 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-04 16:43:56 -04:00
Ed Hennis
72733b57e4 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-04 16:43:52 -04:00
Ed Hennis
7a78449f6d Fix minor review feedback from @Bronek
- Clean up assert, log, and comments
2025-09-04 15:53:04 -04:00
Ed Hennis
0d500343ed New invariant privilege "mayDeleteMPT", used by VauleDeposit & Clawback 2025-09-04 14:08:54 -04:00
Ed Hennis
f15e88c009 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-04 13:15:41 -04:00
Ed Hennis
0069c0c5fa Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-04 13:15:35 -04:00
Ed Hennis
450d38293d Remove unused variable 2025-09-04 13:14:19 -04:00
Ed Hennis
6d9001edac Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-04 12:37:00 -04:00
Ed Hennis
3dc14e7430 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4
* XRPLF/ximinez/lending-refactoring-3:
  ci: Use cleanup-workspace action (5763)
  Add `Scale` to SingleAssetVault (5652)
2025-09-04 12:35:39 -04:00
Ed Hennis
9a8c2523ae Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3
* XRPLF/ximinez/lending-refactoring-2:
  ci: Use cleanup-workspace action (5763)
  Add `Scale` to SingleAssetVault (5652)
2025-09-04 12:29:41 -04:00
Ed Hennis
115161f7d2 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-04 12:27:02 -04:00
Ed Hennis
77fcb9b9b3 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-04 12:26:58 -04:00
Ed Hennis
d2e8144c53 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-refactoring-1
* XRPLF/develop:
  Add `Scale` to SingleAssetVault (5652)
2025-09-04 12:25:49 -04:00
Ed Hennis
9d45fd1873 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-03 21:01:09 -04:00
Ed Hennis
4c43a0bca4 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-03 21:01:01 -04:00
Ed Hennis
bb491431bd Review feedback from @dangell7 and @mvadari
- Rewrite isTesSuccess to use TERSubset::operator bool
- Add Transactor::preflightSigValidated for expensive operations that
  should be done after signature validation. These things would have
  been done after preflight2 before this refactor.
- Split Batch and EscrowFinish preflight to use preflightSigValidated, too.
2025-09-03 20:51:40 -04:00
Ed Hennis
f090434c2d Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-03 19:21:10 -04:00
Ed Hennis
5f7b4a5e13 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-03 19:21:00 -04:00
Ed Hennis
11b8f9978e Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-03 19:20:57 -04:00
Ed Hennis
58551da698 Review feedback from @dangell7 and @Bronek
- Added more `STParsedJSON` test cases.
- Add a `safe_cast` conversion in `parseUint32`.
2025-09-03 19:18:24 -04:00
Ed Hennis
5ade8756f6 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  Review feedback from @Bronek
  Rewrite Units.h and same safe_cast.h restrictions to use concepts
* Also add required support for LoanBroker and Loan ledger entries
2025-09-03 18:41:24 -04:00
Ed Hennis
ac4c4905df Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-03 18:10:26 -04:00
Ed Hennis
a5f1879afb Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-03 18:10:23 -04:00
Ed Hennis
8a77ac71ed Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-03 18:10:19 -04:00
Ed Hennis
a72c237373 Review feedback from @Bronek
- Remove unnecessary #include
- Explanatory comments
- Make the MPT InvariantCheck related to EscrowFinish amendment safe
- Convert SField maps to unordered_maps
- Make jtx::fee::operator() clearer
- Rename checkMyPrivilege to hasPrivilege
2025-09-03 18:04:05 -04:00
Ed Hennis
faae2514b9 Rewrite Units.h and same safe_cast.h restrictions to use concepts 2025-09-03 16:14:28 -04:00
Ed Hennis
bcbbf71f29 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-03 14:04:25 -04:00
Ed Hennis
12994d4251 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-03 14:04:15 -04:00
Ed Hennis
22679673f6 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-03 14:04:12 -04:00
Ed Hennis
a14cbf117c Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-03 14:04:08 -04:00
Ed Hennis
5ce07e769f Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-03 14:04:05 -04:00
Ed Hennis
08a5e8428a Require all SFields to have a name
- From @bronek https://github.com/XRPLF/rippled/pull/5590#discussion_r2290589770
- Adds consistency, and ensures sfInvalid and sfGeneric are handled the
  same as all other SFields
2025-08-29 20:11:28 -04:00
Ed Hennis
a8e35f8399 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-29 17:58:21 -04:00
Ed Hennis
1f85888ae8 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-29 15:53:07 -04:00
Ed Hennis
183450db46 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-29 15:53:04 -04:00
Ed Hennis
64959b980f Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-29 15:53:00 -04:00
Ed Hennis
0b833e17ae Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-29 15:52:57 -04:00
Ed Hennis
2e3c5543f2 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-29 10:43:01 -04:00
Ed Hennis
0475398a17 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-29 10:42:57 -04:00
Ed Hennis
bf483a2e94 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-29 10:42:54 -04:00
Ed Hennis
5e3539d6bb Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-28 18:17:49 -04:00
Ed Hennis
a90265dd2a Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-28 18:17:40 -04:00
Ed Hennis
8498ed9df4 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-28 18:17:36 -04:00
Ed Hennis
4169b0a6b7 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-28 18:17:33 -04:00
Ed Hennis
024339c99b Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-28 18:17:29 -04:00
Ed Hennis
044697c438 fix: Allow the borrower to delete a completed / inactive loan, too. 2025-08-27 15:26:45 -04:00
Ed Hennis
2aebeeb966 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-27 11:15:23 -04:00
Ed Hennis
4c79fe46c9 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-27 11:15:14 -04:00
Ed Hennis
51abafea26 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-27 11:15:10 -04:00
Ed Hennis
f1f1117b08 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-27 11:15:06 -04:00
Ed Hennis
5bb12ac1db Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-27 11:15:03 -04:00
Ed Hennis
dbd9a05e10 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-25 19:51:13 -04:00
Ed Hennis
8981885196 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-25 19:51:04 -04:00
Ed Hennis
a7390c070f Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-25 19:51:01 -04:00
Ed Hennis
4d0f895cda Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-25 19:50:57 -04:00
Ed Hennis
48162219ac Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-25 19:50:54 -04:00
Ed Hennis
1cb4a49ad3 Make a note about PR #5650 integration 2025-08-25 19:48:31 -04:00
Ed Hennis
18ffbbd42d Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-22 20:34:42 -04:00
Ed Hennis
7f1c0e55d6 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-22 19:31:36 -04:00
Ed Hennis
1876ffcd71 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-22 19:31:24 -04:00
Ed Hennis
3ef1e4269b Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-22 19:31:20 -04:00
Ed Hennis
ae25e0f058 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-22 19:31:17 -04:00
Ed Hennis
7d634c1e62 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-22 19:31:14 -04:00
Ed Hennis
f713208d89 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-22 19:09:07 -04:00
Ed Hennis
5d98799205 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-22 19:08:55 -04:00
Ed Hennis
9086c678a9 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-22 19:08:52 -04:00
Ed Hennis
e434563e2e Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-22 19:08:48 -04:00
Ed Hennis
29300fc972 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-refactoring-1
* XRPLF/develop:
  chore: Update clang-format and prettier with pre-commit (5709)
  fix(test): handle null metadata for unvalidated tx in Env::meta (5715)
  chore: Workaround for CI build errors on arm64 (5717)
  chore: Fix file formatting (5718)
  fix: Skip notify-clio when running in a fork, reorder config fields (5712)
  chore: Reverts formatting changes to external files, adds formatting changes to proto files (5711)
2025-08-22 19:07:28 -04:00
Ed Hennis
a88aceb846 Reformat transactions.macro 2025-08-22 16:02:59 -04:00
Ed Hennis
9986346d60 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-21 11:39:20 -04:00
Ed Hennis
7c642783f4 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-21 11:39:09 -04:00
Ed Hennis
0f1a2324bc Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-21 11:39:05 -04:00
Ed Hennis
2d570267de Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-21 11:39:01 -04:00
Ed Hennis
97849b6e70 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-21 11:38:57 -04:00
Ed Hennis
5d2a7d651e Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  Review feedback from @dangell7
2025-08-19 20:22:54 -04:00
Ed Hennis
b26477a21e Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-19 20:11:45 -04:00
Ed Hennis
422a99bb26 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-19 20:11:42 -04:00
Ed Hennis
b447fc54c8 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-19 20:11:38 -04:00
Ed Hennis
9920037d13 Review feedback from @dangell7
- Cleaned up some of the `LEDGER_ENTRY` macros by eliding unnecessary
  parameters.
- Define the transaction privileges in one place (InvariantCheck.cpp).
- Give `EscrowFinish` the `mayAuthorizeMPT` privilege.
- Rename the test helper `expectLine` to `expectHolding` since
  it handles both trust lines and MPTs.
- Restructure the ""pseudo-account has 2 pseudo-account fields set"
  invariant test to loop over all defined pseudo-account fields.
- Fix `operator<<` for `PrettyAmount` to handle `MPTIssue`s.
- Add enforcement of the `AccountRootsDeletedClean` invariant if SAV is
  enabled, and clarify the comment for the pseudo-account field check.
- Delete the 100% redundant `ttMPTOKEN_ISSUANCE_SET` check in
  `ValidMPTIssuance`.
2025-08-19 19:52:30 -04:00
Ed Hennis
714e12f44f Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-19 16:14:20 -04:00
Ed Hennis
fba91487ec Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-19 16:05:34 -04:00
Ed Hennis
49ea5cc152 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-19 16:05:30 -04:00
Ed Hennis
87e0c25a34 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-19 16:05:26 -04:00
Ed Hennis
a648249b90 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-19 16:05:21 -04:00
Ed Hennis
083ab7b054 Prevent Vault unrealized loss from exceeding "unavailable" assets 2025-08-19 15:15:10 -04:00
Ed Hennis
b6ef337e45 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  fix: Modify jobs to use '>>' instead of 'tee' for GITHUB_OUTPUT (5699)
  refactor: Revamp CI workflows (5661)
  refactor: Decouple net from xrpld and move rpc-related classes to the rpc folder (5477)
  Set version to 2.6.0-rc2
  docs: Updates list of maintainers and reviewers (5687)
  fix: Change log to debug level for AMM offer retrieval and IOU payment check (5686)
  fix: Add -Wno-deprecated-declarations for Clang only (5680)
  Update .git-blame-ignore-revs for 5657 (5675)
  Fix BUILD.md instruction (5676)
  Set version to 2.6.0-rc1
  fix: Improve logging of the reason to refuse a peer connection (5664)
  fix: Make test suite names match the directory name (5597)
  chore: Run prettier on all files (5657)
  chore: Set CONAN_REMOTE_URL also for forks (5662)
  chore: Cleanup bin/ directory (5660)
  perf: Optimize hash performance by avoiding allocating hash state object (5469)
2025-08-18 20:36:35 -04:00
Ed Hennis
e62efa2a90 Fix unit tests broken by the addition of signature_target
- Specifically some of the tests for sign and submit
2025-08-18 20:32:53 -04:00
Ed Hennis
3867945b46 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-18 12:44:41 -04:00
Ed Hennis
084896189d Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-18 12:25:55 -04:00
Ed Hennis
e9033898da Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-18 12:25:51 -04:00
Ed Hennis
d952e9de1a Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-refactoring-1
* XRPLF/develop:
  fix: Modify jobs to use '>>' instead of 'tee' for GITHUB_OUTPUT (#5699)
  refactor: Revamp CI workflows (#5661)
  refactor: Decouple net from xrpld and move rpc-related classes to the rpc folder (#5477)
  Set version to 2.6.0-rc2
  docs: Updates list of maintainers and reviewers (#5687)
  fix: Change log to debug level for AMM offer retrieval and IOU payment check (#5686)
  fix: Add -Wno-deprecated-declarations for Clang only (#5680)
  Update .git-blame-ignore-revs for #5657 (#5675)
  Fix BUILD.md instruction (#5676)
  Set version to 2.6.0-rc1
  fix: Improve logging of the reason to refuse a peer connection (#5664)
  fix: Make test suite names match the directory name (#5597)
  chore: Run prettier on all files (#5657)
  chore: Set CONAN_REMOTE_URL also for forks (#5662)
  chore: Cleanup bin/ directory (#5660)
  perf: Optimize hash performance by avoiding allocating hash state object (#5469)
2025-08-18 12:22:43 -04:00
Ed Hennis
bc3c9e1534 fixup! Add Counterparty signing support 2025-08-09 01:19:38 -04:00
Ed Hennis
6d137e44dc Add Counterparty signing support
- Add a new parameter "signature_target" to "sign". Supports single and
  multisign, but I haven't written tests for multisign yet.
- Skip account validation if this field is set, like multisigning.
- Unit tests demonstrating examples.
2025-08-09 00:55:00 -04:00
Ed Hennis
6778521f12 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-08 18:30:40 -04:00
Ed Hennis
b0f3ef4969 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-08 18:23:37 -04:00
Ed Hennis
c01ef3f155 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-08 18:23:34 -04:00
Ed Hennis
241f22bab7 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-08 18:23:30 -04:00
Ed Hennis
a387a7aadf Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-08 18:23:27 -04:00
Ed Hennis
d5e137de82 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-refactoring-1
* XRPLF/develop:
  Switch Conan 1 commands to Conan 2 and fix credentials (#5655)
  perf: Move mutex to the partition level (#5486)
  Upload Conan dependencies upon merge into develop (#5654)
2025-08-08 11:31:44 -04:00
Ed Hennis
e0cdd65352 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-06 21:08:14 -04:00
Ed Hennis
2c1ccdbc84 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-06 21:03:14 -04:00
Ed Hennis
36204d2ce9 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-06 21:03:10 -04:00
Ed Hennis
4639c1c351 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-06 21:03:07 -04:00
Ed Hennis
c863bd25e0 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-06 21:03:04 -04:00
Ed Hennis
7dcc682e29 Make LoanSet.CounterpartySignature optional in the Tx layout
- Still required for the transaction to succeed (except inside a Batch,
  because the batch signers take care of that).
- Started adding tests for Loan-related RPC and low-level math checks.
  Currently only implemented "sign" on a LoanSet to verify it can be
  done.
2025-08-06 20:48:13 -04:00
Ed Hennis
162875616d Correct more issues related to 0-interest loans and some rounding issues
- Addresses FIND-012 from audit.
- If computePeriodicPaymentParts rounds the principal part to 0, add
  a small amount so that some principal is paid regardless of how
  extreme the loan parameters are. For XRP and MPTs, this just adds 1.
  For IOUs, compute an epsilon based on the scale of the original loan.
  (IOUs untested.)
  - Also move this function out of the detail namespace so direct unit
    tests can be written. (Pending.)
- Adds the testLoanPayComputePeriodicPaymentValidRateInvariant from
  auditors with some minor modifications.
- Fixes an assert that the periodic rate > 0, which won't be true if the
  loan interest rate is 0.
2025-08-06 11:47:42 -04:00
Ed Hennis
9847025099 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  Fix formatting
  fix: Ensures canonical order for `PriceDataSeries` upon `PriceOracle` creation (#5485)
  Add code coverage for STParsedJSON edge cases
  refactor: Decouple ledger from xrpld/app (#5492)
2025-08-05 21:30:31 -04:00
Ed Hennis
bb183ea09a Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-05 21:16:57 -04:00
Ed Hennis
9fd45e7aa7 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-05 21:16:54 -04:00
Ed Hennis
924b05ea9f Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-05 21:16:50 -04:00
Ed Hennis
a0a0916108 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-05 21:16:47 -04:00
Ed Hennis
c78b9aedac Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-05 21:16:34 -04:00
Ed Hennis
b07087f10b Fix formatting 2025-08-05 13:20:29 -04:00
Ed Hennis
f89c88dbb8 Add code coverage for STParsedJSON edge cases
- Move several tests from `STObject_test` to new `STParsedJSON_test`
  unchanged.
- Add 3 test cases to cover edge cases for UInt16 values.

Co-authored-by: Denis Angell <dangell@transia.co>
2025-08-05 12:45:05 -04:00
Ed Hennis
0c76153b2c Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-04 13:05:06 -04:00
Ed Hennis
70a23bcca3 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-04 13:05:02 -04:00
Ed Hennis
a66ef800bc Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-04 13:04:59 -04:00
Ed Hennis
5f5f60a024 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-04 13:04:55 -04:00
Ed Hennis
d58399d417 Correct handling of LoanBroker.DebtMaximum zero values
- Addresses FIND-003 from audit.
- Behavior changed to treat a DebtMaximum value of 0 to mean "no limit",
  as defined in spec.
- No need to add unit tests, because the previous commit covers 0, and
  tests already exist for non-zero limits.
2025-07-30 18:08:05 -04:00
Ed Hennis
a1e9091f1e Add the "testBatchBypassCounterparty" test from auditors
- (With some minor modifications)
2025-07-30 17:25:58 -04:00
Ed Hennis
84acebeb7f Enforce valid range of LoanSet.InterestRate
- Addresses FIND-002 from audit.
- Enforces a range of 0-100% in 1/10 bips.
- Also add a couple of unit test checks.
2025-07-30 13:56:50 -04:00
Ed Hennis
83ba11d505 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  fix `DeliveredAmount` and `delivered_amount` in transaction metadata for direct MPT transfer (#5569)
2025-07-30 11:07:03 -04:00
Ed Hennis
97469a1c02 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-07-29 20:33:43 -04:00
Ed Hennis
c74dc6baf2 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-07-29 20:33:40 -04:00
Ed Hennis
1d90ae7c25 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-07-29 20:33:36 -04:00
Ed Hennis
39db7381b2 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-07-29 20:33:32 -04:00
Ed Hennis
ec8eaf0d73 fixup! Ensure Counterparty Signatures are properly handled by Batch tx 2025-07-29 20:31:31 -04:00
Ed Hennis
9d1a23a811 Ensure Counterparty Signatures are properly handled by Batch tx
- Addresses FIND-001 from audit
- LoanSet::preflight will require Counterparty to be set (it's normally
  optional) for an inner batch transaction, because the checks are done
  before the LoanBroker object can be accessed.
- Adjust LoanSet::calculateBaseFee to not charge extra if an inner
  transaction.
- Adds a Loan-specific test to Batch_test.
2025-07-29 19:46:01 -04:00
Ed Hennis
421cbb9abd Add the "testBatchBypassCounterparty" test from auditors
- (With some minor modifications)
2025-07-29 19:34:02 -04:00
Ed Hennis
bba9119a75 Fix a couple of errors
- Mark variable only used in asserts as [[maybe_unused]].
- Restore commented out line that I think I resolved wrong in an earlier
  merge to fix Vault tests.
2025-07-29 14:58:36 -04:00
Ed Hennis
6f00f296c8 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-07-29 12:31:48 -04:00
Ed Hennis
aee4719df4 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-07-29 11:54:30 -04:00
Ed Hennis
5f2402479d Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-07-29 11:54:26 -04:00
Ed Hennis
c3fa4fb71c Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-07-29 11:54:23 -04:00
Ed Hennis
a8d0d763b0 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-07-29 11:54:19 -04:00
Ed Hennis
6310b2544c Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  Build options cleanup (#5581)
  Updates Conan dependencies: Boost 1.86 (#5264)
  VaultWithdraw destination account bugfix (#5572)
2025-07-28 21:10:12 -04:00
Ed Hennis
3c0ef8f8d3 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-07-28 20:57:29 -04:00
Ed Hennis
ebe39e9320 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-07-28 20:57:24 -04:00
Ed Hennis
1b8da176bf Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-07-28 20:57:21 -04:00
Ed Hennis
66dd0de019 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-07-28 20:57:17 -04:00
Ed Hennis
a2be55fbc9 Check LoanBrokerCoverWithdraw Destination and DestinationTag fields
- See also #5572 / e7a7bb8
2025-07-28 19:04:55 -04:00
Ed Hennis
41c24094eb Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-07-24 17:00:57 -04:00
Ed Hennis
3b446f144f Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-07-24 16:13:47 -04:00
Ed Hennis
760a9aad83 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3
* XRPLF/ximinez/lending-refactoring-2:
  refactor: Update rocksdb (#5568)
  Switch instrumentation workflow to use dependencies (#5607)
  chore: Rename conan profile to `default` (#5599)
  Include `network_id` in validations and subscription stream responses (#5579)
  Add support for `DomainID` in `MPTokenIssuance` transactions (#5509)
  chore: Remove unused code after flow cross retirement (#5575)
  Remove obsolete owner pays fee feature and XRPL_ABANDON stanza (#5550)
  refactor: Makes HashRouter flags more type-safe (#5371)
  Fix clang-format CI job (#5598)
2025-07-24 16:12:48 -04:00
Ed Hennis
c73372297c Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-07-24 15:50:17 -04:00
Ed Hennis
1f331bf8d8 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-07-24 15:50:13 -04:00
Ed Hennis
57c78c56ba fixup! fixup! Fix divide by 0 error on 0-interest loans; allow broker to self-lend 2025-07-24 15:08:18 -04:00
Ed Hennis
1adb410e8e fixup! Fix divide by 0 error on 0-interest loans; allow broker to self-lend 2025-07-24 13:58:05 -04:00
Ed Hennis
6444ad4393 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  fixup! Rename Transactor preflight functions
  Rename Transactor preflight functions
  fixup! Make preflight1 and preflight2 private static Transactor functions
  Make preflight1 and preflight2 private static Transactor functions
  Fix formatting
2025-07-23 17:45:51 -04:00
Ed Hennis
1e7462606c Fix divide by 0 error on 0-interest loans; allow broker to self-lend
* Unit tests for self lending
2025-07-23 17:24:53 -04:00
Ed Hennis
68aecfe8a2 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-07-22 14:09:47 -04:00
Ed Hennis
8ffe1838d4 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-07-22 14:09:43 -04:00
Ed Hennis
30becab0b6 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-07-22 14:09:40 -04:00
Ed Hennis
e037ae3d3a Merge branch 'develop' into ximinez/lending-refactoring-1 2025-07-22 14:09:37 -04:00
Ed Hennis
2f3c79837e Merge branch 'develop' into ximinez/lending-XLS-66 2025-07-22 14:09:23 -04:00
Ed Hennis
4550d2bfba Fix build error 2025-07-22 14:06:17 -04:00
Ed Hennis
5edaad41af Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4
* ximinez/lending-refactoring-3: (61 commits)
  fixup! Rename Transactor preflight functions
  Rename Transactor preflight functions
  fixup! Make preflight1 and preflight2 private static Transactor functions
  Make preflight1 and preflight2 private static Transactor functions
  Fix formatting
  Remove `include(default)` from libxrpl profile (#5587)
  refactor: Change boost::shared_mutex to std::shared_mutex (#5576)
  Fix macos runner (#5585)
  Remove the type filter from "ledger" RPC command (#4934)
  refactor: Update date, libarchive, nudb, openssl, sqlite3, xxhash packages (#5567)
  test: Run unit tests regardless of 'Supported' amendment status (#5537)
  Retire Flow Cross amendment (#5562)
  chore: Update CI to use Conan 2 (#5556)
  fixAMMClawbackRounding: adjust last holder's LPToken balance (#5513)
  chore: Add gcc-12 workaround (#5554)
  Add MPT related txns into issuer's account history  (#5530)
  chore: Remove unused headers (#5526)
  fix: add allowTrustLineLocking flag for account_info (#5525)
  Downgrade required CMake version for Antithesis SDK (#5548)
  fix: Link with boost libraries explicitly (#5546)
  ...

Co-authored-by: Bronek Kozicki <brok@incorrekt.com>
2025-07-22 13:34:43 -04:00
Ed Hennis
24447969be fixup! Rename Transactor preflight functions 2025-07-22 12:43:54 -04:00
Ed Hennis
c76e485d01 Rename Transactor preflight functions
- Rename Transactor::preflight to invokePreflight.
- Rename doPreflight back to preflight.
- Update instructions.
- With preflight1 & 2 now uncallable, in-flight code in other
  branches should be easier to convert.
2025-07-22 12:11:00 -04:00
Ed Hennis
021bee8dd4 fixup! Make preflight1 and preflight2 private static Transactor functions 2025-07-22 12:10:58 -04:00
Ed Hennis
6c5945f9e8 Make preflight1 and preflight2 private static Transactor functions
- They should never be called by derived classes.
2025-07-21 23:26:29 -04:00
Ed Hennis
96ad348fb0 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3
* ximinez/lending-refactoring-2: (57 commits)
  Fix formatting
  Remove `include(default)` from libxrpl profile (#5587)
  refactor: Change boost::shared_mutex to std::shared_mutex (#5576)
  Fix macos runner (#5585)
  Remove the type filter from "ledger" RPC command (#4934)
  refactor: Update date, libarchive, nudb, openssl, sqlite3, xxhash packages (#5567)
  test: Run unit tests regardless of 'Supported' amendment status (#5537)
  Retire Flow Cross amendment (#5562)
  chore: Update CI to use Conan 2 (#5556)
  fixAMMClawbackRounding: adjust last holder's LPToken balance (#5513)
  chore: Add gcc-12 workaround (#5554)
  Add MPT related txns into issuer's account history  (#5530)
  chore: Remove unused headers (#5526)
  fix: add allowTrustLineLocking flag for account_info (#5525)
  Downgrade required CMake version for Antithesis SDK (#5548)
  fix: Link with boost libraries explicitly (#5546)
  chore: Fix compilation error with clang-20 and cleanup (#5543)
  test: Remove circular jtx.h dependencies (#5544)
  Decouple CredentialHelpers from xrpld/app/tx (#5487)
  fix: crash when trace-logging in tests (#5529)
  ...
2025-07-21 23:26:23 -04:00
Ed Hennis
72f33d8f3b Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2
* ximinez/lending-refactoring-1: (57 commits)
  Fix formatting
  Remove `include(default)` from libxrpl profile (#5587)
  refactor: Change boost::shared_mutex to std::shared_mutex (#5576)
  Fix macos runner (#5585)
  Remove the type filter from "ledger" RPC command (#4934)
  refactor: Update date, libarchive, nudb, openssl, sqlite3, xxhash packages (#5567)
  test: Run unit tests regardless of 'Supported' amendment status (#5537)
  Retire Flow Cross amendment (#5562)
  chore: Update CI to use Conan 2 (#5556)
  fixAMMClawbackRounding: adjust last holder's LPToken balance (#5513)
  chore: Add gcc-12 workaround (#5554)
  Add MPT related txns into issuer's account history  (#5530)
  chore: Remove unused headers (#5526)
  fix: add allowTrustLineLocking flag for account_info (#5525)
  Downgrade required CMake version for Antithesis SDK (#5548)
  fix: Link with boost libraries explicitly (#5546)
  chore: Fix compilation error with clang-20 and cleanup (#5543)
  test: Remove circular jtx.h dependencies (#5544)
  Decouple CredentialHelpers from xrpld/app/tx (#5487)
  fix: crash when trace-logging in tests (#5529)
  ...
2025-07-21 20:48:44 -04:00
Ed Hennis
96f2a65f64 Fix formatting 2025-07-21 20:37:16 -04:00
Ed Hennis
43fe49e756 Merge remote-tracking branch 'upstream/develop' into ximinez/lending-refactoring-1
* upstream/develop: (56 commits)
  Remove `include(default)` from libxrpl profile (#5587)
  refactor: Change boost::shared_mutex to std::shared_mutex (#5576)
  Fix macos runner (#5585)
  Remove the type filter from "ledger" RPC command (#4934)
  refactor: Update date, libarchive, nudb, openssl, sqlite3, xxhash packages (#5567)
  test: Run unit tests regardless of 'Supported' amendment status (#5537)
  Retire Flow Cross amendment (#5562)
  chore: Update CI to use Conan 2 (#5556)
  fixAMMClawbackRounding: adjust last holder's LPToken balance (#5513)
  chore: Add gcc-12 workaround (#5554)
  Add MPT related txns into issuer's account history  (#5530)
  chore: Remove unused headers (#5526)
  fix: add allowTrustLineLocking flag for account_info (#5525)
  Downgrade required CMake version for Antithesis SDK (#5548)
  fix: Link with boost libraries explicitly (#5546)
  chore: Fix compilation error with clang-20 and cleanup (#5543)
  test: Remove circular jtx.h dependencies (#5544)
  Decouple CredentialHelpers from xrpld/app/tx (#5487)
  fix: crash when trace-logging in tests (#5529)
  test: switch some unit tests to doctest (#5383)
  ...
2025-07-21 19:53:20 -04:00
Ed Hennis
e14ca4c438 Merge branch 'develop' into ximinez/lending-XLS-66 2025-07-21 18:20:32 -04:00
Ed Hennis
ed00018adc fixup! Add pseudo account type to injected data in RPC account_info result 2025-07-18 20:42:00 -04:00
Ed Hennis
f7aef49509 Add pseudo account type to injected data in RPC account_info result
- Low hanging fruit
2025-07-18 20:32:07 -04:00
Ed Hennis
e1edd43205 fixup! Fix LoanBrokerCoverClawback tests? 2025-07-18 19:19:08 -04:00
Ed Hennis
03d253ae20 Fix LoanBrokerCoverClawback tests? 2025-07-18 18:58:58 -04:00
Ed Hennis
577b047cc1 Merge branch 'develop' into ximinez/lending-XLS-66 2025-07-18 18:33:00 -04:00
Ed Hennis
c46d894192 Implement LoanBrokerCoverClawback and many test cases
- Not all tests are passing yet
2025-07-17 20:41:55 -04:00
Ed Hennis
e4480569f7 TEMP: Change VaultWithdraw back so tests pass 2025-07-16 18:58:25 -04:00
Ed Hennis
e6e6360c1a Support MPT payments via Payment tx for LBCoverWithdraw.Destination 2025-07-16 18:31:10 -04:00
Ed Hennis
6b4236343a Get CoverWithdraw IOU payments working
- Clean up some of the payment parameters
- Also factor out Payment::makeMPTDirectPayment for future use
2025-07-16 17:41:23 -04:00
Ed Hennis
45abab3a78 Add missing headers 2025-07-16 15:29:59 -04:00
Ed Hennis
4d7492a00d Use new "testable_amendments" function in new tests 2025-07-16 14:03:50 -04:00
Ed Hennis
b83af2d54a Fix formatting 2025-07-16 13:49:23 -04:00
Ed Hennis
10b73525be fixup! Start implementing LoanBrokerCoverWithdraw.Destination field 2025-07-16 12:55:23 -04:00
Ed Hennis
89dbb48860 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-XLS-66
* XRPLF/develop:
  test: Run unit tests regardless of 'Supported' amendment status (#5537)
  Retire Flow Cross amendment (#5562)
2025-07-16 12:53:36 -04:00
Ed Hennis
16854fff1a Merge branch 'develop' into ximinez/lending-XLS-66 2025-07-15 19:36:14 -04:00
Ed Hennis
b34f59eafc Start implementing LoanBrokerCoverWithdraw.Destination field
- Refactor the IOU payment code out of the Payment transactor and use it
  for different destinations. This should enforce all of the trust line
  rules without having to reinvent a dozen wheels.
- TODO: Same for MPTs.
2025-07-15 19:30:58 -04:00
Ed Hennis
38cb371c72 Make requireAuth work more similarly between IOUs and MPTs
- Unfortunately, to not change behavior, a new "Legacy" authorization
  type was created. It acts like "StrongAuth" for MPTs and "WeakAuth"
  for IOUs.
2025-07-15 17:48:14 -04:00
Ed Hennis
5199c5e073 Improve / add freeze checking helper functions
- Add an override of isDeepFrozen that can take an Asset, and thus an
  MPTIssue. The MPT version just calls isFrozen, since they're
  equivalent for MPTs.
- Add wrappers checkFrozen and checkDeepFrozen that return the
  appropriate TER code, so the Asset type doesn't have to be checked
  at every #*%@ing caller.
- Convert the Loan* transactors to use these functions.
2025-07-15 15:32:21 -04:00
Ed Hennis
3ef72d28bd fixup! Make a few tweaks to the changes in 907cc19a 2025-07-15 14:20:44 -04:00
Ed Hennis
06906a8bd3 Refactor the bulk of testLifecycle into a function
- Allows tweaking loan properties
2025-07-14 18:54:48 -04:00
Ed Hennis
0a3c728a96 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-XLS-66
* XRPLF/develop:
  fixAMMClawbackRounding: adjust last holder's LPToken balance (#5513)
  chore: Add gcc-12 workaround (#5554)
  Add MPT related txns into issuer's account history  (#5530)
  chore: Remove unused headers (#5526)
2025-07-11 19:21:03 -04:00
Ed Hennis
37745cb5b2 Rename Transactor preflight functions
- Rename Transactor::preflight to invokePreflight.
- Rename doPreflight back to preflight.
- Update instructions.
- With preflight1 & 2 now uncallable, in-flight code in other
  branches should be easier to convert.
2025-07-11 19:17:11 -04:00
Ed Hennis
269eac9a15 Mark the LendingProtocol amendment as unsupported 2025-07-11 18:55:08 -04:00
Ed Hennis
d82461ea70 Make preflight1 and preflight2 private static Transactor functions
- They should never be called by derived classes.
2025-07-11 18:42:39 -04:00
Ed Hennis
e9d2dfe329 fixup! Make a few tweaks to the changes in merge cc83ea8 2025-07-11 17:14:53 -04:00
Ed Hennis
9d052dc86c Make a few tweaks to the changes in 907cc19a 2025-07-11 17:06:26 -04:00
Ed Hennis
ad5d28bc48 Make a few tweaks to the changes in merge cc83ea8
- Not necessarily wrong, just not how I want it.
- Fixes a build error in LoanBroker_test
- In CreateOffer, fixes a logic error where _no_ offers will work if
  PermissionedDex amendment is enabled, and FlowCross is not
2025-07-11 16:14:10 -04:00
Ed Hennis
2b5a8ebf2f Merge branch 'develop' into ximinez/lending-XLS-66 2025-07-10 12:30:06 -04:00
Ed Hennis
28999a242c Merge branch 'develop' into ximinez/lending-XLS-66 2025-07-03 15:51:14 -04:00
Ed Hennis
186821f971 Merge branch 'develop' into ximinez/lending-XLS-66 2025-07-02 19:04:56 -04:00
Bronek Kozicki
1c8e4c346b Merge branch 'develop' into ximinez/lending-XLS-66 2025-06-27 10:45:37 +01:00
Bronek Kozicki
6bcd037264 Merge branch 'develop' into ximinez/lending-XLS-66 2025-06-23 10:33:05 +01:00
Bronek Kozicki
439e2d4934 Merge branch 'release' into ximinez/lending-XLS-66 2025-06-23 10:04:20 +01:00
Bronek Kozicki
f812774637 Merge branch 'develop' into ximinez/lending-XLS-66 2025-06-10 23:03:43 +08:00
Bronek Kozicki
d82693c2d3 Merge branch 'develop' into ximinez/lending-XLS-66 2025-06-10 21:51:58 +08:00
Bronek Kozicki
907cc19a41 Merge branch 'develop' into ximinez/lending-XLS-66 2025-06-05 13:04:15 +01:00
Bronek Kozicki
cc83ea8eb6 Merge branch 'develop' into ximinez/lending-XLS-66 2025-06-04 19:35:45 +01:00
Ed Hennis
527e0c916f Lending protocol implementation (XLS-0066)
- Add the LendingProtocol amendment
- Add Loan Broker and Loan ledger objects:
- Also add new SFields, Keylet functions, and an Invariant to verify no
  illegal field modification
- Update list of "constant" fields from spec
- Also add a general check for all object types for the type and index
  fields
- refactor: Check transaction flags in preflight0
- Adds a flagMask parameter to preflight1 so that it's impossible to
  forget to check flags.
- Also adds a short hash prefix to all Transactor log messages.
- refactor: Generalize Transactor preflight:
- Derived classes no longer need to explicitly check amendments, nor
  call into preflight1 or preflight2.
- implemeng LoanBrokerSet
- Transactions: LoanDelete, LoanManage, LoanDraw, LoanPay
- LoanBrokerSet creation mostly done. Need update.
- Also added a lookup table for pseudo account fields.
- Update changed field name.
- Modify modifiable fields in an update. Note there are only two.
- Add a node field to dirLink, defaulting sfOwnerNode, so other
  relationships can be updated.
- Create some helper classes for transaction fields
- Test that they work by converting some of the existing classes
- Finish creating helper classes for JTx fields
- Also change the pseudo account field lookup to a function that uses
  a switch
- Update tests, update pseudo-account checking
- Generalize some of the Invariant checks using macro files
  - Valid ledger entry type
  - Valid new account root and pseudo account check
- Enumerate transaction privileges for invariants
  - Allows them to be defined in transactions.macro instead of needing to
    scrutinize every existing Invariant class.
  - List is not necessarily comprehensive, but does cover every check
    where more than one transaction type is involved.
- Reserve a few values between Vault and Lending for future use
- Pseudo-account improvements
  - Define pseudo-account fields with an sfield flag
  - Pseudo-account invariant checks rules whenever a pseudo-account is
    created or modified.
- Move some helper functions.
- Check the regular key in the pseudo-transaction invariant check.
- Transactor::checkSign will always fail for a pseudo-account, so even
  if someone figures out how to get a good signature, it won't work.
- Fix account creation to check both amendments
- Add a validity range for sfDebtMaximum
- Change more "failed" messages. The goal here is to be able to search
  the log for "failed" and ONLY get test failures.
- NoModifiedUnmodifiableFields and ValidPseudoAccounts
- Move the Invariants_test class into the test namespace
- Clang wants an explicit ctor to emplace in a vector
- Refactor: Add a Transactor base function to make it easier to get the
  owner reserve increment as a fee.
- Refactor: Add an overload jtx::fee(increment) to pay an owner reserve.
- Initial implementation of LoanBrokerDelete
- Generalize the LoanBroker lifecycle test
- Refactor ApplyView::dirAdd to give access to low-level operations
  - Takes a page from #5362, which may turn out to be useful!
- Start writing Loan Broker invariants and tests
  - Specifically those mentioned for LoanBrokerDelete
- Move all detail namespaces to be under ripple
  - Avoids problems with namespace collisions / ambiguous symbol issues
    with unity builds, especially when adding or removing files.
- Add LoanBrokerCoverDeposit transaction
- Add LoanBrokerCoverWithdraw transaction
- Start writing tests for LoanBrokerCover*
- Add support for `Asset` and `MPTIssue` to some `jtx` helper classes
  and functions (`balance`, `expectLine`)
- Add support for pseudo-accounts to `jtx::Account` by allowing directly
  setting the AccountID without a matching key.
- Add Asset and MPTIssue support to more jtx objects / functions
  - Unfortunately, to work around some ambiguous symbol compilation
    errors, I had to change the implicit conversion from IOU to Asset to
    a conversion from IOU to PrettyAsset, and add a more explicit
    `asset()` function. This workaround only required changing two
    existing tests, so seems acceptable.
- Ensure that an account is not deleted with an XRP balance
  - Updates the AccountRootsDeletedClean invariant
- Finish up the Loan Broker tests
- Move inclusion of Transactor headers to transactions.macro
  - Only need to update in one place when adding a new transaction.
- Start implementing LoanSet transactor
  - Add some more values and functions to make it easier to work with
    basis point values / bips.
  - Fix several earlier mistakes.
- Generalize the check*Sign functions to support CounterParty
  - checkSign, checkSingleSign, and checkMultiSign in STTx and Transactor
- Start writing Loan tests
  - Required adding support for counterparty signature to jtx framework:
    arbitrary signature field destination, multiple signer callbacks
- Get Counterparty signing working
- Add more LoanSet unit tests, added LoanBroker LoanSequence field
  - LoanSequence will prevent loan key collisions
- Change Loan object indexing, fix several broken LoanSet unit tests
  - Loan objects will now only be indexed by LoanBrokerID and
    LoanSequence, which is a new field in LoanBroker. Also changes
    Loan.Sequence to Loan.LoanSequence to match up.
  - Several tests weren't working because of `PrettyAsset` scaling. Also,
    `PrettyAsset` calculations could overflow. Made that less likely by
    changing the type of `scale_`.
  - LoanSet will fail if an account tries to loan to itself.
- Ensure that an account is not deleted with a non-zero owner count
  - Updates the AccountRootsDeletedClean invariant
- Add unit tests to create a Loan successfully
  - Fix a few field initializations in LoanSet
- Refactor issuance validity check in VaultCreate
  - Utility function: canAddHolding
  - Call canAddHolding from any transactor that call addEmptyHolding
    (LoanBrokerSet, LoanSet)
- Start implementing LoanManage transaction
  - Also add a ValidLoan invariant
- Finish `LoanManage` functionality and tests, modulo LoanDraw/Pay
- Allow existing trust lines to loan brokers to be managed (by issuer)
- Implement LoanDelete, and fix a bunch of math errors in LoanManage
- Update to match latest spec: compute interest, LoanBroker reserves
- refactor: Define getFlagsMask in the base Transactor class
  - Returns tfUniversalMask for most transactors
  - Only transactors that use other flags need to override
- Implement LoanDraw, and made good progress on related tests
- Start implementing LoanPay transaction
- Implement LoanPay & most tests
- Also add an XRPL_ASSERT_PARTS, which splits the parts of the assert message
    so I don't have to remember the proper formatting.
Start writing LoanPay transaction tests
2025-05-21 11:39:55 +01:00
Ed Hennis
fb5d94bbef Refactor 4: Transactor extra signing support 2025-05-21 11:39:37 +01:00
Ed Hennis
4fe3ec8a08 Refactor 3: Transactors 2025-05-21 11:39:35 +01:00
Ed Hennis
937b67cbc0 Refactor 2: STParsed Json 2025-05-21 11:39:34 +01:00
Ed Hennis
4e50087612 Refactoring 1 2025-05-21 11:39:26 +01:00
1539 changed files with 13652 additions and 96714 deletions

274
.config/cspell.config.yaml Normal file
View File

@@ -0,0 +1,274 @@
ignorePaths:
- build/**
- src/libxrpl/crypto
- src/test/** # Will be removed in the future
- CMakeUserPresets.json
- Doxyfile
- docs/**/*.puml
- cmake/**
- LICENSE.md
language: en
allowCompoundWords: true
ignoreRandomStrings: true
minWordLength: 5
dictionaries:
- cpp
- en_US
- en_GB
ignoreRegExpList:
- /[rs][1-9A-HJ-NP-Za-km-z]{25,34}/g # addresses and seeds
- /(XRPL|BEAST)_[A-Z_0-9]+_H_INCLUDED+/g # include guards
- /(XRPL|BEAST)_[A-Z_0-9]+_H+/g # include guards
- /::[a-z:_]+/g # things from other namespaces
- /lib[a-z]+/g # libraries
- /[0-9]{4}-[0-9]{2}-[0-9]{2}[,:][A-Za-zÀ-ÖØ-öø-ÿ.\s]+/g # copyright dates
- /[0-9]{4}[,:]?\s*[A-Za-zÀ-ÖØ-öø-ÿ.\s]+/g # copyright years
- /\[[A-Za-z0-9-]+\]\(https:\/\/github.com\/[A-Za-z0-9-]+\)/g # Github usernames
- /-[DWw][a-zA-Z0-9_-]+=/g # compile flags
- /[\['"`]-[DWw][a-zA-Z0-9_-]+['"`\]]/g # compile flags
suggestWords:
- xprl->xrpl
- unsynched->unsynced
- synched->synced
- synch->sync
words:
- abempty
- AMMID
- amt
- amts
- asnode
- asynchrony
- attestation
- authorises
- autobridge
- autobridged
- autobridging
- bimap
- bindir
- bookdir
- Bougalis
- Britto
- Btrfs
- canonicality
- checkme
- chrono
- citardauq
- clawback
- clawbacks
- coeffs
- coldwallet
- compr
- conanfile
- conanrun
- connectability
- coro
- coros
- cowid
- cryptocondition
- cryptoconditional
- cryptoconditions
- csprng
- ctid
- currenttxhash
- daria
- dcmake
- dearmor
- deleteme
- demultiplexer
- deserializaton
- desync
- desynced
- determ
- distro
- doxyfile
- dxrpl
- endmacro
- exceptioned
- Falco
- finalizers
- firewalled
- fmtdur
- funclets
- gcov
- gcovr
- ghead
- Gnutella
- gpgcheck
- gpgkey
- hotwallet
- ifndef
- inequation
- insuf
- insuff
- iou
- ious
- isrdc
- jemalloc
- jlog
- keylet
- keylets
- keyvadb
- ledgerentry
- ledgerhash
- ledgerindex
- leftw
- legleux
- levelization
- levelized
- libpb
- libxrpl
- llection
- LOCALGOOD
- logwstream
- lseq
- lsmf
- ltype
- MEMORYSTATUSEX
- Merkle
- Metafuncton
- misprediction
- mptbalance
- mptflags
- mptid
- mptissuance
- mptissuanceid
- mptoken
- mptokenid
- mptokenissuance
- mptokens
- mpts
- multisig
- multisign
- multisigned
- Nakamoto
- nftid
- nftoffer
- nftoken
- nftokenid
- nftokenpages
- nftokens
- nftpage
- nikb
- nonxrp
- noripple
- nudb
- nullptr
- nunl
- Nyffenegger
- ostr
- partitioner
- paychan
- paychans
- permdex
- perminute
- permissioned
- pointee
- preauth
- preauthorization
- preauthorize
- preauthorizes
- preclaim
- protobuf
- protos
- ptrs
- pyenv
- qalloc
- queuable
- Raphson
- replayer
- rerere
- retriable
- RIPD
- ripdtop
- rippleci
- rippled
- ripplerpc
- rippletest
- RLUSD
- rngfill
- rocksdb
- Rohrs
- roundings
- sahyadri
- Satoshi
- secp
- sendq
- seqit
- sf
- shamap
- shamapitem
- sidechain
- SIGGOOD
- sle
- sles
- soci
- socidb
- sslws
- statsd
- STATSDCOLLECTOR
- stissue
- stnum
- stobj
- stobject
- stpath
- stpathset
- sttx
- stvar
- stvector
- stxchainattestations
- superpeer
- superpeers
- takergets
- takerpays
- ters
- TMEndpointv2
- trixie
- tx
- txid
- txids
- txjson
- txn
- txns
- txs
- umant
- unacquired
- unambiguity
- unauthorizes
- unauthorizing
- unergonomic
- unfetched
- unflatten
- unfund
- unimpair
- unroutable
- unscalable
- unserviced
- unshareable
- unshares
- unsquelch
- unsquelched
- unsquelching
- unvalidated
- unveto
- unvetoed
- upvotes
- USDB
- variadics
- venv
- vfalco
- vinnie
- wextra
- wptr
- writeme
- wsrch
- wthread
- xbridge
- xchain
- ximinez
- XMACRO
- xrpkuwait
- xrpl
- xrpld
- xrplf
- xxhash
- xxhasher

5
.gitattributes vendored
View File

@@ -1,9 +1,6 @@
# Set default behaviour, in case users don't have core.autocrlf set.
#* text=auto
# These annoying files
rippled.1 binary
LICENSE binary
# cspell: disable
# Visual Studio
*.sln text eol=crlf

6
.github/CODEOWNERS vendored
View File

@@ -1,2 +1,8 @@
# Allow anyone to review any change by default.
*
# Require the rpc-reviewers team to review changes to the rpc code.
include/xrpl/protocol/ @xrplf/rpc-reviewers
src/libxrpl/protocol/ @xrplf/rpc-reviewers
src/xrpld/rpc/ @xrplf/rpc-reviewers
src/xrpld/app/misc/ @xrplf/rpc-reviewers

View File

@@ -1,7 +1,7 @@
---
name: Bug Report
about: Create a report to help us improve rippled
title: "[Title with short description] (Version: [rippled version])"
about: Create a report to help us improve xrpld
title: "[Title with short description] (Version: [xrpld version])"
labels: ""
assignees: ""
---
@@ -27,7 +27,7 @@ assignees: ""
## Environment
<!--Please describe your environment setup (such as Ubuntu 18.04 with Boost 1.70).-->
<!-- If you are using a formal release, please use the version returned by './rippled --version' as the version number-->
<!-- If you are using a formal release, please use the version returned by './xrpld --version' as the version number-->
<!-- If you are working off of develop, please add the git hash via 'git rev-parse HEAD'-->
## Supporting Files

View File

@@ -4,9 +4,6 @@ description: "Install Conan dependencies, optionally forcing a rebuild of all de
# Note that actions do not support 'type' and all inputs are strings, see
# https://docs.github.com/en/actions/reference/workflows-and-actions/metadata-syntax#inputs.
inputs:
build_dir:
description: "The directory where to build."
required: true
build_type:
description: 'The build type to use ("Debug", "Release").'
required: true
@@ -28,18 +25,13 @@ runs:
- name: Install Conan dependencies
shell: bash
env:
BUILD_DIR: ${{ inputs.build_dir }}
BUILD_NPROC: ${{ inputs.build_nproc }}
BUILD_OPTION: ${{ inputs.force_build == 'true' && '*' || 'missing' }}
BUILD_TYPE: ${{ inputs.build_type }}
LOG_VERBOSITY: ${{ inputs.log_verbosity }}
run: |
echo 'Installing dependencies.'
conan export --version 0.42.1 external/wasmi #TODO Switch to conan package
mkdir -p "${BUILD_DIR}"
cd "${BUILD_DIR}"
conan install \
--output-folder . \
--build="${BUILD_OPTION}" \
--options:host='&:tests=True' \
--options:host='&:xrpld=True' \
@@ -47,4 +39,4 @@ runs:
--conf:all tools.build:jobs=${BUILD_NPROC} \
--conf:all tools.build:verbosity="${LOG_VERBOSITY}" \
--conf:all tools.compilation:verbosity="${LOG_VERBOSITY}" \
..
.

View File

@@ -11,12 +11,6 @@ runs:
echo 'Checking environment variables.'
set
echo 'Checking CMake version.'
cmake --version
echo 'Checking Conan version.'
conan --version
- name: Check configuration (Linux and macOS)
if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }}
shell: bash
@@ -27,17 +21,23 @@ runs:
echo 'Checking environment variables.'
env | sort
echo 'Checking CMake version.'
cmake --version
echo 'Checking compiler version.'
${{ runner.os == 'Linux' && '${CC}' || 'clang' }} --version
echo 'Checking Conan version.'
conan --version
echo 'Checking Ninja version.'
ninja --version
echo 'Checking nproc version.'
nproc --version
- name: Check configuration (all)
shell: bash
run: |
echo 'Checking Ccache version.'
ccache --version
echo 'Checking CMake version.'
cmake --version
echo 'Checking Conan version.'
conan --version

View File

@@ -3,21 +3,26 @@
Levelization is the term used to describe efforts to prevent rippled from
having or creating cyclic dependencies.
rippled code is organized into directories under `src/rippled` (and
rippled code is organized into directories under `src/xrpld`, `src/libxrpl` (and
`src/test`) representing modules. The modules are intended to be
organized into "tiers" or "levels" such that a module from one level can
only include code from lower levels. Additionally, a module
in one level should never include code in an `impl` folder of any level
in one level should never include code in an `impl` or `detail` folder of any level
other than it's own.
The codebase is split into two main areas:
- **libxrpl** (`src/libxrpl`, `include/xrpl`): Reusable library modules with public interfaces
- **xrpld** (`src/xrpld`): Application-specific implementation code
Unfortunately, over time, enforcement of levelization has been
inconsistent, so the current state of the code doesn't necessarily
reflect these rules. Whenever possible, developers should refactor any
levelization violations they find (by moving files or individual
classes). At the very least, don't make things worse.
The table below summarizes the _desired_ division of modules, based on the
state of the rippled code when it was created. The levels are numbered from
The table below summarizes the _desired_ division of modules, based on the current
state of the rippled code. The levels are numbered from
the bottom up with the lower level, lower numbered, more independent
modules listed first, and the higher level, higher numbered modules with
more dependencies listed later.
@@ -25,18 +30,33 @@ more dependencies listed later.
**tl;dr:** The modules listed first are more independent than the modules
listed later.
## libxrpl Modules (Reusable Libraries)
| Level / Tier | Module(s) |
| ------------ | ----------------------------------- |
| 01 | xrpl/beast |
| 02 | xrpl/basics |
| 03 | xrpl/json xrpl/crypto |
| 04 | xrpl/protocol |
| 05 | xrpl/core xrpl/resource xrpl/server |
| 06 | xrpl/ledger xrpl/nodestore xrpl/net |
| 07 | xrpl/shamap |
## xrpld Modules (Application Implementation)
| Level / Tier | Module(s) |
| ------------ | -------------------------------- |
| 05 | xrpld/conditions xrpld/consensus |
| 06 | xrpld/core xrpld/peerfinder |
| 07 | xrpld/shamap xrpld/overlay |
| 08 | xrpld/app |
| 09 | xrpld/rpc |
| 10 | xrpld/perflog |
## Test Modules
| Level / Tier | Module(s) |
| ------------ | -------------------------------------------------------------------------------------------------------- |
| 01 | ripple/beast ripple/unity |
| 02 | ripple/basics |
| 03 | ripple/json ripple/crypto |
| 04 | ripple/protocol |
| 05 | ripple/core ripple/conditions ripple/consensus ripple/resource ripple/server |
| 06 | ripple/peerfinder ripple/ledger ripple/nodestore ripple/net |
| 07 | ripple/shamap ripple/overlay |
| 08 | ripple/app |
| 09 | ripple/rpc |
| 10 | ripple/perflog |
| 11 | test/jtx test/beast test/csf |
| 12 | test/unit_test |
| 13 | test/crypto test/conditions test/json test/resource test/shamap test/peerfinder test/basics test/overlay |
@@ -45,8 +65,8 @@ listed later.
| 16 | test/rpc test/app |
(Note that `test` levelization is _much_ less important and _much_ less
strictly enforced than `ripple` levelization, other than the requirement
that `test` code should _never_ be included in `ripple` code.)
strictly enforced than `xrpl`/`xrpld` levelization, other than the requirement
that `test` code should _never_ be included in `xrpl` or `xrpld` code.)
## Validation
@@ -61,10 +81,10 @@ It generates many files of [results](results):
- `rawincludes.txt`: The raw dump of the `#includes`
- `paths.txt`: A second dump grouping the source module
to the destination module, deduped, and with frequency counts.
to the destination module, de-duped, and with frequency counts.
- `includes/`: A directory where each file represents a module and
contains a list of modules and counts that the module _includes_.
- `includedby/`: Similar to `includes/`, but the other way around. Each
- `included_by/`: Similar to `includes/`, but the other way around. Each
file represents a module and contains a list of modules and counts
that _include_ the module.
- [`loops.txt`](results/loops.txt): A list of direct loops detected

View File

@@ -29,7 +29,7 @@ pushd results
oldifs=${IFS}
IFS=:
mkdir includes
mkdir includedby
mkdir included_by
echo Build levelization paths
exec 3< ${includes} # open rawincludes.txt for input
while read -r -u 3 file include
@@ -59,7 +59,7 @@ do
echo $level $includelevel | tee -a paths.txt
fi
done
echo Sort and dedup paths
echo Sort and deduplicate paths
sort -ds paths.txt | uniq -c | tee sortedpaths.txt
mv sortedpaths.txt paths.txt
exec 3>&- #close fd 3
@@ -71,7 +71,7 @@ exec 4<paths.txt # open paths.txt for input
while read -r -u 4 count level include
do
echo ${include} ${count} | tee -a includes/${level}
echo ${level} ${count} | tee -a includedby/${include}
echo ${level} ${count} | tee -a included_by/${include}
done
exec 4>&- #close fd 4

View File

@@ -19,12 +19,6 @@ Loop: xrpld.app xrpld.rpc
Loop: xrpld.app xrpld.shamap
xrpld.shamap ~= xrpld.app
Loop: xrpld.core xrpld.perflog
xrpld.perflog == xrpld.core
Loop: xrpld.overlay xrpld.rpc
xrpld.rpc ~= xrpld.overlay
Loop: xrpld.perflog xrpld.rpc
xrpld.rpc ~= xrpld.perflog

View File

@@ -1,4 +1,6 @@
libxrpl.basics > xrpl.basics
libxrpl.core > xrpl.basics
libxrpl.core > xrpl.core
libxrpl.crypto > xrpl.basics
libxrpl.json > xrpl.basics
libxrpl.json > xrpl.json
@@ -30,6 +32,7 @@ test.app > test.rpc
test.app > test.toplevel
test.app > test.unit_test
test.app > xrpl.basics
test.app > xrpl.core
test.app > xrpld.app
test.app > xrpld.core
test.app > xrpld.overlay
@@ -42,7 +45,7 @@ test.app > xrpl.resource
test.basics > test.jtx
test.basics > test.unit_test
test.basics > xrpl.basics
test.basics > xrpld.perflog
test.basics > xrpl.core
test.basics > xrpld.rpc
test.basics > xrpl.json
test.basics > xrpl.protocol
@@ -61,8 +64,8 @@ test.core > test.jtx
test.core > test.toplevel
test.core > test.unit_test
test.core > xrpl.basics
test.core > xrpl.core
test.core > xrpld.core
test.core > xrpld.perflog
test.core > xrpl.json
test.core > xrpl.server
test.csf > xrpl.basics
@@ -119,6 +122,7 @@ test.resource > xrpl.resource
test.rpc > test.jtx
test.rpc > test.toplevel
test.rpc > xrpl.basics
test.rpc > xrpl.core
test.rpc > xrpld.app
test.rpc > xrpld.core
test.rpc > xrpld.overlay
@@ -146,6 +150,8 @@ test.unit_test > xrpl.basics
tests.libxrpl > xrpl.basics
tests.libxrpl > xrpl.json
tests.libxrpl > xrpl.net
xrpl.core > xrpl.basics
xrpl.core > xrpl.json
xrpl.json > xrpl.basics
xrpl.ledger > xrpl.basics
xrpl.ledger > xrpl.protocol
@@ -165,9 +171,9 @@ xrpl.shamap > xrpl.nodestore
xrpl.shamap > xrpl.protocol
xrpld.app > test.unit_test
xrpld.app > xrpl.basics
xrpld.app > xrpl.core
xrpld.app > xrpld.conditions
xrpld.app > xrpld.consensus
xrpld.app > xrpld.perflog
xrpld.app > xrpl.json
xrpld.app > xrpl.ledger
xrpld.app > xrpl.net
@@ -181,13 +187,14 @@ xrpld.consensus > xrpl.basics
xrpld.consensus > xrpl.json
xrpld.consensus > xrpl.protocol
xrpld.core > xrpl.basics
xrpld.core > xrpl.core
xrpld.core > xrpl.json
xrpld.core > xrpl.net
xrpld.core > xrpl.protocol
xrpld.overlay > xrpl.basics
xrpld.overlay > xrpl.core
xrpld.overlay > xrpld.core
xrpld.overlay > xrpld.peerfinder
xrpld.overlay > xrpld.perflog
xrpld.overlay > xrpl.json
xrpld.overlay > xrpl.protocol
xrpld.overlay > xrpl.resource
@@ -196,8 +203,11 @@ xrpld.peerfinder > xrpl.basics
xrpld.peerfinder > xrpld.core
xrpld.peerfinder > xrpl.protocol
xrpld.perflog > xrpl.basics
xrpld.perflog > xrpl.core
xrpld.perflog > xrpld.rpc
xrpld.perflog > xrpl.json
xrpld.rpc > xrpl.basics
xrpld.rpc > xrpl.core
xrpld.rpc > xrpld.core
xrpld.rpc > xrpl.json
xrpld.rpc > xrpl.ledger

View File

@@ -19,13 +19,21 @@ run from the repository root.
1. `.github/scripts/rename/definitions.sh`: This script will rename all
definitions, such as include guards, from `RIPPLE_XXX` and `RIPPLED_XXX` to
`XRPL_XXX`.
2. `.github/scripts/rename/copyright.sh`: This script will remove superflous
2. `.github/scripts/rename/copyright.sh`: This script will remove superfluous
copyright notices.
3. `.github/scripts/rename/cmake.sh`: This script will rename all CMake files
from `RippleXXX.cmake` or `RippledXXX.cmake` to `XrplXXX.cmake`, and any
references to `ripple` and `rippled` (with or without capital letters) to
`xrpl` and `xrpld`, respectively. The name of the binary will remain as-is,
and will only be renamed to `xrpld` by a later script.
4. `.github/scripts/rename/binary.sh`: This script will rename the binary from
`rippled` to `xrpld`, and reverses the symlink so that `rippled` points to
the `xrpld` binary.
5. `.github/scripts/rename/namespace.sh`: This script will rename the C++
namespaces from `ripple` to `xrpl`.
6. `.github/scripts/rename/config.sh`: This script will rename the config from
`rippled.cfg` to `xrpld.cfg`, and updating the code accordingly. The old
filename will still be accepted.
You can run all these scripts from the repository root as follows:
@@ -33,4 +41,7 @@ You can run all these scripts from the repository root as follows:
./.github/scripts/rename/definitions.sh .
./.github/scripts/rename/copyright.sh .
./.github/scripts/rename/cmake.sh .
./.github/scripts/rename/binary.sh .
./.github/scripts/rename/namespace.sh .
./.github/scripts/rename/config.sh .
```

54
.github/scripts/rename/binary.sh vendored Executable file
View File

@@ -0,0 +1,54 @@
#!/bin/bash
# Exit the script as soon as an error occurs.
set -e
# On MacOS, ensure that GNU sed is installed and available as `gsed`.
SED_COMMAND=sed
if [[ "${OSTYPE}" == 'darwin'* ]]; then
if ! command -v gsed &> /dev/null; then
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
exit 1
fi
SED_COMMAND=gsed
fi
# This script changes the binary name from `rippled` to `xrpld`, and reverses
# the symlink that currently points from `xrpld` to `rippled` so that it points
# from `rippled` to `xrpld` instead.
# Usage: .github/scripts/rename/binary.sh <repository directory>
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <repository directory>"
exit 1
fi
DIRECTORY=$1
echo "Processing directory: ${DIRECTORY}"
if [ ! -d "${DIRECTORY}" ]; then
echo "Error: Directory '${DIRECTORY}' does not exist."
exit 1
fi
pushd ${DIRECTORY}
# Remove the binary name override added by the cmake.sh script.
${SED_COMMAND} -z -i -E 's@\s+# For the time being.+"rippled"\)@@' cmake/XrplCore.cmake
# Reverse the symlink.
${SED_COMMAND} -i -E 's@create_symbolic_link\(rippled@create_symbolic_link(xrpld@' cmake/XrplInstall.cmake
${SED_COMMAND} -i -E 's@/xrpld\$\{suffix\}@/rippled${suffix}@' cmake/XrplInstall.cmake
# Rename references to the binary.
${SED_COMMAND} -i -E 's@rippled@xrpld@g' BUILD.md
${SED_COMMAND} -i -E 's@rippled@xrpld@g' CONTRIBUTING.md
${SED_COMMAND} -i -E 's@rippled@xrpld@g' .github/ISSUE_TEMPLATE/bug_report.md
# Restore and/or fix certain renames. The pre-commit hook will update the
# formatting upon saving/committing.
${SED_COMMAND} -i -E 's@ripple/xrpld@XRPLF/rippled@g' BUILD.md
${SED_COMMAND} -i -E 's@XRPLF/xrpld@XRPLF/rippled@g' BUILD.md
${SED_COMMAND} -i -E 's@xrpld \(`xrpld`\)@xrpld@g' BUILD.md
${SED_COMMAND} -i -E 's@XRPLF/xrpld@XRPLF/rippled@g' CONTRIBUTING.md
popd
echo "Processing complete."

72
.github/scripts/rename/config.sh vendored Executable file
View File

@@ -0,0 +1,72 @@
#!/bin/bash
# Exit the script as soon as an error occurs.
set -e
# On MacOS, ensure that GNU sed is installed and available as `gsed`.
SED_COMMAND=sed
if [[ "${OSTYPE}" == 'darwin'* ]]; then
if ! command -v gsed &> /dev/null; then
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
exit 1
fi
SED_COMMAND=gsed
fi
# This script renames the config from `rippled.cfg` to `xrpld.cfg`, and updates
# the code accordingly. The old filename will still be accepted.
# Usage: .github/scripts/rename/config.sh <repository directory>
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <repository directory>"
exit 1
fi
DIRECTORY=$1
echo "Processing directory: ${DIRECTORY}"
if [ ! -d "${DIRECTORY}" ]; then
echo "Error: Directory '${DIRECTORY}' does not exist."
exit 1
fi
pushd ${DIRECTORY}
# Add the xrpld.cfg to the .gitignore.
if ! grep -q 'xrpld.cfg' .gitignore; then
${SED_COMMAND} -i '/rippled.cfg/a\
/xrpld.cfg' .gitignore
fi
# Rename the files.
if [ -e rippled.cfg ]; then
mv rippled.cfg xrpld.cfg
fi
if [ -e cfg/rippled-example.cfg ]; then
mv cfg/rippled-example.cfg cfg/xrpld-example.cfg
fi
# Rename inside the files.
DIRECTORIES=("cfg" "cmake" "include" "src")
for DIRECTORY in "${DIRECTORIES[@]}"; do
echo "Processing directory: ${DIRECTORY}"
find "${DIRECTORY}" -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" -o -name "*.cpp" -o -name "*.cmake" -o -name "*.txt" -o -name "*.cfg" -o -name "*.md" \) | while read -r FILE; do
echo "Processing file: ${FILE}"
${SED_COMMAND} -i -E 's/rippled(-example)?[ .]cfg/xrpld\1.cfg/g' "${FILE}"
done
done
${SED_COMMAND} -i 's/rippled/xrpld/g' cfg/xrpld-example.cfg
${SED_COMMAND} -i 's/rippled/xrpld/g' src/test/core/Config_test.cpp
${SED_COMMAND} -i 's/ripplevalidators/xrplvalidators/g' src/test/core/Config_test.cpp # cspell: disable-line
${SED_COMMAND} -i 's/rippleConfig/xrpldConfig/g' src/test/core/Config_test.cpp
${SED_COMMAND} -i 's@ripple/@xrpld/@g' src/test/core/Config_test.cpp
${SED_COMMAND} -i 's/Rippled/File/g' src/test/core/Config_test.cpp
# Restore the old config file name in the code that maintains support for now.
${SED_COMMAND} -i 's/configLegacyName = "xrpld.cfg"/configLegacyName = "rippled.cfg"/g' src/xrpld/core/detail/Config.cpp
# Restore an URL.
${SED_COMMAND} -i 's/connect-your-xrpld-to-the-xrp-test-net.html/connect-your-rippled-to-the-xrp-test-net.html/g' cfg/xrpld-example.cfg
popd
echo "Renaming complete."

View File

@@ -50,11 +50,11 @@ for DIRECTORY in "${DIRECTORIES[@]}"; do
# Handle the cases where the copyright notice is enclosed in /* ... */
# and usually surrounded by //---- and //======.
${SED_COMMAND} -z -i -E 's@^//-------+\n+@@' "${FILE}"
${SED_COMMAND} -z -i -E 's@^.*Copyright.+(Ripple|Bougalis|Falco|Hinnant|Null|Ritchford|XRPLF).+PERFORMANCE OF THIS SOFTWARE\.\n\*/\n+@@' "${FILE}"
${SED_COMMAND} -z -i -E 's@^.*Copyright.+(Ripple|Bougalis|Falco|Hinnant|Null|Ritchford|XRPLF).+PERFORMANCE OF THIS SOFTWARE\.\n\*/\n+@@' "${FILE}" # cspell: ignore Bougalis Falco Hinnant Ritchford
${SED_COMMAND} -z -i -E 's@^//=======+\n+@@' "${FILE}"
# Handle the cases where the copyright notice is commented out with //.
${SED_COMMAND} -z -i -E 's@^//\n// Copyright.+Falco \(vinnie dot falco at gmail dot com\)\n//\n+@@' "${FILE}"
${SED_COMMAND} -z -i -E 's@^//\n// Copyright.+Falco \(vinnie dot falco at gmail dot com\)\n//\n+@@' "${FILE}" # cspell: ignore Vinnie Falco
done
done
@@ -83,16 +83,16 @@ if ! grep -q 'Dev Null' src/xrpld/rpc/handlers/ValidatorInfo.cpp; then
echo -e "// Copyright (c) 2019 Dev Null Productions\n\n$(cat src/xrpld/rpc/handlers/ValidatorInfo.cpp)" > src/xrpld/rpc/handlers/ValidatorInfo.cpp
fi
if ! grep -q 'Bougalis' include/xrpl/basics/SlabAllocator.h; then
echo -e "// Copyright (c) 2022, Nikolaos D. Bougalis <nikb@bougalis.net>\n\n$(cat include/xrpl/basics/SlabAllocator.h)" > include/xrpl/basics/SlabAllocator.h
echo -e "// Copyright (c) 2022, Nikolaos D. Bougalis <nikb@bougalis.net>\n\n$(cat include/xrpl/basics/SlabAllocator.h)" > include/xrpl/basics/SlabAllocator.h # cspell: ignore Nikolaos Bougalis nikb
fi
if ! grep -q 'Bougalis' include/xrpl/basics/spinlock.h; then
echo -e "// Copyright (c) 2022, Nikolaos D. Bougalis <nikb@bougalis.net>\n\n$(cat include/xrpl/basics/spinlock.h)" > include/xrpl/basics/spinlock.h
echo -e "// Copyright (c) 2022, Nikolaos D. Bougalis <nikb@bougalis.net>\n\n$(cat include/xrpl/basics/spinlock.h)" > include/xrpl/basics/spinlock.h # cspell: ignore Nikolaos Bougalis nikb
fi
if ! grep -q 'Bougalis' include/xrpl/basics/tagged_integer.h; then
echo -e "// Copyright (c) 2014, Nikolaos D. Bougalis <nikb@bougalis.net>\n\n$(cat include/xrpl/basics/tagged_integer.h)" > include/xrpl/basics/tagged_integer.h
echo -e "// Copyright (c) 2014, Nikolaos D. Bougalis <nikb@bougalis.net>\n\n$(cat include/xrpl/basics/tagged_integer.h)" > include/xrpl/basics/tagged_integer.h # cspell: ignore Nikolaos Bougalis nikb
fi
if ! grep -q 'Ritchford' include/xrpl/beast/utility/Zero.h; then
echo -e "// Copyright (c) 2014, Tom Ritchford <tom@swirly.com>\n\n$(cat include/xrpl/beast/utility/Zero.h)" > include/xrpl/beast/utility/Zero.h
echo -e "// Copyright (c) 2014, Tom Ritchford <tom@swirly.com>\n\n$(cat include/xrpl/beast/utility/Zero.h)" > include/xrpl/beast/utility/Zero.h # cspell: ignore Ritchford
fi
# Restore newlines and tabs in string literals in the affected file.

58
.github/scripts/rename/namespace.sh vendored Executable file
View File

@@ -0,0 +1,58 @@
#!/bin/bash
# Exit the script as soon as an error occurs.
set -e
# On MacOS, ensure that GNU sed is installed and available as `gsed`.
SED_COMMAND=sed
if [[ "${OSTYPE}" == 'darwin'* ]]; then
if ! command -v gsed &> /dev/null; then
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
exit 1
fi
SED_COMMAND=gsed
fi
# This script renames the `ripple` namespace to `xrpl` in this project.
# Specifically, it renames all occurrences of `namespace ripple` and `ripple::`
# to `namespace xrpl` and `xrpl::`, respectively, by scanning all header and
# source files in the specified directory and its subdirectories, as well as any
# occurrences in the documentation. It also renames them in the test suites.
# Usage: .github/scripts/rename/namespace.sh <repository directory>
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <repository directory>"
exit 1
fi
DIRECTORY=$1
echo "Processing directory: ${DIRECTORY}"
if [ ! -d "${DIRECTORY}" ]; then
echo "Error: Directory '${DIRECTORY}' does not exist."
exit 1
fi
pushd ${DIRECTORY}
DIRECTORIES=("include" "src" "tests")
for DIRECTORY in "${DIRECTORIES[@]}"; do
echo "Processing directory: ${DIRECTORY}"
find "${DIRECTORY}" -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" -o -name "*.cpp" \) | while read -r FILE; do
echo "Processing file: ${FILE}"
${SED_COMMAND} -i 's/namespace ripple/namespace xrpl/g' "${FILE}"
${SED_COMMAND} -i 's/ripple::/xrpl::/g' "${FILE}"
${SED_COMMAND} -i -E 's/(BEAST_DEFINE_TESTSUITE.+)ripple(.+)/\1xrpl\2/g' "${FILE}"
done
done
# Special case for NuDBFactory that has ripple twice in the test suite name.
${SED_COMMAND} -i -E 's/(BEAST_DEFINE_TESTSUITE.+)ripple(.+)/\1xrpl\2/g' src/test/nodestore/NuDBFactory_test.cpp
DIRECTORY=$1
find "${DIRECTORY}" -type f -name "*.md" | while read -r FILE; do
echo "Processing file: ${FILE}"
${SED_COMMAND} -i 's/ripple::/xrpl::/g' "${FILE}"
done
popd
echo "Renaming complete."

View File

@@ -232,6 +232,8 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
f"-{architecture['platform'][architecture['platform'].find('/') + 1 :]}"
)
config_name += f"-{build_type.lower()}"
if "-Dcoverage=ON" in cmake_args:
config_name += "-coverage"
if "-Dunity=ON" in cmake_args:
config_name += "-unity"

View File

@@ -15,196 +15,196 @@
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "12",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "13",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "15",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "16",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "17",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "18",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "19",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "20",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "debian",
"distro_version": "trixie",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "debian",
"distro_version": "trixie",
"compiler_name": "gcc",
"compiler_version": "15",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "debian",
"distro_version": "trixie",
"compiler_name": "clang",
"compiler_version": "20",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "debian",
"distro_version": "trixie",
"compiler_name": "clang",
"compiler_version": "21",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "rhel",
"distro_version": "8",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "rhel",
"distro_version": "8",
"compiler_name": "clang",
"compiler_version": "any",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "rhel",
"distro_version": "9",
"compiler_name": "gcc",
"compiler_version": "12",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "rhel",
"distro_version": "9",
"compiler_name": "gcc",
"compiler_version": "13",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "rhel",
"distro_version": "9",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "rhel",
"distro_version": "9",
"compiler_name": "clang",
"compiler_version": "any",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "rhel",
"distro_version": "10",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "rhel",
"distro_version": "10",
"compiler_name": "clang",
"compiler_version": "any",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "ubuntu",
"distro_version": "jammy",
"compiler_name": "gcc",
"compiler_version": "12",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "gcc",
"compiler_version": "13",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "16",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "17",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "18",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "19",
"image_sha": "ca4517d"
"image_sha": "cc09fd3"
}
],
"build_type": ["Debug", "Release"],

View File

@@ -114,6 +114,9 @@ jobs:
matrix:
os: [linux, macos, windows]
with:
# Enable ccache only for events targeting the XRPLF repository, since
# other accounts will not have access to our remote cache storage.
ccache_enabled: ${{ github.repository_owner == 'XRPLF' }}
os: ${{ matrix.os }}
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -68,6 +68,12 @@ jobs:
matrix:
os: [linux, macos, windows]
with:
# Enable ccache only for events targeting the XRPLF repository, since
# other accounts will not have access to our remote cache storage.
# However, we do not enable ccache for events targeting the master or a
# release branch, to protect against the rare case that the output
# produced by ccache is not identical to a regular compilation.
ccache_enabled: ${{ github.repository_owner == 'XRPLF' && !(github.base_ref == 'master' || startsWith(github.base_ref, 'release')) }}
os: ${{ matrix.os }}
strategy_matrix: ${{ github.event_name == 'schedule' && 'all' || 'minimal' }}
secrets:

View File

@@ -9,7 +9,7 @@ on:
jobs:
# Call the workflow in the XRPLF/actions repo that runs the pre-commit hooks.
run-hooks:
uses: XRPLF/actions/.github/workflows/pre-commit.yml@34790936fae4c6c751f62ec8c06696f9c1a5753a
uses: XRPLF/actions/.github/workflows/pre-commit.yml@5ca417783f0312ab26d6f48b85c78edf1de99bbd
with:
runs_on: ubuntu-latest
container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-a8c7be1" }'

View File

@@ -22,7 +22,7 @@ defaults:
shell: bash
env:
BUILD_DIR: .build
BUILD_DIR: build
NPROC_SUBTRACT: 2
jobs:
@@ -36,7 +36,7 @@ jobs:
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Get number of processors
uses: XRPLF/actions/.github/actions/get-nproc@046b1620f6bfd6cd0985dc82c3df02786801fe0a
uses: XRPLF/actions/get-nproc@2ece4ec6ab7de266859a6f053571425b2bd684b6
id: nproc
with:
subtract: ${{ env.NPROC_SUBTRACT }}

View File

@@ -3,11 +3,6 @@ name: Build and test configuration
on:
workflow_call:
inputs:
build_dir:
description: "The directory where to build."
required: true
type: string
build_only:
description: 'Whether to only build or to build and test the code ("true", "false").'
required: true
@@ -15,8 +10,14 @@ on:
build_type:
description: 'The build type to use ("Debug", "Release").'
type: string
required: true
type: string
ccache_enabled:
description: "Whether to enable ccache."
required: false
type: boolean
default: false
cmake_args:
description: "Additional arguments to pass to CMake."
@@ -26,8 +27,8 @@ on:
cmake_target:
description: "The CMake target to build."
type: string
required: true
type: string
runs_on:
description: Runner to run the job on as a JSON string
@@ -59,6 +60,11 @@ defaults:
run:
shell: bash
env:
# Conan installs the generators in the build/generators directory, see the
# layout() method in conanfile.py. We then run CMake from the build directory.
BUILD_DIR: build
jobs:
build-and-test:
name: ${{ inputs.config_name }}
@@ -66,26 +72,47 @@ jobs:
container: ${{ inputs.image != '' && inputs.image || null }}
timeout-minutes: 60
env:
ENABLED_VOIDSTAR: ${{ contains(inputs.cmake_args, '-Dvoidstar=ON') }}
ENABLED_COVERAGE: ${{ contains(inputs.cmake_args, '-Dcoverage=ON') }}
# Use a namespace to keep the objects separate for each configuration.
CCACHE_NAMESPACE: ${{ inputs.config_name }}
# Ccache supports both Redis and HTTP endpoints.
# * For Redis, use the following format: redis://ip:port, see
# https://github.com/ccache/ccache/wiki/Redis-storage. Note that TLS is
# not directly supported by ccache, and requires use of a proxy.
# * For HTTP use the following format: http://ip:port/cache when using
# nginx as backend or http://ip:port|layout=bazel when using Bazel
# Remote Cache, see https://github.com/ccache/ccache/wiki/HTTP-storage.
# Note that HTTPS is not directly supported by ccache.
CCACHE_REMOTE_ONLY: true
CCACHE_REMOTE_STORAGE: http://cache.dev.ripplex.io:8080|layout=bazel
# Ignore the creation and modification timestamps on files, since the
# header files are copied into separate directories by CMake, which will
# otherwise result in cache misses.
CCACHE_SLOPPINESS: include_file_ctime,include_file_mtime
# Determine if coverage and voidstar should be enabled.
COVERAGE_ENABLED: ${{ contains(inputs.cmake_args, '-Dcoverage=ON') }}
VOIDSTAR_ENABLED: ${{ contains(inputs.cmake_args, '-Dvoidstar=ON') }}
steps:
- name: Cleanup workspace (macOS and Windows)
if: ${{ runner.os == 'macOS' || runner.os == 'Windows' }}
uses: XRPLF/actions/.github/actions/cleanup-workspace@01b244d2718865d427b499822fbd3f15e7197fcc
uses: XRPLF/actions/cleanup-workspace@2ece4ec6ab7de266859a6f053571425b2bd684b6
- name: Checkout repository
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Prepare runner
uses: XRPLF/actions/.github/actions/prepare-runner@ff9f8f649df5855ffe1a1ae715df43e51807f2e0
uses: XRPLF/actions/prepare-runner@65da1c59e81965eeb257caa3587b9d45066fb925
with:
disable_ccache: false
enable_ccache: ${{ inputs.ccache_enabled }}
- name: Set ccache log file
if: ${{ inputs.ccache_enabled && runner.debug == '1' }}
run: echo "CCACHE_LOGFILE=${{ runner.temp }}/ccache.log" >> "${GITHUB_ENV}"
- name: Print build environment
uses: ./.github/actions/print-env
- name: Get number of processors
uses: XRPLF/actions/.github/actions/get-nproc@046b1620f6bfd6cd0985dc82c3df02786801fe0a
uses: XRPLF/actions/get-nproc@2ece4ec6ab7de266859a6f053571425b2bd684b6
id: nproc
with:
subtract: ${{ inputs.nproc_subtract }}
@@ -96,7 +123,6 @@ jobs:
- name: Build dependencies
uses: ./.github/actions/build-deps
with:
build_dir: ${{ inputs.build_dir }}
build_nproc: ${{ steps.nproc.outputs.nproc }}
build_type: ${{ inputs.build_type }}
# Set the verbosity to "quiet" for Windows to avoid an excessive
@@ -104,7 +130,7 @@ jobs:
log_verbosity: ${{ runner.os == 'Windows' && 'quiet' || 'verbose' }}
- name: Configure CMake
working-directory: ${{ inputs.build_dir }}
working-directory: ${{ env.BUILD_DIR }}
env:
BUILD_TYPE: ${{ inputs.build_type }}
CMAKE_ARGS: ${{ inputs.cmake_args }}
@@ -117,7 +143,7 @@ jobs:
..
- name: Build the binary
working-directory: ${{ inputs.build_dir }}
working-directory: ${{ env.BUILD_DIR }}
env:
BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
BUILD_TYPE: ${{ inputs.build_type }}
@@ -129,23 +155,30 @@ jobs:
--parallel "${BUILD_NPROC}" \
--target "${CMAKE_TARGET}"
- name: Upload rippled artifact (Linux)
- name: Show ccache statistics
if: ${{ inputs.ccache_enabled }}
run: |
ccache --show-stats -vv
if [ '${{ runner.debug }}' = '1' ]; then
cat "${CCACHE_LOGFILE}"
curl ${CCACHE_REMOTE_STORAGE%|*}/status || true
fi
- name: Upload the binary (Linux)
if: ${{ github.repository_owner == 'XRPLF' && runner.os == 'Linux' }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
env:
BUILD_DIR: ${{ inputs.build_dir }}
with:
name: rippled-${{ inputs.config_name }}
path: ${{ env.BUILD_DIR }}/rippled
name: xrpld-${{ inputs.config_name }}
path: ${{ env.BUILD_DIR }}/xrpld
retention-days: 3
if-no-files-found: error
- name: Check linking (Linux)
if: ${{ runner.os == 'Linux' }}
working-directory: ${{ inputs.build_dir }}
working-directory: ${{ env.BUILD_DIR }}
run: |
ldd ./rippled
if [ "$(ldd ./rippled | grep -E '(libstdc\+\+|libgcc)' | wc -l)" -eq 0 ]; then
ldd ./xrpld
if [ "$(ldd ./xrpld | grep -E '(libstdc\+\+|libgcc)' | wc -l)" -eq 0 ]; then
echo 'The binary is statically linked.'
else
echo 'The binary is dynamically linked.'
@@ -153,14 +186,14 @@ jobs:
fi
- name: Verify presence of instrumentation (Linux)
if: ${{ runner.os == 'Linux' && env.ENABLED_VOIDSTAR == 'true' }}
working-directory: ${{ inputs.build_dir }}
if: ${{ runner.os == 'Linux' && env.VOIDSTAR_ENABLED == 'true' }}
working-directory: ${{ env.BUILD_DIR }}
run: |
./rippled --version | grep libvoidstar
./xrpld --version | grep libvoidstar
- name: Run the separate tests
if: ${{ !inputs.build_only }}
working-directory: ${{ inputs.build_dir }}
working-directory: ${{ env.BUILD_DIR }}
# Windows locks some of the build files while running tests, and parallel jobs can collide
env:
BUILD_TYPE: ${{ inputs.build_type }}
@@ -173,11 +206,11 @@ jobs:
- name: Run the embedded tests
if: ${{ !inputs.build_only }}
working-directory: ${{ runner.os == 'Windows' && format('{0}/{1}', inputs.build_dir, inputs.build_type) || inputs.build_dir }}
working-directory: ${{ runner.os == 'Windows' && format('{0}/{1}', env.BUILD_DIR, inputs.build_type) || env.BUILD_DIR }}
env:
BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
run: |
./rippled --unittest --unittest-jobs "${BUILD_NPROC}"
./xrpld --unittest --unittest-jobs "${BUILD_NPROC}"
- name: Debug failure (Linux)
if: ${{ failure() && runner.os == 'Linux' && !inputs.build_only }}
@@ -188,8 +221,8 @@ jobs:
netstat -an
- name: Prepare coverage report
if: ${{ !inputs.build_only && env.ENABLED_COVERAGE == 'true' }}
working-directory: ${{ inputs.build_dir }}
if: ${{ !inputs.build_only && env.COVERAGE_ENABLED == 'true' }}
working-directory: ${{ env.BUILD_DIR }}
env:
BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
BUILD_TYPE: ${{ inputs.build_type }}
@@ -201,13 +234,13 @@ jobs:
--target coverage
- name: Upload coverage report
if: ${{ github.repository_owner == 'XRPLF' && !inputs.build_only && env.ENABLED_COVERAGE == 'true' }}
if: ${{ github.repository_owner == 'XRPLF' && !inputs.build_only && env.COVERAGE_ENABLED == 'true' }}
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
with:
disable_search: true
disable_telem: true
fail_ci_if_error: true
files: ${{ inputs.build_dir }}/coverage.xml
files: ${{ env.BUILD_DIR }}/coverage.xml
plugins: noop
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true

View File

@@ -8,21 +8,24 @@ name: Build and test
on:
workflow_call:
inputs:
build_dir:
description: "The directory where to build."
ccache_enabled:
description: "Whether to enable ccache."
required: false
type: string
default: ".build"
type: boolean
default: false
os:
description: 'The operating system to use for the build ("linux", "macos", "windows").'
required: true
type: string
strategy_matrix:
# TODO: Support additional strategies, e.g. "ubuntu" for generating all Ubuntu configurations.
description: 'The strategy matrix to use for generating the configurations ("minimal", "all").'
required: false
type: string
default: "minimal"
secrets:
CODECOV_TOKEN:
description: "The Codecov token to use for uploading coverage reports."
@@ -46,9 +49,9 @@ jobs:
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
max-parallel: 10
with:
build_dir: ${{ inputs.build_dir }}
build_only: ${{ matrix.build_only }}
build_type: ${{ matrix.build_type }}
ccache_enabled: ${{ inputs.ccache_enabled }}
cmake_args: ${{ matrix.cmake_args }}
cmake_target: ${{ matrix.cmake_target }}
runs_on: ${{ toJSON(matrix.architecture.runner) }}

View File

@@ -25,7 +25,7 @@ jobs:
env:
MESSAGE: |
The dependency relationships between the modules in rippled have
The dependency relationships between the modules in xrpld have
changed, which may be an improvement or a regression.
A rule of thumb is that if your changes caused something to be

View File

@@ -25,6 +25,12 @@ jobs:
run: .github/scripts/rename/copyright.sh .
- name: Check CMake configs
run: .github/scripts/rename/cmake.sh .
- name: Check binary name
run: .github/scripts/rename/binary.sh .
- name: Check namespaces
run: .github/scripts/rename/namespace.sh .
- name: Check config name
run: .github/scripts/rename/config.sh .
- name: Check for differences
env:
MESSAGE: |

View File

@@ -64,21 +64,21 @@ jobs:
steps:
- name: Cleanup workspace (macOS and Windows)
if: ${{ runner.os == 'macOS' || runner.os == 'Windows' }}
uses: XRPLF/actions/.github/actions/cleanup-workspace@01b244d2718865d427b499822fbd3f15e7197fcc
uses: XRPLF/actions/cleanup-workspace@2ece4ec6ab7de266859a6f053571425b2bd684b6
- name: Checkout repository
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Prepare runner
uses: XRPLF/actions/.github/actions/prepare-runner@ff9f8f649df5855ffe1a1ae715df43e51807f2e0
uses: XRPLF/actions/prepare-runner@65da1c59e81965eeb257caa3587b9d45066fb925
with:
disable_ccache: false
enable_ccache: false
- name: Print build environment
uses: ./.github/actions/print-env
- name: Get number of processors
uses: XRPLF/actions/.github/actions/get-nproc@046b1620f6bfd6cd0985dc82c3df02786801fe0a
uses: XRPLF/actions/get-nproc@2ece4ec6ab7de266859a6f053571425b2bd684b6
id: nproc
with:
subtract: ${{ env.NPROC_SUBTRACT }}
@@ -92,7 +92,6 @@ jobs:
- name: Build dependencies
uses: ./.github/actions/build-deps
with:
build_dir: .build
build_nproc: ${{ steps.nproc.outputs.nproc }}
build_type: ${{ matrix.build_type }}
force_build: ${{ github.event_name == 'schedule' || github.event.inputs.force_source_build == 'true' }}

117
.gitignore vendored
View File

@@ -1,69 +1,48 @@
# .gitignore
# cspell: disable
bin/boostbook_catalog.xml
bin/config.log
bin/project-cache.jam
# Ignore vim swap files.
*.swp
# Ignore SCons support files.
.sconsign.dblite
# Ignore python compiled files.
*.pyc
# Ignore Macintosh Desktop Services Store files.
# Macintosh Desktop Services Store files.
.DS_Store
# Ignore backup/temps
# Build, intermediate, and temporary artifacts.
*~
# Ignore object files.
*.o
.nih_c
tags
TAGS
GTAGS
GRTAGS
GPATH
bin/rippled
Debug/*.*
Release/*.*
*.pdb
*.swp
/.clangd
Debug/
Release/
/.build/
/build/
/db/
/out.txt
/Testing/
/tmp/
CMakeSettings.json
CMakeUserPresets.json
# Ignore coverage files.
# Coverage files.
*.gcno
*.gcda
*.gcov
# Levelization checking
# Profiling data.
gmon.out
# Levelization data.
.github/scripts/levelization/results/*
!.github/scripts/levelization/results/loops.txt
!.github/scripts/levelization/results/ordering.txt
# Ignore tmp directory.
tmp
# Customized configs.
/rippled.cfg
/xrpld.cfg
/validators.txt
# Ignore database directory.
db/
db/*.db
db/*.db-*
# Locally patched Conan recipes
external/conan-center-index/
# Ignore debug logs
debug_log.txt
# Ignore customized configs
rippled.cfg
validators.txt
# Doxygen generated documentation output
HtmlDocumentation
docs/html_doc
# Xcode user-specific project settings
# Xcode
.DS_Store
/build/
# XCode IDE.
*.pbxuser
!default.pbxuser
*.mode1v3
@@ -76,38 +55,16 @@ xcuserdata
profile
*.moved-aside
DerivedData
.idea/
*.hmap
# Intel Parallel Studio 2013 XE
My Amplifier XE Results - RippleD
# JetBrains IDE.
/.idea/
# Compiler intermediate output
/out.txt
# Microsoft Visual Studio IDE.
/.vs/
/.vscode/
# Build Log
rippled-build.log
# Profiling data
gmon.out
Builds/VisualStudio2015/*.db
Builds/VisualStudio2015/*.user
Builds/VisualStudio2015/*.opendb
Builds/VisualStudio2015/*.sdf
# MSVC
*.pdb
.vs/
CMakeSettings.json
compile_commands.json
.clangd
packages
pkg_out
pkg
CMakeUserPresets.json
bld.rippled/
.vscode
# Suggested in-tree build directory
/.build*/
# AI tools.
/.augment
/.claude
/CLAUDE.md

View File

@@ -36,6 +36,21 @@ repos:
hooks:
- id: black
- repo: https://github.com/streetsidesoftware/cspell-cli
rev: v9.2.0
hooks:
- id: cspell # Spell check changed files
exclude: .config/cspell.config.yaml
- id: cspell # Spell check the commit message
name: check commit message spelling
args:
- --no-must-find-files
- --no-progress
- --no-summary
- --files
- .git/COMMIT_EDITMSG
stages: [commit-msg]
exclude: |
(?x)^(
external/.*|

102
BUILD.md
View File

@@ -10,7 +10,7 @@
## Branches
For a stable release, choose the `master` branch or one of the [tagged
releases](https://github.com/ripple/rippled/releases).
releases](https://github.com/XRPLF/rippled/releases).
```bash
git checkout master
@@ -33,7 +33,7 @@ git checkout develop
See [System Requirements](https://xrpl.org/system-requirements.html).
Building rippled generally requires git, Python, Conan, CMake, and a C++
Building xrpld generally requires git, Python, Conan, CMake, and a C++
compiler. Some guidance on setting up such a [C++ development environment can be
found here](./docs/build/environment.md).
@@ -45,7 +45,7 @@ found here](./docs/build/environment.md).
It is possible to build with Conan 1.60+, but the instructions are
significantly different, which is why we are not recommending it.
`rippled` is written in the C++20 dialect and includes the `<concepts>` header.
`xrpld` is written in the C++20 dialect and includes the `<concepts>` header.
The [minimum compiler versions][2] required are:
| Compiler | Version |
@@ -66,7 +66,7 @@ Linux](./docs/build/environment.md#linux).
### Mac
Many rippled engineers use macOS for development.
Many xrpld engineers use macOS for development.
Here are [sample instructions for setting up a C++ development environment on
macOS](./docs/build/environment.md#macos).
@@ -126,7 +126,7 @@ default profile.
### Patched recipes
The recipes in Conan Center occasionally need to be patched for compatibility
with the latest version of `rippled`. We maintain a fork of the Conan Center
with the latest version of `xrpld`. We maintain a fork of the Conan Center
[here](https://github.com/XRPLF/conan-center-index/) containing the patches.
To ensure our patched recipes are used, you must add our Conan remote at a
@@ -141,20 +141,37 @@ Alternatively, you can pull the patched recipes into the repository and use them
locally:
```bash
# Extract the version number from the lockfile.
function extract_version {
version=$(cat conan.lock | sed -nE "s@.+${1}/(.+)#.+@\1@p" | head -n1)
echo ${version}
}
# Define which recipes to export.
recipes=(ed25519 grpc secp256k1 snappy soci)
# Selectively check out the recipes from our CCI fork.
cd external
mkdir -p conan-center-index
cd conan-center-index
git init
git remote add origin git@github.com:XRPLF/conan-center-index.git
git sparse-checkout init
git sparse-checkout set recipes/ed25519
git sparse-checkout add recipes/snappy
git sparse-checkout add recipes/soci
for recipe in ${recipes[@]}; do
echo "Checking out ${recipe}..."
git sparse-checkout add recipes/${recipe}/all
done
git fetch origin master
git checkout master
conan export --version 2015.03 recipes/ed25519/all
conan export --version 1.1.10 recipes/snappy/all
conan export --version 4.0.3 recipes/soci/all
conan export --version 0.42.1 external/wasmi
rm -rf .git
cd ../..
# Export the recipes into the local cache.
for recipe in ${recipes[@]}; do
version=$(extract_version ${recipe})
echo "Exporting ${recipe}/${version}..."
conan export --version $(extract_version ${recipe}) \
external/conan-center-index/recipes/${recipe}/all
done
```
In the case we switch to a newer version of a dependency that still requires a
@@ -275,7 +292,7 @@ sed -i.bak -e 's|^compiler\.libcxx=.*$|compiler.libcxx=libstdc++11|' $(conan con
to do that is to run the shortcut "x64 Native Tools Command Prompt" for the
version of Visual Studio that you have installed.
Windows developers must also build `rippled` and its dependencies for the x64
Windows developers must also build `xrpld` and its dependencies for the x64
architecture:
```bash
@@ -384,19 +401,6 @@ tools.build:cxxflags=['-DBOOST_ASIO_DISABLE_CONCEPTS']
`--settings build_type=$BUILD_TYPE` or in the profile itself,
under the section `[settings]` with the key `build_type`.
If you are using a Microsoft Visual C++ compiler,
then you will need to ensure consistency between the `build_type` setting
and the `compiler.runtime` setting.
When `build_type` is `Release`, `compiler.runtime` should be `MT`.
When `build_type` is `Debug`, `compiler.runtime` should be `MTd`.
```
conan install .. --output-folder . --build missing --settings build_type=Release --settings compiler.runtime=MT
conan install .. --output-folder . --build missing --settings build_type=Debug --settings compiler.runtime=MTd
```
3. Configure CMake and pass the toolchain file generated by Conan, located at
`$OUTPUT_FOLDER/build/generators/conan_toolchain.cmake`.
@@ -418,9 +422,9 @@ tools.build:cxxflags=['-DBOOST_ASIO_DISABLE_CONCEPTS']
cmake -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake -Dxrpld=ON -Dtests=ON ..
```
**Note:** You can pass build options for `rippled` in this step.
**Note:** You can pass build options for `xrpld` in this step.
4. Build `rippled`.
4. Build `xrpld`.
For a single-configuration generator, it will build whatever configuration
you passed for `CMAKE_BUILD_TYPE`. For a multi-configuration generator, you
@@ -439,26 +443,26 @@ tools.build:cxxflags=['-DBOOST_ASIO_DISABLE_CONCEPTS']
cmake --build . --config Debug
```
5. Test rippled.
5. Test xrpld.
Single-config generators:
```
./rippled --unittest --unittest-jobs N
./xrpld --unittest --unittest-jobs N
```
Multi-config generators:
```
./Release/rippled --unittest --unittest-jobs N
./Debug/rippled --unittest --unittest-jobs N
./Release/xrpld --unittest --unittest-jobs N
./Debug/xrpld --unittest --unittest-jobs N
```
Replace the `--unittest-jobs` parameter N with the desired unit tests
concurrency. Recommended setting is half of the number of available CPU
cores.
The location of `rippled` binary in your build directory depends on your
The location of `xrpld` binary in your build directory depends on your
CMake generator. Pass `--help` to see the rest of the command line options.
## Coverage report
@@ -477,18 +481,18 @@ Prerequisites for the coverage report:
A coverage report is created when the following steps are completed, in order:
1. `rippled` binary built with instrumentation data, enabled by the `coverage`
1. `xrpld` binary built with instrumentation data, enabled by the `coverage`
option mentioned above
2. completed one or more run of the unit tests, which populates coverage capture data
3. completed run of the `gcovr` tool (which internally invokes either `gcov` or `llvm-cov`)
to assemble both instrumentation data and the coverage capture data into a coverage report
The last step of the above is automated into a single target `coverage`. The instrumented
`rippled` binary can also be used for regular development or testing work, at
`xrpld` binary can also be used for regular development or testing work, at
the cost of extra disk space utilization and a small performance hit
(to store coverage capture data). Since `rippled` binary is simply a dependency of the
(to store coverage capture data). Since `xrpld` binary is simply a dependency of the
coverage report target, it is possible to re-run the `coverage` target without
rebuilding the `rippled` binary. Note, running of the unit tests before the `coverage`
rebuilding the `xrpld` binary. Note, running of the unit tests before the `coverage`
target is left to the developer. Each such run will append to the coverage data
collected in the build directory.
@@ -516,16 +520,16 @@ stored inside the build directory, as either of:
## Options
| Option | Default Value | Description |
| ---------- | ------------- | -------------------------------------------------------------------------- |
| `assert` | OFF | Enable assertions. |
| `coverage` | OFF | Prepare the coverage report. |
| `san` | N/A | Enable a sanitizer with Clang. Choices are `thread` and `address`. |
| `tests` | OFF | Build tests. |
| `unity` | OFF | Configure a unity build. |
| `xrpld` | OFF | Build the xrpld (`rippled`) application, and not just the libxrpl library. |
| `werr` | OFF | Treat compilation warnings as errors |
| `wextra` | OFF | Enable additional compilation warnings |
| Option | Default Value | Description |
| ---------- | ------------- | ------------------------------------------------------------------ |
| `assert` | OFF | Enable assertions. |
| `coverage` | OFF | Prepare the coverage report. |
| `san` | N/A | Enable a sanitizer with Clang. Choices are `thread` and `address`. |
| `tests` | OFF | Build tests. |
| `unity` | OFF | Configure a unity build. |
| `xrpld` | OFF | Build the xrpld application, and not just the libxrpl library. |
| `werr` | OFF | Treat compilation warnings as errors |
| `wextra` | OFF | Enable additional compilation warnings |
[Unity builds][5] may be faster for the first build
(at the cost of much more memory) since they concatenate sources into fewer
@@ -569,7 +573,7 @@ you might have generated CMake files for a different `build_type` than the
`CMAKE_BUILD_TYPE` you passed to Conan.
```
/rippled/.build/pb-xrpl.libpb/xrpl/proto/xrpl.pb.h:10:10: fatal error: 'google/protobuf/port_def.inc' file not found
/xrpld/.build/pb-xrpl.libpb/xrpl/proto/xrpl.pb.h:10:10: fatal error: 'google/protobuf/port_def.inc' file not found
10 | #include <google/protobuf/port_def.inc>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

View File

@@ -28,6 +28,9 @@ elseif(MSVC)
add_compile_options(/wd4068) # Ignore unknown pragmas
endif()
# Enable ccache to speed up builds.
include(Ccache)
# make GIT_COMMIT_HASH define available to all sources
find_package(Git)
if(Git_FOUND)
@@ -89,14 +92,7 @@ find_package(OpenSSL 1.1.1 REQUIRED)
set_target_properties(OpenSSL::SSL PROPERTIES
INTERFACE_COMPILE_DEFINITIONS OPENSSL_NO_SSL2
)
set(SECP256K1_INSTALL TRUE)
set(SECP256K1_BUILD_BENCHMARK FALSE)
set(SECP256K1_BUILD_TESTS FALSE)
set(SECP256K1_BUILD_EXHAUSTIVE_TESTS FALSE)
set(SECP256K1_BUILD_CTIME_TESTS FALSE)
set(SECP256K1_BUILD_EXAMPLES FALSE)
add_subdirectory(external/secp256k1)
add_library(secp256k1::secp256k1 ALIAS secp256k1)
add_subdirectory(external/antithesis-sdk)
find_package(gRPC REQUIRED)
find_package(lz4 REQUIRED)
@@ -119,7 +115,7 @@ endif()
find_package(date REQUIRED)
find_package(ed25519 REQUIRED)
find_package(nudb REQUIRED)
find_package(wasmi REQUIRED)
find_package(secp256k1 REQUIRED)
find_package(xxHash REQUIRED)
target_link_libraries(xrpl_libs INTERFACE

View File

@@ -24,7 +24,7 @@ your verifying key. Please set up [signature verification][signing].
In general, external contributions should be developed in your personal
[fork][forking]. Contributions from developers with write permissions
should be done in [the main repository][rippled] in a branch with
should be done in [the main repository][xrpld] in a branch with
a permitted prefix. Permitted prefixes are:
- XLS-[a-zA-Z0-9]+/.+
@@ -73,7 +73,7 @@ Ensure that your code compiles according to the build instructions in
Please write tests for your code.
If your test can be run offline, in under 60 seconds, then it can be an
automatic test run by `rippled --unittest`.
automatic test run by `xrpld --unittest`.
Otherwise, it must be a manual test.
If you create new source files, they must be organized as follows:
@@ -256,13 +256,13 @@ pre-commit install
We are using [Antithesis](https://antithesis.com/) for continuous fuzzing,
and keep a copy of [Antithesis C++ SDK](https://github.com/antithesishq/antithesis-sdk-cpp/)
in `external/antithesis-sdk`. One of the aims of fuzzing is to identify bugs
by finding external conditions which cause contracts violations inside `rippled`.
by finding external conditions which cause contracts violations inside `xrpld`.
The contracts are expressed as `XRPL_ASSERT` or `UNREACHABLE` (defined in
`include/xrpl/beast/utility/instrumentation.h`), which are effectively (outside
of Antithesis) wrappers for `assert(...)` with added name. The purpose of name
is to provide contracts with stable identity which does not rely on line numbers.
When `rippled` is built with the Antithesis instrumentation enabled
When `xrpld` is built with the Antithesis instrumentation enabled
(using `voidstar` CMake option) and ran on the Antithesis platform, the
contracts become
[test properties](https://antithesis.com/docs/using_antithesis/properties.html);
@@ -304,7 +304,7 @@ For this reason:
- Example **bad** name
`"RFC1751::insert(char* s, int x, int start, int length) : length is greater than or equal zero"`
(missing namespace, unnecessary full function signature, description too verbose).
Good name: `"ripple::RFC1751::insert : minimum length"`.
Good name: `"xrpl::RFC1751::insert : minimum length"`.
- In **few** well-justified cases a non-standard name can be used, in which case a
comment should be placed to explain the rationale (example in `contract.cpp`)
- Do **not** rename a contract without a good reason (e.g. the name no longer
@@ -318,7 +318,7 @@ For this reason:
To execute all unit tests:
`rippled --unittest --unittest-jobs=<number of cores>`
`xrpld --unittest --unittest-jobs=<number of cores>`
(Note: Using multiple cores on a Mac M1 can cause spurious test failures. The
cause is still under investigation. If you observe this problem, try specifying fewer jobs.)
@@ -326,7 +326,7 @@ cause is still under investigation. If you observe this problem, try specifying
To run a specific set of test suites:
```
rippled --unittest TestSuiteName
xrpld --unittest TestSuiteName
```
Note: In this example, all tests with prefix `TestSuiteName` will be run, so if
@@ -555,16 +555,16 @@ Rippled uses a linear workflow model that can be summarized as:
git fetch --multiple upstreams user1 user2 user3 [...]
git checkout -B release-next --no-track upstream/develop
# Only do an ff-only merge if prbranch1 is either already
# Only do an ff-only merge if pr-branch1 is either already
# squashed, or needs to be merged with separate commits,
# and has no merge commits.
# Use -S on the ff-only merge if prbranch1 isn't signed.
git merge [-S] --ff-only user1/prbranch1
# Use -S on the ff-only merge if pr-branch1 isn't signed.
git merge [-S] --ff-only user1/pr-branch1
git merge --squash user2/prbranch2
git merge --squash user2/pr-branch2
git commit -S # Use the commit message provided on the PR
git merge --squash user3/prbranch3
git merge --squash user3/pr-branch3
git commit -S # Use the commit message provided on the PR
[...]
@@ -876,7 +876,7 @@ git push --delete upstream-push master-next
#### Special cases: point releases, hotfixes, etc.
On occassion, a bug or issue is discovered in a version that already
On occasion, a bug or issue is discovered in a version that already
had a final release. Most of the time, development will have started
on the next version, and will usually have changes in `develop`
and often in `release`.
@@ -1075,7 +1075,7 @@ git fetch upstreams
[contrib]: https://docs.github.com/en/get-started/quickstart/contributing-to-projects
[squash]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges#squash-and-merge-your-commits
[forking]: https://github.com/XRPLF/rippled/fork
[rippled]: https://github.com/XRPLF/rippled
[xrpld]: https://github.com/XRPLF/rippled
[signing]: https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification
[setup-upstreams]: ./bin/git/setup-upstreams.sh
[squash-branches]: ./bin/git/squash-branches.sh

View File

@@ -42,7 +42,7 @@ For more information on responsible disclosure, please read this [Wikipedia arti
## Report Handling Process
Please report the bug directly to us and limit further disclosure. If you want to prove that you knew the bug as of a given time, consider using a cryptographic precommitment: hash the content of your report and publish the hash on a medium of your choice (e.g. on Twitter or as a memo in a transaction) as "proof" that you had written the text at a given point in time.
Please report the bug directly to us and limit further disclosure. If you want to prove that you knew the bug as of a given time, consider using a cryptographic pre-commitment: hash the content of your report and publish the hash on a medium of your choice (e.g. on Twitter or as a memo in a transaction) as "proof" that you had written the text at a given point in time.
Once we receive a report, we:

View File

@@ -1,7 +1,7 @@
#
# Default validators.txt
#
# This file is located in the same folder as your rippled.cfg file
# This file is located in the same folder as your xrpld.cfg file
# and defines which validators your server trusts not to collude.
#
# This file is UTF-8 with DOS, UNIX, or Mac style line endings.

View File

@@ -29,18 +29,18 @@
#
# Purpose
#
# This file documents and provides examples of all rippled server process
# configuration options. When the rippled server instance is launched, it
# This file documents and provides examples of all xrpld server process
# configuration options. When the xrpld server instance is launched, it
# looks for a file with the following name:
#
# rippled.cfg
# xrpld.cfg
#
# For more information on where the rippled server instance searches for the
# For more information on where the xrpld server instance searches for the
# file, visit:
#
# https://xrpl.org/commandline-usage.html#generic-options
#
# This file should be named rippled.cfg. This file is UTF-8 with DOS, UNIX,
# This file should be named xrpld.cfg. This file is UTF-8 with DOS, UNIX,
# or Mac style end of lines. Blank lines and lines beginning with '#' are
# ignored. Undefined sections are reserved. No escapes are currently defined.
#
@@ -89,8 +89,8 @@
#
#
#
# rippled offers various server protocols to clients making inbound
# connections. The listening ports rippled uses are "universal" ports
# xrpld offers various server protocols to clients making inbound
# connections. The listening ports xrpld uses are "universal" ports
# which may be configured to handshake in one or more of the available
# supported protocols. These universal ports simplify administration:
# A single open port can be used for multiple protocols.
@@ -103,7 +103,7 @@
#
# A list of port names and key/value pairs. A port name must start with a
# letter and contain only letters and numbers. The name is not case-sensitive.
# For each name in this list, rippled will look for a configuration file
# For each name in this list, xrpld will look for a configuration file
# section with the same name and use it to create a listening port. The
# name is informational only; the choice of name does not affect the function
# of the listening port.
@@ -134,7 +134,7 @@
# ip = 127.0.0.1
# protocol = http
#
# When rippled is used as a command line client (for example, issuing a
# When xrpld is used as a command line client (for example, issuing a
# server stop command), the first port advertising the http or https
# protocol will be used to make the connection.
#
@@ -175,7 +175,7 @@
# same time. It is possible have both Websockets and Secure Websockets
# together in one port.
#
# NOTE If no ports support the peer protocol, rippled cannot
# NOTE If no ports support the peer protocol, xrpld cannot
# receive incoming peer connections or become a superpeer.
#
# limit = <number>
@@ -194,7 +194,7 @@
# required. IP address restrictions, if any, will be checked in addition
# to the credentials specified here.
#
# When acting in the client role, rippled will supply these credentials
# When acting in the client role, xrpld will supply these credentials
# using HTTP's Basic Authentication headers when making outbound HTTP/S
# requests.
#
@@ -218,7 +218,7 @@
# administrative commands.
#
# NOTE A common configuration value for the admin field is "localhost".
# If you are listening on all IPv4/IPv6 addresses by specifing
# If you are listening on all IPv4/IPv6 addresses by specifying
# ip = :: then you can use admin = ::ffff:127.0.0.1,::1 to allow
# administrative access from both IPv4 and IPv6 localhost
# connections.
@@ -237,7 +237,7 @@
# WS, or WSS protocol interfaces. If administrative commands are
# disabled for a port, these credentials have no effect.
#
# When acting in the client role, rippled will supply these credentials
# When acting in the client role, xrpld will supply these credentials
# in the submitted JSON for any administrative command requests when
# invoking JSON-RPC commands on remote servers.
#
@@ -258,7 +258,7 @@
# resource controls will default to those for non-administrative users.
#
# The secure_gateway IP addresses are intended to represent
# proxies. Since rippled trusts these hosts, they must be
# proxies. Since xrpld trusts these hosts, they must be
# responsible for properly authenticating the remote user.
#
# If some IP addresses are included for both "admin" and
@@ -272,7 +272,7 @@
# Use the specified files when configuring SSL on the port.
#
# NOTE If no files are specified and secure protocols are selected,
# rippled will generate an internal self-signed certificate.
# xrpld will generate an internal self-signed certificate.
#
# The files have these meanings:
#
@@ -297,12 +297,12 @@
# Control the ciphers which the server will support over SSL on the port,
# specified using the OpenSSL "cipher list format".
#
# NOTE If unspecified, rippled will automatically configure a modern
# NOTE If unspecified, xrpld will automatically configure a modern
# cipher suite. This default suite should be widely supported.
#
# You should not modify this string unless you have a specific
# reason and cryptographic expertise. Incorrect modification may
# keep rippled from connecting to other instances of rippled or
# keep xrpld from connecting to other instances of xrpld or
# prevent RPC and WebSocket clients from connecting.
#
# send_queue_limit = [1..65535]
@@ -382,7 +382,7 @@
#-----------------
#
# These settings control security and access attributes of the Peer to Peer
# server section of the rippled process. Peer Protocol implements the
# server section of the xrpld process. Peer Protocol implements the
# Ripple Payment protocol. It is over peer connections that transactions
# and validations are passed from to machine to machine, to determine the
# contents of validated ledgers.
@@ -396,7 +396,7 @@
# true - enables compression
# false - disables compression [default].
#
# The rippled server can save bandwidth by compressing its peer-to-peer communications,
# The xrpld server can save bandwidth by compressing its peer-to-peer communications,
# at a cost of greater CPU usage. If you enable link compression,
# the server automatically compresses communications with peer servers
# that also have link compression enabled.
@@ -432,7 +432,7 @@
#
# [ips_fixed]
#
# List of IP addresses or hostnames to which rippled should always attempt to
# List of IP addresses or hostnames to which xrpld should always attempt to
# maintain peer connections with. This is useful for manually forming private
# networks, for example to configure a validation server that connects to the
# Ripple network through a public-facing server, or for building a set
@@ -573,7 +573,7 @@
#
# minimum_txn_in_ledger_standalone = <number>
#
# Like minimum_txn_in_ledger when rippled is running in standalone
# Like minimum_txn_in_ledger when xrpld is running in standalone
# mode. Default: 1000.
#
# target_txn_in_ledger = <number>
@@ -710,7 +710,7 @@
#
# [validator_token]
#
# This is an alternative to [validation_seed] that allows rippled to perform
# This is an alternative to [validation_seed] that allows xrpld to perform
# validation without having to store the validator keys on the network
# connected server. The field should contain a single token in the form of a
# base64-encoded blob.
@@ -745,7 +745,7 @@
#
# Specify the file by its name or path.
# Unless an absolute path is specified, it will be considered relative to
# the folder in which the rippled.cfg file is located.
# the folder in which the xrpld.cfg file is located.
#
# Examples:
# /home/ripple/validators.txt
@@ -840,7 +840,7 @@
#
# 0: Disable the ledger replay feature [default]
# 1: Enable the ledger replay feature. With this feature enabled, when
# acquiring a ledger from the network, a rippled node only downloads
# acquiring a ledger from the network, a xrpld node only downloads
# the ledger header and the transactions instead of the whole ledger.
# And the ledger is built by applying the transactions to the parent
# ledger.
@@ -851,7 +851,7 @@
#
#----------------
#
# The rippled server instance uses HTTPS GET requests in a variety of
# The xrpld server instance uses HTTPS GET requests in a variety of
# circumstances, including but not limited to contacting trusted domains to
# fetch information such as mapping an email address to a Ripple Payment
# Network address.
@@ -891,7 +891,7 @@
#
#------------
#
# rippled creates 4 SQLite database to hold bookkeeping information
# xrpld creates 4 SQLite database to hold bookkeeping information
# about transactions, local credentials, and various other things.
# It also creates the NodeDB, which holds all the objects that
# make up the current and historical ledgers.
@@ -902,7 +902,7 @@
# the performance of the server.
#
# Partial pathnames will be considered relative to the location of
# the rippled.cfg file.
# the xrpld.cfg file.
#
# [node_db] Settings for the Node Database (required)
#
@@ -920,11 +920,11 @@
# type = NuDB
#
# NuDB is a high-performance database written by Ripple Labs and optimized
# for rippled and solid-state drives.
# for xrpld and solid-state drives.
#
# NuDB maintains its high speed regardless of the amount of history
# stored. Online delete may be selected, but is not required. NuDB is
# available on all platforms that rippled runs on.
# available on all platforms that xrpld runs on.
#
# type = RocksDB
#
@@ -1049,7 +1049,7 @@
#
# recovery_wait_seconds
# The online delete process checks periodically
# that rippled is still in sync with the network,
# that xrpld is still in sync with the network,
# and that the validated ledger is less than
# 'age_threshold_seconds' old. If not, then continue
# sleeping for this number of seconds and
@@ -1069,8 +1069,8 @@
# The server creates and maintains 4 to 5 bookkeeping SQLite databases in
# the 'database_path' location. If you omit this configuration setting,
# the server creates a directory called "db" located in the same place as
# your rippled.cfg file.
# Partial pathnames are relative to the location of the rippled executable.
# your xrpld.cfg file.
# Partial pathnames are relative to the location of the xrpld executable.
#
# [sqlite] Tuning settings for the SQLite databases (optional)
#
@@ -1120,7 +1120,7 @@
# The default is "wal", which uses a write-ahead
# log to implement database transactions.
# Alternately, "memory" saves disk I/O, but if
# rippled crashes during a transaction, the
# xrpld crashes during a transaction, the
# database is likely to be corrupted.
# See https://www.sqlite.org/pragma.html#pragma_journal_mode
# for more details about the available options.
@@ -1130,7 +1130,7 @@
# synchronous Valid values: off, normal, full, extra
# The default is "normal", which works well with
# the "wal" journal mode. Alternatively, "off"
# allows rippled to continue as soon as data is
# allows xrpld to continue as soon as data is
# passed to the OS, which can significantly
# increase speed, but risks data corruption if
# the host computer crashes before writing that
@@ -1144,7 +1144,7 @@
# The default is "file", which will use files
# for temporary database tables and indices.
# Alternatively, "memory" may save I/O, but
# rippled does not currently use many, if any,
# xrpld does not currently use many, if any,
# of these temporary objects.
# See https://www.sqlite.org/pragma.html#pragma_temp_store
# for more details about the available options.
@@ -1173,7 +1173,7 @@
#
# These settings are designed to help server administrators diagnose
# problems, and obtain detailed information about the activities being
# performed by the rippled process.
# performed by the xrpld process.
#
#
#
@@ -1190,7 +1190,7 @@
#
# Configuration parameters for the Beast. Insight stats collection module.
#
# Insight is a module that collects information from the areas of rippled
# Insight is a module that collects information from the areas of xrpld
# that have instrumentation. The configuration parameters control where the
# collection metrics are sent. The parameters are expressed as key = value
# pairs with no white space. The main parameter is the choice of server:
@@ -1199,7 +1199,7 @@
#
# Choice of server to send metrics to. Currently the only choice is
# "statsd" which sends UDP packets to a StatsD daemon, which must be
# running while rippled is running. More information on StatsD is
# running while xrpld is running. More information on StatsD is
# available here:
# https://github.com/b/statsd_spec
#
@@ -1209,7 +1209,7 @@
# in the format, n.n.n.n:port.
#
# "prefix" A string prepended to each collected metric. This is used
# to distinguish between different running instances of rippled.
# to distinguish between different running instances of xrpld.
#
# If this section is missing, or the server type is unspecified or unknown,
# statistics are not collected or reported.
@@ -1236,7 +1236,7 @@
#
# Example:
# [perf]
# perf_log=/var/log/rippled/perf.log
# perf_log=/var/log/xrpld/perf.log
# log_interval=2
#
#-------------------------------------------------------------------------------
@@ -1246,7 +1246,7 @@
#----------
#
# The vote settings configure settings for the entire Ripple network.
# While a single instance of rippled cannot unilaterally enforce network-wide
# While a single instance of xrpld cannot unilaterally enforce network-wide
# settings, these choices become part of the instance's vote during the
# consensus process for each voting ledger.
#
@@ -1260,7 +1260,7 @@
# The reference transaction is the simplest form of transaction.
# It represents an XRP payment between two parties.
#
# If this parameter is unspecified, rippled will use an internal
# If this parameter is unspecified, xrpld will use an internal
# default. Don't change this without understanding the consequences.
#
# Example:
@@ -1272,7 +1272,7 @@
# account's XRP balance that is at or below the reserve may only be
# spent on transaction fees, and not transferred out of the account.
#
# If this parameter is unspecified, rippled will use an internal
# If this parameter is unspecified, xrpld will use an internal
# default. Don't change this without understanding the consequences.
#
# Example:
@@ -1284,45 +1284,12 @@
# each ledger item owned by the account. Ledger items an account may
# own include trust lines, open orders, and tickets.
#
# If this parameter is unspecified, rippled will use an internal
# If this parameter is unspecified, xrpld will use an internal
# default. Don't change this without understanding the consequences.
#
# Example:
# owner_reserve = 2000000 # 2 XRP
#
# extension_compute_limit = <gas>
#
# The extension compute limit is the maximum amount of gas that can be
# consumed by a single transaction. The gas limit is used to prevent
# transactions from consuming too many resources.
#
# If this parameter is unspecified, rippled will use an internal
# default. Don't change this without understanding the consequences.
#
# Example:
# extension_compute_limit = 1000000 # 1 million gas
#
# extension_size_limit = <bytes>
#
# The extension size limit is the maximum size of a WASM extension in
# bytes. The size limit is used to prevent extensions from consuming
# too many resources.
#
# If this parameter is unspecified, rippled will use an internal
# default. Don't change this without understanding the consequences.
#
# Example:
# extension_size_limit = 100000 # 100 kb
#
# gas_price = <bytes>
#
# The gas price is the conversion between WASM gas and its price in drops.
#
# If this parameter is unspecified, rippled will use an internal
# default. Don't change this without understanding the consequences.
#
# Example:
# gas_price = 1000000 # 1 drop per gas
#-------------------------------------------------------------------------------
#
# 9. Misc Settings
@@ -1359,7 +1326,7 @@
# tool instead.
#
# This flag has no effect on the "sign" and "sign_for" command line options
# that rippled makes available.
# that xrpld makes available.
#
# The default value of this field is "false"
#
@@ -1438,7 +1405,7 @@
#--------------------
#
# Administrators can use these values as a starting point for configuring
# their instance of rippled, but each value should be checked to make sure
# their instance of xrpld, but each value should be checked to make sure
# it meets the business requirements for the organization.
#
# Server
@@ -1448,7 +1415,7 @@
# "peer"
#
# Peer protocol open to everyone. This is required to accept
# incoming rippled connections. This does not affect automatic
# incoming xrpld connections. This does not affect automatic
# or manual outgoing Peer protocol connections.
#
# "rpc"
@@ -1465,7 +1432,7 @@
#
# ETL commands for Clio. We recommend setting secure_gateway
# in this section to a comma-separated list of the addresses
# of your Clio servers, in order to bypass rippled's rate limiting.
# of your Clio servers, in order to bypass xrpld's rate limiting.
#
# This port is commented out but can be enabled by removing
# the '#' from each corresponding line including the entry under [server]
@@ -1482,8 +1449,8 @@
# NOTE
#
# To accept connections on well known ports such as 80 (HTTP) or
# 443 (HTTPS), most operating systems will require rippled to
# run with administrator privileges, or else rippled will not start.
# 443 (HTTPS), most operating systems will require xrpld to
# run with administrator privileges, or else xrpld will not start.
[server]
port_rpc_admin_local
@@ -1529,7 +1496,7 @@ secure_gateway = 127.0.0.1
#-------------------------------------------------------------------------------
# This is primary persistent datastore for rippled. This includes transaction
# This is primary persistent datastore for xrpld. This includes transaction
# metadata, account states, and ledger headers. Helpful information can be
# found at https://xrpl.org/capacity-planning.html#node-db-type
# type=NuDB is recommended for non-validators with fast SSDs. Validators or
@@ -1544,19 +1511,19 @@ secure_gateway = 127.0.0.1
# deletion.
[node_db]
type=NuDB
path=/var/lib/rippled/db/nudb
path=/var/lib/xrpld/db/nudb
nudb_block_size=4096
online_delete=512
advisory_delete=0
[database_path]
/var/lib/rippled/db
/var/lib/xrpld/db
# This needs to be an absolute directory reference, not a relative one.
# Modify this value as required.
[debug_logfile]
/var/log/rippled/debug.log
/var/log/xrpld/debug.log
# To use the XRP test network
# (see https://xrpl.org/connect-your-rippled-to-the-xrp-test-net.html),
@@ -1566,7 +1533,7 @@ advisory_delete=0
# File containing trusted validator keys or validator list publishers.
# Unless an absolute path is specified, it will be considered relative to the
# folder in which the rippled.cfg file is located.
# folder in which the xrpld.cfg file is located.
[validators_file]
validators.txt

51
cmake/Ccache.cmake Normal file
View File

@@ -0,0 +1,51 @@
find_program(CCACHE_PATH "ccache")
if (NOT CCACHE_PATH)
return()
endif ()
# For Linux and macOS we can use the ccache binary directly.
if (NOT MSVC)
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PATH}")
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PATH}")
message(STATUS "Found ccache: ${CCACHE_PATH}")
return()
endif ()
# For Windows more effort is required. The code below is a modified version of
# https://github.com/ccache/ccache/wiki/MS-Visual-Studio#usage-with-cmake.
if ("${CCACHE_PATH}" MATCHES "chocolatey")
message(DEBUG "Ccache path: ${CCACHE_PATH}")
# Chocolatey uses a shim executable that we cannot use directly, in which
# case we have to find the executable it points to. If we cannot find the
# target executable then we cannot use ccache.
find_program(BASH_PATH "bash")
if (NOT BASH_PATH)
message(WARNING "Could not find bash.")
return()
endif ()
execute_process(
COMMAND bash -c "export LC_ALL='en_US.UTF-8'; ${CCACHE_PATH} --shimgen-noop | grep -oP 'path to executable: \\K.+' | head -c -1"
OUTPUT_VARIABLE CCACHE_PATH)
if (NOT CCACHE_PATH)
message(WARNING "Could not find ccache target.")
return()
endif ()
file(TO_CMAKE_PATH "${CCACHE_PATH}" CCACHE_PATH)
endif ()
message(STATUS "Found ccache: ${CCACHE_PATH}")
# Tell cmake to use ccache for compiling with Visual Studio.
file(COPY_FILE
${CCACHE_PATH} ${CMAKE_BINARY_DIR}/cl.exe
ONLY_IF_DIFFERENT)
set(CMAKE_VS_GLOBALS
"CLToolExe=cl.exe"
"CLToolPath=${CMAKE_BINARY_DIR}"
"TrackFileAccess=false"
"UseMultiToolTask=true")
# By default Visual Studio generators will use /Zi, which is not compatible with
# ccache, so tell it to use /Z7 instead.
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<$<CONFIG:Debug,RelWithDebInfo>:Embedded>")

View File

@@ -149,7 +149,7 @@ elseif (use_gold AND is_gcc)
ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
#[=========================================================[
NOTE: THE gold linker inserts -rpath as DT_RUNPATH by
default intead of DT_RPATH, so you might have slightly
default instead of DT_RPATH, so you might have slightly
unexpected runtime ld behavior if you were expecting
DT_RPATH. Specify --disable-new-dtags to gold if you do
not want the default DT_RUNPATH behavior. This rpath

View File

@@ -63,7 +63,6 @@ target_link_libraries(xrpl.imports.main
Xrpl::opts
Xrpl::syslibs
secp256k1::secp256k1
wasmi::wasmi
xrpl.libpb
xxHash::xxhash
$<$<BOOL:${voidstar}>:antithesis-sdk-cpp>
@@ -95,10 +94,18 @@ target_link_libraries(xrpl.libxrpl.protocol PUBLIC
)
# Level 05
add_module(xrpl core)
target_link_libraries(xrpl.libxrpl.core PUBLIC
xrpl.libxrpl.basics
xrpl.libxrpl.json
xrpl.libxrpl.protocol
)
# Level 06
add_module(xrpl resource)
target_link_libraries(xrpl.libxrpl.resource PUBLIC xrpl.libxrpl.protocol)
# Level 06
# Level 07
add_module(xrpl net)
target_link_libraries(xrpl.libxrpl.net PUBLIC
xrpl.libxrpl.basics
@@ -145,6 +152,7 @@ target_sources(xrpl.libxrpl PRIVATE ${sources})
target_link_modules(xrpl PUBLIC
basics
beast
core
crypto
json
protocol
@@ -198,7 +206,7 @@ if(xrpld)
)
exclude_if_included(xrpld)
# define a macro for tests that might need to
# be exluded or run differently in CI environment
# be excluded or run differently in CI environment
if(is_ci)
target_compile_definitions(xrpld PRIVATE XRPL_RUNNING_IN_CI)
endif ()
@@ -224,6 +232,4 @@ if(xrpld)
src/test/ledger/Invariants_test.cpp
PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE)
endif()
# For the time being, we will keep the name of the binary as it was.
set_target_properties(xrpld PROPERTIES OUTPUT_NAME "rippled")
endif()

View File

@@ -2,9 +2,7 @@
docs target (optional)
#]===================================================================]
option(with_docs "Include the docs target?" FALSE)
if(NOT (with_docs OR only_docs))
if(NOT only_docs)
return()
endif()

View File

@@ -16,6 +16,7 @@ install (
xrpl.libxrpl
xrpl.libxrpl.basics
xrpl.libxrpl.beast
xrpl.libxrpl.core
xrpl.libxrpl.crypto
xrpl.libxrpl.json
xrpl.libxrpl.ledger
@@ -61,14 +62,14 @@ if (is_root_project AND TARGET xrpld)
message (\"-- Skipping : \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/\${DEST}/\${NEWNAME}\")
endif ()
endmacro()
copy_if_not_exists(\"${CMAKE_CURRENT_SOURCE_DIR}/cfg/rippled-example.cfg\" etc rippled.cfg)
copy_if_not_exists(\"${CMAKE_CURRENT_SOURCE_DIR}/cfg/xrpld-example.cfg\" etc xrpld.cfg)
copy_if_not_exists(\"${CMAKE_CURRENT_SOURCE_DIR}/cfg/validators-example.txt\" etc validators.txt)
")
install(CODE "
set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\")
include(create_symbolic_link)
create_symbolic_link(rippled${suffix} \
\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/xrpld${suffix})
create_symbolic_link(xrpld${suffix} \
\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/rippled${suffix})
")
endif ()

62
conan.lock Normal file
View File

@@ -0,0 +1,62 @@
{
"version": "0.5",
"requires": [
"zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1756234269.497",
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1756234289.683",
"sqlite3/3.49.1#8631739a4c9b93bd3d6b753bac548a63%1756234266.869",
"soci/4.0.3#a9f8d773cd33e356b5879a4b0564f287%1756234262.318",
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1756234314.246",
"secp256k1/0.7.0#9c4ab67bdc3860c16ea5b36aed8f74ea%1765202256.763",
"rocksdb/10.5.1#4a197eca381a3e5ae8adf8cffa5aacd0%1762797952.535",
"re2/20230301#ca3b241baec15bd31ea9187150e0b333%1764175362.029",
"protobuf/6.32.1#f481fd276fc23a33b85a3ed1e898b693%1764863245.83",
"openssl/3.5.4#a1d5835cc6ed5c5b8f3cd5b9b5d24205%1760106486.594",
"nudb/2.0.9#fb8dfd1a5557f5e0528114c2da17721e%1763150366.909",
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1756234228.999",
"libiconv/1.17#1e65319e945f2d31941a9d28cc13c058%1756223727.64",
"libbacktrace/cci.20210118#a7691bfccd8caaf66309df196790a5a1%1756230911.03",
"libarchive/3.8.1#ffee18995c706e02bf96e7a2f7042e0d%1764175360.142",
"jemalloc/5.3.0#e951da9cf599e956cebc117880d2d9f8%1729241615.244",
"grpc/1.72.0#f244a57bff01e708c55a1100b12e1589%1763158050.628",
"ed25519/2015.03#ae761bdc52730a843f0809bdf6c1b1f6%1764270189.893",
"doctest/2.4.12#eb9fb352fb2fdfc8abb17ec270945165%1762797941.757",
"date/3.0.4#862e11e80030356b53c2c38599ceb32b%1763584497.32",
"c-ares/1.34.5#5581c2b62a608b40bb85d965ab3ec7c8%1764175359.429",
"bzip2/1.0.8#c470882369c2d95c5c77e970c0c7e321%1764175359.429",
"boost/1.88.0#8852c0b72ce8271fb8ff7c53456d4983%1756223752.326",
"abseil/20250127.0#9e8e8cfc89a1324139fc0ee3bd4d8c8c%1753819045.301"
],
"build_requires": [
"zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1756234269.497",
"strawberryperl/5.32.1.1#707032463aa0620fa17ec0d887f5fe41%1756234281.733",
"protobuf/6.32.1#f481fd276fc23a33b85a3ed1e898b693%1764863245.83",
"nasm/2.16.01#31e26f2ee3c4346ecd347911bd126904%1756234232.901",
"msys2/cci.latest#1996656c3c98e5765b25b60ff5cf77b4%1764840888.758",
"m4/1.4.19#70dc8bbb33e981d119d2acc0175cf381%1763158052.846",
"cmake/4.2.0#ae0a44f44a1ef9ab68fd4b3e9a1f8671%1764175359.44",
"cmake/3.31.10#313d16a1aa16bbdb2ca0792467214b76%1764175359.429",
"b2/5.3.3#107c15377719889654eb9a162a673975%1756234226.28",
"automake/1.16.5#b91b7c384c3deaa9d535be02da14d04f%1755524470.56",
"autoconf/2.71#51077f068e61700d65bb05541ea1e4b0%1731054366.86",
"abseil/20250127.0#9e8e8cfc89a1324139fc0ee3bd4d8c8c%1753819045.301"
],
"python_requires": [],
"overrides": {
"protobuf/5.27.0": [
"protobuf/6.32.1"
],
"lz4/1.9.4": [
"lz4/1.10.0"
],
"boost/1.83.0": [
"boost/1.88.0"
],
"sqlite3/3.44.2": [
"sqlite3/3.49.1"
],
"lz4/[>=1.9.4 <2]": [
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504"
]
},
"config_requires": []
}

View File

@@ -20,12 +20,6 @@ compiler.libcxx={{detect_api.detect_libcxx(compiler, version, compiler_exe)}}
{% endif %}
[conf]
{% if compiler == "clang" and compiler_version >= 19 %}
grpc/1.50.1:tools.build:cxxflags+=['-Wno-missing-template-arg-list-after-template-kw']
{% endif %}
{% if compiler == "apple-clang" and compiler_version >= 17 %}
grpc/1.50.1:tools.build:cxxflags+=['-Wno-missing-template-arg-list-after-template-kw']
{% endif %}
{% if compiler == "gcc" and compiler_version < 13 %}
tools.build:cxxflags+=['-Wno-restrict']
{% endif %}

View File

@@ -29,12 +29,12 @@ class Xrpl(ConanFile):
requires = [
"ed25519/2015.03",
"grpc/1.50.1",
"grpc/1.72.0",
"libarchive/3.8.1",
"nudb/2.0.9",
"openssl/3.5.4",
"secp256k1/0.7.0",
"soci/4.0.3",
"wasmi/0.42.1",
"zlib/1.3.1",
]
@@ -43,7 +43,7 @@ class Xrpl(ConanFile):
]
tool_requires = [
"protobuf/3.21.12",
"protobuf/6.32.1",
]
default_options = {
@@ -58,8 +58,19 @@ class Xrpl(ConanFile):
"unity": False,
"xrpld": False,
"date/*:header_only": True,
"ed25519/*:shared": False,
"grpc/*:shared": False,
"grpc/*:secure": True,
"grpc/*:codegen": True,
"grpc/*:cpp_plugin": True,
"grpc/*:csharp_ext": False,
"grpc/*:csharp_plugin": False,
"grpc/*:node_plugin": False,
"grpc/*:objective_c_plugin": False,
"grpc/*:php_plugin": False,
"grpc/*:python_plugin": False,
"grpc/*:ruby_plugin": False,
"grpc/*:otel_plugin": False,
"libarchive/*:shared": False,
"libarchive/*:with_acl": False,
"libarchive/*:with_bzip2": False,
@@ -86,6 +97,7 @@ class Xrpl(ConanFile):
"rocksdb/*:with_jemalloc": False,
"rocksdb/*:with_lz4": True,
"rocksdb/*:with_snappy": True,
"secp256k1/*:shared": False,
"snappy/*:shared": False,
"soci/*:shared": False,
"soci/*:with_sqlite3": True,
@@ -116,7 +128,7 @@ class Xrpl(ConanFile):
self.requires("boost/1.88.0", force=True, **transitive_headers_opt)
self.requires("date/3.0.4", **transitive_headers_opt)
self.requires("lz4/1.10.0", force=True)
self.requires("protobuf/3.21.12", force=True)
self.requires("protobuf/6.32.1", force=True)
self.requires("sqlite3/3.49.1", force=True)
if self.options.jemalloc:
self.requires("jemalloc/5.3.0")
@@ -170,12 +182,10 @@ class Xrpl(ConanFile):
libxrpl.libs = [
"xrpl",
"xrpl.libpb",
"ed25519",
"secp256k1",
]
# TODO: Fix the protobufs to include each other relative to
# `include/`, not `include/ripple/proto/`.
libxrpl.includedirs = ["include", "include/ripple/proto"]
# `include/`, not `include/xrpl/proto/`.
libxrpl.includedirs = ["include", "include/xrpl/proto"]
libxrpl.requires = [
"boost::headers",
"boost::chrono",
@@ -198,8 +208,8 @@ class Xrpl(ConanFile):
"openssl::crypto",
"protobuf::libprotobuf",
"soci::soci",
"secp256k1::secp256k1",
"sqlite3::sqlite",
"wasmi::wasmi",
"xxhash::xxhash",
"zlib::zlib",
]

3
docs/.gitignore vendored
View File

@@ -1,3 +0,0 @@
html
temp
out.txt

View File

@@ -134,7 +134,7 @@ validation messages (_PAV_) received from each validator on the node's UNL. Note
that the node will only count the validation messages that agree with its own
validations.
We define the **PAV** as the **P**ercentage of **A**greed **V**alidation
We define the **PAV** as the Percentage of Agreed Validation
messages received for the last N ledgers, where N = 256 by default.
When the PAV drops below the **_low-water mark_**, the validator is considered

View File

@@ -43,14 +43,14 @@ alt phase == OPEN
alt sqn%256==0
CA -[#green]> RM: <font color=green>getValidations
CA -[#green]> CA: <font color=green>create UNLModify Tx
hnote over CA#lightgreen: use validatations of the last 256 ledgers\nto figure out UNLModify Tx candidates.\nIf any, create UNLModify Tx, and add to TxSet.
hnote over CA#lightgreen: use validations of the last 256 ledgers\nto figure out UNLModify Tx candidates.\nIf any, create UNLModify Tx, and add to TxSet.
end
CA -> GC
GC -> CA: propose
deactivate CA
end
else phase == ESTABLISH
hnote over GC: receive peer postions
hnote over GC: receive peer positions
GC -> GC : update our position
GC -> CA : propose \n(if position changed)
GC -> GC : check if have consensus

View File

@@ -54,8 +54,8 @@ There is a `docs` target in the CMake configuration.
```
mkdir build
cd build
cmake ..
cmake --build . --target docs
cmake -Donly_docs=ON ..
cmake --build . --target docs --parallel
```
The output will be in `build/docs/html`.

View File

@@ -189,7 +189,7 @@ validations. It checks this on every call to `timerEntry`.
- _Wrong Ledger_ indicates the node is not working on the correct prior ledger
and does not have it available. It requests that ledger from the network, but
continues to work towards consensus this round while waiting. If it had been
_proposing_, it will send a special "bowout" proposal to its peers to indicate
_proposing_, it will send a special "bow-out" proposal to its peers to indicate
its change in mode for the rest of this round. For the duration of the round,
it defers to peer positions for determining the consensus outcome as if it
were just _observing_.
@@ -515,7 +515,7 @@ are excerpts of the generic consensus implementation and of helper types that wi
interact with the concrete implementing class.
```{.cpp}
// Represents a transction under dispute this round
// Represents a transaction under dispute this round
template <class Tx_t, class NodeID_t> class DisputedTx;
// Represents how the node participates in Consensus this round

1
external/README.md vendored
View File

@@ -5,4 +5,3 @@ The subdirectories in this directory contain external libraries used by rippled.
| Folder | Upstream | Description |
| :--------------- | :------------------------------------------------------------- | :------------------------------------------------------------------------------------------- |
| `antithesis-sdk` | [Project](https://github.com/antithesishq/antithesis-sdk-cpp/) | [Antithesis](https://antithesis.com/docs/using_antithesis/sdk/cpp/overview.html) SDK for C++ |
| `secp256k1` | [Project](https://github.com/bitcoin-core/secp256k1) | ECDSA digital signatures using the **secp256k1** curve |

View File

@@ -1,101 +0,0 @@
env:
### cirrus config
CIRRUS_CLONE_DEPTH: 1
### compiler options
HOST:
WRAPPER_CMD:
# Specific warnings can be disabled with -Wno-error=foo.
# -pedantic-errors is not equivalent to -Werror=pedantic and thus not implied by -Werror according to the GCC manual.
WERROR_CFLAGS: -Werror -pedantic-errors
MAKEFLAGS: -j4
BUILD: check
### secp256k1 config
ECMULTWINDOW: 15
ECMULTGENKB: 22
ASM: no
WIDEMUL: auto
WITH_VALGRIND: yes
EXTRAFLAGS:
### secp256k1 modules
EXPERIMENTAL: no
ECDH: no
RECOVERY: no
EXTRAKEYS: no
SCHNORRSIG: no
MUSIG: no
ELLSWIFT: no
### test options
SECP256K1_TEST_ITERS: 64
BENCH: yes
SECP256K1_BENCH_ITERS: 2
CTIMETESTS: yes
# Compile and run the tests
EXAMPLES: yes
cat_logs_snippet: &CAT_LOGS
always:
cat_tests_log_script:
- cat tests.log || true
cat_noverify_tests_log_script:
- cat noverify_tests.log || true
cat_exhaustive_tests_log_script:
- cat exhaustive_tests.log || true
cat_ctime_tests_log_script:
- cat ctime_tests.log || true
cat_bench_log_script:
- cat bench.log || true
cat_config_log_script:
- cat config.log || true
cat_test_env_script:
- cat test_env.log || true
cat_ci_env_script:
- env
linux_arm64_container_snippet: &LINUX_ARM64_CONTAINER
env_script:
- env | tee /tmp/env
build_script:
- DOCKER_BUILDKIT=1 docker build --file "ci/linux-debian.Dockerfile" --tag="ci_secp256k1_arm"
- docker image prune --force # Cleanup stale layers
test_script:
- docker run --rm --mount "type=bind,src=./,dst=/ci_secp256k1" --env-file /tmp/env --replace --name "ci_secp256k1_arm" "ci_secp256k1_arm" bash -c "cd /ci_secp256k1/ && ./ci/ci.sh"
task:
name: "ARM64: Linux (Debian stable)"
persistent_worker:
labels:
type: arm64
env:
ECDH: yes
RECOVERY: yes
EXTRAKEYS: yes
SCHNORRSIG: yes
MUSIG: yes
ELLSWIFT: yes
matrix:
# Currently only gcc-snapshot, the other compilers are tested on GHA with QEMU
- env: { CC: 'gcc-snapshot' }
<< : *LINUX_ARM64_CONTAINER
<< : *CAT_LOGS
task:
name: "ARM64: Linux (Debian stable), Valgrind"
persistent_worker:
labels:
type: arm64
env:
ECDH: yes
RECOVERY: yes
EXTRAKEYS: yes
SCHNORRSIG: yes
MUSIG: yes
ELLSWIFT: yes
WRAPPER_CMD: 'valgrind --error-exitcode=42'
SECP256K1_TEST_ITERS: 2
matrix:
- env: { CC: 'gcc' }
- env: { CC: 'clang' }
- env: { CC: 'gcc-snapshot' }
- env: { CC: 'clang-snapshot' }
<< : *LINUX_ARM64_CONTAINER
<< : *CAT_LOGS

View File

@@ -1,2 +0,0 @@
src/precomputed_ecmult.c linguist-generated
src/precomputed_ecmult_gen.c linguist-generated

View File

@@ -1,67 +0,0 @@
bench
bench_ecmult
bench_internal
noverify_tests
tests
exhaustive_tests
precompute_ecmult_gen
precompute_ecmult
ctime_tests
ecdh_example
ecdsa_example
schnorr_example
ellswift_example
musig_example
*.exe
*.so
*.a
*.csv
*.log
*.trs
*.sage.py
Makefile
configure
.libs/
Makefile.in
aclocal.m4
autom4te.cache/
config.log
config.status
conftest*
*.tar.gz
*.la
libtool
.deps/
.dirstamp
*.lo
*.o
*~
coverage/
coverage.html
coverage.*.html
*.gcda
*.gcno
*.gcov
build-aux/ar-lib
build-aux/config.guess
build-aux/config.sub
build-aux/depcomp
build-aux/install-sh
build-aux/ltmain.sh
build-aux/m4/libtool.m4
build-aux/m4/lt~obsolete.m4
build-aux/m4/ltoptions.m4
build-aux/m4/ltsugar.m4
build-aux/m4/ltversion.m4
build-aux/missing
build-aux/compile
build-aux/test-driver
libsecp256k1.pc
### CMake
/CMakeUserPresets.json
# Default CMake build directory.
/build

View File

@@ -1,174 +0,0 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.6.0] - 2024-11-04
#### Added
- New module `musig` implements the MuSig2 multisignature scheme according to the [BIP 327 specification](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki). See:
- Header file `include/secp256k1_musig.h` which defines the new API.
- Document `doc/musig.md` for further notes on API usage.
- Usage example `examples/musig.c`.
- New CMake variable `SECP256K1_APPEND_LDFLAGS` for appending linker flags to the build command.
#### Changed
- API functions now use a significantly more robust method to clear secrets from the stack before returning. However, secret clearing remains a best-effort security measure and cannot guarantee complete removal.
- Any type `secp256k1_foo` can now be forward-declared using `typedef struct secp256k1_foo secp256k1_foo;` (or also `struct secp256k1_foo;` in C++).
- Organized CMake build artifacts into dedicated directories (`bin/` for executables, `lib/` for libraries) to improve build output structure and Windows shared library compatibility.
#### Removed
- Removed the `secp256k1_scratch_space` struct and its associated functions `secp256k1_scratch_space_create` and `secp256k1_scratch_space_destroy` because the scratch space was unused in the API.
#### ABI Compatibility
The symbols `secp256k1_scratch_space_create` and `secp256k1_scratch_space_destroy` were removed.
Otherwise, the library maintains backward compatibility with versions 0.3.x through 0.5.x.
## [0.5.1] - 2024-08-01
#### Added
- Added usage example for an ElligatorSwift key exchange.
#### Changed
- The default size of the precomputed table for signing was changed from 22 KiB to 86 KiB. The size can be changed with the configure option `--ecmult-gen-kb` (`SECP256K1_ECMULT_GEN_KB` for CMake).
- "auto" is no longer an accepted value for the `--with-ecmult-window` and `--with-ecmult-gen-kb` configure options (this also applies to `SECP256K1_ECMULT_WINDOW_SIZE` and `SECP256K1_ECMULT_GEN_KB` in CMake). To achieve the same configuration as previously provided by the "auto" value, omit setting the configure option explicitly.
#### Fixed
- Fixed compilation when the extrakeys module is disabled.
#### ABI Compatibility
The ABI is backward compatible with versions 0.5.0, 0.4.x and 0.3.x.
## [0.5.0] - 2024-05-06
#### Added
- New function `secp256k1_ec_pubkey_sort` that sorts public keys using lexicographic (of compressed serialization) order.
#### Changed
- The implementation of the point multiplication algorithm used for signing and public key generation was changed, resulting in improved performance for those operations.
- The related configure option `--ecmult-gen-precision` was replaced with `--ecmult-gen-kb` (`SECP256K1_ECMULT_GEN_KB` for CMake).
- This changes the supported precomputed table sizes for these operations. The new supported sizes are 2 KiB, 22 KiB, or 86 KiB (while the old supported sizes were 32 KiB, 64 KiB, or 512 KiB).
#### ABI Compatibility
The ABI is backward compatible with versions 0.4.x and 0.3.x.
## [0.4.1] - 2023-12-21
#### Changed
- The point multiplication algorithm used for ECDH operations (module `ecdh`) was replaced with a slightly faster one.
- Optional handwritten x86_64 assembly for field operations was removed because modern C compilers are able to output more efficient assembly. This change results in a significant speedup of some library functions when handwritten x86_64 assembly is enabled (`--with-asm=x86_64` in GNU Autotools, `-DSECP256K1_ASM=x86_64` in CMake), which is the default on x86_64. Benchmarks with GCC 10.5.0 show a 10% speedup for `secp256k1_ecdsa_verify` and `secp256k1_schnorrsig_verify`.
#### ABI Compatibility
The ABI is backward compatible with versions 0.4.0 and 0.3.x.
## [0.4.0] - 2023-09-04
#### Added
- New module `ellswift` implements ElligatorSwift encoding for public keys and x-only Diffie-Hellman key exchange for them.
ElligatorSwift permits representing secp256k1 public keys as 64-byte arrays which cannot be distinguished from uniformly random. See:
- Header file `include/secp256k1_ellswift.h` which defines the new API.
- Document `doc/ellswift.md` which explains the mathematical background of the scheme.
- The [paper](https://eprint.iacr.org/2022/759) on which the scheme is based.
- We now test the library with unreleased development snapshots of GCC and Clang. This gives us an early chance to catch miscompilations and constant-time issues introduced by the compiler (such as those that led to the previous two releases).
#### Fixed
- Fixed symbol visibility in Windows DLL builds, where three internal library symbols were wrongly exported.
#### Changed
- When consuming libsecp256k1 as a static library on Windows, the user must now define the `SECP256K1_STATIC` macro before including `secp256k1.h`.
#### ABI Compatibility
This release is backward compatible with the ABI of 0.3.0, 0.3.1, and 0.3.2. Symbol visibility is now believed to be handled properly on supported platforms and is now considered to be part of the ABI. Please report any improperly exported symbols as a bug.
## [0.3.2] - 2023-05-13
We strongly recommend updating to 0.3.2 if you use or plan to use GCC >=13 to compile libsecp256k1. When in doubt, check the GCC version using `gcc -v`.
#### Security
- Module `ecdh`: Fix "constant-timeness" issue with GCC 13.1 (and potentially future versions of GCC) that could leave applications using libsecp256k1's ECDH module vulnerable to a timing side-channel attack. The fix avoids secret-dependent control flow during ECDH computations when libsecp256k1 is compiled with GCC 13.1.
#### Fixed
- Fixed an old bug that permitted compilers to potentially output bad assembly code on x86_64. In theory, it could lead to a crash or a read of unrelated memory, but this has never been observed on any compilers so far.
#### Changed
- Various improvements and changes to CMake builds. CMake builds remain experimental.
- Made API versioning consistent with GNU Autotools builds.
- Switched to `BUILD_SHARED_LIBS` variable for controlling whether to build a static or a shared library.
- Added `SECP256K1_INSTALL` variable for the controlling whether to install the build artefacts.
- Renamed asm build option `arm` to `arm32`. Use `--with-asm=arm32` instead of `--with-asm=arm` (GNU Autotools), and `-DSECP256K1_ASM=arm32` instead of `-DSECP256K1_ASM=arm` (CMake).
#### ABI Compatibility
The ABI is compatible with versions 0.3.0 and 0.3.1.
## [0.3.1] - 2023-04-10
We strongly recommend updating to 0.3.1 if you use or plan to use Clang >=14 to compile libsecp256k1, e.g., Xcode >=14 on macOS has Clang >=14. When in doubt, check the Clang version using `clang -v`.
#### Security
- Fix "constant-timeness" issue with Clang >=14 that could leave applications using libsecp256k1 vulnerable to a timing side-channel attack. The fix avoids secret-dependent control flow and secret-dependent memory accesses in conditional moves of memory objects when libsecp256k1 is compiled with Clang >=14.
#### Added
- Added tests against [Project Wycheproof's](https://github.com/google/wycheproof/) set of ECDSA test vectors (Bitcoin "low-S" variant), a fixed set of test cases designed to trigger various edge cases.
#### Changed
- Increased minimum required CMake version to 3.13. CMake builds remain experimental.
#### ABI Compatibility
The ABI is compatible with version 0.3.0.
## [0.3.0] - 2023-03-08
#### Added
- Added experimental support for CMake builds. Traditional GNU Autotools builds (`./configure` and `make`) remain fully supported.
- Usage examples: Added a recommended method for securely clearing sensitive data, e.g., secret keys, from memory.
- Tests: Added a new test binary `noverify_tests`. This binary runs the tests without some additional checks present in the ordinary `tests` binary and is thereby closer to production binaries. The `noverify_tests` binary is automatically run as part of the `make check` target.
#### Fixed
- Fixed declarations of API variables for MSVC (`__declspec(dllimport)`). This fixes MSVC builds of programs which link against a libsecp256k1 DLL dynamically and use API variables (and not only API functions). Unfortunately, the MSVC linker now will emit warning `LNK4217` when trying to link against libsecp256k1 statically. Pass `/ignore:4217` to the linker to suppress this warning.
#### Changed
- Forbade cloning or destroying `secp256k1_context_static`. Create a new context instead of cloning the static context. (If this change breaks your code, your code is probably wrong.)
- Forbade randomizing (copies of) `secp256k1_context_static`. Randomizing a copy of `secp256k1_context_static` did not have any effect and did not provide defense-in-depth protection against side-channel attacks. Create a new context if you want to benefit from randomization.
#### Removed
- Removed the configuration header `src/libsecp256k1-config.h`. We recommend passing flags to `./configure` or `cmake` to set configuration options (see `./configure --help` or `cmake -LH`). If you cannot or do not want to use one of the supported build systems, pass configuration flags such as `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG` manually to the compiler (see the file `configure.ac` for supported flags).
#### ABI Compatibility
Due to changes in the API regarding `secp256k1_context_static` described above, the ABI is *not* compatible with previous versions.
## [0.2.0] - 2022-12-12
#### Added
- Added usage examples for common use cases in a new `examples/` directory.
- Added `secp256k1_selftest`, to be used in conjunction with `secp256k1_context_static`.
- Added support for 128-bit wide multiplication on MSVC for x86_64 and arm64, giving roughly a 20% speedup on those platforms.
#### Changed
- Enabled modules `schnorrsig`, `extrakeys` and `ecdh` by default in `./configure`.
- The `secp256k1_nonce_function_rfc6979` nonce function, used by default by `secp256k1_ecdsa_sign`, now reduces the message hash modulo the group order to match the specification. This only affects improper use of ECDSA signing API.
#### Deprecated
- Deprecated context flags `SECP256K1_CONTEXT_VERIFY` and `SECP256K1_CONTEXT_SIGN`. Use `SECP256K1_CONTEXT_NONE` instead.
- Renamed `secp256k1_context_no_precomp` to `secp256k1_context_static`.
- Module `schnorrsig`: renamed `secp256k1_schnorrsig_sign` to `secp256k1_schnorrsig_sign32`.
#### ABI Compatibility
Since this is the first release, we do not compare application binary interfaces.
However, there are earlier unreleased versions of libsecp256k1 that are *not* ABI compatible with this version.
## [0.1.0] - 2013-03-05 to 2021-12-25
This version was in fact never released.
The number was given by the build system since the introduction of autotools in Jan 2014 (ea0fe5a5bf0c04f9cc955b2966b614f5f378c6f6).
Therefore, this version number does not uniquely identify a set of source files.
[0.6.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.5.1...v0.6.0
[0.5.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.5.0...v0.5.1
[0.5.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.4.1...v0.5.0
[0.4.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.4.0...v0.4.1
[0.4.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.2...v0.4.0
[0.3.2]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.1...v0.3.2
[0.3.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.0...v0.3.1
[0.3.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.2.0...v0.3.0
[0.2.0]: https://github.com/bitcoin-core/secp256k1/compare/423b6d19d373f1224fd671a982584d7e7900bc93..v0.2.0
[0.1.0]: https://github.com/bitcoin-core/secp256k1/commit/423b6d19d373f1224fd671a982584d7e7900bc93

View File

@@ -1,405 +0,0 @@
cmake_minimum_required(VERSION 3.16)
#=============================
# Project / Package metadata
#=============================
project(libsecp256k1
# The package (a.k.a. release) version is based on semantic versioning 2.0.0 of
# the API. All changes in experimental modules are treated as
# backwards-compatible and therefore at most increase the minor version.
VERSION 0.6.0
DESCRIPTION "Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1."
HOMEPAGE_URL "https://github.com/bitcoin-core/secp256k1"
LANGUAGES C
)
enable_testing()
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
if(CMAKE_VERSION VERSION_LESS 3.21)
# Emulates CMake 3.21+ behavior.
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
set(PROJECT_IS_TOP_LEVEL ON)
set(${PROJECT_NAME}_IS_TOP_LEVEL ON)
else()
set(PROJECT_IS_TOP_LEVEL OFF)
set(${PROJECT_NAME}_IS_TOP_LEVEL OFF)
endif()
endif()
# The library version is based on libtool versioning of the ABI. The set of
# rules for updating the version can be found here:
# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
# All changes in experimental modules are treated as if they don't affect the
# interface and therefore only increase the revision.
set(${PROJECT_NAME}_LIB_VERSION_CURRENT 5)
set(${PROJECT_NAME}_LIB_VERSION_REVISION 0)
set(${PROJECT_NAME}_LIB_VERSION_AGE 0)
#=============================
# Language setup
#=============================
set(CMAKE_C_STANDARD 90)
set(CMAKE_C_EXTENSIONS OFF)
#=============================
# Configurable options
#=============================
option(BUILD_SHARED_LIBS "Build shared libraries." ON)
option(SECP256K1_DISABLE_SHARED "Disable shared library. Overrides BUILD_SHARED_LIBS." OFF)
if(SECP256K1_DISABLE_SHARED)
set(BUILD_SHARED_LIBS OFF)
endif()
option(SECP256K1_INSTALL "Enable installation." ${PROJECT_IS_TOP_LEVEL})
## Modules
# We declare all options before processing them, to make sure we can express
# dependendencies while processing.
option(SECP256K1_ENABLE_MODULE_ECDH "Enable ECDH module." ON)
option(SECP256K1_ENABLE_MODULE_RECOVERY "Enable ECDSA pubkey recovery module." OFF)
option(SECP256K1_ENABLE_MODULE_EXTRAKEYS "Enable extrakeys module." ON)
option(SECP256K1_ENABLE_MODULE_SCHNORRSIG "Enable schnorrsig module." ON)
option(SECP256K1_ENABLE_MODULE_MUSIG "Enable musig module." ON)
option(SECP256K1_ENABLE_MODULE_ELLSWIFT "Enable ElligatorSwift module." ON)
# Processing must be done in a topological sorting of the dependency graph
# (dependent module first).
if(SECP256K1_ENABLE_MODULE_ELLSWIFT)
add_compile_definitions(ENABLE_MODULE_ELLSWIFT=1)
endif()
if(SECP256K1_ENABLE_MODULE_MUSIG)
if(DEFINED SECP256K1_ENABLE_MODULE_SCHNORRSIG AND NOT SECP256K1_ENABLE_MODULE_SCHNORRSIG)
message(FATAL_ERROR "Module dependency error: You have disabled the schnorrsig module explicitly, but it is required by the musig module.")
endif()
set(SECP256K1_ENABLE_MODULE_SCHNORRSIG ON)
add_compile_definitions(ENABLE_MODULE_MUSIG=1)
endif()
if(SECP256K1_ENABLE_MODULE_SCHNORRSIG)
if(DEFINED SECP256K1_ENABLE_MODULE_EXTRAKEYS AND NOT SECP256K1_ENABLE_MODULE_EXTRAKEYS)
message(FATAL_ERROR "Module dependency error: You have disabled the extrakeys module explicitly, but it is required by the schnorrsig module.")
endif()
set(SECP256K1_ENABLE_MODULE_EXTRAKEYS ON)
add_compile_definitions(ENABLE_MODULE_SCHNORRSIG=1)
endif()
if(SECP256K1_ENABLE_MODULE_EXTRAKEYS)
add_compile_definitions(ENABLE_MODULE_EXTRAKEYS=1)
endif()
if(SECP256K1_ENABLE_MODULE_RECOVERY)
add_compile_definitions(ENABLE_MODULE_RECOVERY=1)
endif()
if(SECP256K1_ENABLE_MODULE_ECDH)
add_compile_definitions(ENABLE_MODULE_ECDH=1)
endif()
option(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS "Enable external default callback functions." OFF)
if(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS)
add_compile_definitions(USE_EXTERNAL_DEFAULT_CALLBACKS=1)
endif()
set(SECP256K1_ECMULT_WINDOW_SIZE 15 CACHE STRING "Window size for ecmult precomputation for verification, specified as integer in range [2..24]. The default value is a reasonable setting for desktop machines (currently 15). [default=15]")
set_property(CACHE SECP256K1_ECMULT_WINDOW_SIZE PROPERTY STRINGS 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24)
include(CheckStringOptionValue)
check_string_option_value(SECP256K1_ECMULT_WINDOW_SIZE)
add_compile_definitions(ECMULT_WINDOW_SIZE=${SECP256K1_ECMULT_WINDOW_SIZE})
set(SECP256K1_ECMULT_GEN_KB 86 CACHE STRING "The size of the precomputed table for signing in multiples of 1024 bytes (on typical platforms). Larger values result in possibly better signing or key generation performance at the cost of a larger table. Valid choices are 2, 22, 86. The default value is a reasonable setting for desktop machines (currently 86). [default=86]")
set_property(CACHE SECP256K1_ECMULT_GEN_KB PROPERTY STRINGS 2 22 86)
check_string_option_value(SECP256K1_ECMULT_GEN_KB)
if(SECP256K1_ECMULT_GEN_KB EQUAL 2)
add_compile_definitions(COMB_BLOCKS=2)
add_compile_definitions(COMB_TEETH=5)
elseif(SECP256K1_ECMULT_GEN_KB EQUAL 22)
add_compile_definitions(COMB_BLOCKS=11)
add_compile_definitions(COMB_TEETH=6)
elseif(SECP256K1_ECMULT_GEN_KB EQUAL 86)
add_compile_definitions(COMB_BLOCKS=43)
add_compile_definitions(COMB_TEETH=6)
endif()
set(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY "OFF" CACHE STRING "Test-only override of the (autodetected by the C code) \"widemul\" setting. Legal values are: \"OFF\", \"int128_struct\", \"int128\" or \"int64\". [default=OFF]")
set_property(CACHE SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY PROPERTY STRINGS "OFF" "int128_struct" "int128" "int64")
check_string_option_value(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
if(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
string(TOUPPER "${SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY}" widemul_upper_value)
add_compile_definitions(USE_FORCE_WIDEMUL_${widemul_upper_value}=1)
endif()
mark_as_advanced(FORCE SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
set(SECP256K1_ASM "AUTO" CACHE STRING "Assembly to use: \"AUTO\", \"OFF\", \"x86_64\" or \"arm32\" (experimental). [default=AUTO]")
set_property(CACHE SECP256K1_ASM PROPERTY STRINGS "AUTO" "OFF" "x86_64" "arm32")
check_string_option_value(SECP256K1_ASM)
if(SECP256K1_ASM STREQUAL "arm32")
enable_language(ASM)
include(CheckArm32Assembly)
check_arm32_assembly()
if(HAVE_ARM32_ASM)
add_compile_definitions(USE_EXTERNAL_ASM=1)
else()
message(FATAL_ERROR "ARM32 assembly requested but not available.")
endif()
elseif(SECP256K1_ASM)
include(CheckX86_64Assembly)
check_x86_64_assembly()
if(HAVE_X86_64_ASM)
set(SECP256K1_ASM "x86_64")
add_compile_definitions(USE_ASM_X86_64=1)
elseif(SECP256K1_ASM STREQUAL "AUTO")
set(SECP256K1_ASM "OFF")
else()
message(FATAL_ERROR "x86_64 assembly requested but not available.")
endif()
endif()
option(SECP256K1_EXPERIMENTAL "Allow experimental configuration options." OFF)
if(NOT SECP256K1_EXPERIMENTAL)
if(SECP256K1_ASM STREQUAL "arm32")
message(FATAL_ERROR "ARM32 assembly is experimental. Use -DSECP256K1_EXPERIMENTAL=ON to allow.")
endif()
endif()
set(SECP256K1_VALGRIND "AUTO" CACHE STRING "Build with extra checks for running inside Valgrind. [default=AUTO]")
set_property(CACHE SECP256K1_VALGRIND PROPERTY STRINGS "AUTO" "OFF" "ON")
check_string_option_value(SECP256K1_VALGRIND)
if(SECP256K1_VALGRIND)
find_package(Valgrind MODULE)
if(Valgrind_FOUND)
set(SECP256K1_VALGRIND ON)
include_directories(${Valgrind_INCLUDE_DIR})
add_compile_definitions(VALGRIND)
elseif(SECP256K1_VALGRIND STREQUAL "AUTO")
set(SECP256K1_VALGRIND OFF)
else()
message(FATAL_ERROR "Valgrind support requested but valgrind/memcheck.h header not available.")
endif()
endif()
option(SECP256K1_BUILD_BENCHMARK "Build benchmarks." ON)
option(SECP256K1_BUILD_TESTS "Build tests." ON)
option(SECP256K1_BUILD_EXHAUSTIVE_TESTS "Build exhaustive tests." ON)
option(SECP256K1_BUILD_CTIME_TESTS "Build constant-time tests." ${SECP256K1_VALGRIND})
option(SECP256K1_BUILD_EXAMPLES "Build examples." OFF)
# Redefine configuration flags.
# We leave assertions on, because they are only used in the examples, and we want them always on there.
if(MSVC)
string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}")
else()
string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}")
# Prefer -O2 optimization level. (-O3 is CMake's default for Release for many compilers.)
string(REGEX REPLACE "-O3( |$)" "-O2\\1" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
endif()
# Define custom "Coverage" build type.
set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O0 -DCOVERAGE=1 --coverage" CACHE STRING
"Flags used by the C compiler during \"Coverage\" builds."
FORCE
)
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} --coverage" CACHE STRING
"Flags used for linking binaries during \"Coverage\" builds."
FORCE
)
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} --coverage" CACHE STRING
"Flags used by the shared libraries linker during \"Coverage\" builds."
FORCE
)
mark_as_advanced(
CMAKE_C_FLAGS_COVERAGE
CMAKE_EXE_LINKER_FLAGS_COVERAGE
CMAKE_SHARED_LINKER_FLAGS_COVERAGE
)
if(PROJECT_IS_TOP_LEVEL)
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
set(default_build_type "RelWithDebInfo")
if(is_multi_config)
set(CMAKE_CONFIGURATION_TYPES "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage" CACHE STRING
"Supported configuration types."
FORCE
)
else()
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
STRINGS "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage"
)
if(NOT CMAKE_BUILD_TYPE)
message(STATUS "Setting build type to \"${default_build_type}\" as none was specified")
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING
"Choose the type of build."
FORCE
)
endif()
endif()
endif()
include(TryAppendCFlags)
if(MSVC)
# Keep the following commands ordered lexicographically.
try_append_c_flags(/W3) # Production quality warning level.
try_append_c_flags(/wd4146) # Disable warning C4146 "unary minus operator applied to unsigned type, result still unsigned".
try_append_c_flags(/wd4244) # Disable warning C4244 "'conversion' conversion from 'type1' to 'type2', possible loss of data".
try_append_c_flags(/wd4267) # Disable warning C4267 "'var' : conversion from 'size_t' to 'type', possible loss of data".
# Eliminate deprecation warnings for the older, less secure functions.
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
else()
# Keep the following commands ordered lexicographically.
try_append_c_flags(-pedantic)
try_append_c_flags(-Wall) # GCC >= 2.95 and probably many other compilers.
try_append_c_flags(-Wcast-align) # GCC >= 2.95.
try_append_c_flags(-Wcast-align=strict) # GCC >= 8.0.
try_append_c_flags(-Wconditional-uninitialized) # Clang >= 3.0 only.
try_append_c_flags(-Wextra) # GCC >= 3.4, this is the newer name of -W, which we don't use because older GCCs will warn about unused functions.
try_append_c_flags(-Wnested-externs)
try_append_c_flags(-Wno-long-long) # GCC >= 3.0, -Wlong-long is implied by -pedantic.
try_append_c_flags(-Wno-overlength-strings) # GCC >= 4.2, -Woverlength-strings is implied by -pedantic.
try_append_c_flags(-Wno-unused-function) # GCC >= 3.0, -Wunused-function is implied by -Wall.
try_append_c_flags(-Wreserved-identifier) # Clang >= 13.0 only.
try_append_c_flags(-Wshadow)
try_append_c_flags(-Wstrict-prototypes)
try_append_c_flags(-Wundef)
endif()
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(print_msan_notice)
if(SECP256K1_BUILD_CTIME_TESTS)
include(CheckMemorySanitizer)
check_memory_sanitizer(msan_enabled)
if(msan_enabled)
try_append_c_flags(-fno-sanitize-memory-param-retval)
set(print_msan_notice YES)
endif()
unset(msan_enabled)
endif()
set(SECP256K1_APPEND_CFLAGS "" CACHE STRING "Compiler flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.")
if(SECP256K1_APPEND_CFLAGS)
# Appending to this low-level rule variable is the only way to
# guarantee that the flags appear at the end of the command line.
string(APPEND CMAKE_C_COMPILE_OBJECT " ${SECP256K1_APPEND_CFLAGS}")
endif()
set(SECP256K1_APPEND_LDFLAGS "" CACHE STRING "Linker flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.")
if(SECP256K1_APPEND_LDFLAGS)
# Appending to this low-level rule variable is the only way to
# guarantee that the flags appear at the end of the command line.
string(APPEND CMAKE_C_CREATE_SHARED_LIBRARY " ${SECP256K1_APPEND_LDFLAGS}")
string(APPEND CMAKE_C_LINK_EXECUTABLE " ${SECP256K1_APPEND_LDFLAGS}")
endif()
if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
endif()
if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
endif()
if(NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
endif()
add_subdirectory(src)
if(SECP256K1_BUILD_EXAMPLES)
add_subdirectory(examples)
endif()
message("\n")
message("secp256k1 configure summary")
message("===========================")
message("Build artifacts:")
if(BUILD_SHARED_LIBS)
set(library_type "Shared")
else()
set(library_type "Static")
endif()
message(" library type ........................ ${library_type}")
message("Optional modules:")
message(" ECDH ................................ ${SECP256K1_ENABLE_MODULE_ECDH}")
message(" ECDSA pubkey recovery ............... ${SECP256K1_ENABLE_MODULE_RECOVERY}")
message(" extrakeys ........................... ${SECP256K1_ENABLE_MODULE_EXTRAKEYS}")
message(" schnorrsig .......................... ${SECP256K1_ENABLE_MODULE_SCHNORRSIG}")
message(" musig ............................... ${SECP256K1_ENABLE_MODULE_MUSIG}")
message(" ElligatorSwift ...................... ${SECP256K1_ENABLE_MODULE_ELLSWIFT}")
message("Parameters:")
message(" ecmult window size .................. ${SECP256K1_ECMULT_WINDOW_SIZE}")
message(" ecmult gen table size ............... ${SECP256K1_ECMULT_GEN_KB} KiB")
message("Optional features:")
message(" assembly ............................ ${SECP256K1_ASM}")
message(" external callbacks .................. ${SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS}")
if(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
message(" wide multiplication (test-only) ..... ${SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY}")
endif()
message("Optional binaries:")
message(" benchmark ........................... ${SECP256K1_BUILD_BENCHMARK}")
message(" noverify_tests ...................... ${SECP256K1_BUILD_TESTS}")
set(tests_status "${SECP256K1_BUILD_TESTS}")
if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
set(tests_status OFF)
endif()
message(" tests ............................... ${tests_status}")
message(" exhaustive tests .................... ${SECP256K1_BUILD_EXHAUSTIVE_TESTS}")
message(" ctime_tests ......................... ${SECP256K1_BUILD_CTIME_TESTS}")
message(" examples ............................ ${SECP256K1_BUILD_EXAMPLES}")
message("")
if(CMAKE_CROSSCOMPILING)
set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}")
else()
set(cross_status "FALSE")
endif()
message("Cross compiling ....................... ${cross_status}")
message("Valgrind .............................. ${SECP256K1_VALGRIND}")
get_directory_property(definitions COMPILE_DEFINITIONS)
string(REPLACE ";" " " definitions "${definitions}")
message("Preprocessor defined macros ........... ${definitions}")
message("C compiler ............................ ${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION}, ${CMAKE_C_COMPILER}")
message("CFLAGS ................................ ${CMAKE_C_FLAGS}")
get_directory_property(compile_options COMPILE_OPTIONS)
string(REPLACE ";" " " compile_options "${compile_options}")
message("Compile options ....................... " ${compile_options})
if(NOT is_multi_config)
message("Build type:")
message(" - CMAKE_BUILD_TYPE ................... ${CMAKE_BUILD_TYPE}")
string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_${build_type}}")
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_${build_type}}")
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_${build_type}}")
else()
message("Supported configurations .............. ${CMAKE_CONFIGURATION_TYPES}")
message("RelWithDebInfo configuration:")
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}")
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}")
message("Debug configuration:")
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_DEBUG}")
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
endif()
if(SECP256K1_APPEND_CFLAGS)
message("SECP256K1_APPEND_CFLAGS ............... ${SECP256K1_APPEND_CFLAGS}")
endif()
if(SECP256K1_APPEND_LDFLAGS)
message("SECP256K1_APPEND_LDFLAGS .............. ${SECP256K1_APPEND_LDFLAGS}")
endif()
message("")
if(print_msan_notice)
message(
"Note:\n"
" MemorySanitizer detected, tried to add -fno-sanitize-memory-param-retval to compile options\n"
" to avoid false positives in ctime_tests. Pass -DSECP256K1_BUILD_CTIME_TESTS=OFF to avoid this.\n"
)
endif()
if(SECP256K1_EXPERIMENTAL)
message(
" ******\n"
" WARNING: experimental build\n"
" Experimental features do not have stable APIs or properties, and may not be safe for production use.\n"
" ******\n"
)
endif()

View File

@@ -1,19 +0,0 @@
{
"cmakeMinimumRequired": {"major": 3, "minor": 21, "patch": 0},
"version": 3,
"configurePresets": [
{
"name": "dev-mode",
"displayName": "Development mode (intended only for developers of the library)",
"cacheVariables": {
"SECP256K1_EXPERIMENTAL": "ON",
"SECP256K1_ENABLE_MODULE_RECOVERY": "ON",
"SECP256K1_BUILD_EXAMPLES": "ON"
},
"warnings": {
"dev": true,
"uninitialized": true
}
}
]
}

View File

@@ -1,108 +0,0 @@
# Contributing to libsecp256k1
## Scope
libsecp256k1 is a library for elliptic curve cryptography on the curve secp256k1, not a general-purpose cryptography library.
The library primarily serves the needs of the Bitcoin Core project but provides additional functionality for the benefit of the wider Bitcoin ecosystem.
## Adding new functionality or modules
The libsecp256k1 project welcomes contributions in the form of new functionality or modules, provided they are within the project's scope.
It is the responsibility of the contributors to convince the maintainers that the proposed functionality is within the project's scope, high-quality and maintainable.
Contributors are recommended to provide the following in addition to the new code:
* **Specification:**
A specification can help significantly in reviewing the new code as it provides documentation and context.
It may justify various design decisions, give a motivation and outline security goals.
If the specification contains pseudocode, a reference implementation or test vectors, these can be used to compare with the proposed libsecp256k1 code.
* **Security Arguments:**
In addition to a defining the security goals, it should be argued that the new functionality meets these goals.
Depending on the nature of the new functionality, a wide range of security arguments are acceptable, ranging from being "obviously secure" to rigorous proofs of security.
* **Relevance Arguments:**
The relevance of the new functionality for the Bitcoin ecosystem should be argued by outlining clear use cases.
These are not the only factors taken into account when considering to add new functionality.
The proposed new libsecp256k1 code must be of high quality, including API documentation and tests, as well as featuring a misuse-resistant API design.
We recommend reaching out to other contributors (see [Communication Channels](#communication-channels)) and get feedback before implementing new functionality.
## Communication channels
Most communication about libsecp256k1 occurs on the GitHub repository: in issues, pull request or on the discussion board.
Additionally, there is an IRC channel dedicated to libsecp256k1, with biweekly meetings (see channel topic).
The channel is `#secp256k1` on Libera Chat.
The easiest way to participate on IRC is with the web client, [web.libera.chat](https://web.libera.chat/#secp256k1).
Chat history logs can be found at https://gnusha.org/secp256k1/.
## Contributor workflow & peer review
The Contributor Workflow & Peer Review in libsecp256k1 are similar to Bitcoin Core's workflow and review processes described in its [CONTRIBUTING.md](https://github.com/bitcoin/bitcoin/blob/master/CONTRIBUTING.md).
### Coding conventions
In addition, libsecp256k1 tries to maintain the following coding conventions:
* No runtime heap allocation (e.g., no `malloc`) unless explicitly requested by the caller (via `secp256k1_context_create` or `secp256k1_scratch_space_create`, for example). Moreover, it should be possible to use the library without any heap allocations.
* The tests should cover all lines and branches of the library (see [Test coverage](#coverage)).
* Operations involving secret data should be tested for being constant time with respect to the secrets (see [src/ctime_tests.c](src/ctime_tests.c)).
* Local variables containing secret data should be cleared explicitly to try to delete secrets from memory.
* Use `secp256k1_memcmp_var` instead of `memcmp` (see [#823](https://github.com/bitcoin-core/secp256k1/issues/823)).
* As a rule of thumb, the default values for configuration options should target standard desktop machines and align with Bitcoin Core's defaults, and the tests should mostly exercise the default configuration (see [#1549](https://github.com/bitcoin-core/secp256k1/issues/1549#issuecomment-2200559257)).
#### Style conventions
* Commits should be atomic and diffs should be easy to read. For this reason, do not mix any formatting fixes or code moves with actual code changes. Make sure each individual commit is hygienic: that it builds successfully on its own without warnings, errors, regressions, or test failures.
* New code should adhere to the style of existing, in particular surrounding, code. Other than that, we do not enforce strict rules for code formatting.
* The code conforms to C89. Most notably, that means that only `/* ... */` comments are allowed (no `//` line comments). Moreover, any declarations in a `{ ... }` block (e.g., a function) must appear at the beginning of the block before any statements. When you would like to declare a variable in the middle of a block, you can open a new block:
```C
void secp256k_foo(void) {
unsigned int x; /* declaration */
int y = 2*x; /* declaration */
x = 17; /* statement */
{
int a, b; /* declaration */
a = x + y; /* statement */
secp256k_bar(x, &b); /* statement */
}
}
```
* Use `unsigned int` instead of just `unsigned`.
* Use `void *ptr` instead of `void* ptr`.
* Arguments of the publicly-facing API must have a specific order defined in [include/secp256k1.h](include/secp256k1.h).
* User-facing comment lines in headers should be limited to 80 chars if possible.
* All identifiers in file scope should start with `secp256k1_`.
* Avoid trailing whitespace.
### Tests
#### Coverage
This library aims to have full coverage of reachable lines and branches.
To create a test coverage report, configure with `--enable-coverage` (use of GCC is necessary):
$ ./configure --enable-coverage
Run the tests:
$ make check
To create a report, `gcovr` is recommended, as it includes branch coverage reporting:
$ gcovr --exclude 'src/bench*' --print-summary
To create a HTML report with coloured and annotated source code:
$ mkdir -p coverage
$ gcovr --exclude 'src/bench*' --html --html-details -o coverage/coverage.html
#### Exhaustive tests
There are tests of several functions in which a small group replaces secp256k1.
These tests are *exhaustive* since they provide all elements and scalars of the small group as input arguments (see [src/tests_exhaustive.c](src/tests_exhaustive.c)).
### Benchmarks
See `src/bench*.c` for examples of benchmarks.

View File

@@ -1,19 +0,0 @@
Copyright (c) 2013 Pieter Wuille
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -1,302 +0,0 @@
ACLOCAL_AMFLAGS = -I build-aux/m4
# AM_CFLAGS will be automatically prepended to CFLAGS by Automake when compiling some foo
# which does not have an explicit foo_CFLAGS variable set.
AM_CFLAGS = $(SECP_CFLAGS)
lib_LTLIBRARIES = libsecp256k1.la
include_HEADERS = include/secp256k1.h
include_HEADERS += include/secp256k1_preallocated.h
noinst_HEADERS =
noinst_HEADERS += src/scalar.h
noinst_HEADERS += src/scalar_4x64.h
noinst_HEADERS += src/scalar_8x32.h
noinst_HEADERS += src/scalar_low.h
noinst_HEADERS += src/scalar_impl.h
noinst_HEADERS += src/scalar_4x64_impl.h
noinst_HEADERS += src/scalar_8x32_impl.h
noinst_HEADERS += src/scalar_low_impl.h
noinst_HEADERS += src/group.h
noinst_HEADERS += src/group_impl.h
noinst_HEADERS += src/ecdsa.h
noinst_HEADERS += src/ecdsa_impl.h
noinst_HEADERS += src/eckey.h
noinst_HEADERS += src/eckey_impl.h
noinst_HEADERS += src/ecmult.h
noinst_HEADERS += src/ecmult_impl.h
noinst_HEADERS += src/ecmult_compute_table.h
noinst_HEADERS += src/ecmult_compute_table_impl.h
noinst_HEADERS += src/ecmult_const.h
noinst_HEADERS += src/ecmult_const_impl.h
noinst_HEADERS += src/ecmult_gen.h
noinst_HEADERS += src/ecmult_gen_impl.h
noinst_HEADERS += src/ecmult_gen_compute_table.h
noinst_HEADERS += src/ecmult_gen_compute_table_impl.h
noinst_HEADERS += src/field_10x26.h
noinst_HEADERS += src/field_10x26_impl.h
noinst_HEADERS += src/field_5x52.h
noinst_HEADERS += src/field_5x52_impl.h
noinst_HEADERS += src/field_5x52_int128_impl.h
noinst_HEADERS += src/modinv32.h
noinst_HEADERS += src/modinv32_impl.h
noinst_HEADERS += src/modinv64.h
noinst_HEADERS += src/modinv64_impl.h
noinst_HEADERS += src/precomputed_ecmult.h
noinst_HEADERS += src/precomputed_ecmult_gen.h
noinst_HEADERS += src/assumptions.h
noinst_HEADERS += src/checkmem.h
noinst_HEADERS += src/testutil.h
noinst_HEADERS += src/util.h
noinst_HEADERS += src/int128.h
noinst_HEADERS += src/int128_impl.h
noinst_HEADERS += src/int128_native.h
noinst_HEADERS += src/int128_native_impl.h
noinst_HEADERS += src/int128_struct.h
noinst_HEADERS += src/int128_struct_impl.h
noinst_HEADERS += src/scratch.h
noinst_HEADERS += src/scratch_impl.h
noinst_HEADERS += src/selftest.h
noinst_HEADERS += src/testrand.h
noinst_HEADERS += src/testrand_impl.h
noinst_HEADERS += src/hash.h
noinst_HEADERS += src/hash_impl.h
noinst_HEADERS += src/field.h
noinst_HEADERS += src/field_impl.h
noinst_HEADERS += src/bench.h
noinst_HEADERS += src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h
noinst_HEADERS += src/hsort.h
noinst_HEADERS += src/hsort_impl.h
noinst_HEADERS += contrib/lax_der_parsing.h
noinst_HEADERS += contrib/lax_der_parsing.c
noinst_HEADERS += contrib/lax_der_privatekey_parsing.h
noinst_HEADERS += contrib/lax_der_privatekey_parsing.c
noinst_HEADERS += examples/examples_util.h
PRECOMPUTED_LIB = libsecp256k1_precomputed.la
noinst_LTLIBRARIES = $(PRECOMPUTED_LIB)
libsecp256k1_precomputed_la_SOURCES = src/precomputed_ecmult.c src/precomputed_ecmult_gen.c
# We need `-I$(top_srcdir)/src` in VPATH builds if libsecp256k1_precomputed_la_SOURCES have been recreated in the build tree.
# This helps users and packagers who insist on recreating the precomputed files (e.g., Gentoo).
libsecp256k1_precomputed_la_CPPFLAGS = -I$(top_srcdir)/src $(SECP_CONFIG_DEFINES)
if USE_EXTERNAL_ASM
COMMON_LIB = libsecp256k1_common.la
else
COMMON_LIB =
endif
noinst_LTLIBRARIES += $(COMMON_LIB)
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libsecp256k1.pc
if USE_EXTERNAL_ASM
if USE_ASM_ARM
libsecp256k1_common_la_SOURCES = src/asm/field_10x26_arm.s
endif
endif
libsecp256k1_la_SOURCES = src/secp256k1.c
libsecp256k1_la_CPPFLAGS = $(SECP_CONFIG_DEFINES)
libsecp256k1_la_LIBADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
libsecp256k1_la_LDFLAGS = -no-undefined -version-info $(LIB_VERSION_CURRENT):$(LIB_VERSION_REVISION):$(LIB_VERSION_AGE)
noinst_PROGRAMS =
if USE_BENCHMARK
noinst_PROGRAMS += bench bench_internal bench_ecmult
bench_SOURCES = src/bench.c
bench_LDADD = libsecp256k1.la
bench_CPPFLAGS = $(SECP_CONFIG_DEFINES)
bench_internal_SOURCES = src/bench_internal.c
bench_internal_LDADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
bench_internal_CPPFLAGS = $(SECP_CONFIG_DEFINES)
bench_ecmult_SOURCES = src/bench_ecmult.c
bench_ecmult_LDADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
bench_ecmult_CPPFLAGS = $(SECP_CONFIG_DEFINES)
endif
TESTS =
if USE_TESTS
TESTS += noverify_tests
noinst_PROGRAMS += noverify_tests
noverify_tests_SOURCES = src/tests.c
noverify_tests_CPPFLAGS = $(SECP_CONFIG_DEFINES)
noverify_tests_LDADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
noverify_tests_LDFLAGS = -static
if !ENABLE_COVERAGE
TESTS += tests
noinst_PROGRAMS += tests
tests_SOURCES = $(noverify_tests_SOURCES)
tests_CPPFLAGS = $(noverify_tests_CPPFLAGS) -DVERIFY
tests_LDADD = $(noverify_tests_LDADD)
tests_LDFLAGS = $(noverify_tests_LDFLAGS)
endif
endif
if USE_CTIME_TESTS
noinst_PROGRAMS += ctime_tests
ctime_tests_SOURCES = src/ctime_tests.c
ctime_tests_LDADD = libsecp256k1.la
ctime_tests_CPPFLAGS = $(SECP_CONFIG_DEFINES)
endif
if USE_EXHAUSTIVE_TESTS
noinst_PROGRAMS += exhaustive_tests
exhaustive_tests_SOURCES = src/tests_exhaustive.c
exhaustive_tests_CPPFLAGS = $(SECP_CONFIG_DEFINES)
if !ENABLE_COVERAGE
exhaustive_tests_CPPFLAGS += -DVERIFY
endif
# Note: do not include $(PRECOMPUTED_LIB) in exhaustive_tests (it uses runtime-generated tables).
exhaustive_tests_LDADD = $(COMMON_LIB)
exhaustive_tests_LDFLAGS = -static
TESTS += exhaustive_tests
endif
if USE_EXAMPLES
noinst_PROGRAMS += ecdsa_example
ecdsa_example_SOURCES = examples/ecdsa.c
ecdsa_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
ecdsa_example_LDADD = libsecp256k1.la
ecdsa_example_LDFLAGS = -static
if BUILD_WINDOWS
ecdsa_example_LDFLAGS += -lbcrypt
endif
TESTS += ecdsa_example
if ENABLE_MODULE_ECDH
noinst_PROGRAMS += ecdh_example
ecdh_example_SOURCES = examples/ecdh.c
ecdh_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
ecdh_example_LDADD = libsecp256k1.la
ecdh_example_LDFLAGS = -static
if BUILD_WINDOWS
ecdh_example_LDFLAGS += -lbcrypt
endif
TESTS += ecdh_example
endif
if ENABLE_MODULE_SCHNORRSIG
noinst_PROGRAMS += schnorr_example
schnorr_example_SOURCES = examples/schnorr.c
schnorr_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
schnorr_example_LDADD = libsecp256k1.la
schnorr_example_LDFLAGS = -static
if BUILD_WINDOWS
schnorr_example_LDFLAGS += -lbcrypt
endif
TESTS += schnorr_example
endif
if ENABLE_MODULE_ELLSWIFT
noinst_PROGRAMS += ellswift_example
ellswift_example_SOURCES = examples/ellswift.c
ellswift_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
ellswift_example_LDADD = libsecp256k1.la
ellswift_example_LDFLAGS = -static
if BUILD_WINDOWS
ellswift_example_LDFLAGS += -lbcrypt
endif
TESTS += ellswift_example
endif
if ENABLE_MODULE_MUSIG
noinst_PROGRAMS += musig_example
musig_example_SOURCES = examples/musig.c
musig_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
musig_example_LDADD = libsecp256k1.la
musig_example_LDFLAGS = -static
if BUILD_WINDOWS
musig_example_LDFLAGS += -lbcrypt
endif
TESTS += musig_example
endif
endif
### Precomputed tables
EXTRA_PROGRAMS = precompute_ecmult precompute_ecmult_gen
CLEANFILES = $(EXTRA_PROGRAMS)
precompute_ecmult_SOURCES = src/precompute_ecmult.c
precompute_ecmult_CPPFLAGS = $(SECP_CONFIG_DEFINES) -DVERIFY
precompute_ecmult_LDADD = $(COMMON_LIB)
precompute_ecmult_gen_SOURCES = src/precompute_ecmult_gen.c
precompute_ecmult_gen_CPPFLAGS = $(SECP_CONFIG_DEFINES) -DVERIFY
precompute_ecmult_gen_LDADD = $(COMMON_LIB)
# See Automake manual, Section "Errors with distclean".
# We don't list any dependencies for the prebuilt files here because
# otherwise make's decision whether to rebuild them (even in the first
# build by a normal user) depends on mtimes, and thus is very fragile.
# This means that rebuilds of the prebuilt files always need to be
# forced by deleting them.
src/precomputed_ecmult.c:
$(MAKE) $(AM_MAKEFLAGS) precompute_ecmult$(EXEEXT)
./precompute_ecmult$(EXEEXT)
src/precomputed_ecmult_gen.c:
$(MAKE) $(AM_MAKEFLAGS) precompute_ecmult_gen$(EXEEXT)
./precompute_ecmult_gen$(EXEEXT)
PRECOMP = src/precomputed_ecmult_gen.c src/precomputed_ecmult.c
precomp: $(PRECOMP)
# Ensure the prebuilt files will be build first (only if they don't exist,
# e.g., after `make maintainer-clean`).
BUILT_SOURCES = $(PRECOMP)
.PHONY: clean-precomp
clean-precomp:
rm -f $(PRECOMP)
maintainer-clean-local: clean-precomp
### Pregenerated test vectors
### (see the comments in the previous section for detailed rationale)
TESTVECTORS = src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h
src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h:
mkdir -p $(@D)
python3 $(top_srcdir)/tools/tests_wycheproof_generate.py $(top_srcdir)/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json > $@
testvectors: $(TESTVECTORS)
BUILT_SOURCES += $(TESTVECTORS)
.PHONY: clean-testvectors
clean-testvectors:
rm -f $(TESTVECTORS)
maintainer-clean-local: clean-testvectors
### Additional files to distribute
EXTRA_DIST = autogen.sh CHANGELOG.md SECURITY.md
EXTRA_DIST += doc/release-process.md doc/safegcd_implementation.md
EXTRA_DIST += doc/ellswift.md doc/musig.md
EXTRA_DIST += examples/EXAMPLES_COPYING
EXTRA_DIST += sage/gen_exhaustive_groups.sage
EXTRA_DIST += sage/gen_split_lambda_constants.sage
EXTRA_DIST += sage/group_prover.sage
EXTRA_DIST += sage/prove_group_implementations.sage
EXTRA_DIST += sage/secp256k1_params.sage
EXTRA_DIST += sage/weierstrass_prover.sage
EXTRA_DIST += src/wycheproof/WYCHEPROOF_COPYING
EXTRA_DIST += src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json
EXTRA_DIST += tools/tests_wycheproof_generate.py
if ENABLE_MODULE_ECDH
include src/modules/ecdh/Makefile.am.include
endif
if ENABLE_MODULE_RECOVERY
include src/modules/recovery/Makefile.am.include
endif
if ENABLE_MODULE_EXTRAKEYS
include src/modules/extrakeys/Makefile.am.include
endif
if ENABLE_MODULE_SCHNORRSIG
include src/modules/schnorrsig/Makefile.am.include
endif
if ENABLE_MODULE_MUSIG
include src/modules/musig/Makefile.am.include
endif
if ENABLE_MODULE_ELLSWIFT
include src/modules/ellswift/Makefile.am.include
endif

View File

@@ -1,142 +0,0 @@
libsecp256k1
============
![Dependencies: None](https://img.shields.io/badge/dependencies-none-success)
[![irc.libera.chat #secp256k1](https://img.shields.io/badge/irc.libera.chat-%23secp256k1-success)](https://web.libera.chat/#secp256k1)
High-performance high-assurance C library for digital signatures and other cryptographic primitives on the secp256k1 elliptic curve.
This library is intended to be the highest quality publicly available library for cryptography on the secp256k1 curve. However, the primary focus of its development has been for usage in the Bitcoin system and usage unlike Bitcoin's may be less well tested, verified, or suffer from a less well thought out interface. Correct usage requires some care and consideration that the library is fit for your application's purpose.
Features:
* secp256k1 ECDSA signing/verification and key generation.
* Additive and multiplicative tweaking of secret/public keys.
* Serialization/parsing of secret keys, public keys, signatures.
* Constant time, constant memory access signing and public key generation.
* Derandomized ECDSA (via RFC6979 or with a caller provided function.)
* Very efficient implementation.
* Suitable for embedded systems.
* No runtime dependencies.
* Optional module for public key recovery.
* Optional module for ECDH key exchange.
* Optional module for Schnorr signatures according to [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki).
* Optional module for ElligatorSwift key exchange according to [BIP-324](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki).
* Optional module for MuSig2 Schnorr multi-signatures according to [BIP-327](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki).
Implementation details
----------------------
* General
* No runtime heap allocation.
* Extensive testing infrastructure.
* Structured to facilitate review and analysis.
* Intended to be portable to any system with a C89 compiler and uint64_t support.
* No use of floating types.
* Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.")
* Field operations
* Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1).
* Using 5 52-bit limbs
* Using 10 26-bit limbs (including hand-optimized assembly for 32-bit ARM, by Wladimir J. van der Laan).
* This is an experimental feature that has not received enough scrutiny to satisfy the standard of quality of this library but is made available for testing and review by the community.
* Scalar operations
* Optimized implementation without data-dependent branches of arithmetic modulo the curve's order.
* Using 4 64-bit limbs (relying on __int128 support in the compiler).
* Using 8 32-bit limbs.
* Modular inverses (both field elements and scalars) based on [safegcd](https://gcd.cr.yp.to/index.html) with some modifications, and a variable-time variant (by Peter Dettman).
* Group operations
* Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7).
* Use addition between points in Jacobian and affine coordinates where possible.
* Use a unified addition/doubling formula where necessary to avoid data-dependent branches.
* Point/x comparison without a field inversion by comparison in the Jacobian coordinate space.
* Point multiplication for verification (a*P + b*G).
* Use wNAF notation for point multiplicands.
* Use a much larger window for multiples of G, using precomputed multiples.
* Use Shamir's trick to do the multiplication with the public key and the generator simultaneously.
* Use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones.
* Point multiplication for signing
* Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions.
* Intended to be completely free of timing sidechannels for secret-key operations (on reasonable hardware/toolchains)
* Access the table with branch-free conditional moves so memory access is uniform.
* No data-dependent branches
* Optional runtime blinding which attempts to frustrate differential power analysis.
* The precomputed tables add and eventually subtract points for which no known scalar (secret key) is known, preventing even an attacker with control over the secret key used to control the data internally.
Building with Autotools
-----------------------
$ ./autogen.sh
$ ./configure
$ make
$ make check # run the test suite
$ sudo make install # optional
To compile optional modules (such as Schnorr signatures), you need to run `./configure` with additional flags (such as `--enable-module-schnorrsig`). Run `./configure --help` to see the full list of available flags.
Building with CMake (experimental)
----------------------------------
To maintain a pristine source tree, CMake encourages to perform an out-of-source build by using a separate dedicated build tree.
### Building on POSIX systems
$ mkdir build && cd build
$ cmake ..
$ cmake --build .
$ ctest # run the test suite
$ sudo cmake --install . # optional
To compile optional modules (such as Schnorr signatures), you need to run `cmake` with additional flags (such as `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG=ON`). Run `cmake .. -LH` to see the full list of available flags.
### Cross compiling
To alleviate issues with cross compiling, preconfigured toolchain files are available in the `cmake` directory.
For example, to cross compile for Windows:
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/x86_64-w64-mingw32.toolchain.cmake
To cross compile for Android with [NDK](https://developer.android.com/ndk/guides/cmake) (using NDK's toolchain file, and assuming the `ANDROID_NDK_ROOT` environment variable has been set):
$ cmake .. -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake" -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=28
### Building on Windows
To build on Windows with Visual Studio, a proper [generator](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators) must be specified for a new build tree.
The following example assumes using of Visual Studio 2022 and CMake v3.21+.
In "Developer Command Prompt for VS 2022":
>cmake -G "Visual Studio 17 2022" -A x64 -S . -B build
>cmake --build build --config RelWithDebInfo
Usage examples
-----------
Usage examples can be found in the [examples](examples) directory. To compile them you need to configure with `--enable-examples`.
* [ECDSA example](examples/ecdsa.c)
* [Schnorr signatures example](examples/schnorr.c)
* [Deriving a shared secret (ECDH) example](examples/ecdh.c)
* [ElligatorSwift key exchange example](examples/ellswift.c)
To compile the Schnorr signature and ECDH examples, you also need to configure with `--enable-module-schnorrsig` and `--enable-module-ecdh`.
Benchmark
------------
If configured with `--enable-benchmark` (which is the default), binaries for benchmarking the libsecp256k1 functions will be present in the root directory after the build.
To print the benchmark result to the command line:
$ ./bench_name
To create a CSV file for the benchmark result :
$ ./bench_name | sed '2d;s/ \{1,\}//g' > bench_name.csv
Reporting a vulnerability
------------
See [SECURITY.md](SECURITY.md)
Contributing to libsecp256k1
------------
See [CONTRIBUTING.md](CONTRIBUTING.md)

View File

@@ -1,15 +0,0 @@
# Security Policy
## Reporting a Vulnerability
To report security issues send an email to secp256k1-security@bitcoincore.org (not for support).
The following keys may be used to communicate sensitive information to developers:
| Name | Fingerprint |
|------|-------------|
| Pieter Wuille | 133E AC17 9436 F14A 5CF1 B794 860F EB80 4E66 9320 |
| Jonas Nick | 36C7 1A37 C9D9 88BD E825 08D9 B1A7 0E4F 8DCD 0366 |
| Tim Ruffing | 09E0 3F87 1092 E40E 106E 902B 33BC 86AB 80FF 5516 |
You can import a key by running the following command with that individuals fingerprint: `gpg --keyserver hkps://keys.openpgp.org --recv-keys "<fingerprint>"` Ensure that you put quotes around fingerprints containing spaces.

View File

@@ -1,3 +0,0 @@
#!/bin/sh
set -e
autoreconf -if --warnings=all

View File

@@ -1,91 +0,0 @@
dnl escape "$0x" below using the m4 quadrigaph @S|@, and escape it again with a \ for the shell.
AC_DEFUN([SECP_X86_64_ASM_CHECK],[
AC_MSG_CHECKING(for x86_64 assembly availability)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <stdint.h>]],[[
uint64_t a = 11, tmp;
__asm__ __volatile__("movq \@S|@0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx");
]])], [has_x86_64_asm=yes], [has_x86_64_asm=no])
AC_MSG_RESULT([$has_x86_64_asm])
])
AC_DEFUN([SECP_ARM32_ASM_CHECK], [
AC_MSG_CHECKING(for ARM32 assembly availability)
SECP_ARM32_ASM_CHECK_CFLAGS_saved_CFLAGS="$CFLAGS"
CFLAGS="-x assembler"
AC_LINK_IFELSE([AC_LANG_SOURCE([[
.syntax unified
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.text
.global main
main:
ldr r0, =0x002A
mov r7, #1
swi 0
]])], [has_arm32_asm=yes], [has_arm32_asm=no])
AC_MSG_RESULT([$has_arm32_asm])
CFLAGS="$SECP_ARM32_ASM_CHECK_CFLAGS_saved_CFLAGS"
])
AC_DEFUN([SECP_VALGRIND_CHECK],[
AC_MSG_CHECKING([for valgrind support])
if test x"$has_valgrind" != x"yes"; then
CPPFLAGS_TEMP="$CPPFLAGS"
CPPFLAGS="$VALGRIND_CPPFLAGS $CPPFLAGS"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <valgrind/memcheck.h>
]], [[
#if defined(NVALGRIND)
# error "Valgrind does not support this platform."
#endif
]])], [has_valgrind=yes])
CPPFLAGS="$CPPFLAGS_TEMP"
fi
AC_MSG_RESULT($has_valgrind)
])
AC_DEFUN([SECP_MSAN_CHECK], [
AC_MSG_CHECKING(whether MemorySanitizer is enabled)
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#if defined(__has_feature)
# if __has_feature(memory_sanitizer)
/* MemorySanitizer is enabled. */
# elif
# error "MemorySanitizer is disabled."
# endif
#else
# error "__has_feature is not defined."
#endif
]])], [msan_enabled=yes], [msan_enabled=no])
AC_MSG_RESULT([$msan_enabled])
])
dnl SECP_TRY_APPEND_CFLAGS(flags, VAR)
dnl Append flags to VAR if CC accepts them.
AC_DEFUN([SECP_TRY_APPEND_CFLAGS], [
AC_MSG_CHECKING([if ${CC} supports $1])
SECP_TRY_APPEND_CFLAGS_saved_CFLAGS="$CFLAGS"
CFLAGS="$1 $CFLAGS"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], [flag_works=yes], [flag_works=no])
AC_MSG_RESULT($flag_works)
CFLAGS="$SECP_TRY_APPEND_CFLAGS_saved_CFLAGS"
if test x"$flag_works" = x"yes"; then
$2="$$2 $1"
fi
unset flag_works
AC_SUBST($2)
])
dnl SECP_SET_DEFAULT(VAR, default, default-dev-mode)
dnl Set VAR to default or default-dev-mode, depending on whether dev mode is enabled
AC_DEFUN([SECP_SET_DEFAULT], [
if test "${enable_dev_mode+set}" != set; then
AC_MSG_ERROR([[Set enable_dev_mode before calling SECP_SET_DEFAULT]])
fi
if test x"$enable_dev_mode" = x"yes"; then
$1="$3"
else
$1="$2"
fi
])

View File

@@ -1,149 +0,0 @@
#!/bin/sh
set -eux
export LC_ALL=C
# Print commit and relevant CI environment to allow reproducing the job outside of CI.
git show --no-patch
print_environment() {
# Turn off -x because it messes up the output
set +x
# There are many ways to print variable names and their content. This one
# does not rely on bash.
for var in WERROR_CFLAGS MAKEFLAGS BUILD \
ECMULTWINDOW ECMULTGENKB ASM WIDEMUL WITH_VALGRIND EXTRAFLAGS \
EXPERIMENTAL ECDH RECOVERY EXTRAKEYS MUSIG SCHNORRSIG ELLSWIFT \
SECP256K1_TEST_ITERS BENCH SECP256K1_BENCH_ITERS CTIMETESTS\
EXAMPLES \
HOST WRAPPER_CMD \
CC CFLAGS CPPFLAGS AR NM \
UBSAN_OPTIONS ASAN_OPTIONS LSAN_OPTIONS
do
eval "isset=\${$var+x}"
if [ -n "$isset" ]; then
eval "val=\${$var}"
# shellcheck disable=SC2154
printf '%s="%s" ' "$var" "$val"
fi
done
echo "$0"
set -x
}
print_environment
env >> test_env.log
# If gcc is requested, assert that it's in fact gcc (and not some symlinked Apple clang).
case "${CC:-undefined}" in
*gcc*)
$CC -v 2>&1 | grep -q "gcc version" || exit 1;
;;
esac
if [ -n "${CC+x}" ]; then
# The MSVC compiler "cl" doesn't understand "-v"
$CC -v || true
fi
if [ "$WITH_VALGRIND" = "yes" ]; then
valgrind --version
fi
if [ -n "$WRAPPER_CMD" ]; then
$WRAPPER_CMD --version
fi
# Workaround for https://bugs.kde.org/show_bug.cgi?id=452758 (fixed in valgrind 3.20.0).
case "${CC:-undefined}" in
clang*)
if [ "$CTIMETESTS" = "yes" ] && [ "$WITH_VALGRIND" = "yes" ]
then
export CFLAGS="${CFLAGS:+$CFLAGS }-gdwarf-4"
else
case "$WRAPPER_CMD" in
valgrind*)
export CFLAGS="${CFLAGS:+$CFLAGS }-gdwarf-4"
;;
esac
fi
;;
esac
./autogen.sh
./configure \
--enable-experimental="$EXPERIMENTAL" \
--with-test-override-wide-multiply="$WIDEMUL" --with-asm="$ASM" \
--with-ecmult-window="$ECMULTWINDOW" \
--with-ecmult-gen-kb="$ECMULTGENKB" \
--enable-module-ecdh="$ECDH" --enable-module-recovery="$RECOVERY" \
--enable-module-ellswift="$ELLSWIFT" \
--enable-module-extrakeys="$EXTRAKEYS" \
--enable-module-schnorrsig="$SCHNORRSIG" \
--enable-module-musig="$MUSIG" \
--enable-examples="$EXAMPLES" \
--enable-ctime-tests="$CTIMETESTS" \
--with-valgrind="$WITH_VALGRIND" \
--host="$HOST" $EXTRAFLAGS
# We have set "-j<n>" in MAKEFLAGS.
build_exit_code=0
make > make.log 2>&1 || build_exit_code=$?
cat make.log
if [ $build_exit_code -ne 0 ]; then
case "${CC:-undefined}" in
*snapshot*)
# Ignore internal compiler errors in gcc-snapshot and clang-snapshot
grep -e "internal compiler error:" -e "PLEASE submit a bug report" make.log
return $?;
;;
*)
return 1;
;;
esac
fi
# Print information about binaries so that we can see that the architecture is correct
file *tests* || true
file bench* || true
file .libs/* || true
# This tells `make check` to wrap test invocations.
export LOG_COMPILER="$WRAPPER_CMD"
make "$BUILD"
# Using the local `libtool` because on macOS the system's libtool has nothing to do with GNU libtool
EXEC='./libtool --mode=execute'
if [ -n "$WRAPPER_CMD" ]
then
EXEC="$EXEC $WRAPPER_CMD"
fi
if [ "$BENCH" = "yes" ]
then
{
$EXEC ./bench_ecmult
$EXEC ./bench_internal
$EXEC ./bench
} >> bench.log 2>&1
fi
if [ "$CTIMETESTS" = "yes" ]
then
if [ "$WITH_VALGRIND" = "yes" ]; then
./libtool --mode=execute valgrind --error-exitcode=42 ./ctime_tests > ctime_tests.log 2>&1
else
$EXEC ./ctime_tests > ctime_tests.log 2>&1
fi
fi
# Rebuild precomputed files (if not cross-compiling).
if [ -z "$HOST" ]
then
make clean-precomp clean-testvectors
make precomp testvectors
fi
# Check that no repo files have been modified by the build.
# (This fails for example if the precomp files need to be updated in the repo.)
git diff --exit-code

View File

@@ -1,79 +0,0 @@
FROM debian:stable-slim
SHELL ["/bin/bash", "-c"]
WORKDIR /root
# A too high maximum number of file descriptors (with the default value
# inherited from the docker host) can cause issues with some of our tools:
# - sanitizers hanging: https://github.com/google/sanitizers/issues/1662
# - valgrind crashing: https://stackoverflow.com/a/75293014
# This is not be a problem on our CI hosts, but developers who run the image
# on their machines may run into this (e.g., on Arch Linux), so warn them.
# (Note that .bashrc is only executed in interactive bash shells.)
RUN echo 'if [[ $(ulimit -n) -gt 200000 ]]; then echo "WARNING: Very high value reported by \"ulimit -n\". Consider passing \"--ulimit nofile=32768\" to \"docker run\"."; fi' >> /root/.bashrc
RUN dpkg --add-architecture i386 && \
dpkg --add-architecture s390x && \
dpkg --add-architecture armhf && \
dpkg --add-architecture arm64 && \
dpkg --add-architecture ppc64el
# dkpg-dev: to make pkg-config work in cross-builds
# llvm: for llvm-symbolizer, which is used by clang's UBSan for symbolized stack traces
RUN apt-get update && apt-get install --no-install-recommends -y \
git ca-certificates \
make automake libtool pkg-config dpkg-dev valgrind qemu-user \
gcc clang llvm libclang-rt-dev libc6-dbg \
g++ \
gcc-i686-linux-gnu libc6-dev-i386-cross libc6-dbg:i386 libubsan1:i386 libasan8:i386 \
gcc-s390x-linux-gnu libc6-dev-s390x-cross libc6-dbg:s390x \
gcc-arm-linux-gnueabihf libc6-dev-armhf-cross libc6-dbg:armhf \
gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross libc6-dbg:ppc64el \
gcc-mingw-w64-x86-64-win32 wine64 wine \
gcc-mingw-w64-i686-win32 wine32 \
python3 && \
if ! ( dpkg --print-architecture | grep --quiet "arm64" ) ; then \
apt-get install --no-install-recommends -y \
gcc-aarch64-linux-gnu libc6-dev-arm64-cross libc6-dbg:arm64 ;\
fi && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# Build and install gcc snapshot
ARG GCC_SNAPSHOT_MAJOR=15
RUN apt-get update && apt-get install --no-install-recommends -y wget libgmp-dev libmpfr-dev libmpc-dev flex && \
mkdir gcc && cd gcc && \
wget --progress=dot:giga --https-only --recursive --accept '*.tar.xz' --level 1 --no-directories "https://gcc.gnu.org/pub/gcc/snapshots/LATEST-${GCC_SNAPSHOT_MAJOR}" && \
wget "https://gcc.gnu.org/pub/gcc/snapshots/LATEST-${GCC_SNAPSHOT_MAJOR}/sha512.sum" && \
sha512sum --check --ignore-missing sha512.sum && \
# We should have downloaded exactly one tar.xz file
ls && \
[ $(ls *.tar.xz | wc -l) -eq "1" ] && \
tar xf *.tar.xz && \
mkdir gcc-build && cd gcc-build && \
../*/configure --prefix=/opt/gcc-snapshot --enable-languages=c --disable-bootstrap --disable-multilib --without-isl && \
make -j $(nproc) && \
make install && \
cd ../.. && rm -rf gcc && \
ln -s /opt/gcc-snapshot/bin/gcc /usr/bin/gcc-snapshot && \
apt-get autoremove -y wget libgmp-dev libmpfr-dev libmpc-dev flex && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# Install clang snapshot, see https://apt.llvm.org/
RUN \
# Setup GPG keys of LLVM repository
apt-get update && apt-get install --no-install-recommends -y wget && \
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc && \
# Add repository for this Debian release
. /etc/os-release && echo "deb http://apt.llvm.org/${VERSION_CODENAME} llvm-toolchain-${VERSION_CODENAME} main" >> /etc/apt/sources.list && \
apt-get update && \
# Determine the version number of the LLVM development branch
LLVM_VERSION=$(apt-cache search --names-only '^clang-[0-9]+$' | sort -V | tail -1 | cut -f1 -d" " | cut -f2 -d"-" ) && \
# Install
apt-get install --no-install-recommends -y "clang-${LLVM_VERSION}" && \
# Create symlink
ln -s "/usr/bin/clang-${LLVM_VERSION}" /usr/bin/clang-snapshot && \
# Clean up
apt-get autoremove -y wget && \
apt-get clean && rm -rf /var/lib/apt/lists/*

View File

@@ -1,6 +0,0 @@
function(check_arm32_assembly)
try_compile(HAVE_ARM32_ASM
${PROJECT_BINARY_DIR}/check_arm32_assembly
SOURCES ${PROJECT_SOURCE_DIR}/cmake/source_arm32.s
)
endfunction()

View File

@@ -1,18 +0,0 @@
include_guard(GLOBAL)
include(CheckCSourceCompiles)
function(check_memory_sanitizer output)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
check_c_source_compiles("
#if defined(__has_feature)
# if __has_feature(memory_sanitizer)
/* MemorySanitizer is enabled. */
# elif
# error \"MemorySanitizer is disabled.\"
# endif
#else
# error \"__has_feature is not defined.\"
#endif
" HAVE_MSAN)
set(${output} ${HAVE_MSAN} PARENT_SCOPE)
endfunction()

View File

@@ -1,10 +0,0 @@
function(check_string_option_value option)
get_property(expected_values CACHE ${option} PROPERTY STRINGS)
if(expected_values)
if(${option} IN_LIST expected_values)
return()
endif()
message(FATAL_ERROR "${option} value is \"${${option}}\", but must be one of ${expected_values}.")
endif()
message(AUTHOR_WARNING "The STRINGS property must be set before invoking `check_string_option_value' function.")
endfunction()

View File

@@ -1,14 +0,0 @@
include(CheckCSourceCompiles)
function(check_x86_64_assembly)
check_c_source_compiles("
#include <stdint.h>
int main()
{
uint64_t a = 11, tmp;
__asm__ __volatile__(\"movq $0x100000000,%1; mulq %%rsi\" : \"+a\"(a) : \"S\"(tmp) : \"cc\", \"%rdx\");
}
" HAVE_X86_64_ASM)
set(HAVE_X86_64_ASM ${HAVE_X86_64_ASM} PARENT_SCOPE)
endfunction()

View File

@@ -1,41 +0,0 @@
if(CMAKE_HOST_APPLE)
find_program(BREW_COMMAND brew)
execute_process(
COMMAND ${BREW_COMMAND} --prefix valgrind
OUTPUT_VARIABLE valgrind_brew_prefix
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
set(hints_paths)
if(valgrind_brew_prefix)
set(hints_paths ${valgrind_brew_prefix}/include)
endif()
find_path(Valgrind_INCLUDE_DIR
NAMES valgrind/memcheck.h
HINTS ${hints_paths}
)
if(Valgrind_INCLUDE_DIR)
include(CheckCSourceCompiles)
set(CMAKE_REQUIRED_INCLUDES ${Valgrind_INCLUDE_DIR})
check_c_source_compiles("
#include <valgrind/memcheck.h>
#if defined(NVALGRIND)
# error \"Valgrind does not support this platform.\"
#endif
int main() {}
" Valgrind_WORKS)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Valgrind
REQUIRED_VARS Valgrind_INCLUDE_DIR Valgrind_WORKS
)
mark_as_advanced(
Valgrind_INCLUDE_DIR
)

View File

@@ -1,8 +0,0 @@
function(generate_pkg_config_file in_file)
set(prefix ${CMAKE_INSTALL_PREFIX})
set(exec_prefix \${prefix})
set(libdir \${exec_prefix}/${CMAKE_INSTALL_LIBDIR})
set(includedir \${prefix}/${CMAKE_INSTALL_INCLUDEDIR})
set(PACKAGE_VERSION ${PROJECT_VERSION})
configure_file(${in_file} ${PROJECT_NAME}.pc @ONLY)
endfunction()

View File

@@ -1,24 +0,0 @@
include(CheckCCompilerFlag)
function(secp256k1_check_c_flags_internal flags output)
string(MAKE_C_IDENTIFIER "${flags}" result)
string(TOUPPER "${result}" result)
set(result "C_SUPPORTS_${result}")
if(NOT MSVC)
set(CMAKE_REQUIRED_FLAGS "-Werror")
endif()
# This avoids running a linker.
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
check_c_compiler_flag("${flags}" ${result})
set(${output} ${${result}} PARENT_SCOPE)
endfunction()
# Append flags to the COMPILE_OPTIONS directory property if CC accepts them.
macro(try_append_c_flags)
secp256k1_check_c_flags_internal("${ARGV}" result)
if(result)
add_compile_options(${ARGV})
endif()
endmacro()

View File

@@ -1,3 +0,0 @@
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)

View File

@@ -1,5 +0,0 @@
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake")
check_required_components(@PROJECT_NAME@)

View File

@@ -1,9 +0,0 @@
.syntax unified
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.text
.global main
main:
ldr r0, =0x002A
mov r7, #1
swi 0

View File

@@ -1,3 +0,0 @@
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)

View File

@@ -1,517 +0,0 @@
AC_PREREQ([2.60])
# The package (a.k.a. release) version is based on semantic versioning 2.0.0 of
# the API. All changes in experimental modules are treated as
# backwards-compatible and therefore at most increase the minor version.
define(_PKG_VERSION_MAJOR, 0)
define(_PKG_VERSION_MINOR, 6)
define(_PKG_VERSION_PATCH, 0)
define(_PKG_VERSION_IS_RELEASE, true)
# The library version is based on libtool versioning of the ABI. The set of
# rules for updating the version can be found here:
# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
# All changes in experimental modules are treated as if they don't affect the
# interface and therefore only increase the revision.
define(_LIB_VERSION_CURRENT, 5)
define(_LIB_VERSION_REVISION, 0)
define(_LIB_VERSION_AGE, 0)
AC_INIT([libsecp256k1],m4_join([.], _PKG_VERSION_MAJOR, _PKG_VERSION_MINOR, _PKG_VERSION_PATCH)m4_if(_PKG_VERSION_IS_RELEASE, [true], [], [-dev]),[https://github.com/bitcoin-core/secp256k1/issues],[libsecp256k1],[https://github.com/bitcoin-core/secp256k1])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([build-aux/m4])
AC_CANONICAL_HOST
# Require Automake 1.11.2 for AM_PROG_AR
AM_INIT_AUTOMAKE([1.11.2 foreign subdir-objects])
# Make the compilation flags quiet unless V=1 is used.
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
if test "${CFLAGS+set}" = "set"; then
CFLAGS_overridden=yes
else
CFLAGS_overridden=no
fi
AC_PROG_CC
AM_PROG_AS
AM_PROG_AR
# Clear some cache variables as a workaround for a bug that appears due to a bad
# interaction between AM_PROG_AR and LT_INIT when combining MSVC's archiver lib.exe.
# https://debbugs.gnu.org/cgi/bugreport.cgi?bug=54421
AS_UNSET(ac_cv_prog_AR)
AS_UNSET(ac_cv_prog_ac_ct_AR)
LT_INIT([win32-dll])
build_windows=no
case $host_os in
*darwin*)
if test x$cross_compiling != xyes; then
AC_CHECK_PROG([BREW], brew, brew)
if test x$BREW = xbrew; then
# These Homebrew packages may be keg-only, meaning that they won't be found
# in expected paths because they may conflict with system files. Ask
# Homebrew where each one is located, then adjust paths accordingly.
if $BREW list --versions valgrind >/dev/null; then
valgrind_prefix=$($BREW --prefix valgrind 2>/dev/null)
VALGRIND_CPPFLAGS="-I$valgrind_prefix/include"
fi
else
AC_CHECK_PROG([PORT], port, port)
# If homebrew isn't installed and macports is, add the macports default paths
# as a last resort.
if test x$PORT = xport; then
CPPFLAGS="$CPPFLAGS -isystem /opt/local/include"
LDFLAGS="$LDFLAGS -L/opt/local/lib"
fi
fi
fi
;;
cygwin*|mingw*)
build_windows=yes
;;
esac
# Try if some desirable compiler flags are supported and append them to SECP_CFLAGS.
#
# These are our own flags, so we append them to our own SECP_CFLAGS variable (instead of CFLAGS) as
# recommended in the automake manual (Section "Flag Variables Ordering"). CFLAGS belongs to the user
# and we are not supposed to touch it. In the Makefile, we will need to ensure that SECP_CFLAGS
# is prepended to CFLAGS when invoking the compiler so that the user always has the last word (flag).
#
# Another advantage of not touching CFLAGS is that the contents of CFLAGS will be picked up by
# libtool for compiling helper executables. For example, when compiling for Windows, libtool will
# generate entire wrapper executables (instead of simple wrapper scripts as on Unix) to ensure
# proper operation of uninstalled programs linked by libtool against the uninstalled shared library.
# These executables are compiled from C source file for which our flags may not be appropriate,
# e.g., -std=c89 flag has lead to undesirable warnings in the past.
#
# TODO We should analogously not touch CPPFLAGS and LDFLAGS but currently there are no issues.
AC_DEFUN([SECP_TRY_APPEND_DEFAULT_CFLAGS], [
# GCC and compatible (incl. clang)
if test "x$GCC" = "xyes"; then
# Try to append -Werror to CFLAGS temporarily. Otherwise checks for some unsupported
# flags will succeed.
# Note that failure to append -Werror does not necessarily mean that -Werror is not
# supported. The compiler may already be warning about something unrelated, for example
# about some path issue. If that is the case, -Werror cannot be used because all
# of those warnings would be turned into errors.
SECP_TRY_APPEND_DEFAULT_CFLAGS_saved_CFLAGS="$CFLAGS"
SECP_TRY_APPEND_CFLAGS([-Werror], CFLAGS)
SECP_TRY_APPEND_CFLAGS([-std=c89 -pedantic -Wno-long-long -Wnested-externs -Wshadow -Wstrict-prototypes -Wundef], $1) # GCC >= 3.0, -Wlong-long is implied by -pedantic.
SECP_TRY_APPEND_CFLAGS([-Wno-overlength-strings], $1) # GCC >= 4.2, -Woverlength-strings is implied by -pedantic.
SECP_TRY_APPEND_CFLAGS([-Wall], $1) # GCC >= 2.95 and probably many other compilers
SECP_TRY_APPEND_CFLAGS([-Wno-unused-function], $1) # GCC >= 3.0, -Wunused-function is implied by -Wall.
SECP_TRY_APPEND_CFLAGS([-Wextra], $1) # GCC >= 3.4, this is the newer name of -W, which we don't use because older GCCs will warn about unused functions.
SECP_TRY_APPEND_CFLAGS([-Wcast-align], $1) # GCC >= 2.95
SECP_TRY_APPEND_CFLAGS([-Wcast-align=strict], $1) # GCC >= 8.0
SECP_TRY_APPEND_CFLAGS([-Wconditional-uninitialized], $1) # Clang >= 3.0 only
SECP_TRY_APPEND_CFLAGS([-Wreserved-identifier], $1) # Clang >= 13.0 only
SECP_TRY_APPEND_CFLAGS([-fvisibility=hidden], $1) # GCC >= 4.0
CFLAGS="$SECP_TRY_APPEND_DEFAULT_CFLAGS_saved_CFLAGS"
fi
# MSVC
# Assume MSVC if we're building for Windows but not with GCC or compatible;
# libtool makes the same assumption internally.
# Note that "/opt" and "-opt" are equivalent for MSVC; we use "-opt" because "/opt" looks like a path.
if test x"$GCC" != x"yes" && test x"$build_windows" = x"yes"; then
SECP_TRY_APPEND_CFLAGS([-W3], $1) # Production quality warning level.
SECP_TRY_APPEND_CFLAGS([-wd4146], $1) # Disable warning C4146 "unary minus operator applied to unsigned type, result still unsigned".
SECP_TRY_APPEND_CFLAGS([-wd4244], $1) # Disable warning C4244 "'conversion' conversion from 'type1' to 'type2', possible loss of data".
SECP_TRY_APPEND_CFLAGS([-wd4267], $1) # Disable warning C4267 "'var' : conversion from 'size_t' to 'type', possible loss of data".
# Eliminate deprecation warnings for the older, less secure functions.
CPPFLAGS="-D_CRT_SECURE_NO_WARNINGS $CPPFLAGS"
fi
])
SECP_TRY_APPEND_DEFAULT_CFLAGS(SECP_CFLAGS)
###
### Define config arguments
###
# In dev mode, we enable all binaries and modules by default but individual options can still be overridden explicitly.
# Check for dev mode first because SECP_SET_DEFAULT needs enable_dev_mode set.
AC_ARG_ENABLE(dev_mode, [], [],
[enable_dev_mode=no])
AC_ARG_ENABLE(benchmark,
AS_HELP_STRING([--enable-benchmark],[compile benchmark [default=yes]]), [],
[SECP_SET_DEFAULT([enable_benchmark], [yes], [yes])])
AC_ARG_ENABLE(coverage,
AS_HELP_STRING([--enable-coverage],[enable compiler flags to support kcov coverage analysis [default=no]]), [],
[SECP_SET_DEFAULT([enable_coverage], [no], [no])])
AC_ARG_ENABLE(tests,
AS_HELP_STRING([--enable-tests],[compile tests [default=yes]]), [],
[SECP_SET_DEFAULT([enable_tests], [yes], [yes])])
AC_ARG_ENABLE(ctime_tests,
AS_HELP_STRING([--enable-ctime-tests],[compile constant-time tests [default=yes if valgrind enabled]]), [],
[SECP_SET_DEFAULT([enable_ctime_tests], [auto], [auto])])
AC_ARG_ENABLE(experimental,
AS_HELP_STRING([--enable-experimental],[allow experimental configure options [default=no]]), [],
[SECP_SET_DEFAULT([enable_experimental], [no], [yes])])
AC_ARG_ENABLE(exhaustive_tests,
AS_HELP_STRING([--enable-exhaustive-tests],[compile exhaustive tests [default=yes]]), [],
[SECP_SET_DEFAULT([enable_exhaustive_tests], [yes], [yes])])
AC_ARG_ENABLE(examples,
AS_HELP_STRING([--enable-examples],[compile the examples [default=no]]), [],
[SECP_SET_DEFAULT([enable_examples], [no], [yes])])
AC_ARG_ENABLE(module_ecdh,
AS_HELP_STRING([--enable-module-ecdh],[enable ECDH module [default=yes]]), [],
[SECP_SET_DEFAULT([enable_module_ecdh], [yes], [yes])])
AC_ARG_ENABLE(module_recovery,
AS_HELP_STRING([--enable-module-recovery],[enable ECDSA pubkey recovery module [default=no]]), [],
[SECP_SET_DEFAULT([enable_module_recovery], [no], [yes])])
AC_ARG_ENABLE(module_extrakeys,
AS_HELP_STRING([--enable-module-extrakeys],[enable extrakeys module [default=yes]]), [],
[SECP_SET_DEFAULT([enable_module_extrakeys], [yes], [yes])])
AC_ARG_ENABLE(module_schnorrsig,
AS_HELP_STRING([--enable-module-schnorrsig],[enable schnorrsig module [default=yes]]), [],
[SECP_SET_DEFAULT([enable_module_schnorrsig], [yes], [yes])])
AC_ARG_ENABLE(module_musig,
AS_HELP_STRING([--enable-module-musig],[enable MuSig2 module [default=yes]]), [],
[SECP_SET_DEFAULT([enable_module_musig], [yes], [yes])])
AC_ARG_ENABLE(module_ellswift,
AS_HELP_STRING([--enable-module-ellswift],[enable ElligatorSwift module [default=yes]]), [],
[SECP_SET_DEFAULT([enable_module_ellswift], [yes], [yes])])
AC_ARG_ENABLE(external_default_callbacks,
AS_HELP_STRING([--enable-external-default-callbacks],[enable external default callback functions [default=no]]), [],
[SECP_SET_DEFAULT([enable_external_default_callbacks], [no], [no])])
# Test-only override of the (autodetected by the C code) "widemul" setting.
# Legal values are:
# * int64 (for [u]int64_t),
# * int128 (for [unsigned] __int128),
# * int128_struct (for int128 implemented as a structure),
# * and auto (the default).
AC_ARG_WITH([test-override-wide-multiply], [] ,[set_widemul=$withval], [set_widemul=auto])
AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|arm32|no|auto],
[assembly to use (experimental: arm32) [default=auto]])],[req_asm=$withval], [req_asm=auto])
AC_ARG_WITH([ecmult-window], [AS_HELP_STRING([--with-ecmult-window=SIZE],
[window size for ecmult precomputation for verification, specified as integer in range [2..24].]
[Larger values result in possibly better performance at the cost of an exponentially larger precomputed table.]
[The table will store 2^(SIZE-1) * 64 bytes of data but can be larger in memory due to platform-specific padding and alignment.]
[A window size larger than 15 will require you delete the prebuilt precomputed_ecmult.c file so that it can be rebuilt.]
[For very large window sizes, use "make -j 1" to reduce memory use during compilation.]
[The default value is a reasonable setting for desktop machines (currently 15). [default=15]]
)],
[set_ecmult_window=$withval], [set_ecmult_window=15])
AC_ARG_WITH([ecmult-gen-kb], [AS_HELP_STRING([--with-ecmult-gen-kb=2|22|86],
[The size of the precomputed table for signing in multiples of 1024 bytes (on typical platforms).]
[Larger values result in possibly better signing/keygeneration performance at the cost of a larger table.]
[The default value is a reasonable setting for desktop machines (currently 86). [default=86]]
)],
[set_ecmult_gen_kb=$withval], [set_ecmult_gen_kb=86])
AC_ARG_WITH([valgrind], [AS_HELP_STRING([--with-valgrind=yes|no|auto],
[Build with extra checks for running inside Valgrind [default=auto]]
)],
[req_valgrind=$withval], [req_valgrind=auto])
###
### Handle config options (except for modules)
###
if test x"$req_valgrind" = x"no"; then
enable_valgrind=no
else
SECP_VALGRIND_CHECK
if test x"$has_valgrind" != x"yes"; then
if test x"$req_valgrind" = x"yes"; then
AC_MSG_ERROR([Valgrind support explicitly requested but valgrind/memcheck.h header not available])
fi
enable_valgrind=no
else
enable_valgrind=yes
fi
fi
if test x"$enable_ctime_tests" = x"auto"; then
enable_ctime_tests=$enable_valgrind
fi
print_msan_notice=no
if test x"$enable_ctime_tests" = x"yes"; then
SECP_MSAN_CHECK
# MSan on Clang >=16 reports unitialized memory in function parameters and return values, even if
# the uninitalized variable is never actually "used". This is called "eager" checking, and it's
# sounds like good idea for normal use of MSan. However, it yields many false positives in the
# ctime_tests because many return values depend on secret (i.e., "uninitialized") values, and
# we're only interested in detecting branches (which count as "uses") on secret data.
if test x"$msan_enabled" = x"yes"; then
SECP_TRY_APPEND_CFLAGS([-fno-sanitize-memory-param-retval], SECP_CFLAGS)
print_msan_notice=yes
fi
fi
if test x"$enable_coverage" = x"yes"; then
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOVERAGE=1"
SECP_CFLAGS="-O0 --coverage $SECP_CFLAGS"
# If coverage is enabled, and the user has not overridden CFLAGS,
# override Autoconf's value "-g -O2" with "-g". Otherwise we'd end up
# with "-O0 --coverage -g -O2".
if test "$CFLAGS_overridden" = "no"; then
CFLAGS="-g"
fi
LDFLAGS="--coverage $LDFLAGS"
else
# Most likely the CFLAGS already contain -O2 because that is autoconf's default.
# We still add it here because passing it twice is not an issue, and handling
# this case would just add unnecessary complexity (see #896).
SECP_CFLAGS="-O2 $SECP_CFLAGS"
fi
if test x"$req_asm" = x"auto"; then
SECP_X86_64_ASM_CHECK
if test x"$has_x86_64_asm" = x"yes"; then
set_asm=x86_64
fi
if test x"$set_asm" = x; then
set_asm=no
fi
else
set_asm=$req_asm
case $set_asm in
x86_64)
SECP_X86_64_ASM_CHECK
if test x"$has_x86_64_asm" != x"yes"; then
AC_MSG_ERROR([x86_64 assembly requested but not available])
fi
;;
arm32)
SECP_ARM32_ASM_CHECK
if test x"$has_arm32_asm" != x"yes"; then
AC_MSG_ERROR([ARM32 assembly requested but not available])
fi
;;
no)
;;
*)
AC_MSG_ERROR([invalid assembly selection])
;;
esac
fi
# Select assembly
enable_external_asm=no
case $set_asm in
x86_64)
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_ASM_X86_64=1"
;;
arm32)
enable_external_asm=yes
;;
no)
;;
*)
AC_MSG_ERROR([invalid assembly selection])
;;
esac
if test x"$enable_external_asm" = x"yes"; then
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_EXTERNAL_ASM=1"
fi
# Select wide multiplication implementation
case $set_widemul in
int128_struct)
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_FORCE_WIDEMUL_INT128_STRUCT=1"
;;
int128)
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_FORCE_WIDEMUL_INT128=1"
;;
int64)
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_FORCE_WIDEMUL_INT64=1"
;;
auto)
;;
*)
AC_MSG_ERROR([invalid wide multiplication implementation])
;;
esac
error_window_size=['window size for ecmult precomputation not an integer in range [2..24]']
case $set_ecmult_window in
''|*[[!0-9]]*)
# no valid integer
AC_MSG_ERROR($error_window_size)
;;
*)
if test "$set_ecmult_window" -lt 2 -o "$set_ecmult_window" -gt 24 ; then
# not in range
AC_MSG_ERROR($error_window_size)
fi
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DECMULT_WINDOW_SIZE=$set_ecmult_window"
;;
esac
case $set_ecmult_gen_kb in
2)
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOMB_BLOCKS=2 -DCOMB_TEETH=5"
;;
22)
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOMB_BLOCKS=11 -DCOMB_TEETH=6"
;;
86)
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOMB_BLOCKS=43 -DCOMB_TEETH=6"
;;
*)
AC_MSG_ERROR(['ecmult gen table size not 2, 22 or 86'])
;;
esac
if test x"$enable_valgrind" = x"yes"; then
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES $VALGRIND_CPPFLAGS -DVALGRIND"
fi
# Add -Werror and similar flags passed from the outside (for testing, e.g., in CI).
# We don't want to set the user variable CFLAGS in CI because this would disable
# autoconf's logic for setting default CFLAGS, which we would like to test in CI.
SECP_CFLAGS="$SECP_CFLAGS $WERROR_CFLAGS"
###
### Handle module options
###
# Processing must be done in a reverse topological sorting of the dependency graph
# (dependent module first).
if test x"$enable_module_ellswift" = x"yes"; then
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_ELLSWIFT=1"
fi
if test x"$enable_module_musig" = x"yes"; then
if test x"$enable_module_schnorrsig" = x"no"; then
AC_MSG_ERROR([Module dependency error: You have disabled the schnorrsig module explicitly, but it is required by the musig module.])
fi
enable_module_schnorrsig=yes
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_MUSIG=1"
fi
if test x"$enable_module_schnorrsig" = x"yes"; then
if test x"$enable_module_extrakeys" = x"no"; then
AC_MSG_ERROR([Module dependency error: You have disabled the extrakeys module explicitly, but it is required by the schnorrsig module.])
fi
enable_module_extrakeys=yes
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_SCHNORRSIG=1"
fi
if test x"$enable_module_extrakeys" = x"yes"; then
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_EXTRAKEYS=1"
fi
if test x"$enable_module_recovery" = x"yes"; then
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_RECOVERY=1"
fi
if test x"$enable_module_ecdh" = x"yes"; then
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_ECDH=1"
fi
if test x"$enable_external_default_callbacks" = x"yes"; then
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_EXTERNAL_DEFAULT_CALLBACKS=1"
fi
###
### Check for --enable-experimental if necessary
###
if test x"$enable_experimental" = x"no"; then
if test x"$set_asm" = x"arm32"; then
AC_MSG_ERROR([ARM32 assembly is experimental. Use --enable-experimental to allow.])
fi
fi
###
### Generate output
###
AC_CONFIG_FILES([Makefile libsecp256k1.pc])
AC_SUBST(SECP_CFLAGS)
AC_SUBST(SECP_CONFIG_DEFINES)
AM_CONDITIONAL([ENABLE_COVERAGE], [test x"$enable_coverage" = x"yes"])
AM_CONDITIONAL([USE_TESTS], [test x"$enable_tests" != x"no"])
AM_CONDITIONAL([USE_CTIME_TESTS], [test x"$enable_ctime_tests" = x"yes"])
AM_CONDITIONAL([USE_EXHAUSTIVE_TESTS], [test x"$enable_exhaustive_tests" != x"no"])
AM_CONDITIONAL([USE_EXAMPLES], [test x"$enable_examples" != x"no"])
AM_CONDITIONAL([USE_BENCHMARK], [test x"$enable_benchmark" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_ECDH], [test x"$enable_module_ecdh" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_RECOVERY], [test x"$enable_module_recovery" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_EXTRAKEYS], [test x"$enable_module_extrakeys" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_SCHNORRSIG], [test x"$enable_module_schnorrsig" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_MUSIG], [test x"$enable_module_musig" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_ELLSWIFT], [test x"$enable_module_ellswift" = x"yes"])
AM_CONDITIONAL([USE_EXTERNAL_ASM], [test x"$enable_external_asm" = x"yes"])
AM_CONDITIONAL([USE_ASM_ARM], [test x"$set_asm" = x"arm32"])
AM_CONDITIONAL([BUILD_WINDOWS], [test "$build_windows" = "yes"])
AC_SUBST(LIB_VERSION_CURRENT, _LIB_VERSION_CURRENT)
AC_SUBST(LIB_VERSION_REVISION, _LIB_VERSION_REVISION)
AC_SUBST(LIB_VERSION_AGE, _LIB_VERSION_AGE)
AC_OUTPUT
echo
echo "Build Options:"
echo " with external callbacks = $enable_external_default_callbacks"
echo " with benchmarks = $enable_benchmark"
echo " with tests = $enable_tests"
echo " with ctime tests = $enable_ctime_tests"
echo " with coverage = $enable_coverage"
echo " with examples = $enable_examples"
echo " module ecdh = $enable_module_ecdh"
echo " module recovery = $enable_module_recovery"
echo " module extrakeys = $enable_module_extrakeys"
echo " module schnorrsig = $enable_module_schnorrsig"
echo " module musig = $enable_module_musig"
echo " module ellswift = $enable_module_ellswift"
echo
echo " asm = $set_asm"
echo " ecmult window size = $set_ecmult_window"
echo " ecmult gen table size = $set_ecmult_gen_kb KiB"
# Hide test-only options unless they're used.
if test x"$set_widemul" != xauto; then
echo " wide multiplication = $set_widemul"
fi
echo
echo " valgrind = $enable_valgrind"
echo " CC = $CC"
echo " CPPFLAGS = $CPPFLAGS"
echo " SECP_CFLAGS = $SECP_CFLAGS"
echo " CFLAGS = $CFLAGS"
echo " LDFLAGS = $LDFLAGS"
if test x"$print_msan_notice" = x"yes"; then
echo
echo "Note:"
echo " MemorySanitizer detected, tried to add -fno-sanitize-memory-param-retval to SECP_CFLAGS"
echo " to avoid false positives in ctime_tests. Pass --disable-ctime-tests to avoid this."
fi
if test x"$enable_experimental" = x"yes"; then
echo
echo "WARNING: Experimental build"
echo " Experimental features do not have stable APIs or properties, and may not be safe for"
echo " production use."
fi

View File

@@ -1,148 +0,0 @@
/***********************************************************************
* Copyright (c) 2015 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#include <string.h>
#include "lax_der_parsing.h"
int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
size_t rpos, rlen, spos, slen;
size_t pos = 0;
size_t lenbyte;
unsigned char tmpsig[64] = {0};
int overflow = 0;
/* Hack to initialize sig with a correctly-parsed but invalid signature. */
secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
/* Sequence tag byte */
if (pos == inputlen || input[pos] != 0x30) {
return 0;
}
pos++;
/* Sequence length bytes */
if (pos == inputlen) {
return 0;
}
lenbyte = input[pos++];
if (lenbyte & 0x80) {
lenbyte -= 0x80;
if (lenbyte > inputlen - pos) {
return 0;
}
pos += lenbyte;
}
/* Integer tag byte for R */
if (pos == inputlen || input[pos] != 0x02) {
return 0;
}
pos++;
/* Integer length for R */
if (pos == inputlen) {
return 0;
}
lenbyte = input[pos++];
if (lenbyte & 0x80) {
lenbyte -= 0x80;
if (lenbyte > inputlen - pos) {
return 0;
}
while (lenbyte > 0 && input[pos] == 0) {
pos++;
lenbyte--;
}
if (lenbyte >= sizeof(size_t)) {
return 0;
}
rlen = 0;
while (lenbyte > 0) {
rlen = (rlen << 8) + input[pos];
pos++;
lenbyte--;
}
} else {
rlen = lenbyte;
}
if (rlen > inputlen - pos) {
return 0;
}
rpos = pos;
pos += rlen;
/* Integer tag byte for S */
if (pos == inputlen || input[pos] != 0x02) {
return 0;
}
pos++;
/* Integer length for S */
if (pos == inputlen) {
return 0;
}
lenbyte = input[pos++];
if (lenbyte & 0x80) {
lenbyte -= 0x80;
if (lenbyte > inputlen - pos) {
return 0;
}
while (lenbyte > 0 && input[pos] == 0) {
pos++;
lenbyte--;
}
if (lenbyte >= sizeof(size_t)) {
return 0;
}
slen = 0;
while (lenbyte > 0) {
slen = (slen << 8) + input[pos];
pos++;
lenbyte--;
}
} else {
slen = lenbyte;
}
if (slen > inputlen - pos) {
return 0;
}
spos = pos;
/* Ignore leading zeroes in R */
while (rlen > 0 && input[rpos] == 0) {
rlen--;
rpos++;
}
/* Copy R value */
if (rlen > 32) {
overflow = 1;
} else if (rlen) {
memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
}
/* Ignore leading zeroes in S */
while (slen > 0 && input[spos] == 0) {
slen--;
spos++;
}
/* Copy S value */
if (slen > 32) {
overflow = 1;
} else if (slen) {
memcpy(tmpsig + 64 - slen, input + spos, slen);
}
if (!overflow) {
overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
}
if (overflow) {
memset(tmpsig, 0, 64);
secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
}
return 1;
}

View File

@@ -1,97 +0,0 @@
/***********************************************************************
* Copyright (c) 2015 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
/****
* Please do not link this file directly. It is not part of the libsecp256k1
* project and does not promise any stability in its API, functionality or
* presence. Projects which use this code should instead copy this header
* and its accompanying .c file directly into their codebase.
****/
/* This file defines a function that parses DER with various errors and
* violations. This is not a part of the library itself, because the allowed
* violations are chosen arbitrarily and do not follow or establish any
* standard.
*
* In many places it matters that different implementations do not only accept
* the same set of valid signatures, but also reject the same set of signatures.
* The only means to accomplish that is by strictly obeying a standard, and not
* accepting anything else.
*
* Nonetheless, sometimes there is a need for compatibility with systems that
* use signatures which do not strictly obey DER. The snippet below shows how
* certain violations are easily supported. You may need to adapt it.
*
* Do not use this for new systems. Use well-defined DER or compact signatures
* instead if you have the choice (see secp256k1_ecdsa_signature_parse_der and
* secp256k1_ecdsa_signature_parse_compact).
*
* The supported violations are:
* - All numbers are parsed as nonnegative integers, even though X.609-0207
* section 8.3.3 specifies that integers are always encoded as two's
* complement.
* - Integers can have length 0, even though section 8.3.1 says they can't.
* - Integers with overly long padding are accepted, violation section
* 8.3.2.
* - 127-byte long length descriptors are accepted, even though section
* 8.1.3.5.c says that they are not.
* - Trailing garbage data inside or after the signature is ignored.
* - The length descriptor of the sequence is ignored.
*
* Compared to for example OpenSSL, many violations are NOT supported:
* - Using overly long tag descriptors for the sequence or integers inside,
* violating section 8.1.2.2.
* - Encoding primitive integers as constructed values, violating section
* 8.3.1.
*/
#ifndef SECP256K1_CONTRIB_LAX_DER_PARSING_H
#define SECP256K1_CONTRIB_LAX_DER_PARSING_H
/* #include secp256k1.h only when it hasn't been included yet.
This enables this file to be #included directly in other project
files (such as tests.c) without the need to set an explicit -I flag,
which would be necessary to locate secp256k1.h. */
#ifndef SECP256K1_H
#include <secp256k1.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** Parse a signature in "lax DER" format
*
* Returns: 1 when the signature could be parsed, 0 otherwise.
* Args: ctx: a secp256k1 context object
* Out: sig: pointer to a signature object
* In: input: pointer to the signature to be parsed
* inputlen: the length of the array pointed to be input
*
* This function will accept any valid DER encoded signature, even if the
* encoded numbers are out of range. In addition, it will accept signatures
* which violate the DER spec in various ways. Its purpose is to allow
* validation of the Bitcoin blockchain, which includes non-DER signatures
* from before the network rules were updated to enforce DER. Note that
* the set of supported violations is a strict subset of what OpenSSL will
* accept.
*
* After the call, sig will always be initialized. If parsing failed or the
* encoded numbers are out of range, signature validation with it is
* guaranteed to fail for every message and public key.
*/
int ecdsa_signature_parse_der_lax(
const secp256k1_context* ctx,
secp256k1_ecdsa_signature* sig,
const unsigned char *input,
size_t inputlen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
#ifdef __cplusplus
}
#endif
#endif /* SECP256K1_CONTRIB_LAX_DER_PARSING_H */

View File

@@ -1,112 +0,0 @@
/***********************************************************************
* Copyright (c) 2014, 2015 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#include <string.h>
#include "lax_der_privatekey_parsing.h"
int ec_privkey_import_der(const secp256k1_context* ctx, unsigned char *out32, const unsigned char *privkey, size_t privkeylen) {
const unsigned char *end = privkey + privkeylen;
int lenb = 0;
int len = 0;
memset(out32, 0, 32);
/* sequence header */
if (end < privkey+1 || *privkey != 0x30) {
return 0;
}
privkey++;
/* sequence length constructor */
if (end < privkey+1 || !(*privkey & 0x80)) {
return 0;
}
lenb = *privkey & ~0x80; privkey++;
if (lenb < 1 || lenb > 2) {
return 0;
}
if (end < privkey+lenb) {
return 0;
}
/* sequence length */
len = privkey[lenb-1] | (lenb > 1 ? privkey[lenb-2] << 8 : 0);
privkey += lenb;
if (end < privkey+len) {
return 0;
}
/* sequence element 0: version number (=1) */
if (end < privkey+3 || privkey[0] != 0x02 || privkey[1] != 0x01 || privkey[2] != 0x01) {
return 0;
}
privkey += 3;
/* sequence element 1: octet string, up to 32 bytes */
if (end < privkey+2 || privkey[0] != 0x04 || privkey[1] > 0x20 || end < privkey+2+privkey[1]) {
return 0;
}
if (privkey[1]) memcpy(out32 + 32 - privkey[1], privkey + 2, privkey[1]);
if (!secp256k1_ec_seckey_verify(ctx, out32)) {
memset(out32, 0, 32);
return 0;
}
return 1;
}
int ec_privkey_export_der(const secp256k1_context *ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *key32, int compressed) {
secp256k1_pubkey pubkey;
size_t pubkeylen = 0;
if (!secp256k1_ec_pubkey_create(ctx, &pubkey, key32)) {
*privkeylen = 0;
return 0;
}
if (compressed) {
static const unsigned char begin[] = {
0x30,0x81,0xD3,0x02,0x01,0x01,0x04,0x20
};
static const unsigned char middle[] = {
0xA0,0x81,0x85,0x30,0x81,0x82,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48,
0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04,
0x21,0x02,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87,
0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8,
0x17,0x98,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,
0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x24,0x03,0x22,0x00
};
unsigned char *ptr = privkey;
memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
memcpy(ptr, key32, 32); ptr += 32;
memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
pubkeylen = 33;
secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED);
ptr += pubkeylen;
*privkeylen = ptr - privkey;
} else {
static const unsigned char begin[] = {
0x30,0x82,0x01,0x13,0x02,0x01,0x01,0x04,0x20
};
static const unsigned char middle[] = {
0xA0,0x81,0xA5,0x30,0x81,0xA2,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48,
0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04,
0x41,0x04,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87,
0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8,
0x17,0x98,0x48,0x3A,0xDA,0x77,0x26,0xA3,0xC4,0x65,0x5D,0xA4,0xFB,0xFC,0x0E,0x11,
0x08,0xA8,0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19,0x9C,0x47,0xD0,0x8F,0xFB,0x10,
0xD4,0xB8,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,
0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x44,0x03,0x42,0x00
};
unsigned char *ptr = privkey;
memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
memcpy(ptr, key32, 32); ptr += 32;
memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
pubkeylen = 65;
secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
ptr += pubkeylen;
*privkeylen = ptr - privkey;
}
return 1;
}

View File

@@ -1,95 +0,0 @@
/***********************************************************************
* Copyright (c) 2014, 2015 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
/****
* Please do not link this file directly. It is not part of the libsecp256k1
* project and does not promise any stability in its API, functionality or
* presence. Projects which use this code should instead copy this header
* and its accompanying .c file directly into their codebase.
****/
/* This file contains code snippets that parse DER private keys with
* various errors and violations. This is not a part of the library
* itself, because the allowed violations are chosen arbitrarily and
* do not follow or establish any standard.
*
* It also contains code to serialize private keys in a compatible
* manner.
*
* These functions are meant for compatibility with applications
* that require BER encoded keys. When working with secp256k1-specific
* code, the simple 32-byte private keys normally used by the
* library are sufficient.
*/
#ifndef SECP256K1_CONTRIB_BER_PRIVATEKEY_H
#define SECP256K1_CONTRIB_BER_PRIVATEKEY_H
/* #include secp256k1.h only when it hasn't been included yet.
This enables this file to be #included directly in other project
files (such as tests.c) without the need to set an explicit -I flag,
which would be necessary to locate secp256k1.h. */
#ifndef SECP256K1_H
#include <secp256k1.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** Export a private key in DER format.
*
* Returns: 1 if the private key was valid.
* Args: ctx: pointer to a context object (not secp256k1_context_static).
* Out: privkey: pointer to an array for storing the private key in BER.
* Should have space for 279 bytes, and cannot be NULL.
* privkeylen: Pointer to an int where the length of the private key in
* privkey will be stored.
* In: seckey: pointer to a 32-byte secret key to export.
* compressed: 1 if the key should be exported in
* compressed format, 0 otherwise
*
* This function is purely meant for compatibility with applications that
* require BER encoded keys. When working with secp256k1-specific code, the
* simple 32-byte private keys are sufficient.
*
* Note that this function does not guarantee correct DER output. It is
* guaranteed to be parsable by secp256k1_ec_privkey_import_der
*/
SECP256K1_WARN_UNUSED_RESULT int ec_privkey_export_der(
const secp256k1_context* ctx,
unsigned char *privkey,
size_t *privkeylen,
const unsigned char *seckey,
int compressed
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Import a private key in DER format.
* Returns: 1 if a private key was extracted.
* Args: ctx: pointer to a context object (cannot be NULL).
* Out: seckey: pointer to a 32-byte array for storing the private key.
* (cannot be NULL).
* In: privkey: pointer to a private key in DER format (cannot be NULL).
* privkeylen: length of the DER private key pointed to be privkey.
*
* This function will accept more than just strict DER, and even allow some BER
* violations. The public key stored inside the DER-encoded private key is not
* verified for correctness, nor are the curve parameters. Use this function
* only if you know in advance it is supposed to contain a secp256k1 private
* key.
*/
SECP256K1_WARN_UNUSED_RESULT int ec_privkey_import_der(
const secp256k1_context* ctx,
unsigned char *seckey,
const unsigned char *privkey,
size_t privkeylen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
#ifdef __cplusplus
}
#endif
#endif /* SECP256K1_CONTRIB_BER_PRIVATEKEY_H */

View File

@@ -1,483 +0,0 @@
# ElligatorSwift for secp256k1 explained
In this document we explain how the `ellswift` module implementation is related to the
construction in the
["SwiftEC: Shalluevan de Woestijne Indifferentiable Function To Elliptic Curves"](https://eprint.iacr.org/2022/759)
paper by Jorge Chávez-Saab, Francisco Rodríguez-Henríquez, and Mehdi Tibouchi.
* [1. Introduction](#1-introduction)
* [2. The decoding function](#2-the-decoding-function)
+ [2.1 Decoding for `secp256k1`](#21-decoding-for-secp256k1)
* [3. The encoding function](#3-the-encoding-function)
+ [3.1 Switching to *v, w* coordinates](#31-switching-to-v-w-coordinates)
+ [3.2 Avoiding computing all inverses](#32-avoiding-computing-all-inverses)
+ [3.3 Finding the inverse](#33-finding-the-inverse)
+ [3.4 Dealing with special cases](#34-dealing-with-special-cases)
+ [3.5 Encoding for `secp256k1`](#35-encoding-for-secp256k1)
* [4. Encoding and decoding full *(x, y)* coordinates](#4-encoding-and-decoding-full-x-y-coordinates)
+ [4.1 Full *(x, y)* coordinates for `secp256k1`](#41-full-x-y-coordinates-for-secp256k1)
## 1. Introduction
The `ellswift` module effectively introduces a new 64-byte public key format, with the property
that (uniformly random) public keys can be encoded as 64-byte arrays which are computationally
indistinguishable from uniform byte arrays. The module provides functions to convert public keys
from and to this format, as well as convenience functions for key generation and ECDH that operate
directly on ellswift-encoded keys.
The encoding consists of the concatenation of two (32-byte big endian) encoded field elements $u$
and $t.$ Together they encode an x-coordinate on the curve $x$, or (see further) a full point $(x, y)$ on
the curve.
**Decoding** consists of decoding the field elements $u$ and $t$ (values above the field size $p$
are taken modulo $p$), and then evaluating $F_u(t)$, which for every $u$ and $t$ results in a valid
x-coordinate on the curve. The functions $F_u$ will be defined in [Section 2](#2-the-decoding-function).
**Encoding** a given $x$ coordinate is conceptually done as follows:
* Loop:
* Pick a uniformly random field element $u.$
* Compute the set $L = F_u^{-1}(x)$ of $t$ values for which $F_u(t) = x$, which may have up to *8* elements.
* With probability $1 - \dfrac{\\#L}{8}$, restart the loop.
* Select a uniformly random $t \in L$ and return $(u, t).$
This is the *ElligatorSwift* algorithm, here given for just x-coordinates. An extension to full
$(x, y)$ points will be given in [Section 4](#4-encoding-and-decoding-full-x-y-coordinates).
The algorithm finds a uniformly random $(u, t)$ among (almost all) those
for which $F_u(t) = x.$ Section 3.2 in the paper proves that the number of such encodings for
almost all x-coordinates on the curve (all but at most 39) is close to two times the field size
(specifically, it lies in the range $2q \pm (22\sqrt{q} + O(1))$, where $q$ is the size of the field).
## 2. The decoding function
First some definitions:
* $\mathbb{F}$ is the finite field of size $q$, of characteristic 5 or more, and $q \equiv 1 \mod 3.$
* For `secp256k1`, $q = 2^{256} - 2^{32} - 977$, which satisfies that requirement.
* Let $E$ be the elliptic curve of points $(x, y) \in \mathbb{F}^2$ for which $y^2 = x^3 + ax + b$, with $a$ and $b$
public constants, for which $\Delta_E = -16(4a^3 + 27b^2)$ is a square, and at least one of $(-b \pm \sqrt{-3 \Delta_E} / 36)/2$ is a square.
This implies that the order of $E$ is either odd, or a multiple of *4*.
If $a=0$, this condition is always fulfilled.
* For `secp256k1`, $a=0$ and $b=7.$
* Let the function $g(x) = x^3 + ax + b$, so the $E$ curve equation is also $y^2 = g(x).$
* Let the function $h(x) = 3x^3 + 4a.$
* Define $V$ as the set of solutions $(x_1, x_2, x_3, z)$ to $z^2 = g(x_1)g(x_2)g(x_3).$
* Define $S_u$ as the set of solutions $(X, Y)$ to $X^2 + h(u)Y^2 = -g(u)$ and $Y \neq 0.$
* $P_u$ is a function from $\mathbb{F}$ to $S_u$ that will be defined below.
* $\psi_u$ is a function from $S_u$ to $V$ that will be defined below.
**Note**: In the paper:
* $F_u$ corresponds to $F_{0,u}$ there.
* $P_u(t)$ is called $P$ there.
* All $S_u$ sets together correspond to $S$ there.
* All $\psi_u$ functions together (operating on elements of $S$) correspond to $\psi$ there.
Note that for $V$, the left hand side of the equation $z^2$ is square, and thus the right
hand must also be square. As multiplying non-squares results in a square in $\mathbb{F}$,
out of the three right-hand side factors an even number must be non-squares.
This implies that exactly *1* or exactly *3* out of
$\\{g(x_1), g(x_2), g(x_3)\\}$ must be square, and thus that for any $(x_1,x_2,x_3,z) \in V$,
at least one of $\\{x_1, x_2, x_3\\}$ must be a valid x-coordinate on $E.$ There is one exception
to this, namely when $z=0$, but even then one of the three values is a valid x-coordinate.
**Define** the decoding function $F_u(t)$ as:
* Let $(x_1, x_2, x_3, z) = \psi_u(P_u(t)).$
* Return the first element $x$ of $(x_3, x_2, x_1)$ which is a valid x-coordinate on $E$ (i.e., $g(x)$ is square).
$P_u(t) = (X(u, t), Y(u, t))$, where:
$$
\begin{array}{lcl}
X(u, t) & = & \left\\{\begin{array}{ll}
\dfrac{g(u) - t^2}{2t} & a = 0 \\
\dfrac{g(u) + h(u)(Y_0(u) - X_0(u)t)^2}{X_0(u)(1 + h(u)t^2)} & a \neq 0
\end{array}\right. \\
Y(u, t) & = & \left\\{\begin{array}{ll}
\dfrac{X(u, t) + t}{u \sqrt{-3}} = \dfrac{g(u) + t^2}{2tu\sqrt{-3}} & a = 0 \\
Y_0(u) + t(X(u, t) - X_0(u)) & a \neq 0
\end{array}\right.
\end{array}
$$
$P_u(t)$ is defined:
* For $a=0$, unless:
* $u = 0$ or $t = 0$ (division by zero)
* $g(u) = -t^2$ (would give $Y=0$).
* For $a \neq 0$, unless:
* $X_0(u) = 0$ or $h(u)t^2 = -1$ (division by zero)
* $Y_0(u) (1 - h(u)t^2) = 2X_0(u)t$ (would give $Y=0$).
The functions $X_0(u)$ and $Y_0(u)$ are defined in Appendix A of the paper, and depend on various properties of $E.$
The function $\psi_u$ is the same for all curves: $\psi_u(X, Y) = (x_1, x_2, x_3, z)$, where:
$$
\begin{array}{lcl}
x_1 & = & \dfrac{X}{2Y} - \dfrac{u}{2} && \\
x_2 & = & -\dfrac{X}{2Y} - \dfrac{u}{2} && \\
x_3 & = & u + 4Y^2 && \\
z & = & \dfrac{g(x_3)}{2Y}(u^2 + ux_1 + x_1^2 + a) = \dfrac{-g(u)g(x_3)}{8Y^3}
\end{array}
$$
### 2.1 Decoding for `secp256k1`
Put together and specialized for $a=0$ curves, decoding $(u, t)$ to an x-coordinate is:
**Define** $F_u(t)$ as:
* Let $X = \dfrac{u^3 + b - t^2}{2t}.$
* Let $Y = \dfrac{X + t}{u\sqrt{-3}}.$
* Return the first $x$ in $(u + 4Y^2, \dfrac{-X}{2Y} - \dfrac{u}{2}, \dfrac{X}{2Y} - \dfrac{u}{2})$ for which $g(x)$ is square.
To make sure that every input decodes to a valid x-coordinate, we remap the inputs in case
$P_u$ is not defined (when $u=0$, $t=0$, or $g(u) = -t^2$):
**Define** $F_u(t)$ as:
* Let $u'=u$ if $u \neq 0$; $1$ otherwise (guaranteeing $u' \neq 0$).
* Let $t'=t$ if $t \neq 0$; $1$ otherwise (guaranteeing $t' \neq 0$).
* Let $t''=t'$ if $g(u') \neq -t'^2$; $2t'$ otherwise (guaranteeing $t'' \neq 0$ and $g(u') \neq -t''^2$).
* Let $X = \dfrac{u'^3 + b - t''^2}{2t''}.$
* Let $Y = \dfrac{X + t''}{u'\sqrt{-3}}.$
* Return the first $x$ in $(u' + 4Y^2, \dfrac{-X}{2Y} - \dfrac{u'}{2}, \dfrac{X}{2Y} - \dfrac{u'}{2})$ for which $x^3 + b$ is square.
The choices here are not strictly necessary. Just returning a fixed constant in any of the undefined cases would suffice,
but the approach here is simple enough and gives fairly uniform output even in these cases.
**Note**: in the paper these conditions result in $\infty$ as output, due to the use of projective coordinates there.
We wish to avoid the need for callers to deal with this special case.
This is implemented in `secp256k1_ellswift_xswiftec_frac_var` (which decodes to an x-coordinate represented as a fraction), and
in `secp256k1_ellswift_xswiftec_var` (which outputs the actual x-coordinate).
## 3. The encoding function
To implement $F_u^{-1}(x)$, the function to find the set of inverses $t$ for which $F_u(t) = x$, we have to reverse the process:
* Find all the $(X, Y) \in S_u$ that could have given rise to $x$, through the $x_1$, $x_2$, or $x_3$ formulas in $\psi_u.$
* Map those $(X, Y)$ solutions to $t$ values using $P_u^{-1}(X, Y).$
* For each of the found $t$ values, verify that $F_u(t) = x.$
* Return the remaining $t$ values.
The function $P_u^{-1}$, which finds $t$ given $(X, Y) \in S_u$, is significantly simpler than $P_u:$
$$
P_u^{-1}(X, Y) = \left\\{\begin{array}{ll}
Yu\sqrt{-3} - X & a = 0 \\
\dfrac{Y-Y_0(u)}{X-X_0(u)} & a \neq 0 \land X \neq X_0(u) \\
\dfrac{-X_0(u)}{h(u)Y_0(u)} & a \neq 0 \land X = X_0(u) \land Y = Y_0(u)
\end{array}\right.
$$
The third step above, verifying that $F_u(t) = x$, is necessary because for the $(X, Y)$ values found through the $x_1$ and $x_2$ expressions,
it is possible that decoding through $\psi_u(X, Y)$ yields a valid $x_3$ on the curve, which would take precedence over the
$x_1$ or $x_2$ decoding. These $(X, Y)$ solutions must be rejected.
Since we know that exactly one or exactly three out of $\\{x_1, x_2, x_3\\}$ are valid x-coordinates for any $t$,
the case where either $x_1$ or $x_2$ is valid and in addition also $x_3$ is valid must mean that all three are valid.
This means that instead of checking whether $x_3$ is on the curve, it is also possible to check whether the other one out of
$x_1$ and $x_2$ is on the curve. This is significantly simpler, as it turns out.
Observe that $\psi_u$ guarantees that $x_1 + x_2 = -u.$ So given either $x = x_1$ or $x = x_2$, the other one of the two can be computed as
$-u - x.$ Thus, when encoding $x$ through the $x_1$ or $x_2$ expressions, one can simply check whether $g(-u-x)$ is a square,
and if so, not include the corresponding $t$ values in the returned set. As this does not need $X$, $Y$, or $t$, this condition can be determined
before those values are computed.
It is not possible that an encoding found through the $x_1$ expression decodes to a different valid x-coordinate using $x_2$ (which would
take precedence), for the same reason: if both $x_1$ and $x_2$ decodings were valid, $x_3$ would be valid as well, and thus take
precedence over both. Because of this, the $g(-u-x)$ being square test for $x_1$ and $x_2$ is the only test necessary to guarantee the found $t$
values round-trip back to the input $x$ correctly. This is the reason for choosing the $(x_3, x_2, x_1)$ precedence order in the decoder;
any order which does not place $x_3$ first requires more complicated round-trip checks in the encoder.
### 3.1 Switching to *v, w* coordinates
Before working out the formulas for all this, we switch to different variables for $S_u.$ Let $v = (X/Y - u)/2$, and
$w = 2Y.$ Or in the other direction, $X = w(u/2 + v)$ and $Y = w/2:$
* $S_u'$ becomes the set of $(v, w)$ for which $w^2 (u^2 + uv + v^2 + a) = -g(u)$ and $w \neq 0.$
* For $a=0$ curves, $P_u^{-1}$ can be stated for $(v,w)$ as $P_u^{'-1}(v, w) = w\left(\frac{\sqrt{-3}-1}{2}u - v\right).$
* $\psi_u$ can be stated for $(v, w)$ as $\psi_u'(v, w) = (x_1, x_2, x_3, z)$, where
$$
\begin{array}{lcl}
x_1 & = & v \\
x_2 & = & -u - v \\
x_3 & = & u + w^2 \\
z & = & \dfrac{g(x_3)}{w}(u^2 + uv + v^2 + a) = \dfrac{-g(u)g(x_3)}{w^3}
\end{array}
$$
We can now write the expressions for finding $(v, w)$ given $x$ explicitly, by solving each of the $\\{x_1, x_2, x_3\\}$
expressions for $v$ or $w$, and using the $S_u'$ equation to find the other variable:
* Assuming $x = x_1$, we find $v = x$ and $w = \pm\sqrt{-g(u)/(u^2 + uv + v^2 + a)}$ (two solutions).
* Assuming $x = x_2$, we find $v = -u-x$ and $w = \pm\sqrt{-g(u)/(u^2 + uv + v^2 + a)}$ (two solutions).
* Assuming $x = x_3$, we find $w = \pm\sqrt{x-u}$ and $v = -u/2 \pm \sqrt{-w^2(4g(u) + w^2h(u))}/(2w^2)$ (four solutions).
### 3.2 Avoiding computing all inverses
The *ElligatorSwift* algorithm as stated in Section 1 requires the computation of $L = F_u^{-1}(x)$ (the
set of all $t$ such that $(u, t)$ decode to $x$) in full. This is unnecessary.
Observe that the procedure of restarting with probability $(1 - \frac{\\#L}{8})$ and otherwise returning a
uniformly random element from $L$ is actually equivalent to always padding $L$ with $\bot$ values up to length 8,
picking a uniformly random element from that, restarting whenever $\bot$ is picked:
**Define** *ElligatorSwift(x)* as:
* Loop:
* Pick a uniformly random field element $u.$
* Compute the set $L = F_u^{-1}(x).$
* Let $T$ be the 8-element vector consisting of the elements of $L$, plus $8 - \\#L$ times $\\{\bot\\}.$
* Select a uniformly random $t \in T.$
* If $t \neq \bot$, return $(u, t)$; restart loop otherwise.
Now notice that the order of elements in $T$ does not matter, as all we do is pick a uniformly
random element in it, so we do not need to have all $\bot$ values at the end.
As we have 8 distinct formulas for finding $(v, w)$ (taking the variants due to $\pm$ into account),
we can associate every index in $T$ with exactly one of those formulas, making sure that:
* Formulas that yield no solutions (due to division by zero or non-existing square roots) or invalid solutions are made to return $\bot.$
* For the $x_1$ and $x_2$ cases, if $g(-u-x)$ is a square, $\bot$ is returned instead (the round-trip check).
* In case multiple formulas would return the same non- $\bot$ result, all but one of those must be turned into $\bot$ to avoid biasing those.
The last condition above only occurs with negligible probability for cryptographically-sized curves, but is interesting
to take into account as it allows exhaustive testing in small groups. See [Section 3.4](#34-dealing-with-special-cases)
for an analysis of all the negligible cases.
If we define $T = (G_{0,u}(x), G_{1,u}(x), \ldots, G_{7,u}(x))$, with each $G_{i,u}$ matching one of the formulas,
the loop can be simplified to only compute one of the inverses instead of all of them:
**Define** *ElligatorSwift(x)* as:
* Loop:
* Pick a uniformly random field element $u.$
* Pick a uniformly random integer $c$ in $[0,8).$
* Let $t = G_{c,u}(x).$
* If $t \neq \bot$, return $(u, t)$; restart loop otherwise.
This is implemented in `secp256k1_ellswift_xelligatorswift_var`.
### 3.3 Finding the inverse
To implement $G_{c,u}$, we map $c=0$ to the $x_1$ formula, $c=1$ to the $x_2$ formula, and $c=2$ and $c=3$ to the $x_3$ formula.
Those are then repeated as $c=4$ through $c=7$ for the other sign of $w$ (noting that in each formula, $w$ is a square root of some expression).
Ignoring the negligible cases, we get:
**Define** $G_{c,u}(x)$ as:
* If $c \in \\{0, 1, 4, 5\\}$ (for $x_1$ and $x_2$ formulas):
* If $g(-u-x)$ is square, return $\bot$ (as $x_3$ would be valid and take precedence).
* If $c \in \\{0, 4\\}$ (the $x_1$ formula) let $v = x$, otherwise let $v = -u-x$ (the $x_2$ formula)
* Let $s = -g(u)/(u^2 + uv + v^2 + a)$ (using $s = w^2$ in what follows).
* Otherwise, when $c \in \\{2, 3, 6, 7\\}$ (for $x_3$ formulas):
* Let $s = x-u.$
* Let $r = \sqrt{-s(4g(u) + sh(u))}.$
* Let $v = (r/s - u)/2$ if $c \in \\{3, 7\\}$; $(-r/s - u)/2$ otherwise.
* Let $w = \sqrt{s}.$
* Depending on $c:$
* If $c \in \\{0, 1, 2, 3\\}:$ return $P_u^{'-1}(v, w).$
* If $c \in \\{4, 5, 6, 7\\}:$ return $P_u^{'-1}(v, -w).$
Whenever a square root of a non-square is taken, $\bot$ is returned; for both square roots this happens with roughly
50% on random inputs. Similarly, when a division by 0 would occur, $\bot$ is returned as well; this will only happen
with negligible probability. A division by 0 in the first branch in fact cannot occur at all, because $u^2 + uv + v^2 + a = 0$
implies $g(-u-x) = g(x)$ which would mean the $g(-u-x)$ is square condition has triggered
and $\bot$ would have been returned already.
**Note**: In the paper, the $case$ variable corresponds roughly to the $c$ above, but only takes on 4 possible values (1 to 4).
The conditional negation of $w$ at the end is done randomly, which is equivalent, but makes testing harder. We choose to
have the $G_{c,u}$ be deterministic, and capture all choices in $c.$
Now observe that the $c \in \\{1, 5\\}$ and $c \in \\{3, 7\\}$ conditions effectively perform the same $v \rightarrow -u-v$
transformation. Furthermore, that transformation has no effect on $s$ in the first branch
as $u^2 + ux + x^2 + a = u^2 + u(-u-x) + (-u-x)^2 + a.$ Thus we can extract it out and move it down:
**Define** $G_{c,u}(x)$ as:
* If $c \in \\{0, 1, 4, 5\\}:$
* If $g(-u-x)$ is square, return $\bot.$
* Let $s = -g(u)/(u^2 + ux + x^2 + a).$
* Let $v = x.$
* Otherwise, when $c \in \\{2, 3, 6, 7\\}:$
* Let $s = x-u.$
* Let $r = \sqrt{-s(4g(u) + sh(u))}.$
* Let $v = (r/s - u)/2.$
* Let $w = \sqrt{s}.$
* Depending on $c:$
* If $c \in \\{0, 2\\}:$ return $P_u^{'-1}(v, w).$
* If $c \in \\{1, 3\\}:$ return $P_u^{'-1}(-u-v, w).$
* If $c \in \\{4, 6\\}:$ return $P_u^{'-1}(v, -w).$
* If $c \in \\{5, 7\\}:$ return $P_u^{'-1}(-u-v, -w).$
This shows there will always be exactly 0, 4, or 8 $t$ values for a given $(u, x)$ input.
There can be 0, 1, or 2 $(v, w)$ pairs before invoking $P_u^{'-1}$, and each results in 4 distinct $t$ values.
### 3.4 Dealing with special cases
As mentioned before there are a few cases to deal with which only happen in a negligibly small subset of inputs.
For cryptographically sized fields, if only random inputs are going to be considered, it is unnecessary to deal with these. Still, for completeness
we analyse them here. They generally fall into two categories: cases in which the encoder would produce $t$ values that
do not decode back to $x$ (or at least cannot guarantee that they do), and cases in which the encoder might produce the same
$t$ value for multiple $c$ inputs (thereby biasing that encoding):
* In the branch for $x_1$ and $x_2$ (where $c \in \\{0, 1, 4, 5\\}$):
* When $g(u) = 0$, we would have $s=w=Y=0$, which is not on $S_u.$ This is only possible on even-ordered curves.
Excluding this also removes the one condition under which the simplified check for $x_3$ on the curve
fails (namely when $g(x_1)=g(x_2)=0$ but $g(x_3)$ is not square).
This does exclude some valid encodings: when both $g(u)=0$ and $u^2+ux+x^2+a=0$ (also implying $g(x)=0$),
the $S_u'$ equation degenerates to $0 = 0$, and many valid $t$ values may exist. Yet, these cannot be targeted uniformly by the
encoder anyway as there will generally be more than 8.
* When $g(x) = 0$, the same $t$ would be produced as in the $x_3$ branch (where $c \in \\{2, 3, 6, 7\\}$) which we give precedence
as it can deal with $g(u)=0$.
This is again only possible on even-ordered curves.
* In the branch for $x_3$ (where $c \in \\{2, 3, 6, 7\\}$):
* When $s=0$, a division by zero would occur.
* When $v = -u-v$ and $c \in \\{3, 7\\}$, the same $t$ would be returned as in the $c \in \\{2, 6\\}$ cases.
It is equivalent to checking whether $r=0$.
This cannot occur in the $x_1$ or $x_2$ branches, as it would trigger the $g(-u-x)$ is square condition.
A similar concern for $w = -w$ does not exist, as $w=0$ is already impossible in both branches: in the first
it requires $g(u)=0$ which is already outlawed on even-ordered curves and impossible on others; in the second it would trigger division by zero.
* Curve-specific special cases also exist that need to be rejected, because they result in $(u,t)$ which is invalid to the decoder, or because of division by zero in the encoder:
* For $a=0$ curves, when $u=0$ or when $t=0$. The latter can only be reached by the encoder when $g(u)=0$, which requires an even-ordered curve.
* For $a \neq 0$ curves, when $X_0(u)=0$, when $h(u)t^2 = -1$, or when $w(u + 2v) = 2X_0(u)$ while also either $w \neq 2Y_0(u)$ or $h(u)=0$.
**Define** a version of $G_{c,u}(x)$ which deals with all these cases:
* If $a=0$ and $u=0$, return $\bot.$
* If $a \neq 0$ and $X_0(u)=0$, return $\bot.$
* If $c \in \\{0, 1, 4, 5\\}:$
* If $g(u) = 0$ or $g(x) = 0$, return $\bot$ (even curves only).
* If $g(-u-x)$ is square, return $\bot.$
* Let $s = -g(u)/(u^2 + ux + x^2 + a)$ (cannot cause division by zero).
* Let $v = x.$
* Otherwise, when $c \in \\{2, 3, 6, 7\\}:$
* Let $s = x-u.$
* Let $r = \sqrt{-s(4g(u) + sh(u))}$; return $\bot$ if not square.
* If $c \in \\{3, 7\\}$ and $r=0$, return $\bot.$
* If $s = 0$, return $\bot.$
* Let $v = (r/s - u)/2.$
* Let $w = \sqrt{s}$; return $\bot$ if not square.
* If $a \neq 0$ and $w(u+2v) = 2X_0(u)$ and either $w \neq 2Y_0(u)$ or $h(u) = 0$, return $\bot.$
* Depending on $c:$
* If $c \in \\{0, 2\\}$, let $t = P_u^{'-1}(v, w).$
* If $c \in \\{1, 3\\}$, let $t = P_u^{'-1}(-u-v, w).$
* If $c \in \\{4, 6\\}$, let $t = P_u^{'-1}(v, -w).$
* If $c \in \\{5, 7\\}$, let $t = P_u^{'-1}(-u-v, -w).$
* If $a=0$ and $t=0$, return $\bot$ (even curves only).
* If $a \neq 0$ and $h(u)t^2 = -1$, return $\bot.$
* Return $t.$
Given any $u$, using this algorithm over all $x$ and $c$ values, every $t$ value will be reached exactly once,
for an $x$ for which $F_u(t) = x$ holds, except for these cases that will not be reached:
* All cases where $P_u(t)$ is not defined:
* For $a=0$ curves, when $u=0$, $t=0$, or $g(u) = -t^2.$
* For $a \neq 0$ curves, when $h(u)t^2 = -1$, $X_0(u) = 0$, or $Y_0(u) (1 - h(u) t^2) = 2X_0(u)t.$
* When $g(u)=0$, the potentially many $t$ values that decode to an $x$ satisfying $g(x)=0$ using the $x_2$ formula. These were excluded by the $g(u)=0$ condition in the $c \in \\{0, 1, 4, 5\\}$ branch.
These cases form a negligible subset of all $(u, t)$ for cryptographically sized curves.
### 3.5 Encoding for `secp256k1`
Specialized for odd-ordered $a=0$ curves:
**Define** $G_{c,u}(x)$ as:
* If $u=0$, return $\bot.$
* If $c \in \\{0, 1, 4, 5\\}:$
* If $(-u-x)^3 + b$ is square, return $\bot$
* Let $s = -(u^3 + b)/(u^2 + ux + x^2)$ (cannot cause division by 0).
* Let $v = x.$
* Otherwise, when $c \in \\{2, 3, 6, 7\\}:$
* Let $s = x-u.$
* Let $r = \sqrt{-s(4(u^3 + b) + 3su^2)}$; return $\bot$ if not square.
* If $c \in \\{3, 7\\}$ and $r=0$, return $\bot.$
* If $s = 0$, return $\bot.$
* Let $v = (r/s - u)/2.$
* Let $w = \sqrt{s}$; return $\bot$ if not square.
* Depending on $c:$
* If $c \in \\{0, 2\\}:$ return $w(\frac{\sqrt{-3}-1}{2}u - v).$
* If $c \in \\{1, 3\\}:$ return $w(\frac{\sqrt{-3}+1}{2}u + v).$
* If $c \in \\{4, 6\\}:$ return $w(\frac{-\sqrt{-3}+1}{2}u + v).$
* If $c \in \\{5, 7\\}:$ return $w(\frac{-\sqrt{-3}-1}{2}u - v).$
This is implemented in `secp256k1_ellswift_xswiftec_inv_var`.
And the x-only ElligatorSwift encoding algorithm is still:
**Define** *ElligatorSwift(x)* as:
* Loop:
* Pick a uniformly random field element $u.$
* Pick a uniformly random integer $c$ in $[0,8).$
* Let $t = G_{c,u}(x).$
* If $t \neq \bot$, return $(u, t)$; restart loop otherwise.
Note that this logic does not take the remapped $u=0$, $t=0$, and $g(u) = -t^2$ cases into account; it just avoids them.
While it is not impossible to make the encoder target them, this would increase the maximum number of $t$ values for a given $(u, x)$
combination beyond 8, and thereby slow down the ElligatorSwift loop proportionally, for a negligible gain in uniformity.
## 4. Encoding and decoding full *(x, y)* coordinates
So far we have only addressed encoding and decoding x-coordinates, but in some cases an encoding
for full points with $(x, y)$ coordinates is desirable. It is possible to encode this information
in $t$ as well.
Note that for any $(X, Y) \in S_u$, $(\pm X, \pm Y)$ are all on $S_u.$ Moreover, all of these are
mapped to the same x-coordinate. Negating $X$ or negating $Y$ just results in $x_1$ and $x_2$
being swapped, and does not affect $x_3.$ This will not change the outcome x-coordinate as the order
of $x_1$ and $x_2$ only matters if both were to be valid, and in that case $x_3$ would be used instead.
Still, these four $(X, Y)$ combinations all correspond to distinct $t$ values, so we can encode
the sign of the y-coordinate in the sign of $X$ or the sign of $Y.$ They correspond to the
four distinct $P_u^{'-1}$ calls in the definition of $G_{u,c}.$
**Note**: In the paper, the sign of the y coordinate is encoded in a separately-coded bit.
To encode the sign of $y$ in the sign of $Y:$
**Define** *Decode(u, t)* for full $(x, y)$ as:
* Let $(X, Y) = P_u(t).$
* Let $x$ be the first value in $(u + 4Y^2, \frac{-X}{2Y} - \frac{u}{2}, \frac{X}{2Y} - \frac{u}{2})$ for which $g(x)$ is square.
* Let $y = \sqrt{g(x)}.$
* If $sign(y) = sign(Y)$, return $(x, y)$; otherwise return $(x, -y).$
And encoding would be done using a $G_{c,u}(x, y)$ function defined as:
**Define** $G_{c,u}(x, y)$ as:
* If $c \in \\{0, 1\\}:$
* If $g(u) = 0$ or $g(x) = 0$, return $\bot$ (even curves only).
* If $g(-u-x)$ is square, return $\bot.$
* Let $s = -g(u)/(u^2 + ux + x^2 + a)$ (cannot cause division by zero).
* Let $v = x.$
* Otherwise, when $c \in \\{2, 3\\}:$
* Let $s = x-u.$
* Let $r = \sqrt{-s(4g(u) + sh(u))}$; return $\bot$ if not square.
* If $c = 3$ and $r = 0$, return $\bot.$
* Let $v = (r/s - u)/2.$
* Let $w = \sqrt{s}$; return $\bot$ if not square.
* Let $w' = w$ if $sign(w/2) = sign(y)$; $-w$ otherwise.
* Depending on $c:$
* If $c \in \\{0, 2\\}:$ return $P_u^{'-1}(v, w').$
* If $c \in \\{1, 3\\}:$ return $P_u^{'-1}(-u-v, w').$
Note that $c$ now only ranges $[0,4)$, as the sign of $w'$ is decided based on that of $y$, rather than on $c.$
This change makes some valid encodings unreachable: when $y = 0$ and $sign(Y) \neq sign(0)$.
In the above logic, $sign$ can be implemented in several ways, such as parity of the integer representation
of the input field element (for prime-sized fields) or the quadratic residuosity (for fields where
$-1$ is not square). The choice does not matter, as long as it only takes on two possible values, and for $x \neq 0$ it holds that $sign(x) \neq sign(-x)$.
### 4.1 Full *(x, y)* coordinates for `secp256k1`
For $a=0$ curves, there is another option. Note that for those,
the $P_u(t)$ function translates negations of $t$ to negations of (both) $X$ and $Y.$ Thus, we can use $sign(t)$ to
encode the y-coordinate directly. Combined with the earlier remapping to guarantee all inputs land on the curve, we get
as decoder:
**Define** *Decode(u, t)* as:
* Let $u'=u$ if $u \neq 0$; $1$ otherwise.
* Let $t'=t$ if $t \neq 0$; $1$ otherwise.
* Let $t''=t'$ if $u'^3 + b + t'^2 \neq 0$; $2t'$ otherwise.
* Let $X = \dfrac{u'^3 + b - t''^2}{2t''}.$
* Let $Y = \dfrac{X + t''}{u'\sqrt{-3}}.$
* Let $x$ be the first element of $(u' + 4Y^2, \frac{-X}{2Y} - \frac{u'}{2}, \frac{X}{2Y} - \frac{u'}{2})$ for which $g(x)$ is square.
* Let $y = \sqrt{g(x)}.$
* Return $(x, y)$ if $sign(y) = sign(t)$; $(x, -y)$ otherwise.
This is implemented in `secp256k1_ellswift_swiftec_var`. The used $sign(x)$ function is the parity of $x$ when represented as in integer in $[0,q).$
The corresponding encoder would invoke the x-only one, but negating the output $t$ if $sign(t) \neq sign(y).$
This is implemented in `secp256k1_ellswift_elligatorswift_var`.
Note that this is only intended for encoding points where both the x-coordinate and y-coordinate are unpredictable. When encoding x-only points
where the y-coordinate is implicitly even (or implicitly square, or implicitly in $[0,q/2]$), the encoder in
[Section 3.5](#35-encoding-for-secp256k1) must be used, or a bias is reintroduced that undoes all the benefit of using ElligatorSwift
in the first place.

View File

@@ -1,54 +0,0 @@
Notes on the musig module API
===========================
The following sections contain additional notes on the API of the musig module (`include/secp256k1_musig.h`).
A usage example can be found in `examples/musig.c`.
## API misuse
The musig API is designed with a focus on misuse resistance.
However, due to the interactive nature of the MuSig protocol, there are additional failure modes that are not present in regular (single-party) Schnorr signature creation.
While the results can be catastrophic (e.g. leaking of the secret key), it is unfortunately not possible for the musig implementation to prevent all such failure modes.
Therefore, users of the musig module must take great care to make sure of the following:
1. A unique nonce per signing session is generated in `secp256k1_musig_nonce_gen`.
See the corresponding comment in `include/secp256k1_musig.h` for how to ensure that.
2. The `secp256k1_musig_secnonce` structure is never copied or serialized.
See also the comment on `secp256k1_musig_secnonce` in `include/secp256k1_musig.h`.
3. Opaque data structures are never written to or read from directly.
Instead, only the provided accessor functions are used.
## Key Aggregation and (Taproot) Tweaking
Given a set of public keys, the aggregate public key is computed with `secp256k1_musig_pubkey_agg`.
A plain tweak can be added to the resulting public key with `secp256k1_ec_pubkey_tweak_add` by setting the `tweak32` argument to the hash defined in BIP 32. Similarly, a Taproot tweak can be added with `secp256k1_xonly_pubkey_tweak_add` by setting the `tweak32` argument to the TapTweak hash defined in BIP 341.
Both types of tweaking can be combined and invoked multiple times if the specific application requires it.
## Signing
This is covered by `examples/musig.c`.
Essentially, the protocol proceeds in the following steps:
1. Generate a keypair with `secp256k1_keypair_create` and obtain the public key with `secp256k1_keypair_pub`.
2. Call `secp256k1_musig_pubkey_agg` with the pubkeys of all participants.
3. Optionally add a (Taproot) tweak with `secp256k1_musig_pubkey_xonly_tweak_add` and a plain tweak with `secp256k1_musig_pubkey_ec_tweak_add`.
4. Generate a pair of secret and public nonce with `secp256k1_musig_nonce_gen` and send the public nonce to the other signers.
5. Someone (not necessarily the signer) aggregates the public nonces with `secp256k1_musig_nonce_agg` and sends it to the signers.
6. Process the aggregate nonce with `secp256k1_musig_nonce_process`.
7. Create a partial signature with `secp256k1_musig_partial_sign`.
8. Verify the partial signatures (optional in some scenarios) with `secp256k1_musig_partial_sig_verify`.
9. Someone (not necessarily the signer) obtains all partial signatures and aggregates them into the final Schnorr signature using `secp256k1_musig_partial_sig_agg`.
The aggregate signature can be verified with `secp256k1_schnorrsig_verify`.
Steps 1 through 5 above can occur before or after the signers are aware of the message to be signed.
Whenever possible, it is recommended to generate the nonces only after the message is known.
This provides enhanced defense-in-depth measures, protecting against potential API misuse in certain scenarios.
However, it does require two rounds of communication during the signing process.
The alternative, generating the nonces in a pre-processing step before the message is known, eliminates these additional protective measures but allows for non-interactive signing.
Similarly, the API supports an alternative protocol flow where generating the aggregate key (steps 1 to 3) is allowed to happen after exchanging nonces (steps 4 to 5).
## Verification
A participant who wants to verify the partial signatures, but does not sign itself may do so using the above instructions except that the verifier skips steps 1, 4 and 7.

View File

@@ -1,94 +0,0 @@
# Release process
This document outlines the process for releasing versions of the form `$MAJOR.$MINOR.$PATCH`.
We distinguish between two types of releases: *regular* and *maintenance* releases.
Regular releases are releases of a new major or minor version as well as patches of the most recent release.
Maintenance releases, on the other hand, are required for patches of older releases.
You should coordinate with the other maintainers on the release date, if possible.
This date will be part of the release entry in [CHANGELOG.md](../CHANGELOG.md) and it should match the dates of the remaining steps in the release process (including the date of the tag and the GitHub release).
It is best if the maintainers are present during the release, so they can help ensure that the process is followed correctly and, in the case of a regular release, they are aware that they should not modify the master branch between merging the PR in step 1 and the PR in step 3.
This process also assumes that there will be no minor releases for old major releases.
We aim to cut a regular release every 3-4 months, approximately twice as frequent as major Bitcoin Core releases. Every second release should be published one month before the feature freeze of the next major Bitcoin Core release, allowing sufficient time to update the library in Core.
## Sanity checks
Perform these checks when reviewing the release PR (see below):
1. Ensure `make distcheck` doesn't fail.
```shell
./autogen.sh && ./configure --enable-dev-mode && make distcheck
```
2. Check installation with autotools:
```shell
dir=$(mktemp -d)
./autogen.sh && ./configure --prefix=$dir && make clean && make install && ls -RlAh $dir
gcc -o ecdsa examples/ecdsa.c $(PKG_CONFIG_PATH=$dir/lib/pkgconfig pkg-config --cflags --libs libsecp256k1) -Wl,-rpath,"$dir/lib" && ./ecdsa
```
3. Check installation with CMake:
```shell
dir=$(mktemp -d)
build=$(mktemp -d)
cmake -B $build -DCMAKE_INSTALL_PREFIX=$dir && cmake --build $build && cmake --install $build && ls -RlAh $dir
gcc -o ecdsa examples/ecdsa.c -I $dir/include -L $dir/lib*/ -l secp256k1 -Wl,-rpath,"$dir/lib",-rpath,"$dir/lib64" && ./ecdsa
```
4. Use the [`check-abi.sh`](/tools/check-abi.sh) tool to verify that there are no unexpected ABI incompatibilities and that the version number and the release notes accurately reflect all potential ABI changes. To run this tool, the `abi-dumper` and `abi-compliance-checker` packages are required.
```shell
tools/check-abi.sh
```
## Regular release
1. Open a PR to the master branch with a commit (using message `"release: prepare for $MAJOR.$MINOR.$PATCH"`, for example) that
* finalizes the release notes in [CHANGELOG.md](../CHANGELOG.md) by
* adding a section for the release (make sure that the version number is a link to a diff between the previous and new version),
* removing the `[Unreleased]` section header,
* ensuring that the release notes are not missing entries (check the `needs-changelog` label on github), and
* including an entry for `### ABI Compatibility` if it doesn't exist,
* sets `_PKG_VERSION_IS_RELEASE` to `true` in `configure.ac`, and,
* if this is not a patch release,
* updates `_PKG_VERSION_*` and `_LIB_VERSION_*` in `configure.ac`, and
* updates `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_*` in `CMakeLists.txt`.
2. Perform the [sanity checks](#sanity-checks) on the PR branch.
3. After the PR is merged, tag the commit, and push the tag:
```
RELEASE_COMMIT=<merge commit of step 1>
git tag -s v$MAJOR.$MINOR.$PATCH -m "libsecp256k1 $MAJOR.$MINOR.$PATCH" $RELEASE_COMMIT
git push git@github.com:bitcoin-core/secp256k1.git v$MAJOR.$MINOR.$PATCH
```
4. Open a PR to the master branch with a commit (using message `"release cleanup: bump version after $MAJOR.$MINOR.$PATCH"`, for example) that
* sets `_PKG_VERSION_IS_RELEASE` to `false` and increments `_PKG_VERSION_PATCH` and `_LIB_VERSION_REVISION` in `configure.ac`,
* increments the `$PATCH` component of `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_REVISION` in `CMakeLists.txt`, and
* adds an `[Unreleased]` section header to the [CHANGELOG.md](../CHANGELOG.md).
If other maintainers are not present to approve the PR, it can be merged without ACKs.
5. Create a new GitHub release with a link to the corresponding entry in [CHANGELOG.md](../CHANGELOG.md).
6. Send an announcement email to the bitcoin-dev mailing list.
## Maintenance release
Note that bug fixes need to be backported only to releases for which no compatible release without the bug exists.
1. If there's no maintenance branch `$MAJOR.$MINOR`, create one:
```
git checkout -b $MAJOR.$MINOR v$MAJOR.$MINOR.$((PATCH - 1))
git push git@github.com:bitcoin-core/secp256k1.git $MAJOR.$MINOR
```
2. Open a pull request to the `$MAJOR.$MINOR` branch that
* includes the bug fixes,
* finalizes the release notes similar to a regular release,
* increments `_PKG_VERSION_PATCH` and `_LIB_VERSION_REVISION` in `configure.ac`
and the `$PATCH` component of `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_REVISION` in `CMakeLists.txt`
(with commit message `"release: bump versions for $MAJOR.$MINOR.$PATCH"`, for example).
3. Perform the [sanity checks](#sanity-checks) on the PR branch.
4. After the PRs are merged, update the release branch, tag the commit, and push the tag:
```
git checkout $MAJOR.$MINOR && git pull
git tag -s v$MAJOR.$MINOR.$PATCH -m "libsecp256k1 $MAJOR.$MINOR.$PATCH"
git push git@github.com:bitcoin-core/secp256k1.git v$MAJOR.$MINOR.$PATCH
```
6. Create a new GitHub release with a link to the corresponding entry in [CHANGELOG.md](../CHANGELOG.md).
7. Send an announcement email to the bitcoin-dev mailing list.
8. Open PR to the master branch that includes a commit (with commit message `"release notes: add $MAJOR.$MINOR.$PATCH"`, for example) that adds release notes to [CHANGELOG.md](../CHANGELOG.md).

View File

@@ -1,819 +0,0 @@
# The safegcd implementation in libsecp256k1 explained
This document explains the modular inverse and Jacobi symbol implementations in the `src/modinv*.h` files.
It is based on the paper
["Fast constant-time gcd computation and modular inversion"](https://gcd.cr.yp.to/papers.html#safegcd)
by Daniel J. Bernstein and Bo-Yin Yang. The references below are for the Date: 2019.04.13 version.
The actual implementation is in C of course, but for demonstration purposes Python3 is used here.
Most implementation aspects and optimizations are explained, except those that depend on the specific
number representation used in the C code.
## 1. Computing the Greatest Common Divisor (GCD) using divsteps
The algorithm from the paper (section 11), at a very high level, is this:
```python
def gcd(f, g):
"""Compute the GCD of an odd integer f and another integer g."""
assert f & 1 # require f to be odd
delta = 1 # additional state variable
while g != 0:
assert f & 1 # f will be odd in every iteration
if delta > 0 and g & 1:
delta, f, g = 1 - delta, g, (g - f) // 2
elif g & 1:
delta, f, g = 1 + delta, f, (g + f) // 2
else:
delta, f, g = 1 + delta, f, (g ) // 2
return abs(f)
```
It computes the greatest common divisor of an odd integer *f* and any integer *g*. Its inner loop
keeps rewriting the variables *f* and *g* alongside a state variable *&delta;* that starts at *1*, until
*g=0* is reached. At that point, *|f|* gives the GCD. Each of the transitions in the loop is called a
"division step" (referred to as divstep in what follows).
For example, *gcd(21, 14)* would be computed as:
- Start with *&delta;=1 f=21 g=14*
- Take the third branch: *&delta;=2 f=21 g=7*
- Take the first branch: *&delta;=-1 f=7 g=-7*
- Take the second branch: *&delta;=0 f=7 g=0*
- The answer *|f| = 7*.
Why it works:
- Divsteps can be decomposed into two steps (see paragraph 8.2 in the paper):
- (a) If *g* is odd, replace *(f,g)* with *(g,g-f)* or (f,g+f), resulting in an even *g*.
- (b) Replace *(f,g)* with *(f,g/2)* (where *g* is guaranteed to be even).
- Neither of those two operations change the GCD:
- For (a), assume *gcd(f,g)=c*, then it must be the case that *f=a&thinsp;c* and *g=b&thinsp;c* for some integers *a*
and *b*. As *(g,g-f)=(b&thinsp;c,(b-a)c)* and *(f,f+g)=(a&thinsp;c,(a+b)c)*, the result clearly still has
common factor *c*. Reasoning in the other direction shows that no common factor can be added by
doing so either.
- For (b), we know that *f* is odd, so *gcd(f,g)* clearly has no factor *2*, and we can remove
it from *g*.
- The algorithm will eventually converge to *g=0*. This is proven in the paper (see theorem G.3).
- It follows that eventually we find a final value *f'* for which *gcd(f,g) = gcd(f',0)*. As the
gcd of *f'* and *0* is *|f'|* by definition, that is our answer.
Compared to more [traditional GCD algorithms](https://en.wikipedia.org/wiki/Euclidean_algorithm), this one has the property of only ever looking at
the low-order bits of the variables to decide the next steps, and being easy to make
constant-time (in more low-level languages than Python). The *&delta;* parameter is necessary to
guide the algorithm towards shrinking the numbers' magnitudes without explicitly needing to look
at high order bits.
Properties that will become important later:
- Performing more divsteps than needed is not a problem, as *f* does not change anymore after *g=0*.
- Only even numbers are divided by *2*. This means that when reasoning about it algebraically we
do not need to worry about rounding.
- At every point during the algorithm's execution the next *N* steps only depend on the bottom *N*
bits of *f* and *g*, and on *&delta;*.
## 2. From GCDs to modular inverses
We want an algorithm to compute the inverse *a* of *x* modulo *M*, i.e. the number a such that *a&thinsp;x=1
mod M*. This inverse only exists if the GCD of *x* and *M* is *1*, but that is always the case if *M* is
prime and *0 < x < M*. In what follows, assume that the modular inverse exists.
It turns out this inverse can be computed as a side effect of computing the GCD by keeping track
of how the internal variables can be written as linear combinations of the inputs at every step
(see the [extended Euclidean algorithm](https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm)).
Since the GCD is *1*, such an algorithm will compute numbers *a* and *b* such that a&thinsp;x + b&thinsp;M = 1*.
Taking that expression *mod M* gives *a&thinsp;x mod M = 1*, and we see that *a* is the modular inverse of *x
mod M*.
A similar approach can be used to calculate modular inverses using the divsteps-based GCD
algorithm shown above, if the modulus *M* is odd. To do so, compute *gcd(f=M,g=x)*, while keeping
track of extra variables *d* and *e*, for which at every step *d = f/x (mod M)* and *e = g/x (mod M)*.
*f/x* here means the number which multiplied with *x* gives *f mod M*. As *f* and *g* are initialized to *M*
and *x* respectively, *d* and *e* just start off being *0* (*M/x mod M = 0/x mod M = 0*) and *1* (*x/x mod M
= 1*).
```python
def div2(M, x):
"""Helper routine to compute x/2 mod M (where M is odd)."""
assert M & 1
if x & 1: # If x is odd, make it even by adding M.
x += M
# x must be even now, so a clean division by 2 is possible.
return x // 2
def modinv(M, x):
"""Compute the inverse of x mod M (given that it exists, and M is odd)."""
assert M & 1
delta, f, g, d, e = 1, M, x, 0, 1
while g != 0:
# Note that while division by two for f and g is only ever done on even inputs, this is
# not true for d and e, so we need the div2 helper function.
if delta > 0 and g & 1:
delta, f, g, d, e = 1 - delta, g, (g - f) // 2, e, div2(M, e - d)
elif g & 1:
delta, f, g, d, e = 1 + delta, f, (g + f) // 2, d, div2(M, e + d)
else:
delta, f, g, d, e = 1 + delta, f, (g ) // 2, d, div2(M, e )
# Verify that the invariants d=f/x mod M, e=g/x mod M are maintained.
assert f % M == (d * x) % M
assert g % M == (e * x) % M
assert f == 1 or f == -1 # |f| is the GCD, it must be 1
# Because of invariant d = f/x (mod M), 1/x = d/f (mod M). As |f|=1, d/f = d*f.
return (d * f) % M
```
Also note that this approach to track *d* and *e* throughout the computation to determine the inverse
is different from the paper. There (see paragraph 12.1 in the paper) a transition matrix for the
entire computation is determined (see section 3 below) and the inverse is computed from that.
The approach here avoids the need for 2x2 matrix multiplications of various sizes, and appears to
be faster at the level of optimization we're able to do in C.
## 3. Batching multiple divsteps
Every divstep can be expressed as a matrix multiplication, applying a transition matrix *(1/2 t)*
to both vectors *[f, g]* and *[d, e]* (see paragraph 8.1 in the paper):
```
t = [ u, v ]
[ q, r ]
[ out_f ] = (1/2 * t) * [ in_f ]
[ out_g ] = [ in_g ]
[ out_d ] = (1/2 * t) * [ in_d ] (mod M)
[ out_e ] [ in_e ]
```
where *(u, v, q, r)* is *(0, 2, -1, 1)*, *(2, 0, 1, 1)*, or *(2, 0, 0, 1)*, depending on which branch is
taken. As above, the resulting *f* and *g* are always integers.
Performing multiple divsteps corresponds to a multiplication with the product of all the
individual divsteps' transition matrices. As each transition matrix consists of integers
divided by *2*, the product of these matrices will consist of integers divided by *2<sup>N</sup>* (see also
theorem 9.2 in the paper). These divisions are expensive when updating *d* and *e*, so we delay
them: we compute the integer coefficients of the combined transition matrix scaled by *2<sup>N</sup>*, and
do one division by *2<sup>N</sup>* as a final step:
```python
def divsteps_n_matrix(delta, f, g):
"""Compute delta and transition matrix t after N divsteps (multiplied by 2^N)."""
u, v, q, r = 1, 0, 0, 1 # start with identity matrix
for _ in range(N):
if delta > 0 and g & 1:
delta, f, g, u, v, q, r = 1 - delta, g, (g - f) // 2, 2*q, 2*r, q-u, r-v
elif g & 1:
delta, f, g, u, v, q, r = 1 + delta, f, (g + f) // 2, 2*u, 2*v, q+u, r+v
else:
delta, f, g, u, v, q, r = 1 + delta, f, (g ) // 2, 2*u, 2*v, q , r
return delta, (u, v, q, r)
```
As the branches in the divsteps are completely determined by the bottom *N* bits of *f* and *g*, this
function to compute the transition matrix only needs to see those bottom bits. Furthermore all
intermediate results and outputs fit in *(N+1)*-bit numbers (unsigned for *f* and *g*; signed for *u*, *v*,
*q*, and *r*) (see also paragraph 8.3 in the paper). This means that an implementation using 64-bit
integers could set *N=62* and compute the full transition matrix for 62 steps at once without any
big integer arithmetic at all. This is the reason why this algorithm is efficient: it only needs
to update the full-size *f*, *g*, *d*, and *e* numbers once every *N* steps.
We still need functions to compute:
```
[ out_f ] = (1/2^N * [ u, v ]) * [ in_f ]
[ out_g ] ( [ q, r ]) [ in_g ]
[ out_d ] = (1/2^N * [ u, v ]) * [ in_d ] (mod M)
[ out_e ] ( [ q, r ]) [ in_e ]
```
Because the divsteps transformation only ever divides even numbers by two, the result of *t&thinsp;[f,g]* is always even. When *t* is a composition of *N* divsteps, it follows that the resulting *f*
and *g* will be multiple of *2<sup>N</sup>*, and division by *2<sup>N</sup>* is simply shifting them down:
```python
def update_fg(f, g, t):
"""Multiply matrix t/2^N with [f, g]."""
u, v, q, r = t
cf, cg = u*f + v*g, q*f + r*g
# (t / 2^N) should cleanly apply to [f,g] so the result of t*[f,g] should have N zero
# bottom bits.
assert cf % 2**N == 0
assert cg % 2**N == 0
return cf >> N, cg >> N
```
The same is not true for *d* and *e*, and we need an equivalent of the `div2` function for division by *2<sup>N</sup> mod M*.
This is easy if we have precomputed *1/M mod 2<sup>N</sup>* (which always exists for odd *M*):
```python
def div2n(M, Mi, x):
"""Compute x/2^N mod M, given Mi = 1/M mod 2^N."""
assert (M * Mi) % 2**N == 1
# Find a factor m such that m*M has the same bottom N bits as x. We want:
# (m * M) mod 2^N = x mod 2^N
# <=> m mod 2^N = (x / M) mod 2^N
# <=> m mod 2^N = (x * Mi) mod 2^N
m = (Mi * x) % 2**N
# Subtract that multiple from x, cancelling its bottom N bits.
x -= m * M
# Now a clean division by 2^N is possible.
assert x % 2**N == 0
return (x >> N) % M
def update_de(d, e, t, M, Mi):
"""Multiply matrix t/2^N with [d, e], modulo M."""
u, v, q, r = t
cd, ce = u*d + v*e, q*d + r*e
return div2n(M, Mi, cd), div2n(M, Mi, ce)
```
With all of those, we can write a version of `modinv` that performs *N* divsteps at once:
```python3
def modinv(M, Mi, x):
"""Compute the modular inverse of x mod M, given Mi=1/M mod 2^N."""
assert M & 1
delta, f, g, d, e = 1, M, x, 0, 1
while g != 0:
# Compute the delta and transition matrix t for the next N divsteps (this only needs
# (N+1)-bit signed integer arithmetic).
delta, t = divsteps_n_matrix(delta, f % 2**N, g % 2**N)
# Apply the transition matrix t to [f, g]:
f, g = update_fg(f, g, t)
# Apply the transition matrix t to [d, e]:
d, e = update_de(d, e, t, M, Mi)
return (d * f) % M
```
This means that in practice we'll always perform a multiple of *N* divsteps. This is not a problem
because once *g=0*, further divsteps do not affect *f*, *g*, *d*, or *e* anymore (only *&delta;* keeps
increasing). For variable time code such excess iterations will be mostly optimized away in later
sections.
## 4. Avoiding modulus operations
So far, there are two places where we compute a remainder of big numbers modulo *M*: at the end of
`div2n` in every `update_de`, and at the very end of `modinv` after potentially negating *d* due to the
sign of *f*. These are relatively expensive operations when done generically.
To deal with the modulus operation in `div2n`, we simply stop requiring *d* and *e* to be in range
*[0,M)* all the time. Let's start by inlining `div2n` into `update_de`, and dropping the modulus
operation at the end:
```python
def update_de(d, e, t, M, Mi):
"""Multiply matrix t/2^N with [d, e] mod M, given Mi=1/M mod 2^N."""
u, v, q, r = t
cd, ce = u*d + v*e, q*d + r*e
# Cancel out bottom N bits of cd and ce.
md = -((Mi * cd) % 2**N)
me = -((Mi * ce) % 2**N)
cd += md * M
ce += me * M
# And cleanly divide by 2**N.
return cd >> N, ce >> N
```
Let's look at bounds on the ranges of these numbers. It can be shown that *|u|+|v|* and *|q|+|r|*
never exceed *2<sup>N</sup>* (see paragraph 8.3 in the paper), and thus a multiplication with *t* will have
outputs whose absolute values are at most *2<sup>N</sup>* times the maximum absolute input value. In case the
inputs *d* and *e* are in *(-M,M)*, which is certainly true for the initial values *d=0* and *e=1* assuming
*M > 1*, the multiplication results in numbers in range *(-2<sup>N</sup>M,2<sup>N</sup>M)*. Subtracting less than *2<sup>N</sup>*
times *M* to cancel out *N* bits brings that up to *(-2<sup>N+1</sup>M,2<sup>N</sup>M)*, and
dividing by *2<sup>N</sup>* at the end takes it to *(-2M,M)*. Another application of `update_de` would take that
to *(-3M,2M)*, and so forth. This progressive expansion of the variables' ranges can be
counteracted by incrementing *d* and *e* by *M* whenever they're negative:
```python
...
if d < 0:
d += M
if e < 0:
e += M
cd, ce = u*d + v*e, q*d + r*e
# Cancel out bottom N bits of cd and ce.
...
```
With inputs in *(-2M,M)*, they will first be shifted into range *(-M,M)*, which means that the
output will again be in *(-2M,M)*, and this remains the case regardless of how many `update_de`
invocations there are. In what follows, we will try to make this more efficient.
Note that increasing *d* by *M* is equal to incrementing *cd* by *u&thinsp;M* and *ce* by *q&thinsp;M*. Similarly,
increasing *e* by *M* is equal to incrementing *cd* by *v&thinsp;M* and *ce* by *r&thinsp;M*. So we could instead write:
```python
...
cd, ce = u*d + v*e, q*d + r*e
# Perform the equivalent of incrementing d, e by M when they're negative.
if d < 0:
cd += u*M
ce += q*M
if e < 0:
cd += v*M
ce += r*M
# Cancel out bottom N bits of cd and ce.
md = -((Mi * cd) % 2**N)
me = -((Mi * ce) % 2**N)
cd += md * M
ce += me * M
...
```
Now note that we have two steps of corrections to *cd* and *ce* that add multiples of *M*: this
increment, and the decrement that cancels out bottom bits. The second one depends on the first
one, but they can still be efficiently combined by only computing the bottom bits of *cd* and *ce*
at first, and using that to compute the final *md*, *me* values:
```python
def update_de(d, e, t, M, Mi):
"""Multiply matrix t/2^N with [d, e], modulo M."""
u, v, q, r = t
md, me = 0, 0
# Compute what multiples of M to add to cd and ce.
if d < 0:
md += u
me += q
if e < 0:
md += v
me += r
# Compute bottom N bits of t*[d,e] + M*[md,me].
cd, ce = (u*d + v*e + md*M) % 2**N, (q*d + r*e + me*M) % 2**N
# Correct md and me such that the bottom N bits of t*[d,e] + M*[md,me] are zero.
md -= (Mi * cd) % 2**N
me -= (Mi * ce) % 2**N
# Do the full computation.
cd, ce = u*d + v*e + md*M, q*d + r*e + me*M
# And cleanly divide by 2**N.
return cd >> N, ce >> N
```
One last optimization: we can avoid the *md&thinsp;M* and *me&thinsp;M* multiplications in the bottom bits of *cd*
and *ce* by moving them to the *md* and *me* correction:
```python
...
# Compute bottom N bits of t*[d,e].
cd, ce = (u*d + v*e) % 2**N, (q*d + r*e) % 2**N
# Correct md and me such that the bottom N bits of t*[d,e]+M*[md,me] are zero.
# Note that this is not the same as {md = (-Mi * cd) % 2**N} etc. That would also result in N
# zero bottom bits, but isn't guaranteed to be a reduction of [0,2^N) compared to the
# previous md and me values, and thus would violate our bounds analysis.
md -= (Mi*cd + md) % 2**N
me -= (Mi*ce + me) % 2**N
...
```
The resulting function takes *d* and *e* in range *(-2M,M)* as inputs, and outputs values in the same
range. That also means that the *d* value at the end of `modinv` will be in that range, while we want
a result in *[0,M)*. To do that, we need a normalization function. It's easy to integrate the
conditional negation of *d* (based on the sign of *f*) into it as well:
```python
def normalize(sign, v, M):
"""Compute sign*v mod M, where v is in range (-2*M,M); output in [0,M)."""
assert sign == 1 or sign == -1
# v in (-2*M,M)
if v < 0:
v += M
# v in (-M,M). Now multiply v with sign (which can only be 1 or -1).
if sign == -1:
v = -v
# v in (-M,M)
if v < 0:
v += M
# v in [0,M)
return v
```
And calling it in `modinv` is simply:
```python
...
return normalize(f, d, M)
```
## 5. Constant-time operation
The primary selling point of the algorithm is fast constant-time operation. What code flow still
depends on the input data so far?
- the number of iterations of the while *g &ne; 0* loop in `modinv`
- the branches inside `divsteps_n_matrix`
- the sign checks in `update_de`
- the sign checks in `normalize`
To make the while loop in `modinv` constant time it can be replaced with a constant number of
iterations. The paper proves (Theorem 11.2) that *741* divsteps are sufficient for any *256*-bit
inputs, and [safegcd-bounds](https://github.com/sipa/safegcd-bounds) shows that the slightly better bound *724* is
sufficient even. Given that every loop iteration performs *N* divsteps, it will run a total of
*&lceil;724/N&rceil;* times.
To deal with the branches in `divsteps_n_matrix` we will replace them with constant-time bitwise
operations (and hope the C compiler isn't smart enough to turn them back into branches; see
`ctime_tests.c` for automated tests that this isn't the case). To do so, observe that a
divstep can be written instead as (compare to the inner loop of `gcd` in section 1).
```python
x = -f if delta > 0 else f # set x equal to (input) -f or f
if g & 1:
g += x # set g to (input) g-f or g+f
if delta > 0:
delta = -delta
f += g # set f to (input) g (note that g was set to g-f before)
delta += 1
g >>= 1
```
To convert the above to bitwise operations, we rely on a trick to negate conditionally: per the
definition of negative numbers in two's complement, (*-v == ~v + 1*) holds for every number *v*. As
*-1* in two's complement is all *1* bits, bitflipping can be expressed as xor with *-1*. It follows
that *-v == (v ^ -1) - (-1)*. Thus, if we have a variable *c* that takes on values *0* or *-1*, then
*(v ^ c) - c* is *v* if *c=0* and *-v* if *c=-1*.
Using this we can write:
```python
x = -f if delta > 0 else f
```
in constant-time form as:
```python
c1 = (-delta) >> 63
# Conditionally negate f based on c1:
x = (f ^ c1) - c1
```
To use that trick, we need a helper mask variable *c1* that resolves the condition *&delta;>0* to *-1*
(if true) or *0* (if false). We compute *c1* using right shifting, which is equivalent to dividing by
the specified power of *2* and rounding down (in Python, and also in C under the assumption of a typical two's complement system; see
`assumptions.h` for tests that this is the case). Right shifting by *63* thus maps all
numbers in range *[-2<sup>63</sup>,0)* to *-1*, and numbers in range *[0,2<sup>63</sup>)* to *0*.
Using the facts that *x&0=0* and *x&(-1)=x* (on two's complement systems again), we can write:
```python
if g & 1:
g += x
```
as:
```python
# Compute c2=0 if g is even and c2=-1 if g is odd.
c2 = -(g & 1)
# This masks out x if g is even, and leaves x be if g is odd.
g += x & c2
```
Using the conditional negation trick again we can write:
```python
if g & 1:
if delta > 0:
delta = -delta
```
as:
```python
# Compute c3=-1 if g is odd and delta>0, and 0 otherwise.
c3 = c1 & c2
# Conditionally negate delta based on c3:
delta = (delta ^ c3) - c3
```
Finally:
```python
if g & 1:
if delta > 0:
f += g
```
becomes:
```python
f += g & c3
```
It turns out that this can be implemented more efficiently by applying the substitution
*&eta;=-&delta;*. In this representation, negating *&delta;* corresponds to negating *&eta;*, and incrementing
*&delta;* corresponds to decrementing *&eta;*. This allows us to remove the negation in the *c1*
computation:
```python
# Compute a mask c1 for eta < 0, and compute the conditional negation x of f:
c1 = eta >> 63
x = (f ^ c1) - c1
# Compute a mask c2 for odd g, and conditionally add x to g:
c2 = -(g & 1)
g += x & c2
# Compute a mask c for (eta < 0) and odd (input) g, and use it to conditionally negate eta,
# and add g to f:
c3 = c1 & c2
eta = (eta ^ c3) - c3
f += g & c3
# Incrementing delta corresponds to decrementing eta.
eta -= 1
g >>= 1
```
A variant of divsteps with better worst-case performance can be used instead: starting *&delta;* at
*1/2* instead of *1*. This reduces the worst case number of iterations to *590* for *256*-bit inputs
(which can be shown using convex hull analysis). In this case, the substitution *&zeta;=-(&delta;+1/2)*
is used instead to keep the variable integral. Incrementing *&delta;* by *1* still translates to
decrementing *&zeta;* by *1*, but negating *&delta;* now corresponds to going from *&zeta;* to *-(&zeta;+1)*, or
*~&zeta;*. Doing that conditionally based on *c3* is simply:
```python
...
c3 = c1 & c2
zeta ^= c3
...
```
By replacing the loop in `divsteps_n_matrix` with a variant of the divstep code above (extended to
also apply all *f* operations to *u*, *v* and all *g* operations to *q*, *r*), a constant-time version of
`divsteps_n_matrix` is obtained. The full code will be in section 7.
These bit fiddling tricks can also be used to make the conditional negations and additions in
`update_de` and `normalize` constant-time.
## 6. Variable-time optimizations
In section 5, we modified the `divsteps_n_matrix` function (and a few others) to be constant time.
Constant time operations are only necessary when computing modular inverses of secret data. In
other cases, it slows down calculations unnecessarily. In this section, we will construct a
faster non-constant time `divsteps_n_matrix` function.
To do so, first consider yet another way of writing the inner loop of divstep operations in
`gcd` from section 1. This decomposition is also explained in the paper in section 8.2. We use
the original version with initial *&delta;=1* and *&eta;=-&delta;* here.
```python
for _ in range(N):
if g & 1 and eta < 0:
eta, f, g = -eta, g, -f
if g & 1:
g += f
eta -= 1
g >>= 1
```
Whenever *g* is even, the loop only shifts *g* down and decreases *&eta;*. When *g* ends in multiple zero
bits, these iterations can be consolidated into one step. This requires counting the bottom zero
bits efficiently, which is possible on most platforms; it is abstracted here as the function
`count_trailing_zeros`.
```python
def count_trailing_zeros(v):
"""
When v is zero, consider all N zero bits as "trailing".
For a non-zero value v, find z such that v=(d<<z) for some odd d.
"""
if v == 0:
return N
else:
return (v & -v).bit_length() - 1
i = N # divsteps left to do
while True:
# Get rid of all bottom zeros at once. In the first iteration, g may be odd and the following
# lines have no effect (until "if eta < 0").
zeros = min(i, count_trailing_zeros(g))
eta -= zeros
g >>= zeros
i -= zeros
if i == 0:
break
# We know g is odd now
if eta < 0:
eta, f, g = -eta, g, -f
g += f
# g is even now, and the eta decrement and g shift will happen in the next loop.
```
We can now remove multiple bottom *0* bits from *g* at once, but still need a full iteration whenever
there is a bottom *1* bit. In what follows, we will get rid of multiple *1* bits simultaneously as
well.
Observe that as long as *&eta; &geq; 0*, the loop does not modify *f*. Instead, it cancels out bottom
bits of *g* and shifts them out, and decreases *&eta;* and *i* accordingly - interrupting only when *&eta;*
becomes negative, or when *i* reaches *0*. Combined, this is equivalent to adding a multiple of *f* to
*g* to cancel out multiple bottom bits, and then shifting them out.
It is easy to find what that multiple is: we want a number *w* such that *g+w&thinsp;f* has a few bottom
zero bits. If that number of bits is *L*, we want *g+w&thinsp;f mod 2<sup>L</sup> = 0*, or *w = -g/f mod 2<sup>L</sup>*. Since *f*
is odd, such a *w* exists for any *L*. *L* cannot be more than *i* steps (as we'd finish the loop before
doing more) or more than *&eta;+1* steps (as we'd run `eta, f, g = -eta, g, -f` at that point), but
apart from that, we're only limited by the complexity of computing *w*.
This code demonstrates how to cancel up to 4 bits per step:
```python
NEGINV16 = [15, 5, 3, 9, 7, 13, 11, 1] # NEGINV16[n//2] = (-n)^-1 mod 16, for odd n
i = N
while True:
zeros = min(i, count_trailing_zeros(g))
eta -= zeros
g >>= zeros
i -= zeros
if i == 0:
break
# We know g is odd now
if eta < 0:
eta, f, g = -eta, g, -f
# Compute limit on number of bits to cancel
limit = min(min(eta + 1, i), 4)
# Compute w = -g/f mod 2**limit, using the table value for -1/f mod 2**4. Note that f is
# always odd, so its inverse modulo a power of two always exists.
w = (g * NEGINV16[(f & 15) // 2]) % (2**limit)
# As w = -g/f mod (2**limit), g+w*f mod 2**limit = 0 mod 2**limit.
g += w * f
assert g % (2**limit) == 0
# The next iteration will now shift out at least limit bottom zero bits from g.
```
By using a bigger table more bits can be cancelled at once. The table can also be implemented
as a formula. Several formulas are known for computing modular inverses modulo powers of two;
some can be found in Hacker's Delight second edition by Henry S. Warren, Jr. pages 245-247.
Here we need the negated modular inverse, which is a simple transformation of those:
- Instead of a 3-bit table:
- *-f* or *f ^ 6*
- Instead of a 4-bit table:
- *1 - f(f + 1)*
- *-(f + (((f + 1) & 4) << 1))*
- For larger tables the following technique can be used: if *w=-1/f mod 2<sup>L</sup>*, then *w(w&thinsp;f+2)* is
*-1/f mod 2<sup>2L</sup>*. This allows extending the previous formulas (or tables). In particular we
have this 6-bit function (based on the 3-bit function above):
- *f(f<sup>2</sup> - 2)*
This loop, again extended to also handle *u*, *v*, *q*, and *r* alongside *f* and *g*, placed in
`divsteps_n_matrix`, gives a significantly faster, but non-constant time version.
## 7. Final Python version
All together we need the following functions:
- A way to compute the transition matrix in constant time, using the `divsteps_n_matrix` function
from section 2, but with its loop replaced by a variant of the constant-time divstep from
section 5, extended to handle *u*, *v*, *q*, *r*:
```python
def divsteps_n_matrix(zeta, f, g):
"""Compute zeta and transition matrix t after N divsteps (multiplied by 2^N)."""
u, v, q, r = 1, 0, 0, 1 # start with identity matrix
for _ in range(N):
c1 = zeta >> 63
# Compute x, y, z as conditionally-negated versions of f, u, v.
x, y, z = (f ^ c1) - c1, (u ^ c1) - c1, (v ^ c1) - c1
c2 = -(g & 1)
# Conditionally add x, y, z to g, q, r.
g, q, r = g + (x & c2), q + (y & c2), r + (z & c2)
c1 &= c2 # reusing c1 here for the earlier c3 variable
zeta = (zeta ^ c1) - 1 # inlining the unconditional zeta decrement here
# Conditionally add g, q, r to f, u, v.
f, u, v = f + (g & c1), u + (q & c1), v + (r & c1)
# When shifting g down, don't shift q, r, as we construct a transition matrix multiplied
# by 2^N. Instead, shift f's coefficients u and v up.
g, u, v = g >> 1, u << 1, v << 1
return zeta, (u, v, q, r)
```
- The functions to update *f* and *g*, and *d* and *e*, from section 2 and section 4, with the constant-time
changes to `update_de` from section 5:
```python
def update_fg(f, g, t):
"""Multiply matrix t/2^N with [f, g]."""
u, v, q, r = t
cf, cg = u*f + v*g, q*f + r*g
return cf >> N, cg >> N
def update_de(d, e, t, M, Mi):
"""Multiply matrix t/2^N with [d, e], modulo M."""
u, v, q, r = t
d_sign, e_sign = d >> 257, e >> 257
md, me = (u & d_sign) + (v & e_sign), (q & d_sign) + (r & e_sign)
cd, ce = (u*d + v*e) % 2**N, (q*d + r*e) % 2**N
md -= (Mi*cd + md) % 2**N
me -= (Mi*ce + me) % 2**N
cd, ce = u*d + v*e + M*md, q*d + r*e + M*me
return cd >> N, ce >> N
```
- The `normalize` function from section 4, made constant time as well:
```python
def normalize(sign, v, M):
"""Compute sign*v mod M, where v in (-2*M,M); output in [0,M)."""
v_sign = v >> 257
# Conditionally add M to v.
v += M & v_sign
c = (sign - 1) >> 1
# Conditionally negate v.
v = (v ^ c) - c
v_sign = v >> 257
# Conditionally add M to v again.
v += M & v_sign
return v
```
- And finally the `modinv` function too, adapted to use *&zeta;* instead of *&delta;*, and using the fixed
iteration count from section 5:
```python
def modinv(M, Mi, x):
"""Compute the modular inverse of x mod M, given Mi=1/M mod 2^N."""
zeta, f, g, d, e = -1, M, x, 0, 1
for _ in range((590 + N - 1) // N):
zeta, t = divsteps_n_matrix(zeta, f % 2**N, g % 2**N)
f, g = update_fg(f, g, t)
d, e = update_de(d, e, t, M, Mi)
return normalize(f, d, M)
```
- To get a variable time version, replace the `divsteps_n_matrix` function with one that uses the
divsteps loop from section 5, and a `modinv` version that calls it without the fixed iteration
count:
```python
NEGINV16 = [15, 5, 3, 9, 7, 13, 11, 1] # NEGINV16[n//2] = (-n)^-1 mod 16, for odd n
def divsteps_n_matrix_var(eta, f, g):
"""Compute eta and transition matrix t after N divsteps (multiplied by 2^N)."""
u, v, q, r = 1, 0, 0, 1
i = N
while True:
zeros = min(i, count_trailing_zeros(g))
eta, i = eta - zeros, i - zeros
g, u, v = g >> zeros, u << zeros, v << zeros
if i == 0:
break
if eta < 0:
eta, f, u, v, g, q, r = -eta, g, q, r, -f, -u, -v
limit = min(min(eta + 1, i), 4)
w = (g * NEGINV16[(f & 15) // 2]) % (2**limit)
g, q, r = g + w*f, q + w*u, r + w*v
return eta, (u, v, q, r)
def modinv_var(M, Mi, x):
"""Compute the modular inverse of x mod M, given Mi = 1/M mod 2^N."""
eta, f, g, d, e = -1, M, x, 0, 1
while g != 0:
eta, t = divsteps_n_matrix_var(eta, f % 2**N, g % 2**N)
f, g = update_fg(f, g, t)
d, e = update_de(d, e, t, M, Mi)
return normalize(f, d, Mi)
```
## 8. From GCDs to Jacobi symbol
We can also use a similar approach to calculate Jacobi symbol *(x | M)* by keeping track of an
extra variable *j*, for which at every step *(x | M) = j (g | f)*. As we update *f* and *g*, we
make corresponding updates to *j* using
[properties of the Jacobi symbol](https://en.wikipedia.org/wiki/Jacobi_symbol#Properties):
* *((g/2) | f)* is either *(g | f)* or *-(g | f)*, depending on the value of *f mod 8* (negating if it's *3* or *5*).
* *(f | g)* is either *(g | f)* or *-(g | f)*, depending on *f mod 4* and *g mod 4* (negating if both are *3*).
These updates depend only on the values of *f* and *g* modulo *4* or *8*, and can thus be applied
very quickly, as long as we keep track of a few additional bits of *f* and *g*. Overall, this
calculation is slightly simpler than the one for the modular inverse because we no longer need to
keep track of *d* and *e*.
However, one difficulty of this approach is that the Jacobi symbol *(a | n)* is only defined for
positive odd integers *n*, whereas in the original safegcd algorithm, *f, g* can take negative
values. We resolve this by using the following modified steps:
```python
# Before
if delta > 0 and g & 1:
delta, f, g = 1 - delta, g, (g - f) // 2
# After
if delta > 0 and g & 1:
delta, f, g = 1 - delta, g, (g + f) // 2
```
The algorithm is still correct, since the changed divstep, called a "posdivstep" (see section 8.4
and E.5 in the paper) preserves *gcd(f, g)*. However, there's no proof that the modified algorithm
will converge. The justification for posdivsteps is completely empirical: in practice, it appears
that the vast majority of nonzero inputs converge to *f=g=gcd(f<sub>0</sub>, g<sub>0</sub>)* in a
number of steps proportional to their logarithm.
Note that:
- We require inputs to satisfy *gcd(x, M) = 1*, as otherwise *f=1* is not reached.
- We require inputs *x &neq; 0*, because applying posdivstep with *g=0* has no effect.
- We need to update the termination condition from *g=0* to *f=1*.
We account for the possibility of nonconvergence by only performing a bounded number of
posdivsteps, and then falling back to square-root based Jacobi calculation if a solution has not
yet been found.
The optimizations in sections 3-7 above are described in the context of the original divsteps, but
in the C implementation we also adapt most of them (not including "avoiding modulus operations",
since it's not necessary to track *d, e*, and "constant-time operation", since we never calculate
Jacobi symbols for secret data) to the posdivsteps version.

View File

@@ -1,31 +0,0 @@
function(add_example name)
set(target_name ${name}_example)
add_executable(${target_name} ${name}.c)
target_include_directories(${target_name} PRIVATE
${PROJECT_SOURCE_DIR}/include
)
target_link_libraries(${target_name}
secp256k1
$<$<PLATFORM_ID:Windows>:bcrypt>
)
set(test_name ${name}_example)
add_test(NAME secp256k1_${test_name} COMMAND ${target_name})
endfunction()
add_example(ecdsa)
if(SECP256K1_ENABLE_MODULE_ECDH)
add_example(ecdh)
endif()
if(SECP256K1_ENABLE_MODULE_SCHNORRSIG)
add_example(schnorr)
endif()
if(SECP256K1_ENABLE_MODULE_ELLSWIFT)
add_example(ellswift)
endif()
if(SECP256K1_ENABLE_MODULE_MUSIG)
add_example(musig)
endif()

View File

@@ -1,121 +0,0 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.

View File

@@ -1,120 +0,0 @@
/*************************************************************************
* Written in 2020-2022 by Elichai Turkel *
* To the extent possible under law, the author(s) have dedicated all *
* copyright and related and neighboring rights to the software in this *
* file to the public domain worldwide. This software is distributed *
* without any warranty. For the CC0 Public Domain Dedication, see *
* EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
*************************************************************************/
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <secp256k1.h>
#include <secp256k1_ecdh.h>
#include "examples_util.h"
int main(void) {
unsigned char seckey1[32];
unsigned char seckey2[32];
unsigned char compressed_pubkey1[33];
unsigned char compressed_pubkey2[33];
unsigned char shared_secret1[32];
unsigned char shared_secret2[32];
unsigned char randomize[32];
int return_val;
size_t len;
secp256k1_pubkey pubkey1;
secp256k1_pubkey pubkey2;
/* Before we can call actual API functions, we need to create a "context". */
secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
if (!fill_random(randomize, sizeof(randomize))) {
printf("Failed to generate randomness\n");
return 1;
}
/* Randomizing the context is recommended to protect against side-channel
* leakage See `secp256k1_context_randomize` in secp256k1.h for more
* information about it. This should never fail. */
return_val = secp256k1_context_randomize(ctx, randomize);
assert(return_val);
/*** Key Generation ***/
if (!fill_random(seckey1, sizeof(seckey1)) || !fill_random(seckey2, sizeof(seckey2))) {
printf("Failed to generate randomness\n");
return 1;
}
/* If the secret key is zero or out of range (greater than secp256k1's
* order), we fail. Note that the probability of this occurring is negligible
* with a properly functioning random number generator. */
if (!secp256k1_ec_seckey_verify(ctx, seckey1) || !secp256k1_ec_seckey_verify(ctx, seckey2)) {
printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n");
return 1;
}
/* Public key creation using a valid context with a verified secret key should never fail */
return_val = secp256k1_ec_pubkey_create(ctx, &pubkey1, seckey1);
assert(return_val);
return_val = secp256k1_ec_pubkey_create(ctx, &pubkey2, seckey2);
assert(return_val);
/* Serialize pubkey1 in a compressed form (33 bytes), should always return 1 */
len = sizeof(compressed_pubkey1);
return_val = secp256k1_ec_pubkey_serialize(ctx, compressed_pubkey1, &len, &pubkey1, SECP256K1_EC_COMPRESSED);
assert(return_val);
/* Should be the same size as the size of the output, because we passed a 33 byte array. */
assert(len == sizeof(compressed_pubkey1));
/* Serialize pubkey2 in a compressed form (33 bytes) */
len = sizeof(compressed_pubkey2);
return_val = secp256k1_ec_pubkey_serialize(ctx, compressed_pubkey2, &len, &pubkey2, SECP256K1_EC_COMPRESSED);
assert(return_val);
/* Should be the same size as the size of the output, because we passed a 33 byte array. */
assert(len == sizeof(compressed_pubkey2));
/*** Creating the shared secret ***/
/* Perform ECDH with seckey1 and pubkey2. Should never fail with a verified
* seckey and valid pubkey */
return_val = secp256k1_ecdh(ctx, shared_secret1, &pubkey2, seckey1, NULL, NULL);
assert(return_val);
/* Perform ECDH with seckey2 and pubkey1. Should never fail with a verified
* seckey and valid pubkey */
return_val = secp256k1_ecdh(ctx, shared_secret2, &pubkey1, seckey2, NULL, NULL);
assert(return_val);
/* Both parties should end up with the same shared secret */
return_val = memcmp(shared_secret1, shared_secret2, sizeof(shared_secret1));
assert(return_val == 0);
printf("Secret Key1: ");
print_hex(seckey1, sizeof(seckey1));
printf("Compressed Pubkey1: ");
print_hex(compressed_pubkey1, sizeof(compressed_pubkey1));
printf("\nSecret Key2: ");
print_hex(seckey2, sizeof(seckey2));
printf("Compressed Pubkey2: ");
print_hex(compressed_pubkey2, sizeof(compressed_pubkey2));
printf("\nShared Secret: ");
print_hex(shared_secret1, sizeof(shared_secret1));
/* This will clear everything from the context and free the memory */
secp256k1_context_destroy(ctx);
/* It's best practice to try to clear secrets from memory after using them.
* This is done because some bugs can allow an attacker to leak memory, for
* example through "out of bounds" array access (see Heartbleed), or the OS
* swapping them to disk. Hence, we overwrite the secret key buffer with zeros.
*
* Here we are preventing these writes from being optimized out, as any good compiler
* will remove any writes that aren't used. */
secure_erase(seckey1, sizeof(seckey1));
secure_erase(seckey2, sizeof(seckey2));
secure_erase(shared_secret1, sizeof(shared_secret1));
secure_erase(shared_secret2, sizeof(shared_secret2));
return 0;
}

View File

@@ -1,137 +0,0 @@
/*************************************************************************
* Written in 2020-2022 by Elichai Turkel *
* To the extent possible under law, the author(s) have dedicated all *
* copyright and related and neighboring rights to the software in this *
* file to the public domain worldwide. This software is distributed *
* without any warranty. For the CC0 Public Domain Dedication, see *
* EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
*************************************************************************/
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <secp256k1.h>
#include "examples_util.h"
int main(void) {
/* Instead of signing the message directly, we must sign a 32-byte hash.
* Here the message is "Hello, world!" and the hash function was SHA-256.
* An actual implementation should just call SHA-256, but this example
* hardcodes the output to avoid depending on an additional library.
* See https://bitcoin.stackexchange.com/questions/81115/if-someone-wanted-to-pretend-to-be-satoshi-by-posting-a-fake-signature-to-defrau/81116#81116 */
unsigned char msg_hash[32] = {
0x31, 0x5F, 0x5B, 0xDB, 0x76, 0xD0, 0x78, 0xC4,
0x3B, 0x8A, 0xC0, 0x06, 0x4E, 0x4A, 0x01, 0x64,
0x61, 0x2B, 0x1F, 0xCE, 0x77, 0xC8, 0x69, 0x34,
0x5B, 0xFC, 0x94, 0xC7, 0x58, 0x94, 0xED, 0xD3,
};
unsigned char seckey[32];
unsigned char randomize[32];
unsigned char compressed_pubkey[33];
unsigned char serialized_signature[64];
size_t len;
int is_signature_valid, is_signature_valid2;
int return_val;
secp256k1_pubkey pubkey;
secp256k1_ecdsa_signature sig;
/* Before we can call actual API functions, we need to create a "context". */
secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
if (!fill_random(randomize, sizeof(randomize))) {
printf("Failed to generate randomness\n");
return 1;
}
/* Randomizing the context is recommended to protect against side-channel
* leakage See `secp256k1_context_randomize` in secp256k1.h for more
* information about it. This should never fail. */
return_val = secp256k1_context_randomize(ctx, randomize);
assert(return_val);
/*** Key Generation ***/
if (!fill_random(seckey, sizeof(seckey))) {
printf("Failed to generate randomness\n");
return 1;
}
/* If the secret key is zero or out of range (greater than secp256k1's
* order), we fail. Note that the probability of this occurring is negligible
* with a properly functioning random number generator. */
if (!secp256k1_ec_seckey_verify(ctx, seckey)) {
printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n");
return 1;
}
/* Public key creation using a valid context with a verified secret key should never fail */
return_val = secp256k1_ec_pubkey_create(ctx, &pubkey, seckey);
assert(return_val);
/* Serialize the pubkey in a compressed form(33 bytes). Should always return 1. */
len = sizeof(compressed_pubkey);
return_val = secp256k1_ec_pubkey_serialize(ctx, compressed_pubkey, &len, &pubkey, SECP256K1_EC_COMPRESSED);
assert(return_val);
/* Should be the same size as the size of the output, because we passed a 33 byte array. */
assert(len == sizeof(compressed_pubkey));
/*** Signing ***/
/* Generate an ECDSA signature `noncefp` and `ndata` allows you to pass a
* custom nonce function, passing `NULL` will use the RFC-6979 safe default.
* Signing with a valid context, verified secret key
* and the default nonce function should never fail. */
return_val = secp256k1_ecdsa_sign(ctx, &sig, msg_hash, seckey, NULL, NULL);
assert(return_val);
/* Serialize the signature in a compact form. Should always return 1
* according to the documentation in secp256k1.h. */
return_val = secp256k1_ecdsa_signature_serialize_compact(ctx, serialized_signature, &sig);
assert(return_val);
/*** Verification ***/
/* Deserialize the signature. This will return 0 if the signature can't be parsed correctly. */
if (!secp256k1_ecdsa_signature_parse_compact(ctx, &sig, serialized_signature)) {
printf("Failed parsing the signature\n");
return 1;
}
/* Deserialize the public key. This will return 0 if the public key can't be parsed correctly. */
if (!secp256k1_ec_pubkey_parse(ctx, &pubkey, compressed_pubkey, sizeof(compressed_pubkey))) {
printf("Failed parsing the public key\n");
return 1;
}
/* Verify a signature. This will return 1 if it's valid and 0 if it's not. */
is_signature_valid = secp256k1_ecdsa_verify(ctx, &sig, msg_hash, &pubkey);
printf("Is the signature valid? %s\n", is_signature_valid ? "true" : "false");
printf("Secret Key: ");
print_hex(seckey, sizeof(seckey));
printf("Public Key: ");
print_hex(compressed_pubkey, sizeof(compressed_pubkey));
printf("Signature: ");
print_hex(serialized_signature, sizeof(serialized_signature));
/* This will clear everything from the context and free the memory */
secp256k1_context_destroy(ctx);
/* Bonus example: if all we need is signature verification (and no key
generation or signing), we don't need to use a context created via
secp256k1_context_create(). We can simply use the static (i.e., global)
context secp256k1_context_static. See its description in
include/secp256k1.h for details. */
is_signature_valid2 = secp256k1_ecdsa_verify(secp256k1_context_static,
&sig, msg_hash, &pubkey);
assert(is_signature_valid2 == is_signature_valid);
/* It's best practice to try to clear secrets from memory after using them.
* This is done because some bugs can allow an attacker to leak memory, for
* example through "out of bounds" array access (see Heartbleed), or the OS
* swapping them to disk. Hence, we overwrite the secret key buffer with zeros.
*
* Here we are preventing these writes from being optimized out, as any good compiler
* will remove any writes that aren't used. */
secure_erase(seckey, sizeof(seckey));
return 0;
}

View File

@@ -1,121 +0,0 @@
/*************************************************************************
* Written in 2024 by Sebastian Falbesoner *
* To the extent possible under law, the author(s) have dedicated all *
* copyright and related and neighboring rights to the software in this *
* file to the public domain worldwide. This software is distributed *
* without any warranty. For the CC0 Public Domain Dedication, see *
* EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
*************************************************************************/
/** This file demonstrates how to use the ElligatorSwift module to perform
* a key exchange according to BIP 324. Additionally, see the documentation
* in include/secp256k1_ellswift.h and doc/ellswift.md.
*/
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <secp256k1.h>
#include <secp256k1_ellswift.h>
#include "examples_util.h"
int main(void) {
secp256k1_context* ctx;
unsigned char randomize[32];
unsigned char auxrand1[32];
unsigned char auxrand2[32];
unsigned char seckey1[32];
unsigned char seckey2[32];
unsigned char ellswift_pubkey1[64];
unsigned char ellswift_pubkey2[64];
unsigned char shared_secret1[32];
unsigned char shared_secret2[32];
int return_val;
/* Create a secp256k1 context */
ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
if (!fill_random(randomize, sizeof(randomize))) {
printf("Failed to generate randomness\n");
return 1;
}
/* Randomizing the context is recommended to protect against side-channel
* leakage. See `secp256k1_context_randomize` in secp256k1.h for more
* information about it. This should never fail. */
return_val = secp256k1_context_randomize(ctx, randomize);
assert(return_val);
/*** Generate secret keys ***/
if (!fill_random(seckey1, sizeof(seckey1)) || !fill_random(seckey2, sizeof(seckey2))) {
printf("Failed to generate randomness\n");
return 1;
}
/* If the secret key is zero or out of range (greater than secp256k1's
* order), we fail. Note that the probability of this occurring is negligible
* with a properly functioning random number generator. */
if (!secp256k1_ec_seckey_verify(ctx, seckey1) || !secp256k1_ec_seckey_verify(ctx, seckey2)) {
printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n");
return 1;
}
/* Generate ElligatorSwift public keys. This should never fail with valid context and
verified secret keys. Note that providing additional randomness (fourth parameter) is
optional, but recommended. */
if (!fill_random(auxrand1, sizeof(auxrand1)) || !fill_random(auxrand2, sizeof(auxrand2))) {
printf("Failed to generate randomness\n");
return 1;
}
return_val = secp256k1_ellswift_create(ctx, ellswift_pubkey1, seckey1, auxrand1);
assert(return_val);
return_val = secp256k1_ellswift_create(ctx, ellswift_pubkey2, seckey2, auxrand2);
assert(return_val);
/*** Create the shared secret on each side ***/
/* Perform x-only ECDH with seckey1 and ellswift_pubkey2. Should never fail
* with a verified seckey and valid pubkey. Note that both parties pass both
* EllSwift pubkeys in the same order; the pubkey of the calling party is
* determined by the "party" boolean (sixth parameter). */
return_val = secp256k1_ellswift_xdh(ctx, shared_secret1, ellswift_pubkey1, ellswift_pubkey2,
seckey1, 0, secp256k1_ellswift_xdh_hash_function_bip324, NULL);
assert(return_val);
/* Perform x-only ECDH with seckey2 and ellswift_pubkey1. Should never fail
* with a verified seckey and valid pubkey. */
return_val = secp256k1_ellswift_xdh(ctx, shared_secret2, ellswift_pubkey1, ellswift_pubkey2,
seckey2, 1, secp256k1_ellswift_xdh_hash_function_bip324, NULL);
assert(return_val);
/* Both parties should end up with the same shared secret */
return_val = memcmp(shared_secret1, shared_secret2, sizeof(shared_secret1));
assert(return_val == 0);
printf( " Secret Key1: ");
print_hex(seckey1, sizeof(seckey1));
printf( "EllSwift Pubkey1: ");
print_hex(ellswift_pubkey1, sizeof(ellswift_pubkey1));
printf("\n Secret Key2: ");
print_hex(seckey2, sizeof(seckey2));
printf( "EllSwift Pubkey2: ");
print_hex(ellswift_pubkey2, sizeof(ellswift_pubkey2));
printf("\n Shared Secret: ");
print_hex(shared_secret1, sizeof(shared_secret1));
/* This will clear everything from the context and free the memory */
secp256k1_context_destroy(ctx);
/* It's best practice to try to clear secrets from memory after using them.
* This is done because some bugs can allow an attacker to leak memory, for
* example through "out of bounds" array access (see Heartbleed), or the OS
* swapping them to disk. Hence, we overwrite the secret key buffer with zeros.
*
* Here we are preventing these writes from being optimized out, as any good compiler
* will remove any writes that aren't used. */
secure_erase(seckey1, sizeof(seckey1));
secure_erase(seckey2, sizeof(seckey2));
secure_erase(shared_secret1, sizeof(shared_secret1));
secure_erase(shared_secret2, sizeof(shared_secret2));
return 0;
}

View File

@@ -1,108 +0,0 @@
/*************************************************************************
* Copyright (c) 2020-2021 Elichai Turkel *
* Distributed under the CC0 software license, see the accompanying file *
* EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
*************************************************************************/
/*
* This file is an attempt at collecting best practice methods for obtaining randomness with different operating systems.
* It may be out-of-date. Consult the documentation of the operating system before considering to use the methods below.
*
* Platform randomness sources:
* Linux -> `getrandom(2)`(`sys/random.h`), if not available `/dev/urandom` should be used. http://man7.org/linux/man-pages/man2/getrandom.2.html, https://linux.die.net/man/4/urandom
* macOS -> `getentropy(2)`(`sys/random.h`), if not available `/dev/urandom` should be used. https://www.unix.com/man-page/mojave/2/getentropy, https://opensource.apple.com/source/xnu/xnu-517.12.7/bsd/man/man4/random.4.auto.html
* FreeBSD -> `getrandom(2)`(`sys/random.h`), if not available `kern.arandom` should be used. https://www.freebsd.org/cgi/man.cgi?query=getrandom, https://www.freebsd.org/cgi/man.cgi?query=random&sektion=4
* OpenBSD -> `getentropy(2)`(`unistd.h`), if not available `/dev/urandom` should be used. https://man.openbsd.org/getentropy, https://man.openbsd.org/urandom
* Windows -> `BCryptGenRandom`(`bcrypt.h`). https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
*/
#if defined(_WIN32)
/*
* The defined WIN32_NO_STATUS macro disables return code definitions in
* windows.h, which avoids "macro redefinition" MSVC warnings in ntstatus.h.
*/
#define WIN32_NO_STATUS
#include <windows.h>
#undef WIN32_NO_STATUS
#include <ntstatus.h>
#include <bcrypt.h>
#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
#include <sys/random.h>
#elif defined(__OpenBSD__)
#include <unistd.h>
#else
#error "Couldn't identify the OS"
#endif
#include <stddef.h>
#include <limits.h>
#include <stdio.h>
/* Returns 1 on success, and 0 on failure. */
static int fill_random(unsigned char* data, size_t size) {
#if defined(_WIN32)
NTSTATUS res = BCryptGenRandom(NULL, data, size, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
if (res != STATUS_SUCCESS || size > ULONG_MAX) {
return 0;
} else {
return 1;
}
#elif defined(__linux__) || defined(__FreeBSD__)
/* If `getrandom(2)` is not available you should fallback to /dev/urandom */
ssize_t res = getrandom(data, size, 0);
if (res < 0 || (size_t)res != size ) {
return 0;
} else {
return 1;
}
#elif defined(__APPLE__) || defined(__OpenBSD__)
/* If `getentropy(2)` is not available you should fallback to either
* `SecRandomCopyBytes` or /dev/urandom */
int res = getentropy(data, size);
if (res == 0) {
return 1;
} else {
return 0;
}
#endif
return 0;
}
static void print_hex(unsigned char* data, size_t size) {
size_t i;
printf("0x");
for (i = 0; i < size; i++) {
printf("%02x", data[i]);
}
printf("\n");
}
#if defined(_MSC_VER)
// For SecureZeroMemory
#include <Windows.h>
#endif
/* Cleanses memory to prevent leaking sensitive info. Won't be optimized out. */
static void secure_erase(void *ptr, size_t len) {
#if defined(_MSC_VER)
/* SecureZeroMemory is guaranteed not to be optimized out by MSVC. */
SecureZeroMemory(ptr, len);
#elif defined(__GNUC__)
/* We use a memory barrier that scares the compiler away from optimizing out the memset.
*
* Quoting Adam Langley <agl@google.com> in commit ad1907fe73334d6c696c8539646c21b11178f20f
* in BoringSSL (ISC License):
* As best as we can tell, this is sufficient to break any optimisations that
* might try to eliminate "superfluous" memsets.
* This method used in memzero_explicit() the Linux kernel, too. Its advantage is that it is
* pretty efficient, because the compiler can still implement the memset() efficiently,
* just not remove it entirely. See "Dead Store Elimination (Still) Considered Harmful" by
* Yang et al. (USENIX Security 2017) for more background.
*/
memset(ptr, 0, len);
__asm__ __volatile__("" : : "r"(ptr) : "memory");
#else
void *(*volatile const volatile_memset)(void *, int, size_t) = memset;
volatile_memset(ptr, 0, len);
#endif
}

View File

@@ -1,260 +0,0 @@
/*************************************************************************
* To the extent possible under law, the author(s) have dedicated all *
* copyright and related and neighboring rights to the software in this *
* file to the public domain worldwide. This software is distributed *
* without any warranty. For the CC0 Public Domain Dedication, see *
* EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
*************************************************************************/
/** This file demonstrates how to use the MuSig module to create a
* 3-of-3 multisignature. Additionally, see the documentation in
* include/secp256k1_musig.h and doc/musig.md.
*/
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <secp256k1.h>
#include <secp256k1_extrakeys.h>
#include <secp256k1_musig.h>
#include <secp256k1_schnorrsig.h>
#include "examples_util.h"
struct signer_secrets {
secp256k1_keypair keypair;
secp256k1_musig_secnonce secnonce;
};
struct signer {
secp256k1_pubkey pubkey;
secp256k1_musig_pubnonce pubnonce;
secp256k1_musig_partial_sig partial_sig;
};
/* Number of public keys involved in creating the aggregate signature */
#define N_SIGNERS 3
/* Create a key pair, store it in signer_secrets->keypair and signer->pubkey */
static int create_keypair(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, struct signer *signer) {
unsigned char seckey[32];
if (!fill_random(seckey, sizeof(seckey))) {
printf("Failed to generate randomness\n");
return 0;
}
/* Try to create a keypair with a valid context. This only fails if the
* secret key is zero or out of range (greater than secp256k1's order). Note
* that the probability of this occurring is negligible with a properly
* functioning random number generator. */
if (!secp256k1_keypair_create(ctx, &signer_secrets->keypair, seckey)) {
return 0;
}
if (!secp256k1_keypair_pub(ctx, &signer->pubkey, &signer_secrets->keypair)) {
return 0;
}
secure_erase(seckey, sizeof(seckey));
return 1;
}
/* Tweak the pubkey corresponding to the provided keyagg cache, update the cache
* and return the tweaked aggregate pk. */
static int tweak(const secp256k1_context* ctx, secp256k1_xonly_pubkey *agg_pk, secp256k1_musig_keyagg_cache *cache) {
secp256k1_pubkey output_pk;
/* For BIP 32 tweaking the plain_tweak is set to a hash as defined in BIP
* 32. */
unsigned char plain_tweak[32] = "this could be a BIP32 tweak....";
/* For Taproot tweaking the xonly_tweak is set to the TapTweak hash as
* defined in BIP 341 */
unsigned char xonly_tweak[32] = "this could be a Taproot tweak..";
/* Plain tweaking which, for example, allows deriving multiple child
* public keys from a single aggregate key using BIP32 */
if (!secp256k1_musig_pubkey_ec_tweak_add(ctx, NULL, cache, plain_tweak)) {
return 0;
}
/* Note that we did not provide an output_pk argument, because the
* resulting pk is also saved in the cache and so if one is just interested
* in signing, the output_pk argument is unnecessary. On the other hand, if
* one is not interested in signing, the same output_pk can be obtained by
* calling `secp256k1_musig_pubkey_get` right after key aggregation to get
* the full pubkey and then call `secp256k1_ec_pubkey_tweak_add`. */
/* Xonly tweaking which, for example, allows creating Taproot commitments */
if (!secp256k1_musig_pubkey_xonly_tweak_add(ctx, &output_pk, cache, xonly_tweak)) {
return 0;
}
/* Note that if we wouldn't care about signing, we can arrive at the same
* output_pk by providing the untweaked public key to
* `secp256k1_xonly_pubkey_tweak_add` (after converting it to an xonly pubkey
* if necessary with `secp256k1_xonly_pubkey_from_pubkey`). */
/* Now we convert the output_pk to an xonly pubkey to allow to later verify
* the Schnorr signature against it. For this purpose we can ignore the
* `pk_parity` output argument; we would need it if we would have to open
* the Taproot commitment. */
if (!secp256k1_xonly_pubkey_from_pubkey(ctx, agg_pk, NULL, &output_pk)) {
return 0;
}
return 1;
}
/* Sign a message hash with the given key pairs and store the result in sig */
static int sign(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, struct signer *signer, const secp256k1_musig_keyagg_cache *cache, const unsigned char *msg32, unsigned char *sig64) {
int i;
const secp256k1_musig_pubnonce *pubnonces[N_SIGNERS];
const secp256k1_musig_partial_sig *partial_sigs[N_SIGNERS];
/* The same for all signers */
secp256k1_musig_session session;
secp256k1_musig_aggnonce agg_pubnonce;
for (i = 0; i < N_SIGNERS; i++) {
unsigned char seckey[32];
unsigned char session_secrand[32];
/* Create random session ID. It is absolutely necessary that the session ID
* is unique for every call of secp256k1_musig_nonce_gen. Otherwise
* it's trivial for an attacker to extract the secret key! */
if (!fill_random(session_secrand, sizeof(session_secrand))) {
return 0;
}
if (!secp256k1_keypair_sec(ctx, seckey, &signer_secrets[i].keypair)) {
return 0;
}
/* Initialize session and create secret nonce for signing and public
* nonce to send to the other signers. */
if (!secp256k1_musig_nonce_gen(ctx, &signer_secrets[i].secnonce, &signer[i].pubnonce, session_secrand, seckey, &signer[i].pubkey, msg32, NULL, NULL)) {
return 0;
}
pubnonces[i] = &signer[i].pubnonce;
secure_erase(seckey, sizeof(seckey));
}
/* Communication round 1: Every signer sends their pubnonce to the
* coordinator. The coordinator runs secp256k1_musig_nonce_agg and sends
* agg_pubnonce to each signer */
if (!secp256k1_musig_nonce_agg(ctx, &agg_pubnonce, pubnonces, N_SIGNERS)) {
return 0;
}
/* Every signer creates a partial signature */
for (i = 0; i < N_SIGNERS; i++) {
/* Initialize the signing session by processing the aggregate nonce */
if (!secp256k1_musig_nonce_process(ctx, &session, &agg_pubnonce, msg32, cache)) {
return 0;
}
/* partial_sign will clear the secnonce by setting it to 0. That's because
* you must _never_ reuse the secnonce (or use the same session_secrand to
* create a secnonce). If you do, you effectively reuse the nonce and
* leak the secret key. */
if (!secp256k1_musig_partial_sign(ctx, &signer[i].partial_sig, &signer_secrets[i].secnonce, &signer_secrets[i].keypair, cache, &session)) {
return 0;
}
partial_sigs[i] = &signer[i].partial_sig;
}
/* Communication round 2: Every signer sends their partial signature to the
* coordinator, who verifies the partial signatures and aggregates them. */
for (i = 0; i < N_SIGNERS; i++) {
/* To check whether signing was successful, it suffices to either verify
* the aggregate signature with the aggregate public key using
* secp256k1_schnorrsig_verify, or verify all partial signatures of all
* signers individually. Verifying the aggregate signature is cheaper but
* verifying the individual partial signatures has the advantage that it
* can be used to determine which of the partial signatures are invalid
* (if any), i.e., which of the partial signatures cause the aggregate
* signature to be invalid and thus the protocol run to fail. It's also
* fine to first verify the aggregate sig, and only verify the individual
* sigs if it does not work.
*/
if (!secp256k1_musig_partial_sig_verify(ctx, &signer[i].partial_sig, &signer[i].pubnonce, &signer[i].pubkey, cache, &session)) {
return 0;
}
}
return secp256k1_musig_partial_sig_agg(ctx, sig64, &session, partial_sigs, N_SIGNERS);
}
int main(void) {
secp256k1_context* ctx;
int i;
struct signer_secrets signer_secrets[N_SIGNERS];
struct signer signers[N_SIGNERS];
const secp256k1_pubkey *pubkeys_ptr[N_SIGNERS];
secp256k1_xonly_pubkey agg_pk;
secp256k1_musig_keyagg_cache cache;
unsigned char msg[32] = "this_could_be_the_hash_of_a_msg";
unsigned char sig[64];
/* Create a secp256k1 context */
ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
printf("Creating key pairs......");
fflush(stdout);
for (i = 0; i < N_SIGNERS; i++) {
if (!create_keypair(ctx, &signer_secrets[i], &signers[i])) {
printf("FAILED\n");
return 1;
}
pubkeys_ptr[i] = &signers[i].pubkey;
}
printf("ok\n");
/* The aggregate public key produced by secp256k1_musig_pubkey_agg depends
* on the order of the provided public keys. If there is no canonical order
* of the signers, the individual public keys can optionally be sorted with
* secp256k1_ec_pubkey_sort to ensure that the aggregate public key is
* independent of the order of signers. */
printf("Sorting public keys.....");
fflush(stdout);
if (!secp256k1_ec_pubkey_sort(ctx, pubkeys_ptr, N_SIGNERS)) {
printf("FAILED\n");
return 1;
}
printf("ok\n");
printf("Combining public keys...");
fflush(stdout);
/* If you just want to aggregate and not sign, you can call
* secp256k1_musig_pubkey_agg with the keyagg_cache argument set to NULL
* while providing a non-NULL agg_pk argument. */
if (!secp256k1_musig_pubkey_agg(ctx, NULL, &cache, pubkeys_ptr, N_SIGNERS)) {
printf("FAILED\n");
return 1;
}
printf("ok\n");
printf("Tweaking................");
fflush(stdout);
/* Optionally tweak the aggregate key */
if (!tweak(ctx, &agg_pk, &cache)) {
printf("FAILED\n");
return 1;
}
printf("ok\n");
printf("Signing message.........");
fflush(stdout);
if (!sign(ctx, signer_secrets, signers, &cache, msg, sig)) {
printf("FAILED\n");
return 1;
}
printf("ok\n");
printf("Verifying signature.....");
fflush(stdout);
if (!secp256k1_schnorrsig_verify(ctx, sig, msg, 32, &agg_pk)) {
printf("FAILED\n");
return 1;
}
printf("ok\n");
/* It's best practice to try to clear secrets from memory after using them.
* This is done because some bugs can allow an attacker to leak memory, for
* example through "out of bounds" array access (see Heartbleed), or the OS
* swapping them to disk. Hence, we overwrite secret key material with zeros.
*
* Here we are preventing these writes from being optimized out, as any good compiler
* will remove any writes that aren't used. */
for (i = 0; i < N_SIGNERS; i++) {
secure_erase(&signer_secrets[i], sizeof(signer_secrets[i]));
}
secp256k1_context_destroy(ctx);
return 0;
}

View File

@@ -1,153 +0,0 @@
/*************************************************************************
* Written in 2020-2022 by Elichai Turkel *
* To the extent possible under law, the author(s) have dedicated all *
* copyright and related and neighboring rights to the software in this *
* file to the public domain worldwide. This software is distributed *
* without any warranty. For the CC0 Public Domain Dedication, see *
* EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
*************************************************************************/
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <secp256k1.h>
#include <secp256k1_extrakeys.h>
#include <secp256k1_schnorrsig.h>
#include "examples_util.h"
int main(void) {
unsigned char msg[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!'};
unsigned char msg_hash[32];
unsigned char tag[] = {'m', 'y', '_', 'f', 'a', 'n', 'c', 'y', '_', 'p', 'r', 'o', 't', 'o', 'c', 'o', 'l'};
unsigned char seckey[32];
unsigned char randomize[32];
unsigned char auxiliary_rand[32];
unsigned char serialized_pubkey[32];
unsigned char signature[64];
int is_signature_valid, is_signature_valid2;
int return_val;
secp256k1_xonly_pubkey pubkey;
secp256k1_keypair keypair;
/* Before we can call actual API functions, we need to create a "context". */
secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
if (!fill_random(randomize, sizeof(randomize))) {
printf("Failed to generate randomness\n");
return 1;
}
/* Randomizing the context is recommended to protect against side-channel
* leakage See `secp256k1_context_randomize` in secp256k1.h for more
* information about it. This should never fail. */
return_val = secp256k1_context_randomize(ctx, randomize);
assert(return_val);
/*** Key Generation ***/
if (!fill_random(seckey, sizeof(seckey))) {
printf("Failed to generate randomness\n");
return 1;
}
/* Try to create a keypair with a valid context. This only fails if the
* secret key is zero or out of range (greater than secp256k1's order). Note
* that the probability of this occurring is negligible with a properly
* functioning random number generator. */
if (!secp256k1_keypair_create(ctx, &keypair, seckey)) {
printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n");
return 1;
}
/* Extract the X-only public key from the keypair. We pass NULL for
* `pk_parity` as the parity isn't needed for signing or verification.
* `secp256k1_keypair_xonly_pub` supports returning the parity for
* other use cases such as tests or verifying Taproot tweaks.
* This should never fail with a valid context and public key. */
return_val = secp256k1_keypair_xonly_pub(ctx, &pubkey, NULL, &keypair);
assert(return_val);
/* Serialize the public key. Should always return 1 for a valid public key. */
return_val = secp256k1_xonly_pubkey_serialize(ctx, serialized_pubkey, &pubkey);
assert(return_val);
/*** Signing ***/
/* Instead of signing (possibly very long) messages directly, we sign a
* 32-byte hash of the message in this example.
*
* We use secp256k1_tagged_sha256 to create this hash. This function expects
* a context-specific "tag", which restricts the context in which the signed
* messages should be considered valid. For example, if protocol A mandates
* to use the tag "my_fancy_protocol" and protocol B mandates to use the tag
* "my_boring_protocol", then signed messages from protocol A will never be
* valid in protocol B (and vice versa), even if keys are reused across
* protocols. This implements "domain separation", which is considered good
* practice. It avoids attacks in which users are tricked into signing a
* message that has intended consequences in the intended context (e.g.,
* protocol A) but would have unintended consequences if it were valid in
* some other context (e.g., protocol B). */
return_val = secp256k1_tagged_sha256(ctx, msg_hash, tag, sizeof(tag), msg, sizeof(msg));
assert(return_val);
/* Generate 32 bytes of randomness to use with BIP-340 schnorr signing. */
if (!fill_random(auxiliary_rand, sizeof(auxiliary_rand))) {
printf("Failed to generate randomness\n");
return 1;
}
/* Generate a Schnorr signature.
*
* We use the secp256k1_schnorrsig_sign32 function that provides a simple
* interface for signing 32-byte messages (which in our case is a hash of
* the actual message). BIP-340 recommends passing 32 bytes of randomness
* to the signing function to improve security against side-channel attacks.
* Signing with a valid context, a 32-byte message, a verified keypair, and
* any 32 bytes of auxiliary random data should never fail. */
return_val = secp256k1_schnorrsig_sign32(ctx, signature, msg_hash, &keypair, auxiliary_rand);
assert(return_val);
/*** Verification ***/
/* Deserialize the public key. This will return 0 if the public key can't
* be parsed correctly */
if (!secp256k1_xonly_pubkey_parse(ctx, &pubkey, serialized_pubkey)) {
printf("Failed parsing the public key\n");
return 1;
}
/* Compute the tagged hash on the received messages using the same tag as the signer. */
return_val = secp256k1_tagged_sha256(ctx, msg_hash, tag, sizeof(tag), msg, sizeof(msg));
assert(return_val);
/* Verify a signature. This will return 1 if it's valid and 0 if it's not. */
is_signature_valid = secp256k1_schnorrsig_verify(ctx, signature, msg_hash, 32, &pubkey);
printf("Is the signature valid? %s\n", is_signature_valid ? "true" : "false");
printf("Secret Key: ");
print_hex(seckey, sizeof(seckey));
printf("Public Key: ");
print_hex(serialized_pubkey, sizeof(serialized_pubkey));
printf("Signature: ");
print_hex(signature, sizeof(signature));
/* This will clear everything from the context and free the memory */
secp256k1_context_destroy(ctx);
/* Bonus example: if all we need is signature verification (and no key
generation or signing), we don't need to use a context created via
secp256k1_context_create(). We can simply use the static (i.e., global)
context secp256k1_context_static. See its description in
include/secp256k1.h for details. */
is_signature_valid2 = secp256k1_schnorrsig_verify(secp256k1_context_static,
signature, msg_hash, 32, &pubkey);
assert(is_signature_valid2 == is_signature_valid);
/* It's best practice to try to clear secrets from memory after using them.
* This is done because some bugs can allow an attacker to leak memory, for
* example through "out of bounds" array access (see Heartbleed), or the OS
* swapping them to disk. Hence, we overwrite the secret key buffer with zeros.
*
* Here we are preventing these writes from being optimized out, as any good compiler
* will remove any writes that aren't used. */
secure_erase(seckey, sizeof(seckey));
return 0;
}

View File

@@ -1,899 +0,0 @@
#ifndef SECP256K1_H
#define SECP256K1_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
/** Unless explicitly stated all pointer arguments must not be NULL.
*
* The following rules specify the order of arguments in API calls:
*
* 1. Context pointers go first, followed by output arguments, combined
* output/input arguments, and finally input-only arguments.
* 2. Array lengths always immediately follow the argument whose length
* they describe, even if this violates rule 1.
* 3. Within the OUT/OUTIN/IN groups, pointers to data that is typically generated
* later go first. This means: signatures, public nonces, secret nonces,
* messages, public keys, secret keys, tweaks.
* 4. Arguments that are not data pointers go last, from more complex to less
* complex: function pointers, algorithm names, messages, void pointers,
* counts, flags, booleans.
* 5. Opaque data pointers follow the function pointer they are to be passed to.
*/
/** Opaque data structure that holds context information
*
* The primary purpose of context objects is to store randomization data for
* enhanced protection against side-channel leakage. This protection is only
* effective if the context is randomized after its creation. See
* secp256k1_context_create for creation of contexts and
* secp256k1_context_randomize for randomization.
*
* A secondary purpose of context objects is to store pointers to callback
* functions that the library will call when certain error states arise. See
* secp256k1_context_set_error_callback as well as
* secp256k1_context_set_illegal_callback for details. Future library versions
* may use context objects for additional purposes.
*
* A constructed context can safely be used from multiple threads
* simultaneously, but API calls that take a non-const pointer to a context
* need exclusive access to it. In particular this is the case for
* secp256k1_context_destroy, secp256k1_context_preallocated_destroy,
* and secp256k1_context_randomize.
*
* Regarding randomization, either do it once at creation time (in which case
* you do not need any locking for the other calls), or use a read-write lock.
*/
typedef struct secp256k1_context_struct secp256k1_context;
/** Opaque data structure that holds a parsed and valid public key.
*
* The exact representation of data inside is implementation defined and not
* guaranteed to be portable between different platforms or versions. It is
* however guaranteed to be 64 bytes in size, and can be safely copied/moved.
* If you need to convert to a format suitable for storage or transmission,
* use secp256k1_ec_pubkey_serialize and secp256k1_ec_pubkey_parse. To
* compare keys, use secp256k1_ec_pubkey_cmp.
*/
typedef struct secp256k1_pubkey {
unsigned char data[64];
} secp256k1_pubkey;
/** Opaque data structure that holds a parsed ECDSA signature.
*
* The exact representation of data inside is implementation defined and not
* guaranteed to be portable between different platforms or versions. It is
* however guaranteed to be 64 bytes in size, and can be safely copied/moved.
* If you need to convert to a format suitable for storage, transmission, or
* comparison, use the secp256k1_ecdsa_signature_serialize_* and
* secp256k1_ecdsa_signature_parse_* functions.
*/
typedef struct secp256k1_ecdsa_signature {
unsigned char data[64];
} secp256k1_ecdsa_signature;
/** A pointer to a function to deterministically generate a nonce.
*
* Returns: 1 if a nonce was successfully generated. 0 will cause signing to fail.
* Out: nonce32: pointer to a 32-byte array to be filled by the function.
* In: msg32: the 32-byte message hash being verified (will not be NULL)
* key32: pointer to a 32-byte secret key (will not be NULL)
* algo16: pointer to a 16-byte array describing the signature
* algorithm (will be NULL for ECDSA for compatibility).
* data: Arbitrary data pointer that is passed through.
* attempt: how many iterations we have tried to find a nonce.
* This will almost always be 0, but different attempt values
* are required to result in a different nonce.
*
* Except for test cases, this function should compute some cryptographic hash of
* the message, the algorithm, the key and the attempt.
*/
typedef int (*secp256k1_nonce_function)(
unsigned char *nonce32,
const unsigned char *msg32,
const unsigned char *key32,
const unsigned char *algo16,
void *data,
unsigned int attempt
);
# if !defined(SECP256K1_GNUC_PREREQ)
# if defined(__GNUC__)&&defined(__GNUC_MINOR__)
# define SECP256K1_GNUC_PREREQ(_maj,_min) \
((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min))
# else
# define SECP256K1_GNUC_PREREQ(_maj,_min) 0
# endif
# endif
/* When this header is used at build-time the SECP256K1_BUILD define needs to be set
* to correctly setup export attributes and nullness checks. This is normally done
* by secp256k1.c but to guard against this header being included before secp256k1.c
* has had a chance to set the define (e.g. via test harnesses that just includes
* secp256k1.c) we set SECP256K1_NO_BUILD when this header is processed without the
* BUILD define so this condition can be caught.
*/
#ifndef SECP256K1_BUILD
# define SECP256K1_NO_BUILD
#endif
/* Symbol visibility. */
#if defined(_WIN32)
/* GCC for Windows (e.g., MinGW) accepts the __declspec syntax
* for MSVC compatibility. A __declspec declaration implies (but is not
* exactly equivalent to) __attribute__ ((visibility("default"))), and so we
* actually want __declspec even on GCC, see "Microsoft Windows Function
* Attributes" in the GCC manual and the recommendations in
* https://gcc.gnu.org/wiki/Visibility. */
# if defined(SECP256K1_BUILD)
# if defined(DLL_EXPORT) || defined(SECP256K1_DLL_EXPORT)
/* Building libsecp256k1 as a DLL.
* 1. If using Libtool, it defines DLL_EXPORT automatically.
* 2. In other cases, SECP256K1_DLL_EXPORT must be defined. */
# define SECP256K1_API extern __declspec (dllexport)
# else
/* Building libsecp256k1 as a static library on Windows.
* No declspec is needed, and so we would want the non-Windows-specific
* logic below take care of this case. However, this may result in setting
* __attribute__ ((visibility("default"))), which is supposed to be a noop
* on Windows but may trigger warnings when compiling with -flto due to a
* bug in GCC, see
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116478 . */
# define SECP256K1_API extern
# endif
/* The user must define SECP256K1_STATIC when consuming libsecp256k1 as a static
* library on Windows. */
# elif !defined(SECP256K1_STATIC)
/* Consuming libsecp256k1 as a DLL. */
# define SECP256K1_API extern __declspec (dllimport)
# endif
#endif
#ifndef SECP256K1_API
/* All cases not captured by the Windows-specific logic. */
# if defined(__GNUC__) && (__GNUC__ >= 4) && defined(SECP256K1_BUILD)
/* Building libsecp256k1 using GCC or compatible. */
# define SECP256K1_API extern __attribute__ ((visibility ("default")))
# else
/* Fall back to standard C's extern. */
# define SECP256K1_API extern
# endif
#endif
/* Warning attributes
* NONNULL is not used if SECP256K1_BUILD is set to avoid the compiler optimizing out
* some paranoid null checks. */
# if defined(__GNUC__) && SECP256K1_GNUC_PREREQ(3, 4)
# define SECP256K1_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__))
# else
# define SECP256K1_WARN_UNUSED_RESULT
# endif
# if !defined(SECP256K1_BUILD) && defined(__GNUC__) && SECP256K1_GNUC_PREREQ(3, 4)
# define SECP256K1_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x)))
# else
# define SECP256K1_ARG_NONNULL(_x)
# endif
/* Attribute for marking functions, types, and variables as deprecated */
#if !defined(SECP256K1_BUILD) && defined(__has_attribute)
# if __has_attribute(__deprecated__)
# define SECP256K1_DEPRECATED(_msg) __attribute__ ((__deprecated__(_msg)))
# else
# define SECP256K1_DEPRECATED(_msg)
# endif
#else
# define SECP256K1_DEPRECATED(_msg)
#endif
/* All flags' lower 8 bits indicate what they're for. Do not use directly. */
#define SECP256K1_FLAGS_TYPE_MASK ((1 << 8) - 1)
#define SECP256K1_FLAGS_TYPE_CONTEXT (1 << 0)
#define SECP256K1_FLAGS_TYPE_COMPRESSION (1 << 1)
/* The higher bits contain the actual data. Do not use directly. */
#define SECP256K1_FLAGS_BIT_CONTEXT_VERIFY (1 << 8)
#define SECP256K1_FLAGS_BIT_CONTEXT_SIGN (1 << 9)
#define SECP256K1_FLAGS_BIT_CONTEXT_DECLASSIFY (1 << 10)
#define SECP256K1_FLAGS_BIT_COMPRESSION (1 << 8)
/** Context flags to pass to secp256k1_context_create, secp256k1_context_preallocated_size, and
* secp256k1_context_preallocated_create. */
#define SECP256K1_CONTEXT_NONE (SECP256K1_FLAGS_TYPE_CONTEXT)
/** Deprecated context flags. These flags are treated equivalent to SECP256K1_CONTEXT_NONE. */
#define SECP256K1_CONTEXT_VERIFY (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_VERIFY)
#define SECP256K1_CONTEXT_SIGN (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_SIGN)
/* Testing flag. Do not use. */
#define SECP256K1_CONTEXT_DECLASSIFY (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_DECLASSIFY)
/** Flag to pass to secp256k1_ec_pubkey_serialize. */
#define SECP256K1_EC_COMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION | SECP256K1_FLAGS_BIT_COMPRESSION)
#define SECP256K1_EC_UNCOMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION)
/** Prefix byte used to tag various encoded curvepoints for specific purposes */
#define SECP256K1_TAG_PUBKEY_EVEN 0x02
#define SECP256K1_TAG_PUBKEY_ODD 0x03
#define SECP256K1_TAG_PUBKEY_UNCOMPRESSED 0x04
#define SECP256K1_TAG_PUBKEY_HYBRID_EVEN 0x06
#define SECP256K1_TAG_PUBKEY_HYBRID_ODD 0x07
/** A built-in constant secp256k1 context object with static storage duration, to be
* used in conjunction with secp256k1_selftest.
*
* This context object offers *only limited functionality* , i.e., it cannot be used
* for API functions that perform computations involving secret keys, e.g., signing
* and public key generation. If this restriction applies to a specific API function,
* it is mentioned in its documentation. See secp256k1_context_create if you need a
* full context object that supports all functionality offered by the library.
*
* It is highly recommended to call secp256k1_selftest before using this context.
*/
SECP256K1_API const secp256k1_context *secp256k1_context_static;
/** Deprecated alias for secp256k1_context_static. */
SECP256K1_API const secp256k1_context *secp256k1_context_no_precomp
SECP256K1_DEPRECATED("Use secp256k1_context_static instead");
/** Perform basic self tests (to be used in conjunction with secp256k1_context_static)
*
* This function performs self tests that detect some serious usage errors and
* similar conditions, e.g., when the library is compiled for the wrong endianness.
* This is a last resort measure to be used in production. The performed tests are
* very rudimentary and are not intended as a replacement for running the test
* binaries.
*
* It is highly recommended to call this before using secp256k1_context_static.
* It is not necessary to call this function before using a context created with
* secp256k1_context_create (or secp256k1_context_preallocated_create), which will
* take care of performing the self tests.
*
* If the tests fail, this function will call the default error handler to abort the
* program (see secp256k1_context_set_error_callback).
*/
SECP256K1_API void secp256k1_selftest(void);
/** Create a secp256k1 context object (in dynamically allocated memory).
*
* This function uses malloc to allocate memory. It is guaranteed that malloc is
* called at most once for every call of this function. If you need to avoid dynamic
* memory allocation entirely, see secp256k1_context_static and the functions in
* secp256k1_preallocated.h.
*
* Returns: pointer to a newly created context object.
* In: flags: Always set to SECP256K1_CONTEXT_NONE (see below).
*
* The only valid non-deprecated flag in recent library versions is
* SECP256K1_CONTEXT_NONE, which will create a context sufficient for all functionality
* offered by the library. All other (deprecated) flags will be treated as equivalent
* to the SECP256K1_CONTEXT_NONE flag. Though the flags parameter primarily exists for
* historical reasons, future versions of the library may introduce new flags.
*
* If the context is intended to be used for API functions that perform computations
* involving secret keys, e.g., signing and public key generation, then it is highly
* recommended to call secp256k1_context_randomize on the context before calling
* those API functions. This will provide enhanced protection against side-channel
* leakage, see secp256k1_context_randomize for details.
*
* Do not create a new context object for each operation, as construction and
* randomization can take non-negligible time.
*/
SECP256K1_API secp256k1_context *secp256k1_context_create(
unsigned int flags
) SECP256K1_WARN_UNUSED_RESULT;
/** Copy a secp256k1 context object (into dynamically allocated memory).
*
* This function uses malloc to allocate memory. It is guaranteed that malloc is
* called at most once for every call of this function. If you need to avoid dynamic
* memory allocation entirely, see the functions in secp256k1_preallocated.h.
*
* Cloning secp256k1_context_static is not possible, and should not be emulated by
* the caller (e.g., using memcpy). Create a new context instead.
*
* Returns: pointer to a newly created context object.
* Args: ctx: pointer to a context to copy (not secp256k1_context_static).
*/
SECP256K1_API secp256k1_context *secp256k1_context_clone(
const secp256k1_context *ctx
) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT;
/** Destroy a secp256k1 context object (created in dynamically allocated memory).
*
* The context pointer may not be used afterwards.
*
* The context to destroy must have been created using secp256k1_context_create
* or secp256k1_context_clone. If the context has instead been created using
* secp256k1_context_preallocated_create or secp256k1_context_preallocated_clone, the
* behaviour is undefined. In that case, secp256k1_context_preallocated_destroy must
* be used instead.
*
* Args: ctx: pointer to a context to destroy, constructed using
* secp256k1_context_create or secp256k1_context_clone
* (i.e., not secp256k1_context_static).
*/
SECP256K1_API void secp256k1_context_destroy(
secp256k1_context *ctx
) SECP256K1_ARG_NONNULL(1);
/** Set a callback function to be called when an illegal argument is passed to
* an API call. It will only trigger for violations that are mentioned
* explicitly in the header.
*
* The philosophy is that these shouldn't be dealt with through a
* specific return value, as calling code should not have branches to deal with
* the case that this code itself is broken.
*
* On the other hand, during debug stage, one would want to be informed about
* such mistakes, and the default (crashing) may be inadvisable.
* When this callback is triggered, the API function called is guaranteed not
* to cause a crash, though its return value and output arguments are
* undefined.
*
* When this function has not been called (or called with fn==NULL), then the
* default handler will be used. The library provides a default handler which
* writes the message to stderr and calls abort. This default handler can be
* replaced at link time if the preprocessor macro
* USE_EXTERNAL_DEFAULT_CALLBACKS is defined, which is the case if the build
* has been configured with --enable-external-default-callbacks. Then the
* following two symbols must be provided to link against:
* - void secp256k1_default_illegal_callback_fn(const char *message, void *data);
* - void secp256k1_default_error_callback_fn(const char *message, void *data);
* The library can call these default handlers even before a proper callback data
* pointer could have been set using secp256k1_context_set_illegal_callback or
* secp256k1_context_set_error_callback, e.g., when the creation of a context
* fails. In this case, the corresponding default handler will be called with
* the data pointer argument set to NULL.
*
* Args: ctx: pointer to a context object.
* In: fun: pointer to a function to call when an illegal argument is
* passed to the API, taking a message and an opaque pointer.
* (NULL restores the default handler.)
* data: the opaque pointer to pass to fun above, must be NULL for the default handler.
*
* See also secp256k1_context_set_error_callback.
*/
SECP256K1_API void secp256k1_context_set_illegal_callback(
secp256k1_context *ctx,
void (*fun)(const char *message, void *data),
const void *data
) SECP256K1_ARG_NONNULL(1);
/** Set a callback function to be called when an internal consistency check
* fails.
*
* The default callback writes an error message to stderr and calls abort
* to abort the program.
*
* This can only trigger in case of a hardware failure, miscompilation,
* memory corruption, serious bug in the library, or other error would can
* otherwise result in undefined behaviour. It will not trigger due to mere
* incorrect usage of the API (see secp256k1_context_set_illegal_callback
* for that). After this callback returns, anything may happen, including
* crashing.
*
* Args: ctx: pointer to a context object.
* In: fun: pointer to a function to call when an internal error occurs,
* taking a message and an opaque pointer (NULL restores the
* default handler, see secp256k1_context_set_illegal_callback
* for details).
* data: the opaque pointer to pass to fun above, must be NULL for the default handler.
*
* See also secp256k1_context_set_illegal_callback.
*/
SECP256K1_API void secp256k1_context_set_error_callback(
secp256k1_context *ctx,
void (*fun)(const char *message, void *data),
const void *data
) SECP256K1_ARG_NONNULL(1);
/** Parse a variable-length public key into the pubkey object.
*
* Returns: 1 if the public key was fully valid.
* 0 if the public key could not be parsed or is invalid.
* Args: ctx: pointer to a context object.
* Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a
* parsed version of input. If not, its value is undefined.
* In: input: pointer to a serialized public key
* inputlen: length of the array pointed to by input
*
* This function supports parsing compressed (33 bytes, header byte 0x02 or
* 0x03), uncompressed (65 bytes, header byte 0x04), or hybrid (65 bytes, header
* byte 0x06 or 0x07) format public keys.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(
const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const unsigned char *input,
size_t inputlen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Serialize a pubkey object into a serialized byte sequence.
*
* Returns: 1 always.
* Args: ctx: pointer to a context object.
* Out: output: pointer to a 65-byte (if compressed==0) or 33-byte (if
* compressed==1) byte array to place the serialized key
* in.
* In/Out: outputlen: pointer to an integer which is initially set to the
* size of output, and is overwritten with the written
* size.
* In: pubkey: pointer to a secp256k1_pubkey containing an
* initialized public key.
* flags: SECP256K1_EC_COMPRESSED if serialization should be in
* compressed format, otherwise SECP256K1_EC_UNCOMPRESSED.
*/
SECP256K1_API int secp256k1_ec_pubkey_serialize(
const secp256k1_context *ctx,
unsigned char *output,
size_t *outputlen,
const secp256k1_pubkey *pubkey,
unsigned int flags
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Compare two public keys using lexicographic (of compressed serialization) order
*
* Returns: <0 if the first public key is less than the second
* >0 if the first public key is greater than the second
* 0 if the two public keys are equal
* Args: ctx: pointer to a context object
* In: pubkey1: first public key to compare
* pubkey2: second public key to compare
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_cmp(
const secp256k1_context *ctx,
const secp256k1_pubkey *pubkey1,
const secp256k1_pubkey *pubkey2
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Sort public keys using lexicographic (of compressed serialization) order
*
* Returns: 0 if the arguments are invalid. 1 otherwise.
*
* Args: ctx: pointer to a context object
* In: pubkeys: array of pointers to pubkeys to sort
* n_pubkeys: number of elements in the pubkeys array
*/
SECP256K1_API int secp256k1_ec_pubkey_sort(
const secp256k1_context *ctx,
const secp256k1_pubkey **pubkeys,
size_t n_pubkeys
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
/** Parse an ECDSA signature in compact (64 bytes) format.
*
* Returns: 1 when the signature could be parsed, 0 otherwise.
* Args: ctx: pointer to a context object
* Out: sig: pointer to a signature object
* In: input64: pointer to the 64-byte array to parse
*
* The signature must consist of a 32-byte big endian R value, followed by a
* 32-byte big endian S value. If R or S fall outside of [0..order-1], the
* encoding is invalid. R and S with value 0 are allowed in the encoding.
*
* After the call, sig will always be initialized. If parsing failed or R or
* S are zero, the resulting sig value is guaranteed to fail verification for
* any message and public key.
*/
SECP256K1_API int secp256k1_ecdsa_signature_parse_compact(
const secp256k1_context *ctx,
secp256k1_ecdsa_signature *sig,
const unsigned char *input64
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Parse a DER ECDSA signature.
*
* Returns: 1 when the signature could be parsed, 0 otherwise.
* Args: ctx: pointer to a context object
* Out: sig: pointer to a signature object
* In: input: pointer to the signature to be parsed
* inputlen: the length of the array pointed to be input
*
* This function will accept any valid DER encoded signature, even if the
* encoded numbers are out of range.
*
* After the call, sig will always be initialized. If parsing failed or the
* encoded numbers are out of range, signature verification with it is
* guaranteed to fail for every message and public key.
*/
SECP256K1_API int secp256k1_ecdsa_signature_parse_der(
const secp256k1_context *ctx,
secp256k1_ecdsa_signature *sig,
const unsigned char *input,
size_t inputlen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Serialize an ECDSA signature in DER format.
*
* Returns: 1 if enough space was available to serialize, 0 otherwise
* Args: ctx: pointer to a context object
* Out: output: pointer to an array to store the DER serialization
* In/Out: outputlen: pointer to a length integer. Initially, this integer
* should be set to the length of output. After the call
* it will be set to the length of the serialization (even
* if 0 was returned).
* In: sig: pointer to an initialized signature object
*/
SECP256K1_API int secp256k1_ecdsa_signature_serialize_der(
const secp256k1_context *ctx,
unsigned char *output,
size_t *outputlen,
const secp256k1_ecdsa_signature *sig
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Serialize an ECDSA signature in compact (64 byte) format.
*
* Returns: 1
* Args: ctx: pointer to a context object
* Out: output64: pointer to a 64-byte array to store the compact serialization
* In: sig: pointer to an initialized signature object
*
* See secp256k1_ecdsa_signature_parse_compact for details about the encoding.
*/
SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact(
const secp256k1_context *ctx,
unsigned char *output64,
const secp256k1_ecdsa_signature *sig
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Verify an ECDSA signature.
*
* Returns: 1: correct signature
* 0: incorrect or unparsable signature
* Args: ctx: pointer to a context object
* In: sig: the signature being verified.
* msghash32: the 32-byte message hash being verified.
* The verifier must make sure to apply a cryptographic
* hash function to the message by itself and not accept an
* msghash32 value directly. Otherwise, it would be easy to
* create a "valid" signature without knowledge of the
* secret key. See also
* https://bitcoin.stackexchange.com/a/81116/35586 for more
* background on this topic.
* pubkey: pointer to an initialized public key to verify with.
*
* To avoid accepting malleable signatures, only ECDSA signatures in lower-S
* form are accepted.
*
* If you need to accept ECDSA signatures from sources that do not obey this
* rule, apply secp256k1_ecdsa_signature_normalize to the signature prior to
* verification, but be aware that doing so results in malleable signatures.
*
* For details, see the comments for that function.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
const secp256k1_context *ctx,
const secp256k1_ecdsa_signature *sig,
const unsigned char *msghash32,
const secp256k1_pubkey *pubkey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Convert a signature to a normalized lower-S form.
*
* Returns: 1 if sigin was not normalized, 0 if it already was.
* Args: ctx: pointer to a context object
* Out: sigout: pointer to a signature to fill with the normalized form,
* or copy if the input was already normalized. (can be NULL if
* you're only interested in whether the input was already
* normalized).
* In: sigin: pointer to a signature to check/normalize (can be identical to sigout)
*
* With ECDSA a third-party can forge a second distinct signature of the same
* message, given a single initial signature, but without knowing the key. This
* is done by negating the S value modulo the order of the curve, 'flipping'
* the sign of the random point R which is not included in the signature.
*
* Forgery of the same message isn't universally problematic, but in systems
* where message malleability or uniqueness of signatures is important this can
* cause issues. This forgery can be blocked by all verifiers forcing signers
* to use a normalized form.
*
* The lower-S form reduces the size of signatures slightly on average when
* variable length encodings (such as DER) are used and is cheap to verify,
* making it a good choice. Security of always using lower-S is assured because
* anyone can trivially modify a signature after the fact to enforce this
* property anyway.
*
* The lower S value is always between 0x1 and
* 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,
* inclusive.
*
* No other forms of ECDSA malleability are known and none seem likely, but
* there is no formal proof that ECDSA, even with this additional restriction,
* is free of other malleability. Commonly used serialization schemes will also
* accept various non-unique encodings, so care should be taken when this
* property is required for an application.
*
* The secp256k1_ecdsa_sign function will by default create signatures in the
* lower-S form, and secp256k1_ecdsa_verify will not accept others. In case
* signatures come from a system that cannot enforce this property,
* secp256k1_ecdsa_signature_normalize must be called before verification.
*/
SECP256K1_API int secp256k1_ecdsa_signature_normalize(
const secp256k1_context *ctx,
secp256k1_ecdsa_signature *sigout,
const secp256k1_ecdsa_signature *sigin
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3);
/** An implementation of RFC6979 (using HMAC-SHA256) as nonce generation function.
* If a data pointer is passed, it is assumed to be a pointer to 32 bytes of
* extra entropy.
*/
SECP256K1_API const secp256k1_nonce_function secp256k1_nonce_function_rfc6979;
/** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */
SECP256K1_API const secp256k1_nonce_function secp256k1_nonce_function_default;
/** Create an ECDSA signature.
*
* Returns: 1: signature created
* 0: the nonce generation function failed, or the secret key was invalid.
* Args: ctx: pointer to a context object (not secp256k1_context_static).
* Out: sig: pointer to an array where the signature will be placed.
* In: msghash32: the 32-byte message hash being signed.
* seckey: pointer to a 32-byte secret key.
* noncefp: pointer to a nonce generation function. If NULL,
* secp256k1_nonce_function_default is used.
* ndata: pointer to arbitrary data used by the nonce generation function
* (can be NULL). If it is non-NULL and
* secp256k1_nonce_function_default is used, then ndata must be a
* pointer to 32-bytes of additional data.
*
* The created signature is always in lower-S form. See
* secp256k1_ecdsa_signature_normalize for more details.
*/
SECP256K1_API int secp256k1_ecdsa_sign(
const secp256k1_context *ctx,
secp256k1_ecdsa_signature *sig,
const unsigned char *msghash32,
const unsigned char *seckey,
secp256k1_nonce_function noncefp,
const void *ndata
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Verify an elliptic curve secret key.
*
* A secret key is valid if it is not 0 and less than the secp256k1 curve order
* when interpreted as an integer (most significant byte first). The
* probability of choosing a 32-byte string uniformly at random which is an
* invalid secret key is negligible. However, if it does happen it should
* be assumed that the randomness source is severely broken and there should
* be no retry.
*
* Returns: 1: secret key is valid
* 0: secret key is invalid
* Args: ctx: pointer to a context object.
* In: seckey: pointer to a 32-byte secret key.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(
const secp256k1_context *ctx,
const unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
/** Compute the public key for a secret key.
*
* Returns: 1: secret was valid, public key stores.
* 0: secret was invalid, try again.
* Args: ctx: pointer to a context object (not secp256k1_context_static).
* Out: pubkey: pointer to the created public key.
* In: seckey: pointer to a 32-byte secret key.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Negates a secret key in place.
*
* Returns: 0 if the given secret key is invalid according to
* secp256k1_ec_seckey_verify. 1 otherwise
* Args: ctx: pointer to a context object
* In/Out: seckey: pointer to the 32-byte secret key to be negated. If the
* secret key is invalid according to
* secp256k1_ec_seckey_verify, this function returns 0 and
* seckey will be set to some unspecified value.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_negate(
const secp256k1_context *ctx,
unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
/** Same as secp256k1_ec_seckey_negate, but DEPRECATED. Will be removed in
* future versions. */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_negate(
const secp256k1_context *ctx,
unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2)
SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_negate instead");
/** Negates a public key in place.
*
* Returns: 1 always
* Args: ctx: pointer to a context object
* In/Out: pubkey: pointer to the public key to be negated.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_negate(
const secp256k1_context *ctx,
secp256k1_pubkey *pubkey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
/** Tweak a secret key by adding tweak to it.
*
* Returns: 0 if the arguments are invalid or the resulting secret key would be
* invalid (only when the tweak is the negation of the secret key). 1
* otherwise.
* Args: ctx: pointer to a context object.
* In/Out: seckey: pointer to a 32-byte secret key. If the secret key is
* invalid according to secp256k1_ec_seckey_verify, this
* function returns 0. seckey will be set to some unspecified
* value if this function returns 0.
* In: tweak32: pointer to a 32-byte tweak, which must be valid according to
* secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly
* random 32-byte tweaks, the chance of being invalid is
* negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_add(
const secp256k1_context *ctx,
unsigned char *seckey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Same as secp256k1_ec_seckey_tweak_add, but DEPRECATED. Will be removed in
* future versions. */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(
const secp256k1_context *ctx,
unsigned char *seckey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_tweak_add instead");
/** Tweak a public key by adding tweak times the generator to it.
*
* Returns: 0 if the arguments are invalid or the resulting public key would be
* invalid (only when the tweak is the negation of the corresponding
* secret key). 1 otherwise.
* Args: ctx: pointer to a context object.
* In/Out: pubkey: pointer to a public key object. pubkey will be set to an
* invalid value if this function returns 0.
* In: tweak32: pointer to a 32-byte tweak, which must be valid according to
* secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly
* random 32-byte tweaks, the chance of being invalid is
* negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(
const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Tweak a secret key by multiplying it by a tweak.
*
* Returns: 0 if the arguments are invalid. 1 otherwise.
* Args: ctx: pointer to a context object.
* In/Out: seckey: pointer to a 32-byte secret key. If the secret key is
* invalid according to secp256k1_ec_seckey_verify, this
* function returns 0. seckey will be set to some unspecified
* value if this function returns 0.
* In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to
* secp256k1_ec_seckey_verify, this function returns 0. For
* uniformly random 32-byte arrays the chance of being invalid
* is negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_mul(
const secp256k1_context *ctx,
unsigned char *seckey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Same as secp256k1_ec_seckey_tweak_mul, but DEPRECATED. Will be removed in
* future versions. */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(
const secp256k1_context *ctx,
unsigned char *seckey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_tweak_mul instead");
/** Tweak a public key by multiplying it by a tweak value.
*
* Returns: 0 if the arguments are invalid. 1 otherwise.
* Args: ctx: pointer to a context object.
* In/Out: pubkey: pointer to a public key object. pubkey will be set to an
* invalid value if this function returns 0.
* In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to
* secp256k1_ec_seckey_verify, this function returns 0. For
* uniformly random 32-byte arrays the chance of being invalid
* is negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(
const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Randomizes the context to provide enhanced protection against side-channel leakage.
*
* Returns: 1: randomization successful
* 0: error
* Args: ctx: pointer to a context object (not secp256k1_context_static).
* In: seed32: pointer to a 32-byte random seed (NULL resets to initial state).
*
* While secp256k1 code is written and tested to be constant-time no matter what
* secret values are, it is possible that a compiler may output code which is not,
* and also that the CPU may not emit the same radio frequencies or draw the same
* amount of power for all values. Randomization of the context shields against
* side-channel observations which aim to exploit secret-dependent behaviour in
* certain computations which involve secret keys.
*
* It is highly recommended to call this function on contexts returned from
* secp256k1_context_create or secp256k1_context_clone (or from the corresponding
* functions in secp256k1_preallocated.h) before using these contexts to call API
* functions that perform computations involving secret keys, e.g., signing and
* public key generation. It is possible to call this function more than once on
* the same context, and doing so before every few computations involving secret
* keys is recommended as a defense-in-depth measure. Randomization of the static
* context secp256k1_context_static is not supported.
*
* Currently, the random seed is mainly used for blinding multiplications of a
* secret scalar with the elliptic curve base point. Multiplications of this
* kind are performed by exactly those API functions which are documented to
* require a context that is not secp256k1_context_static. As a rule of thumb,
* these are all functions which take a secret key (or a keypair) as an input.
* A notable exception to that rule is the ECDH module, which relies on a different
* kind of elliptic curve point multiplication and thus does not benefit from
* enhanced protection against side-channel leakage currently.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize(
secp256k1_context *ctx,
const unsigned char *seed32
) SECP256K1_ARG_NONNULL(1);
/** Add a number of public keys together.
*
* Returns: 1: the sum of the public keys is valid.
* 0: the sum of the public keys is not valid.
* Args: ctx: pointer to a context object.
* Out: out: pointer to a public key object for placing the resulting public key.
* In: ins: pointer to array of pointers to public keys.
* n: the number of public keys to add together (must be at least 1).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine(
const secp256k1_context *ctx,
secp256k1_pubkey *out,
const secp256k1_pubkey * const *ins,
size_t n
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Compute a tagged hash as defined in BIP-340.
*
* This is useful for creating a message hash and achieving domain separation
* through an application-specific tag. This function returns
* SHA256(SHA256(tag)||SHA256(tag)||msg). Therefore, tagged hash
* implementations optimized for a specific tag can precompute the SHA256 state
* after hashing the tag hashes.
*
* Returns: 1 always.
* Args: ctx: pointer to a context object
* Out: hash32: pointer to a 32-byte array to store the resulting hash
* In: tag: pointer to an array containing the tag
* taglen: length of the tag array
* msg: pointer to an array containing the message
* msglen: length of the message array
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_tagged_sha256(
const secp256k1_context *ctx,
unsigned char *hash32,
const unsigned char *tag,
size_t taglen,
const unsigned char *msg,
size_t msglen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
#ifdef __cplusplus
}
#endif
#endif /* SECP256K1_H */

View File

@@ -1,63 +0,0 @@
#ifndef SECP256K1_ECDH_H
#define SECP256K1_ECDH_H
#include "secp256k1.h"
#ifdef __cplusplus
extern "C" {
#endif
/** A pointer to a function that hashes an EC point to obtain an ECDH secret
*
* Returns: 1 if the point was successfully hashed.
* 0 will cause secp256k1_ecdh to fail and return 0.
* Other return values are not allowed, and the behaviour of
* secp256k1_ecdh is undefined for other return values.
* Out: output: pointer to an array to be filled by the function
* In: x32: pointer to a 32-byte x coordinate
* y32: pointer to a 32-byte y coordinate
* data: arbitrary data pointer that is passed through
*/
typedef int (*secp256k1_ecdh_hash_function)(
unsigned char *output,
const unsigned char *x32,
const unsigned char *y32,
void *data
);
/** An implementation of SHA256 hash function that applies to compressed public key.
* Populates the output parameter with 32 bytes. */
SECP256K1_API const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256;
/** A default ECDH hash function (currently equal to secp256k1_ecdh_hash_function_sha256).
* Populates the output parameter with 32 bytes. */
SECP256K1_API const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default;
/** Compute an EC Diffie-Hellman secret in constant time
*
* Returns: 1: exponentiation was successful
* 0: scalar was invalid (zero or overflow) or hashfp returned 0
* Args: ctx: pointer to a context object.
* Out: output: pointer to an array to be filled by hashfp.
* In: pubkey: pointer to a secp256k1_pubkey containing an initialized public key.
* seckey: a 32-byte scalar with which to multiply the point.
* hashfp: pointer to a hash function. If NULL,
* secp256k1_ecdh_hash_function_sha256 is used
* (in which case, 32 bytes will be written to output).
* data: arbitrary data pointer that is passed through to hashfp
* (can be NULL for secp256k1_ecdh_hash_function_sha256).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh(
const secp256k1_context *ctx,
unsigned char *output,
const secp256k1_pubkey *pubkey,
const unsigned char *seckey,
secp256k1_ecdh_hash_function hashfp,
void *data
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
#ifdef __cplusplus
}
#endif
#endif /* SECP256K1_ECDH_H */

View File

@@ -1,200 +0,0 @@
#ifndef SECP256K1_ELLSWIFT_H
#define SECP256K1_ELLSWIFT_H
#include "secp256k1.h"
#ifdef __cplusplus
extern "C" {
#endif
/* This module provides an implementation of ElligatorSwift as well as a
* version of x-only ECDH using it (including compatibility with BIP324).
*
* ElligatorSwift is described in https://eprint.iacr.org/2022/759 by
* Chavez-Saab, Rodriguez-Henriquez, and Tibouchi. It permits encoding
* uniformly chosen public keys as 64-byte arrays which are indistinguishable
* from uniformly random arrays.
*
* Let f be the function from pairs of field elements to point X coordinates,
* defined as follows (all operations modulo p = 2^256 - 2^32 - 977)
* f(u,t):
* - Let C = 0xa2d2ba93507f1df233770c2a797962cc61f6d15da14ecd47d8d27ae1cd5f852,
* a square root of -3.
* - If u=0, set u=1 instead.
* - If t=0, set t=1 instead.
* - If u^3 + t^2 + 7 = 0, multiply t by 2.
* - Let X = (u^3 + 7 - t^2) / (2 * t)
* - Let Y = (X + t) / (C * u)
* - Return the first in [u + 4 * Y^2, (-X/Y - u) / 2, (X/Y - u) / 2] that is an
* X coordinate on the curve (at least one of them is, for any u and t).
*
* Then an ElligatorSwift encoding of x consists of the 32-byte big-endian
* encodings of field elements u and t concatenated, where f(u,t) = x.
* The encoding algorithm is described in the paper, and effectively picks a
* uniformly random pair (u,t) among those which encode x.
*
* If the Y coordinate is relevant, it is given the same parity as t.
*
* Changes w.r.t. the paper:
* - The u=0, t=0, and u^3+t^2+7=0 conditions result in decoding to the point
* at infinity in the paper. Here they are remapped to finite points.
* - The paper uses an additional encoding bit for the parity of y. Here the
* parity of t is used (negating t does not affect the decoded x coordinate,
* so this is possible).
*
* For mathematical background about the scheme, see the doc/ellswift.md file.
*/
/** A pointer to a function used by secp256k1_ellswift_xdh to hash the shared X
* coordinate along with the encoded public keys to a uniform shared secret.
*
* Returns: 1 if a shared secret was successfully computed.
* 0 will cause secp256k1_ellswift_xdh to fail and return 0.
* Other return values are not allowed, and the behaviour of
* secp256k1_ellswift_xdh is undefined for other return values.
* Out: output: pointer to an array to be filled by the function
* In: x32: pointer to the 32-byte serialized X coordinate
* of the resulting shared point (will not be NULL)
* ell_a64: pointer to the 64-byte encoded public key of party A
* (will not be NULL)
* ell_b64: pointer to the 64-byte encoded public key of party B
* (will not be NULL)
* data: arbitrary data pointer that is passed through
*/
typedef int (*secp256k1_ellswift_xdh_hash_function)(
unsigned char *output,
const unsigned char *x32,
const unsigned char *ell_a64,
const unsigned char *ell_b64,
void *data
);
/** An implementation of an secp256k1_ellswift_xdh_hash_function which uses
* SHA256(prefix64 || ell_a64 || ell_b64 || x32), where prefix64 is the 64-byte
* array pointed to by data. */
SECP256K1_API const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_prefix;
/** An implementation of an secp256k1_ellswift_xdh_hash_function compatible with
* BIP324. It returns H_tag(ell_a64 || ell_b64 || x32), where H_tag is the
* BIP340 tagged hash function with tag "bip324_ellswift_xonly_ecdh". Equivalent
* to secp256k1_ellswift_xdh_hash_function_prefix with prefix64 set to
* SHA256("bip324_ellswift_xonly_ecdh")||SHA256("bip324_ellswift_xonly_ecdh").
* The data argument is ignored. */
SECP256K1_API const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_bip324;
/** Construct a 64-byte ElligatorSwift encoding of a given pubkey.
*
* Returns: 1 always.
* Args: ctx: pointer to a context object
* Out: ell64: pointer to a 64-byte array to be filled
* In: pubkey: pointer to a secp256k1_pubkey containing an
* initialized public key
* rnd32: pointer to 32 bytes of randomness
*
* It is recommended that rnd32 consists of 32 uniformly random bytes, not
* known to any adversary trying to detect whether public keys are being
* encoded, though 16 bytes of randomness (padded to an array of 32 bytes,
* e.g., with zeros) suffice to make the result indistinguishable from
* uniform. The randomness in rnd32 must not be a deterministic function of
* the pubkey (it can be derived from the private key, though).
*
* It is not guaranteed that the computed encoding is stable across versions
* of the library, even if all arguments to this function (including rnd32)
* are the same.
*
* This function runs in variable time.
*/
SECP256K1_API int secp256k1_ellswift_encode(
const secp256k1_context *ctx,
unsigned char *ell64,
const secp256k1_pubkey *pubkey,
const unsigned char *rnd32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Decode a 64-bytes ElligatorSwift encoded public key.
*
* Returns: always 1
* Args: ctx: pointer to a context object
* Out: pubkey: pointer to a secp256k1_pubkey that will be filled
* In: ell64: pointer to a 64-byte array to decode
*
* This function runs in variable time.
*/
SECP256K1_API int secp256k1_ellswift_decode(
const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const unsigned char *ell64
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Compute an ElligatorSwift public key for a secret key.
*
* Returns: 1: secret was valid, public key was stored.
* 0: secret was invalid, try again.
* Args: ctx: pointer to a context object
* Out: ell64: pointer to a 64-byte array to receive the ElligatorSwift
* public key
* In: seckey32: pointer to a 32-byte secret key
* auxrnd32: (optional) pointer to 32 bytes of randomness
*
* Constant time in seckey and auxrnd32, but not in the resulting public key.
*
* It is recommended that auxrnd32 contains 32 uniformly random bytes, though
* it is optional (and does result in encodings that are indistinguishable from
* uniform even without any auxrnd32). It differs from the (mandatory) rnd32
* argument to secp256k1_ellswift_encode in this regard.
*
* This function can be used instead of calling secp256k1_ec_pubkey_create
* followed by secp256k1_ellswift_encode. It is safer, as it uses the secret
* key as entropy for the encoding (supplemented with auxrnd32, if provided).
*
* Like secp256k1_ellswift_encode, this function does not guarantee that the
* computed encoding is stable across versions of the library, even if all
* arguments (including auxrnd32) are the same.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ellswift_create(
const secp256k1_context *ctx,
unsigned char *ell64,
const unsigned char *seckey32,
const unsigned char *auxrnd32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Given a private key, and ElligatorSwift public keys sent in both directions,
* compute a shared secret using x-only Elliptic Curve Diffie-Hellman (ECDH).
*
* Returns: 1: shared secret was successfully computed
* 0: secret was invalid or hashfp returned 0
* Args: ctx: pointer to a context object.
* Out: output: pointer to an array to be filled by hashfp.
* In: ell_a64: pointer to the 64-byte encoded public key of party A
* (will not be NULL)
* ell_b64: pointer to the 64-byte encoded public key of party B
* (will not be NULL)
* seckey32: pointer to our 32-byte secret key
* party: boolean indicating which party we are: zero if we are
* party A, non-zero if we are party B. seckey32 must be
* the private key corresponding to that party's ell_?64.
* This correspondence is not checked.
* hashfp: pointer to a hash function.
* data: arbitrary data pointer passed through to hashfp.
*
* Constant time in seckey32.
*
* This function is more efficient than decoding the public keys, and performing
* ECDH on them.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ellswift_xdh(
const secp256k1_context *ctx,
unsigned char *output,
const unsigned char *ell_a64,
const unsigned char *ell_b64,
const unsigned char *seckey32,
int party,
secp256k1_ellswift_xdh_hash_function hashfp,
void *data
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(7);
#ifdef __cplusplus
}
#endif
#endif /* SECP256K1_ELLSWIFT_H */

View File

@@ -1,250 +0,0 @@
#ifndef SECP256K1_EXTRAKEYS_H
#define SECP256K1_EXTRAKEYS_H
#include "secp256k1.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Opaque data structure that holds a parsed and valid "x-only" public key.
* An x-only pubkey encodes a point whose Y coordinate is even. It is
* serialized using only its X coordinate (32 bytes). See BIP-340 for more
* information about x-only pubkeys.
*
* The exact representation of data inside is implementation defined and not
* guaranteed to be portable between different platforms or versions. It is
* however guaranteed to be 64 bytes in size, and can be safely copied/moved.
* If you need to convert to a format suitable for storage, transmission, use
* use secp256k1_xonly_pubkey_serialize and secp256k1_xonly_pubkey_parse. To
* compare keys, use secp256k1_xonly_pubkey_cmp.
*/
typedef struct secp256k1_xonly_pubkey {
unsigned char data[64];
} secp256k1_xonly_pubkey;
/** Opaque data structure that holds a keypair consisting of a secret and a
* public key.
*
* The exact representation of data inside is implementation defined and not
* guaranteed to be portable between different platforms or versions. It is
* however guaranteed to be 96 bytes in size, and can be safely copied/moved.
*/
typedef struct secp256k1_keypair {
unsigned char data[96];
} secp256k1_keypair;
/** Parse a 32-byte sequence into a xonly_pubkey object.
*
* Returns: 1 if the public key was fully valid.
* 0 if the public key could not be parsed or is invalid.
*
* Args: ctx: pointer to a context object.
* Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a
* parsed version of input. If not, it's set to an invalid value.
* In: input32: pointer to a serialized xonly_pubkey.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_parse(
const secp256k1_context *ctx,
secp256k1_xonly_pubkey *pubkey,
const unsigned char *input32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Serialize an xonly_pubkey object into a 32-byte sequence.
*
* Returns: 1 always.
*
* Args: ctx: pointer to a context object.
* Out: output32: pointer to a 32-byte array to place the serialized key in.
* In: pubkey: pointer to a secp256k1_xonly_pubkey containing an initialized public key.
*/
SECP256K1_API int secp256k1_xonly_pubkey_serialize(
const secp256k1_context *ctx,
unsigned char *output32,
const secp256k1_xonly_pubkey *pubkey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Compare two x-only public keys using lexicographic order
*
* Returns: <0 if the first public key is less than the second
* >0 if the first public key is greater than the second
* 0 if the two public keys are equal
* Args: ctx: pointer to a context object.
* In: pubkey1: first public key to compare
* pubkey2: second public key to compare
*/
SECP256K1_API int secp256k1_xonly_pubkey_cmp(
const secp256k1_context *ctx,
const secp256k1_xonly_pubkey *pk1,
const secp256k1_xonly_pubkey *pk2
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Converts a secp256k1_pubkey into a secp256k1_xonly_pubkey.
*
* Returns: 1 always.
*
* Args: ctx: pointer to a context object.
* Out: xonly_pubkey: pointer to an x-only public key object for placing the converted public key.
* pk_parity: Ignored if NULL. Otherwise, pointer to an integer that
* will be set to 1 if the point encoded by xonly_pubkey is
* the negation of the pubkey and set to 0 otherwise.
* In: pubkey: pointer to a public key that is converted.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_from_pubkey(
const secp256k1_context *ctx,
secp256k1_xonly_pubkey *xonly_pubkey,
int *pk_parity,
const secp256k1_pubkey *pubkey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
/** Tweak an x-only public key by adding the generator multiplied with tweak32
* to it.
*
* Note that the resulting point can not in general be represented by an x-only
* pubkey because it may have an odd Y coordinate. Instead, the output_pubkey
* is a normal secp256k1_pubkey.
*
* Returns: 0 if the arguments are invalid or the resulting public key would be
* invalid (only when the tweak is the negation of the corresponding
* secret key). 1 otherwise.
*
* Args: ctx: pointer to a context object.
* Out: output_pubkey: pointer to a public key to store the result. Will be set
* to an invalid value if this function returns 0.
* In: internal_pubkey: pointer to an x-only pubkey to apply the tweak to.
* tweak32: pointer to a 32-byte tweak, which must be valid
* according to secp256k1_ec_seckey_verify or 32 zero
* bytes. For uniformly random 32-byte tweaks, the chance of
* being invalid is negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add(
const secp256k1_context *ctx,
secp256k1_pubkey *output_pubkey,
const secp256k1_xonly_pubkey *internal_pubkey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Checks that a tweaked pubkey is the result of calling
* secp256k1_xonly_pubkey_tweak_add with internal_pubkey and tweak32.
*
* The tweaked pubkey is represented by its 32-byte x-only serialization and
* its pk_parity, which can both be obtained by converting the result of
* tweak_add to a secp256k1_xonly_pubkey.
*
* Note that this alone does _not_ verify that the tweaked pubkey is a
* commitment. If the tweak is not chosen in a specific way, the tweaked pubkey
* can easily be the result of a different internal_pubkey and tweak.
*
* Returns: 0 if the arguments are invalid or the tweaked pubkey is not the
* result of tweaking the internal_pubkey with tweak32. 1 otherwise.
* Args: ctx: pointer to a context object.
* In: tweaked_pubkey32: pointer to a serialized xonly_pubkey.
* tweaked_pk_parity: the parity of the tweaked pubkey (whose serialization
* is passed in as tweaked_pubkey32). This must match the
* pk_parity value that is returned when calling
* secp256k1_xonly_pubkey with the tweaked pubkey, or
* this function will fail.
* internal_pubkey: pointer to an x-only public key object to apply the tweak to.
* tweak32: pointer to a 32-byte tweak.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add_check(
const secp256k1_context *ctx,
const unsigned char *tweaked_pubkey32,
int tweaked_pk_parity,
const secp256k1_xonly_pubkey *internal_pubkey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
/** Compute the keypair for a valid secret key.
*
* See the documentation of `secp256k1_ec_seckey_verify` for more information
* about the validity of secret keys.
*
* Returns: 1: secret key is valid
* 0: secret key is invalid
* Args: ctx: pointer to a context object (not secp256k1_context_static).
* Out: keypair: pointer to the created keypair.
* In: seckey: pointer to a 32-byte secret key.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_create(
const secp256k1_context *ctx,
secp256k1_keypair *keypair,
const unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Get the secret key from a keypair.
*
* Returns: 1 always.
* Args: ctx: pointer to a context object.
* Out: seckey: pointer to a 32-byte buffer for the secret key.
* In: keypair: pointer to a keypair.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_sec(
const secp256k1_context *ctx,
unsigned char *seckey,
const secp256k1_keypair *keypair
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Get the public key from a keypair.
*
* Returns: 1 always.
* Args: ctx: pointer to a context object.
* Out: pubkey: pointer to a pubkey object, set to the keypair public key.
* In: keypair: pointer to a keypair.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_pub(
const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const secp256k1_keypair *keypair
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Get the x-only public key from a keypair.
*
* This is the same as calling secp256k1_keypair_pub and then
* secp256k1_xonly_pubkey_from_pubkey.
*
* Returns: 1 always.
* Args: ctx: pointer to a context object.
* Out: pubkey: pointer to an xonly_pubkey object, set to the keypair
* public key after converting it to an xonly_pubkey.
* pk_parity: Ignored if NULL. Otherwise, pointer to an integer that will be set to the
* pk_parity argument of secp256k1_xonly_pubkey_from_pubkey.
* In: keypair: pointer to a keypair.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_pub(
const secp256k1_context *ctx,
secp256k1_xonly_pubkey *pubkey,
int *pk_parity,
const secp256k1_keypair *keypair
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
/** Tweak a keypair by adding tweak32 to the secret key and updating the public
* key accordingly.
*
* Calling this function and then secp256k1_keypair_pub results in the same
* public key as calling secp256k1_keypair_xonly_pub and then
* secp256k1_xonly_pubkey_tweak_add.
*
* Returns: 0 if the arguments are invalid or the resulting keypair would be
* invalid (only when the tweak is the negation of the keypair's
* secret key). 1 otherwise.
*
* Args: ctx: pointer to a context object.
* In/Out: keypair: pointer to a keypair to apply the tweak to. Will be set to
* an invalid value if this function returns 0.
* In: tweak32: pointer to a 32-byte tweak, which must be valid according to
* secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly
* random 32-byte tweaks, the chance of being invalid is
* negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_tweak_add(
const secp256k1_context *ctx,
secp256k1_keypair *keypair,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
#ifdef __cplusplus
}
#endif
#endif /* SECP256K1_EXTRAKEYS_H */

View File

@@ -1,588 +0,0 @@
#ifndef SECP256K1_MUSIG_H
#define SECP256K1_MUSIG_H
#include "secp256k1_extrakeys.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdint.h>
/** This module implements BIP 327 "MuSig2 for BIP340-compatible
* Multi-Signatures"
* (https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki)
* v1.0.0. You can find an example demonstrating the musig module in
* examples/musig.c.
*
* The module also supports BIP 341 ("Taproot") public key tweaking.
*
* It is recommended to read the documentation in this include file carefully.
* Further notes on API usage can be found in doc/musig.md
*
* Since the first version of MuSig is essentially replaced by MuSig2, we use
* MuSig, musig and MuSig2 synonymously unless noted otherwise.
*/
/** Opaque data structures
*
* The exact representation of data inside the opaque data structures is
* implementation defined and not guaranteed to be portable between different
* platforms or versions. With the exception of `secp256k1_musig_secnonce`, the
* data structures can be safely copied/moved. If you need to convert to a
* format suitable for storage, transmission, or comparison, use the
* corresponding serialization and parsing functions.
*/
/** Opaque data structure that caches information about public key aggregation.
*
* Guaranteed to be 197 bytes in size. No serialization and parsing functions
* (yet).
*/
typedef struct secp256k1_musig_keyagg_cache {
unsigned char data[197];
} secp256k1_musig_keyagg_cache;
/** Opaque data structure that holds a signer's _secret_ nonce.
*
* Guaranteed to be 132 bytes in size.
*
* WARNING: This structure MUST NOT be copied or read or written to directly. A
* signer who is online throughout the whole process and can keep this
* structure in memory can use the provided API functions for a safe standard
* workflow.
*
* Copying this data structure can result in nonce reuse which will leak the
* secret signing key.
*/
typedef struct secp256k1_musig_secnonce {
unsigned char data[132];
} secp256k1_musig_secnonce;
/** Opaque data structure that holds a signer's public nonce.
*
* Guaranteed to be 132 bytes in size. Serialized and parsed with
* `musig_pubnonce_serialize` and `musig_pubnonce_parse`.
*/
typedef struct secp256k1_musig_pubnonce {
unsigned char data[132];
} secp256k1_musig_pubnonce;
/** Opaque data structure that holds an aggregate public nonce.
*
* Guaranteed to be 132 bytes in size. Serialized and parsed with
* `musig_aggnonce_serialize` and `musig_aggnonce_parse`.
*/
typedef struct secp256k1_musig_aggnonce {
unsigned char data[132];
} secp256k1_musig_aggnonce;
/** Opaque data structure that holds a MuSig session.
*
* This structure is not required to be kept secret for the signing protocol to
* be secure. Guaranteed to be 133 bytes in size. No serialization and parsing
* functions (yet).
*/
typedef struct secp256k1_musig_session {
unsigned char data[133];
} secp256k1_musig_session;
/** Opaque data structure that holds a partial MuSig signature.
*
* Guaranteed to be 36 bytes in size. Serialized and parsed with
* `musig_partial_sig_serialize` and `musig_partial_sig_parse`.
*/
typedef struct secp256k1_musig_partial_sig {
unsigned char data[36];
} secp256k1_musig_partial_sig;
/** Parse a signer's public nonce.
*
* Returns: 1 when the nonce could be parsed, 0 otherwise.
* Args: ctx: pointer to a context object
* Out: nonce: pointer to a nonce object
* In: in66: pointer to the 66-byte nonce to be parsed
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubnonce_parse(
const secp256k1_context *ctx,
secp256k1_musig_pubnonce *nonce,
const unsigned char *in66
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Serialize a signer's public nonce
*
* Returns: 1 always
* Args: ctx: pointer to a context object
* Out: out66: pointer to a 66-byte array to store the serialized nonce
* In: nonce: pointer to the nonce
*/
SECP256K1_API int secp256k1_musig_pubnonce_serialize(
const secp256k1_context *ctx,
unsigned char *out66,
const secp256k1_musig_pubnonce *nonce
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Parse an aggregate public nonce.
*
* Returns: 1 when the nonce could be parsed, 0 otherwise.
* Args: ctx: pointer to a context object
* Out: nonce: pointer to a nonce object
* In: in66: pointer to the 66-byte nonce to be parsed
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_aggnonce_parse(
const secp256k1_context *ctx,
secp256k1_musig_aggnonce *nonce,
const unsigned char *in66
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Serialize an aggregate public nonce
*
* Returns: 1 always
* Args: ctx: pointer to a context object
* Out: out66: pointer to a 66-byte array to store the serialized nonce
* In: nonce: pointer to the nonce
*/
SECP256K1_API int secp256k1_musig_aggnonce_serialize(
const secp256k1_context *ctx,
unsigned char *out66,
const secp256k1_musig_aggnonce *nonce
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Parse a MuSig partial signature.
*
* Returns: 1 when the signature could be parsed, 0 otherwise.
* Args: ctx: pointer to a context object
* Out: sig: pointer to a signature object
* In: in32: pointer to the 32-byte signature to be parsed
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_parse(
const secp256k1_context *ctx,
secp256k1_musig_partial_sig *sig,
const unsigned char *in32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Serialize a MuSig partial signature
*
* Returns: 1 always
* Args: ctx: pointer to a context object
* Out: out32: pointer to a 32-byte array to store the serialized signature
* In: sig: pointer to the signature
*/
SECP256K1_API int secp256k1_musig_partial_sig_serialize(
const secp256k1_context *ctx,
unsigned char *out32,
const secp256k1_musig_partial_sig *sig
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Computes an aggregate public key and uses it to initialize a keyagg_cache
*
* Different orders of `pubkeys` result in different `agg_pk`s.
*
* Before aggregating, the pubkeys can be sorted with `secp256k1_ec_pubkey_sort`
* which ensures the same `agg_pk` result for the same multiset of pubkeys.
* This is useful to do before `pubkey_agg`, such that the order of pubkeys
* does not affect the aggregate public key.
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* Out: agg_pk: the MuSig-aggregated x-only public key. If you do not need it,
* this arg can be NULL.
* keyagg_cache: if non-NULL, pointer to a musig_keyagg_cache struct that
* is required for signing (or observing the signing session
* and verifying partial signatures).
* In: pubkeys: input array of pointers to public keys to aggregate. The order
* is important; a different order will result in a different
* aggregate public key.
* n_pubkeys: length of pubkeys array. Must be greater than 0.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_agg(
const secp256k1_context *ctx,
secp256k1_xonly_pubkey *agg_pk,
secp256k1_musig_keyagg_cache *keyagg_cache,
const secp256k1_pubkey * const *pubkeys,
size_t n_pubkeys
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(4);
/** Obtain the aggregate public key from a keyagg_cache.
*
* This is only useful if you need the non-xonly public key, in particular for
* plain (non-xonly) tweaking or batch-verifying multiple key aggregations
* (not implemented).
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* Out: agg_pk: the MuSig-aggregated public key.
* In: keyagg_cache: pointer to a `musig_keyagg_cache` struct initialized by
* `musig_pubkey_agg`
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_get(
const secp256k1_context *ctx,
secp256k1_pubkey *agg_pk,
const secp256k1_musig_keyagg_cache *keyagg_cache
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Apply plain "EC" tweaking to a public key in a given keyagg_cache by adding
* the generator multiplied with `tweak32` to it. This is useful for deriving
* child keys from an aggregate public key via BIP 32 where `tweak32` is set to
* a hash as defined in BIP 32.
*
* Callers are responsible for deriving `tweak32` in a way that does not reduce
* the security of MuSig (for example, by following BIP 32).
*
* The tweaking method is the same as `secp256k1_ec_pubkey_tweak_add`. So after
* the following pseudocode buf and buf2 have identical contents (absent
* earlier failures).
*
* secp256k1_musig_pubkey_agg(..., keyagg_cache, pubkeys, ...)
* secp256k1_musig_pubkey_get(..., agg_pk, keyagg_cache)
* secp256k1_musig_pubkey_ec_tweak_add(..., output_pk, tweak32, keyagg_cache)
* secp256k1_ec_pubkey_serialize(..., buf, ..., output_pk, ...)
* secp256k1_ec_pubkey_tweak_add(..., agg_pk, tweak32)
* secp256k1_ec_pubkey_serialize(..., buf2, ..., agg_pk, ...)
*
* This function is required if you want to _sign_ for a tweaked aggregate key.
* If you are only computing a public key but not intending to create a
* signature for it, use `secp256k1_ec_pubkey_tweak_add` instead.
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* Out: output_pubkey: pointer to a public key to store the result. Will be set
* to an invalid value if this function returns 0. If you
* do not need it, this arg can be NULL.
* In/Out: keyagg_cache: pointer to a `musig_keyagg_cache` struct initialized by
* `musig_pubkey_agg`
* In: tweak32: pointer to a 32-byte tweak. The tweak is valid if it passes
* `secp256k1_ec_seckey_verify` and is not equal to the
* secret key corresponding to the public key represented
* by keyagg_cache or its negation. For uniformly random
* 32-byte arrays the chance of being invalid is
* negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_ec_tweak_add(
const secp256k1_context *ctx,
secp256k1_pubkey *output_pubkey,
secp256k1_musig_keyagg_cache *keyagg_cache,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Apply x-only tweaking to a public key in a given keyagg_cache by adding the
* generator multiplied with `tweak32` to it. This is useful for creating
* Taproot outputs where `tweak32` is set to a TapTweak hash as defined in BIP
* 341.
*
* Callers are responsible for deriving `tweak32` in a way that does not reduce
* the security of MuSig (for example, by following Taproot BIP 341).
*
* The tweaking method is the same as `secp256k1_xonly_pubkey_tweak_add`. So in
* the following pseudocode xonly_pubkey_tweak_add_check (absent earlier
* failures) returns 1.
*
* secp256k1_musig_pubkey_agg(..., agg_pk, keyagg_cache, pubkeys, ...)
* secp256k1_musig_pubkey_xonly_tweak_add(..., output_pk, keyagg_cache, tweak32)
* secp256k1_xonly_pubkey_serialize(..., buf, output_pk)
* secp256k1_xonly_pubkey_tweak_add_check(..., buf, ..., agg_pk, tweak32)
*
* This function is required if you want to _sign_ for a tweaked aggregate key.
* If you are only computing a public key but not intending to create a
* signature for it, use `secp256k1_xonly_pubkey_tweak_add` instead.
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* Out: output_pubkey: pointer to a public key to store the result. Will be set
* to an invalid value if this function returns 0. If you
* do not need it, this arg can be NULL.
* In/Out: keyagg_cache: pointer to a `musig_keyagg_cache` struct initialized by
* `musig_pubkey_agg`
* In: tweak32: pointer to a 32-byte tweak. The tweak is valid if it passes
* `secp256k1_ec_seckey_verify` and is not equal to the
* secret key corresponding to the public key represented
* by keyagg_cache or its negation. For uniformly random
* 32-byte arrays the chance of being invalid is
* negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_xonly_tweak_add(
const secp256k1_context *ctx,
secp256k1_pubkey *output_pubkey,
secp256k1_musig_keyagg_cache *keyagg_cache,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Starts a signing session by generating a nonce
*
* This function outputs a secret nonce that will be required for signing and a
* corresponding public nonce that is intended to be sent to other signers.
*
* MuSig differs from regular Schnorr signing in that implementers _must_ take
* special care to not reuse a nonce. This can be ensured by following these rules:
*
* 1. Each call to this function must have a UNIQUE session_secrand32 that must
* NOT BE REUSED in subsequent calls to this function and must be KEPT
* SECRET (even from other signers).
* 2. If you already know the seckey, message or aggregate public key
* cache, they can be optionally provided to derive the nonce and increase
* misuse-resistance. The extra_input32 argument can be used to provide
* additional data that does not repeat in normal scenarios, such as the
* current time.
* 3. Avoid copying (or serializing) the secnonce. This reduces the possibility
* that it is used more than once for signing.
*
* If you don't have access to good randomness for session_secrand32, but you
* have access to a non-repeating counter, then see
* secp256k1_musig_nonce_gen_counter.
*
* Remember that nonce reuse will leak the secret key!
* Note that using the same seckey for multiple MuSig sessions is fine.
*
* Returns: 0 if the arguments are invalid and 1 otherwise
* Args: ctx: pointer to a context object (not secp256k1_context_static)
* Out: secnonce: pointer to a structure to store the secret nonce
* pubnonce: pointer to a structure to store the public nonce
* In/Out:
* session_secrand32: a 32-byte session_secrand32 as explained above. Must be unique to this
* call to secp256k1_musig_nonce_gen and must be uniformly
* random. If the function call is successful, the
* session_secrand32 buffer is invalidated to prevent reuse.
* In:
* seckey: the 32-byte secret key that will later be used for signing, if
* already known (can be NULL)
* pubkey: public key of the signer creating the nonce. The secnonce
* output of this function cannot be used to sign for any
* other public key. While the public key should correspond
* to the provided seckey, a mismatch will not cause the
* function to return 0.
* msg32: the 32-byte message that will later be signed, if already known
* (can be NULL)
* keyagg_cache: pointer to the keyagg_cache that was used to create the aggregate
* (and potentially tweaked) public key if already known
* (can be NULL)
* extra_input32: an optional 32-byte array that is input to the nonce
* derivation function (can be NULL)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_nonce_gen(
const secp256k1_context *ctx,
secp256k1_musig_secnonce *secnonce,
secp256k1_musig_pubnonce *pubnonce,
unsigned char *session_secrand32,
const unsigned char *seckey,
const secp256k1_pubkey *pubkey,
const unsigned char *msg32,
const secp256k1_musig_keyagg_cache *keyagg_cache,
const unsigned char *extra_input32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(6);
/** Alternative way to generate a nonce and start a signing session
*
* This function outputs a secret nonce that will be required for signing and a
* corresponding public nonce that is intended to be sent to other signers.
*
* This function differs from `secp256k1_musig_nonce_gen` by accepting a
* non-repeating counter value instead of a secret random value. This requires
* that a secret key is provided to `secp256k1_musig_nonce_gen_counter`
* (through the keypair argument), as opposed to `secp256k1_musig_nonce_gen`
* where the seckey argument is optional.
*
* MuSig differs from regular Schnorr signing in that implementers _must_ take
* special care to not reuse a nonce. This can be ensured by following these rules:
*
* 1. The nonrepeating_cnt argument must be a counter value that never repeats,
* i.e., you must never call `secp256k1_musig_nonce_gen_counter` twice with
* the same keypair and nonrepeating_cnt value. For example, this implies
* that if the same keypair is used with `secp256k1_musig_nonce_gen_counter`
* on multiple devices, none of the devices should have the same counter
* value as any other device.
* 2. If the seckey, message or aggregate public key cache is already available
* at this stage, any of these can be optionally provided, in which case
* they will be used in the derivation of the nonce and increase
* misuse-resistance. The extra_input32 argument can be used to provide
* additional data that does not repeat in normal scenarios, such as the
* current time.
* 3. Avoid copying (or serializing) the secnonce. This reduces the possibility
* that it is used more than once for signing.
*
* Remember that nonce reuse will leak the secret key!
* Note that using the same keypair for multiple MuSig sessions is fine.
*
* Returns: 0 if the arguments are invalid and 1 otherwise
* Args: ctx: pointer to a context object (not secp256k1_context_static)
* Out: secnonce: pointer to a structure to store the secret nonce
* pubnonce: pointer to a structure to store the public nonce
* In:
* nonrepeating_cnt: the value of a counter as explained above. Must be
* unique to this call to secp256k1_musig_nonce_gen.
* keypair: keypair of the signer creating the nonce. The secnonce
* output of this function cannot be used to sign for any
* other keypair.
* msg32: the 32-byte message that will later be signed, if already known
* (can be NULL)
* keyagg_cache: pointer to the keyagg_cache that was used to create the aggregate
* (and potentially tweaked) public key if already known
* (can be NULL)
* extra_input32: an optional 32-byte array that is input to the nonce
* derivation function (can be NULL)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_nonce_gen_counter(
const secp256k1_context *ctx,
secp256k1_musig_secnonce *secnonce,
secp256k1_musig_pubnonce *pubnonce,
uint64_t nonrepeating_cnt,
const secp256k1_keypair *keypair,
const unsigned char *msg32,
const secp256k1_musig_keyagg_cache *keyagg_cache,
const unsigned char *extra_input32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
/** Aggregates the nonces of all signers into a single nonce
*
* This can be done by an untrusted party to reduce the communication
* between signers. Instead of everyone sending nonces to everyone else, there
* can be one party receiving all nonces, aggregating the nonces with this
* function and then sending only the aggregate nonce back to the signers.
*
* If the aggregator does not compute the aggregate nonce correctly, the final
* signature will be invalid.
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* Out: aggnonce: pointer to an aggregate public nonce object for
* musig_nonce_process
* In: pubnonces: array of pointers to public nonces sent by the
* signers
* n_pubnonces: number of elements in the pubnonces array. Must be
* greater than 0.
*/
SECP256K1_API int secp256k1_musig_nonce_agg(
const secp256k1_context *ctx,
secp256k1_musig_aggnonce *aggnonce,
const secp256k1_musig_pubnonce * const *pubnonces,
size_t n_pubnonces
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Takes the aggregate nonce and creates a session that is required for signing
* and verification of partial signatures.
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* Out: session: pointer to a struct to store the session
* In: aggnonce: pointer to an aggregate public nonce object that is the
* output of musig_nonce_agg
* msg32: the 32-byte message to sign
* keyagg_cache: pointer to the keyagg_cache that was used to create the
* aggregate (and potentially tweaked) pubkey
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_nonce_process(
const secp256k1_context *ctx,
secp256k1_musig_session *session,
const secp256k1_musig_aggnonce *aggnonce,
const unsigned char *msg32,
const secp256k1_musig_keyagg_cache *keyagg_cache
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
/** Produces a partial signature
*
* This function overwrites the given secnonce with zeros and will abort if given a
* secnonce that is all zeros. This is a best effort attempt to protect against nonce
* reuse. However, this is of course easily defeated if the secnonce has been
* copied (or serialized). Remember that nonce reuse will leak the secret key!
*
* For signing to succeed, the secnonce provided to this function must have
* been generated for the provided keypair. This means that when signing for a
* keypair consisting of a seckey and pubkey, the secnonce must have been
* created by calling musig_nonce_gen with that pubkey. Otherwise, the
* illegal_callback is called.
*
* This function does not verify the output partial signature, deviating from
* the BIP 327 specification. It is recommended to verify the output partial
* signature with `secp256k1_musig_partial_sig_verify` to prevent random or
* adversarially provoked computation errors.
*
* Returns: 0 if the arguments are invalid or the provided secnonce has already
* been used for signing, 1 otherwise
* Args: ctx: pointer to a context object
* Out: partial_sig: pointer to struct to store the partial signature
* In/Out: secnonce: pointer to the secnonce struct created in
* musig_nonce_gen that has been never used in a
* partial_sign call before and has been created for the
* keypair
* In: keypair: pointer to keypair to sign the message with
* keyagg_cache: pointer to the keyagg_cache that was output when the
* aggregate public key for this session
* session: pointer to the session that was created with
* musig_nonce_process
*/
SECP256K1_API int secp256k1_musig_partial_sign(
const secp256k1_context *ctx,
secp256k1_musig_partial_sig *partial_sig,
secp256k1_musig_secnonce *secnonce,
const secp256k1_keypair *keypair,
const secp256k1_musig_keyagg_cache *keyagg_cache,
const secp256k1_musig_session *session
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
/** Verifies an individual signer's partial signature
*
* The signature is verified for a specific signing session. In order to avoid
* accidentally verifying a signature from a different or non-existing signing
* session, you must ensure the following:
* 1. The `keyagg_cache` argument is identical to the one used to create the
* `session` with `musig_nonce_process`.
* 2. The `pubkey` argument must be identical to the one sent by the signer
* before aggregating it with `musig_pubkey_agg` to create the
* `keyagg_cache`.
* 3. The `pubnonce` argument must be identical to the one sent by the signer
* before aggregating it with `musig_nonce_agg` and using the result to
* create the `session` with `musig_nonce_process`.
*
* It is not required to call this function in regular MuSig sessions, because
* if any partial signature does not verify, the final signature will not
* verify either, so the problem will be caught. However, this function
* provides the ability to identify which specific partial signature fails
* verification.
*
* Returns: 0 if the arguments are invalid or the partial signature does not
* verify, 1 otherwise
* Args ctx: pointer to a context object
* In: partial_sig: pointer to partial signature to verify, sent by
* the signer associated with `pubnonce` and `pubkey`
* pubnonce: public nonce of the signer in the signing session
* pubkey: public key of the signer in the signing session
* keyagg_cache: pointer to the keyagg_cache that was output when the
* aggregate public key for this signing session
* session: pointer to the session that was created with
* `musig_nonce_process`
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_verify(
const secp256k1_context *ctx,
const secp256k1_musig_partial_sig *partial_sig,
const secp256k1_musig_pubnonce *pubnonce,
const secp256k1_pubkey *pubkey,
const secp256k1_musig_keyagg_cache *keyagg_cache,
const secp256k1_musig_session *session
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
/** Aggregates partial signatures
*
* Returns: 0 if the arguments are invalid, 1 otherwise (which does NOT mean
* the resulting signature verifies).
* Args: ctx: pointer to a context object
* Out: sig64: complete (but possibly invalid) Schnorr signature
* In: session: pointer to the session that was created with
* musig_nonce_process
* partial_sigs: array of pointers to partial signatures to aggregate
* n_sigs: number of elements in the partial_sigs array. Must be
* greater than 0.
*/
SECP256K1_API int secp256k1_musig_partial_sig_agg(
const secp256k1_context *ctx,
unsigned char *sig64,
const secp256k1_musig_session *session,
const secp256k1_musig_partial_sig * const *partial_sigs,
size_t n_sigs
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,134 +0,0 @@
#ifndef SECP256K1_PREALLOCATED_H
#define SECP256K1_PREALLOCATED_H
#include "secp256k1.h"
#ifdef __cplusplus
extern "C" {
#endif
/* The module provided by this header file is intended for settings in which it
* is not possible or desirable to rely on dynamic memory allocation. It provides
* functions for creating, cloning, and destroying secp256k1 context objects in a
* contiguous fixed-size block of memory provided by the caller.
*
* Context objects created by functions in this module can be used like contexts
* objects created by functions in secp256k1.h, i.e., they can be passed to any
* API function that expects a context object (see secp256k1.h for details). The
* only exception is that context objects created by functions in this module
* must be destroyed using secp256k1_context_preallocated_destroy (in this
* module) instead of secp256k1_context_destroy (in secp256k1.h).
*
* It is guaranteed that functions in this module will not call malloc or its
* friends realloc, calloc, and free.
*/
/** Determine the memory size of a secp256k1 context object to be created in
* caller-provided memory.
*
* The purpose of this function is to determine how much memory must be provided
* to secp256k1_context_preallocated_create.
*
* Returns: the required size of the caller-provided memory block
* In: flags: which parts of the context to initialize.
*/
SECP256K1_API size_t secp256k1_context_preallocated_size(
unsigned int flags
) SECP256K1_WARN_UNUSED_RESULT;
/** Create a secp256k1 context object in caller-provided memory.
*
* The caller must provide a pointer to a rewritable contiguous block of memory
* of size at least secp256k1_context_preallocated_size(flags) bytes, suitably
* aligned to hold an object of any type.
*
* The block of memory is exclusively owned by the created context object during
* the lifetime of this context object, which begins with the call to this
* function and ends when a call to secp256k1_context_preallocated_destroy
* (which destroys the context object again) returns. During the lifetime of the
* context object, the caller is obligated not to access this block of memory,
* i.e., the caller may not read or write the memory, e.g., by copying the memory
* contents to a different location or trying to create a second context object
* in the memory. In simpler words, the prealloc pointer (or any pointer derived
* from it) should not be used during the lifetime of the context object.
*
* Returns: pointer to newly created context object.
* In: prealloc: pointer to a rewritable contiguous block of memory of
* size at least secp256k1_context_preallocated_size(flags)
* bytes, as detailed above.
* flags: which parts of the context to initialize.
*
* See secp256k1_context_create (in secp256k1.h) for further details.
*
* See also secp256k1_context_randomize (in secp256k1.h)
* and secp256k1_context_preallocated_destroy.
*/
SECP256K1_API secp256k1_context *secp256k1_context_preallocated_create(
void *prealloc,
unsigned int flags
) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT;
/** Determine the memory size of a secp256k1 context object to be copied into
* caller-provided memory.
*
* Returns: the required size of the caller-provided memory block.
* In: ctx: pointer to a context to copy.
*/
SECP256K1_API size_t secp256k1_context_preallocated_clone_size(
const secp256k1_context *ctx
) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT;
/** Copy a secp256k1 context object into caller-provided memory.
*
* The caller must provide a pointer to a rewritable contiguous block of memory
* of size at least secp256k1_context_preallocated_size(flags) bytes, suitably
* aligned to hold an object of any type.
*
* The block of memory is exclusively owned by the created context object during
* the lifetime of this context object, see the description of
* secp256k1_context_preallocated_create for details.
*
* Cloning secp256k1_context_static is not possible, and should not be emulated by
* the caller (e.g., using memcpy). Create a new context instead.
*
* Returns: pointer to a newly created context object.
* Args: ctx: pointer to a context to copy (not secp256k1_context_static).
* In: prealloc: pointer to a rewritable contiguous block of memory of
* size at least secp256k1_context_preallocated_size(flags)
* bytes, as detailed above.
*/
SECP256K1_API secp256k1_context *secp256k1_context_preallocated_clone(
const secp256k1_context *ctx,
void *prealloc
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_WARN_UNUSED_RESULT;
/** Destroy a secp256k1 context object that has been created in
* caller-provided memory.
*
* The context pointer may not be used afterwards.
*
* The context to destroy must have been created using
* secp256k1_context_preallocated_create or secp256k1_context_preallocated_clone.
* If the context has instead been created using secp256k1_context_create or
* secp256k1_context_clone, the behaviour is undefined. In that case,
* secp256k1_context_destroy must be used instead.
*
* If required, it is the responsibility of the caller to deallocate the block
* of memory properly after this function returns, e.g., by calling free on the
* preallocated pointer given to secp256k1_context_preallocated_create or
* secp256k1_context_preallocated_clone.
*
* Args: ctx: pointer to a context to destroy, constructed using
* secp256k1_context_preallocated_create or
* secp256k1_context_preallocated_clone
* (i.e., not secp256k1_context_static).
*/
SECP256K1_API void secp256k1_context_preallocated_destroy(
secp256k1_context *ctx
) SECP256K1_ARG_NONNULL(1);
#ifdef __cplusplus
}
#endif
#endif /* SECP256K1_PREALLOCATED_H */

View File

@@ -1,113 +0,0 @@
#ifndef SECP256K1_RECOVERY_H
#define SECP256K1_RECOVERY_H
#include "secp256k1.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Opaque data structure that holds a parsed ECDSA signature,
* supporting pubkey recovery.
*
* The exact representation of data inside is implementation defined and not
* guaranteed to be portable between different platforms or versions. It is
* however guaranteed to be 65 bytes in size, and can be safely copied/moved.
* If you need to convert to a format suitable for storage or transmission, use
* the secp256k1_ecdsa_signature_serialize_* and
* secp256k1_ecdsa_signature_parse_* functions.
*
* Furthermore, it is guaranteed that identical signatures (including their
* recoverability) will have identical representation, so they can be
* memcmp'ed.
*/
typedef struct secp256k1_ecdsa_recoverable_signature {
unsigned char data[65];
} secp256k1_ecdsa_recoverable_signature;
/** Parse a compact ECDSA signature (64 bytes + recovery id).
*
* Returns: 1 when the signature could be parsed, 0 otherwise
* Args: ctx: pointer to a context object
* Out: sig: pointer to a signature object
* In: input64: pointer to a 64-byte compact signature
* recid: the recovery id (0, 1, 2 or 3)
*/
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact(
const secp256k1_context *ctx,
secp256k1_ecdsa_recoverable_signature *sig,
const unsigned char *input64,
int recid
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Convert a recoverable signature into a normal signature.
*
* Returns: 1
* Args: ctx: pointer to a context object.
* Out: sig: pointer to a normal signature.
* In: sigin: pointer to a recoverable signature.
*/
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert(
const secp256k1_context *ctx,
secp256k1_ecdsa_signature *sig,
const secp256k1_ecdsa_recoverable_signature *sigin
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Serialize an ECDSA signature in compact format (64 bytes + recovery id).
*
* Returns: 1
* Args: ctx: pointer to a context object.
* Out: output64: pointer to a 64-byte array of the compact signature.
* recid: pointer to an integer to hold the recovery id.
* In: sig: pointer to an initialized signature object.
*/
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact(
const secp256k1_context *ctx,
unsigned char *output64,
int *recid,
const secp256k1_ecdsa_recoverable_signature *sig
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Create a recoverable ECDSA signature.
*
* Returns: 1: signature created
* 0: the nonce generation function failed, or the secret key was invalid.
* Args: ctx: pointer to a context object (not secp256k1_context_static).
* Out: sig: pointer to an array where the signature will be placed.
* In: msghash32: the 32-byte message hash being signed.
* seckey: pointer to a 32-byte secret key.
* noncefp: pointer to a nonce generation function. If NULL,
* secp256k1_nonce_function_default is used.
* ndata: pointer to arbitrary data used by the nonce generation function
* (can be NULL for secp256k1_nonce_function_default).
*/
SECP256K1_API int secp256k1_ecdsa_sign_recoverable(
const secp256k1_context *ctx,
secp256k1_ecdsa_recoverable_signature *sig,
const unsigned char *msghash32,
const unsigned char *seckey,
secp256k1_nonce_function noncefp,
const void *ndata
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Recover an ECDSA public key from a signature.
*
* Returns: 1: public key successfully recovered (which guarantees a correct signature).
* 0: otherwise.
* Args: ctx: pointer to a context object.
* Out: pubkey: pointer to the recovered public key.
* In: sig: pointer to initialized signature that supports pubkey recovery.
* msghash32: the 32-byte message hash assumed to be signed.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover(
const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const secp256k1_ecdsa_recoverable_signature *sig,
const unsigned char *msghash32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
#ifdef __cplusplus
}
#endif
#endif /* SECP256K1_RECOVERY_H */

View File

@@ -1,190 +0,0 @@
#ifndef SECP256K1_SCHNORRSIG_H
#define SECP256K1_SCHNORRSIG_H
#include "secp256k1.h"
#include "secp256k1_extrakeys.h"
#ifdef __cplusplus
extern "C" {
#endif
/** This module implements a variant of Schnorr signatures compliant with
* Bitcoin Improvement Proposal 340 "Schnorr Signatures for secp256k1"
* (https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki).
*/
/** A pointer to a function to deterministically generate a nonce.
*
* Same as secp256k1_nonce function with the exception of accepting an
* additional pubkey argument and not requiring an attempt argument. The pubkey
* argument can protect signature schemes with key-prefixed challenge hash
* inputs against reusing the nonce when signing with the wrong precomputed
* pubkey.
*
* Returns: 1 if a nonce was successfully generated. 0 will cause signing to
* return an error.
* Out: nonce32: pointer to a 32-byte array to be filled by the function
* In: msg: the message being verified. Is NULL if and only if msglen
* is 0.
* msglen: the length of the message
* key32: pointer to a 32-byte secret key (will not be NULL)
* xonly_pk32: the 32-byte serialized xonly pubkey corresponding to key32
* (will not be NULL)
* algo: pointer to an array describing the signature
* algorithm (will not be NULL)
* algolen: the length of the algo array
* data: arbitrary data pointer that is passed through
*
* Except for test cases, this function should compute some cryptographic hash of
* the message, the key, the pubkey, the algorithm description, and data.
*/
typedef int (*secp256k1_nonce_function_hardened)(
unsigned char *nonce32,
const unsigned char *msg,
size_t msglen,
const unsigned char *key32,
const unsigned char *xonly_pk32,
const unsigned char *algo,
size_t algolen,
void *data
);
/** An implementation of the nonce generation function as defined in Bitcoin
* Improvement Proposal 340 "Schnorr Signatures for secp256k1"
* (https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki).
*
* If a data pointer is passed, it is assumed to be a pointer to 32 bytes of
* auxiliary random data as defined in BIP-340. If the data pointer is NULL,
* the nonce derivation procedure follows BIP-340 by setting the auxiliary
* random data to zero. The algo argument must be non-NULL, otherwise the
* function will fail and return 0. The hash will be tagged with algo.
* Therefore, to create BIP-340 compliant signatures, algo must be set to
* "BIP0340/nonce" and algolen to 13.
*/
SECP256K1_API const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340;
/** Data structure that contains additional arguments for schnorrsig_sign_custom.
*
* A schnorrsig_extraparams structure object can be initialized correctly by
* setting it to SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT.
*
* Members:
* magic: set to SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC at initialization
* and has no other function than making sure the object is
* initialized.
* noncefp: pointer to a nonce generation function. If NULL,
* secp256k1_nonce_function_bip340 is used
* ndata: pointer to arbitrary data used by the nonce generation function
* (can be NULL). If it is non-NULL and
* secp256k1_nonce_function_bip340 is used, then ndata must be a
* pointer to 32-byte auxiliary randomness as per BIP-340.
*/
typedef struct secp256k1_schnorrsig_extraparams {
unsigned char magic[4];
secp256k1_nonce_function_hardened noncefp;
void *ndata;
} secp256k1_schnorrsig_extraparams;
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC { 0xda, 0x6f, 0xb3, 0x8c }
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT {\
SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC,\
NULL,\
NULL\
}
/** Create a Schnorr signature.
*
* Does _not_ strictly follow BIP-340 because it does not verify the resulting
* signature. Instead, you can manually use secp256k1_schnorrsig_verify and
* abort if it fails.
*
* This function only signs 32-byte messages. If you have messages of a
* different size (or the same size but without a context-specific tag
* prefix), it is recommended to create a 32-byte message hash with
* secp256k1_tagged_sha256 and then sign the hash. Tagged hashing allows
* providing an context-specific tag for domain separation. This prevents
* signatures from being valid in multiple contexts by accident.
*
* Returns 1 on success, 0 on failure.
* Args: ctx: pointer to a context object (not secp256k1_context_static).
* Out: sig64: pointer to a 64-byte array to store the serialized signature.
* In: msg32: the 32-byte message being signed.
* keypair: pointer to an initialized keypair.
* aux_rand32: 32 bytes of fresh randomness. While recommended to provide
* this, it is only supplemental to security and can be NULL. A
* NULL argument is treated the same as an all-zero one. See
* BIP-340 "Default Signing" for a full explanation of this
* argument and for guidance if randomness is expensive.
*/
SECP256K1_API int secp256k1_schnorrsig_sign32(
const secp256k1_context *ctx,
unsigned char *sig64,
const unsigned char *msg32,
const secp256k1_keypair *keypair,
const unsigned char *aux_rand32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Same as secp256k1_schnorrsig_sign32, but DEPRECATED. Will be removed in
* future versions. */
SECP256K1_API int secp256k1_schnorrsig_sign(
const secp256k1_context *ctx,
unsigned char *sig64,
const unsigned char *msg32,
const secp256k1_keypair *keypair,
const unsigned char *aux_rand32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
SECP256K1_DEPRECATED("Use secp256k1_schnorrsig_sign32 instead");
/** Create a Schnorr signature with a more flexible API.
*
* Same arguments as secp256k1_schnorrsig_sign except that it allows signing
* variable length messages and accepts a pointer to an extraparams object that
* allows customizing signing by passing additional arguments.
*
* Equivalent to secp256k1_schnorrsig_sign32(..., aux_rand32) if msglen is 32
* and extraparams is initialized as follows:
* ```
* secp256k1_schnorrsig_extraparams extraparams = SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT;
* extraparams.ndata = (unsigned char*)aux_rand32;
* ```
*
* Returns 1 on success, 0 on failure.
* Args: ctx: pointer to a context object (not secp256k1_context_static).
* Out: sig64: pointer to a 64-byte array to store the serialized signature.
* In: msg: the message being signed. Can only be NULL if msglen is 0.
* msglen: length of the message.
* keypair: pointer to an initialized keypair.
* extraparams: pointer to an extraparams object (can be NULL).
*/
SECP256K1_API int secp256k1_schnorrsig_sign_custom(
const secp256k1_context *ctx,
unsigned char *sig64,
const unsigned char *msg,
size_t msglen,
const secp256k1_keypair *keypair,
secp256k1_schnorrsig_extraparams *extraparams
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(5);
/** Verify a Schnorr signature.
*
* Returns: 1: correct signature
* 0: incorrect signature
* Args: ctx: pointer to a context object.
* In: sig64: pointer to the 64-byte signature to verify.
* msg: the message being verified. Can only be NULL if msglen is 0.
* msglen: length of the message
* pubkey: pointer to an x-only public key to verify with
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_verify(
const secp256k1_context *ctx,
const unsigned char *sig64,
const unsigned char *msg,
size_t msglen,
const secp256k1_xonly_pubkey *pubkey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(5);
#ifdef __cplusplus
}
#endif
#endif /* SECP256K1_SCHNORRSIG_H */

View File

@@ -1,12 +0,0 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libsecp256k1
Description: Optimized C library for EC operations on curve secp256k1
URL: https://github.com/bitcoin-core/secp256k1
Version: @PACKAGE_VERSION@
Cflags: -I${includedir}
Libs: -L${libdir} -lsecp256k1

Some files were not shown because too many files have changed in this diff Show More