Skip to content

feat: add Kurihara n-of-m threshold XOR secret-sharing core#883

Draft
CaverneCrypto wants to merge 2 commits into
selfcustody:developfrom
CaverneCrypto:feat/kurihara-threshold-backup
Draft

feat: add Kurihara n-of-m threshold XOR secret-sharing core#883
CaverneCrypto wants to merge 2 commits into
selfcustody:developfrom
CaverneCrypto:feat/kurihara-threshold-backup

Conversation

@CaverneCrypto

Copy link
Copy Markdown

Summary

This extends Krux's existing Mnemonic XOR (src/krux/pages/home_pages/mnemonic_xor.py) from an m-of-m split to a true n-of-m threshold backup, using the ideal threshold XOR secret-sharing scheme of Kurihara et al. (ISC 2008).

Today's SeedXOR-style Mnemonic XOR requires every share to reconstruct the seed — lose one share and the seed is gone. This adds the natural generalization: any n of m shares reconstruct it, while any n − 1 reveal nothing (perfect, information-theoretic confidentiality up to the threshold). It keeps everything that makes Mnemonic XOR nice:

  • pure XOR on BIP39 entropy (no finite-field arithmetic), pen-and-paper friendly;
  • each share is exactly the size of the secret and re-encodes to a valid BIP39 mnemonic of the same word count (the same property xor_with_current_mnemonic already produces);
  • and it now tolerates the loss of up to m − n shares.

Scope of this PR

Audited arithmetic core + unit tests only — no UI yet. Wiring it into the Mnemonic XOR page is intended as a follow-up, so the security-critical math can be reviewed in isolation first.

  • src/krux/kurihara.py — the scheme: split / reconstruct / regenerate a lost share, via Gaussian elimination over GF(2) (coefficient rows as column-index sets → no big-int bitmasks, MicroPython-friendly). No hardware dependency: the randomness source is injected into generate(), and embit is imported lazily only for the BIP39 glue (mirroring mnemonic_xor.py).
  • tests/test_kurihara.py — 20 tests, 100% coverage of the new module.

Testing

black --check clean · pylint src → 10.00/10 · pytest green · 100% coverage on kurihara.py.

Recommended parameter pairs: 2-of-3 (12 words) and 3-of-5 (24 words).

References

  • Whitepaper (BIP39 adaptation, pen-and-paper derivation, security-property verification, ready-to-print templates): CaverneCrypto, Bitcoin Mnemonic Backup via Threshold XOR (n-of-m): A pen-and-paper adaptation of the Kurihara scheme to BIP39, 2026 — https://doi.org/10.5281/zenodo.20734041 (CC BY 4.0)
  • Underlying scheme: J. Kurihara, S. Kiyomoto, K. Fukushima, T. Tanaka, A New (k, n)-Threshold Secret Sharing Scheme and Its Extension, ISC 2008 — https://eprint.iacr.org/2008/409

🤖 Generated with Claude Code

@qlrd

qlrd commented Jun 17, 2026

Copy link
Copy Markdown
Member

nACK for now (maybe i could change after more reviews on other referenced issues).

EDIT: not against kurihara itself.

I don't really see demand for it and it's relly do no extend, since do not implement on MnemonicXOR procedures. It only have unit tests and basic structure (even quoted on commit message, i mean, when possible, you need to check some classes that could use it, so we not ship to develop branch without the implementation).

@odudex

odudex commented Jun 17, 2026

Copy link
Copy Markdown
Member

Is it similar to Shamir from a UX perspective? The idea looks interesting, but it currently lacks a user-facing integration.

While this is a cool feature, we tend to apply the same criteria we use for things like Shamir support: we usually look for stronger user demand, broader adoption, or additional reference implementations before incorporating a feature into the main firmware. Krux already includes some unique functionality, but we are trying to be more careful about adding too many options and overwhelming users, so we've intentionally slowed the rate at which new features are added.

Regarding contributions, the preferred process is to open an issue first. That gives you a chance to present the idea, discuss the use case, and gather feedback before investing time in a full implementation. If you decide to move forward, PRs should target the develop branch.

That said, cypherpunks don't need permission. I don't want to discourage you from continuing to explore and evolve the idea. It's great that you were able to use Krux infrastructure for the core implementation. I think the next valuable step would be building a UI around it so you and others can experience the full workflow and evaluate the UX in practice.

Even if it doesn't get merged into Krux, a working implementation can help demonstrate the concept, attract users, and potentially encourage adoption. Having a tangible implementation often does more to advance an idea than discussion alone.

@codecov

codecov Bot commented Jun 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.41%. Comparing base (a0924c7) to head (7381e87).
⚠️ Report is 2 commits behind head on develop.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop     #883      +/-   ##
===========================================
+ Coverage    97.34%   97.41%   +0.06%     
===========================================
  Files           83       85       +2     
  Lines        10814    11100     +286     
===========================================
+ Hits         10527    10813     +286     
  Misses         287      287              

☔ 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.

@qlrd

qlrd commented Jun 17, 2026

Copy link
Copy Markdown
Member

@CaverneCrypto CaverneCrypto changed the base branch from main to develop June 17, 2026 21:08
@CaverneCrypto

Copy link
Copy Markdown
Author

Appreciated, and well taken. You were right that the UI was the missing piece, so it's in — and both split and restore work now:

  • Create shares lives under Backup Mnemonic ("Threshold Split"): pick m and n on the keypad, review each share as a normal BIP39 mnemonic, and confirm at the end that they're all written down.
  • Restore lives in the login Load Mnemonic menu ("Restore from shares"): enter any n shares (number + mnemonic) and the seed is reconstructed and loaded through the standard flow.

Shares are derived deterministically from the secret (like Coldcard's deterministic Seed XOR). There's 100% test coverage of the new page, including an end-to-end 3-of-5 split-then-restore test, and I've retargeted this PR to develop as you asked. Translations for all locales are included (machine-filled then domain-term corrected — the non-Latin ones would benefit from a native review).

On process: I'll also open an issue to lay out the use case and let demand decide, and I'm framing this as "Seed XOR that survives losing a share" rather than a new paradigm.

Merge or not, no pressure: a working, tested implementation people can actually run moves an idea further than another thread can. Either way it's out there now — which is rather the point of doing this in the open.

CaverneCrypto and others added 2 commits June 17, 2026 22:12
Adds the pure, UI-less core of an n-of-m threshold backup for BIP39
mnemonics (Kurihara et al., ISC 2008). Any n of m shares reconstruct the
secret; strictly fewer than n reveal nothing (information-theoretic
confidentiality up to the threshold). Each share is the size of the secret
and re-encodes to a valid BIP39 mnemonic -- a true threshold generalization
of the existing m-of-m Mnemonic XOR (SeedXOR), which has no loss tolerance.

- src/krux/kurihara.py: scheme (split / reconstruct / regenerate a lost
  share) via Gaussian elimination over GF(2); no hardware dependency
  (randomness injected; embit imported lazily for the BIP39 glue).
- tests/test_kurihara.py: 20 tests, 100% coverage of the new module.

UI integration into the existing Mnemonic XOR page is intended as a
follow-up so the security-critical math can be reviewed in isolation.

Reference: https://doi.org/10.5281/zenodo.20734041 (CC BY 4.0)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds the user-facing flow for the n-of-m threshold backup:
- Create shares: "Threshold Split" under Backup Mnemonic -- choose m and n on
  the keypad, review each share as a BIP39 mnemonic, confirm they are saved.
- Restore: "Restore from shares" in the login Load Mnemonic menu -- enter n
  shares (number + mnemonic), the seed is reconstructed and loaded via the
  standard load flow.

Shares are derived deterministically from the secret (like Coldcard's
deterministic Seed XOR). 100% test coverage of the new page (incl. an
end-to-end 3-of-5 split-then-restore test); updates the three existing tests
affected by the new Backup Mnemonic menu item, and adds 12-language
translations (machine-filled then domain-term corrected; non-Latin locales
would benefit from a native review).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@CaverneCrypto CaverneCrypto force-pushed the feat/kurihara-threshold-backup branch from 628ec25 to 7381e87 Compare June 17, 2026 21:23
@qlrd

qlrd commented Jun 17, 2026

Copy link
Copy Markdown
Member

please keep it draft

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.

3 participants