mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-19 22:29:53 +01:00
Add basic hash tree API and implementation.
This commit is contained in:
@@ -24,6 +24,12 @@ public class MessageId extends UniqueId {
|
|||||||
public static final String BLOCK_LABEL =
|
public static final String BLOCK_LABEL =
|
||||||
"org.briarproject.bramble/MESSAGE_BLOCK";
|
"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) {
|
public MessageId(byte[] id) {
|
||||||
super(id);
|
super(id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user