From 8b3492c921f061b6b32e0df6410b2fcf9fe353b1 Mon Sep 17 00:00:00 2001 From: Leon Hibnik <107353745+LeonHibnik@users.noreply.github.com> Date: Thu, 7 Nov 2024 15:01:38 +0200 Subject: [PATCH 1/8] Update getting_started.md --- docs/docs/icicle/getting_started.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/docs/icicle/getting_started.md b/docs/docs/icicle/getting_started.md index 3ca043aad..72f155e15 100644 --- a/docs/docs/icicle/getting_started.md +++ b/docs/docs/icicle/getting_started.md @@ -141,7 +141,7 @@ pub fn load_backend_from_env_or_default() -> Result<(), eIcicleError>; ``` **Go** ```go -TODO +func LoadBackendFromEnvOrDefault() EIcicleError ``` ### Custom Backend Loading @@ -164,5 +164,7 @@ extern "C" eIcicleError icicle_load_backend(const char* path, bool is_recursive) **Go** ```go -TODO +func LoadBackend(path string, isRecursive bool) EIcicleError ``` +- **`path`**: The directory where the backend libraries are located. +- **`isRecursive`**: If `true`, the function will search for backend libraries recursively within the specified path. From 9bf31080e51b9fcdfd8c7a6d883c98abdd6cb6a6 Mon Sep 17 00:00:00 2001 From: Leon Hibnik Date: Thu, 7 Nov 2024 17:01:18 +0200 Subject: [PATCH 2/8] update colab --- docs/docs/icicle/colab-instructions.md | 60 ++++++++++++++++++-------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/docs/docs/icicle/colab-instructions.md b/docs/docs/icicle/colab-instructions.md index 6cc729910..e81bb3907 100644 --- a/docs/docs/icicle/colab-instructions.md +++ b/docs/docs/icicle/colab-instructions.md @@ -90,19 +90,48 @@ Now we are ready to clone ICICE repository, !git clone https://github.com/ingonyama-zk/icicle.git ``` -We now can browse the repository and run tests to check the runtime environment: +We can browse the repository and run tests to check the runtime environment: ```sh !ls -la -%cd icicle +%cd /content/icicle ``` +## Download CUDA backend + +First let's create a backend directory + +```sh +%cd /content +!rm -rf cuda_backend/ +!mkdir cuda_backend +%cd cuda_backend +``` + +Download and extract a backend from [ICICLE released](https://github.com/ingonyama-zk/icicle/releases) backends +In this example we are using [ICICLE Cuda backend v3.1.0](https://github.com/ingonyama-zk/icicle/releases/download/v3.1.0/icicle_3_1_0-ubuntu22-cuda122.tar.gz) + +```sh +!curl -O -L https://github.com/ingonyama-zk/icicle/releases/download/v3.1.0/icicle_3_1_0-ubuntu22-cuda122.tar.gz +!tar -xvf icicle_3_1_0-ubuntu22-cuda122.tar.gz +``` + +## Setting CUDA backend installation directory +Point colab to the extracted cuda backend using an [environment variable](https://github.com/ingonyama-zk/icicle/blob/f638e9d3056d2a5d6271a67ba4f63973a2ba2c1a/docs/docs/icicle/getting_started.md#backend-loading) + +```sh +import os +os.envvar["ICICLE_BACKEND_INSTALL_DIR"] = "/content/cuda_backend/icicle" +``` + +## Fun with ICICLE + Let's run a test! Navigate to icicle/wrappers/rust/icicle-curves/icicle-bn254 and run cargo test: ```sh -%cd wrappers/rust/icicle-curves/icicle-bn254/ -!cargo test --release +%cd /content/icicle/wrappers/rust/icicle-curves/icicle-bn254/ +!cargo test --release -- ntt ``` :::note @@ -114,25 +143,20 @@ Compiling the first time may take a while Test run should end like this: ```sh -running 15 tests -test curve::tests::test_ark_point_convert ... ok -test curve::tests::test_ark_scalar_convert ... ok -test curve::tests::test_affine_projective_convert ... ok -test curve::tests::test_point_equality ... ok -test curve::tests::test_field_convert_montgomery ... ok -test curve::tests::test_scalar_equality ... ok -test curve::tests::test_points_convert_montgomery ... ok -test msm::tests::test_msm ... ok -test msm::tests::test_msm_skewed_distributions ... ok +running 9 tests +[WARNING] Defaulting to Ingonyama icicle-cuda-license-server at `5053@license.icicle.ingonyama.com`. For more information about icicle-cuda-license, please contact support@ingonyama.com. +[INFO] ICICLE backend loaded from $ICICLE_BACKEND_INSTALL_DIR=/content/cuda_backend/icicle +test ecntt::tests::test_ecntt::test_ecntt_batch ... ok test ntt::tests::test_ntt ... ok test ntt::tests::test_ntt_arbitrary_coset ... ok -test msm::tests::test_msm_batch has been running for over 60 seconds -test msm::tests::test_msm_batch ... ok +test ntt::tests::test_ntt_batch ... ok test ntt::tests::test_ntt_coset_from_subgroup ... ok +test ntt::tests::test_ntt_coset_interpolation_nm ... ok +test ecntt::tests::test_ecntt::test_ecntt ... ok test ntt::tests::test_ntt_device_async ... ok -test ntt::tests::test_ntt_batch ... ok +test ntt::tests::test_ntt_release_domain ... ok -test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 99.39s +test result: ok. 9 passed; 0 failed; 0 ignored; 0 measured; 36 filtered out; finished in 42.71s ``` Viola, ICICLE in Colab! From b4eb31e84c382746f5feeb35b59aa15a6ec28483 Mon Sep 17 00:00:00 2001 From: Leon Hibnik Date: Sun, 10 Nov 2024 10:36:47 +0200 Subject: [PATCH 3/8] Uodate documentation, remove pages from sidebars --- docs/docs/icicle/getting_started.md | 2 +- docs/docs/icicle/multi-device.md | 2 +- docs/docs/icicle/primitives/msm.md | 2 +- docs/docs/icicle/primitives/ntt.md | 2 +- docs/docs/icicle/programmers_guide/go.md | 2 -- docs/sidebars.js | 30 ++++++++++++------------ 6 files changed, 19 insertions(+), 21 deletions(-) diff --git a/docs/docs/icicle/getting_started.md b/docs/docs/icicle/getting_started.md index 72f155e15..a08111092 100644 --- a/docs/docs/icicle/getting_started.md +++ b/docs/docs/icicle/getting_started.md @@ -2,7 +2,7 @@ ## Overview -This guide will walk you through the entire process of building, testing, and installing ICICLE using your preferred programming languageā€”C++, Rust, or Go. Whether you're deploying on a CPU or leveraging CUDA for accelerated performance, this guide provides comprehensive instructions to get you started. It also outlines the typical workflow for a user, including key installation steps: +This guide will walk you through the entire process of building, testing, and installing ICICLE using your preferred programming language: C++, Rust, or Go. Whether you're deploying on a CPU or leveraging CUDA for accelerated performance, this guide provides comprehensive instructions to get you started. It also outlines the typical workflow for a user, including key installation steps: 1. **Install ICICLE or build it from source**: This is explained in this guide. For building from source, refer to the [Build from Source page](./build_from_source.md). diff --git a/docs/docs/icicle/multi-device.md b/docs/docs/icicle/multi-device.md index 3334914b7..afce6318f 100644 --- a/docs/docs/icicle/multi-device.md +++ b/docs/docs/icicle/multi-device.md @@ -76,4 +76,4 @@ extern "C" eIcicleError icicle_get_device_count(int& device_count /*OUT*/); - **Launch One CPU Thread per Device:** To avoid [common errors](https://developer.nvidia.com/blog/cuda-pro-tip-always-set-current-device-avoid-multithreading-bugs/) and ensure code readability, we recommend creating a dedicated thread for each device. Within each CPU thread, you can launch as many tasks as you like for a device, as long as they all run on the same device ID. This will make your code more manageable, easier to read, and performant. --- -This guide provides an overview of multi-device support in ICICLE, explaining the approaches and best practices for efficiently scaling ZK computations across multiple devices. For further information or support, please refer to our [documentation](./) or join the discussion on [Discord](https://discord.gg/6vYrE7waPj). +This guide provides an overview of multi-device support in ICICLE, explaining the approaches and best practices for efficiently scaling ZK computations across multiple devices. For further information or support, please refer to our [documentation](../introduction.md) or join the discussion on [Discord](https://discord.gg/6vYrE7waPj). diff --git a/docs/docs/icicle/primitives/msm.md b/docs/docs/icicle/primitives/msm.md index 32c6a5de7..4328d0fed 100644 --- a/docs/docs/icicle/primitives/msm.md +++ b/docs/docs/icicle/primitives/msm.md @@ -152,7 +152,7 @@ msm(..., config,...); // msm backend is reading the config-extension ### Choosing optimal parameters -`is_big_triangle` should be `false` in almost all cases. It might provide better results only for very small MSMs (smaller than 2^8^) with a large batch (larger than 100) but this should be tested per scenario. +`is_big_triangle` should be `false` in almost all cases. It might provide better results only for very small MSMs (smaller than 2^8) with a large batch (larger than 100) but this should be tested per scenario. Large buckets exist in two cases: 1. When the scalar distribution isn't uniform. 2. When `c` does not divide the scalar bit-size. diff --git a/docs/docs/icicle/primitives/ntt.md b/docs/docs/icicle/primitives/ntt.md index 7d45ef9b1..83afd41a3 100644 --- a/docs/docs/icicle/primitives/ntt.md +++ b/docs/docs/icicle/primitives/ntt.md @@ -169,7 +169,7 @@ To compute a batch, set the `batch_size` and `columns_batch` fields of the confi ### Example -The following example demonstartes how to use ntt and how pass custom configurations to the CUDA backend. This is discussed below. +The following example demonstartes how to use ntt and how pass custom configurations to the CUDA backend. Details are discussed below. ```cpp #include "icicle/backend/ntt_config.h" diff --git a/docs/docs/icicle/programmers_guide/go.md b/docs/docs/icicle/programmers_guide/go.md index d869c98f0..92df226f9 100644 --- a/docs/docs/icicle/programmers_guide/go.md +++ b/docs/docs/icicle/programmers_guide/go.md @@ -292,5 +292,3 @@ if result != runtime.SUCCESS { // Handle error } ``` - -This guide provides an overview of the essential APIs available in Icicle for C++. The provided examples should help you get started with integrating Icicle into your high-performance computing projects. diff --git a/docs/sidebars.js b/docs/sidebars.js index a26023cfa..316d1e761 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -75,11 +75,11 @@ module.exports = { label: "Multi-Device Support", id: "icicle/multi-device", }, - { - type: "doc", - label: "Build Your Own Backend", - id: "icicle/build_your_own_backend" - }, + // { + // type: "doc", + // label: "Build Your Own Backend", + // id: "icicle/build_your_own_backend" + // }, ] }, { @@ -241,16 +241,16 @@ module.exports = { label: "Migrate from ICICLE v2", id: "icicle/migrate_from_v2", }, - { - type: "doc", - label: "Benchmarks", - id: "icicle/benchmarks", - }, - { - type: "doc", - label: "FAQ and Troubleshooting", - id: "icicle/faq_and_troubleshooting", - }, + // { + // type: "doc", + // label: "Benchmarks", + // id: "icicle/benchmarks", + // }, + // { + // type: "doc", + // label: "FAQ and Troubleshooting", + // id: "icicle/faq_and_troubleshooting", + // }, { type: "doc", label: "Google Colab Instructions", From 86ea4671655ca3632bb53832654a5b7447000d8c Mon Sep 17 00:00:00 2001 From: Leon Hibnik Date: Sun, 10 Nov 2024 11:05:00 +0200 Subject: [PATCH 4/8] fix edit page --- docs/docusaurus.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index b90aa1c30..61835f0b8 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -29,7 +29,7 @@ const config = { remarkPlugins: [math, require('mdx-mermaid')], rehypePlugins: [katex], sidebarPath: require.resolve('./sidebars.js'), - editUrl: 'https://github.com/ingonyama-zk/icicle/tree/main', + editUrl: 'https://github.com/ingonyama-zk/icicle/tree/main/docs', }, blog: { remarkPlugins: [math, require('mdx-mermaid')], From 5ee45854b343f3988a3801ae57c6efaa2f2825f6 Mon Sep 17 00:00:00 2001 From: Leon Hibnik Date: Sun, 10 Nov 2024 11:06:04 +0200 Subject: [PATCH 5/8] update overview --- docs/docs/icicle/overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/icicle/overview.md b/docs/docs/icicle/overview.md index afb83d767..42557e7ea 100644 --- a/docs/docs/icicle/overview.md +++ b/docs/docs/icicle/overview.md @@ -56,7 +56,7 @@ For a detailed guide on setting up Google Colab with ICICLE, refer to [this arti [ICICLE](https://github.com/ingonyama-zk/icicle) can be used similarly to any other cryptography library. Through various integrations, ICICLE has proven effective in multiple use cases: -### Circuit Developers +### Boost Your ZK Prover Performance If you're a circuit developer facing bottlenecks, integrating ICICLE into your prover may solve performance issues. ICICLE is integrated into popular ZK provers like [Gnark](https://github.com/Consensys/gnark) and [Halo2](https://github.com/zkonduit/halo2), enabling immediate GPU acceleration without additional code changes. From f2fd9df28487489b4006f08026d444172737b4db Mon Sep 17 00:00:00 2001 From: Yuval Shekel Date: Sun, 10 Nov 2024 13:57:29 +0200 Subject: [PATCH 6/8] update docs regarding poseidon and error for wrong t value --- docs/docs/icicle/primitives/hash.md | 9 ++++- docs/docs/icicle/rust-bindings/hash.md | 56 +++++++++++++++++--------- icicle/src/hash/poseidon.cpp | 6 +++ 3 files changed, 49 insertions(+), 22 deletions(-) diff --git a/docs/docs/icicle/primitives/hash.md b/docs/docs/icicle/primitives/hash.md index cd64bae8e..ec3fafb3e 100644 --- a/docs/docs/icicle/primitives/hash.md +++ b/docs/docs/icicle/primitives/hash.md @@ -67,8 +67,13 @@ auto keccak512 = Keccak512::create(); auto sha3_256 = Sha3_256::create(); auto sha3_512 = Sha3_512::create(); auto blake2s = Blake2s::create(); -// Poseidon requires specifying the field type and arity (supported 3,5,9,12) -auto poseidon = Poseidon::create(arity); +// Poseidon requires specifying the field-type and t parameter (supported 3,5,9,12) as defined by the Poseidon paper. +auto poseidon = Poseidon::create(t); +// Optionally, Poseidon can accept a domain-tag, which is a field element used to separate applications or contexts. +// The domain tag acts as the first input to the hash function, with the remaining t-1 inputs following it. +scalar_t domain_tag = scalar_t::zero(); // Example using zero; this can be set to any valid field element. +auto poseidon_with_domain_tag = Poseidon::create(t, &domain_tag); +// This version of the hasher with a domain tag expects t-1 additional inputs for hashing. ``` ### 2. Hashing Data diff --git a/docs/docs/icicle/rust-bindings/hash.md b/docs/docs/icicle/rust-bindings/hash.md index 512a089c4..b57c76fe8 100644 --- a/docs/docs/icicle/rust-bindings/hash.md +++ b/docs/docs/icicle/rust-bindings/hash.md @@ -70,25 +70,41 @@ The Poseidon hash is designed for cryptographic field elements and curves, makin Poseidon hash using babybear field: ```rust - use icicle_babybear::field::{ScalarCfg, ScalarField}; - use icicle_core::hash::HashConfig; - use icicle_core::poseidon::{Poseidon, PoseidonHasher}; - use icicle_core::traits::FieldImpl; - use icicle_runtime::memory::HostSlice; - - let batch = 1 << 10; - let arity = 3; - let inputs = ScalarCfg::generate_random(batch * arity); - let mut outputs = vec![ScalarField::zero(); batch]; // note output array is sized for batch - - let poseidon_hasher = Poseidon::new::(arity as u32).unwrap(); - - poseidon_hasher - .hash( - HostSlice::from_slice(&inputs), - &HashConfig::default(), - HostSlice::from_mut_slice(&mut outputs), - ) - .unwrap(); +use icicle_babybear::field::{ScalarCfg, ScalarField}; +use icicle_core::hash::HashConfig; +use icicle_core::poseidon::{Poseidon, PoseidonHasher}; +use icicle_core::traits::FieldImpl; +use icicle_runtime::memory::HostSlice; + +let batch = 1 << 10; // Number of hashes to compute in a single batch +let t = 3; // Poseidon parameter that specifies the arity (number of inputs) for each hash function +let mut outputs = vec![ScalarField::zero(); batch]; // Output array sized for the batch count + +// Case (1): Hashing without a domain tag +// Generates 'batch * t' random input elements as each hash needs 't' inputs +let inputs = ScalarCfg::generate_random(batch * t); +let poseidon_hasher = Poseidon::new::(t as u32, None /*=domain-tag*/).unwrap(); // Instantiate Poseidon without domain tag + +poseidon_hasher + .hash( + HostSlice::from_slice(&inputs), // Input slice for the hash function + &HashConfig::default(), // Default hashing configuration + HostSlice::from_mut_slice(&mut outputs), // Output slice to store hash results + ) + .unwrap(); + +// Case (2): Hashing with a domain tag +// Generates 'batch * (t - 1)' inputs, as domain tag counts as one input in each hash +let inputs = ScalarCfg::generate_random(batch * (t - 1)); +let domain_tag = ScalarField::zero(); // Example domain tag (can be any valid field element) +let poseidon_hasher_with_domain_tag = Poseidon::new::(t as u32, Some(&domain_tag) /*=domain-tag*/).unwrap(); + +poseidon_hasher_with_domain_tag + .hash( + HostSlice::from_slice(&inputs), // Input slice with 't - 1' elements per hash + &HashConfig::default(), // Default hashing configuration + HostSlice::from_mut_slice(&mut outputs), // Output slice to store hash results + ) + .unwrap(); ``` diff --git a/icicle/src/hash/poseidon.cpp b/icicle/src/hash/poseidon.cpp index 67baea280..43c52d6c6 100644 --- a/icicle/src/hash/poseidon.cpp +++ b/icicle/src/hash/poseidon.cpp @@ -9,6 +9,12 @@ namespace icicle { template <> Hash create_poseidon_hash(unsigned t, const scalar_t* domain_tag) { + // Assert that t is valid. Ideally would like to return an eIcicleError but the API doesn't let us do it + constexpr std::array validTValues = {3, 5, 9, 12}; + const bool is_valid_t = std::find(validTValues.begin(), validTValues.end(), t) != validTValues.end(); + ICICLE_LOG_ERROR << "Poseidon only supports t values of 3, 5, 9, or 12."; + ICICLE_ASSERT(false); + std::shared_ptr backend; ICICLE_CHECK(CreatePoseidonHasherDispatcher::execute(t, domain_tag, backend)); Hash poseidon{backend}; From d36d778d258d764c3a27f741aabc096244d00ed9 Mon Sep 17 00:00:00 2001 From: Yuval Shekel Date: Sun, 10 Nov 2024 16:10:29 +0200 Subject: [PATCH 7/8] removed C++ code to avoid full CI in docs commit --- icicle/src/hash/poseidon.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/icicle/src/hash/poseidon.cpp b/icicle/src/hash/poseidon.cpp index 43c52d6c6..67baea280 100644 --- a/icicle/src/hash/poseidon.cpp +++ b/icicle/src/hash/poseidon.cpp @@ -9,12 +9,6 @@ namespace icicle { template <> Hash create_poseidon_hash(unsigned t, const scalar_t* domain_tag) { - // Assert that t is valid. Ideally would like to return an eIcicleError but the API doesn't let us do it - constexpr std::array validTValues = {3, 5, 9, 12}; - const bool is_valid_t = std::find(validTValues.begin(), validTValues.end(), t) != validTValues.end(); - ICICLE_LOG_ERROR << "Poseidon only supports t values of 3, 5, 9, or 12."; - ICICLE_ASSERT(false); - std::shared_ptr backend; ICICLE_CHECK(CreatePoseidonHasherDispatcher::execute(t, domain_tag, backend)); Hash poseidon{backend}; From ddeb7113da73858b4ff4984f881fbfa9298fdcd7 Mon Sep 17 00:00:00 2001 From: Leon Hibnik Date: Mon, 11 Nov 2024 16:34:32 +0200 Subject: [PATCH 8/8] fix docs release domain --- docs/docs/icicle/primitives/ntt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/icicle/primitives/ntt.md b/docs/docs/icicle/primitives/ntt.md index 83afd41a3..967cc0e6a 100644 --- a/docs/docs/icicle/primitives/ntt.md +++ b/docs/docs/icicle/primitives/ntt.md @@ -117,7 +117,7 @@ template S get_root_of_unity(uint64_t max_size); Finally, release the domain to free up device memory when not required: ```cpp -template S get_root_of_unity(uint64_t max_size); +template eIcicleError ntt_release_domain(); ``` where