Adds salt to the bloom filter

This commit is contained in:
Vitor Pamplona
2024-09-15 14:28:49 -04:00
parent 5921b712b0
commit 428ed464af
@@ -41,6 +41,7 @@ class BloomFilter(
private val size: Int, private val size: Int,
private val rounds: Int, private val rounds: Int,
private val bits: BitSet = BitSet(size), private val bits: BitSet = BitSet(size),
private val salt: ByteArray = CryptoUtils.random(8),
) { ) {
private val hash = MessageDigest.getInstance("SHA-256") private val hash = MessageDigest.getInstance("SHA-256")
private val lock = ReentrantReadWriteLock() private val lock = ReentrantReadWriteLock()
@@ -76,34 +77,33 @@ class BloomFilter(
return true return true
} }
fun encode() = "$size:$rounds:${Base64.getEncoder().encodeToString(bits.toByteArray())}" fun encode() = "$size:$rounds:${Base64.getEncoder().encodeToString(bits.toByteArray())}:${Base64.getEncoder().encodeToString(salt)}"
fun hash( fun hash(
seed: Int, seed: Int,
value: ByteArray, value: ByteArray,
) = BigInteger(1, hash.digest(value + seed.toByte())) ) = BigInteger(1, hash.digest(value + salt + seed.toByte()))
.remainder(BigInteger.valueOf(size.toLong())) .remainder(BigInteger.valueOf(size.toLong()))
.toInt() .toInt()
companion object { companion object {
fun decode(encodedStr: String): BloomFilter { fun decode(encodedStr: String): BloomFilter {
val parts = encodedStr.split(":") val (sizeStr, roundsStr, filterB64, saltB64) = encodedStr.split(":")
val size = parts[0].toInt() val bitSet = BitSet.valueOf(Base64.getDecoder().decode(filterB64))
val rounds = parts[1].toInt() val salt = Base64.getDecoder().decode(saltB64)
val bitSet = BitSet.valueOf(Base64.getDecoder().decode(parts[2])) return BloomFilter(sizeStr.toInt(), roundsStr.toInt(), bitSet, salt)
return BloomFilter(size, rounds, bitSet)
} }
} }
} }
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
class BloomFilterTest { class BloomFilterTest {
val testEncoded = "100:10:QGKCgBEBAAhIAApO" val testEncoded = "100:10:AAAkAQANcYQFCQoB:hZkZYqqdxcE="
val testInBinary = "00000010010001100100000100000001100010001000000000000000000100000001001000000000010100000111001000000000000000000000000000000000" val testInBinary = "00000000000000000010010010000000000000001011000010001110001000011010000010010000010100001000000000000000000000000000000000000000"
@Test @Test
fun testCreate() { fun testCreate() {
val bloomFilter = BloomFilter(100, 10) val bloomFilter = BloomFilter(100, 10, salt = Base64.getDecoder().decode("hZkZYqqdxcE="))
bloomFilter.add("ca29c211f1c72d5b6622268ff43d2288ea2b2cb5b9aa196ff9f1704fc914b71b") bloomFilter.add("ca29c211f1c72d5b6622268ff43d2288ea2b2cb5b9aa196ff9f1704fc914b71b")
bloomFilter.add("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") bloomFilter.add("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c")