mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 03:09:04 +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 =
|
||||
"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);
|
||||
}
|
||||
|
||||
@@ -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