{"id":20600148,"url":"https://github.com/malb/bdd-predicate","last_synced_at":"2025-08-20T06:33:31.050Z","repository":{"id":41449239,"uuid":"314858625","full_name":"malb/bdd-predicate","owner":"malb","description":"Solving BDD and uSVP with predicate","archived":false,"fork":false,"pushed_at":"2024-07-31T14:37:14.000Z","size":39,"stargazers_count":47,"open_issues_count":8,"forks_count":17,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-07T11:05:07.585Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/malb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-11-21T16:49:14.000Z","updated_at":"2025-03-20T14:34:24.000Z","dependencies_parsed_at":"2024-07-31T18:22:55.554Z","dependency_job_id":null,"html_url":"https://github.com/malb/bdd-predicate","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/malb/bdd-predicate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/malb%2Fbdd-predicate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/malb%2Fbdd-predicate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/malb%2Fbdd-predicate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/malb%2Fbdd-predicate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/malb","download_url":"https://codeload.github.com/malb/bdd-predicate/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/malb%2Fbdd-predicate/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271278911,"owners_count":24731900,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-20T02:00:09.606Z","response_time":69,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-16T08:37:03.987Z","updated_at":"2025-08-20T06:33:30.773Z","avatar_url":"https://github.com/malb.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bounded Distance Decoding with Predicate\n\nThis repository contains the Python/Sagemath source code for solving Bounded Distance Decoding augmented with a predicate characterising the target as introduced in:\n\n\u003e **On Bounded Distance Decoding with Predicate: Breaking the \"Lattice Barrier\" for the Hidden Number Problem**  \n\u003e\n\u003e *Martin R. Albrecht and Nadia Heninger*  \n\u003e\n\u003e Lattice-based algorithms in cryptanalysis often search for a target vector satisfying integer linear constraints as a shortest or closest vector in some lattice.  In this work, we observe that these formulations may discard non-linear information from the underlying application that can be used to distinguish the target vector even when it is far from being uniquely close or short.  \n\u003e\n\u003e We formalize lattice problems augmented with a predicate distinguishing a target vector and give algorithms for solving instances of these problems. We apply our techniques to lattice-based approaches for solving the Hidden Number Problem, a popular technique for recovering secret DSA or ECDSA keys in side-channel attacks, and demonstrate that our algorithms succeed in recovering the signing key for instances that were previously believed to be unsolvable using lattice approaches. We carried out extensive experiments using our estimation and solving framework, which we also make available with this work.\n\nIf you use this library in your work please cite\n\n  Martin R. Albrecht and Nadia Heninger. *On Bounded Distance Decoding with Predicate: Breaking the \"Lattice Barrier\" for the Hidden Number Problem*. EUROCRYPT 2021. full version available as Cryptology ePrint Archive: [Report 2020/1540](https://ia.cr/2020/1540)\n\n## ECDSA with Partially Known Nonces\n\nThe flagship application of this work is solving ECDSA with known nonce bits. The `ecdsa_cli.py` script provides a high level entry point.\n\n1. To get estimates for the running times of the different algorithms for a set of parameters, the `estimate` functionality can be invoked as\n\n    ``` shell\n    sage -python ecdsa_cli.py estimate -n 256 -k 252 -m 66\n    ```\n\n2. To run the solver on a randomly generated problem instance with these parameters, use the `benchmark` function:\n\n    ``` shell\n    sage -python ecdsa_cli.py benchmark -n 256 -k 252 -m 65 --loglvl DEBUG\n    ```\n\n    If the algorithm is not specified, the script will automatically choose one for you, but you can also specify your chosen algorithm on the command line\n\n    ``` shell\n    sage -python ecdsa_cli.py benchmark -n 256 -k 252 -m 65 --algorithm \"enum_pred\" --loglvl DEBUG\n    ```\n\n3. To actually compute the secret key from input provided in a file, you can use the `solve` function. You need to specify the curve to use by name:\n\n    ``` shell\n    sage -python ecdsa_cli.py solve -c secp256k1 sample_input.txt\n    ```\n\n    Each line of the file is a space-separated list of the bit length of the nonce, the hex-encoded hash used in the ECDSA signature, the hex-encoded ECDSA signature as (r,s) concatenated together, and the hex-encoded public key.  The `ecdsa.sample` function will generate sample input in this form.\n\nFor the moment, our scripts assume the most significant bits of the nonce are 0. If your use case involves known nonzero most significant bits, least significant bits, or another case, you can either transform your signatures and hash values accordingly, or modify our script to implement that case.\n\nThe following example uses the `scale` strategy to continue searching until the solution is found, which can deal with errors in the data, and will parallelize the algorithm in 8 threads:\n\n``` shell\nsage -python ecdsa_cli.py solve -c secp256k1 -f scale -p 8 sample_input.txt\n```\n\nIf you wish to write your own script to use our functions as a library, here is a small custom Python script that shows how to invoke the relevant functions to compute the secret key for some randomly generated data:\n``` python\nfrom ecdsa_hnp import ECDSA, ECDSASolver,make_klen_list\n\nif  __name__=='__main__':\n    k = 252\n    m = 70\n    ecdsa = ECDSA(nbits=256)\n    lines, k_list, d = ecdsa.sample(m,make_klen_list(k,m))\n    solver = ECDSASolver(ecdsa,lines,m=m)\n    key, res = solver(\"bkz-enum\")\n    if res.success:\n        print(hex(key))\n    else:\n        print(\"Failed\")\n```\n\n## Implemented Algorithms\n\nOur algorithms solve the unique shortest vector problem augmented with a predicate. Using Kannan's embedding this enables to solve bounded distance decoding augmented with a predicate.\n\n- **Enumeration with Predicate**: This algorithm performs lattice-point enumeration within a ball of radius *R*, for each point *v* found it checks whether the predicate *f(⋅)* holds, i.e. if *f(v) = 1*.\n\n- **Sieving with Predicate**: This algorithm performs lattice sieving followed by a check for points *v* of norm bounded by *(4/3)^(1/2) ⋅ gh(Λ)* whether the predicate *f(⋅)* holds, i.e. if *f(v) = 1*.\n\n- **BKZ** with sieving or enumeration followed by a check for each point *v* in the output basis whether the predicate *f(⋅)* holds, i.e. if *f(v) = 1*.\n\n## How to Install/Run\n\nThis framework builds on\n\n- [FPLLL](https://github.com/fplll/fplll) and [FPyLLL](https://github.com/fplll/fpylll) for datastructures and lattice-point enumeration, and\n- [G6k](https://github.com/fplll/g6k) for lattice sieving.\n\n### Using Conda/Manually\n\n```shell\nconda create -n bddp python=3.10\nconda activate bddp\nconda install -c conda-forge sage\n\n# # It is generally not necessary to update FPLLL/FPyLLL\n\n# git clone https://github.com/fplll/fplll\n# cd fplll\n# autoreconf -i\n# ./configure --prefix=$SAGE_LOCAL --disable-static\n# make install\n# cd ..\n\n# git clone https://github.com/fplll/fpylll\n# cd fpylll\n# pip install -r requirements.txt\n# pip install -r suggestions.txt\n# python setup.py build\n# python setup.py -q install\n# cd ..\n    \ngit clone https://github.com/fplll/g6k\ncd g6k\nautoreconf -i\n./configure --prefix=$SAGE_LOCAL --disable-static\nmake\npip install -r requirements.txt\n./rebuild.sh\npython setup.py build\npython setup.py -q install \ncd ..\n```\n\n### Using Docker\n\nRunning\n\n```shell\ndocker run -ti --rm -v `pwd`:/bdd-predicate -w /bdd-predicate martinralbrecht/bdd-predicate\n```\n\nfrom the root directory of this repository  will start SageMath with recent versions of FPLLL, FPyLLL and G6K installed. Our code is available under `/bdd-predicate`. Thus, e.g.\n\n``` python\ncd /bdd-predicate\nload(\"usvp.py\")\n```\n\nwill load it.\n\n## Acknowledgements\n\nThis work was supported by EPSRC grants EP/S020330/1, EP/S02087X/1, by the European Union Horizon 2020 Research and Innovation Program Grant 780701, Innovate UK grant AQuaSec, US NSF under grants no. 1513671, 1651344, and 1913210. Part of this work was done while the authors were visiting the Simons Institute for the Theory of Computing. Our experiments were carried out on Cisco UCS equipment donated by Cisco and housed at UCSD.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmalb%2Fbdd-predicate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmalb%2Fbdd-predicate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmalb%2Fbdd-predicate/lists"}