From 6823a8c9c972d71d7a81acc5ff469e5573f70ecd Mon Sep 17 00:00:00 2001 From: wjblanke Date: Wed, 26 Jan 2022 10:52:33 -0800 Subject: [PATCH] Revert "Compress y. (#87)" This reverts commit 0cd64249119b9c1d68e18a0fcfb76a4dcc01678d. --- .github/workflows/test.yaml | 5 -- src/2weso_test.cpp | 2 +- src/prover_test.cpp | 2 +- src/python_bindings/fastvdf.cpp | 29 +------ src/verifier.h | 74 +++------------- src/verifier_test.cpp | 1 + tests/test_n_weso_verifier.py | 148 -------------------------------- 7 files changed, 16 insertions(+), 245 deletions(-) delete mode 100644 tests/test_n_weso_verifier.py diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index f68dff84..9758a7e3 100755 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -20,11 +20,6 @@ jobs: if: startsWith(matrix.os, 'ubuntu') run: | sudo apt-get install libgmp-dev libboost-python-dev libpython3.8-dev libboost-system-dev build-essential -y - sudo fallocate -l 16G /swapfile - sudo chmod 600 /swapfile - sudo mkswap /swapfile - sudo swapon /swapfile - swapon -s cd src make ${{ matrix.config }} -f Makefile.vdf-client diff --git a/src/2weso_test.cpp b/src/2weso_test.cpp index 196d28c0..39019f66 100644 --- a/src/2weso_test.cpp +++ b/src/2weso_test.cpp @@ -15,7 +15,7 @@ void CheckProof(integer& D, Proof& proof, uint64_t iteration) { std::vector bytes; bytes.insert(bytes.end(), proof.y.begin(), proof.y.end()); bytes.insert(bytes.end(), proof.proof.begin(), proof.proof.end()); - if (CheckProofOfTimeNWesolowski(D, DEFAULT_ELEMENT, bytes.data(), bytes.size(), iteration, proof.witness_type)) { + if (CheckProofOfTimeNWesolowski(D, DEFAULT_ELEMENT, bytes.data(), bytes.size(), iteration, 1024, proof.witness_type)) { std::cout << "Correct proof\n"; } else { std::cout << "Incorrect proof\n"; diff --git a/src/prover_test.cpp b/src/prover_test.cpp index 16705e9c..3f7bdece 100644 --- a/src/prover_test.cpp +++ b/src/prover_test.cpp @@ -14,7 +14,7 @@ Proof CreateProof(integer D, ProverManager& pm, uint64_t iteration) { std::vector bytes; bytes.insert(bytes.end(), proof.y.begin(), proof.y.end()); bytes.insert(bytes.end(), proof.proof.begin(), proof.proof.end()); - if (CheckProofOfTimeNWesolowski(D, DEFAULT_ELEMENT, bytes.data(), bytes.size(), iteration, proof.witness_type)) { + if (CheckProofOfTimeNWesolowski(D, DEFAULT_ELEMENT, bytes.data(), bytes.size(), iteration, 1024, proof.witness_type)) { std::cout << "Correct proof"; } else { std::cout << "Incorrect proof\n"; diff --git a/src/python_bindings/fastvdf.cpp b/src/python_bindings/fastvdf.cpp index b8c6a0a5..583f194c 100644 --- a/src/python_bindings/fastvdf.cpp +++ b/src/python_bindings/fastvdf.cpp @@ -43,34 +43,7 @@ PYBIND11_MODULE(chiavdf, m) { uint8_t *proof_blob_ptr = reinterpret_cast(proof_blob_str.data()); int proof_blob_size = proof_blob.size(); - return CheckProofOfTimeNWesolowski(integer(discriminant), (const uint8_t *)x_s.data(), proof_blob_ptr, proof_blob_size, num_iterations, recursion); - }); - - // Checks an N wesolowski proof, given y is given by 'GetB()' instead of a form. - m.def("verify_n_wesolowski_with_b", [] (const string& discriminant, - const string& B, - const string& x_s, - const string& proof_blob, - const uint64_t num_iterations, const uint64_t recursion) { - std::string proof_blob_str(proof_blob); - uint8_t *proof_blob_ptr = reinterpret_cast(proof_blob_str.data()); - int proof_blob_size = proof_blob.size(); - std::pair> result; - result = CheckProofOfTimeNWesolowskiWithB(integer(discriminant), integer(B), (const uint8_t *)x_s.data(), proof_blob_ptr, proof_blob_size, num_iterations, recursion); - py::bytes res_bytes = py::bytes(reinterpret_cast(result.second.data()), result.second.size()); - py::tuple res_tuple = py::make_tuple(result.first, res_bytes); - return res_tuple; - }); - - m.def("get_b_from_n_wesolowski", [] (const string& discriminant, - const string& x_s, - const string& proof_blob, - const uint64_t num_iterations, const uint64_t recursion) { - std::string proof_blob_str(proof_blob); - uint8_t *proof_blob_ptr = reinterpret_cast(proof_blob_str.data()); - int proof_blob_size = proof_blob.size(); - integer B = GetBFromProof(integer(discriminant), (const uint8_t *)x_s.data(), proof_blob_ptr, proof_blob_size, num_iterations, recursion); - return B.to_string(); + return CheckProofOfTimeNWesolowski(integer(discriminant), (const uint8_t *)x_s.data(), proof_blob_ptr, proof_blob_size, num_iterations, disc_size_bits, recursion); }); m.def("prove", [] (const py::bytes& challenge_hash, const string& x_s, int discriminant_size_bits, uint64_t num_iterations) { diff --git a/src/verifier.h b/src/verifier.h index d15ad63a..293ea706 100644 --- a/src/verifier.h +++ b/src/verifier.h @@ -11,7 +11,7 @@ const uint8_t DEFAULT_ELEMENT[] = { 0x08 }; -int VerifyWesoSegment(integer &D, form x, form proof, integer &B, uint64_t iters, bool skip_check, form &out_y) +int VerifyWesoSegment(integer &D, form x, form proof, integer &B, uint64_t iters, form &out_y) { PulmarkReducer reducer; integer L = root(-D, 4); @@ -19,10 +19,7 @@ int VerifyWesoSegment(integer &D, form x, form proof, integer &B, uint64_t iters form f1 = FastPowFormNucomp(proof, D, B, L, reducer); form f2 = FastPowFormNucomp(x, D, r, L, reducer); out_y = f1 * f2; - // Optimize to only get `out_y` without verification, when not needed. - if (skip_check) { - return 0; - } + return B == GetB(D, x, out_y) ? 0 : -1; } @@ -44,39 +41,30 @@ void VerifyWesolowskiProof(integer &D, form x, form y, form proof, uint64_t iter } } -bool CheckProofOfTimeNWesolowskiCommon(integer& D, form& x, const uint8_t* proof_blob, int32_t proof_blob_len, uint64_t& iterations, int last_segment, bool skip_check = false) { +bool CheckProofOfTimeNWesolowski(integer D, const uint8_t* x_s, const uint8_t* proof_blob, int32_t proof_blob_len, uint64_t iterations, uint64 disc_size_bits, int32_t depth) +{ int form_size = BQFC_FORM_SIZE; int segment_len = 8 + B_bytes + form_size; int i = proof_blob_len - segment_len; + form x = DeserializeForm(D, x_s, form_size); - for (; i >= last_segment; i -= segment_len) { + if (proof_blob_len != 2 * form_size + depth * segment_len) + return false; + + // Loop depth times + bool is_valid = false; + for (; i >= 2 * form_size; i -= segment_len) { uint64_t segment_iters = BytesToInt64(&proof_blob[i]); form proof = DeserializeForm(D, &proof_blob[i + 8 + B_bytes], form_size); integer B(&proof_blob[i + 8], B_bytes); form xnew; - if (VerifyWesoSegment(D, x, proof, B, segment_iters, skip_check, xnew)) + if (VerifyWesoSegment(D, x, proof, B, segment_iters, xnew)) return false; x = xnew; - if (segment_iters > iterations) { - return false; - } iterations -= segment_iters; } - return true; -} -bool CheckProofOfTimeNWesolowski(integer D, const uint8_t* x_s, const uint8_t* proof_blob, int32_t proof_blob_len, uint64_t iterations, int32_t depth) { - int form_size = BQFC_FORM_SIZE; - int segment_len = 8 + B_bytes + form_size; - form x = DeserializeForm(D, x_s, form_size); - if (proof_blob_len != 2 * form_size + depth * segment_len) { - return false; - } - bool is_valid = CheckProofOfTimeNWesolowskiCommon(D, x, proof_blob, proof_blob_len, iterations, 2 * form_size); - if (is_valid == false) { - return false; - } VerifyWesolowskiProof(D, x, DeserializeForm(D, proof_blob, form_size), DeserializeForm(D, &proof_blob[form_size], form_size), @@ -85,42 +73,4 @@ bool CheckProofOfTimeNWesolowski(integer D, const uint8_t* x_s, const uint8_t* p return is_valid; } -std::pair> CheckProofOfTimeNWesolowskiWithB(integer D, integer B, const uint8_t* x_s, const uint8_t* proof_blob, int32_t proof_blob_len, uint64_t iterations, int32_t depth) { - int form_size = BQFC_FORM_SIZE; - int segment_len = 8 + B_bytes + form_size; - form x = DeserializeForm(D, x_s, form_size); - std::vector result; - if (proof_blob_len != form_size + depth * segment_len) { - return {false, result}; - } - bool is_valid = CheckProofOfTimeNWesolowskiCommon(D, x, proof_blob, proof_blob_len, iterations, form_size); - if (is_valid == false) { - return {false, result}; - } - form proof = DeserializeForm(D, proof_blob, form_size); - form y_result; - if (VerifyWesoSegment(D, x, proof, B, iterations, /*skip_check=*/false, y_result) == -1) { - return {false, result}; - } - int d_bits = D.num_bits(); - result = SerializeForm(y_result, d_bits); - return {true, result}; -} - -// TODO: Perhaps move? -integer GetBFromProof(integer D, const uint8_t* x_s, const uint8_t* proof_blob, int32_t proof_blob_len, uint64_t iterations, int32_t depth) { - int form_size = BQFC_FORM_SIZE; - int segment_len = 8 + B_bytes + form_size; - form x = DeserializeForm(D, x_s, form_size); - if (proof_blob_len != 2 * form_size + depth * segment_len) { - throw std::runtime_error("Invalid proof."); - } - bool is_valid = CheckProofOfTimeNWesolowskiCommon(D, x, proof_blob, proof_blob_len, iterations, 2 * form_size, true); - if (is_valid == false) { - throw std::runtime_error("Invalid proof."); - } - form y = DeserializeForm(D, proof_blob, form_size); - return GetB(D, x, y); -} - #endif // VERIFIER_H diff --git a/src/verifier_test.cpp b/src/verifier_test.cpp index 7c96b656..93d36792 100644 --- a/src/verifier_test.cpp +++ b/src/verifier_test.cpp @@ -34,6 +34,7 @@ std::copy(result.begin(), result.end(), arr); arr, result.size(), 33554432, + 1024, 2); auto challenge_hash1 = HexToBytes(string("a4bb1461ade74ac602e9ae511af68bb254dfe65d61b7faf9fab82d0b4364a30b").data()); diff --git a/tests/test_n_weso_verifier.py b/tests/test_n_weso_verifier.py deleted file mode 100644 index 0701409b..00000000 --- a/tests/test_n_weso_verifier.py +++ /dev/null @@ -1,148 +0,0 @@ -import secrets - -from chiavdf import ( - create_discriminant, - prove, - verify_wesolowski, - verify_n_wesolowski, - verify_n_wesolowski_with_b, - get_b_from_n_wesolowski, -) - - -def prove_n_weso(discriminant_challenge, x, discriminant_size, form_size, iters, witness, wrong_segm): - iters_chunk = iters // (witness + 1) - partials = [] - discriminant = create_discriminant(discriminant_challenge, discriminant_size) - for _ in range(witness): - result = prove(discriminant_challenge, x, discriminant_size, iters_chunk) - y = result[:form_size] - proof = result[form_size : 2 * form_size] - partials.append((x, y, proof)) - x = y - iters -= iters_chunk * witness - result = prove(discriminant_challenge, x, discriminant_size, iters) - y_result = result[:form_size] - y_proof = result[form_size : 2 * form_size] - assert verify_wesolowski(discriminant, x, y_result, y_proof, iters) - b_hex = get_b_from_n_wesolowski(discriminant, x, y_result + y_proof, iters, 0) - is_valid, y_from_compression = verify_n_wesolowski_with_b( - discriminant, - b_hex, - x, - y_proof, - iters, - 0, - ) - assert is_valid - assert y_from_compression == y_result - inner_proof = b"" - for x, y, proof in reversed(partials): - b_hex = get_b_from_n_wesolowski(discriminant, x, y + proof, iters_chunk, 0) - b = int(b_hex, 16) - assert verify_wesolowski(discriminant, x, y, proof, iters_chunk) - is_valid, y_from_compression = verify_n_wesolowski_with_b( - discriminant, - b_hex, - x, - proof, - iters_chunk, - 0, - ) - assert is_valid - assert y == y_from_compression - if not wrong_segm: - inner_proof += iters_chunk.to_bytes(8, byteorder='big') - else: - iters_wrong = iters_chunk + 1 - inner_proof += iters_wrong.to_bytes(8, byteorder='big') - wrong_segm = False - inner_proof += b.to_bytes(33, byteorder='big') - inner_proof += proof - return y_result, y_proof + inner_proof - - -def test_prove_n_weso_and_verify(): - discriminant_challenge = secrets.token_bytes(10) - discriminant_size = 512 - discriminant = create_discriminant(discriminant_challenge, discriminant_size) - form_size = 100 - initial_el = b"\x08" + (b"\x00" * 99) - - for iters in [1000000, 5000000, 10000000]: - y, proof = prove_n_weso(discriminant_challenge, initial_el, discriminant_size, form_size, iters, 5, False) - is_valid = verify_n_wesolowski( - str(discriminant), - initial_el, - y + proof, - iters, - discriminant_size, - 5, - ) - assert is_valid - is_valid = verify_n_wesolowski( - str(discriminant), - initial_el, - y + proof, - iters + 1, - discriminant_size, - 5, - ) - assert not is_valid - y, proof_wrong = prove_n_weso(discriminant_challenge, initial_el, discriminant_size, form_size, iters, 10, True) - is_valid = verify_n_wesolowski( - str(discriminant), - initial_el, - y + proof_wrong, - iters, - discriminant_size, - 10, - ) - assert not is_valid - b_hex = get_b_from_n_wesolowski(discriminant, initial_el, y + proof, iters, 5) - is_valid, y_from_compression = verify_n_wesolowski_with_b( - discriminant, - b_hex, - initial_el, - proof, - iters, - 5, - ) - assert is_valid - assert y_from_compression == y - B = str(int(b_hex, 16)) - is_valid, y_from_compression = verify_n_wesolowski_with_b( - discriminant, - B, - initial_el, - proof, - iters, - 5, - ) - assert is_valid - assert y_from_compression == y - B_wrong = str(int(b_hex, 16) + 1) - is_valid, y_from_compression = verify_n_wesolowski_with_b( - discriminant, - B_wrong, - initial_el, - proof, - iters, - 5, - ) - assert not is_valid - assert y_from_compression == b"" - is_valid, y_from_compression = verify_n_wesolowski_with_b( - discriminant, - B, - initial_el, - proof_wrong, - iters, - 10, - ) - assert not is_valid - assert y_from_compression == b"" - initial_el = y - - -test_prove_n_weso_and_verify()