Skip to main content

Recover ECDSA private keys from biased-nonce signatures via LLL/BKZ lattice reduction

Project description

BreakingECDSAwithLLL

Recover ECDSA private keys from biased-nonce signatures via LLL/BKZ lattice reduction.

lint_python PyPI Python Coverage Ruff GitHub issues GitHub forks GitHub stars

The core idea: if you have many ECDSA signatures generated with a private key whose nonces have a fixed-bit bias, those signatures converge toward the private key via the Hidden Number Problem (HNP). We solve HNP with the Lenstra–Lenstra–Lovász (LLL) lattice reduction algorithm, optionally followed by a BKZ post-processing pass.

The main countermeasure against this attack is using deterministic signatures like Z = H(h || d) (RFC 6979), which eliminates nonce bias entirely.

Based on prior work:

Referenced in CVE-2024-31497 on 4/16/2024.

Install

pip install breaking-ecdsa-with-lll
# With weak-signature generator support:
pip install "breaking-ecdsa-with-lll[generator]"

Quick start

# (Victim) generate 6 weak signatures
gen-weak-sigs e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 176 6 > nonces.csv

# (Attacker) recover the private key
break-ecdsa nonces.csv 176 6 | grep e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

Python API

from breaking_ecdsa_with_lll import (
    load_csv,
    make_matrix,
    reduce_matrix,
    privkeys_from_reduced_matrix,
    display_keys,
)

msgs, sigs, pubs = load_csv("nonces.csv", limit=6)
matrix = make_matrix(msgs, sigs, pubs, B=176)
reduced = reduce_matrix(matrix, do_bkz=False)
keys = privkeys_from_reduced_matrix(msgs, sigs, pubs, reduced)
display_keys(keys)

CLI reference

break-ecdsa

break-ecdsa <filename> <B> <limit> [--matrix_type dense|sparse]
            [--order N] [--bkz] [--mmap]

gen-weak-sigs

gen-weak-sigs <secret_hex> <bits> <n> [--mode MSB|LSB]

API

Symbol Module Description
load_csv io Load signatures from CSV
make_matrix lattice Build HNP lattice matrix
reduce_matrix lattice LLL (+ optional BKZ) reduction
privkeys_from_reduced_matrix lattice Extract private key candidates
display_keys display Print keys as 64-char hex strings
generate_weak_signatures generator Produce biased-nonce test signatures
DEFAULT_ORDER lattice secp256k1 group order

Development

git clone https://github.com/daedalus/BreakingECDSAwithLLL.git
cd BreakingECDSAwithLLL
pip install -e ".[test]"

# Run tests
pytest

# Format
ruff format src/ tests/

# Lint
ruff check src/ tests/

# Type check
mypy src/

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ecdsa_break-0.1.0.1.tar.gz (8.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ecdsa_break-0.1.0.1-py3-none-any.whl (11.4 kB view details)

Uploaded Python 3

File details

Details for the file ecdsa_break-0.1.0.1.tar.gz.

File metadata

  • Download URL: ecdsa_break-0.1.0.1.tar.gz
  • Upload date:
  • Size: 8.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for ecdsa_break-0.1.0.1.tar.gz
Algorithm Hash digest
SHA256 11c7565db339ab672adf8664a0798b699f920dee8f8cce002bbba30400197cb4
MD5 8c71d7a0bec82e8607653f92f7b765ee
BLAKE2b-256 88fd70c424661b5b932bacf300964f57500bc390990b01c9b3a8b1ba93949536

See more details on using hashes here.

Provenance

The following attestation bundles were made for ecdsa_break-0.1.0.1.tar.gz:

Publisher: pypi-publish.yml on daedalus/BreakingECDSAwithLLL

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ecdsa_break-0.1.0.1-py3-none-any.whl.

File metadata

  • Download URL: ecdsa_break-0.1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 11.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for ecdsa_break-0.1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 4aedea10bab0a65900949c753541c277204e2109181c1e219a54ba7a2cc258dc
MD5 cca2148aafae2dde7c9445a9797ca1fc
BLAKE2b-256 7624082949d326eaa9989c0105f186f87301584cccb4e142e017b8c18addc8c1

See more details on using hashes here.

Provenance

The following attestation bundles were made for ecdsa_break-0.1.0.1-py3-none-any.whl:

Publisher: pypi-publish.yml on daedalus/BreakingECDSAwithLLL

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page