Skip to main content

A Python library for constructing Merkle Trees and validating Log Proofs

Project description

pymerkle: A Python library for constructing Merkle Trees and validating Log Proofs

Build Status Docs Status PyPI version Python >= 3.6

Complete documentation can be found at pymerkle.readthedocs.org.

This library implements

  • a class for binary balanced Merkle-Trees (with possibly odd number of leaves) capable of generating consistency-proofs except for audit-proofs (along with inclusion-tests), supporting all hashing algorithms (including SHA3 variations) and most encoding types provided by Python>=3.6
  • defense against second-preimage attack
  • flexible mechanisms for validating the generated proofs

It is currently the only Python library implementing all the above features, with an eye on protocols like Certificate Transparency and real-life applications.

Installation

pip3 install pymerkle

Quick example

See also Usage and API

from pymerkle import *           # Import MerkleTree, validateProof
                                 # and ProofValidator
tree = MerkleTree()              # Create empty SHA256/UTF-8 Merkle-tree with
                                 # defense against second-preimage attack
validator = ProofValidator()     # Create object for validating proofs

# Successively update the tree with one hundred records
for i in range(100):
    tree.update(bytes('{}-th record'.format(i), 'utf-8'))

p = tree.auditProof(b'12-th record') # Generate audit-proof for the given record
q = tree.auditProof(55) # Generate audit-proof based upon the 56-th leaf

# Quick validation of the above proofs
validateProof(target_hash=tree.rootHash(), proof=p) # True
validateProof(target_hash=tree.rootHash(), proof=q) # True

# Store the tree's current state (root-hash and length) for later use
top_hash = tree.rootHash()
length = tree.length()

# Update the tree by encrypting a new log
tree.encryptLog('logs/sample_log')

# Generate consistency-proof for the stage before encrypting the log
r = tree.consistencyProof(old_hash=top_hash, sublength=length)

# Validate consistency-proof and generate receipt
validation_receipt = validator.validate(target_hash=tree.rootHash(), proof=r)

Tree structure

Contrary to most implementations, the Merkle-tree is here always binary balanced, with all nodes except for the exterior ones (leaves) having two parents. This is achieved as follows: upon appending a block of new leaves, instead of promoting a lonely leaf or duplicating it, a bifurcation node gets created so that trees with the same number of leaves have always identical structure and input clashes among growing strategies be avoided (independently of the configured hash and encoding types). This standardization is further crucial for:

  • fast generation of consistency-proof paths (based on additive decompositions in decreasing powers of 2)
  • fast recalculation of the root-hash after appending a new leaf, since only the hashes at the tree's left-most branch need be recalculated
  • memory efficiency, since the height as well as total number of nodes with respect to the tree's length is controlled to the minimum. For example, a tree with 9 leaves has 17 nodes in the present implementation, whereas the total number of nodes in the structure described here is 20.

The topology is namely identical to that of a binary Sekura tree, depicted in Section 5.4 of this paper. Follow the straightforward algorithm of the MerkleTree.update method for further insight, or the gradual development exposed in the tests/test_tree_structure.py file inside the project's repository.

Deviation from bitcoin specification

In contrast to the bitcoin specification for Merkle-trees, lonely leaves are not duplicated in order for the tree to remain genuinely binary. Instead, creating bifurcation nodes at the rightmost branch allows the tree to remain balanced upon any update. As a consequence, even if security against second-preimage attack (see below) were deactivated, the current implementation is by structure invulnerable to the kind of attack that is described here.

Defense against second-preimage attack

Defense against second-preimage attack is by default activated. Roughly speaking, it consists in the following security measures:

  • Before calculating the hash of a leaf, prepend the corresponding record with the null hexadecimal 0x00

  • Before calculating the hash any interior node, prepend both of its parents' hashes with the unit hexadecimal 0x01

(See here or here for some insight). Read the tests/test_defense.py file inside the project's repository to see how to perform second-preimage attacks against the current implementation.

Running tests

In order to run all integration tests, execute

./run_tests.sh

from inside the root directory of the project. Alternatively, run the command pytest tests/. You can run only a specific test file, e.g., test_log_encryption.py, with the command pytest tests/test_log_encryption.py.

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

pymerkle-2.0.1b0.tar.gz (27.0 kB view details)

Uploaded Source

Built Distribution

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

pymerkle-2.0.1b0-py3-none-any.whl (35.6 kB view details)

Uploaded Python 3

File details

Details for the file pymerkle-2.0.1b0.tar.gz.

File metadata

  • Download URL: pymerkle-2.0.1b0.tar.gz
  • Upload date:
  • Size: 27.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.20.1 setuptools/40.6.3 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.6.7

File hashes

Hashes for pymerkle-2.0.1b0.tar.gz
Algorithm Hash digest
SHA256 d50df34aab102f8570a41d3d21a90384d88183a71d80584ad692000866c63c4a
MD5 4d2d01c3dfcfbe60fe510002b2538697
BLAKE2b-256 bbf3bf81438dd2a5faa54aa6ad50d0ea7e2ec622edea531e6de31760a2ca9465

See more details on using hashes here.

File details

Details for the file pymerkle-2.0.1b0-py3-none-any.whl.

File metadata

  • Download URL: pymerkle-2.0.1b0-py3-none-any.whl
  • Upload date:
  • Size: 35.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.20.1 setuptools/40.6.3 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.6.7

File hashes

Hashes for pymerkle-2.0.1b0-py3-none-any.whl
Algorithm Hash digest
SHA256 bf0e857ec7f56cc81eb65d22e28af20b183bf4c18d71a8d81d81a66d1a173dc3
MD5 d5423cd79aa338c15f113c969f9a7bdc
BLAKE2b-256 c7a8d62840408a89ee7d244ad16d01e6ca569dde621ef70b0915e34c2bdf7cb7

See more details on using hashes here.

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