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
Beispiel #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]
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]