def test_public_smoke_matches(random, seed, data): """Prepare a params struct, and make sure the UMASH function matches our reference.""" params = FFI.new("struct umash_params[1]") size = FFI.sizeof("struct umash_params") assert size % 8 == 0 for i in range(size // 8): FFI.cast("uint64_t *", params)[i] = random.getrandbits(64) # Pseudorandom input should always succeed. assert C.umash_params_prepare(params) == True assert_idempotent(params) expected0 = umash( UmashKey(params[0].poly[0][1], [params[0].oh[i] for i in range(OH_COUNT)]), seed, data, secondary=False, ) assert C.umash_full(params, seed, 0, data, len(data)) == expected0 expected1 = umash( UmashKey( params[0].poly[1][1], [params[0].oh[i] for i in range(OH_COUNT)], ), seed, data, secondary=True, ) assert C.umash_full(params, seed, 1, data, len(data)) == expected1
def reference_value(self): return umash( UmashKey( poly=self.multipliers[self.which], ph=self.ph[self.which * C.UMASH_PH_TOEPLITZ_SHIFT:], ), self.seed, self.acc, )
def test_public_umash_fprint(seed, multipliers, key, data): """Compare umash_fprint with two calls to the reference.""" expected = [ umash(UmashKey(poly=multipliers[0], oh=key[:-4]), seed, data), umash(UmashKey(poly=multipliers[1], oh=key[4:]), seed, data), ] n_bytes = len(data) block = FFI.new("char[]", n_bytes) FFI.memmove(block, data, n_bytes) params = FFI.new("struct umash_params[1]") for i, multiplier in enumerate(multipliers): params[0].poly[i][0] = (multiplier**2) % FIELD params[0].poly[i][1] = multiplier for i, param in enumerate(key): params[0].oh[i] = param actual = C.umash_fprint(params, seed, block, n_bytes) assert [actual.hash[0], actual.hash[1]] == expected
def reference_value(self): return [ umash( UmashKey( poly=self.multipliers[which], oh=self.oh[which * C.UMASH_OH_TOEPLITZ_SHIFT:], ), self.seed, self.acc, ) for which in range(2) ]
def test_umash_short(seed, key, data): """Compare umash_short with the reference.""" expected = umash(UmashKey(poly=0, oh=key), seed, data) n_bytes = len(data) block = FFI.new("char[]", n_bytes) FFI.memmove(block, data, n_bytes) params = FFI.new("struct umash_params[1]") for i, param in enumerate(key): params[0].oh[i] = param assert C.umash_short(params[0].oh, seed, block, n_bytes) == expected
def test_public_umash_full_shifted(seed, multiplier, key, data): """Compare umash_full(which=1) with the reference.""" expected = umash(UmashKey(poly=multiplier, oh=key), seed, data) n_bytes = len(data) block = FFI.new("char[]", n_bytes) FFI.memmove(block, data, n_bytes) params = FFI.new("struct umash_params[1]") params[0].poly[1][0] = (multiplier**2) % FIELD params[0].poly[1][1] = multiplier for i, param in enumerate(key): params[0].oh[i + C.UMASH_OH_TOEPLITZ_SHIFT] = param assert C.umash_full(params, seed, 1, block, n_bytes) == expected
def test_public_umash_full(seed, multiplier, key, data): """Compare umash_full with the reference.""" expected = umash(UmashKey(poly=multiplier, ph=key), seed, data) n_bytes = len(data) block = FFI.new("char[]", n_bytes) FFI.memmove(block, data, n_bytes) params = FFI.new("struct umash_params[1]") params[0].poly[0][0] = (multiplier ** 2) % FIELD params[0].poly[0][1] = multiplier for i, param in enumerate(key): params[0].ph[i] = param assert C.umash_full(params, seed, 0, block, n_bytes) == expected
def test_umash_medium(seed, multiplier, key, data): """Compare umash_medium with the reference.""" expected = umash(UmashKey(poly=multiplier, ph=key), seed, data) n_bytes = len(data) block = FFI.new("char[]", n_bytes) FFI.memmove(block, data, n_bytes) poly = FFI.new("uint64_t[2]") poly[0] = (multiplier**2) % FIELD poly[1] = multiplier params = FFI.new("struct umash_params[1]") for i, param in enumerate(key): params[0].ph[i] = param assert C.umash_medium(poly, params[0].ph, seed, block, n_bytes) == expected
def test_umash_long_repeat(seed, multiplier, key, data): """Compare umash_long on repeated strings with the reference.""" expected = umash(UmashKey(poly=multiplier, oh=key), seed, data, secondary=False) note(len(data)) n_bytes = len(data) block = FFI.new("char[]", n_bytes) FFI.memmove(block, data, n_bytes) poly = FFI.new("uint64_t[2]") poly[0] = (multiplier ** 2) % FIELD poly[1] = multiplier params = FFI.new("struct umash_params[1]") for i, param in enumerate(key): params[0].oh[i] = param assert C.umash_long(poly, params[0].oh, seed, block, n_bytes) == expected