From 3a276ef23cd42261c0e01f376e8a198636d2720b Mon Sep 17 00:00:00 2001 From: Karthik Inbasekar <61501745+krakhit@users.noreply.github.com> Date: Wed, 5 Jun 2024 18:25:12 +0300 Subject: [PATCH] added example cpp: example_commit_with_device_memory_view() (#532) ## Describe the changes This PR... Added an example for simple commit that makes use of polynomial views. Output attached ``` Example: a) commit with Polynomial views [(f1+f2)^2 + (f1-f2)^2 ]_1 = [4 (f1^2+ f_2^2)]_1 Example: b) commit with Polynomial views [(f1+f2)^2 - (f1-f2)^2 ]_1 = [4 f1 *f_2]_1 Setup: Generating mock SRS Setup: SRS of length 1025 generated and loaded to device. Took: 19557 milliseconds Setup: Generating polys (on device) f1,f2 of log degree 10 Setup: Gen poly done. Took: 7 milliseconds Computing constraints..start Computing constraints..done. Took: 0 milliseconds Computing Commitments with poly view Commitments done. Took: 29 milliseconds commitment [(f1+f2)^2 + (f1-f2)^2]_1: [x: 0x1e35d81da10e5026dacdd907d6ed0dde673de449ff8c0137ec6acbfd6b1dfe1b, y: 0x21fc051415af35a781f84ebcf999313d489ae38ebefa561c9de2fb0b11091502] commitment [[2 (f_1^2+f_2^2]_1: [x: 0x1e35d81da10e5026dacdd907d6ed0dde673de449ff8c0137ec6acbfd6b1dfe1b, y: 0x21fc051415af35a781f84ebcf999313d489ae38ebefa561c9de2fb0b11091502] commitment [(f1+f2)^2 - (f1-f2)^2]_1: [x: 0x21e9dc012aef8d95107fbfe63f455d4345b9b21e37bcb0a49043b1066e211ffa, y: 0x2d6a3b2f1be1042a17c58ff595134b9cceb71d1af4f1c67a5696859cd4bafae3] commitment [4 f_1*f_2]_1: [x: 0x21e9dc012aef8d95107fbfe63f455d4345b9b21e37bcb0a49043b1066e211ffa, y: 0x2d6a3b2f1be1042a17c58ff595134b9cceb71d1af4f1c67a5696859cd4bafae3] ``` ## Linked Issues Resolves # --- examples/c++/polynomial-api/CMakeLists.txt | 5 +- examples/c++/polynomial-api/example.cu | 123 ++++++++++++++++++++- 2 files changed, 126 insertions(+), 2 deletions(-) diff --git a/examples/c++/polynomial-api/CMakeLists.txt b/examples/c++/polynomial-api/CMakeLists.txt index 805b6714..616e5188 100644 --- a/examples/c++/polynomial-api/CMakeLists.txt +++ b/examples/c++/polynomial-api/CMakeLists.txt @@ -23,5 +23,8 @@ set_target_properties(example PROPERTIES CUDA_SEPARABLE_COMPILATION ON) target_include_directories(example PRIVATE "../../../icicle/include") # can link to another curve/field by changing the following lib and FIELD_ID -target_link_libraries(example ${CMAKE_SOURCE_DIR}/build/icicle/lib/libingo_field_bn254.a) +target_link_libraries(example +${CMAKE_SOURCE_DIR}/build/icicle/lib/libingo_curve_bn254.a +${CMAKE_SOURCE_DIR}/build/icicle/lib/libingo_field_bn254.a +) target_compile_definitions(example PUBLIC FIELD_ID BN254) \ No newline at end of file diff --git a/examples/c++/polynomial-api/example.cu b/examples/c++/polynomial-api/example.cu index 1199d2e6..d19178b2 100644 --- a/examples/c++/polynomial-api/example.cu +++ b/examples/c++/polynomial-api/example.cu @@ -1,13 +1,16 @@ #include - +#include #include "polynomials/polynomials.h" #include "polynomials/cuda_backend/polynomial_cuda_backend.cuh" #include "ntt/ntt.cuh" #include "poseidon/tree/merkle.cuh" +#include "api/bn254.h" +#include // using namespace field_config; using namespace polynomials; using namespace merkle; +using namespace bn254; // define the polynomial type typedef Polynomial Polynomial_t; @@ -21,6 +24,27 @@ const auto four = scalar_t::from(4); const auto five = scalar_t::from(5); const auto minus_one = zero - one; +static std::unique_ptr generate_pows(scalar_t tau, uint32_t size){ + auto vec = std::make_unique(size); + vec[0] = scalar_t::one(); + for (size_t i = 1; i < size; ++i) { + vec[i] = vec[i-1] * tau; + } + return std::move(vec); +} + +static std::unique_ptr generate_SRS(uint32_t size) { + auto secret_scalar = scalar_t::rand_host(); + auto gen = projective_t::generator(); + auto pows_of_tau = generate_pows(secret_scalar,size); + auto SRS = std::make_unique(size); + for (size_t i = 0; i < size; ++i) { + SRS[i] = projective_t::to_affine(pows_of_tau[i] * gen); + } + return std::move(SRS); +} + + void example_evaluate() { std::cout << std::endl << "Example: Polynomial evaluation on random value" << std::endl; @@ -298,6 +322,102 @@ void example_device_memory_view() ntt::ntt(d_coeffs.get(), size, ntt::NTTDir::kForward, ntt_config, coset_evals.get()); } + +void example_commit_with_device_memory_view() +{ + //declare time vars + std::chrono::time_point start, end; + std::chrono::milliseconds duration; + + std::cout << std::endl << "Example: a) commit with Polynomial views [(f1+f2)^2 + (f1-f2)^2 ]_1 = [4 (f1^2+ f_2^2)]_1" << std::endl; + std::cout<< "Example: b) commit with Polynomial views [(f1+f2)^2 - (f1-f2)^2 ]_1 = [4 f1 *f_2]_1" << std::endl; + int N = 1025; + + //generate group elements string of length N: (1, beta,beta^2....,beta^{N-1}). g + std::cout << "Setup: Generating mock SRS" << std::endl; + start = std::chrono::high_resolution_clock::now(); + auto SRS = generate_SRS(2*N); + //Allocate memory on device (points) + affine_t* points_d; + cudaMalloc(&points_d, sizeof(affine_t)* 2 * N); + // copy SRS to device (could have generated on device, but gives an indicator) + cudaMemcpy(points_d, SRS.get(), sizeof(affine_t)* 2 * N, cudaMemcpyHostToDevice); + end = std::chrono::high_resolution_clock::now(); + duration = std::chrono::duration_cast(end - start); + std::cout << "Setup: SRS of length "<< N << " generated and loaded to device. Took: " << duration.count() << " milliseconds" << std::endl; + + //goal: + //test commitment equality [(f1+f2)^2 + (f1-f2)^2 ]_1 = [4 (f1^2+ f_2^2)]_1 + //test commitment equality [(f1+f2)^2 - (f1-f2)^2 ]_1 = [4 f1 *f_2]_1 + //note: using polyapi to gen scalars: already on device. + std::cout << "Setup: Generating polys (on device) f1,f2 of log degree " << log2(N-1) << std::endl; + start = std::chrono::high_resolution_clock::now(); + auto f1 = randomize_polynomial(N); + auto f2 = randomize_polynomial(N); + end = std::chrono::high_resolution_clock::now(); + duration = std::chrono::duration_cast(end - start); + std::cout << "Setup: Gen poly done. Took: " << duration.count() << " milliseconds" << std::endl; + + //deg 2N constraints (f1+f2)^2 + (f1-f2)^2 = 2 (f1^2+ f_2^2) + std::cout << "Computing constraints..start "<< std::endl; + start = std::chrono::high_resolution_clock::now(); + auto L1 = (f1+f2)*(f1+f2) + (f1-f2)*(f1-f2); + auto R1 = scalar_t::from(2) * (f1*f1 + f2*f2); + //deg 2N constraints (f1+f2)^2 - (f1-f2)^2 = 4 f1 *f_2 + auto L2 = (f1+f2)*(f1+f2) - (f1-f2)*(f1-f2); + auto R2 = scalar_t::from(4) * f1 * f2; + end = std::chrono::high_resolution_clock::now(); + duration = std::chrono::duration_cast(end - start); + std::cout << "Computing constraints..done. Took: " << duration.count() << " milliseconds"<< std::endl; + + // extract coeff using coeff view + auto [viewL1, sizeL1, device_idL1] = L1.get_coefficients_view(); + auto [viewL2, sizeL2, device_idL2] = L2.get_coefficients_view(); + auto [viewR1, sizeR1, device_idR1] = R1.get_coefficients_view(); + auto [viewR2, sizeR2, device_idR2] = R2.get_coefficients_view(); + + std::cout << "Computing Commitments with poly view"<< std::endl; + start = std::chrono::high_resolution_clock::now(); + msm::MSMConfig config = msm::default_msm_config(); + config.are_points_on_device = true; + config.are_scalars_on_device = true; + + //host vars (for result) + projective_t hL1{}, hL2{}, hR1{}, hR2{}; + + //straightforward msm bn254 api: no batching + bn254_msm_cuda(viewL1.get(),points_d,N,config,&hL1); + bn254_msm_cuda(viewL2.get(),points_d,N,config,&hL2); + bn254_msm_cuda(viewR1.get(),points_d,N,config,&hR1); + bn254_msm_cuda(viewR2.get(),points_d,N,config,&hR2); + + end = std::chrono::high_resolution_clock::now(); + duration = std::chrono::duration_cast(end - start); + std::cout << "Commitments done. Took: " << duration.count() << " milliseconds"<< std::endl; + + //sanity checks + auto affL1 = projective_t::to_affine(hL1); + auto affR1 = projective_t::to_affine(hR1); + + auto affL2 = projective_t::to_affine(hL2); + auto affR2 = projective_t::to_affine(hR2); + + //test commitment equality [(f1+f2)^2 + (f1-f2)^2]_1 = [4 (f_1^2+f_2^2]_1 + assert(affL1.x==affR1.x && affL1.y==affR1.y); + std::cout << "commitment [(f1+f2)^2 + (f1-f2)^2]_1:" << std::endl; + std::cout << "[x: " << affL1.x << ", y: " << affL1.y << "]" << std::endl; + std::cout << "commitment [[2 (f_1^2+f_2^2]_1:" <