Class Proof

java.lang.Object
io.crums.util.mrkl.Proof

public class Proof extends Object
A cryptographic path from an item (expressed in bytes) to the root of a Merkle tree. Note although instances are immutable, a reference to one does not imply a verified proof. For such a guarantee, considering defining a subclass.
See Also:
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    protected
    Proof(Proof copy)
    Copy constructor.
     
    Proof(Tree tree, int leafIndex)
     
     
    Proof(String algo, int leafCount, int leafIndex, byte[][] chain)
     
     
    Proof(String algo, int leafCount, int leafIndex, byte[][] chain, boolean copy)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    Returns the hash chain.
    static int
    chainLength(int leafCount, int leafIndex)
    Returns the chain length.
    final boolean
     
    Returns the proof's funnel.
    static int
    funnelLength(int leafCount, int leafIndex)
    Returns the funnel length.
    final String
     
    final List<byte[]>
    Returns the hash chain.
    final int
     
    final byte[]
    Returns [a copy of] the item proven.
    final int
    Returns the total number of leaves in the tree from which this proof was constructed.
    final int
    The [leaf] index of the item proven.
    static byte[]
    merkleRoot(ByteBuffer item, int index, int count, List<ByteBuffer> funnel, MessageDigest digest)
    Computes and returns the merkle root for the given item and proof-funnel.
    final byte[]
    Returns[a copy of] the hash at the root of the Merkle tree.
    final boolean
    Verifies this proof and returns the result.

    Methods inherited from class java.lang.Object

    clone, finalize, getClass, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

  • Method Details

    • verify

      public final boolean verify(MessageDigest digest)
      Verifies this proof and returns the result.
    • chainLength

      public static int chainLength(int leafCount, int leafIndex)
      Returns the chain length.
    • funnelLength

      public static int funnelLength(int leafCount, int leafIndex)
      Returns the funnel length.
    • merkleRoot

      public static byte[] merkleRoot(ByteBuffer item, int index, int count, List<ByteBuffer> funnel, MessageDigest digest)
      Computes and returns the merkle root for the given item and proof-funnel.

      On Proof Funnels

      In many an application, a merkle proof is a link in a larger hash proof. Thus, it may be possible (there's already a usecase) that both the item and its merkle-coordinates (and even this method's return value) are already known. In such cases, the funnel argument below is the most compact scheme for establishing a cryptographic link to the root hash.

      This funnel concept is not unique to merkle proofs. Time permitting, I'll flesh it out more.

      Parameters:
      item - the leaf value in the merkle tree; its coordinates follow..
      index - item leaf-index in the merkle tree
      count - no. of items in the merkle tree
      funnel - intermediate node hashes in a merkle proof
      digest - digester
      Returns:
      root hash of the merkle tree
      See Also:
    • equals

      public final boolean equals(Object o)
      Overrides:
      equals in class Object
    • hashCode

      public final int hashCode()
      Overrides:
      hashCode in class Object
    • leafIndex

      public final int leafIndex()
      The [leaf] index of the item proven.
    • leafCount

      public final int leafCount()
      Returns the total number of leaves in the tree from which this proof was constructed. The number of leaves determines the structure of the tree, which in turn governs the validity of the proof.
    • getHashAlgo

      public final String getHashAlgo()
    • hashChain

      public final List<byte[]> hashChain()
      Returns the hash chain. The returned list is immutable (both structurally and contents-wise). The first element in the list is the item, the last element is root of the Merkle tree, and the elements in between are siblings on the path to root.

      So the element at index 1 is the first element's (the item's) sibling, the element at index 2 is the sibling of the (implied and calculable) parent of the first 2 elements, the element at index 3 the sibling of the parent of the last element, and so on, until the last child of root.

      Note the returned list does not contain information on its own about the handedness of the nodes (whether they join their siblings from the left or the right); that is established the leaf index and leaf count.

    • chain

      public final List<ByteBuffer> chain()
      Returns the hash chain. The first element in the list is [a view of] the item, the last element is [a view of] the root of the Merkle tree, and the elements in between are siblings on the path to root.

      So the element at index 1 is the first element's (the item's) sibling, the element at index 2 is the sibling of the (implied and calculable) parent of the first 2 elements, the element at index 3 the sibling of the parent of the last element, and so on, until the last child of root.

      Note the returned list does not contain information on its own about the handedness of the nodes (whether they join their siblings from the left or the right); that is established the leaf index and leaf count.

      Returns:
      list that generates a new buffer one each invocation of List.get(int), of size >= 3
    • funnel

      public final List<ByteBuffer> funnel()
      Returns the proof's funnel.
      Returns:
      the chain() with first and last elements clipped
      See Also:
    • rootHash

      public final byte[] rootHash()
      Returns[a copy of] the hash at the root of the Merkle tree.
    • item

      public final byte[] item()
      Returns [a copy of] the item proven.