Skip to content

Commit

Permalink
Added top bit field grinding variant.
Browse files Browse the repository at this point in the history
  • Loading branch information
Iluvmagick committed Jan 16, 2024
1 parent 681f264 commit 4a1b9f4
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 1 deletion.
1 change: 1 addition & 0 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ jobs:
crypto3_zk_systems_plonk_plonk_constraint_test
crypto3_zk_commitment_proof_of_knowledge_test
crypto3_zk_transcript_transcript_test
crypto3_zk_commitment_proof_of_work_test
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@

#include <boost/property_tree/ptree.hpp>

#include <cstdint>

#include <nil/crypto3/random/algebraic_engine.hpp>
#include <nil/crypto3/marshalling/algebra/types/field_element.hpp>
#include <nil/crypto3/zk/transcript/fiat_shamir.hpp>

Expand Down Expand Up @@ -83,6 +86,48 @@ namespace nil {
return ((result & mask) == 0);
}
};

template<typename TranscriptHashType, typename FieldType, std::uint64_t MASK=0x1FFFFFFFF0000000>
class field_proof_of_work {
public:
using transcript_hash_type = TranscriptHashType;
using transcript_type = transcript::fiat_shamir_heuristic_sequential<transcript_hash_type>;
using value_type = typename FieldType::value_type;
using integral_type = typename FieldType::integral_type;

constexpr static const integral_type mask = integral_type(MASK) << FieldType::modulus_bits - 64;

static inline boost::property_tree::ptree get_params() {
boost::property_tree::ptree params;
params.put("mask", mask);
return params;
}

static inline value_type generate(transcript_type &transcript) {
static boost::random::random_device dev;
static nil::crypto3::random::algebraic_engine<FieldType> random_engine(dev);
value_type proof_of_work = random_engine();
integral_type result;

while( true ) {
transcript_type tmp_transcript = transcript;
tmp_transcript(proof_of_work);
result = integral_type(tmp_transcript.template challenge<FieldType>().data);
if ((result & mask) == 0)
break;
proof_of_work++;
}
transcript(proof_of_work);
result = integral_type(transcript.template challenge<FieldType>().data);
return proof_of_work;
}

static inline bool verify(transcript_type &transcript, value_type proof_of_work) {
transcript(proof_of_work);
integral_type result = integral_type(transcript.template challenge<FieldType>().data);
return ((result & mask) == 0);
}
};
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@

#include <unordered_map>
#include <iostream>
#include <memory>

#include <nil/crypto3/math/polynomial/polynomial.hpp>
#include <nil/crypto3/math/polynomial/shift.hpp>
#include <nil/crypto3/math/domains/evaluation_domain.hpp>
#include <nil/crypto3/math/algorithms/make_evaluation_domain.hpp>
#include <nil/crypto3/zk/snark/arithmetization/plonk/assignment.hpp>

#include <nil/crypto3/hash/sha2.hpp>

Expand Down
3 changes: 2 additions & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ set(TESTS_NAMES
"commitment/r1cs_gg_ppzksnark_mpc"
"commitment/type_traits"
"commitment/kimchi_pedersen"
"commitment/proof_of_work"

"math/expression"

Expand All @@ -96,7 +97,7 @@ set(TESTS_NAMES
"systems/plonk/pickles/oracles"
"systems/plonk/pickles/to_field"
"systems/plonk/pickles/to_group"

"systems/plonk/placeholder/placeholder"
"systems/plonk/placeholder/performance"

Expand Down
98 changes: 98 additions & 0 deletions test/commitment/proof_of_work.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
//---------------------------------------------------------------------------//
// Copyright (c) 2024 Dmitrii Tabalin <[email protected]>
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//---------------------------------------------------------------------------//

#define BOOST_TEST_MODULE proof_of_work_test

#include <boost/test/unit_test.hpp>

#include <nil/crypto3/algebra/curves/pallas.hpp>
#include <nil/crypto3/algebra/fields/pallas/scalar_field.hpp>
#include <nil/crypto3/algebra/fields/pallas/base_field.hpp>

#include <nil/crypto3/zk/commitments/detail/polynomial/proof_of_work.hpp>

#include <nil/crypto3/hash/poseidon.hpp>
#include <nil/crypto3/hash/detail/poseidon/poseidon_policy.hpp>
#include <nil/crypto3/hash/keccak.hpp>

#include <nil/crypto3/zk/transcript/fiat_shamir.hpp>

using namespace nil::crypto3::algebra;
using namespace nil::crypto3::zk::commitments;

BOOST_AUTO_TEST_SUITE(proof_of_knowledge_test_suite)

BOOST_AUTO_TEST_CASE(pow_poseidon_basic_test) {
using curve_type = curves::pallas;
using field_type = curve_type::base_field_type;
using integral_type = typename field_type::integral_type;
using policy = nil::crypto3::hashes::detail::mina_poseidon_policy<field_type>;
using poseidon = nil::crypto3::hashes::poseidon<policy>;
const std::uint64_t mask = 0x1F;
using pow_type = nil::crypto3::zk::commitments::field_proof_of_work<poseidon, field_type, mask>;

nil::crypto3::zk::transcript::fiat_shamir_heuristic_sequential<poseidon> transcript;
auto old_transcript_1 = transcript, old_transcript_2 = transcript;

auto result = pow_type::generate(transcript);
BOOST_ASSERT(pow_type::verify(old_transcript_1, result));

// manually reimplement verify to ensure that changes in implementation didn't break it
old_transcript_2(result);
auto chal = old_transcript_2.template challenge<field_type>();
integral_type int_mask = integral_type(mask) << (field_type::modulus_bits - 64);
BOOST_ASSERT((integral_type(chal.data) & int_mask) == 0);

using hard_pow_type = nil::crypto3::zk::commitments::field_proof_of_work<poseidon, field_type, 0x1FFFFFFFF>;
// check that random stuff doesn't pass verify
BOOST_ASSERT(!hard_pow_type::verify(old_transcript_1, result));
}

BOOST_AUTO_TEST_CASE(pow_basic_test) {
using keccak = nil::crypto3::hashes::keccak_1600<512>;
const std::uint32_t mask = 0xFFFFF000;
using pow_type = nil::crypto3::zk::commitments::proof_of_work<keccak, std::uint32_t, mask>;

nil::crypto3::zk::transcript::fiat_shamir_heuristic_sequential<keccak> transcript;
auto old_transcript_1 = transcript, old_transcript_2 = transcript;

auto result = pow_type::generate(transcript);
BOOST_ASSERT(pow_type::verify(old_transcript_1, result));

// manually reimplement verify to ensure that changes in implementation didn't break it
std::array<std::uint8_t, 4> bytes;
bytes[0] = std::uint8_t((result & 0xFF000000) >> 24);
bytes[1] = std::uint8_t((result & 0x00FF0000) >> 16);
bytes[2] = std::uint8_t((result & 0x0000FF00) >> 8);
bytes[3] = std::uint8_t(result & 0x000000FF);
old_transcript_2(bytes);
auto chal = old_transcript_2.template int_challenge<std::uint32_t>();
BOOST_ASSERT((chal & mask) == 0);

// check that random stuff doesn't pass verify
using hard_pow_type = nil::crypto3::zk::commitments::proof_of_work<keccak, std::uint32_t, 0xFFFF0000>;
BOOST_ASSERT(!hard_pow_type::verify(old_transcript_1, result));
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit 4a1b9f4

Please sign in to comment.