Skip to content
This repository was archived by the owner on Feb 17, 2025. It is now read-only.

Commit ac7d631

Browse files
committed
Reworked proof of work #288
1 parent 93edae7 commit ac7d631

File tree

3 files changed

+33
-31
lines changed

3 files changed

+33
-31
lines changed

libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/proof_of_work.hpp

+18-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//---------------------------------------------------------------------------//
22
// Copyright (c) 2023 Elena Tatuzova <[email protected]>
3+
// Copyright (c) 2024 Vasiliy Olekhov <[email protected]>
34
//
45
// MIT License
56
//
@@ -44,37 +45,38 @@ namespace nil {
4445
using transcript_type = transcript::fiat_shamir_heuristic_sequential<transcript_hash_type>;
4546
using output_type = OutType;
4647

47-
static inline OutType generate(transcript_type &transcript, OutType mask=0xFFFF) {
48+
static inline std::array<std::uint8_t, sizeof(OutType)>
49+
int_be(OutType v) {
50+
std::array<std::uint8_t, sizeof(OutType)> bytes;
51+
for(int i = sizeof(v)-1; i>=0; --i) {
52+
bytes[i] = v & 0xFF;
53+
v >>= 8;
54+
}
55+
return bytes;
56+
}
57+
58+
static inline OutType generate(transcript_type &transcript, std::size_t GrindingBits = 16) {
59+
output_type mask = GrindingBits > 0 ? ( 1ULL << GrindingBits ) - 1 : 0;
4860
output_type proof_of_work = std::rand();
4961
output_type result;
50-
std::vector<std::uint8_t> bytes(4);
5162

5263
while( true ) {
5364
transcript_type tmp_transcript = transcript;
54-
bytes[0] = std::uint8_t((proof_of_work&0xFF000000)>>24);
55-
bytes[1] = std::uint8_t((proof_of_work&0x00FF0000)>>16);
56-
bytes[2] = std::uint8_t((proof_of_work&0x0000FF00)>>8);
57-
bytes[3] = std::uint8_t(proof_of_work&0x000000FF);
58-
59-
tmp_transcript(bytes);
65+
tmp_transcript(int_be(proof_of_work));
6066
result = tmp_transcript.template int_challenge<output_type>();
6167
if ((result & mask) == 0)
6268
break;
6369
proof_of_work++;
6470
}
65-
transcript(bytes);
71+
transcript(int_be(proof_of_work));
6672
result = transcript.template int_challenge<output_type>();
6773
return proof_of_work;
6874
}
6975

70-
static inline bool verify(transcript_type &transcript, output_type proof_of_work, OutType mask=0xFFFF) {
71-
std::vector<std::uint8_t> bytes(4);
72-
bytes[0] = std::uint8_t((proof_of_work&0xFF000000)>>24);
73-
bytes[1] = std::uint8_t((proof_of_work&0x00FF0000)>>16);
74-
bytes[2] = std::uint8_t((proof_of_work&0x0000FF00)>>8);
75-
bytes[3] = std::uint8_t(proof_of_work&0x000000FF);
76-
transcript(bytes);
76+
static inline bool verify(transcript_type &transcript, output_type proof_of_work, std::size_t GrindingBits = 16) {
77+
transcript(int_be(proof_of_work));
7778
output_type result = transcript.template int_challenge<output_type>();
79+
output_type mask = GrindingBits > 0 ? ( 1ULL << GrindingBits ) - 1 : 0;
7880
return ((result & mask) == 0);
7981
}
8082
};

libs/zk/test/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ set(TESTS_NAMES
5656
# "commitment/r1cs_gg_ppzksnark_mpc"
5757
# "commitment/type_traits"
5858
# "commitment/kimchi_pedersen"
59-
# "commitment/proof_of_work"
59+
"commitment/proof_of_work"
6060

6161
"math/expression"
6262

libs/zk/test/commitment/proof_of_work.cpp

+14-14
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,18 @@ BOOST_AUTO_TEST_SUITE(proof_of_knowledge_test_suite)
5151
using poseidon = nil::crypto3::hashes::poseidon<policy>;
5252
using pow_type = nil::crypto3::zk::commitments::field_proof_of_work<poseidon, field_type>;
5353

54-
const integral_type expected_mask = integral_type(0xFF80000000000000) << (field_type::modulus_bits - 64);
54+
std::size_t grinding_bits = 9;
5555
nil::crypto3::zk::transcript::fiat_shamir_heuristic_sequential<poseidon> transcript;
5656
auto old_transcript_1 = transcript, old_transcript_2 = transcript;
5757

58-
auto result = pow_type::generate(transcript, 9);
59-
BOOST_ASSERT(pow_type::verify(old_transcript_1, result, 9));
58+
auto result = pow_type::generate(transcript, grinding_bits);
59+
BOOST_ASSERT(pow_type::verify(old_transcript_1, result, grinding_bits));
6060

6161
// manually reimplement verify to ensure that changes in implementation didn't break it
6262
old_transcript_2(result);
6363
auto chal = old_transcript_2.template challenge<field_type>();
64+
const integral_type expected_mask = integral_type( (1 << grinding_bits) - 1 ) << (field_type::modulus_bits - grinding_bits);
65+
6466
BOOST_ASSERT((integral_type(chal.data) & expected_mask) == 0);
6567

6668
using hard_pow_type = nil::crypto3::zk::commitments::field_proof_of_work<poseidon, field_type>;
@@ -70,28 +72,26 @@ BOOST_AUTO_TEST_SUITE(proof_of_knowledge_test_suite)
7072

7173
BOOST_AUTO_TEST_CASE(pow_basic_test) {
7274
using keccak = nil::crypto3::hashes::keccak_1600<512>;
73-
const std::uint32_t mask = 0xFFFFF000;
75+
76+
const std::uint32_t grinding_bits = 20;
77+
const uint64_t expected_mask = (1 << grinding_bits) - 1;
78+
7479
using pow_type = nil::crypto3::zk::commitments::proof_of_work<keccak, std::uint32_t>;
7580

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

79-
auto result = pow_type::generate(transcript, mask);
80-
BOOST_ASSERT(pow_type::verify(old_transcript_1, result, mask));
84+
auto result = pow_type::generate(transcript, grinding_bits);
85+
BOOST_ASSERT(pow_type::verify(old_transcript_1, result, grinding_bits));
8186

8287
// manually reimplement verify to ensure that changes in implementation didn't break it
83-
std::array<std::uint8_t, 4> bytes;
84-
bytes[0] = std::uint8_t((result & 0xFF000000) >> 24);
85-
bytes[1] = std::uint8_t((result & 0x00FF0000) >> 16);
86-
bytes[2] = std::uint8_t((result & 0x0000FF00) >> 8);
87-
bytes[3] = std::uint8_t(result & 0x000000FF);
88-
old_transcript_2(bytes);
88+
old_transcript_2(pow_type::int_be(result));
8989
auto chal = old_transcript_2.template int_challenge<std::uint32_t>();
90-
BOOST_ASSERT((chal & mask) == 0);
90+
BOOST_ASSERT( (chal & expected_mask) == 0);
9191

9292
// check that random stuff doesn't pass verify
9393
using hard_pow_type = nil::crypto3::zk::commitments::proof_of_work<keccak, std::uint32_t>;
94-
BOOST_ASSERT(!hard_pow_type::verify(old_transcript_1, result, mask));
94+
BOOST_ASSERT(!hard_pow_type::verify(old_transcript_1, result, grinding_bits));
9595
}
9696

9797
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)