%global _empty_manifest_terminate_build 0 Name: python-pymerkle Version: 5.0.3 Release: 1 Summary: merkle-tree cryptography License: GNU General Public License v3 or later (GPLv3+) URL: https://github.com/fmerg/pymerkle Source0: https://mirrors.aliyun.com/pypi/web/packages/a3/a2/99627726cdefcb5e5f2e6252e61caf95e8f3067ad22f5e00cd89d8ca85ee/pymerkle-5.0.3.tar.gz BuildArch: noarch %description # pymerkle **Merkle-tree cryptography in python** [![Build Status](https://gitlab.com/fmerg/pymerkle/badges/master/pipeline.svg)](https://gitlab.com/fmerg/pymerkle/commits/master) [![Docs Status](https://readthedocs.org/projects/pymerkle/badge/?version=latest)](http://pymerkle.readthedocs.org) [![PyPI version](https://badge.fury.io/py/pymerkle.svg)](https://pypi.org/project/pymerkle/) ![Python >= 3.10](https://img.shields.io/badge/python-%3E%3D%203.10-blue.svg) Documentation at **[pymerkle.readthedocs.org](http://pymerkle.readthedocs.org/)**. Storage agnostic implementation capable of generating inclusion and consistency proofs. ## Install ```bash pip3 install pymerkle ``` ## Basic API Let ``MerkleTree`` be any class implementing correctly the ``BaseMerkleTree`` interface; e.g., ```python from pymerkle import InmemoryTree as MerkleTree tree = MerkleTree() ``` Store data into the tree and retrieve the corresponding leaf-hash: ```python index = tree.append(b'foo') # index counting from one value = tree.get_leaf(index) # leaf hash ``` Current size and root-hash: ```python size = tree.get_size() # number of leaves state = tree.get_state() # current root hash ``` ### Inclusion proof Prove inclusion of the 3-rd leaf hash in the size 5 subtree: ```python proof = tree.prove_inclusion(3, 5) ``` Verify the proof against the base hash and the subtree root: ```python from pymerkle import verify_inclusion base = tree.get_leaf(3) target = tree.get_state(5) verify_inclusion(base, target, proof) ``` ### Consistency proof Prove consistency between the subtrees of size 3 and 5: ```python proof = tree.prove_consistency(3, 5) ``` Verify the proof against the respective root hashes: ```python from pymerkle import verify_consistency state1 = tree.get_state(3) state2 = tree.get_state(5) verify_consistency(state1, state2, proof) ``` ## Storage Pymerkle is unopinionated on how leaves are appended to the tree, i.e., how entries should be stored in concrete. Core cryptographic functionality is encapsulated in the `BaseMerkleTree` abstract class which admits pluggable storage backends. It is the developer's choice to decide how to store data in concrete by implementing the interior storage interface of this class. Any contiguously indexed dataset should do the job. ### Example This is the simplest possible non-peristent implementation utilizing a list as storage. It expects strings as entries and encodes them in utf-8 before hashing. ```python from pymerkle import BaseMerkleTree class MerkleTree(BaseMerkleTree): def __init__(self, algorithm='sha256', security=True): self.leaves = [] super().__init__(algorithm, security) def _encode_leaf(self, entry): return entry.encode('utf-8') def _store_leaf(self, entry, value): self.leaves += [(entry, value)] return len(self.leaves) def _get_leaf(self, index): _, value = self.leaves[index - 1] return value def _get_size(self): return len(self.leaves) ``` ## Security **Disclaimer**: This is currently a prototype requiring security review. ### Resistance against second-preimage attack This consists in the following standard technique: - Upon computing the hash of a leaf node, prepend `0x00` to the payload - Upon computing the hash of an interior node, prepend `0x01` to the payload Refer [here](./tests/test_defense.py) to see how to perform second-preimage attack against the present implementation. ### Resistance against CVE-2012-2459 DOS Contrary to the [bitcoin](https://en.bitcoin.it/wiki/Protocol_documentation#Merkle_Trees) spec, lonely leaves are not duplicated while the tree is growing; instead, a bifurcation node is created at the rightmost branch (see next section). As a consequence, the present implementation should be invulnerable to the [CVE-2012-2459](https://nvd.nist.gov/vuln/detail/CVE-2012-2459) DOS attack (see also [here](https://github.com/bitcoin/bitcoin/blob/bccb4d29a8080bf1ecda1fc235415a11d903a680/src/consensus/merkle.cpp) for insight). ## Tree topology Interior nodes are in general not stored in memory and no concrete links are established between them. The tree structure is determined by the recursive function which computes intermediate states on the fly and is essentially the same as [RFC 9162](https://datatracker.ietf.org/doc/html/rfc9162) (Section 2). It turns out to be that of a binary [Sakura tree](https://keccak.team/files/Sakura.pdf) (Section 5.4). ## Development ```commandline pip3 install -r requirements-dev.txt ``` ### Tests ```commandline ./test.sh --help ``` ## Documentation **[pymerkle.readthedocs.org](http://pymerkle.readthedocs.org/)**. ### Build locally Documentation is built with [`sphinx`](https://www.sphinx-doc.org/en/master/index.html): ```commandline pip3 install -r requirements-doc.txt ``` Once installed, build the docs with ```commandline ./build-docs.sh [--help] ``` and browse at ``` docs/target/build/html/index.html ``` %package -n python3-pymerkle Summary: merkle-tree cryptography Provides: python-pymerkle BuildRequires: python3-devel BuildRequires: python3-setuptools BuildRequires: python3-pip %description -n python3-pymerkle # pymerkle **Merkle-tree cryptography in python** [![Build Status](https://gitlab.com/fmerg/pymerkle/badges/master/pipeline.svg)](https://gitlab.com/fmerg/pymerkle/commits/master) [![Docs Status](https://readthedocs.org/projects/pymerkle/badge/?version=latest)](http://pymerkle.readthedocs.org) [![PyPI version](https://badge.fury.io/py/pymerkle.svg)](https://pypi.org/project/pymerkle/) ![Python >= 3.10](https://img.shields.io/badge/python-%3E%3D%203.10-blue.svg) Documentation at **[pymerkle.readthedocs.org](http://pymerkle.readthedocs.org/)**. Storage agnostic implementation capable of generating inclusion and consistency proofs. ## Install ```bash pip3 install pymerkle ``` ## Basic API Let ``MerkleTree`` be any class implementing correctly the ``BaseMerkleTree`` interface; e.g., ```python from pymerkle import InmemoryTree as MerkleTree tree = MerkleTree() ``` Store data into the tree and retrieve the corresponding leaf-hash: ```python index = tree.append(b'foo') # index counting from one value = tree.get_leaf(index) # leaf hash ``` Current size and root-hash: ```python size = tree.get_size() # number of leaves state = tree.get_state() # current root hash ``` ### Inclusion proof Prove inclusion of the 3-rd leaf hash in the size 5 subtree: ```python proof = tree.prove_inclusion(3, 5) ``` Verify the proof against the base hash and the subtree root: ```python from pymerkle import verify_inclusion base = tree.get_leaf(3) target = tree.get_state(5) verify_inclusion(base, target, proof) ``` ### Consistency proof Prove consistency between the subtrees of size 3 and 5: ```python proof = tree.prove_consistency(3, 5) ``` Verify the proof against the respective root hashes: ```python from pymerkle import verify_consistency state1 = tree.get_state(3) state2 = tree.get_state(5) verify_consistency(state1, state2, proof) ``` ## Storage Pymerkle is unopinionated on how leaves are appended to the tree, i.e., how entries should be stored in concrete. Core cryptographic functionality is encapsulated in the `BaseMerkleTree` abstract class which admits pluggable storage backends. It is the developer's choice to decide how to store data in concrete by implementing the interior storage interface of this class. Any contiguously indexed dataset should do the job. ### Example This is the simplest possible non-peristent implementation utilizing a list as storage. It expects strings as entries and encodes them in utf-8 before hashing. ```python from pymerkle import BaseMerkleTree class MerkleTree(BaseMerkleTree): def __init__(self, algorithm='sha256', security=True): self.leaves = [] super().__init__(algorithm, security) def _encode_leaf(self, entry): return entry.encode('utf-8') def _store_leaf(self, entry, value): self.leaves += [(entry, value)] return len(self.leaves) def _get_leaf(self, index): _, value = self.leaves[index - 1] return value def _get_size(self): return len(self.leaves) ``` ## Security **Disclaimer**: This is currently a prototype requiring security review. ### Resistance against second-preimage attack This consists in the following standard technique: - Upon computing the hash of a leaf node, prepend `0x00` to the payload - Upon computing the hash of an interior node, prepend `0x01` to the payload Refer [here](./tests/test_defense.py) to see how to perform second-preimage attack against the present implementation. ### Resistance against CVE-2012-2459 DOS Contrary to the [bitcoin](https://en.bitcoin.it/wiki/Protocol_documentation#Merkle_Trees) spec, lonely leaves are not duplicated while the tree is growing; instead, a bifurcation node is created at the rightmost branch (see next section). As a consequence, the present implementation should be invulnerable to the [CVE-2012-2459](https://nvd.nist.gov/vuln/detail/CVE-2012-2459) DOS attack (see also [here](https://github.com/bitcoin/bitcoin/blob/bccb4d29a8080bf1ecda1fc235415a11d903a680/src/consensus/merkle.cpp) for insight). ## Tree topology Interior nodes are in general not stored in memory and no concrete links are established between them. The tree structure is determined by the recursive function which computes intermediate states on the fly and is essentially the same as [RFC 9162](https://datatracker.ietf.org/doc/html/rfc9162) (Section 2). It turns out to be that of a binary [Sakura tree](https://keccak.team/files/Sakura.pdf) (Section 5.4). ## Development ```commandline pip3 install -r requirements-dev.txt ``` ### Tests ```commandline ./test.sh --help ``` ## Documentation **[pymerkle.readthedocs.org](http://pymerkle.readthedocs.org/)**. ### Build locally Documentation is built with [`sphinx`](https://www.sphinx-doc.org/en/master/index.html): ```commandline pip3 install -r requirements-doc.txt ``` Once installed, build the docs with ```commandline ./build-docs.sh [--help] ``` and browse at ``` docs/target/build/html/index.html ``` %package help Summary: Development documents and examples for pymerkle Provides: python3-pymerkle-doc %description help # pymerkle **Merkle-tree cryptography in python** [![Build Status](https://gitlab.com/fmerg/pymerkle/badges/master/pipeline.svg)](https://gitlab.com/fmerg/pymerkle/commits/master) [![Docs Status](https://readthedocs.org/projects/pymerkle/badge/?version=latest)](http://pymerkle.readthedocs.org) [![PyPI version](https://badge.fury.io/py/pymerkle.svg)](https://pypi.org/project/pymerkle/) ![Python >= 3.10](https://img.shields.io/badge/python-%3E%3D%203.10-blue.svg) Documentation at **[pymerkle.readthedocs.org](http://pymerkle.readthedocs.org/)**. Storage agnostic implementation capable of generating inclusion and consistency proofs. ## Install ```bash pip3 install pymerkle ``` ## Basic API Let ``MerkleTree`` be any class implementing correctly the ``BaseMerkleTree`` interface; e.g., ```python from pymerkle import InmemoryTree as MerkleTree tree = MerkleTree() ``` Store data into the tree and retrieve the corresponding leaf-hash: ```python index = tree.append(b'foo') # index counting from one value = tree.get_leaf(index) # leaf hash ``` Current size and root-hash: ```python size = tree.get_size() # number of leaves state = tree.get_state() # current root hash ``` ### Inclusion proof Prove inclusion of the 3-rd leaf hash in the size 5 subtree: ```python proof = tree.prove_inclusion(3, 5) ``` Verify the proof against the base hash and the subtree root: ```python from pymerkle import verify_inclusion base = tree.get_leaf(3) target = tree.get_state(5) verify_inclusion(base, target, proof) ``` ### Consistency proof Prove consistency between the subtrees of size 3 and 5: ```python proof = tree.prove_consistency(3, 5) ``` Verify the proof against the respective root hashes: ```python from pymerkle import verify_consistency state1 = tree.get_state(3) state2 = tree.get_state(5) verify_consistency(state1, state2, proof) ``` ## Storage Pymerkle is unopinionated on how leaves are appended to the tree, i.e., how entries should be stored in concrete. Core cryptographic functionality is encapsulated in the `BaseMerkleTree` abstract class which admits pluggable storage backends. It is the developer's choice to decide how to store data in concrete by implementing the interior storage interface of this class. Any contiguously indexed dataset should do the job. ### Example This is the simplest possible non-peristent implementation utilizing a list as storage. It expects strings as entries and encodes them in utf-8 before hashing. ```python from pymerkle import BaseMerkleTree class MerkleTree(BaseMerkleTree): def __init__(self, algorithm='sha256', security=True): self.leaves = [] super().__init__(algorithm, security) def _encode_leaf(self, entry): return entry.encode('utf-8') def _store_leaf(self, entry, value): self.leaves += [(entry, value)] return len(self.leaves) def _get_leaf(self, index): _, value = self.leaves[index - 1] return value def _get_size(self): return len(self.leaves) ``` ## Security **Disclaimer**: This is currently a prototype requiring security review. ### Resistance against second-preimage attack This consists in the following standard technique: - Upon computing the hash of a leaf node, prepend `0x00` to the payload - Upon computing the hash of an interior node, prepend `0x01` to the payload Refer [here](./tests/test_defense.py) to see how to perform second-preimage attack against the present implementation. ### Resistance against CVE-2012-2459 DOS Contrary to the [bitcoin](https://en.bitcoin.it/wiki/Protocol_documentation#Merkle_Trees) spec, lonely leaves are not duplicated while the tree is growing; instead, a bifurcation node is created at the rightmost branch (see next section). As a consequence, the present implementation should be invulnerable to the [CVE-2012-2459](https://nvd.nist.gov/vuln/detail/CVE-2012-2459) DOS attack (see also [here](https://github.com/bitcoin/bitcoin/blob/bccb4d29a8080bf1ecda1fc235415a11d903a680/src/consensus/merkle.cpp) for insight). ## Tree topology Interior nodes are in general not stored in memory and no concrete links are established between them. The tree structure is determined by the recursive function which computes intermediate states on the fly and is essentially the same as [RFC 9162](https://datatracker.ietf.org/doc/html/rfc9162) (Section 2). It turns out to be that of a binary [Sakura tree](https://keccak.team/files/Sakura.pdf) (Section 5.4). ## Development ```commandline pip3 install -r requirements-dev.txt ``` ### Tests ```commandline ./test.sh --help ``` ## Documentation **[pymerkle.readthedocs.org](http://pymerkle.readthedocs.org/)**. ### Build locally Documentation is built with [`sphinx`](https://www.sphinx-doc.org/en/master/index.html): ```commandline pip3 install -r requirements-doc.txt ``` Once installed, build the docs with ```commandline ./build-docs.sh [--help] ``` and browse at ``` docs/target/build/html/index.html ``` %prep %autosetup -n pymerkle-5.0.3 %build %py3_build %install %py3_install install -d -m755 %{buildroot}/%{_pkgdocdir} if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi pushd %{buildroot} if [ -d usr/lib ]; then find usr/lib -type f -printf "\"/%h/%f\"\n" >> filelist.lst fi if [ -d usr/lib64 ]; then find usr/lib64 -type f -printf "\"/%h/%f\"\n" >> filelist.lst fi if [ -d usr/bin ]; then find usr/bin -type f -printf "\"/%h/%f\"\n" >> filelist.lst fi if [ -d usr/sbin ]; then find usr/sbin -type f -printf "\"/%h/%f\"\n" >> filelist.lst fi touch doclist.lst if [ -d usr/share/man ]; then find usr/share/man -type f -printf "\"/%h/%f.gz\"\n" >> doclist.lst fi popd mv %{buildroot}/filelist.lst . mv %{buildroot}/doclist.lst . %files -n python3-pymerkle -f filelist.lst %dir %{python3_sitelib}/* %files help -f doclist.lst %{_docdir}/* %changelog * Tue Jun 20 2023 Python_Bot - 5.0.3-1 - Package Spec generated