Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Danny poseidon2 mont #691

Open
wants to merge 4 commits into
base: hadar/switch-to-mont
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ jobs:
- name: Run C++ curve Tests
working-directory: ./icicle/build/tests
if: needs.check-changed-files.outputs.cpp == 'true'
run: ctest
run: ctest --output-on-failure

test-linux-field:
name: Test on Linux
Expand Down Expand Up @@ -107,4 +107,4 @@ jobs:
- name: Run C++ field Tests
working-directory: ./icicle/build/tests
if: needs.check-changed-files.outputs.cpp == 'true'
run: ctest --output-on-failure
run: ctest --output-on-failure
35 changes: 33 additions & 2 deletions icicle/backend/cpu/src/field/cpu_vec_ops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
#include <sys/types.h>
#include <vector>

#include "icicle/program/program.h"
#include "cpu_program_executor.h"

using namespace field_config;
using namespace icicle;

Expand All @@ -32,7 +35,7 @@ enum VecOperation {
REPLACE_ELEMENTS,
OUT_OF_PLACE_MATRIX_TRANSPOSE,

NOF_OPERATIONS
NOF_VECTOR_OPERATIONS
};

/**
Expand Down Expand Up @@ -329,7 +332,7 @@ class VectorOpTask : public TaskBase

// An array of available function pointers arranged according to the VecOperation enum
using FunctionPtr = void (VectorOpTask::*)();
static constexpr std::array<FunctionPtr, static_cast<int>(NOF_OPERATIONS)> functionPtrs = {
static constexpr std::array<FunctionPtr, static_cast<int>(NOF_VECTOR_OPERATIONS)> functionPtrs = {
&VectorOpTask::vector_add, // VECTOR_ADD,
&VectorOpTask::vector_sub, // VECTOR_SUB,
&VectorOpTask::vector_mul, // VECTOR_MUL,
Expand Down Expand Up @@ -838,6 +841,34 @@ eIcicleError cpu_highest_non_zero_idx(

REGISTER_HIGHEST_NON_ZERO_IDX_BACKEND("CPU", cpu_highest_non_zero_idx<scalar_t>);

/*********************************** Execute program ***********************************/
template <typename T>
eIcicleError cpu_execute_program(std::vector<T*>& data, Program<T>& program, uint64_t size, const VecOpsConfig& config)
{
if (data.size() != program.m_nof_parameters) {
ICICLE_LOG_ERROR << "Program has " << program.m_nof_parameters << " while data has " << data.size()
<< " parameters";
return eIcicleError::INVALID_ARGUMENT;
}
const uint64_t total_nof_operations = size * config.batch_size;
CpuProgramExecutor prog_executor(program);
// init prog_executor to point to data vectors
for (int param_idx = 0; param_idx < program.m_nof_parameters; ++param_idx) {
prog_executor.m_variable_ptrs[param_idx] = data[param_idx];
}

// run over all elements in the arrays and execute the program
for (uint64_t i = 0; i < total_nof_operations; i++) {
prog_executor.execute();
for (auto& var_ptr : prog_executor.m_variable_ptrs) {
var_ptr++;
}
}
return eIcicleError::SUCCESS;
}

// REGISTER_EXECUTE_PROGRAM_BACKEND("CPU", cpu_execute_program<scalar_t>);

/*********************************** Polynomial evaluation ***********************************/

template <typename T>
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1,393 changes: 1,088 additions & 305 deletions icicle/include/icicle/hash/poseidon2_constants/constants/babybear_poseidon2.h

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1,403 changes: 1,097 additions & 306 deletions icicle/include/icicle/hash/poseidon2_constants/constants/m31_poseidon2.h

Large diffs are not rendered by default.

1,172 changes: 598 additions & 574 deletions icicle/include/icicle/hash/poseidon2_constants/constants/stark252_poseidon2.h

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
int full_rounds_2 = 12;
int half_full_rounds_2 = 6;
int partial_rounds_2 = 24;
int alpha_2 = 7;

static const std::string rounds_constants_2[] = {
"0x76a8932a",
"0x496e51f7",
"0xbb32543",
"0x3b852d97",
"0x54a11a80",
"0x65ba8e68",
"0x29f09389",
"0x2343a6e6",
"0x4b8a8ec1",
"0x676c3489",
"0x3fa2f7a2",
"0x541ef7dd",
"0x2be3fd0c",
"0x212ef216",
"0x6ab70c3d",
"0x162baeaf",
"0xcd8e8f1",
"0x4a4bd455",
"0x3a34c8f0",
"0x11e9d456",
"0x3c11bf77",
"0x1fed11a4",
"0x27eb37f3",
"0x5d6b800f",
rc_idx = 11",
"0x6dcafcd",
"0x28ae336a",
"0x19fd4b2a",
"0xc47274b",
"0x1ccd65c3",
"0x1470aec",
"0x3733a0c2",
"0x151e4376",
"0x18b43754",
"0x4da62b63",
"0x2ed74076",
"0xe0954d8",
"0x368f93a6",
"0x3dcd4061",
"0xe8024cd",
"0x30886148",
"0x3b8f289a",
"0x68785d3b",
"0x4f5afa7b",
"0x335ab08f",
"0x64c82b68",
"0x6c7fd1b5",
"0x76245680",
"0x39fb5f79",
"0x1ab4ac2f",
"0xb838c9b",
"0x3ca5f68e",
"0x274ef903",
"0x14bd49b1",
"0x31e0c277",
"0x52d03b15",
"0x6faa6ba7",
"0x8cd74b3",
"0x5e9c5053",
"0x1edb152a",
"0x3f164fd4",
"0x3037497a",
"0x3491d3c3",
"0x498a68ec",
"0x98e7f05",
"0x6b11f228",
"0xdcab970",
"0x21214194",
"0x24a953a7",
"0x640be0ba",
"0x6548a9e6",
"0x4bd18241",
"0x1f208622",
rc_idx = 59",
"0x20094634" "0x45d3f963",
"0x126e22d8" "0x457524d",
"0x42d213d1" "0xb98477",
"0x667db627" "0x72ad1b94",
"0x29345ea8" "0x240c67d6",
"0x4e79edfa" "0x44abde5",
"0x22abc20" "0x45b04867",
"0x36a8e6ca" "0xdb23d07",
"0x5f11d45" "0x69a97a62",
"0x311d4622" "0x539c81ff",
"0x346d7598" "0x1813c6d6",
"0x61b18ef3" "0x7cb2342"
};

static const std::string mds_matrix_2[] = {
"0x2" "0xffffffe", "0x1" "0x7ffffff",
"0x1" "0x7ffffff", "0x2" "0xffffffe"
};

static const std::string partial_matrix_diagonal_2[] = {
"0x2" "0xffffffe", "0x3" "0x17fffffd"
};

Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import os
import subprocess
import sys

possible_hash_width = [2, 3, 4, 8, 12, 16, 20, 24]
small_field_max_width = 64

fields = [
# <field_name>, <is_field> <hash_width>, <prime>
["babybear", [2, 3, 4, 8, 12, 16, 20, 24], 0x78000001], # 15 * 2^27 + 1
["m31", [2, 3, 4, 8, 12, 16, 20, 24], 0x7fffffff], # 2^31 - 1
# ["goldilocks", [2, 3, 4, 8, 12, 16, 20, 24], 0xffffffff00000001], # 2^64 - 2^32 + 1
["stark252", [2, 3, 4, 8], 0x800000000000011000000000000000000000000000000000000000000000001], # 2^251 + 17 * 2^192 + 1
["bn254", [2, 3, 4, 8], 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001],
["bls12_377", [2, 3, 4, 8], 0x12ab655e9a2ca55660b44d1e5c37b00159aa76fed00000010a11800000000001],
["bls12_381", [2, 3, 4, 8], 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001],
["grumpkin", [2, 3, 4, 8], 0x30644E72E131A029B85045B68181585D97816A916871CA8D3C208C16D87CFD47],
["bw6_761", [2, 3, 4, 8], 0x1AE3A4617C510EAC63B05C06CA1493B1A22D9F300F5138F1EF3622FBA094800170B5D44300000008508C00000000001]
]

script_dir = os.path.dirname(os.path.abspath(__file__))
constants_files_dir = script_dir + '/../constants'
os.chdir(script_dir) # Run in scripts directory because *.sage.py files are generated there.

for field in fields:
poseidon2_h_file = f"{field[0]}_poseidon2.h"
FILE_cpp = open(poseidon2_h_file, 'w')
FILE_cpp.write(f'#pragma once\n')
FILE_cpp.write(f'#ifndef {field[0].upper()}_POSEIDON2_H\n')
FILE_cpp.write(f'#define {field[0].upper()}_POSEIDON2_H\n\n')
FILE_cpp.write(f'#include <string>\n\n')
FILE_cpp.write(f'namespace poseidon2_constants_{field[0]} {{\n\n')
FILE_cpp.write(f' /**\n')
FILE_cpp.write(f' * This inner namespace contains constants for running Poseidon2.\n')
FILE_cpp.write(f' * The number in the name corresponds to the arity of hash function\n')
FILE_cpp.write(f' */\n\n')
for hash_width in possible_hash_width:
field_width = len(bin(field[2]))-2
gen_constants = True
if field_width > small_field_max_width: # large field
if hash_width > max(field[1]): # generate file with empty var's and arrays.
gen_constants = False
alpha = 0
if not gen_constants: # generate empty file to be concat later
FILE_cpp_tmp = open(f'{field[0]}_poseidon2_{hash_width}_{alpha}.h', 'w') # alpha = 0 just for later concatenation
FILE_cpp_tmp.write(f'int full_rounds_{hash_width} = 0;\n')
FILE_cpp_tmp.write(f'int half_full_rounds_{hash_width} = 0;\n')
FILE_cpp_tmp.write(f'int partial_rounds_{hash_width} = 0;\n')
FILE_cpp_tmp.write(f'int alpha_{hash_width} = 0;\n')
FILE_cpp_tmp.write(f'static const std::string rounds_constants_{hash_width}[] = {{}};\n')
FILE_cpp_tmp.write(f'static const std::string mds_matrix_{hash_width}[] = {{}};\n')
FILE_cpp_tmp.write(f'static const std::string partial_matrix_diagonal_{hash_width}[] = {{}};\n\n')
FILE_cpp_tmp.write(f'static const std::string partial_matrix_diagonal_m1_{hash_width}[] = {{}};\n\n')
FILE_cpp_tmp.close()
else:
gen_constants_cmd = f'sage poseidon2_barrett_params.sage {field[0]} {hash_width} {hex(field[2])}'
print(f'command: {gen_constants_cmd}')
result = subprocess.run([gen_constants_cmd], shell=True, capture_output=True, text=True)
output_lines = result.stdout.strip().split('\n')
for line in output_lines:
print(line)
if line.startswith("RESULT:"):
full_round = int(line.split()[1]) # Not needed in this case.
partial_round = int(line.split()[2]) # Not needed in this case.
alpha = int(line.split()[3])
break
# exit() # For DEBUG - run a single width of a single field

with open(f'{field[0]}_poseidon2_{hash_width}_{alpha}.h', 'r') as f_params:
FILE_cpp.write(f_params.read())
FILE_cpp.write(f'\n')
FILE_cpp.write(f'}} // namespace poseidon2_constants_{field[0]} {{\n')
FILE_cpp.write(f'#endif\n')
FILE_cpp.close()
print(f'rm -rf {constants_files_dir}/{poseidon2_h_file}')
print(f'mv {poseidon2_h_file} {constants_files_dir}')
os.system(f'rm -rf {constants_files_dir}/{poseidon2_h_file}')
os.system(f'mv {poseidon2_h_file} {constants_files_dir}')
os.system(f'rm -rf *.h')
os.system(f'rm -rf *sage.py')
os.system(f'rm -rf *_poseidon_rc_and_mds_matrix_*')
# exit() # For DEBUG - run a single field

exit()

Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
FILE_cpp_tmp.write(f'static const std::string partial_matrix_diagonal_m1_{hash_width}[] = {{}};\n\n')
FILE_cpp_tmp.close()
else:
gen_constants_cmd = f'sage poseidon2_params.sage {field[0]} {hash_width} {hex(field[2])}'
gen_constants_cmd = f'sage poseidon2_mont_params.sage {field[0]} {hash_width} {hex(field[2])}'
print(f'command: {gen_constants_cmd}')
result = subprocess.run([gen_constants_cmd], shell=True, capture_output=True, text=True)
output_lines = result.stdout.strip().split('\n')
Expand Down
Loading