/** * Returns true if the given object matches the filter either because it was inserted, or because we have a * false-positive. */ public synchronized boolean contains(byte[] object) { for (int i = 0; i < hashFuncs; i++) { if (!Utils.checkBitLE(data, murmurHash3(data, nTweak, i, object))) return false; } return true; }
/** * Returns true if the given object matches the filter either because it was inserted, or because we have a * false-positive. */ public synchronized boolean contains(byte[] object) { for (int i = 0; i < hashFuncs; i++) { if (!Utils.checkBitLE(data, murmurHash3(data, nTweak, i, object))) return false; } return true; }
/** * Returns true if the given object matches the filter either because it was inserted, or because we have a * false-positive. */ public synchronized boolean contains(byte[] object) { for (int i = 0; i < hashFuncs; i++) { if (!Utils.checkBitLE(data, murmurHash3(data, nTweak, i, object))) return false; } return true; }
/** * Returns true if the given object matches the filter either because it was inserted, or because we have a * false-positive. */ public synchronized boolean contains(byte[] object) { for (int i = 0; i < hashFuncs; i++) { if (!Utils.checkBitLE(data, murmurHash3(data, nTweak, i, object))) return false; } return true; }
private static void traverseAndBuild(int height, int pos, List<Sha256Hash> allLeafHashes, byte[] includeBits, List<Boolean> matchedChildBits, List<Sha256Hash> resultHashes) { boolean parentOfMatch = false; // Is this node a parent of at least one matched hash? for (int p = pos << height; p < (pos+1) << height && p < allLeafHashes.size(); p++) { if (Utils.checkBitLE(includeBits, p)) { parentOfMatch = true; break; } } // Store as a flag bit. matchedChildBits.add(parentOfMatch); if (height == 0 || !parentOfMatch) { // If at height 0, or nothing interesting below, store hash and stop. resultHashes.add(calcHash(height, pos, allLeafHashes)); } else { // Otherwise descend into the subtrees. int h = height - 1; int p = pos * 2; traverseAndBuild(h, p, allLeafHashes, includeBits, matchedChildBits, resultHashes); if (p + 1 < getTreeWidth(allLeafHashes.size(), h)) traverseAndBuild(h, p + 1, allLeafHashes, includeBits, matchedChildBits, resultHashes); } }
private static void traverseAndBuild(int height, int pos, List<Sha256Hash> allLeafHashes, byte[] includeBits, List<Boolean> matchedChildBits, List<Sha256Hash> resultHashes) { boolean parentOfMatch = false; // Is this node a parent of at least one matched hash? for (int p = pos << height; p < (pos+1) << height && p < allLeafHashes.size(); p++) { if (Utils.checkBitLE(includeBits, p)) { parentOfMatch = true; break; } } // Store as a flag bit. matchedChildBits.add(parentOfMatch); if (height == 0 || !parentOfMatch) { // If at height 0, or nothing interesting below, store hash and stop. resultHashes.add(calcHash(height, pos, allLeafHashes)); } else { // Otherwise descend into the subtrees. int h = height - 1; int p = pos * 2; traverseAndBuild(h, p, allLeafHashes, includeBits, matchedChildBits, resultHashes); if (p + 1 < getTreeWidth(allLeafHashes.size(), h)) traverseAndBuild(h, p + 1, allLeafHashes, includeBits, matchedChildBits, resultHashes); } }
private static void traverseAndBuild(int height, int pos, List<Sha256Hash> allLeafHashes, byte[] includeBits, List<Boolean> matchedChildBits, List<Sha256Hash> resultHashes) { boolean parentOfMatch = false; // Is this node a parent of at least one matched hash? for (int p = pos << height; p < (pos+1) << height && p < allLeafHashes.size(); p++) { if (Utils.checkBitLE(includeBits, p)) { parentOfMatch = true; break; } } // Store as a flag bit. matchedChildBits.add(parentOfMatch); if (height == 0 || !parentOfMatch) { // If at height 0, or nothing interesting below, store hash and stop. resultHashes.add(calcHash(height, pos, allLeafHashes)); } else { // Otherwise descend into the subtrees. int h = height - 1; int p = pos * 2; traverseAndBuild(h, p, allLeafHashes, includeBits, matchedChildBits, resultHashes); if (p + 1 < getTreeWidth(allLeafHashes.size(), h)) traverseAndBuild(h, p + 1, allLeafHashes, includeBits, matchedChildBits, resultHashes); } }
private static void traverseAndBuild(int height, int pos, List<Sha256Hash> allLeafHashes, byte[] includeBits, List<Boolean> matchedChildBits, List<Sha256Hash> resultHashes) { boolean parentOfMatch = false; // Is this node a parent of at least one matched hash? for (int p = pos << height; p < (pos+1) << height && p < allLeafHashes.size(); p++) { if (Utils.checkBitLE(includeBits, p)) { parentOfMatch = true; break; } } // Store as a flag bit. matchedChildBits.add(parentOfMatch); if (height == 0 || !parentOfMatch) { // If at height 0, or nothing interesting below, store hash and stop. resultHashes.add(calcHash(height, pos, allLeafHashes)); } else { // Otherwise descend into the subtrees. int h = height - 1; int p = pos * 2; traverseAndBuild(h, p, allLeafHashes, includeBits, matchedChildBits, resultHashes); if (p + 1 < getTreeWidth(allLeafHashes.size(), h)) traverseAndBuild(h, p + 1, allLeafHashes, includeBits, matchedChildBits, resultHashes); } }
boolean parentOfMatch = checkBitLE(matchedChildBits, used.bitsUsed++); if (height == 0 || !parentOfMatch) {
private Sha256Hash recursiveExtractHashes(int height, int pos, ValuesUsed used, List<Sha256Hash> matchedHashes) throws VerificationException { if (used.bitsUsed >= matchedChildBits.length*8) { // overflowed the bits array - failure throw new VerificationException("PartialMerkleTree overflowed its bits array"); } boolean parentOfMatch = checkBitLE(matchedChildBits, used.bitsUsed++); if (height == 0 || !parentOfMatch) { // if at height 0, or nothing interesting below, use stored hash and do not descend if (used.hashesUsed >= hashes.size()) { // overflowed the hash array - failure throw new VerificationException("PartialMerkleTree overflowed its hash array"); } Sha256Hash hash = hashes.get(used.hashesUsed++); if (height == 0 && parentOfMatch) // in case of height 0, we have a matched txid matchedHashes.add(hash); return hash; } else { // otherwise, descend into the subtrees to extract matched txids and hashes byte[] left = recursiveExtractHashes(height - 1, pos * 2, used, matchedHashes).getBytes(), right; if (pos * 2 + 1 < getTreeWidth(transactionCount, height-1)) { right = recursiveExtractHashes(height - 1, pos * 2 + 1, used, matchedHashes).getBytes(); if (Arrays.equals(right, left)) throw new VerificationException("Invalid merkle tree with duplicated left/right branches"); } else { right = left; } // and combine them before returning return combineLeftRight(left, right); } }
private Sha256Hash recursiveExtractHashes(int height, int pos, ValuesUsed used, List<Sha256Hash> matchedHashes) throws VerificationException { if (used.bitsUsed >= matchedChildBits.length*8) { // overflowed the bits array - failure throw new VerificationException("PartialMerkleTree overflowed its bits array"); } boolean parentOfMatch = checkBitLE(matchedChildBits, used.bitsUsed++); if (height == 0 || !parentOfMatch) { // if at height 0, or nothing interesting below, use stored hash and do not descend if (used.hashesUsed >= hashes.size()) { // overflowed the hash array - failure throw new VerificationException("PartialMerkleTree overflowed its hash array"); } Sha256Hash hash = hashes.get(used.hashesUsed++); if (height == 0 && parentOfMatch) // in case of height 0, we have a matched txid matchedHashes.add(hash); return hash; } else { // otherwise, descend into the subtrees to extract matched txids and hashes byte[] left = recursiveExtractHashes(height - 1, pos * 2, used, matchedHashes).getBytes(), right; if (pos * 2 + 1 < getTreeWidth(transactionCount, height-1)) { right = recursiveExtractHashes(height - 1, pos * 2 + 1, used, matchedHashes).getBytes(); if (Arrays.equals(right, left)) throw new VerificationException("Invalid merkle tree with duplicated left/right branches"); } else { right = left; } // and combine them before returning return combineLeftRight(left, right); } }
private Sha256Hash recursiveExtractHashes(int height, int pos, ValuesUsed used, List<Sha256Hash> matchedHashes) throws VerificationException { if (used.bitsUsed >= matchedChildBits.length*8) { // overflowed the bits array - failure throw new VerificationException("PartialMerkleTree overflowed its bits array"); } boolean parentOfMatch = checkBitLE(matchedChildBits, used.bitsUsed++); if (height == 0 || !parentOfMatch) { // if at height 0, or nothing interesting below, use stored hash and do not descend if (used.hashesUsed >= hashes.size()) { // overflowed the hash array - failure throw new VerificationException("PartialMerkleTree overflowed its hash array"); } Sha256Hash hash = hashes.get(used.hashesUsed++); if (height == 0 && parentOfMatch) // in case of height 0, we have a matched txid matchedHashes.add(hash); return hash; } else { // otherwise, descend into the subtrees to extract matched txids and hashes byte[] left = recursiveExtractHashes(height - 1, pos * 2, used, matchedHashes).getBytes(), right; if (pos * 2 + 1 < getTreeWidth(transactionCount, height-1)) { right = recursiveExtractHashes(height - 1, pos * 2 + 1, used, matchedHashes).getBytes(); if (Arrays.equals(right, left)) throw new VerificationException("Invalid merkle tree with duplicated left/right branches"); } else { right = left; } // and combine them before returning return combineLeftRight(left, right); } }