Skip to content

Clear text representation of wallet policies#494

Draft
bigspider wants to merge 4 commits into
developfrom
cleartext
Draft

Clear text representation of wallet policies#494
bigspider wants to merge 4 commits into
developfrom
cleartext

Conversation

@bigspider

@bigspider bigspider commented May 26, 2026

Copy link
Copy Markdown
Collaborator

TODO:

  • document standardness rules for cleartext
  • document how the confusion_score is computed (maybe in the Rust crate)

Enhances the UX for the registration of multisig and (taproot) miniscript wallet policies by identifying and explaining in human terms the meaning of the descriptor template.

The cleartext representation has the following properties:

  • composable: instead of a list of hardcoded patterns known patterns, a core set of pattern is identified that, with a limited amount of composability, aims to cover the vast majority of the descriptor templates that people are likely to use in practice, despite inherently not being as general as the full set of miniscript wallet policies.
  • reversible: going from a descriptor template to a clear-text description is a lossy process: there could be many different descriptor templates that have essentially the same meaning.
  • extensible: the specifications of the patterns, and a number of test cases are listed in TOML files; the C implementation and the unit tests are automatically generated with a python script (in C), or with a build.rs file in the reference Rust crate. As long as the language's grammar doesn't change, adding some new patterns only requires updating the TOML files, and regenerating the code.

The model introduces a confusion_score that allows to provide an upper bound on the number of different descriptor templates that could possibly generate the same cleartext description. For any descriptor template with a too high confusion_score, or with no cleartext representation for any other reason, the descriptor template is shown as usual, in order to not prevent more advanced users from benefiting from the generality of miniscript.

This guarantees that, even if the user does not have a backup of the descriptor template, but has an exact backup of the cleartext description, it is possible to programmatically enumerate all the possible descriptor templates, and eventually find the correct one. In this way, the user is protected from ransom attacks even if they only check that they have a backup for the cleartext, rather than the descriptor template.

The implementation in C only needs:

  • descriptor_template to cleartext conversion
  • confusion_score computation (to make sure it is reasonable)

The full reversible process (validating that the grammar is unambiguous, and that bruteforcing a cleartext description is feasible) is implemented in this rust crate.

In this PR, the descriptor template is still shown to the user in addition to the descriptor template. In the future, we could have as an opt-in feature to hide the descriptor_template (if the software wallet is prepared to show the identical clear-text to the user).

@github-actions

github-actions Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

elf sizes
source = source branch cleartext
target = target branch develop

Device .text source .text target .text delta .bss source .bss target .bss delta max stack size source max stack size target max stack size delta
apex_p 108712 101544 7168 9786 9642 144 31168 31312 -144
flex 112553 105385 7168 9786 9642 144 27072 27216 -144
nanos2 87668 80500 7168 8680 8536 144 32276 32420 -144
stax 112503 105335 7168 9786 9642 144 27072 27216 -144
nanox 87396 80228 7168 6908 6764 144 8192 8192 0

Stack consumption summary

⚠️ This summary is for informative purpose only. It may not give the application actual worst case, for example if the test coverage is low.

Device Worst case (bytes) Remaining stack (bytes) Test
apex_p 16441 14727 test_e2e_miniscript.py::test_e2e_miniscript_bolt3_received_htlc[apex_p-apex_p]
flex 16441 10631 test_e2e_miniscript.py::test_e2e_miniscript_bolt3_received_htlc[flex-flex]
nanosp 16441 15835 test_e2e_miniscript.py::test_e2e_miniscript_bolt3_received_htlc[nanosp-nanosp]
nanox 16441 5319 test_e2e_miniscript.py::test_e2e_miniscript_bolt3_received_htlc[nanox-nanox]
stax 16441 10631 test_e2e_miniscript.py::test_e2e_miniscript_bolt3_received_htlc[stax-stax]

Full details

@codecov-commenter

codecov-commenter commented May 26, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 73.20955% with 202 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.39%. Comparing base (912b73a) to head (1b41d07).

Files with missing lines Patch % Lines
src/common/cleartext.c 76.00% 62 Missing and 105 partials ⚠️
unit-tests/test_cleartext.c 39.65% 26 Missing and 9 partials ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop     #494      +/-   ##
===========================================
+ Coverage    71.25%   71.39%   +0.14%     
===========================================
  Files           62       64       +2     
  Lines         9510    10264     +754     
  Branches      1690     1917     +227     
===========================================
+ Hits          6776     7328     +552     
- Misses        2140     2228      +88     
- Partials       594      708     +114     
Flag Coverage Δ
unittests 71.39% <73.20%> (+0.14%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@bigspider bigspider force-pushed the cleartext branch 5 times, most recently from 407e2b5 to 308dab3 Compare June 3, 2026 09:54
@bigspider bigspider force-pushed the cleartext branch 8 times, most recently from 2b4b96c to ac59da0 Compare June 11, 2026 13:40
@bigspider bigspider requested a review from Copilot June 11, 2026 15:15

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Comment thread unit-tests/test_cleartext.c Outdated
Comment thread src/common/cleartext.c

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.

Comment thread unit-tests/test_cleartext.c
Writing the struct directly is fragile, and risks incomplete
initializations or non-zeroed fields 'leaking' into future calls.

We rather write a simple helper that creates the full struct with
a literal, guaranteeing that everything that is no not explicitly
set is zeroed.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.

Comment thread src/ui/display.c Outdated
Comment thread src/ui/display_nbgl.c
Comment thread src/ui/display.c Dismissed
Implements the computation of the confusion score, and the
cleartext representation, for a large subset of commonly used
wallet policies.

For multisig wallet policies specifically, this also simplifies
the UX by omitting the raw descriptor template altogether. This
is safe for such simple policies, with very little ambiguity.
In the long term, we might be able to extend this to more complex
wallet policies, but that needs to be done intentiionally, and
possibly be an opt-in feature that is explicitly requested by
software wallets that adapt their own UX accordingly.

Mostly ported by Claude from the Rust reference implementation,
with several iterations of review and refinement.
@github-actions

Copy link
Copy Markdown
Contributor

Code coverage report

Code Coverage

Per-file coverage
Package Line Rate Branch Rate Health
src.boilerplate 100% 0%
src.common 85% 66%
src 85% 59%
src.debug-helpers 100% 0%
src.handler.lib 49% 38%
src.handler.sign_psbt 88% 83%
src.musig 24% 15%
src.ui 86% 100%
Summary 72% (3227 / 4507) 56% (1657 / 2939)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants