Skip to content

Commit

Permalink
Changed interface for proof_of_work #11
Browse files Browse the repository at this point in the history
Added parallel implementation for proof_of_work for non-poseidon trascript, #11

Update for grinding, synchronizing with crypto3 #11

Renamed int_be to to_byte_array #11
  • Loading branch information
vo-nil committed Jul 18, 2024
1 parent c0e5955 commit bec804d
Show file tree
Hide file tree
Showing 14 changed files with 124 additions and 160 deletions.
20 changes: 20 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@ project(parallel-crypto3)
list(APPEND CMAKE_MODULE_PATH
"${CMAKE_CURRENT_LIST_DIR}/cmake/modules/share/modules/cmake")

# This is useful due to some build systems (Ninja in particular) are piping
# compiler output and compiler switches it's output to plain text
option (FORCE_COLORED_OUTPUT "Always produce ANSI-colored output (GNU/Clang only)." FALSE)
if (${FORCE_COLORED_OUTPUT})
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
add_compile_options (-fdiagnostics-color=always)
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_compile_options (-fcolor-diagnostics)
endif ()
endif ()

# The file compile_commands.json is generated in build directory, so LSP could
# pick it up and guess all include paths, defines and other stuff.
# If Nix is used, LSP could not guess the locations of implicit include
# directories, so we need to include them explicitly.
if(CMAKE_EXPORT_COMPILE_COMMANDS)
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES
${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
endif()

# TODO: check what is actually required here
include(CMConfig)
include(CMDeploy)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,7 @@ namespace nil {
}

void eval_polys() {
for(auto it = _polys.begin(); it != _polys.end(); ++it) {
std::size_t k = it->first;
const auto& poly = it->second;

for(auto const &[k, poly] : _polys) {
_z.set_batch_size(k, poly.size());
auto const &point = _points.at(k);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ namespace nil {
std::size_t lambda,
std::size_t expand_factor,
bool use_grinding = false,
std::size_t grinding_parameter = 0xFFFF
std::size_t grinding_parameter = 16
): lambda(lambda)
, use_grinding(use_grinding)
, grinding_parameter(grinding_parameter)
Expand All @@ -174,7 +174,7 @@ namespace nil {
std::size_t lambda,
std::size_t expand_factor,
bool use_grinding = false,
std::size_t grinding_parameter = 0xFFFF
std::size_t grinding_parameter = 16
): lambda(lambda)
, use_grinding(use_grinding)
, grinding_parameter(grinding_parameter)
Expand All @@ -192,7 +192,7 @@ namespace nil {
std::size_t expand_factor,
std::size_t lambda,
bool use_grinding = false,
std::size_t grinding_parameter = 0xFFFF
std::size_t grinding_parameter = 16
) : lambda(lambda)
, use_grinding(use_grinding)
, grinding_parameter(grinding_parameter)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//---------------------------------------------------------------------------//
// Copyright (c) 2023 Elena Tatuzova <e.tatuzova@nil.foundation>
// Copyright (c) 2024 Vasiliy Olekhov <vasiliy.olekhov@nil.foundation>
//
// MIT License
//
Expand Down Expand Up @@ -47,37 +48,66 @@ namespace nil {
using transcript_type = transcript::fiat_shamir_heuristic_sequential<transcript_hash_type>;
using output_type = OutType;

static inline OutType generate(transcript_type &transcript, OutType mask=0xFFFF) {
output_type proof_of_work = std::rand();
output_type result;
std::vector<std::uint8_t> bytes(4);
static inline std::array<std::uint8_t, sizeof(OutType)>
to_byte_array(OutType v) {
std::array<std::uint8_t, sizeof(OutType)> bytes;
for(int i = sizeof(v)-1; i>=0; --i) {
bytes[i] = v & 0xFF;
v >>= 8;
}
return bytes;
}

static inline OutType generate(transcript_type &transcript, std::size_t grinding_bits = 16) {
BOOST_ASSERT_MSG(grinding_bits < 64, "Grinding parameter should be bits, not mask");
output_type mask = grinding_bits > 0 ? ( 1ULL << grinding_bits ) - 1 : 0;
output_type pow_seed = std::rand();

/* Enough work for ~ two minutes on 48 cores, keccak<512> */
std::size_t per_block = 1 << 30;

std::atomic<bool> challenge_found = false;
std::atomic<std::size_t> pow_value_offset;

while( true ) {
transcript_type tmp_transcript = transcript;
bytes[0] = std::uint8_t((proof_of_work&0xFF000000)>>24);
bytes[1] = std::uint8_t((proof_of_work&0x00FF0000)>>16);
bytes[2] = std::uint8_t((proof_of_work&0x0000FF00)>>8);
bytes[3] = std::uint8_t(proof_of_work&0x000000FF);

tmp_transcript(bytes);
result = tmp_transcript.template int_challenge<output_type>();
if ((result & mask) == 0)
wait_for_all(parallel_run_in_chunks<void>(
per_block,
[&transcript, &pow_seed, &challenge_found, &pow_value_offset, &mask](std::size_t pow_start, std::size_t pow_finish) {
std::size_t i = pow_start;
while ( i < pow_finish ) {
if (challenge_found) {
break;
}
transcript_type tmp_transcript = transcript;
tmp_transcript(to_byte_array(pow_seed + i));
OutType pow_result = tmp_transcript.template int_challenge<OutType>();
if ( ((pow_result & mask) == 0) && !challenge_found ) {
bool expected = false;
if (challenge_found.compare_exchange_strong(expected, true)) {
pow_value_offset = i;
}
break;
}
++i;
}
}, ThreadPool::PoolLevel::LOW));

if (challenge_found) {
break;
proof_of_work++;
}
pow_seed += per_block;
}
transcript(bytes);
result = transcript.template int_challenge<output_type>();
return proof_of_work;

transcript(to_byte_array(pow_seed + (std::size_t)pow_value_offset));
transcript.template int_challenge<OutType>();
return pow_seed + (std::size_t)pow_value_offset;
}

static inline bool verify(transcript_type &transcript, output_type proof_of_work, OutType mask=0xFFFF) {
std::vector<std::uint8_t> bytes(4);
bytes[0] = std::uint8_t((proof_of_work&0xFF000000)>>24);
bytes[1] = std::uint8_t((proof_of_work&0x00FF0000)>>16);
bytes[2] = std::uint8_t((proof_of_work&0x0000FF00)>>8);
bytes[3] = std::uint8_t(proof_of_work&0x000000FF);
transcript(bytes);
static inline bool verify(transcript_type &transcript, output_type proof_of_work, std::size_t grinding_bits = 16) {
BOOST_ASSERT_MSG(grinding_bits < 64, "Grinding parameter should be bits, not mask");
transcript(to_byte_array(proof_of_work));
output_type result = transcript.template int_challenge<output_type>();
output_type mask = grinding_bits > 0 ? ( 1ULL << grinding_bits ) - 1 : 0;
return ((result & mask) == 0);
}
};
Expand All @@ -104,8 +134,8 @@ namespace nil {
((integral_type(1) << GrindingBits) - 1) << (FieldType::modulus_bits - GrindingBits)
: 0);

/* Enough work for ~ two minutes on 48 cores */
std::size_t per_block = 1<<23;
/* Enough work for ~ two minutes on 48 cores, poseidon<pallas> */
std::size_t per_block = 1 << 23;

std::atomic<bool> challenge_found = false;
std::atomic<std::size_t> pow_value_offset;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,43 +352,18 @@ namespace nil {
/* The procedure of updating the transcript is subject to review and change
* #295 */

nil::marshalling::status_type status;

for (const auto &commit: public_key.commits) {
std::vector<uint8_t> byteblob =
nil::marshalling::pack<nil::marshalling::option::big_endian>(commit, status);
BOOST_ASSERT(status == nil::marshalling::status_type::success);
transcript(
::nil::crypto3::hashes::conditional_block_to_field_elements_wrapper<
typename CommitmentSchemeType::transcript_hash_type::word_type,
decltype(byteblob)
>(byteblob)
);

for (const auto &commit : public_key.commits) {
transcript(commit);
}
for (const auto &S: public_key.S) {
for (const auto &s: S) {
std::vector<uint8_t> byteblob =
nil::marshalling::pack<nil::marshalling::option::big_endian>(s, status);
BOOST_ASSERT(status == nil::marshalling::status_type::success);
transcript(
::nil::crypto3::hashes::conditional_block_to_field_elements_wrapper<
typename CommitmentSchemeType::transcript_hash_type::word_type,
decltype(byteblob)
>(byteblob)
);
for (const auto &S : public_key.S) {
for (const auto &s : S) {
transcript(s);
}
}
for (const auto &r: public_key.r) {
for (std::size_t i = 0; i < r.size(); ++i) {
std::vector<uint8_t> byteblob =
nil::marshalling::pack<nil::marshalling::option::big_endian>(r[i], status);
BOOST_ASSERT(status == nil::marshalling::status_type::success);
transcript(
::nil::crypto3::hashes::conditional_block_to_field_elements_wrapper<
typename CommitmentSchemeType::transcript_hash_type::word_type,
decltype(byteblob)
>(byteblob)
);
transcript(r[i]);
}
}
}
Expand Down Expand Up @@ -730,41 +705,21 @@ namespace nil {
* #295 */

// Push commitments to transcript
transcript(::nil::crypto3::hashes::conditional_block_to_field_elements_wrapper<
typename CommitmentSchemeType::transcript_hash_type::word_type,
decltype(_commitments[batch_ind])
>(_commitments[batch_ind]));

transcript(_commitments[batch_ind]);

// Push evaluation points to transcript
for (std::size_t i = 0; i < this->_z.get_batch_size(batch_ind); i++) {
for (std::size_t j = 0; j < this->_z.get_poly_points_number(batch_ind, i); j++) {
nil::marshalling::status_type status;
std::vector<uint8_t> byteblob =
nil::marshalling::pack<endianness>(this->_z.get(batch_ind, i, j), status);
BOOST_ASSERT(status == nil::marshalling::status_type::success);
transcript(
::nil::crypto3::hashes::conditional_block_to_field_elements_wrapper<
typename CommitmentSchemeType::transcript_hash_type::word_type,
decltype(byteblob)
>(byteblob)
);
for(std::size_t i = 0; i < this->_z.get_batch_size(batch_ind); i++) {
for(std::size_t j = 0; j < this->_z.get_poly_points_number(batch_ind, i); j++) {
transcript(this->_z.get(batch_ind, i, j));
}
}

// Push U polynomials to transcript
for (std::size_t i = 0; i < this->_points[batch_ind].size(); i++) {
auto poly = this->get_U(batch_ind, i);
for (std::size_t j = 0; j < poly.size(); ++j) {
nil::marshalling::status_type status;
std::vector<uint8_t> byteblob =
nil::marshalling::pack<endianness>(poly[j], status);
BOOST_ASSERT(status == nil::marshalling::status_type::success);
transcript(
::nil::crypto3::hashes::conditional_block_to_field_elements_wrapper<
typename CommitmentSchemeType::transcript_hash_type::word_type,
decltype(byteblob)
>(byteblob)
);
transcript(poly[j]);
}
}
}
Expand Down
Loading

0 comments on commit bec804d

Please sign in to comment.