Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so

# Virtual environments
venv/
.venv/
ENV/

# IDE
.idea/
.vscode/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db

# Testing
.pytest_cache/
.coverage
htmlcov/

# Distribution
dist/
build/
*.egg-info/
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# SeedSigner Codex32

Convert [Codex32 (BIP-93)](https://github.com/bitcoin/bips/blob/master/bip-0093.mediawiki) shares to BIP39 mnemonics for use with any Bitcoin wallet.

**→ [Setup & Usage](codex32_terminal/README.md)**

## Why?

Codex32 lets you create and verify Bitcoin seed backups entirely by hand—no electronics needed. But wallet support is nearly nonexistent. This tool bridges the gap: enter your Codex32 shares and get a standard 12-word BIP39 mnemonic.

## Ecosystem

| Resource | Description |
|----------|-------------|
| [BIP-93](https://github.com/bitcoin/bips/blob/master/bip-0093.mediawiki) | Codex32 specification |
| [secretcodex32.com](https://secretcodex32.com) | Official paper worksheets & volvelles |
| [rust-codex32](https://github.com/apoelstra/rust-codex32) | Rust reference implementation (Andrew Poelstra) |
| [python-codex32](https://github.com/benwestgate/python-codex32) | Python library (Ben Westgate) |
| [Bails](https://github.com/BenWestgate/Bails) | First wallet with native codex32 support |
| [SeedSigner](https://github.com/SeedSigner/seedsigner) | Target platform for this integration |

## Credits

- **FractalEncrypt** — This project
- **Leon Olsson Curr & Pearlwort Sneed** — Codex32 creators
- **Andrew Poelstra** — Rust reference, Blockstream Research
- **Ben Westgate** — python-codex32 library, Bails wallet

## License

MIT
59 changes: 58 additions & 1 deletion codex32_terminal/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,18 @@ This folder contains a terminal-based MVP for validating Codex32 shares, recover

⚠️ Not an ECW yet (no error correction). The codex32 Python library does **not** provide substitution/erasure correction, so this tool does not attempt it. Error-correction should be implemented separately before advertising ECW behavior.

## Setup (Windows PowerShell)
## Setup

### macOS / Linux

```bash
cd codex32_terminal
python3 -m venv venv
source venv/bin/activate
pip install codex32 embit
```

### Windows PowerShell

From the repo root:

Expand All @@ -30,6 +41,13 @@ pip freeze > .\codex32_terminal\requirements.txt

### Box-by-box entry (default)

**macOS / Linux:**
```bash
source venv/bin/activate
python src/main.py
```

**Windows PowerShell:**
```powershell
.\codex32_terminal\venv\Scripts\Activate.ps1 ; python .\codex32_terminal\src\main.py
```
Expand All @@ -43,12 +61,42 @@ Features:

### Full-share paste mode

**macOS / Linux:**
```bash
source venv/bin/activate
python src/main.py --full
```

**Windows PowerShell:**
```powershell
.\codex32_terminal\venv\Scripts\Activate.ps1 ; python .\codex32_terminal\src\main.py --full
```

Paste full shares in sequence. For `k-of-n` shares, the tool will ask for additional shares until the threshold is met.

## Run Tests

Run all tests:

**macOS / Linux:**
```bash
source venv/bin/activate
python run_tests.py
```

**Windows PowerShell:**
```powershell
.\codex32_terminal\venv\Scripts\Activate.ps1 ; python .\codex32_terminal\run_tests.py
```

Or run individual test files:
```bash
python tests/test_vectors.py
python tests/test_share_recovery.py
python tests/test_validation.py
python tests/test_invalid_vectors.py
```

## Test vectors

Use BIP-93 test vectors to validate recovery:
Expand Down Expand Up @@ -96,6 +144,15 @@ Expected output:
- `tests/test_vectors.py`
- Manual harness for BIP-93 vectors 2/3

- `tests/test_share_recovery.py`
- Tests 2-of-n and 3-of-n share recovery with BIP-93 vectors

- `tests/test_validation.py`
- Tests input validation (checksum, length, empty input, sanitization)

- `tests/test_invalid_vectors.py`
- Tests rejection of BIP-93 invalid test vectors

### Implementation rationale

- **Validation** uses `codex32.Codex32String`, which enforces checksum + header correctness.
Expand Down
59 changes: 59 additions & 0 deletions codex32_terminal/run_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env python3
"""Run all tests for codex32_terminal."""

from __future__ import annotations

import subprocess
import sys
from pathlib import Path

TESTS_DIR = Path(__file__).parent / "tests"

TEST_FILES = [
"test_vectors.py",
"test_share_recovery.py",
"test_validation.py",
"test_invalid_vectors.py",
]


def main() -> int:
failed = []
passed = []

for test_file in TEST_FILES:
test_path = TESTS_DIR / test_file
if not test_path.exists():
print(f"SKIP: {test_file} (not found)")
continue

print(f"\n{'='*60}")
print(f"Running {test_file}")
print('='*60)

result = subprocess.run(
[sys.executable, str(test_path)],
cwd=Path(__file__).parent,
)

if result.returncode == 0:
passed.append(test_file)
else:
failed.append(test_file)

print(f"\n{'='*60}")
print("SUMMARY")
print('='*60)
print(f"Passed: {len(passed)}")
print(f"Failed: {len(failed)}")

if failed:
print(f"\nFailed tests: {', '.join(failed)}")
return 1

print("\nAll tests passed!")
return 0


if __name__ == "__main__":
sys.exit(main())