{"id":37066937,"url":"https://github.com/nthparty/circuitry","last_synced_at":"2026-01-14T07:51:26.303Z","repository":{"id":62562271,"uuid":"250124514","full_name":"nthparty/circuitry","owner":"nthparty","description":"Embedded domain-specific combinator library for the abstract assembly and automated synthesis of logical circuits.","archived":false,"fork":false,"pushed_at":"2023-01-30T03:56:19.000Z","size":161,"stargazers_count":8,"open_issues_count":4,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-05T08:21:11.690Z","etag":null,"topics":["circuit","circuits","data-structures","domain-specific-language","domain-specific-languages","embedded-language","garbled-circuits","logic","logic-circuit","logic-circuits","logic-gates","logical-circuit","logical-circuits","logical-gates","mpc","multi-party-computation","multiparty-computation","python","secure-multi-party-computation"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/circuitry","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nthparty.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-26T00:39:39.000Z","updated_at":"2025-11-08T04:16:28.000Z","dependencies_parsed_at":"2023-02-16T03:46:07.629Z","dependency_job_id":null,"html_url":"https://github.com/nthparty/circuitry","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/nthparty/circuitry","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nthparty%2Fcircuitry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nthparty%2Fcircuitry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nthparty%2Fcircuitry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nthparty%2Fcircuitry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nthparty","download_url":"https://codeload.github.com/nthparty/circuitry/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nthparty%2Fcircuitry/sbom","scorecard":{"id":697697,"data":{"date":"2025-08-11","repo":{"name":"github.com/nthparty/circuitry","commit":"035120e87a07cb436a809d88866415ea3f5d735d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/lint-test-cover-docs.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint-test-cover-docs.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/nthparty/circuitry/lint-test-cover-docs.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint-test-cover-docs.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/nthparty/circuitry/lint-test-cover-docs.yml/main?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/lint-test-cover-docs.yml:20","Warn: pipCommand not pinned by hash: .github/workflows/lint-test-cover-docs.yml:25","Warn: pipCommand not pinned by hash: .github/workflows/lint-test-cover-docs.yml:32","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   3 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-22T04:12:52.286Z","repository_id":62562271,"created_at":"2025-08-22T04:12:52.286Z","updated_at":"2025-08-22T04:12:52.286Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28413512,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T05:26:33.345Z","status":"ssl_error","status_checked_at":"2026-01-14T05:21:57.251Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["circuit","circuits","data-structures","domain-specific-language","domain-specific-languages","embedded-language","garbled-circuits","logic","logic-circuit","logic-circuits","logic-gates","logical-circuit","logical-circuits","logical-gates","mpc","multi-party-computation","multiparty-computation","python","secure-multi-party-computation"],"created_at":"2026-01-14T07:51:25.826Z","updated_at":"2026-01-14T07:51:26.289Z","avatar_url":"https://github.com/nthparty.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"=========\ncircuitry\n=========\n\nEmbedded domain-specific combinator library for the abstract assembly and automated synthesis of logical circuits.\n\n|pypi| |readthedocs| |actions| |coveralls|\n\n.. |pypi| image:: https://badge.fury.io/py/circuitry.svg\n   :target: https://badge.fury.io/py/circuitry\n   :alt: PyPI version and link.\n\n.. |readthedocs| image:: https://readthedocs.org/projects/circuitry/badge/?version=latest\n   :target: https://circuitry.readthedocs.io/en/latest/?badge=latest\n   :alt: Read the Docs documentation status.\n\n.. |actions| image:: https://github.com/nthparty/circuitry/workflows/lint-test-cover-docs/badge.svg\n   :target: https://github.com/nthparty/circuitry/actions/workflows/lint-test-cover-docs.yml\n   :alt: GitHub Actions status.\n\n.. |coveralls| image:: https://coveralls.io/repos/github/nthparty/circuitry/badge.svg?branch=main\n   :target: https://coveralls.io/github/nthparty/circuitry?branch=main\n   :alt: Coveralls test coverage summary.\n\nPurpose\n-------\nThis embedded domain-specific language (DSL) makes it possible to write an algorithm in Python that operates on bit values and/or bit vectors, and then to interpret that algorithm implementation as a circuit definition in order to synthesize automatically a logical circuit represented using the `circuit \u003chttps://pypi.org/project/circuit\u003e`__ library. Additional background information and examples can be found in a `relevant report \u003chttps://eprint.iacr.org/2020/1604\u003e`__.\n\nInstallation and Usage\n----------------------\nThis library is available as a `package on PyPI \u003chttps://pypi.org/project/circuitry\u003e`__::\n\n    python -m pip install circuitry\n\nThe library can be imported in the usual ways::\n\n    import circuitry\n    from circuitry import *\n\nExamples\n^^^^^^^^\n\n.. |bit| replace:: ``bit``\n.. _bit: https://circuitry.readthedocs.io/en/2.0.0/_source/circuitry.html#circuitry.circuitry.bit\n\n.. |synthesize| replace:: ``synthesize``\n.. _synthesize: https://circuitry.readthedocs.io/en/2.0.0/_source/circuitry.html#circuitry.circuitry.synthesize\n\n.. |circuit_| replace:: ``circuit``\n.. _circuit_: https://circuit.readthedocs.io/en/2.0.0/_source/circuit.html#circuit.circuit.circuit\n\n.. |disjunction| replace:: ``__or__``\n.. _disjunction: https://circuitry.readthedocs.io/en/2.0.0/_source/circuitry.html#circuitry.circuitry.bit.__or__\n\nThis library makes it possible to embed within Python a function that operates on individual bits and/or bit vectors (subject to specific limitations) and then to automatically synthesize a logical circuit that implements that function. In the simple example below, the defined bit equality function takes two |bit|_ objects as its inputs and returns one |bit|_ object as its output. Because nearly all built-in Python operators are supported by the |bit|_ class via `appropriate method definitions \u003chttps://docs.python.org/3/reference/datamodel.html#emulating-numeric-types\u003e`__ (*e.g.*, see the |disjunction|_ method), the statements and expressions in the function can employ a straightforward and familiar syntax::\n\n    \u003e\u003e\u003e from circuitry import *\n    \u003e\u003e\u003e @synthesize\n    ... def equal(x: bit, y: bit) -\u003e bit:\n    ...     return (x \u0026 y) | ((1 - x) \u0026 (1 - y))\n\nThe function itself can be invoked in the usual manner if the supplied inputs are integers or instances of the |bit|_ class::\n\n    \u003e\u003e\u003e equal(0, 1)\n    0\n    \u003e\u003e\u003e b = equal(bit(0), bit(1))\n    \u003e\u003e\u003e isinstance(b, bit)\n    True\n    \u003e\u003e\u003e int(b)\n    0\n\n.. |circuit__| replace:: ``circuit``\n.. _circuit__: https://circuit.readthedocs.io/en/2.0.0/_source/circuit.html#circuit.circuit.circuit\n\nThe |synthesize|_ decorator automatically synthesizes the corresponding circuit (as an instance of the |circuit_|_ class defined in the `circuit \u003chttps://pypi.org/project/circuit\u003e`__ library). The synthesized |circuit__|_ object is stored within an attribute of the function itself and can be evaluated on two bit values (as specified by the function's type annotation). See the documentation of the `circuit \u003chttps://pypi.org/project/circuit\u003e`__ library for more information on how input bit vectors should be structured when evaluating a circuit::\n\n    \u003e\u003e\u003e equal.circuit.evaluate([[0], [1]])\n    [[0]]\n\n.. |bits| replace:: ``bits``\n.. _bits: https://circuitry.readthedocs.io/en/2.0.0/_source/circuitry.html#circuitry.circuitry.bits\n\nThe |synthesize|_ decorator can also be applied to functions that are defined explicitly as operating on *bit vectors* (where bit vectors can be represented as lists of integers or as |bits|_ objects). Furthermore, functions can be invoked in other functions, making it possible to reuse modular algorithm components. In the example below, the bit vector equality function invokes the bit equality function defined above::\n\n    \u003e\u003e\u003e @synthesize\n    ... def equals(xs: bits(8), ys: bits(8)) -\u003e bit:\n    ...     z = 1\n    ...     for i in range(8):\n    ...         z = z \u0026 equal(xs[i], ys[i])\n    ...     return z\n    \u003e\u003e\u003e bs = [0, 1, 1, 0, 1, 0, 1, 0]\n    \u003e\u003e\u003e equals.circuit.evaluate([bs, bs])\n    [[1]]\n    \u003e\u003e\u003e equals.circuit.count() # Number of gates in circuit.\n    66\n\nBecause a circuit is synthesized via standard execution of a decorated Python function, all native Python language features (and even external libraries) can be employed. The most important constraint (which is the responsibility of the programmer to maintain) is that the execution of the function (*i.e.*, the `flow of control \u003chttps://en.wikipedia.org/wiki/Control_flow\u003e`__) should not depend on the *values* of the inputs bits. The alternative implementation below demonstrates that recursion and higher-order functions can be used within decorated functions::\n\n    \u003e\u003e\u003e from functools import reduce\n    \u003e\u003e\u003e @synthesize\n    ... def equals(xs: bits(8), ys: bits(8)) -\u003e bit:\n    ...     es = [equal(x, y) for (x, y) in zip(xs, ys)]\n    ...     return reduce((lambda e0, e1: e0 \u0026 e1), es)\n    \u003e\u003e\u003e bs = [0, 1, 1, 0, 1, 0, 1, 0]\n    \u003e\u003e\u003e equals.circuit.evaluate([bs, list(reversed(bs))])\n    [[0]]\n    \u003e\u003e\u003e equals.circuit.count() # Number of gates in circuit.\n    64\n\nA `more complex example \u003chttps://circuitry.readthedocs.io/en/2.0.0/_source/test_circuitry.html#test.test_circuitry.sha256\u003e`__ involving an implementation of SHA-265 that conforms to the `FIPS 180-4 specification \u003chttps://www.tandfonline.com/doi/abs/10.1080/01611194.2012.687431\u003e`__ is found in the `testing script \u003chttps://circuitry.readthedocs.io/en/2.0.0/_source/test_circuitry.html\u003e`__ that accompanies this library. The SHA-256 example is also described in a `relevant report \u003chttps://eprint.iacr.org/2020/1604\u003e`__.\n\nDevelopment\n-----------\nAll installation and development dependencies are fully specified in ``pyproject.toml``. The ``project.optional-dependencies`` object is used to `specify optional requirements \u003chttps://peps.python.org/pep-0621\u003e`__ for various development tasks. This makes it possible to specify additional options (such as ``docs``, ``lint``, and so on) when performing installation using `pip \u003chttps://pypi.org/project/pip\u003e`__::\n\n    python -m pip install .[docs,lint]\n\nDocumentation\n^^^^^^^^^^^^^\nThe documentation can be generated automatically from the source files using `Sphinx \u003chttps://www.sphinx-doc.org\u003e`__::\n\n    python -m pip install .[docs]\n    cd docs\n    sphinx-apidoc -f -E --templatedir=_templates -o _source .. \u0026\u0026 make html\n\nTesting and Conventions\n^^^^^^^^^^^^^^^^^^^^^^^\nAll unit tests are executed and their coverage is measured when using `pytest \u003chttps://docs.pytest.org\u003e`__ (see the ``pyproject.toml`` file for configuration details)::\n\n    python -m pip install .[test]\n    python -m pytest\n\nThe subset of the unit tests included in the module itself and the *documentation examples* that appear in the testing script can be executed separately using `doctest \u003chttps://docs.python.org/3/library/doctest.html\u003e`__::\n\n    python src/circuitry/circuitry.py -v\n    python test/test_circuitry.py -v\n\nStyle conventions are enforced using `Pylint \u003chttps://pylint.pycqa.org\u003e`__::\n\n    python -m pip install .[lint]\n    python -m pylint src/circuitry test/test_circuitry.py\n\nContributions\n^^^^^^^^^^^^^\nIn order to contribute to the source code, open an issue or submit a pull request on the `GitHub page \u003chttps://github.com/nthparty/circuitry\u003e`__ for this library.\n\nVersioning\n^^^^^^^^^^\nBeginning with version 0.1.0, the version number format for this library and the changes to the library associated with version number increments conform with `Semantic Versioning 2.0.0 \u003chttps://semver.org/#semantic-versioning-200\u003e`__.\n\nPublishing\n^^^^^^^^^^\nThis library can be published as a `package on PyPI \u003chttps://pypi.org/project/circuitry\u003e`__ by a package maintainer. First, install the dependencies required for packaging and publishing::\n\n    python -m pip install .[publish]\n\nEnsure that the correct version number appears in ``pyproject.toml``, and that any links in this README document to the Read the Docs documentation of this package (or its dependencies) have appropriate version numbers. Also ensure that the Read the Docs project for this library has an `automation rule \u003chttps://docs.readthedocs.io/en/stable/automation-rules.html\u003e`__ that activates and sets as the default all tagged versions. Create and push a tag for this version (replacing ``?.?.?`` with the version number)::\n\n    git tag ?.?.?\n    git push origin ?.?.?\n\nRemove any old build/distribution files and package the source into a distribution archive::\n\n    rm -rf build dist src/*.egg-info\n    python -m build --sdist --wheel .\n\nFinally, upload the package distribution archive to `PyPI \u003chttps://pypi.org\u003e`__ using the `twine \u003chttps://pypi.org/project/twine\u003e`__ package::\n\n    python -m twine upload dist/*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnthparty%2Fcircuitry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnthparty%2Fcircuitry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnthparty%2Fcircuitry/lists"}