Пример #1
0
def test_encoded():
    for case in VECTORS["encode"]:
        input_len = case["input_len"]
        input_bytes = generate_input.input_bytes(input_len)
        output_len = case["output_len"]
        expected_bao_hash = case["bao_hash"]
        encoded_blake2b = case["encoded_blake2b"]
        corruptions = case["corruptions"]

        # First make sure the encoded output is what it's supposed to be.
        encoded = bao_encode(input_bytes)
        assert output_len == len(encoded)
        assert encoded_blake2b == blake2b(encoded)

        # Test hashing the encoded bytes.
        encoded_hash = bao_hash_encoded(encoded)
        assert expected_bao_hash == encoded_hash

        # Now test decoding.
        output = bao_decode(expected_bao_hash, encoded)
        assert input_bytes == output

        # Make sure decoding with the wrong hash fails.
        wrong_hash = "0" * len(encoded_hash)
        assert_decode_failure(bao_decode, wrong_hash, encoded)

        # Make sure each of the corruption points causes decoding to fail.
        for c in corruptions:
            corrupted = bytearray(encoded)
            corrupted[c] ^= 1
            assert_decode_failure(bao_decode, encoded_hash, corrupted)
Пример #2
0
def slices():
    ret = []
    for case in seeks():
        size = case["input_len"]
        offsets = case["seek_offsets"]
        b = input_bytes(size)
        encoded = bao.bao_encode(b)
        slices = []
        for offset in offsets:
            slice_bytes = io.BytesIO()
            slice_len = 2 * CHUNK_SIZE
            bao.bao_slice(io.BytesIO(encoded), slice_bytes, offset, slice_len)
            slice_hash = blake2b_hash(slice_bytes.getbuffer())
            fields = [
                ("start", offset),
                ("len", slice_len),
                ("output_len", len(slice_bytes.getbuffer())),
                ("output_blake2b", slice_hash),
                ("corruptions",
                 slice_corruption_points(size, offset, slice_len)),
            ]
            slices.append(OrderedDict(fields))
        fields = [
            ("input_len", size),
            ("bao_hash", bao.bao_hash(io.BytesIO(b)).hex()),
            ("slices", slices),
        ]
        ret.append(OrderedDict(fields))
    return ret
Пример #3
0
def test_hashes():
    for case in VECTORS["hash"]:
        input_len = case["input_len"]
        input_bytes = generate_input.input_bytes(input_len)
        expected_hash = case["bao_hash"]

        computed_hash = bao_hash(input_bytes)
        assert expected_hash == computed_hash
Пример #4
0
def hashes():
    ret = []
    for size in SIZES:
        b = input_bytes(size)
        h = bao.bao_hash(io.BytesIO(b))
        fields = [("input_len", size), ("bao_hash", h.hex())]
        ret.append(OrderedDict(fields))
    return ret
Пример #5
0
def encoded():
    ret = []
    for size in SIZES:
        b = input_bytes(size)
        encoded = bao.bao_encode(b)
        fields = [
            ("input_len", size),
            ("output_len", len(encoded)),
            ("bao_hash", bao.bao_hash(io.BytesIO(b)).hex()),
            ("encoded_blake2b", blake2b_hash(encoded)),
            ("corruptions", encode_corruption_points(size)),
        ]
        ret.append(OrderedDict(fields))
    return ret
Пример #6
0
def test_slices():
    for case in VECTORS["slice"]:
        input_len = case["input_len"]
        input_bytes = generate_input.input_bytes(input_len)
        expected_bao_hash = case["bao_hash"]
        slices = case["slices"]

        encoded, hash_ = bao_encode(input_bytes)
        outboard, hash_outboard = bao_encode_outboard(input_bytes)
        assert expected_bao_hash == hash_
        assert expected_bao_hash == hash_outboard

        for slice_case in slices:
            slice_start = slice_case["start"]
            slice_len = slice_case["len"]
            output_len = slice_case["output_len"]
            output_blake3 = slice_case["output_blake3"]
            corruptions = slice_case["corruptions"]

            # Make sure the slice output is what it should be.
            slice_bytes = bao_slice(encoded, slice_start, slice_len)
            assert output_len == len(slice_bytes)
            assert output_blake3 == blake3(slice_bytes)

            # Make sure slicing an outboard tree is the same.
            outboard_slice_bytes = bao_slice_outboard(input_bytes, outboard,
                                                      slice_start, slice_len)
            assert slice_bytes == outboard_slice_bytes

            # Test decoding the slice, and compare it to the input. Note that
            # slicing a byte array in Python allows indices past the end of the
            # array, and sort of silently caps them.
            input_slice = input_bytes[slice_start:][:slice_len]
            output = bao_decode_slice(slice_bytes, hash_, slice_start,
                                      slice_len)
            assert input_slice == output

            # Make sure decoding with the wrong hash fails.
            wrong_hash = "0" * len(hash_)
            assert_decode_failure(bao_decode_slice, slice_bytes, wrong_hash,
                                  slice_start, slice_len)

            # Make sure each of the slice corruption points causes decoding to
            # fail.
            for c in corruptions:
                corrupted = bytearray(slice_bytes)
                corrupted[c] ^= 1
                assert_decode_failure(bao_decode_slice, corrupted, hash_,
                                      slice_start, slice_len)
Пример #7
0
def test_outboard():
    for case in VECTORS["outboard"]:
        input_len = case["input_len"]
        input_bytes = generate_input.input_bytes(input_len)
        output_len = case["output_len"]
        expected_bao_hash = case["bao_hash"]
        encoded_blake2b = case["encoded_blake2b"]
        outboard_corruptions = case["outboard_corruptions"]
        input_corruptions = case["input_corruptions"]

        # First make sure the encoded output is what it's supposed to be.
        outboard = bao_encode_outboard(input_bytes)
        assert output_len == len(outboard)
        assert encoded_blake2b == blake2b(outboard)

        # Test `bao hash --outboard`.
        bao_hash_encoded = bao_hash_outboard(input_bytes, outboard)
        assert expected_bao_hash == bao_hash_encoded

        # Now test decoding.
        output = bao_decode_outboard(expected_bao_hash, input_bytes, outboard)
        assert input_bytes == output

        # Make sure decoding with the wrong hash fails.
        wrong_hash = "0" * len(expected_bao_hash)
        assert_decode_failure(bao_decode_outboard, wrong_hash, input_bytes,
                              outboard)

        # Make sure each of the outboard corruption points causes decoding to
        # fail.
        for c in outboard_corruptions:
            corrupted = bytearray(outboard)
            corrupted[c] ^= 1
            assert_decode_failure(bao_decode_outboard, expected_bao_hash,
                                  input_bytes, corrupted)

        # Make sure each of the input corruption points causes decoding to
        # fail.
        for c in input_corruptions:
            corrupted = bytearray(input_bytes)
            corrupted[c] ^= 1
            assert_decode_failure(bao_decode_outboard, expected_bao_hash,
                                  corrupted, outboard)
Пример #8
0
def outboard():
    ret = []
    for size in SIZES:
        b = input_bytes(size)
        encoded = bao.bao_encode(b, outboard=True)
        input_corruptions = []
        corruption = 0
        while corruption < size:
            input_corruptions.append(corruption)
            corruption += CHUNK_SIZE
        fields = [
            ("input_len", size),
            ("output_len", len(encoded)),
            ("bao_hash", bao.bao_hash(io.BytesIO(b)).hex()),
            ("encoded_blake2b", blake2b_hash(encoded)),
            ("outboard_corruptions",
             encode_corruption_points(size, outboard=True)),
            ("input_corruptions", input_corruptions),
        ]
        ret.append(OrderedDict(fields))
    return ret
Пример #9
0
    cmd = " ".join(["bao.py"] + list(args))
    if should_fail:
        assert output.returncode != 0, "`{}` should've failed".format(cmd)
    else:
        assert output.returncode == 0, "`{}` failed".format(cmd)
    return output.stdout


def test_hash_cli():
    # CLI tests just use the final (largest) test vector in each set, to avoid
    # shelling out hundreds of times. There's no need to exhaustively test the
    # implementation via the CLI, because it's tested on its own above.
    # Instead, we just need to verify once that it's hooked up properly.
    case = VECTORS["hash"][-1]
    input_len = case["input_len"]
    input_bytes = generate_input.input_bytes(input_len)
    expected_hash = case["bao_hash"]

    computed_hash = bao_cli("hash", input=input_bytes).decode().strip()
    assert expected_hash == computed_hash


def blake2b(b):
    return hashlib.blake2b(b, digest_size=16).hexdigest()


def assert_decode_failure(f, *args):
    try:
        f(*args)
    except AssertionError:
        pass