diff --git a/.github/workflows/python-bindings-test.yml b/.github/workflows/python-bindings-test.yml index d4c20bb..d4b3a59 100644 --- a/.github/workflows/python-bindings-test.yml +++ b/.github/workflows/python-bindings-test.yml @@ -21,6 +21,7 @@ jobs: run: | python -m pip install --upgrade pip pip install py_ecc + pip install PyYAML - name: Build BLST run: | cd src diff --git a/bindings/python/README.md b/bindings/python/README.md index 9a625c2..705af1f 100644 --- a/bindings/python/README.md +++ b/bindings/python/README.md @@ -8,6 +8,7 @@ These bindings require `python3` and `py-ecc`. ``` sudo apt install python3 python3-pip python3 -m pip install py-ecc +python3 -m pip install PyYAML ``` ## Build & test diff --git a/bindings/python/tests.py b/bindings/python/tests.py index d82a5e5..cf87f8b 100644 --- a/bindings/python/tests.py +++ b/bindings/python/tests.py @@ -1,6 +1,5 @@ import glob -from os.path import join -from os.path import isfile +import yaml import ckzg @@ -8,108 +7,133 @@ import ckzg # Constants ############################################################################### -blob_to_kzg_commitment_tests = "../../tests/blob_to_kzg_commitment/*" -compute_kzg_proof_tests = "../../tests/compute_kzg_proof/*" -compute_blob_kzg_proof_tests = "../../tests/compute_blob_kzg_proof/*" -verify_kzg_proof_tests = "../../tests/verify_kzg_proof/*" -verify_blob_kzg_proof_tests = "../../tests/verify_blob_kzg_proof/*" -verify_blob_kzg_proof_batch_tests = "../../tests/verify_blob_kzg_proof_batch/*" +BLOB_TO_KZG_COMMITMENT_TESTS = "../../tests/blob_to_kzg_commitment/*/*/data.yaml" +COMPUTE_KZG_PROOF_TESTS = "../../tests/compute_kzg_proof/*/*/data.yaml" +COMPUTE_BLOB_KZG_PROOF_TESTS = "../../tests/compute_blob_kzg_proof/*/*/data.yaml" +VERIFY_KZG_PROOF_TESTS = "../../tests/verify_kzg_proof/*/*/data.yaml" +VERIFY_BLOB_KZG_PROOF_TESTS = "../../tests/verify_blob_kzg_proof/*/*/data.yaml" +VERIFY_BLOB_KZG_PROOF_BATCH_TESTS = "../../tests/verify_blob_kzg_proof_batch/*/*/data.yaml" ############################################################################### # Helper Functions ############################################################################### -def get_blob(path): - with open(path, "r") as f: - return bytes.fromhex(f.read()) - -def get_bytes32(path): - with open(path, "r") as f: - return bytes.fromhex(f.read()) - -def get_bytes48(path): - with open(path, "r") as f: - return bytes.fromhex(f.read()) - -def get_boolean(path): - with open(path, "r") as f: - return "true" in f.read() +def bytes_from_hex(hexstring): + return bytes.fromhex(hexstring.replace("0x", "")) ############################################################################### # Tests ############################################################################### def test_blob_to_kzg_commitment(ts): - for test in glob.glob(blob_to_kzg_commitment_tests): - blob = get_blob(join(test, "blob.txt")) + for test_file in glob.glob(BLOB_TO_KZG_COMMITMENT_TESTS): + with open(test_file, "r") as f: + test = yaml.safe_load(f) + + blob = bytes_from_hex(test["input"]["blob"]) + try: commitment = ckzg.blob_to_kzg_commitment(blob, ts) - expected_commitment = get_bytes48(join(test, "commitment.txt")) - assert commitment == expected_commitment except: - assert not isfile(join(test, "commitment.txt")) + assert test["output"] is None + continue + + expected_commitment = bytes_from_hex(test["output"]) + assert commitment == expected_commitment, f"{test_file}\n{commitment.hex()=}\n{expected_commitment.hex()=}" + def test_compute_kzg_proof(ts): - for test in glob.glob(compute_kzg_proof_tests): - blob = get_blob(join(test, "blob.txt")) - input_point = get_bytes32(join(test, "input_point.txt")) + for test_file in glob.glob(COMPUTE_KZG_PROOF_TESTS): + with open(test_file, "r") as f: + test = yaml.safe_load(f) + + blob = bytes_from_hex(test["input"]["blob"]) + z = bytes_from_hex(test["input"]["z"]) + try: - proof = ckzg.compute_kzg_proof(blob, input_point, ts) - expected_proof = get_bytes48(join(test, "proof.txt")) - assert proof == expected_proof + proof = ckzg.compute_kzg_proof(blob, z, ts) except: - assert not isfile(join(test, "proof.txt")) + assert test["output"] is None + continue + + expected_proof = bytes_from_hex(test["output"]) + assert proof == expected_proof, f"{test_file}\n{proof.hex()=}\n{expected_proof.hex()=}" + def test_compute_blob_kzg_proof(ts): - for test in glob.glob(compute_blob_kzg_proof_tests): - blob = get_blob(join(test, "blob.txt")) + for test_file in glob.glob(COMPUTE_BLOB_KZG_PROOF_TESTS): + with open(test_file, "r") as f: + test = yaml.safe_load(f) + + blob = bytes_from_hex(test["input"]["blob"]) + try: proof = ckzg.compute_blob_kzg_proof(blob, ts) - expected_proof = get_bytes48(join(test, "proof.txt")) - assert proof == expected_proof except: - assert not isfile(join(test, "proof.txt")) + assert test["output"] is None + continue + + expected_proof = bytes_from_hex(test["output"]) + assert proof == expected_proof, f"{test_file}\n{proof.hex()=}\n{expected_proof.hex()=}" + def test_verify_kzg_proof(ts): - for test in glob.glob(verify_kzg_proof_tests): - commitment = get_bytes48(join(test, "commitment.txt")) - input_point = get_bytes32(join(test, "input_point.txt")) - claimed_value = get_bytes32(join(test, "claimed_value.txt")) - proof = get_bytes48(join(test, "proof.txt")) + for test_file in glob.glob(VERIFY_KZG_PROOF_TESTS): + with open(test_file, "r") as f: + test = yaml.safe_load(f) + + commitment = bytes_from_hex(test["input"]["commitment"]) + z = bytes_from_hex(test["input"]["z"]) + y = bytes_from_hex(test["input"]["y"]) + proof = bytes_from_hex(test["input"]["proof"]) + try: - ok = ckzg.verify_kzg_proof(commitment, input_point, claimed_value, proof, ts) - expected_ok = get_boolean(join(test, "ok.txt")) - assert ok == expected_ok + valid = ckzg.verify_kzg_proof(commitment, z, y, proof, ts) except: - assert not isfile(join(test, "ok.txt")) + assert test["output"] is None + continue + + expected_valid = test["output"] + assert valid == expected_valid, f"{test_file}\n{valid=}\n{expected_valid=}" + def test_verify_blob_kzg_proof(ts): - for test in glob.glob(verify_blob_kzg_proof_tests): - blob = get_bytes32(join(test, "blob.txt")) - commitment = get_bytes48(join(test, "commitment.txt")) - proof = get_bytes48(join(test, "proof.txt")) + for test_file in glob.glob(VERIFY_BLOB_KZG_PROOF_TESTS): + with open(test_file, "r") as f: + test = yaml.safe_load(f) + + blob = bytes_from_hex(test["input"]["blob"]) + commitment = bytes_from_hex(test["input"]["commitment"]) + proof = bytes_from_hex(test["input"]["proof"]) + try: - ok = ckzg.verify_blob_kzg_proof(blob, commitment, proof, ts) - expected_ok = get_boolean(join(test, "ok.txt")) - assert ok == expected_ok + valid = ckzg.verify_blob_kzg_proof(blob, commitment, proof, ts) except: - assert not isfile(join(test, "ok.txt")) + assert test["output"] is None + continue + + expected_valid = test["output"] + assert valid == expected_valid, f"{test_file}\n{valid=}\n{expected_valid=}" + def test_verify_blob_kzg_proof_batch(ts): - for test in glob.glob(verify_blob_kzg_proof_batch_tests): - blob_files = sorted(glob.glob(join(test, "blobs/*"))) - blobs = b"".join([get_blob(b) for b in blob_files]) - commitment_files = sorted(glob.glob(join(test, "commitments/*"))) - commitments = b"".join([get_bytes48(c) for c in commitment_files]) - proof_files = sorted(glob.glob(join(test, "proofs/*"))) - proofs = b"".join([get_bytes48(p) for p in proof_files]) + for test_file in glob.glob(VERIFY_BLOB_KZG_PROOF_BATCH_TESTS): + with open(test_file, "r") as f: + test = yaml.safe_load(f) + + blobs = b"".join(map(bytes_from_hex, test["input"]["blobs"])) + commitments = b"".join(map(bytes_from_hex, test["input"]["commitments"])) + proofs = b"".join(map(bytes_from_hex, test["input"]["proofs"])) try: - ok = ckzg.verify_blob_kzg_proof_batch(blobs, commitments, proofs, ts) - expected_ok = get_boolean(join(test, "ok.txt")) - assert ok == expected_ok + valid = ckzg.verify_blob_kzg_proof_batch(blobs, commitments, proofs, ts) except: - assert not isfile(join(test, "ok.txt")) + assert test["output"] is None + continue + + expected_valid = test["output"] + assert valid == expected_valid, f"{test_file}\n{valid=}\n{expected_valid=}" + ############################################################################### # Main Logic @@ -125,4 +149,4 @@ if __name__ == "__main__": test_verify_blob_kzg_proof(ts) test_verify_blob_kzg_proof_batch(ts) - print('tests passed') + print("tests passed")