Add basic hash tree API and implementation.

This commit is contained in:
akwizgran
2018-12-06 16:07:22 +00:00
parent f915eb4d36
commit 4b04e6a21d
7 changed files with 126 additions and 0 deletions

View File

@@ -24,6 +24,12 @@ public class MessageId extends UniqueId {
public static final String BLOCK_LABEL =
"org.briarproject.bramble/MESSAGE_BLOCK";
/**
* Label for hashing two tree hashes to produce a parent.
*/
public static final String TREE_LABEL =
"org.briarproject.bramble/MESSAGE_TREE";
public MessageId(byte[] id) {
super(id);
}

View File

@@ -0,0 +1,8 @@
package org.briarproject.bramble.api.sync.tree;
public class LeafNode extends TreeNode {
public LeafNode(TreeHash hash, int blockNumber) {
super(hash, 0, blockNumber, blockNumber);
}
}

View File

@@ -0,0 +1,9 @@
package org.briarproject.bramble.api.sync.tree;
public class ParentNode extends TreeNode {
public ParentNode(TreeHash hash, TreeNode left, TreeNode right) {
super(hash, Math.max(left.getHeight(), right.getHeight()) + 1,
left.getFirstBlockNumber(), right.getLastBlockNumber());
}
}

View File

@@ -0,0 +1,24 @@
package org.briarproject.bramble.api.sync.tree;
import org.briarproject.bramble.api.UniqueId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.ThreadSafe;
/**
* Type-safe wrapper for a byte array that uniquely identifies a sequence of
* one or more message blocks.
*/
@ThreadSafe
@NotNullByDefault
public class TreeHash extends UniqueId {
public TreeHash(byte[] id) {
super(id);
}
@Override
public boolean equals(Object o) {
return o instanceof TreeHash && super.equals(o);
}
}

View File

@@ -0,0 +1,8 @@
package org.briarproject.bramble.api.sync.tree;
public interface TreeHasher {
LeafNode hashBlock(int blockNumber, byte[] data);
ParentNode mergeTrees(TreeNode left, TreeNode right);
}

View File

@@ -0,0 +1,31 @@
package org.briarproject.bramble.api.sync.tree;
public class TreeNode {
private final TreeHash hash;
private final int height, firstBlockNumber, lastBlockNumber;
TreeNode(TreeHash hash, int height, int firstBlockNumber,
int lastBlockNumber) {
this.hash = hash;
this.height = height;
this.firstBlockNumber = firstBlockNumber;
this.lastBlockNumber = lastBlockNumber;
}
public TreeHash getHash() {
return hash;
}
public int getHeight() {
return height;
}
public int getFirstBlockNumber() {
return firstBlockNumber;
}
public int getLastBlockNumber() {
return lastBlockNumber;
}
}

View File

@@ -0,0 +1,40 @@
package org.briarproject.bramble.sync.tree;
import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.sync.tree.LeafNode;
import org.briarproject.bramble.api.sync.tree.ParentNode;
import org.briarproject.bramble.api.sync.tree.TreeHash;
import org.briarproject.bramble.api.sync.tree.TreeHasher;
import org.briarproject.bramble.api.sync.tree.TreeNode;
import javax.inject.Inject;
import static org.briarproject.bramble.api.sync.Message.FORMAT_VERSION;
import static org.briarproject.bramble.api.sync.MessageId.BLOCK_LABEL;
import static org.briarproject.bramble.api.sync.MessageId.TREE_LABEL;
class TreeHasherImpl implements TreeHasher {
private static final byte[] FORMAT_VERSION_BYTES =
new byte[] {FORMAT_VERSION};
private final CryptoComponent crypto;
@Inject
TreeHasherImpl(CryptoComponent crypto) {
this.crypto = crypto;
}
@Override
public LeafNode hashBlock(int blockNumber, byte[] data) {
byte[] hash = crypto.hash(BLOCK_LABEL, FORMAT_VERSION_BYTES, data);
return new LeafNode(new TreeHash(hash), blockNumber);
}
@Override
public ParentNode mergeTrees(TreeNode left, TreeNode right) {
byte[] hash = crypto.hash(TREE_LABEL, FORMAT_VERSION_BYTES,
left.getHash().getBytes(), right.getHash().getBytes());
return new ParentNode(new TreeHash(hash), left, right);
}
}