diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | python-pymerkle.spec | 681 | ||||
-rw-r--r-- | sources | 1 |
3 files changed, 683 insertions, 0 deletions
@@ -0,0 +1 @@ +/pymerkle-5.0.3.tar.gz diff --git a/python-pymerkle.spec b/python-pymerkle.spec new file mode 100644 index 0000000..85a5c16 --- /dev/null +++ b/python-pymerkle.spec @@ -0,0 +1,681 @@ +%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** + +[](https://gitlab.com/fmerg/pymerkle/commits/master) +[](http://pymerkle.readthedocs.org) +[](https://pypi.org/project/pymerkle/) + + +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** + +[](https://gitlab.com/fmerg/pymerkle/commits/master) +[](http://pymerkle.readthedocs.org) +[](https://pypi.org/project/pymerkle/) + + +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** + +[](https://gitlab.com/fmerg/pymerkle/commits/master) +[](http://pymerkle.readthedocs.org) +[](https://pypi.org/project/pymerkle/) + + +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 <Python_Bot@openeuler.org> - 5.0.3-1 +- Package Spec generated @@ -0,0 +1 @@ +bf835a0fe98ea77ebea2dc0b99348633 pymerkle-5.0.3.tar.gz |