From 0f4965c775280ef25b3ca88f06261c4b32cd093d Mon Sep 17 00:00:00 2001 From: Florin Chirica Date: Thu, 17 Jun 2021 00:43:29 +0300 Subject: [PATCH 01/17] Checkpoint compress y and pybinds. --- src/python_bindings/fastvdf.cpp | 23 ++++++++++++++ src/verifier.h | 55 +++++++++++++++++++++++++++++---- 2 files changed, 72 insertions(+), 6 deletions(-) diff --git a/src/python_bindings/fastvdf.cpp b/src/python_bindings/fastvdf.cpp index 583f194c..7655a4d2 100644 --- a/src/python_bindings/fastvdf.cpp +++ b/src/python_bindings/fastvdf.cpp @@ -46,6 +46,29 @@ PYBIND11_MODULE(chiavdf, m) { return CheckProofOfTimeNWesolowski(integer(discriminant), (const uint8_t *)x_s.data(), proof_blob_ptr, proof_blob_size, num_iterations, disc_size_bits, recursion); }); + // Checks an N wesolowski proof, given y is given by 'GetB()' instead of a form. + m.def("verify_n_wesolowski_y_compressed", [] (const string& discriminant, + const string& B, + const string& x_s, + const string& proof_blob, + const uint64_t num_iterations, const uint64_t disc_size_bits, 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(); + return CheckProofOfTimeNWesolowskiYCompressed(integer(discriminant), integer(B), (const uint8_t *)x_s.data(), proof_blob_ptr, proof_blob_size, num_iterations, disc_size_bits, recursion); + }); + + m.def("compress_y_from_n_wesolowski", [] (const string& discriminant, + const string& x_s, + const string& proof_blob, + const uint64_t num_iterations, const uint64_t disc_size_bits, 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), integer(B), (const uint8_t *)x_s.data(), proof_blob_ptr, proof_blob_size, num_iterations, disc_size_bits, recursion); + return B.to_string(); + }); + m.def("prove", [] (const py::bytes& challenge_hash, const string& x_s, int discriminant_size_bits, uint64_t num_iterations) { std::string challenge_hash_str(challenge_hash); std::vector challenge_hash_bytes(challenge_hash_str.begin(), challenge_hash_str.end()); diff --git a/src/verifier.h b/src/verifier.h index 293ea706..e074b612 100644 --- a/src/verifier.h +++ b/src/verifier.h @@ -41,15 +41,10 @@ void VerifyWesolowskiProof(integer &D, form x, form y, form proof, uint64_t iter } } -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) -{ +bool CheckProofOfTimeNWesolowskiCommon(integer& D, form& x, const uint8_t* proof_blob, int32_t proof_blob_len, uint64_t& iterations, int 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); - - if (proof_blob_len != 2 * form_size + depth * segment_len) - return false; // Loop depth times bool is_valid = false; @@ -64,7 +59,20 @@ bool CheckProofOfTimeNWesolowski(integer D, const uint8_t* x_s, const uint8_t* p x = xnew; 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, uint64 disc_size_bits, int32_t depth) { + form x = DeserializeForm(D, x_s, form_size); + int form_size = BQFC_FORM_SIZE; + int segment_len = 8 + B_bytes + 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, depth); + if (is_valid == false) { + return false; + } VerifyWesolowskiProof(D, x, DeserializeForm(D, proof_blob, form_size), DeserializeForm(D, &proof_blob[form_size], form_size), @@ -73,4 +81,39 @@ bool CheckProofOfTimeNWesolowski(integer D, const uint8_t* x_s, const uint8_t* p return is_valid; } +bool CheckProofOfTimeNWesolowskiYCompressed(integer D, integer B, 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) { + form x = DeserializeForm(D, x_s, form_size); + int form_size = BQFC_FORM_SIZE; + int segment_len = 8 + B_bytes + form_size; + if (proof_blob_len != form_size + depth * segment_len) { + return false; + } + bool is_valid = CheckProofOfTimeNWesolowskiCommon(D, x, proof_blob, proof_blob_len, iterations, depth); + if (is_valid == false) { + return false; + } + proof = DeserializeForm(D, proof_blob, form_size); + form tmp; + if (VerifyWesoSegment(D, x, proof, B, iterations, tmp) == -1) { + return false; + } + return true; +} + +// 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, uint64 disc_size_bits, int32_t depth) { + form x = DeserializeForm(D, x_s, form_size); + int form_size = BQFC_FORM_SIZE; + int segment_len = 8 + B_bytes + 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, depth); + 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 From 20874b7fe3333022e320f1bd3887d5f46f0600b2 Mon Sep 17 00:00:00 2001 From: Florin Chirica Date: Mon, 21 Jun 2021 16:02:39 +0300 Subject: [PATCH 02/17] Compile errors. --- src/verifier.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/verifier.h b/src/verifier.h index e074b612..9954f6c0 100644 --- a/src/verifier.h +++ b/src/verifier.h @@ -63,9 +63,9 @@ bool CheckProofOfTimeNWesolowskiCommon(integer& D, form& x, const uint8_t* proof } 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) { - form x = DeserializeForm(D, x_s, form_size); 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; } @@ -82,9 +82,9 @@ bool CheckProofOfTimeNWesolowski(integer D, const uint8_t* x_s, const uint8_t* p } bool CheckProofOfTimeNWesolowskiYCompressed(integer D, integer B, 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) { - form x = DeserializeForm(D, x_s, form_size); 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 != form_size + depth * segment_len) { return false; } @@ -92,7 +92,7 @@ bool CheckProofOfTimeNWesolowskiYCompressed(integer D, integer B, const uint8_t* if (is_valid == false) { return false; } - proof = DeserializeForm(D, proof_blob, form_size); + form proof = DeserializeForm(D, proof_blob, form_size); form tmp; if (VerifyWesoSegment(D, x, proof, B, iterations, tmp) == -1) { return false; @@ -102,9 +102,9 @@ bool CheckProofOfTimeNWesolowskiYCompressed(integer D, integer B, const uint8_t* // 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, uint64 disc_size_bits, int32_t depth) { - form x = DeserializeForm(D, x_s, form_size); 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."); } From 4f0f50be44d3add8a97a949743a97a5709d78705 Mon Sep 17 00:00:00 2001 From: Florin Chirica Date: Mon, 21 Jun 2021 16:25:24 +0300 Subject: [PATCH 03/17] Also fix error in pybind. --- src/python_bindings/fastvdf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_bindings/fastvdf.cpp b/src/python_bindings/fastvdf.cpp index 7655a4d2..89ce75e2 100644 --- a/src/python_bindings/fastvdf.cpp +++ b/src/python_bindings/fastvdf.cpp @@ -65,7 +65,7 @@ PYBIND11_MODULE(chiavdf, m) { 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), integer(B), (const uint8_t *)x_s.data(), proof_blob_ptr, proof_blob_size, num_iterations, disc_size_bits, recursion); + integer B = GetBFromProof(integer(discriminant), (const uint8_t *)x_s.data(), proof_blob_ptr, proof_blob_size, num_iterations, disc_size_bits, recursion); return B.to_string(); }); From aff300bb4d9409649d08716876aae6876f7757fd Mon Sep 17 00:00:00 2001 From: Florin Chirica Date: Tue, 22 Jun 2021 16:20:09 +0300 Subject: [PATCH 04/17] Add test, fix bug. --- src/verifier.h | 10 +++--- tests/test_n_weso_verifier.py | 68 +++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 tests/test_n_weso_verifier.py diff --git a/src/verifier.h b/src/verifier.h index 9954f6c0..dea3ce1f 100644 --- a/src/verifier.h +++ b/src/verifier.h @@ -41,14 +41,14 @@ 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 depth) { +bool CheckProofOfTimeNWesolowskiCommon(integer& D, form& x, const uint8_t* proof_blob, int32_t proof_blob_len, uint64_t& iterations, int depth, int last_segment) { int form_size = BQFC_FORM_SIZE; int segment_len = 8 + B_bytes + form_size; int i = proof_blob_len - segment_len; // Loop depth times bool is_valid = false; - for (; i >= 2 * form_size; i -= segment_len) { + for (; i >= last_segment; 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); @@ -69,7 +69,7 @@ bool CheckProofOfTimeNWesolowski(integer D, const uint8_t* x_s, const uint8_t* p if (proof_blob_len != 2 * form_size + depth * segment_len) { return false; } - bool is_valid = CheckProofOfTimeNWesolowskiCommon(D, x, proof_blob, proof_blob_len, iterations, depth); + bool is_valid = CheckProofOfTimeNWesolowskiCommon(D, x, proof_blob, proof_blob_len, iterations, depth, 2 * form_size); if (is_valid == false) { return false; } @@ -88,7 +88,7 @@ bool CheckProofOfTimeNWesolowskiYCompressed(integer D, integer B, const uint8_t* if (proof_blob_len != form_size + depth * segment_len) { return false; } - bool is_valid = CheckProofOfTimeNWesolowskiCommon(D, x, proof_blob, proof_blob_len, iterations, depth); + bool is_valid = CheckProofOfTimeNWesolowskiCommon(D, x, proof_blob, proof_blob_len, iterations, depth, form_size); if (is_valid == false) { return false; } @@ -108,7 +108,7 @@ integer GetBFromProof(integer D, const uint8_t* x_s, const uint8_t* proof_blob, 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, depth); + bool is_valid = CheckProofOfTimeNWesolowskiCommon(D, x, proof_blob, proof_blob_len, iterations, depth, 2 * form_size); if (is_valid == false) { throw std::runtime_error("Invalid proof."); } diff --git a/tests/test_n_weso_verifier.py b/tests/test_n_weso_verifier.py new file mode 100644 index 00000000..4e1310a2 --- /dev/null +++ b/tests/test_n_weso_verifier.py @@ -0,0 +1,68 @@ +import secrets +import time + +from chiavdf import ( + create_discriminant, + prove, + verify_wesolowski, + verify_n_wesolowski, + verify_n_wesolowski_y_compressed, + compress_y_from_n_wesolowski, +) + +def prove_n_weso(discriminant_challenge, x, discriminant_size, form_size, iters, witness): + 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 = compress_y_from_n_wesolowski(discriminant, x, y_result + y_proof, iters, discriminant_size, 0) + assert verify_n_wesolowski_y_compressed(discriminant, b_hex, x, y_proof, iters, discriminant_size, 0) + inner_proof = b"" + for x, y, proof in reversed(partials): + b_hex = compress_y_from_n_wesolowski(discriminant, x, y + proof, iters_chunk, discriminant_size, 0) + b = int(b_hex, 16) + assert verify_wesolowski(discriminant, x, y, proof, iters_chunk) + assert verify_n_wesolowski_y_compressed(discriminant, b_hex, x, proof, iters_chunk, discriminant_size, 0) + inner_proof += iters_chunk.to_bytes(8, byteorder='big') + 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) + is_valid = verify_n_wesolowski( + str(discriminant), + initial_el, + y + proof, + iters, + discriminant_size, + 5, + ) + assert is_valid + b_hex = compress_y_from_n_wesolowski(discriminant, initial_el, y + proof, iters, discriminant_size, 5) + assert verify_n_wesolowski_y_compressed(discriminant, b_hex, initial_el, proof, iters, discriminant_size, 5) + B = str(int(b_hex, 16)) + assert verify_n_wesolowski_y_compressed(discriminant, B, initial_el, proof, iters, discriminant_size, 5) + B_wrong = str(int(b_hex, 16) + 1) + assert not verify_n_wesolowski_y_compressed(discriminant, B_wrong, initial_el, proof, iters, discriminant_size, 5) + initial_el = y + + +test_prove_n_weso_and_verify() From 0c66593ec898f987cceadaa60b1ca645574de255 Mon Sep 17 00:00:00 2001 From: Florin Chirica Date: Tue, 22 Jun 2021 16:22:11 +0300 Subject: [PATCH 05/17] Flake8 test. --- tests/test_n_weso_verifier.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/test_n_weso_verifier.py b/tests/test_n_weso_verifier.py index 4e1310a2..d49d2e1b 100644 --- a/tests/test_n_weso_verifier.py +++ b/tests/test_n_weso_verifier.py @@ -1,5 +1,4 @@ import secrets -import time from chiavdf import ( create_discriminant, @@ -10,6 +9,7 @@ compress_y_from_n_wesolowski, ) + def prove_n_weso(discriminant_challenge, x, discriminant_size, form_size, iters, witness): iters_chunk = iters // (witness + 1) partials = [] @@ -38,6 +38,7 @@ def prove_n_weso(discriminant_challenge, x, discriminant_size, form_size, iters, 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 @@ -61,7 +62,15 @@ def test_prove_n_weso_and_verify(): B = str(int(b_hex, 16)) assert verify_n_wesolowski_y_compressed(discriminant, B, initial_el, proof, iters, discriminant_size, 5) B_wrong = str(int(b_hex, 16) + 1) - assert not verify_n_wesolowski_y_compressed(discriminant, B_wrong, initial_el, proof, iters, discriminant_size, 5) + assert not verify_n_wesolowski_y_compressed( + discriminant, + B_wrong, + initial_el, + proof, + iters, + discriminant_size, + 5, + ) initial_el = y From b1d181128a3c2fcce7924f2736a70f01c2a96392 Mon Sep 17 00:00:00 2001 From: Florin Chirica Date: Wed, 30 Jun 2021 19:01:13 +0300 Subject: [PATCH 06/17] Checkpoint return intermediates. --- src/python_bindings/fastvdf.cpp | 6 +++- src/verifier.h | 17 ++++++----- tests/test_n_weso_verifier.py | 52 +++++++++++++++++++++++++++++---- 3 files changed, 62 insertions(+), 13 deletions(-) diff --git a/src/python_bindings/fastvdf.cpp b/src/python_bindings/fastvdf.cpp index 89ce75e2..b17ce58b 100644 --- a/src/python_bindings/fastvdf.cpp +++ b/src/python_bindings/fastvdf.cpp @@ -55,7 +55,11 @@ PYBIND11_MODULE(chiavdf, m) { 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(); - return CheckProofOfTimeNWesolowskiYCompressed(integer(discriminant), integer(B), (const uint8_t *)x_s.data(), proof_blob_ptr, proof_blob_size, num_iterations, disc_size_bits, recursion); + std::pair> result; + result = CheckProofOfTimeNWesolowskiYCompressed(integer(discriminant), integer(B), (const uint8_t *)x_s.data(), proof_blob_ptr, proof_blob_size, num_iterations, disc_size_bits, 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("compress_y_from_n_wesolowski", [] (const string& discriminant, diff --git a/src/verifier.h b/src/verifier.h index dea3ce1f..7396aff5 100644 --- a/src/verifier.h +++ b/src/verifier.h @@ -81,23 +81,26 @@ bool CheckProofOfTimeNWesolowski(integer D, const uint8_t* x_s, const uint8_t* p return is_valid; } -bool CheckProofOfTimeNWesolowskiYCompressed(integer D, integer B, 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) { +std::pair> CheckProofOfTimeNWesolowskiYCompressed(integer D, integer B, 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; form x = DeserializeForm(D, x_s, form_size); + std::vector result; if (proof_blob_len != form_size + depth * segment_len) { - return false; + return {false, result}; } bool is_valid = CheckProofOfTimeNWesolowskiCommon(D, x, proof_blob, proof_blob_len, iterations, depth, form_size); if (is_valid == false) { - return false; + return {false, result}; } form proof = DeserializeForm(D, proof_blob, form_size); - form tmp; - if (VerifyWesoSegment(D, x, proof, B, iterations, tmp) == -1) { - return false; + form y_result; + if (VerifyWesoSegment(D, x, proof, B, iterations, y_result) == -1) { + return {false, result}; } - return true; + int d_bits = D.num_bits(); + result = SerializeForm(y_result, d_bits); + return {true, result}; } // TODO: Perhaps move? diff --git a/tests/test_n_weso_verifier.py b/tests/test_n_weso_verifier.py index d49d2e1b..7cc44237 100644 --- a/tests/test_n_weso_verifier.py +++ b/tests/test_n_weso_verifier.py @@ -26,13 +26,33 @@ def prove_n_weso(discriminant_challenge, x, discriminant_size, form_size, iters, y_proof = result[form_size : 2 * form_size] assert verify_wesolowski(discriminant, x, y_result, y_proof, iters) b_hex = compress_y_from_n_wesolowski(discriminant, x, y_result + y_proof, iters, discriminant_size, 0) - assert verify_n_wesolowski_y_compressed(discriminant, b_hex, x, y_proof, iters, discriminant_size, 0) + is_valid, y_from_compression = verify_n_wesolowski_y_compressed( + discriminant, + b_hex, + x, + y_proof, + iters, + discriminant_size, + 0, + ) + assert is_valid + assert y_from_compression == y_result inner_proof = b"" for x, y, proof in reversed(partials): b_hex = compress_y_from_n_wesolowski(discriminant, x, y + proof, iters_chunk, discriminant_size, 0) b = int(b_hex, 16) assert verify_wesolowski(discriminant, x, y, proof, iters_chunk) - assert verify_n_wesolowski_y_compressed(discriminant, b_hex, x, proof, iters_chunk, discriminant_size, 0) + is_valid, y_from_compression = verify_n_wesolowski_y_compressed( + discriminant, + b_hex, + x, + proof, + iters_chunk, + discriminant_size, + 0 + ) + assert is_valid + assert y == y_from_compression inner_proof += iters_chunk.to_bytes(8, byteorder='big') inner_proof += b.to_bytes(33, byteorder='big') inner_proof += proof @@ -58,11 +78,31 @@ def test_prove_n_weso_and_verify(): ) assert is_valid b_hex = compress_y_from_n_wesolowski(discriminant, initial_el, y + proof, iters, discriminant_size, 5) - assert verify_n_wesolowski_y_compressed(discriminant, b_hex, initial_el, proof, iters, discriminant_size, 5) + is_valid, y_from_compression = verify_n_wesolowski_y_compressed( + discriminant, + b_hex, + initial_el, + proof, + iters, + discriminant_size, + 5, + ) + assert is_valid + assert y_from_compression == y B = str(int(b_hex, 16)) - assert verify_n_wesolowski_y_compressed(discriminant, B, initial_el, proof, iters, discriminant_size, 5) + is_valid, y_from_compression = verify_n_wesolowski_y_compressed( + discriminant, + B, + initial_el, + proof, + iters, + discriminant_size, + 5, + ) + assert is_valid + assert y_from_compression == y B_wrong = str(int(b_hex, 16) + 1) - assert not verify_n_wesolowski_y_compressed( + is_valid, y_from_compression = verify_n_wesolowski_y_compressed( discriminant, B_wrong, initial_el, @@ -71,6 +111,8 @@ def test_prove_n_weso_and_verify(): discriminant_size, 5, ) + assert not is_valid + assert y_from_compression == b"" initial_el = y From 416a60e92acceb2b15c60464ada4d5bc48187f76 Mon Sep 17 00:00:00 2001 From: Florin Chirica Date: Thu, 8 Jul 2021 20:42:28 +0300 Subject: [PATCH 07/17] Add sanity check. --- src/verifier.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/verifier.h b/src/verifier.h index 7396aff5..8cf294fc 100644 --- a/src/verifier.h +++ b/src/verifier.h @@ -57,6 +57,9 @@ bool CheckProofOfTimeNWesolowskiCommon(integer& D, form& x, const uint8_t* proof return false; x = xnew; + if (segment_iters > iterations) { + return false; + } iterations -= segment_iters; } return true; From e4fc738cb292c07c2d167a63ad7cbcc3a068a026 Mon Sep 17 00:00:00 2001 From: Florin Chirica Date: Wed, 21 Jul 2021 15:10:43 +0300 Subject: [PATCH 08/17] First attempt code review. --- src/python_bindings/fastvdf.cpp | 6 +++--- src/verifier.h | 15 +++++++++------ tests/test_n_weso_verifier.py | 20 ++++++++++---------- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/python_bindings/fastvdf.cpp b/src/python_bindings/fastvdf.cpp index b17ce58b..0089df14 100644 --- a/src/python_bindings/fastvdf.cpp +++ b/src/python_bindings/fastvdf.cpp @@ -47,7 +47,7 @@ PYBIND11_MODULE(chiavdf, m) { }); // Checks an N wesolowski proof, given y is given by 'GetB()' instead of a form. - m.def("verify_n_wesolowski_y_compressed", [] (const string& discriminant, + m.def("verify_n_wesolowski_with_b", [] (const string& discriminant, const string& B, const string& x_s, const string& proof_blob, @@ -56,13 +56,13 @@ PYBIND11_MODULE(chiavdf, m) { uint8_t *proof_blob_ptr = reinterpret_cast(proof_blob_str.data()); int proof_blob_size = proof_blob.size(); std::pair> result; - result = CheckProofOfTimeNWesolowskiYCompressed(integer(discriminant), integer(B), (const uint8_t *)x_s.data(), proof_blob_ptr, proof_blob_size, num_iterations, disc_size_bits, recursion); + result = CheckProofOfTimeNWesolowskiWithB(integer(discriminant), integer(B), (const uint8_t *)x_s.data(), proof_blob_ptr, proof_blob_size, num_iterations, disc_size_bits, 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("compress_y_from_n_wesolowski", [] (const string& discriminant, + 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 disc_size_bits, const uint64_t recursion) { diff --git a/src/verifier.h b/src/verifier.h index 8cf294fc..788b5b72 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, form &out_y) +int VerifyWesoSegment(integer &D, form x, form proof, integer &B, uint64_t iters, bool skip_check, form &out_y) { PulmarkReducer reducer; integer L = root(-D, 4); @@ -19,7 +19,10 @@ 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 true; + } return B == GetB(D, x, out_y) ? 0 : -1; } @@ -41,7 +44,7 @@ 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 depth, int last_segment) { +bool CheckProofOfTimeNWesolowskiCommon(integer& D, form& x, const uint8_t* proof_blob, int32_t proof_blob_len, uint64_t& iterations, int depth, int last_segment, bool skip_check = false) { int form_size = BQFC_FORM_SIZE; int segment_len = 8 + B_bytes + form_size; int i = proof_blob_len - segment_len; @@ -53,7 +56,7 @@ bool CheckProofOfTimeNWesolowskiCommon(integer& D, form& x, const uint8_t* proof 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, xnew)) + if (VerifyWesoSegment(D, x, proof, B, segment_iters, skip_check, xnew)) return false; x = xnew; @@ -84,7 +87,7 @@ bool CheckProofOfTimeNWesolowski(integer D, const uint8_t* x_s, const uint8_t* p return is_valid; } -std::pair> CheckProofOfTimeNWesolowskiYCompressed(integer D, integer B, 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) { +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, uint64 disc_size_bits, 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); @@ -114,7 +117,7 @@ integer GetBFromProof(integer D, const uint8_t* x_s, const uint8_t* proof_blob, 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, depth, 2 * form_size); + bool is_valid = CheckProofOfTimeNWesolowskiCommon(D, x, proof_blob, proof_blob_len, iterations, depth, 2 * form_size, true); if (is_valid == false) { throw std::runtime_error("Invalid proof."); } diff --git a/tests/test_n_weso_verifier.py b/tests/test_n_weso_verifier.py index 7cc44237..ec5ab460 100644 --- a/tests/test_n_weso_verifier.py +++ b/tests/test_n_weso_verifier.py @@ -5,8 +5,8 @@ prove, verify_wesolowski, verify_n_wesolowski, - verify_n_wesolowski_y_compressed, - compress_y_from_n_wesolowski, + verify_n_wesolowski_with_b, + get_b_from_n_wesolowski, ) @@ -25,8 +25,8 @@ def prove_n_weso(discriminant_challenge, x, discriminant_size, form_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 = compress_y_from_n_wesolowski(discriminant, x, y_result + y_proof, iters, discriminant_size, 0) - is_valid, y_from_compression = verify_n_wesolowski_y_compressed( + b_hex = get_b_from_n_wesolowski(discriminant, x, y_result + y_proof, iters, discriminant_size, 0) + is_valid, y_from_compression = verify_n_wesolowski_with_b( discriminant, b_hex, x, @@ -39,10 +39,10 @@ def prove_n_weso(discriminant_challenge, x, discriminant_size, form_size, iters, assert y_from_compression == y_result inner_proof = b"" for x, y, proof in reversed(partials): - b_hex = compress_y_from_n_wesolowski(discriminant, x, y + proof, iters_chunk, discriminant_size, 0) + b_hex = get_b_from_n_wesolowski(discriminant, x, y + proof, iters_chunk, discriminant_size, 0) b = int(b_hex, 16) assert verify_wesolowski(discriminant, x, y, proof, iters_chunk) - is_valid, y_from_compression = verify_n_wesolowski_y_compressed( + is_valid, y_from_compression = verify_n_wesolowski_with_b( discriminant, b_hex, x, @@ -77,8 +77,8 @@ def test_prove_n_weso_and_verify(): 5, ) assert is_valid - b_hex = compress_y_from_n_wesolowski(discriminant, initial_el, y + proof, iters, discriminant_size, 5) - is_valid, y_from_compression = verify_n_wesolowski_y_compressed( + b_hex = get_b_from_n_wesolowski(discriminant, initial_el, y + proof, iters, discriminant_size, 5) + is_valid, y_from_compression = verify_n_wesolowski_with_b( discriminant, b_hex, initial_el, @@ -90,7 +90,7 @@ def test_prove_n_weso_and_verify(): assert is_valid assert y_from_compression == y B = str(int(b_hex, 16)) - is_valid, y_from_compression = verify_n_wesolowski_y_compressed( + is_valid, y_from_compression = verify_n_wesolowski_with_b( discriminant, B, initial_el, @@ -102,7 +102,7 @@ def test_prove_n_weso_and_verify(): assert is_valid assert y_from_compression == y B_wrong = str(int(b_hex, 16) + 1) - is_valid, y_from_compression = verify_n_wesolowski_y_compressed( + is_valid, y_from_compression = verify_n_wesolowski_with_b( discriminant, B_wrong, initial_el, From 3d5f1e936e1622777d9de79080ee7cd44e3bf5a7 Mon Sep 17 00:00:00 2001 From: Florin Chirica Date: Wed, 21 Jul 2021 15:13:01 +0300 Subject: [PATCH 09/17] Typo. --- src/verifier.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/verifier.h b/src/verifier.h index 788b5b72..807604b0 100644 --- a/src/verifier.h +++ b/src/verifier.h @@ -101,7 +101,7 @@ std::pair> CheckProofOfTimeNWesolowskiWithB(integer D } form proof = DeserializeForm(D, proof_blob, form_size); form y_result; - if (VerifyWesoSegment(D, x, proof, B, iterations, y_result) == -1) { + if (VerifyWesoSegment(D, x, proof, B, iterations, /*skip_check=*/false, y_result) == -1) { return {false, result}; } int d_bits = D.num_bits(); From ce0f97a5f89b9127dae07eb24aaf93d3efb62033 Mon Sep 17 00:00:00 2001 From: Florin Chirica Date: Wed, 21 Jul 2021 15:29:40 +0300 Subject: [PATCH 10/17] return 0 not true. --- src/verifier.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/verifier.h b/src/verifier.h index 807604b0..d4b39ee0 100644 --- a/src/verifier.h +++ b/src/verifier.h @@ -21,7 +21,7 @@ int VerifyWesoSegment(integer &D, form x, form proof, integer &B, uint64_t iters out_y = f1 * f2; // Optimize to only get `out_y` without verification, when not needed. if (skip_check) { - return true; + return 0; } return B == GetB(D, x, out_y) ? 0 : -1; } From 67a253e0da46b2079fdb872a40ca7f8531b2d92c Mon Sep 17 00:00:00 2001 From: Florin Chirica Date: Wed, 21 Jul 2021 16:53:25 +0300 Subject: [PATCH 11/17] Add more tests for false proofs. --- tests/test_n_weso_verifier.py | 43 +++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/tests/test_n_weso_verifier.py b/tests/test_n_weso_verifier.py index ec5ab460..c316a0ab 100644 --- a/tests/test_n_weso_verifier.py +++ b/tests/test_n_weso_verifier.py @@ -10,7 +10,7 @@ ) -def prove_n_weso(discriminant_challenge, x, discriminant_size, form_size, iters, witness): +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) @@ -49,11 +49,16 @@ def prove_n_weso(discriminant_challenge, x, discriminant_size, form_size, iters, proof, iters_chunk, discriminant_size, - 0 + 0, ) assert is_valid assert y == y_from_compression - inner_proof += iters_chunk.to_bytes(8, byteorder='big') + if 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 @@ -67,7 +72,7 @@ def test_prove_n_weso_and_verify(): 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) + 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, @@ -77,6 +82,25 @@ def test_prove_n_weso_and_verify(): 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, discriminant_size, 5) is_valid, y_from_compression = verify_n_wesolowski_with_b( discriminant, @@ -113,6 +137,17 @@ def test_prove_n_weso_and_verify(): ) 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, + discriminant_size, + 10, + ) + assert not is_valid + assert y_from_compression == b"" initial_el = y From 60878908a91e2bb39b747618f51f8b9a632c4793 Mon Sep 17 00:00:00 2001 From: Florin Chirica Date: Wed, 21 Jul 2021 16:55:34 +0300 Subject: [PATCH 12/17] Typo... --- tests/test_n_weso_verifier.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_n_weso_verifier.py b/tests/test_n_weso_verifier.py index c316a0ab..094be147 100644 --- a/tests/test_n_weso_verifier.py +++ b/tests/test_n_weso_verifier.py @@ -53,7 +53,7 @@ def prove_n_weso(discriminant_challenge, x, discriminant_size, form_size, iters, ) assert is_valid assert y == y_from_compression - if wrong_segm: + if not wrong_segm: inner_proof += iters_chunk.to_bytes(8, byteorder='big') else: iters_wrong = iters_chunk + 1 From a88ded89a5291260c286133ad5f40b7ba19947f1 Mon Sep 17 00:00:00 2001 From: Florin Chirica Date: Wed, 21 Jul 2021 18:08:08 +0300 Subject: [PATCH 13/17] Try passing test similar to chiapos. --- .github/workflows/test.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 9758a7e3..f68dff84 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -20,6 +20,11 @@ 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 From 27f4db069b36339a8023273c673230c544f0248d Mon Sep 17 00:00:00 2001 From: Florin Chirica Date: Thu, 22 Jul 2021 15:40:31 +0300 Subject: [PATCH 14/17] Remove useless variables. --- src/python_bindings/fastvdf.cpp | 10 +++++----- src/verifier.h | 16 +++++++--------- tests/test_n_weso_verifier.py | 10 ++-------- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/src/python_bindings/fastvdf.cpp b/src/python_bindings/fastvdf.cpp index 0089df14..b8c6a0a5 100644 --- a/src/python_bindings/fastvdf.cpp +++ b/src/python_bindings/fastvdf.cpp @@ -43,7 +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, disc_size_bits, recursion); + 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. @@ -51,12 +51,12 @@ PYBIND11_MODULE(chiavdf, m) { const string& B, const string& x_s, const string& proof_blob, - const uint64_t num_iterations, const uint64_t disc_size_bits, const uint64_t recursion) { + 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, disc_size_bits, recursion); + 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; @@ -65,11 +65,11 @@ PYBIND11_MODULE(chiavdf, m) { 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 disc_size_bits, const uint64_t recursion) { + 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, disc_size_bits, recursion); + integer B = GetBFromProof(integer(discriminant), (const uint8_t *)x_s.data(), proof_blob_ptr, proof_blob_size, num_iterations, recursion); return B.to_string(); }); diff --git a/src/verifier.h b/src/verifier.h index d4b39ee0..d15ad63a 100644 --- a/src/verifier.h +++ b/src/verifier.h @@ -44,13 +44,11 @@ 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 depth, int last_segment, bool skip_check = false) { +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) { int form_size = BQFC_FORM_SIZE; int segment_len = 8 + B_bytes + form_size; int i = proof_blob_len - segment_len; - // Loop depth times - bool is_valid = false; for (; i >= last_segment; i -= segment_len) { uint64_t segment_iters = BytesToInt64(&proof_blob[i]); form proof = DeserializeForm(D, &proof_blob[i + 8 + B_bytes], form_size); @@ -68,14 +66,14 @@ bool CheckProofOfTimeNWesolowskiCommon(integer& D, form& x, const uint8_t* proof return true; } -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) { +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, depth, 2 * form_size); + bool is_valid = CheckProofOfTimeNWesolowskiCommon(D, x, proof_blob, proof_blob_len, iterations, 2 * form_size); if (is_valid == false) { return false; } @@ -87,7 +85,7 @@ 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, uint64 disc_size_bits, int32_t depth) { +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); @@ -95,7 +93,7 @@ std::pair> CheckProofOfTimeNWesolowskiWithB(integer D if (proof_blob_len != form_size + depth * segment_len) { return {false, result}; } - bool is_valid = CheckProofOfTimeNWesolowskiCommon(D, x, proof_blob, proof_blob_len, iterations, depth, form_size); + bool is_valid = CheckProofOfTimeNWesolowskiCommon(D, x, proof_blob, proof_blob_len, iterations, form_size); if (is_valid == false) { return {false, result}; } @@ -110,14 +108,14 @@ std::pair> CheckProofOfTimeNWesolowskiWithB(integer D } // 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, uint64 disc_size_bits, int32_t depth) { +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, depth, 2 * form_size, true); + 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."); } diff --git a/tests/test_n_weso_verifier.py b/tests/test_n_weso_verifier.py index 094be147..2cbc0116 100644 --- a/tests/test_n_weso_verifier.py +++ b/tests/test_n_weso_verifier.py @@ -25,21 +25,20 @@ def prove_n_weso(discriminant_challenge, x, discriminant_size, form_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, discriminant_size, 0) + 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, - discriminant_size, 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, discriminant_size, 0) + 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( @@ -48,7 +47,6 @@ def prove_n_weso(discriminant_challenge, x, discriminant_size, form_size, iters, x, proof, iters_chunk, - discriminant_size, 0, ) assert is_valid @@ -108,7 +106,6 @@ def test_prove_n_weso_and_verify(): initial_el, proof, iters, - discriminant_size, 5, ) assert is_valid @@ -120,7 +117,6 @@ def test_prove_n_weso_and_verify(): initial_el, proof, iters, - discriminant_size, 5, ) assert is_valid @@ -132,7 +128,6 @@ def test_prove_n_weso_and_verify(): initial_el, proof, iters, - discriminant_size, 5, ) assert not is_valid @@ -143,7 +138,6 @@ def test_prove_n_weso_and_verify(): initial_el, proof_wrong, iters, - discriminant_size, 10, ) assert not is_valid From a796eac7ad666782351536d69e3754aa26146acb Mon Sep 17 00:00:00 2001 From: Florin Chirica Date: Thu, 22 Jul 2021 15:58:07 +0300 Subject: [PATCH 15/17] Put back disc_size_bits in n-weso verify. --- src/python_bindings/fastvdf.cpp | 2 +- src/verifier.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/python_bindings/fastvdf.cpp b/src/python_bindings/fastvdf.cpp index b8c6a0a5..0f7f833f 100644 --- a/src/python_bindings/fastvdf.cpp +++ b/src/python_bindings/fastvdf.cpp @@ -43,7 +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); + return CheckProofOfTimeNWesolowski(integer(discriminant), (const uint8_t *)x_s.data(), proof_blob_ptr, proof_blob_size, num_iterations, disc_size_bits, recursion); }); // Checks an N wesolowski proof, given y is given by 'GetB()' instead of a form. diff --git a/src/verifier.h b/src/verifier.h index d15ad63a..329ea977 100644 --- a/src/verifier.h +++ b/src/verifier.h @@ -66,7 +66,7 @@ bool CheckProofOfTimeNWesolowskiCommon(integer& D, form& x, const uint8_t* proof 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) { +bool CheckProofOfTimeNWesolowski(integer D, const uint8_t* x_s, const uint8_t* proof_blob, int32_t proof_blob_len, uint64_t iterations, const uint64_t disc_size_bits, 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); From 102ab409a7edd83fb6e95df690852185b521ca66 Mon Sep 17 00:00:00 2001 From: Florin Chirica Date: Thu, 22 Jul 2021 16:02:40 +0300 Subject: [PATCH 16/17] Try to fix test. --- tests/test_n_weso_verifier.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_n_weso_verifier.py b/tests/test_n_weso_verifier.py index 2cbc0116..0701409b 100644 --- a/tests/test_n_weso_verifier.py +++ b/tests/test_n_weso_verifier.py @@ -99,7 +99,7 @@ def test_prove_n_weso_and_verify(): 10, ) assert not is_valid - b_hex = get_b_from_n_wesolowski(discriminant, initial_el, y + proof, iters, discriminant_size, 5) + 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, From bfe9d6dfe3fab6cdb5af6bde6347d6a828ed8ec9 Mon Sep 17 00:00:00 2001 From: Florin Chirica Date: Thu, 22 Jul 2021 18:57:33 +0300 Subject: [PATCH 17/17] Try to remove size_bits from C++. --- src/2weso_test.cpp | 2 +- src/prover_test.cpp | 2 +- src/python_bindings/fastvdf.cpp | 2 +- src/verifier.h | 2 +- src/verifier_test.cpp | 1 - 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/2weso_test.cpp b/src/2weso_test.cpp index 39019f66..196d28c0 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, 1024, proof.witness_type)) { + if (CheckProofOfTimeNWesolowski(D, DEFAULT_ELEMENT, bytes.data(), bytes.size(), iteration, 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 3f7bdece..16705e9c 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, 1024, proof.witness_type)) { + if (CheckProofOfTimeNWesolowski(D, DEFAULT_ELEMENT, bytes.data(), bytes.size(), iteration, 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 0f7f833f..b8c6a0a5 100644 --- a/src/python_bindings/fastvdf.cpp +++ b/src/python_bindings/fastvdf.cpp @@ -43,7 +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, disc_size_bits, recursion); + 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. diff --git a/src/verifier.h b/src/verifier.h index 329ea977..d15ad63a 100644 --- a/src/verifier.h +++ b/src/verifier.h @@ -66,7 +66,7 @@ bool CheckProofOfTimeNWesolowskiCommon(integer& D, form& x, const uint8_t* proof return true; } -bool CheckProofOfTimeNWesolowski(integer D, const uint8_t* x_s, const uint8_t* proof_blob, int32_t proof_blob_len, uint64_t iterations, const uint64_t disc_size_bits, int32_t depth) { +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); diff --git a/src/verifier_test.cpp b/src/verifier_test.cpp index 93d36792..7c96b656 100644 --- a/src/verifier_test.cpp +++ b/src/verifier_test.cpp @@ -34,7 +34,6 @@ std::copy(result.begin(), result.end(), arr); arr, result.size(), 33554432, - 1024, 2); auto challenge_hash1 = HexToBytes(string("a4bb1461ade74ac602e9ae511af68bb254dfe65d61b7faf9fab82d0b4364a30b").data());