Exemple #1
0
 def _update(self, buf):
     self.acc += buf
     n = len(buf)
     # Copy to the heap to help ASan
     copy = FFI.new("char[]", n)
     FFI.memmove(copy, buf, n)
     self.update(copy, n)
Exemple #2
0
def test_public_params_derive(bits, key):
    length = FFI.sizeof("struct umash_params")

    umash_key = b"Do not use UMASH VS adversaries."
    if key is not None:
        umash_key = key
    nonce = struct.pack("<Q", bits)

    expected = FFI.new("struct umash_params[1]")
    salsa_bytes = Salsa20.new(umash_key, nonce).encrypt(b"\x00" * length)
    FFI.memmove(expected, salsa_bytes, length)
    assert C.umash_params_prepare(expected)

    actual = FFI.new("struct umash_params[1]")
    if key is None:
        C.umash_params_derive(actual, bits, FFI.NULL)
    else:
        buf = FFI.new("char[]", len(key))
        FFI.memmove(buf, key, len(key))
        C.umash_params_derive(actual, bits, buf)

    # The values should all be the same.
    assert length % 8 == 0
    for i in range(length // 8):
        assert FFI.cast("uint64_t *",
                        actual)[i] == FFI.cast("uint64_t *", expected)[i]
Exemple #3
0
def test_vec_to_u64(data):
    """Make sure we expand to a uint64 correctly."""
    n_bytes = len(data)
    # Copy to a malloc-ed buffer to help ASan.
    buf = FFI.new("char[]", n_bytes)
    FFI.memmove(buf, data, n_bytes)
    assert C.vec_to_u64(buf, n_bytes) == vec_to_u64(data)
Exemple #4
0
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 assert_idempotent(params):
    """Asserts that calling `umash_params_prepare` on something that was
    successfully prepared is idempotent.
    """
    size = FFI.sizeof("struct umash_params")
    copy = FFI.new("struct umash_params[1]")
    FFI.memmove(copy, params, size)
    assert C.umash_params_prepare(copy) == True
    # The copy should still be the same as params.
    assert size % 8 == 0
    for i in range(size // 8):
        assert FFI.cast("uint64_t *",
                        params)[i] == FFI.cast("uint64_t *", copy)[i]
Exemple #6
0
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
Exemple #7
0
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
Exemple #8
0
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
Exemple #9
0
def test_ph_one_block(seed, key, data):
    """Compare PH compression for full blocks."""
    expected = ph_compress_one_block(key, seed, split_block(data))

    # Copy to exactly-sized malloced buffers to help ASan.
    block = FFI.new("char[]", BLOCK_SIZE)
    FFI.memmove(block, data, BLOCK_SIZE)
    params = FFI.new("struct umash_params[1]")
    for i, param in enumerate(key):
        params[0].ph[i] = param

    actual = C.ph_one_block(params[0].ph, seed, block)
    assert expected == actual.bits[0] + (actual.bits[1] << 64), (
        actual.bits[0],
        actual.bits[1],
    )
Exemple #10
0
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
Exemple #11
0
def test_ph_tail_large(seed, key, data):
    """Compare PH compression for the last block, when it has enough data
    to fully contain the last 16-byte chunk."""
    expected = ph_compress_one_block(key, seed, split_block(data))

    n_bytes = len(data)
    # Copy to exactly-sized malloced buffers to help ASan.
    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].ph[i] = param

    actual = C.ph_last_block(params[0].ph, seed, block, n_bytes)
    assert expected == actual.bits[0] + (actual.bits[1] << 64), (
        actual.bits[0],
        actual.bits[1],
    )
Exemple #12
0
def test_oh_one_block(tag, key, data):
    """Compare OH compression for full blocks."""
    # The C-side implicit accepts the high half of the tag, and leaves
    # the low half zeroed out.
    expected = oh_compress_one_block(key, split_block(data), tag << 64)

    # Copy to exactly-sized malloced buffers to help ASan.
    block = FFI.new("char[]", BLOCK_SIZE)
    FFI.memmove(block, data, BLOCK_SIZE)
    params = FFI.new("struct umash_params[1]")
    for i, param in enumerate(key):
        params[0].oh[i] = param

    actual = C.oh_one_block(params[0].oh, tag, block)
    assert expected == actual.bits[0] + (actual.bits[1] << 64), (
        actual.bits[0],
        actual.bits[1],
    )
Exemple #13
0
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
Exemple #14
0
def test_ph_tail_short(seed, key, prefix, data):
    """Compare PH compression for the last block, when we must steal some
    data from the previous chunk."""
    expected = ph_compress_one_block(
        key, seed, split_block(prefix * (C.UMASH_PH_PARAM_COUNT // 2) + data)
    )

    offset = len(prefix)
    n_bytes = len(data)
    # Copy to exactly-sized malloced buffers to help ASan.
    block = FFI.new("char[]", offset + n_bytes)
    FFI.memmove(block, prefix + data, offset + n_bytes)
    params = FFI.new("struct umash_params[1]")
    for i, param in enumerate(key):
        params[0].ph[i] = param

    actual = C.ph_last_block(params[0].ph, seed, block + offset, n_bytes)
    assert expected == actual.bits[0] + (actual.bits[1] << 64), (
        actual.bits[0],
        actual.bits[1],
    )