mirror of
https://github.com/pseXperiments/icicle.git
synced 2026-01-09 15:37:58 -05:00
Merge branch 'ingonyama-zk:main' into main
This commit is contained in:
@@ -6,52 +6,53 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
bn254 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254"
|
||||
bn254_msm "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254/msm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Obtain the default MSM configuration.
|
||||
cfg := bn254.GetDefaultMSMConfig()
|
||||
// Obtain the default MSM configuration.
|
||||
cfg := core.GetDefaultMSMConfig()
|
||||
|
||||
// Define the size of the problem, here 2^18.
|
||||
size := 1 << 18
|
||||
// Define the size of the problem, here 2^18.
|
||||
size := 1 << 18
|
||||
|
||||
// Generate scalars and points for the MSM operation.
|
||||
scalars := bn254.GenerateScalars(size)
|
||||
points := bn254.GenerateAffinePoints(size)
|
||||
// Generate scalars and points for the MSM operation.
|
||||
scalars := bn254.GenerateScalars(size)
|
||||
points := bn254.GenerateAffinePoints(size)
|
||||
|
||||
// Create a CUDA stream for asynchronous operations.
|
||||
stream, _ := cr.CreateStream()
|
||||
var p bn254.Projective
|
||||
// Create a CUDA stream for asynchronous operations.
|
||||
stream, _ := cr.CreateStream()
|
||||
var p bn254.Projective
|
||||
|
||||
// Allocate memory on the device for the result of the MSM operation.
|
||||
var out core.DeviceSlice
|
||||
_, e := out.MallocAsync(p.Size(), p.Size(), stream)
|
||||
// Allocate memory on the device for the result of the MSM operation.
|
||||
var out core.DeviceSlice
|
||||
_, e := out.MallocAsync(p.Size(), p.Size(), stream)
|
||||
|
||||
if e != cr.CudaSuccess {
|
||||
panic(e)
|
||||
}
|
||||
if e != cr.CudaSuccess {
|
||||
panic(e)
|
||||
}
|
||||
|
||||
// Set the CUDA stream in the MSM configuration.
|
||||
cfg.Ctx.Stream = &stream
|
||||
cfg.IsAsync = true
|
||||
// Set the CUDA stream in the MSM configuration.
|
||||
cfg.Ctx.Stream = &stream
|
||||
cfg.IsAsync = true
|
||||
|
||||
// Perform the MSM operation.
|
||||
e = bn254.Msm(scalars, points, &cfg, out)
|
||||
// Perform the MSM operation.
|
||||
e = bn254_msm.Msm(scalars, points, &cfg, out)
|
||||
|
||||
if e != cr.CudaSuccess {
|
||||
panic(e)
|
||||
}
|
||||
if e != cr.CudaSuccess {
|
||||
panic(e)
|
||||
}
|
||||
|
||||
// Allocate host memory for the results and copy the results from the device.
|
||||
outHost := make(core.HostSlice[bn254.Projective], 1)
|
||||
cr.SynchronizeStream(&stream)
|
||||
outHost.CopyFromDevice(&out)
|
||||
// Allocate host memory for the results and copy the results from the device.
|
||||
outHost := make(core.HostSlice[bn254.Projective], 1)
|
||||
cr.SynchronizeStream(&stream)
|
||||
outHost.CopyFromDevice(&out)
|
||||
|
||||
// Free the device memory allocated for the results.
|
||||
out.Free()
|
||||
// Free the device memory allocated for the results.
|
||||
out.Free()
|
||||
}
|
||||
|
||||
```
|
||||
@@ -169,23 +170,23 @@ This package include `G2Projective` and `G2Affine` points as well as a `G2Msm` m
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
bn254 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254"
|
||||
g2 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254/g2"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
bn254 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254"
|
||||
g2 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254/g2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cfg := bn254.GetDefaultMSMConfig()
|
||||
size := 1 << 12
|
||||
batchSize := 3
|
||||
totalSize := size * batchSize
|
||||
scalars := bn254.GenerateScalars(totalSize)
|
||||
points := g2.G2GenerateAffinePoints(totalSize)
|
||||
cfg := core.GetDefaultMSMConfig()
|
||||
size := 1 << 12
|
||||
batchSize := 3
|
||||
totalSize := size * batchSize
|
||||
scalars := bn254.GenerateScalars(totalSize)
|
||||
points := g2.G2GenerateAffinePoints(totalSize)
|
||||
|
||||
var p g2.G2Projective
|
||||
var out core.DeviceSlice
|
||||
out.Malloc(batchSize*p.Size(), p.Size())
|
||||
g2.G2Msm(scalars, points, &cfg, out)
|
||||
var p g2.G2Projective
|
||||
var out core.DeviceSlice
|
||||
out.Malloc(batchSize*p.Size(), p.Size())
|
||||
g2.G2Msm(scalars, points, &cfg, out)
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
23
examples/c++/best-practice-ntt/CMakeLists.txt
Normal file
23
examples/c++/best-practice-ntt/CMakeLists.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CUDA_STANDARD 17)
|
||||
set(CMAKE_CUDA_STANDARD_REQUIRED TRUE)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
|
||||
if (${CMAKE_VERSION} VERSION_LESS "3.24.0")
|
||||
set(CMAKE_CUDA_ARCHITECTURES ${CUDA_ARCH})
|
||||
else()
|
||||
set(CMAKE_CUDA_ARCHITECTURES native) # on 3.24+, on earlier it is ignored, and the target is not passed
|
||||
endif ()
|
||||
project(example LANGUAGES CUDA CXX)
|
||||
|
||||
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --expt-relaxed-constexpr")
|
||||
set(CMAKE_CUDA_FLAGS_RELEASE "")
|
||||
set(CMAKE_CUDA_FLAGS_DEBUG "${CMAKE_CUDA_FLAGS_DEBUG} -g -G -O0")
|
||||
|
||||
add_executable(
|
||||
example
|
||||
example.cu
|
||||
)
|
||||
target_include_directories(example PRIVATE "../../../icicle/include")
|
||||
target_link_libraries(example ${CMAKE_SOURCE_DIR}/build/icicle/lib/libingo_field_bn254.a)
|
||||
set_target_properties(example PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
|
||||
33
examples/c++/best-practice-ntt/README.md
Normal file
33
examples/c++/best-practice-ntt/README.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# ICICLE best practices: Concurrent Data Transfer and NTT Computation
|
||||
|
||||
The [Number Theoretic Transform (NTT)](https://dev.ingonyama.com/icicle/primitives/ntt) is an integral component of many cryptographic algorithms, such as polynomial multiplication in Zero Knowledge Proofs. The performance bottleneck of NTT on GPUs is the data transfer between the host (CPU) and the device (GPU). In a typical NVIDIA GPU this transfer dominates the total NTT execution time.
|
||||
|
||||
## Key-Takeaway
|
||||
|
||||
When you have to run several NTTs, consider Concurrent Data Download, Upload, and Computation to improve data bus (PCIe) and GPU utilization, and get better total execution time.
|
||||
|
||||
Typically, you concurrently
|
||||
|
||||
1. Download the output of a previous NTT back to the host
|
||||
2. Upload the input for a next NTT on the device
|
||||
3. Run current NTT
|
||||
|
||||
> [!NOTE]
|
||||
> This approach requires two on-device memory vectors, decreasing the maximum size of NTT by 2x.
|
||||
|
||||
## Best-Practices
|
||||
|
||||
1. Use three separate CUDA streams for Download, Upload, and Compute operations
|
||||
2. Use pinned (page-locked) memory on host to speed data bus transfers. Calling `cudaHostAlloc` allocates pinned memory.
|
||||
3. Use in-place NTT to save on device memory.
|
||||
|
||||
## Running the example
|
||||
|
||||
To change the default curve BN254, edit `compile.sh` and `CMakeLists.txt`
|
||||
|
||||
```sh
|
||||
./compile.sh
|
||||
./run.sh
|
||||
```
|
||||
|
||||
To compare with ICICLE baseline (i.e. non-concurrent) NTT, you can run [this example](../ntt/README.md).
|
||||
16
examples/c++/best-practice-ntt/compile.sh
Executable file
16
examples/c++/best-practice-ntt/compile.sh
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit immediately on error
|
||||
set -e
|
||||
|
||||
mkdir -p build/example
|
||||
mkdir -p build/icicle
|
||||
|
||||
# Configure and build Icicle
|
||||
cmake -S ../../../icicle/ -B build/icicle -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DG2=OFF -DMSM=OFF
|
||||
cmake --build build/icicle
|
||||
|
||||
# Configure and build the example application
|
||||
cmake -S . -B build/example
|
||||
cmake --build build/example
|
||||
|
||||
142
examples/c++/best-practice-ntt/example.cu
Normal file
142
examples/c++/best-practice-ntt/example.cu
Normal file
@@ -0,0 +1,142 @@
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
|
||||
#include "curves/params/bn254.cuh"
|
||||
#include "api/bn254.h"
|
||||
using namespace bn254;
|
||||
using namespace ntt;
|
||||
|
||||
const std::string curve = "BN254";
|
||||
|
||||
typedef scalar_t S;
|
||||
typedef scalar_t E;
|
||||
|
||||
const unsigned max_log_ntt_size = 27;
|
||||
|
||||
void initialize_input(const unsigned ntt_size, const unsigned nof_ntts, E * elements ) {
|
||||
for (unsigned i = 0; i < ntt_size * nof_ntts; i++) {
|
||||
elements[i] = E::from(i+1);
|
||||
}
|
||||
}
|
||||
|
||||
using FpMilliseconds = std::chrono::duration<float, std::chrono::milliseconds::period>;
|
||||
#define START_TIMER(timer) auto timer##_start = std::chrono::high_resolution_clock::now();
|
||||
#define END_TIMER(timer, msg) printf("%s: %.0f ms\n", msg, FpMilliseconds(std::chrono::high_resolution_clock::now() - timer##_start).count());
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
cudaDeviceReset();
|
||||
cudaDeviceProp deviceProperties;
|
||||
int deviceId=0;
|
||||
cudaGetDeviceProperties(&deviceProperties, deviceId);
|
||||
std::string gpu_full_name = deviceProperties.name;
|
||||
std::cout << gpu_full_name << std::endl;
|
||||
std::string gpu_name = gpu_full_name;
|
||||
|
||||
std::cout << "Curve: " << curve << std::endl;
|
||||
|
||||
S basic_root = S::omega(max_log_ntt_size);
|
||||
|
||||
// change these parameters to match the desired NTT size and batch size
|
||||
const unsigned log_ntt_size = 22;
|
||||
const unsigned nof_ntts = 16;
|
||||
|
||||
std::cout << "log NTT size: " << log_ntt_size << std::endl;
|
||||
const unsigned ntt_size = 1 << log_ntt_size;
|
||||
|
||||
std::cout << "Batch size: " << nof_ntts << std::endl;
|
||||
|
||||
// Create separate CUDA streams for overlapping data transfers and kernel execution.
|
||||
cudaStream_t stream_compute, stream_h2d, stream_d2h;
|
||||
cudaStreamCreate(&stream_compute);
|
||||
cudaStreamCreate(&stream_h2d);
|
||||
cudaStreamCreate(&stream_d2h);
|
||||
|
||||
// Create device context for NTT computation
|
||||
auto ctx_compute = device_context::DeviceContext{
|
||||
stream_compute, // stream
|
||||
0, // device_id
|
||||
0, // mempool
|
||||
};
|
||||
|
||||
// Initialize NTT domain and configuration
|
||||
bn254_initialize_domain(&basic_root, ctx_compute, /* fast twiddles */ true);
|
||||
NTTConfig<S> config_compute = default_ntt_config<S>(ctx_compute);
|
||||
config_compute.ntt_algorithm = NttAlgorithm::MixedRadix;
|
||||
config_compute.batch_size = nof_ntts;
|
||||
config_compute.are_inputs_on_device = true;
|
||||
config_compute.are_outputs_on_device = true;
|
||||
config_compute.is_async = true;
|
||||
|
||||
std::cout << "Concurrent Download, Upload, and Compute In-place NTT" << std::endl;
|
||||
int nof_blocks = 32;
|
||||
std::cout << "Number of blocks: " << nof_blocks << std::endl;
|
||||
int block_size = ntt_size*nof_ntts/nof_blocks;
|
||||
|
||||
// on-host pinned data
|
||||
E * h_inp[2];
|
||||
E * h_out[2];
|
||||
for (int i = 0; i < 2; i++) {
|
||||
cudaHostAlloc((void**)&h_inp[i], sizeof(E)*ntt_size*nof_ntts, cudaHostAllocDefault);
|
||||
cudaHostAlloc((void**)&h_out[i], sizeof(E)*ntt_size*nof_ntts, cudaHostAllocDefault);
|
||||
}
|
||||
|
||||
// on-device in-place data
|
||||
// we need two on-device vectors to overlap data transfers with NTT kernel execution
|
||||
E * d_vec[2];
|
||||
for (int i = 0; i < 2; i++) {
|
||||
cudaMalloc((void**)&d_vec[i], sizeof(E)*ntt_size*nof_ntts);
|
||||
}
|
||||
|
||||
// initialize input data
|
||||
initialize_input(ntt_size, nof_ntts, h_inp[0]);
|
||||
initialize_input(ntt_size, nof_ntts, h_inp[1]);
|
||||
|
||||
cudaEvent_t compute_start, compute_stop;
|
||||
cudaEventCreate(&compute_start);
|
||||
cudaEventCreate(&compute_stop);
|
||||
|
||||
for ( int run = 0; run < 10; run++ ) {
|
||||
int vec_compute = run % 2;
|
||||
int vec_transfer = (run + 1) % 2;
|
||||
std::cout << "Run: " << run << std::endl;
|
||||
std::cout << "Compute Vector: " << vec_compute << std::endl;
|
||||
std::cout << "Transfer Vector: " << vec_transfer << std::endl;
|
||||
START_TIMER(inplace);
|
||||
cudaEventRecord(compute_start, stream_compute);
|
||||
bn254_ntt_cuda(d_vec[vec_compute], ntt_size, NTTDir::kForward, config_compute, d_vec[vec_compute]);
|
||||
cudaEventRecord(compute_stop, stream_compute);
|
||||
// we have to delay upload to device relative to download from device by one block: preserve write after read
|
||||
for (int i = 0; i <= nof_blocks; i++) {
|
||||
if (i < nof_blocks) {
|
||||
cudaMemcpyAsync(&h_out[vec_transfer][i*block_size], &d_vec[vec_transfer][i*block_size], sizeof(E)*block_size, cudaMemcpyDeviceToHost, stream_d2h);
|
||||
}
|
||||
if (i>0) {
|
||||
cudaMemcpyAsync(&d_vec[vec_transfer][(i-1)*block_size], &h_inp[vec_transfer][(i-1)*block_size], sizeof(E)*block_size, cudaMemcpyHostToDevice, stream_h2d);
|
||||
}
|
||||
// synchronize upload and download at the end of the block to ensure data integrity
|
||||
cudaStreamSynchronize(stream_d2h);
|
||||
cudaStreamSynchronize(stream_h2d);
|
||||
}
|
||||
// synchronize compute stream with the end of the computation
|
||||
cudaEventSynchronize(compute_stop);
|
||||
float milliseconds = 0;
|
||||
cudaEventElapsedTime(&milliseconds, compute_start, compute_stop);
|
||||
END_TIMER(inplace, "Concurrent In-Place NTT");
|
||||
std::cout << "NTT time: " << milliseconds << " ms" << std::endl;
|
||||
};
|
||||
|
||||
// Clean-up
|
||||
for (int i = 0; i < 2; i++) {
|
||||
cudaFree(d_vec[i]);
|
||||
cudaFreeHost(h_inp[i]);
|
||||
cudaFreeHost(h_out[i]);
|
||||
}
|
||||
cudaEventDestroy(compute_start);
|
||||
cudaEventDestroy(compute_stop);
|
||||
cudaStreamDestroy(stream_compute);
|
||||
cudaStreamDestroy(stream_d2h);
|
||||
cudaStreamDestroy(stream_h2d);
|
||||
return 0;
|
||||
}
|
||||
2
examples/c++/best-practice-ntt/run.sh
Executable file
2
examples/c++/best-practice-ntt/run.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
./build/example/example
|
||||
34
examples/golang/msm/README.md
Normal file
34
examples/golang/msm/README.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# ICICLE example: MultiScalar Multiplication (MSM) in Golang
|
||||
|
||||
`ICICLE` provides Golang bindings to CUDA-accelerated C++ implementation of [Multi-Scalar Multiplication](https://github.com/ingonyama-zk/ingopedia/blob/master/src/msm.md).
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
err := Msm(
|
||||
/* Scalars input vector */ scalars,
|
||||
/* Points input vector */ points,
|
||||
/* MSMConfig reference */ &cfg,
|
||||
/* Projective point result */ results)
|
||||
```
|
||||
|
||||
In this example we use `BN254` and `BLS12377` curves. The function computes $result = \sum_{i=0}^{size-1} scalars[i] \cdot points[i]$, where input `points[]` uses affine coordinates, and `result` uses projective coordinates.
|
||||
|
||||
## What's in the example
|
||||
|
||||
1. Define the size of MSM.
|
||||
2. Generate random inputs on-device
|
||||
3. Configure MSM
|
||||
4. Execute MSM on-device
|
||||
5. Move the result on host
|
||||
|
||||
Running the example:
|
||||
```sh
|
||||
go run main.go
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> The default sizes are 2^17 - 2^22. You can change this by passing the `-l <size> -u <size>` options. To change the size range to 2^21 - 2^24, run the example like this:
|
||||
> ```sh
|
||||
> go run main.go -l=21 -u=24
|
||||
> ```
|
||||
209
examples/golang/msm/main.go
Normal file
209
examples/golang/msm/main.go
Normal file
@@ -0,0 +1,209 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12377"
|
||||
|
||||
bls12377G2 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12377/g2"
|
||||
bls12377Msm "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12377/msm"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254"
|
||||
|
||||
bn254G2 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254/g2"
|
||||
bn254Msm "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254/msm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var logSizeMin int
|
||||
var logSizeMax int
|
||||
|
||||
flag.IntVar(&logSizeMin, "l", 17, "Minimum log size")
|
||||
flag.IntVar(&logSizeMax, "u", 22, "Maximum log size")
|
||||
flag.Parse()
|
||||
|
||||
sizeMax := 1 << logSizeMax
|
||||
|
||||
print("Generating BN254 scalars ... ")
|
||||
startTime := time.Now()
|
||||
scalarsBn254Max := bn254.GenerateScalars(sizeMax)
|
||||
println(time.Since(startTime).String())
|
||||
|
||||
print("Generating BN254 points ... ")
|
||||
startTime = time.Now()
|
||||
pointsBn254Max := bn254.GenerateAffinePoints(sizeMax)
|
||||
println(time.Since(startTime).String())
|
||||
|
||||
print("Generating BN254 G2 points ... ")
|
||||
startTime = time.Now()
|
||||
pointsBn254G2Max := bn254G2.G2GenerateAffinePoints(sizeMax)
|
||||
println(time.Since(startTime).String())
|
||||
|
||||
print("Generating BLS12_377 scalars ... ")
|
||||
startTime = time.Now()
|
||||
scalarsBls12377Max := bls12377.GenerateScalars(sizeMax)
|
||||
println(time.Since(startTime).String())
|
||||
|
||||
print("Generating BLS12_377 points ... ")
|
||||
startTime = time.Now()
|
||||
pointsBls12377Max := bls12377.GenerateAffinePoints(sizeMax)
|
||||
println(time.Since(startTime).String())
|
||||
|
||||
print("Generating BLS12_377 G2 points ... ")
|
||||
startTime = time.Now()
|
||||
pointsBls12377G2Max := bls12377G2.G2GenerateAffinePoints(sizeMax)
|
||||
println(time.Since(startTime).String())
|
||||
|
||||
for logSize := logSizeMin; logSize <= logSizeMax; logSize++ {
|
||||
|
||||
// Define the size of the problem, here 2^18.
|
||||
size := 1 << logSize
|
||||
|
||||
fmt.Printf("---------------------- MSM size 2^%d=%d ------------------------\n", logSize, size)
|
||||
|
||||
// println(scalarsBls12377, pointsBls12377, pointsBn254G2)
|
||||
// println(scalarsBn254, pointsBn254, pointsBls12377G2)
|
||||
|
||||
print("Configuring bn254 MSM ... ")
|
||||
startTime = time.Now()
|
||||
|
||||
scalarsBn254 := scalarsBn254Max[:size]
|
||||
pointsBn254 := pointsBn254Max[:size]
|
||||
pointsBn254G2 := pointsBn254G2Max[:size]
|
||||
|
||||
cfgBn254 := core.GetDefaultMSMConfig()
|
||||
cfgBn254G2 := core.GetDefaultMSMConfig()
|
||||
cfgBn254.IsAsync = true
|
||||
cfgBn254G2.IsAsync = true
|
||||
|
||||
streamBn254, _ := cr.CreateStream()
|
||||
streamBn254G2, _ := cr.CreateStream()
|
||||
|
||||
cfgBn254.Ctx.Stream = &streamBn254
|
||||
cfgBn254G2.Ctx.Stream = &streamBn254G2
|
||||
|
||||
var projectiveBn254 bn254.Projective
|
||||
var projectiveBn254G2 bn254G2.G2Projective
|
||||
|
||||
var msmResultBn254 core.DeviceSlice
|
||||
var msmResultBn254G2 core.DeviceSlice
|
||||
|
||||
_, e := msmResultBn254.MallocAsync(projectiveBn254.Size(), projectiveBn254.Size(), streamBn254)
|
||||
if e != cr.CudaSuccess {
|
||||
errorString := fmt.Sprint(
|
||||
"Bn254 Malloc failed: ", e)
|
||||
panic(errorString)
|
||||
}
|
||||
_, e = msmResultBn254G2.MallocAsync(projectiveBn254G2.Size(), projectiveBn254G2.Size(), streamBn254G2)
|
||||
if e != cr.CudaSuccess {
|
||||
errorString := fmt.Sprint(
|
||||
"Bn254 Malloc G2 failed: ", e)
|
||||
panic(errorString)
|
||||
}
|
||||
|
||||
println(time.Since(startTime).String())
|
||||
|
||||
print("Configuring Bls12377 MSM ... ")
|
||||
startTime = time.Now()
|
||||
|
||||
scalarsBls12377 := scalarsBls12377Max[:size]
|
||||
pointsBls12377 := pointsBls12377Max[:size]
|
||||
pointsBls12377G2 := pointsBls12377G2Max[:size]
|
||||
|
||||
cfgBls12377 := core.GetDefaultMSMConfig()
|
||||
cfgBls12377G2 := core.GetDefaultMSMConfig()
|
||||
cfgBls12377.IsAsync = true
|
||||
cfgBls12377G2.IsAsync = true
|
||||
|
||||
streamBls12377, _ := cr.CreateStream()
|
||||
streamBls12377G2, _ := cr.CreateStream()
|
||||
|
||||
cfgBls12377.Ctx.Stream = &streamBls12377
|
||||
cfgBls12377G2.Ctx.Stream = &streamBls12377G2
|
||||
|
||||
var projectiveBls12377 bls12377.Projective
|
||||
var projectiveBls12377G2 bls12377G2.G2Projective
|
||||
|
||||
var msmResultBls12377 core.DeviceSlice
|
||||
var msmResultBls12377G2 core.DeviceSlice
|
||||
|
||||
_, e = msmResultBls12377.MallocAsync(projectiveBls12377.Size(), projectiveBls12377.Size(), streamBls12377)
|
||||
if e != cr.CudaSuccess {
|
||||
errorString := fmt.Sprint(
|
||||
"Bls12_377 Malloc failed: ", e)
|
||||
panic(errorString)
|
||||
}
|
||||
_, e = msmResultBls12377G2.MallocAsync(projectiveBls12377G2.Size(), projectiveBls12377G2.Size(), streamBls12377G2)
|
||||
if e != cr.CudaSuccess {
|
||||
errorString := fmt.Sprint(
|
||||
"Bls12_377 Malloc G2 failed: ", e)
|
||||
panic(errorString)
|
||||
}
|
||||
|
||||
println(time.Since(startTime).String())
|
||||
|
||||
print("Executing bn254 MSM on device ... ")
|
||||
startTime = time.Now()
|
||||
|
||||
e = bn254Msm.Msm(scalarsBn254, pointsBn254, &cfgBn254, msmResultBn254)
|
||||
if e != cr.CudaSuccess {
|
||||
errorString := fmt.Sprint(
|
||||
"bn254 Msm failed: ", e)
|
||||
panic(errorString)
|
||||
}
|
||||
e = bn254G2.G2Msm(scalarsBn254, pointsBn254G2, &cfgBn254G2, msmResultBn254G2)
|
||||
if e != cr.CudaSuccess {
|
||||
errorString := fmt.Sprint(
|
||||
"bn254 Msm G2 failed: ", e)
|
||||
panic(errorString)
|
||||
}
|
||||
|
||||
msmResultBn254Host := make(core.HostSlice[bn254.Projective], 1)
|
||||
msmResultBn254G2Host := make(core.HostSlice[bn254G2.G2Projective], 1)
|
||||
|
||||
msmResultBn254Host.CopyFromDeviceAsync(&msmResultBn254, streamBn254)
|
||||
msmResultBn254G2Host.CopyFromDeviceAsync(&msmResultBn254G2, streamBn254G2)
|
||||
|
||||
msmResultBn254.FreeAsync(streamBn254)
|
||||
msmResultBn254G2.FreeAsync(streamBn254G2)
|
||||
|
||||
cr.SynchronizeStream(&streamBn254)
|
||||
cr.SynchronizeStream(&streamBn254G2)
|
||||
|
||||
println(time.Since(startTime).String())
|
||||
|
||||
print("Executing Bls12377 MSM on device ... ")
|
||||
startTime = time.Now()
|
||||
|
||||
e = bls12377Msm.Msm(scalarsBls12377, pointsBls12377, &cfgBls12377, msmResultBls12377)
|
||||
if e != cr.CudaSuccess {
|
||||
errorString := fmt.Sprint(
|
||||
"bls12_377 Msm failed: ", e)
|
||||
panic(errorString)
|
||||
}
|
||||
e = bls12377G2.G2Msm(scalarsBls12377, pointsBls12377G2, &cfgBls12377G2, msmResultBls12377G2)
|
||||
if e != cr.CudaSuccess {
|
||||
errorString := fmt.Sprint(
|
||||
"bls12_377 Msm G2 failed: ", e)
|
||||
panic(errorString)
|
||||
}
|
||||
|
||||
msmResultBls12377Host := make(core.HostSlice[bls12377.Projective], 1)
|
||||
msmResultBls12377G2Host := make(core.HostSlice[bls12377G2.G2Projective], 1)
|
||||
|
||||
msmResultBls12377Host.CopyFromDeviceAsync(&msmResultBls12377, streamBls12377)
|
||||
msmResultBls12377G2Host.CopyFromDeviceAsync(&msmResultBls12377G2, streamBls12377G2)
|
||||
|
||||
msmResultBls12377.FreeAsync(streamBls12377)
|
||||
msmResultBls12377G2.FreeAsync(streamBls12377G2)
|
||||
|
||||
cr.SynchronizeStream(&streamBls12377)
|
||||
cr.SynchronizeStream(&streamBls12377G2)
|
||||
|
||||
println(time.Since(startTime).String())
|
||||
}
|
||||
}
|
||||
39
examples/golang/ntt/README.md
Normal file
39
examples/golang/ntt/README.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# ICICLE example: Number Theoretic Transform (NTT) in Golang
|
||||
|
||||
## Key-Takeaway
|
||||
|
||||
`ICICLE` provides Golang bindings to CUDA-accelerated C++ implementation of [Number Theoretic Transform](https://github.com/ingonyama-zk/ingopedia/blob/master/src/fft.md).
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
err := Ntt(
|
||||
/* input slice */ scalars,
|
||||
/* NTT Direction */ core.KForward,
|
||||
/* NTT Configuration */ &cfg,
|
||||
/* output slice */ result)
|
||||
```
|
||||
|
||||
In this example we use the `BN254` and `BLS12377` fields.
|
||||
|
||||
## What's in this example
|
||||
|
||||
1. Define the size of NTT.
|
||||
2. Generate random inputs
|
||||
3. Set up the domain.
|
||||
4. Configure NTT
|
||||
5. Execute NTT on-device
|
||||
6. Move the result on host
|
||||
|
||||
Running the example:
|
||||
|
||||
```sh
|
||||
go run main.go
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> The default size is 2^20. You can change this by passing the `-s <size>` option. To change the size to 2^23, run the example like this:
|
||||
|
||||
```sh
|
||||
go run main.go -s=23
|
||||
```
|
||||
131
examples/golang/ntt/main.go
Normal file
131
examples/golang/ntt/main.go
Normal file
@@ -0,0 +1,131 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12377"
|
||||
|
||||
bls12377Ntt "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12377/ntt"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254"
|
||||
|
||||
bn254Ntt "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254/ntt"
|
||||
|
||||
bls12377Fft "github.com/consensys/gnark-crypto/ecc/bls12-377/fr/fft"
|
||||
bn254Fft "github.com/consensys/gnark-crypto/ecc/bn254/fr/fft"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var logSize int
|
||||
|
||||
flag.IntVar(&logSize, "s", 20, "Log size")
|
||||
flag.Parse()
|
||||
|
||||
size := 1 << logSize
|
||||
|
||||
fmt.Printf("---------------------- NTT size 2^%d=%d ------------------------\n", logSize, size)
|
||||
|
||||
print("Generating BN254 scalars ... ")
|
||||
startTime := time.Now()
|
||||
scalarsBn254 := bn254.GenerateScalars(size)
|
||||
println(time.Since(startTime).String())
|
||||
|
||||
cfgBn254 := bn254Ntt.GetDefaultNttConfig()
|
||||
cfgBn254.IsAsync = true
|
||||
|
||||
print("Generating BLS12_377 scalars ... ")
|
||||
startTime = time.Now()
|
||||
scalarsBls12377 := bls12377.GenerateScalars(size)
|
||||
println(time.Since(startTime).String())
|
||||
|
||||
cfgBls12377 := bls12377Ntt.GetDefaultNttConfig()
|
||||
cfgBls12377.IsAsync = true
|
||||
|
||||
rouMontBn254, _ := bn254Fft.Generator(uint64(size))
|
||||
rouBn254 := rouMontBn254.Bits()
|
||||
rouIcicleBn254 := bn254.ScalarField{}
|
||||
limbsBn254 := core.ConvertUint64ArrToUint32Arr(rouBn254[:])
|
||||
rouIcicleBn254.FromLimbs(limbsBn254)
|
||||
bn254Ntt.InitDomain(rouIcicleBn254, cfgBn254.Ctx, false)
|
||||
|
||||
rouMontBls12377, _ := bls12377Fft.Generator(uint64(size))
|
||||
rouBls12377 := rouMontBls12377.Bits()
|
||||
rouIcicleBls12377 := bls12377.ScalarField{}
|
||||
limbsBls12377 := core.ConvertUint64ArrToUint32Arr(rouBls12377[:])
|
||||
rouIcicleBls12377.FromLimbs(limbsBls12377)
|
||||
bls12377Ntt.InitDomain(rouIcicleBls12377, cfgBls12377.Ctx, false)
|
||||
|
||||
print("Configuring bn254 NTT ... ")
|
||||
startTime = time.Now()
|
||||
|
||||
streamBn254, _ := cr.CreateStream()
|
||||
|
||||
cfgBn254.Ctx.Stream = &streamBn254
|
||||
|
||||
var nttResultBn254 core.DeviceSlice
|
||||
|
||||
_, e := nttResultBn254.MallocAsync(size*scalarsBn254.SizeOfElement(), scalarsBn254.SizeOfElement(), streamBn254)
|
||||
if e != cr.CudaSuccess {
|
||||
errorString := fmt.Sprint(
|
||||
"Bn254 Malloc failed: ", e)
|
||||
panic(errorString)
|
||||
}
|
||||
|
||||
println(time.Since(startTime).String())
|
||||
|
||||
print("Configuring Bls12377 NTT ... ")
|
||||
startTime = time.Now()
|
||||
|
||||
streamBls12377, _ := cr.CreateStream()
|
||||
|
||||
cfgBls12377.Ctx.Stream = &streamBls12377
|
||||
|
||||
var nttResultBls12377 core.DeviceSlice
|
||||
|
||||
_, e = nttResultBls12377.MallocAsync(size*scalarsBls12377.SizeOfElement(), scalarsBls12377.SizeOfElement(), streamBls12377)
|
||||
if e != cr.CudaSuccess {
|
||||
errorString := fmt.Sprint(
|
||||
"Bls12_377 Malloc failed: ", e)
|
||||
panic(errorString)
|
||||
}
|
||||
|
||||
println(time.Since(startTime).String())
|
||||
|
||||
print("Executing bn254 NTT on device ... ")
|
||||
startTime = time.Now()
|
||||
|
||||
err := bn254Ntt.Ntt(scalarsBn254, core.KForward, &cfgBn254, nttResultBn254)
|
||||
if err.CudaErrorCode != cr.CudaSuccess {
|
||||
errorString := fmt.Sprint(
|
||||
"bn254 Ntt failed: ", e)
|
||||
panic(errorString)
|
||||
}
|
||||
|
||||
nttResultBn254Host := make(core.HostSlice[bn254.ScalarField], size)
|
||||
nttResultBn254Host.CopyFromDeviceAsync(&nttResultBn254, streamBn254)
|
||||
nttResultBn254.FreeAsync(streamBn254)
|
||||
cr.SynchronizeStream(&streamBn254)
|
||||
println(time.Since(startTime).String())
|
||||
|
||||
print("Executing Bls12377 NTT on device ... ")
|
||||
startTime = time.Now()
|
||||
|
||||
err = bls12377Ntt.Ntt(scalarsBls12377, core.KForward, &cfgBls12377, nttResultBls12377)
|
||||
if err.CudaErrorCode != cr.CudaSuccess {
|
||||
errorString := fmt.Sprint(
|
||||
"bls12_377 Ntt failed: ", e)
|
||||
panic(errorString)
|
||||
}
|
||||
|
||||
nttResultBls12377Host := make(core.HostSlice[bls12377.ScalarField], size)
|
||||
nttResultBls12377Host.CopyFromDeviceAsync(&nttResultBls12377, streamBls12377)
|
||||
nttResultBls12377.FreeAsync(streamBls12377)
|
||||
|
||||
cr.SynchronizeStream(&streamBls12377)
|
||||
|
||||
println(time.Since(startTime).String())
|
||||
}
|
||||
49
examples/golang/polynomials/README.md
Normal file
49
examples/golang/polynomials/README.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# ICICLE example: Polynomials in Golang
|
||||
|
||||
`ICICLE` provides Golang bindings to CUDA-accelerated C++ implementation of [Polynomials](https://dev.ingonyama.com/icicle/polynomials/overview).
|
||||
|
||||
## Usage
|
||||
### Backend Initialization
|
||||
```go
|
||||
InitPolyBackend()
|
||||
```
|
||||
### Construction
|
||||
|
||||
```go
|
||||
poly1 := CreateFromCoeffecitients(/* Coefficients of polynomial */ coeffs)
|
||||
poly2 := CreateFromROUEvaluations(/* evaluations */ evals)
|
||||
poly3 := Clone(/* polynomial to clone */ poly1)
|
||||
```
|
||||
|
||||
### Arithmetic
|
||||
|
||||
```go
|
||||
polyAdd := poly1.Add(&poly2)
|
||||
polySub := poly1.Subtract(&poly2)
|
||||
polyMul := poly1.Multiply(&poly2)
|
||||
polyMulScalar := MultiplyByScalar(scalar)
|
||||
quotient, remainder := poly1.Divide(&poly2)
|
||||
```
|
||||
|
||||
### Evaluation
|
||||
|
||||
```go
|
||||
ev := poly1.Eval(scalar)
|
||||
ev2 := poly1.EvalOnDomain(scalars)
|
||||
```
|
||||
|
||||
In this example we use `BN254` and `Babybear` fields. The examples shows arithmetic operations and evaluations execution.
|
||||
|
||||
## What's in the example
|
||||
|
||||
1. Define the size of polynomials.
|
||||
2. Initialize backends.
|
||||
3. Generate random polynomials.
|
||||
4. Execute arithmetic operations.
|
||||
5. Execute evaluations.
|
||||
6. Execute slicing.
|
||||
|
||||
Running the example:
|
||||
```sh
|
||||
go run main.go
|
||||
```
|
||||
114
examples/golang/polynomials/main.go
Normal file
114
examples/golang/polynomials/main.go
Normal file
@@ -0,0 +1,114 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
bn254Fft "github.com/consensys/gnark-crypto/ecc/bn254/fr/fft"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254"
|
||||
bn254Ntt "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254/ntt"
|
||||
bn254Polynomial "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254/polynomial"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
babybear "github.com/ingonyama-zk/icicle/v2/wrappers/golang/fields/babybear"
|
||||
babybearNtt "github.com/ingonyama-zk/icicle/v2/wrappers/golang/fields/babybear/ntt"
|
||||
babybearPolynomial "github.com/ingonyama-zk/icicle/v2/wrappers/golang/fields/babybear/polynomial"
|
||||
)
|
||||
|
||||
var maxNttLogSize uint
|
||||
var polyLogSize uint
|
||||
|
||||
func initBn254Domain() core.IcicleError {
|
||||
deviceCfg, _ := cr.GetDefaultDeviceContext()
|
||||
rouMontBn254, _ := bn254Fft.Generator(uint64(1 << maxNttLogSize))
|
||||
rouBn254 := rouMontBn254.Bits()
|
||||
rouIcicleBn254 := bn254.ScalarField{}
|
||||
limbsBn254 := core.ConvertUint64ArrToUint32Arr(rouBn254[:])
|
||||
rouIcicleBn254.FromLimbs(limbsBn254)
|
||||
return bn254Ntt.InitDomain(rouIcicleBn254, deviceCfg, false)
|
||||
}
|
||||
|
||||
func initBabybearDomain() core.IcicleError {
|
||||
deviceCfg, _ := cr.GetDefaultDeviceContext()
|
||||
rouIcicle := babybear.ScalarField{}
|
||||
rouIcicle.FromUint32(1461624142)
|
||||
return babybearNtt.InitDomain(rouIcicle, deviceCfg, false)
|
||||
}
|
||||
|
||||
func init() {
|
||||
flag.UintVar(&maxNttLogSize, "maxNttLogSize", 20, "")
|
||||
flag.UintVar(&polyLogSize, "polyLogSize", 15, "")
|
||||
|
||||
e := initBn254Domain()
|
||||
if e.IcicleErrorCode != core.IcicleSuccess {
|
||||
errorString := fmt.Sprint(
|
||||
"Bn254 Domain initialization failed: ", e)
|
||||
panic(errorString)
|
||||
}
|
||||
e = initBabybearDomain()
|
||||
if e.IcicleErrorCode != core.IcicleSuccess {
|
||||
errorString := fmt.Sprint(
|
||||
"Babybear Domain initialization failed: ", e)
|
||||
panic(errorString)
|
||||
}
|
||||
|
||||
bn254Polynomial.InitPolyBackend()
|
||||
babybearPolynomial.InitPolyBackend()
|
||||
}
|
||||
func main() {
|
||||
polySize := 1 << polyLogSize
|
||||
|
||||
// randomize three polynomials over bn254 scalar field
|
||||
var fBn254 bn254Polynomial.DensePolynomial
|
||||
var gBn254 bn254Polynomial.DensePolynomial
|
||||
var hBn254 bn254Polynomial.DensePolynomial
|
||||
fBn254.CreateFromCoeffecitients(bn254.GenerateScalars(polySize))
|
||||
gBn254.CreateFromCoeffecitients(bn254.GenerateScalars(polySize / 2))
|
||||
hBn254.CreateFromROUEvaluations(bn254.GenerateScalars(polySize / 4))
|
||||
|
||||
// randomize two polynomials over babybear field
|
||||
var fBabybear babybearPolynomial.DensePolynomial
|
||||
var gBabybear babybearPolynomial.DensePolynomial
|
||||
fBabybear.CreateFromCoeffecitients(babybear.GenerateScalars(polySize))
|
||||
gBabybear.CreateFromCoeffecitients(babybear.GenerateScalars(polySize / 2))
|
||||
|
||||
// Arithmetic
|
||||
t0 := fBn254.Add(&gBn254)
|
||||
t1 := fBn254.Multiply(&hBn254)
|
||||
q, r := t1.Divide(&t0)
|
||||
rBabybear := fBabybear.Add(&gBabybear)
|
||||
rDegree := r.Degree()
|
||||
_ = rBabybear
|
||||
_ = rDegree
|
||||
|
||||
// evaluate in single domain point
|
||||
var five bn254.ScalarField
|
||||
five.FromUint32(5)
|
||||
qAtFive := q.Eval(five)
|
||||
|
||||
var thirty bn254.ScalarField
|
||||
thirty.FromUint32(30)
|
||||
|
||||
// evaluate on domain. Note: domain and image can be either Host or Device slice.
|
||||
// in this example domain in on host and evals on device.
|
||||
hostDomain := core.HostSliceFromElements([]bn254.ScalarField{five, thirty})
|
||||
var deviceImage core.DeviceSlice
|
||||
_, err := deviceImage.Malloc(five.Size()*hostDomain.Len(), five.Size())
|
||||
if err != cr.CudaSuccess {
|
||||
errorString := fmt.Sprint(
|
||||
"deviceImage allocation failed: ", err)
|
||||
panic(errorString)
|
||||
}
|
||||
t1.EvalOnDomain(hostDomain, deviceImage)
|
||||
|
||||
// slicing
|
||||
o := hBn254.Odd()
|
||||
e := hBn254.Even()
|
||||
|
||||
oddMult := o.MultiplyByScalar(qAtFive)
|
||||
fold := e.Add(&oddMult) // e(x) + o(x)*scalar
|
||||
|
||||
coeff := fold.GetCoeff(2) // coeff of x^2
|
||||
_ = coeff
|
||||
}
|
||||
@@ -24,6 +24,7 @@ set(POLYNOMIAL_SOURCE_FILES
|
||||
|
||||
# TODO: impl poseidon for small fields. note that it needs to be defined over the extension field!
|
||||
if (DEFINED CURVE)
|
||||
list(APPEND FIELD_SOURCE ${SRC}/poseidon/extern.cu)
|
||||
list(APPEND FIELD_SOURCE ${SRC}/poseidon/poseidon.cu)
|
||||
list(APPEND FIELD_SOURCE ${SRC}/poseidon/tree/merkle.cu)
|
||||
endif()
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
test_poseidon: test.cu poseidon.cu kernels.cu constants.cu
|
||||
nvcc -o test_poseidon -I../../include -DFIELD_ID=2 -DCURVE_ID=2 test.cu
|
||||
./test_poseidon
|
||||
test_poseidon : test.cu poseidon.cu kernels.cu constants.cu nvcc - o test_poseidon - I../../ include - DFIELD_ID =
|
||||
2 - DCURVE_ID = 2 test.cu./ test_poseidon
|
||||
|
||||
@@ -98,22 +98,4 @@ namespace poseidon {
|
||||
|
||||
return CHK_LAST();
|
||||
}
|
||||
|
||||
extern "C" cudaError_t CONCAT_EXPAND(FIELD, create_optimized_poseidon_constants_cuda)(
|
||||
int arity,
|
||||
int full_rounds_half,
|
||||
int partial_rounds,
|
||||
const scalar_t* constants,
|
||||
device_context::DeviceContext& ctx,
|
||||
PoseidonConstants<scalar_t>* poseidon_constants)
|
||||
{
|
||||
return create_optimized_poseidon_constants<scalar_t>(
|
||||
arity, full_rounds_half, partial_rounds, constants, ctx, poseidon_constants);
|
||||
}
|
||||
|
||||
extern "C" cudaError_t CONCAT_EXPAND(FIELD, init_optimized_poseidon_constants_cuda)(
|
||||
int arity, device_context::DeviceContext& ctx, PoseidonConstants<scalar_t>* constants)
|
||||
{
|
||||
return init_optimized_poseidon_constants<scalar_t>(arity, ctx, constants);
|
||||
}
|
||||
} // namespace poseidon
|
||||
59
icicle/src/poseidon/extern.cu
Normal file
59
icicle/src/poseidon/extern.cu
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "fields/field_config.cuh"
|
||||
|
||||
using namespace field_config;
|
||||
|
||||
#include "poseidon.cu"
|
||||
#include "constants.cu"
|
||||
|
||||
#include "gpu-utils/device_context.cuh"
|
||||
#include "utils/utils.h"
|
||||
|
||||
namespace poseidon {
|
||||
/**
|
||||
* Extern "C" version of [poseidon_hash_cuda] function with the following
|
||||
* value of template parameter (where the field is given by `-DFIELD` env variable during build):
|
||||
* - `S` is the [field](@ref scalar_t) - either a scalar field of the elliptic curve or a
|
||||
* stand-alone "STARK field";
|
||||
* @return `cudaSuccess` if the execution was successful and an error code otherwise.
|
||||
*/
|
||||
extern "C" cudaError_t CONCAT_EXPAND(FIELD, poseidon_hash_cuda)(
|
||||
scalar_t* input,
|
||||
scalar_t* output,
|
||||
int number_of_states,
|
||||
int arity,
|
||||
const PoseidonConstants<scalar_t>& constants,
|
||||
PoseidonConfig& config)
|
||||
{
|
||||
switch (arity) {
|
||||
case 2:
|
||||
return poseidon_hash<scalar_t, 3>(input, output, number_of_states, constants, config);
|
||||
case 4:
|
||||
return poseidon_hash<scalar_t, 5>(input, output, number_of_states, constants, config);
|
||||
case 8:
|
||||
return poseidon_hash<scalar_t, 9>(input, output, number_of_states, constants, config);
|
||||
case 11:
|
||||
return poseidon_hash<scalar_t, 12>(input, output, number_of_states, constants, config);
|
||||
default:
|
||||
THROW_ICICLE_ERR(IcicleError_t::InvalidArgument, "PoseidonHash: #arity must be one of [2, 4, 8, 11]");
|
||||
}
|
||||
return CHK_LAST();
|
||||
}
|
||||
|
||||
extern "C" cudaError_t CONCAT_EXPAND(FIELD, create_optimized_poseidon_constants_cuda)(
|
||||
int arity,
|
||||
int full_rounds_half,
|
||||
int partial_rounds,
|
||||
const scalar_t* constants,
|
||||
device_context::DeviceContext& ctx,
|
||||
PoseidonConstants<scalar_t>* poseidon_constants)
|
||||
{
|
||||
return create_optimized_poseidon_constants<scalar_t>(
|
||||
arity, full_rounds_half, partial_rounds, constants, ctx, poseidon_constants);
|
||||
}
|
||||
|
||||
extern "C" cudaError_t CONCAT_EXPAND(FIELD, init_optimized_poseidon_constants_cuda)(
|
||||
int arity, device_context::DeviceContext& ctx, PoseidonConstants<scalar_t>* constants)
|
||||
{
|
||||
return init_optimized_poseidon_constants<scalar_t>(arity, ctx, constants);
|
||||
}
|
||||
} // namespace poseidon
|
||||
@@ -3,7 +3,6 @@
|
||||
using namespace field_config;
|
||||
|
||||
#include "poseidon/poseidon.cuh"
|
||||
#include "constants.cu"
|
||||
#include "kernels.cu"
|
||||
|
||||
namespace poseidon {
|
||||
@@ -88,27 +87,4 @@ namespace poseidon {
|
||||
if (!config.is_async) return CHK_STICKY(cudaStreamSynchronize(stream));
|
||||
return CHK_LAST();
|
||||
}
|
||||
|
||||
extern "C" cudaError_t CONCAT_EXPAND(FIELD, poseidon_hash_cuda)(
|
||||
scalar_t* input,
|
||||
scalar_t* output,
|
||||
int number_of_states,
|
||||
int arity,
|
||||
const PoseidonConstants<scalar_t>& constants,
|
||||
PoseidonConfig& config)
|
||||
{
|
||||
switch (arity) {
|
||||
case 2:
|
||||
return poseidon_hash<scalar_t, 3>(input, output, number_of_states, constants, config);
|
||||
case 4:
|
||||
return poseidon_hash<scalar_t, 5>(input, output, number_of_states, constants, config);
|
||||
case 8:
|
||||
return poseidon_hash<scalar_t, 9>(input, output, number_of_states, constants, config);
|
||||
case 11:
|
||||
return poseidon_hash<scalar_t, 12>(input, output, number_of_states, constants, config);
|
||||
default:
|
||||
THROW_ICICLE_ERR(IcicleError_t::InvalidArgument, "PoseidonHash: #arity must be one of [2, 4, 8, 11]");
|
||||
}
|
||||
return CHK_LAST();
|
||||
}
|
||||
} // namespace poseidon
|
||||
94
wrappers/golang/core/poseidon.go
Normal file
94
wrappers/golang/core/poseidon.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
)
|
||||
|
||||
type PoseidonConfig struct {
|
||||
/// Details related to the device such as its id and stream id. See [DeviceContext](@ref device_context::DeviceContext).
|
||||
Ctx cr.DeviceContext
|
||||
areInputsOnDevice bool
|
||||
areOutputsOnDevice bool
|
||||
///If true, input is considered to be a states vector, holding the preimages in aligned or not aligned format.
|
||||
///Memory under the input pointer will be used for states. If false, fresh states memory will be allocated and input will be copied into it */
|
||||
InputIsAState bool
|
||||
/// If true - input should be already aligned for poseidon permutation.
|
||||
///* Aligned format: [0, A, B, 0, C, D, ...] (as you might get by using loop_state)
|
||||
///* not aligned format: [A, B, 0, C, D, 0, ...] (as you might get from cudaMemcpy2D) */
|
||||
Aligned bool
|
||||
///If true, hash results will also be copied in the input pointer in aligned format
|
||||
LoopState bool
|
||||
///Whether to run the Poseidon asynchronously. If set to `true`, the poseidon_hash function will be
|
||||
///non-blocking and you'd need to synchronize it explicitly by running `cudaStreamSynchronize` or `cudaDeviceSynchronize`.
|
||||
///If set to false, the poseidon_hash function will block the current CPU thread. */
|
||||
IsAsync bool
|
||||
}
|
||||
|
||||
type PoseidonConstants[T any] struct {
|
||||
Arity int32
|
||||
PartialRounds int32
|
||||
FullRoundsHalf int32
|
||||
RoundConstants unsafe.Pointer
|
||||
MdsMatrix unsafe.Pointer
|
||||
NonSparseMatrix unsafe.Pointer
|
||||
SparseMatrices unsafe.Pointer
|
||||
DomainTag T
|
||||
}
|
||||
|
||||
func GetDefaultPoseidonConfig() PoseidonConfig {
|
||||
ctx, _ := cr.GetDefaultDeviceContext()
|
||||
return PoseidonConfig{
|
||||
ctx, // Ctx
|
||||
false, // areInputsOnDevice
|
||||
false, // areOutputsOnDevice
|
||||
false, // inputIsAState
|
||||
false, // aligned
|
||||
false, // loopState
|
||||
false, // IsAsync
|
||||
}
|
||||
}
|
||||
|
||||
func PoseidonCheck[T any](input, output HostOrDeviceSlice, cfg *PoseidonConfig, constants *PoseidonConstants[T], numberOfStates int) (unsafe.Pointer, unsafe.Pointer, unsafe.Pointer) {
|
||||
inputLen, outputLen := input.Len(), output.Len()
|
||||
arity := int(constants.Arity)
|
||||
expectedInputLen := arity * numberOfStates
|
||||
if cfg.InputIsAState {
|
||||
expectedInputLen += numberOfStates
|
||||
}
|
||||
|
||||
if inputLen != expectedInputLen {
|
||||
errorString := fmt.Sprintf(
|
||||
"input is not the right length for the given parameters: %d, should be: %d",
|
||||
inputLen,
|
||||
arity*numberOfStates,
|
||||
)
|
||||
panic(errorString)
|
||||
}
|
||||
|
||||
if outputLen != numberOfStates {
|
||||
errorString := fmt.Sprintf(
|
||||
"output is not the right length for the given parameters: %d, should be: %d",
|
||||
outputLen,
|
||||
numberOfStates,
|
||||
)
|
||||
panic(errorString)
|
||||
}
|
||||
cfg.areInputsOnDevice = input.IsOnDevice()
|
||||
cfg.areOutputsOnDevice = output.IsOnDevice()
|
||||
|
||||
if input.IsOnDevice() {
|
||||
input.(DeviceSlice).CheckDevice()
|
||||
|
||||
}
|
||||
|
||||
if output.IsOnDevice() {
|
||||
output.(DeviceSlice).CheckDevice()
|
||||
}
|
||||
|
||||
cfgPointer := unsafe.Pointer(cfg)
|
||||
|
||||
return input.AsUnsafePointer(), output.AsUnsafePointer(), cfgPointer
|
||||
}
|
||||
@@ -5,10 +5,9 @@ package g2
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func G2GetDefaultMSMConfig() core.MSMConfig {
|
||||
|
||||
@@ -5,10 +5,9 @@ package msm
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func GetDefaultMSMConfig() core.MSMConfig {
|
||||
|
||||
@@ -5,13 +5,15 @@ package ntt
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
bls12_377 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12377"
|
||||
)
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func Ntt[T any](scalars core.HostOrDeviceSlice, dir core.NTTDir, cfg *core.NTTConfig[T], results core.HostOrDeviceSlice) core.IcicleError {
|
||||
scalarsPointer, resultsPointer, size, cfgPointer := core.NttCheck[T](scalars, cfg, results)
|
||||
|
||||
|
||||
25
wrappers/golang/curves/bls12377/poseidon/include/poseidon.h
Normal file
25
wrappers/golang/curves/bls12377/poseidon/include/poseidon.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_377_POSEIDON_H
|
||||
#define _BLS12_377_POSEIDON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct scalar_t scalar_t;
|
||||
typedef struct PoseidonConfig PoseidonConfig;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
typedef struct PoseidonConstants PoseidonConstants;
|
||||
|
||||
|
||||
cudaError_t bls12_377_poseidon_hash_cuda(const scalar_t* input, scalar_t* output, int number_of_states, int arity, PoseidonConstants* constants, PoseidonConfig* config);
|
||||
cudaError_t bls12_377_create_optimized_poseidon_constants_cuda(int arity, int full_rounds_halfs, int partial_rounds, const scalar_t* constants, DeviceContext* ctx, PoseidonConstants* poseidon_constants);
|
||||
cudaError_t bls12_377_init_optimized_poseidon_constants_cuda(int arity, DeviceContext* ctx, PoseidonConstants* constants);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
57
wrappers/golang/curves/bls12377/poseidon/poseidon.go
Normal file
57
wrappers/golang/curves/bls12377/poseidon/poseidon.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package poseidon
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "poseidon.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
)
|
||||
|
||||
func GetDefaultPoseidonConfig() core.PoseidonConfig {
|
||||
return core.GetDefaultPoseidonConfig()
|
||||
}
|
||||
|
||||
func PoseidonHash[T any](scalars, results core.HostOrDeviceSlice, numberOfStates int, cfg *core.PoseidonConfig, constants *core.PoseidonConstants[T]) core.IcicleError {
|
||||
scalarsPointer, resultsPointer, cfgPointer := core.PoseidonCheck(scalars, results, cfg, constants, numberOfStates)
|
||||
|
||||
cScalars := (*C.scalar_t)(scalarsPointer)
|
||||
cResults := (*C.scalar_t)(resultsPointer)
|
||||
cNumberOfStates := (C.int)(numberOfStates)
|
||||
cArity := (C.int)(constants.Arity)
|
||||
cConstants := (*C.PoseidonConstants)(unsafe.Pointer(constants))
|
||||
cCfg := (*C.PoseidonConfig)(cfgPointer)
|
||||
|
||||
__ret := C.bls12_377_poseidon_hash_cuda(cScalars, cResults, cNumberOfStates, cArity, cConstants, cCfg)
|
||||
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func CreateOptimizedPoseidonConstants[T any](arity, fullRoundsHalfs, partialRounds int, constants core.HostOrDeviceSlice, ctx cr.DeviceContext, poseidonConstants *core.PoseidonConstants[T]) core.IcicleError {
|
||||
|
||||
cArity := (C.int)(arity)
|
||||
cFullRoundsHalfs := (C.int)(fullRoundsHalfs)
|
||||
cPartialRounds := (C.int)(partialRounds)
|
||||
cConstants := (*C.scalar_t)(constants.AsUnsafePointer())
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
cPoseidonConstants := (*C.PoseidonConstants)(unsafe.Pointer(poseidonConstants))
|
||||
|
||||
__ret := C.bls12_377_create_optimized_poseidon_constants_cuda(cArity, cFullRoundsHalfs, cPartialRounds, cConstants, cCtx, cPoseidonConstants)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func InitOptimizedPoseidonConstantsCuda[T any](arity int, ctx cr.DeviceContext, constants *core.PoseidonConstants[T]) core.IcicleError {
|
||||
|
||||
cArity := (C.int)(arity)
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
cConstants := (*C.PoseidonConstants)(unsafe.Pointer(constants))
|
||||
|
||||
__ret := C.bls12_377_init_optimized_poseidon_constants_cuda(cArity, cCtx, cConstants)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
@@ -6,10 +6,9 @@ import "C"
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
bls12_377 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12377"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
bls12_377 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12377"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAffineZero(t *testing.T) {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12377/g2"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestG2AffineZero(t *testing.T) {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
bls12_377 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12377/g2"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
bls12_377 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12377"
|
||||
|
||||
// "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12377/ntt"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12377/polynomial"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12377/vecOps"
|
||||
|
||||
42
wrappers/golang/curves/bls12377/tests/poseidon_test.go
Normal file
42
wrappers/golang/curves/bls12377/tests/poseidon_test.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
core "github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
bls12_377 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12377"
|
||||
poseidon "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12377/poseidon"
|
||||
)
|
||||
|
||||
func TestPoseidon(t *testing.T) {
|
||||
|
||||
arity := 2
|
||||
numberOfStates := 1
|
||||
|
||||
cfg := poseidon.GetDefaultPoseidonConfig()
|
||||
cfg.IsAsync = true
|
||||
stream, _ := cr.CreateStream()
|
||||
cfg.Ctx.Stream = &stream
|
||||
|
||||
var constants core.PoseidonConstants[bls12_377.ScalarField]
|
||||
|
||||
poseidon.InitOptimizedPoseidonConstantsCuda(arity, cfg.Ctx, &constants) //generate constants
|
||||
|
||||
scalars := bls12_377.GenerateScalars(numberOfStates * arity)
|
||||
scalars[0] = scalars[0].Zero()
|
||||
scalars[1] = scalars[0].Zero()
|
||||
|
||||
scalarsCopy := core.HostSliceFromElements(scalars[:numberOfStates*arity])
|
||||
|
||||
var deviceInput core.DeviceSlice
|
||||
scalarsCopy.CopyToDeviceAsync(&deviceInput, stream, true)
|
||||
var deviceOutput core.DeviceSlice
|
||||
deviceOutput.MallocAsync(numberOfStates*scalarsCopy.SizeOfElement(), scalarsCopy.SizeOfElement(), stream)
|
||||
|
||||
poseidon.PoseidonHash(deviceInput, deviceOutput, numberOfStates, &cfg, &constants) //run Hash function
|
||||
|
||||
output := make(core.HostSlice[bls12_377.ScalarField], numberOfStates)
|
||||
output.CopyFromDeviceAsync(&deviceOutput, stream)
|
||||
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
bls12_377 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12377"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -5,10 +5,9 @@ package g2
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func G2GetDefaultMSMConfig() core.MSMConfig {
|
||||
|
||||
@@ -5,10 +5,9 @@ package msm
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func GetDefaultMSMConfig() core.MSMConfig {
|
||||
|
||||
@@ -5,13 +5,15 @@ package ntt
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
bls12_381 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12381"
|
||||
)
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func Ntt[T any](scalars core.HostOrDeviceSlice, dir core.NTTDir, cfg *core.NTTConfig[T], results core.HostOrDeviceSlice) core.IcicleError {
|
||||
scalarsPointer, resultsPointer, size, cfgPointer := core.NttCheck[T](scalars, cfg, results)
|
||||
|
||||
|
||||
25
wrappers/golang/curves/bls12381/poseidon/include/poseidon.h
Normal file
25
wrappers/golang/curves/bls12381/poseidon/include/poseidon.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_381_POSEIDON_H
|
||||
#define _BLS12_381_POSEIDON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct scalar_t scalar_t;
|
||||
typedef struct PoseidonConfig PoseidonConfig;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
typedef struct PoseidonConstants PoseidonConstants;
|
||||
|
||||
|
||||
cudaError_t bls12_381_poseidon_hash_cuda(const scalar_t* input, scalar_t* output, int number_of_states, int arity, PoseidonConstants* constants, PoseidonConfig* config);
|
||||
cudaError_t bls12_381_create_optimized_poseidon_constants_cuda(int arity, int full_rounds_halfs, int partial_rounds, const scalar_t* constants, DeviceContext* ctx, PoseidonConstants* poseidon_constants);
|
||||
cudaError_t bls12_381_init_optimized_poseidon_constants_cuda(int arity, DeviceContext* ctx, PoseidonConstants* constants);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
57
wrappers/golang/curves/bls12381/poseidon/poseidon.go
Normal file
57
wrappers/golang/curves/bls12381/poseidon/poseidon.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package poseidon
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "poseidon.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
)
|
||||
|
||||
func GetDefaultPoseidonConfig() core.PoseidonConfig {
|
||||
return core.GetDefaultPoseidonConfig()
|
||||
}
|
||||
|
||||
func PoseidonHash[T any](scalars, results core.HostOrDeviceSlice, numberOfStates int, cfg *core.PoseidonConfig, constants *core.PoseidonConstants[T]) core.IcicleError {
|
||||
scalarsPointer, resultsPointer, cfgPointer := core.PoseidonCheck(scalars, results, cfg, constants, numberOfStates)
|
||||
|
||||
cScalars := (*C.scalar_t)(scalarsPointer)
|
||||
cResults := (*C.scalar_t)(resultsPointer)
|
||||
cNumberOfStates := (C.int)(numberOfStates)
|
||||
cArity := (C.int)(constants.Arity)
|
||||
cConstants := (*C.PoseidonConstants)(unsafe.Pointer(constants))
|
||||
cCfg := (*C.PoseidonConfig)(cfgPointer)
|
||||
|
||||
__ret := C.bls12_381_poseidon_hash_cuda(cScalars, cResults, cNumberOfStates, cArity, cConstants, cCfg)
|
||||
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func CreateOptimizedPoseidonConstants[T any](arity, fullRoundsHalfs, partialRounds int, constants core.HostOrDeviceSlice, ctx cr.DeviceContext, poseidonConstants *core.PoseidonConstants[T]) core.IcicleError {
|
||||
|
||||
cArity := (C.int)(arity)
|
||||
cFullRoundsHalfs := (C.int)(fullRoundsHalfs)
|
||||
cPartialRounds := (C.int)(partialRounds)
|
||||
cConstants := (*C.scalar_t)(constants.AsUnsafePointer())
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
cPoseidonConstants := (*C.PoseidonConstants)(unsafe.Pointer(poseidonConstants))
|
||||
|
||||
__ret := C.bls12_381_create_optimized_poseidon_constants_cuda(cArity, cFullRoundsHalfs, cPartialRounds, cConstants, cCtx, cPoseidonConstants)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func InitOptimizedPoseidonConstantsCuda[T any](arity int, ctx cr.DeviceContext, constants *core.PoseidonConstants[T]) core.IcicleError {
|
||||
|
||||
cArity := (C.int)(arity)
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
cConstants := (*C.PoseidonConstants)(unsafe.Pointer(constants))
|
||||
|
||||
__ret := C.bls12_381_init_optimized_poseidon_constants_cuda(cArity, cCtx, cConstants)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
@@ -6,10 +6,9 @@ import "C"
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
bls12_381 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12381"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
bls12_381 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12381"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAffineZero(t *testing.T) {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12381/g2"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestG2AffineZero(t *testing.T) {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
bls12_381 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12381/g2"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
bls12_381 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12381"
|
||||
|
||||
// "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12381/ntt"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12381/polynomial"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12381/vecOps"
|
||||
|
||||
55
wrappers/golang/curves/bls12381/tests/poseidon_test.go
Normal file
55
wrappers/golang/curves/bls12381/tests/poseidon_test.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
core "github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
bls12_381 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12381"
|
||||
poseidon "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12381/poseidon"
|
||||
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func formatOutput(x bls12_381.ScalarField) string {
|
||||
r := x.GetLimbs()
|
||||
return fmt.Sprintf("%08x%08x%08x%08x%08x%08x%08x%08x", r[7], r[6], r[5], r[4], r[3], r[2], r[1], r[0])
|
||||
}
|
||||
|
||||
func TestPoseidon(t *testing.T) {
|
||||
|
||||
arity := 2
|
||||
numberOfStates := 1
|
||||
|
||||
cfg := poseidon.GetDefaultPoseidonConfig()
|
||||
cfg.IsAsync = true
|
||||
stream, _ := cr.CreateStream()
|
||||
cfg.Ctx.Stream = &stream
|
||||
|
||||
var constants core.PoseidonConstants[bls12_381.ScalarField]
|
||||
|
||||
poseidon.InitOptimizedPoseidonConstantsCuda(arity, cfg.Ctx, &constants) //generate constants
|
||||
|
||||
scalars := bls12_381.GenerateScalars(numberOfStates * arity)
|
||||
scalars[0] = scalars[0].Zero()
|
||||
scalars[1] = scalars[0].Zero()
|
||||
|
||||
scalarsCopy := core.HostSliceFromElements(scalars[:numberOfStates*arity])
|
||||
|
||||
var deviceInput core.DeviceSlice
|
||||
scalarsCopy.CopyToDeviceAsync(&deviceInput, stream, true)
|
||||
var deviceOutput core.DeviceSlice
|
||||
deviceOutput.MallocAsync(numberOfStates*scalarsCopy.SizeOfElement(), scalarsCopy.SizeOfElement(), stream)
|
||||
|
||||
poseidon.PoseidonHash(deviceInput, deviceOutput, numberOfStates, &cfg, &constants) //run Hash function
|
||||
|
||||
output := make(core.HostSlice[bls12_381.ScalarField], numberOfStates)
|
||||
output.CopyFromDeviceAsync(&deviceOutput, stream)
|
||||
|
||||
expectedString := "48fe0b1331196f6cdb33a7c6e5af61b76fd388e1ef1d3d418be5147f0e4613d4" //This result is from https://github.com/triplewz/poseidon
|
||||
outputString := formatOutput(output[0])
|
||||
|
||||
assert.Equal(t, outputString, expectedString, "Poseidon hash does not match expected result")
|
||||
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
bls12_381 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bls12381"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -5,10 +5,9 @@ package g2
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func G2GetDefaultMSMConfig() core.MSMConfig {
|
||||
|
||||
@@ -5,10 +5,9 @@ package msm
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func GetDefaultMSMConfig() core.MSMConfig {
|
||||
|
||||
@@ -5,13 +5,15 @@ package ntt
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
bn254 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254"
|
||||
)
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func Ntt[T any](scalars core.HostOrDeviceSlice, dir core.NTTDir, cfg *core.NTTConfig[T], results core.HostOrDeviceSlice) core.IcicleError {
|
||||
scalarsPointer, resultsPointer, size, cfgPointer := core.NttCheck[T](scalars, cfg, results)
|
||||
|
||||
|
||||
25
wrappers/golang/curves/bn254/poseidon/include/poseidon.h
Normal file
25
wrappers/golang/curves/bn254/poseidon/include/poseidon.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BN254_POSEIDON_H
|
||||
#define _BN254_POSEIDON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct scalar_t scalar_t;
|
||||
typedef struct PoseidonConfig PoseidonConfig;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
typedef struct PoseidonConstants PoseidonConstants;
|
||||
|
||||
|
||||
cudaError_t bn254_poseidon_hash_cuda(const scalar_t* input, scalar_t* output, int number_of_states, int arity, PoseidonConstants* constants, PoseidonConfig* config);
|
||||
cudaError_t bn254_create_optimized_poseidon_constants_cuda(int arity, int full_rounds_halfs, int partial_rounds, const scalar_t* constants, DeviceContext* ctx, PoseidonConstants* poseidon_constants);
|
||||
cudaError_t bn254_init_optimized_poseidon_constants_cuda(int arity, DeviceContext* ctx, PoseidonConstants* constants);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
57
wrappers/golang/curves/bn254/poseidon/poseidon.go
Normal file
57
wrappers/golang/curves/bn254/poseidon/poseidon.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package poseidon
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "poseidon.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
)
|
||||
|
||||
func GetDefaultPoseidonConfig() core.PoseidonConfig {
|
||||
return core.GetDefaultPoseidonConfig()
|
||||
}
|
||||
|
||||
func PoseidonHash[T any](scalars, results core.HostOrDeviceSlice, numberOfStates int, cfg *core.PoseidonConfig, constants *core.PoseidonConstants[T]) core.IcicleError {
|
||||
scalarsPointer, resultsPointer, cfgPointer := core.PoseidonCheck(scalars, results, cfg, constants, numberOfStates)
|
||||
|
||||
cScalars := (*C.scalar_t)(scalarsPointer)
|
||||
cResults := (*C.scalar_t)(resultsPointer)
|
||||
cNumberOfStates := (C.int)(numberOfStates)
|
||||
cArity := (C.int)(constants.Arity)
|
||||
cConstants := (*C.PoseidonConstants)(unsafe.Pointer(constants))
|
||||
cCfg := (*C.PoseidonConfig)(cfgPointer)
|
||||
|
||||
__ret := C.bn254_poseidon_hash_cuda(cScalars, cResults, cNumberOfStates, cArity, cConstants, cCfg)
|
||||
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func CreateOptimizedPoseidonConstants[T any](arity, fullRoundsHalfs, partialRounds int, constants core.HostOrDeviceSlice, ctx cr.DeviceContext, poseidonConstants *core.PoseidonConstants[T]) core.IcicleError {
|
||||
|
||||
cArity := (C.int)(arity)
|
||||
cFullRoundsHalfs := (C.int)(fullRoundsHalfs)
|
||||
cPartialRounds := (C.int)(partialRounds)
|
||||
cConstants := (*C.scalar_t)(constants.AsUnsafePointer())
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
cPoseidonConstants := (*C.PoseidonConstants)(unsafe.Pointer(poseidonConstants))
|
||||
|
||||
__ret := C.bn254_create_optimized_poseidon_constants_cuda(cArity, cFullRoundsHalfs, cPartialRounds, cConstants, cCtx, cPoseidonConstants)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func InitOptimizedPoseidonConstantsCuda[T any](arity int, ctx cr.DeviceContext, constants *core.PoseidonConstants[T]) core.IcicleError {
|
||||
|
||||
cArity := (C.int)(arity)
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
cConstants := (*C.PoseidonConstants)(unsafe.Pointer(constants))
|
||||
|
||||
__ret := C.bn254_init_optimized_poseidon_constants_cuda(cArity, cCtx, cConstants)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
@@ -6,10 +6,9 @@ import "C"
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
bn254 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
bn254 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAffineZero(t *testing.T) {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254/g2"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestG2AffineZero(t *testing.T) {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
bn254 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254/g2"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
bn254 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254"
|
||||
|
||||
// "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254/ntt"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254/polynomial"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254/vecOps"
|
||||
|
||||
42
wrappers/golang/curves/bn254/tests/poseidon_test.go
Normal file
42
wrappers/golang/curves/bn254/tests/poseidon_test.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
core "github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
bn254 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254"
|
||||
poseidon "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254/poseidon"
|
||||
)
|
||||
|
||||
func TestPoseidon(t *testing.T) {
|
||||
|
||||
arity := 2
|
||||
numberOfStates := 1
|
||||
|
||||
cfg := poseidon.GetDefaultPoseidonConfig()
|
||||
cfg.IsAsync = true
|
||||
stream, _ := cr.CreateStream()
|
||||
cfg.Ctx.Stream = &stream
|
||||
|
||||
var constants core.PoseidonConstants[bn254.ScalarField]
|
||||
|
||||
poseidon.InitOptimizedPoseidonConstantsCuda(arity, cfg.Ctx, &constants) //generate constants
|
||||
|
||||
scalars := bn254.GenerateScalars(numberOfStates * arity)
|
||||
scalars[0] = scalars[0].Zero()
|
||||
scalars[1] = scalars[0].Zero()
|
||||
|
||||
scalarsCopy := core.HostSliceFromElements(scalars[:numberOfStates*arity])
|
||||
|
||||
var deviceInput core.DeviceSlice
|
||||
scalarsCopy.CopyToDeviceAsync(&deviceInput, stream, true)
|
||||
var deviceOutput core.DeviceSlice
|
||||
deviceOutput.MallocAsync(numberOfStates*scalarsCopy.SizeOfElement(), scalarsCopy.SizeOfElement(), stream)
|
||||
|
||||
poseidon.PoseidonHash(deviceInput, deviceOutput, numberOfStates, &cfg, &constants) //run Hash function
|
||||
|
||||
output := make(core.HostSlice[bn254.ScalarField], numberOfStates)
|
||||
output.CopyFromDeviceAsync(&deviceOutput, stream)
|
||||
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
bn254 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bn254"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -5,10 +5,9 @@ package g2
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func G2GetDefaultMSMConfig() core.MSMConfig {
|
||||
|
||||
@@ -5,10 +5,9 @@ package msm
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func GetDefaultMSMConfig() core.MSMConfig {
|
||||
|
||||
@@ -5,13 +5,15 @@ package ntt
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
bw6_761 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bw6761"
|
||||
)
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func Ntt[T any](scalars core.HostOrDeviceSlice, dir core.NTTDir, cfg *core.NTTConfig[T], results core.HostOrDeviceSlice) core.IcicleError {
|
||||
scalarsPointer, resultsPointer, size, cfgPointer := core.NttCheck[T](scalars, cfg, results)
|
||||
|
||||
|
||||
25
wrappers/golang/curves/bw6761/poseidon/include/poseidon.h
Normal file
25
wrappers/golang/curves/bw6761/poseidon/include/poseidon.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BW6_761_POSEIDON_H
|
||||
#define _BW6_761_POSEIDON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct scalar_t scalar_t;
|
||||
typedef struct PoseidonConfig PoseidonConfig;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
typedef struct PoseidonConstants PoseidonConstants;
|
||||
|
||||
|
||||
cudaError_t bw6_761_poseidon_hash_cuda(const scalar_t* input, scalar_t* output, int number_of_states, int arity, PoseidonConstants* constants, PoseidonConfig* config);
|
||||
cudaError_t bw6_761_create_optimized_poseidon_constants_cuda(int arity, int full_rounds_halfs, int partial_rounds, const scalar_t* constants, DeviceContext* ctx, PoseidonConstants* poseidon_constants);
|
||||
cudaError_t bw6_761_init_optimized_poseidon_constants_cuda(int arity, DeviceContext* ctx, PoseidonConstants* constants);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
57
wrappers/golang/curves/bw6761/poseidon/poseidon.go
Normal file
57
wrappers/golang/curves/bw6761/poseidon/poseidon.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package poseidon
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "poseidon.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
)
|
||||
|
||||
func GetDefaultPoseidonConfig() core.PoseidonConfig {
|
||||
return core.GetDefaultPoseidonConfig()
|
||||
}
|
||||
|
||||
func PoseidonHash[T any](scalars, results core.HostOrDeviceSlice, numberOfStates int, cfg *core.PoseidonConfig, constants *core.PoseidonConstants[T]) core.IcicleError {
|
||||
scalarsPointer, resultsPointer, cfgPointer := core.PoseidonCheck(scalars, results, cfg, constants, numberOfStates)
|
||||
|
||||
cScalars := (*C.scalar_t)(scalarsPointer)
|
||||
cResults := (*C.scalar_t)(resultsPointer)
|
||||
cNumberOfStates := (C.int)(numberOfStates)
|
||||
cArity := (C.int)(constants.Arity)
|
||||
cConstants := (*C.PoseidonConstants)(unsafe.Pointer(constants))
|
||||
cCfg := (*C.PoseidonConfig)(cfgPointer)
|
||||
|
||||
__ret := C.bw6_761_poseidon_hash_cuda(cScalars, cResults, cNumberOfStates, cArity, cConstants, cCfg)
|
||||
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func CreateOptimizedPoseidonConstants[T any](arity, fullRoundsHalfs, partialRounds int, constants core.HostOrDeviceSlice, ctx cr.DeviceContext, poseidonConstants *core.PoseidonConstants[T]) core.IcicleError {
|
||||
|
||||
cArity := (C.int)(arity)
|
||||
cFullRoundsHalfs := (C.int)(fullRoundsHalfs)
|
||||
cPartialRounds := (C.int)(partialRounds)
|
||||
cConstants := (*C.scalar_t)(constants.AsUnsafePointer())
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
cPoseidonConstants := (*C.PoseidonConstants)(unsafe.Pointer(poseidonConstants))
|
||||
|
||||
__ret := C.bw6_761_create_optimized_poseidon_constants_cuda(cArity, cFullRoundsHalfs, cPartialRounds, cConstants, cCtx, cPoseidonConstants)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func InitOptimizedPoseidonConstantsCuda[T any](arity int, ctx cr.DeviceContext, constants *core.PoseidonConstants[T]) core.IcicleError {
|
||||
|
||||
cArity := (C.int)(arity)
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
cConstants := (*C.PoseidonConstants)(unsafe.Pointer(constants))
|
||||
|
||||
__ret := C.bw6_761_init_optimized_poseidon_constants_cuda(cArity, cCtx, cConstants)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
@@ -6,10 +6,9 @@ import "C"
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
bw6_761 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bw6761"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
bw6_761 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bw6761"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAffineZero(t *testing.T) {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bw6761/g2"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestG2AffineZero(t *testing.T) {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
bw6_761 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bw6761/g2"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
bw6_761 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bw6761"
|
||||
|
||||
// "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bw6761/ntt"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bw6761/polynomial"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bw6761/vecOps"
|
||||
|
||||
42
wrappers/golang/curves/bw6761/tests/poseidon_test.go
Normal file
42
wrappers/golang/curves/bw6761/tests/poseidon_test.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
core "github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
bw6_761 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bw6761"
|
||||
poseidon "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bw6761/poseidon"
|
||||
)
|
||||
|
||||
func TestPoseidon(t *testing.T) {
|
||||
|
||||
arity := 2
|
||||
numberOfStates := 1
|
||||
|
||||
cfg := poseidon.GetDefaultPoseidonConfig()
|
||||
cfg.IsAsync = true
|
||||
stream, _ := cr.CreateStream()
|
||||
cfg.Ctx.Stream = &stream
|
||||
|
||||
var constants core.PoseidonConstants[bw6_761.ScalarField]
|
||||
|
||||
poseidon.InitOptimizedPoseidonConstantsCuda(arity, cfg.Ctx, &constants) //generate constants
|
||||
|
||||
scalars := bw6_761.GenerateScalars(numberOfStates * arity)
|
||||
scalars[0] = scalars[0].Zero()
|
||||
scalars[1] = scalars[0].Zero()
|
||||
|
||||
scalarsCopy := core.HostSliceFromElements(scalars[:numberOfStates*arity])
|
||||
|
||||
var deviceInput core.DeviceSlice
|
||||
scalarsCopy.CopyToDeviceAsync(&deviceInput, stream, true)
|
||||
var deviceOutput core.DeviceSlice
|
||||
deviceOutput.MallocAsync(numberOfStates*scalarsCopy.SizeOfElement(), scalarsCopy.SizeOfElement(), stream)
|
||||
|
||||
poseidon.PoseidonHash(deviceInput, deviceOutput, numberOfStates, &cfg, &constants) //run Hash function
|
||||
|
||||
output := make(core.HostSlice[bw6_761.ScalarField], numberOfStates)
|
||||
output.CopyFromDeviceAsync(&deviceOutput, stream)
|
||||
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
bw6_761 "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/bw6761"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -5,10 +5,9 @@ package msm
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func GetDefaultMSMConfig() core.MSMConfig {
|
||||
|
||||
25
wrappers/golang/curves/grumpkin/poseidon/include/poseidon.h
Normal file
25
wrappers/golang/curves/grumpkin/poseidon/include/poseidon.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _GRUMPKIN_POSEIDON_H
|
||||
#define _GRUMPKIN_POSEIDON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct scalar_t scalar_t;
|
||||
typedef struct PoseidonConfig PoseidonConfig;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
typedef struct PoseidonConstants PoseidonConstants;
|
||||
|
||||
|
||||
cudaError_t grumpkin_poseidon_hash_cuda(const scalar_t* input, scalar_t* output, int number_of_states, int arity, PoseidonConstants* constants, PoseidonConfig* config);
|
||||
cudaError_t grumpkin_create_optimized_poseidon_constants_cuda(int arity, int full_rounds_halfs, int partial_rounds, const scalar_t* constants, DeviceContext* ctx, PoseidonConstants* poseidon_constants);
|
||||
cudaError_t grumpkin_init_optimized_poseidon_constants_cuda(int arity, DeviceContext* ctx, PoseidonConstants* constants);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
57
wrappers/golang/curves/grumpkin/poseidon/poseidon.go
Normal file
57
wrappers/golang/curves/grumpkin/poseidon/poseidon.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package poseidon
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "poseidon.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
)
|
||||
|
||||
func GetDefaultPoseidonConfig() core.PoseidonConfig {
|
||||
return core.GetDefaultPoseidonConfig()
|
||||
}
|
||||
|
||||
func PoseidonHash[T any](scalars, results core.HostOrDeviceSlice, numberOfStates int, cfg *core.PoseidonConfig, constants *core.PoseidonConstants[T]) core.IcicleError {
|
||||
scalarsPointer, resultsPointer, cfgPointer := core.PoseidonCheck(scalars, results, cfg, constants, numberOfStates)
|
||||
|
||||
cScalars := (*C.scalar_t)(scalarsPointer)
|
||||
cResults := (*C.scalar_t)(resultsPointer)
|
||||
cNumberOfStates := (C.int)(numberOfStates)
|
||||
cArity := (C.int)(constants.Arity)
|
||||
cConstants := (*C.PoseidonConstants)(unsafe.Pointer(constants))
|
||||
cCfg := (*C.PoseidonConfig)(cfgPointer)
|
||||
|
||||
__ret := C.grumpkin_poseidon_hash_cuda(cScalars, cResults, cNumberOfStates, cArity, cConstants, cCfg)
|
||||
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func CreateOptimizedPoseidonConstants[T any](arity, fullRoundsHalfs, partialRounds int, constants core.HostOrDeviceSlice, ctx cr.DeviceContext, poseidonConstants *core.PoseidonConstants[T]) core.IcicleError {
|
||||
|
||||
cArity := (C.int)(arity)
|
||||
cFullRoundsHalfs := (C.int)(fullRoundsHalfs)
|
||||
cPartialRounds := (C.int)(partialRounds)
|
||||
cConstants := (*C.scalar_t)(constants.AsUnsafePointer())
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
cPoseidonConstants := (*C.PoseidonConstants)(unsafe.Pointer(poseidonConstants))
|
||||
|
||||
__ret := C.grumpkin_create_optimized_poseidon_constants_cuda(cArity, cFullRoundsHalfs, cPartialRounds, cConstants, cCtx, cPoseidonConstants)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func InitOptimizedPoseidonConstantsCuda[T any](arity int, ctx cr.DeviceContext, constants *core.PoseidonConstants[T]) core.IcicleError {
|
||||
|
||||
cArity := (C.int)(arity)
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
cConstants := (*C.PoseidonConstants)(unsafe.Pointer(constants))
|
||||
|
||||
__ret := C.grumpkin_init_optimized_poseidon_constants_cuda(cArity, cCtx, cConstants)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
@@ -6,10 +6,9 @@ import "C"
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
grumpkin "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/grumpkin"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
grumpkin "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/grumpkin"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAffineZero(t *testing.T) {
|
||||
|
||||
42
wrappers/golang/curves/grumpkin/tests/poseidon_test.go
Normal file
42
wrappers/golang/curves/grumpkin/tests/poseidon_test.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
core "github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
grumpkin "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/grumpkin"
|
||||
poseidon "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/grumpkin/poseidon"
|
||||
)
|
||||
|
||||
func TestPoseidon(t *testing.T) {
|
||||
|
||||
arity := 2
|
||||
numberOfStates := 1
|
||||
|
||||
cfg := poseidon.GetDefaultPoseidonConfig()
|
||||
cfg.IsAsync = true
|
||||
stream, _ := cr.CreateStream()
|
||||
cfg.Ctx.Stream = &stream
|
||||
|
||||
var constants core.PoseidonConstants[grumpkin.ScalarField]
|
||||
|
||||
poseidon.InitOptimizedPoseidonConstantsCuda(arity, cfg.Ctx, &constants) //generate constants
|
||||
|
||||
scalars := grumpkin.GenerateScalars(numberOfStates * arity)
|
||||
scalars[0] = scalars[0].Zero()
|
||||
scalars[1] = scalars[0].Zero()
|
||||
|
||||
scalarsCopy := core.HostSliceFromElements(scalars[:numberOfStates*arity])
|
||||
|
||||
var deviceInput core.DeviceSlice
|
||||
scalarsCopy.CopyToDeviceAsync(&deviceInput, stream, true)
|
||||
var deviceOutput core.DeviceSlice
|
||||
deviceOutput.MallocAsync(numberOfStates*scalarsCopy.SizeOfElement(), scalarsCopy.SizeOfElement(), stream)
|
||||
|
||||
poseidon.PoseidonHash(deviceInput, deviceOutput, numberOfStates, &cfg, &constants) //run Hash function
|
||||
|
||||
output := make(core.HostSlice[grumpkin.ScalarField], numberOfStates)
|
||||
output.CopyFromDeviceAsync(&deviceOutput, stream)
|
||||
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
grumpkin "github.com/ingonyama-zk/icicle/v2/wrappers/golang/curves/grumpkin"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -6,10 +6,9 @@ import "C"
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -5,13 +5,15 @@ package ntt
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
babybear "github.com/ingonyama-zk/icicle/v2/wrappers/golang/fields/babybear"
|
||||
)
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func Ntt[T any](scalars core.HostOrDeviceSlice, dir core.NTTDir, cfg *core.NTTConfig[T], results core.HostOrDeviceSlice) core.IcicleError {
|
||||
scalarsPointer, resultsPointer, size, cfgPointer := core.NttCheck[T](scalars, cfg, results)
|
||||
|
||||
|
||||
@@ -6,10 +6,9 @@ import "C"
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
babybear_extension "github.com/ingonyama-zk/icicle/v2/wrappers/golang/fields/babybear/extension"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
babybear "github.com/ingonyama-zk/icicle/v2/wrappers/golang/fields/babybear"
|
||||
|
||||
// "github.com/ingonyama-zk/icicle/v2/wrappers/golang/fields/babybear/ntt"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/fields/babybear/polynomial"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/fields/babybear/vecOps"
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
babybear "github.com/ingonyama-zk/icicle/v2/wrappers/golang/fields/babybear"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
msm "github.com/ingonyama-zk/icicle/v2/wrappers/golang/internal/generator/msm"
|
||||
ntt "github.com/ingonyama-zk/icicle/v2/wrappers/golang/internal/generator/ntt"
|
||||
poly "github.com/ingonyama-zk/icicle/v2/wrappers/golang/internal/generator/polynomial"
|
||||
poseidon "github.com/ingonyama-zk/icicle/v2/wrappers/golang/internal/generator/poseidon"
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/internal/generator/tests"
|
||||
vecops "github.com/ingonyama-zk/icicle/v2/wrappers/golang/internal/generator/vecOps"
|
||||
)
|
||||
@@ -43,6 +44,7 @@ func generateFiles() {
|
||||
}
|
||||
|
||||
msm.Generate(curveDir, "msm", curve.Curve, "", curve.GnarkImport)
|
||||
poseidon.Generate(curveDir, "", curve.Curve, scalarFieldPrefix)
|
||||
if curve.SupportsG2 {
|
||||
g2BaseDir := path.Join(curveDir, "g2")
|
||||
packageName := "g2"
|
||||
|
||||
32
wrappers/golang/internal/generator/poseidon/generate.go
Normal file
32
wrappers/golang/internal/generator/poseidon/generate.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package poseidon
|
||||
|
||||
import (
|
||||
"path"
|
||||
|
||||
generator "github.com/ingonyama-zk/icicle/v2/wrappers/golang/internal/generator/generator_utils"
|
||||
)
|
||||
|
||||
var poseidonTemplates = map[string]string{
|
||||
"src": "poseidon/templates/poseidon.go.tmpl",
|
||||
"test": "poseidon/templates/poseidon_test.go.tmpl",
|
||||
"header": "poseidon/templates/poseidon.h.tmpl",
|
||||
}
|
||||
|
||||
func Generate(baseDir, additionalDirPath, field, fieldPrefix string) {
|
||||
|
||||
data := struct {
|
||||
PackageName string
|
||||
Field string
|
||||
FieldPrefix string
|
||||
BaseImportPath string
|
||||
}{
|
||||
"poseidon",
|
||||
field,
|
||||
fieldPrefix,
|
||||
baseDir,
|
||||
}
|
||||
|
||||
generator.GenerateFile(poseidonTemplates["src"], path.Join(baseDir, additionalDirPath, "poseidon"), "", "", data)
|
||||
generator.GenerateFile(poseidonTemplates["header"], path.Join(baseDir, additionalDirPath, "poseidon", "include"), "", "", data)
|
||||
generator.GenerateFile(poseidonTemplates["test"], path.Join(baseDir, "tests"), "", "", data)
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package {{.PackageName}}
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "poseidon.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
)
|
||||
|
||||
func GetDefaultPoseidonConfig() core.PoseidonConfig {
|
||||
return core.GetDefaultPoseidonConfig()
|
||||
}
|
||||
|
||||
func PoseidonHash[T any](scalars, results core.HostOrDeviceSlice, numberOfStates int, cfg *core.PoseidonConfig, constants *core.PoseidonConstants[T]) core.IcicleError {
|
||||
scalarsPointer, resultsPointer, cfgPointer := core.PoseidonCheck(scalars, results, cfg, constants, numberOfStates)
|
||||
|
||||
cScalars := (*C.scalar_t)(scalarsPointer)
|
||||
cResults := (*C.scalar_t)(resultsPointer)
|
||||
cNumberOfStates := (C.int)(numberOfStates)
|
||||
cArity := (C.int)(constants.Arity)
|
||||
cConstants := (*C.PoseidonConstants)(unsafe.Pointer(constants))
|
||||
cCfg := (*C.PoseidonConfig)(cfgPointer)
|
||||
|
||||
__ret := C.{{.Field}}_poseidon_hash_cuda(cScalars, cResults, cNumberOfStates, cArity, cConstants, cCfg)
|
||||
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func CreateOptimizedPoseidonConstants[T any](arity, fullRoundsHalfs, partialRounds int, constants core.HostOrDeviceSlice, ctx cr.DeviceContext, poseidonConstants *core.PoseidonConstants[T]) core.IcicleError {
|
||||
|
||||
cArity := (C.int)(arity)
|
||||
cFullRoundsHalfs := (C.int)(fullRoundsHalfs)
|
||||
cPartialRounds := (C.int)(partialRounds)
|
||||
cConstants := (*C.scalar_t)(constants.AsUnsafePointer())
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
cPoseidonConstants := (*C.PoseidonConstants)(unsafe.Pointer(poseidonConstants))
|
||||
|
||||
__ret := C.{{.Field}}_create_optimized_poseidon_constants_cuda(cArity, cFullRoundsHalfs, cPartialRounds, cConstants, cCtx, cPoseidonConstants)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func InitOptimizedPoseidonConstantsCuda[T any](arity int, ctx cr.DeviceContext, constants *core.PoseidonConstants[T]) core.IcicleError {
|
||||
|
||||
cArity := (C.int)(arity)
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
cConstants := (*C.PoseidonConstants)(unsafe.Pointer(constants))
|
||||
|
||||
__ret := C.{{.Field}}_init_optimized_poseidon_constants_cuda(cArity, cCtx, cConstants)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _{{toUpper .Field}}_POSEIDON_H
|
||||
#define _{{toUpper .Field}}_POSEIDON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct scalar_t scalar_t;
|
||||
typedef struct PoseidonConfig PoseidonConfig;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
typedef struct PoseidonConstants PoseidonConstants;
|
||||
|
||||
|
||||
cudaError_t {{.Field}}_poseidon_hash_cuda(const scalar_t* input, scalar_t* output, int number_of_states, int arity, PoseidonConstants* constants, PoseidonConfig* config);
|
||||
cudaError_t {{.Field}}_create_optimized_poseidon_constants_cuda(int arity, int full_rounds_halfs, int partial_rounds, const scalar_t* constants, DeviceContext* ctx, PoseidonConstants* poseidon_constants);
|
||||
cudaError_t {{.Field}}_init_optimized_poseidon_constants_cuda(int arity, DeviceContext* ctx, PoseidonConstants* constants);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
core "github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
|
||||
{{.Field}} "github.com/ingonyama-zk/icicle/v2/wrappers/golang/{{.BaseImportPath}}"
|
||||
poseidon "github.com/ingonyama-zk/icicle/v2/wrappers/golang/{{.BaseImportPath}}/poseidon"
|
||||
|
||||
{{if eq .Field "bls12_381"}}
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
{{end}}
|
||||
)
|
||||
{{if eq .Field "bls12_381"}}
|
||||
func formatOutput(x {{.Field}}.{{.FieldPrefix}}Field) string {
|
||||
r := x.GetLimbs()
|
||||
return fmt.Sprintf("%08x%08x%08x%08x%08x%08x%08x%08x", r[7], r[6], r[5], r[4], r[3], r[2], r[1], r[0])
|
||||
}
|
||||
{{end}}
|
||||
|
||||
func TestPoseidon(t *testing.T) {
|
||||
|
||||
arity := 2
|
||||
numberOfStates := 1
|
||||
|
||||
cfg := poseidon.GetDefaultPoseidonConfig()
|
||||
cfg.IsAsync = true
|
||||
stream, _ := cr.CreateStream()
|
||||
cfg.Ctx.Stream = &stream
|
||||
|
||||
var constants core.PoseidonConstants[{{.Field}}.{{.FieldPrefix}}Field]
|
||||
|
||||
poseidon.InitOptimizedPoseidonConstantsCuda(arity, cfg.Ctx, &constants) //generate constants
|
||||
|
||||
scalars := {{.Field}}.GenerateScalars(numberOfStates * arity)
|
||||
scalars[0] = scalars[0].Zero()
|
||||
scalars[1] = scalars[0].Zero()
|
||||
|
||||
scalarsCopy := core.HostSliceFromElements(scalars[:numberOfStates*arity])
|
||||
|
||||
var deviceInput core.DeviceSlice
|
||||
scalarsCopy.CopyToDeviceAsync(&deviceInput, stream, true)
|
||||
var deviceOutput core.DeviceSlice
|
||||
deviceOutput.MallocAsync(numberOfStates*scalarsCopy.SizeOfElement(), scalarsCopy.SizeOfElement(), stream)
|
||||
|
||||
poseidon.PoseidonHash(deviceInput, deviceOutput, numberOfStates, &cfg, &constants) //run Hash function
|
||||
|
||||
output := make(core.HostSlice[{{.Field}}.{{.FieldPrefix}}Field], numberOfStates)
|
||||
output.CopyFromDeviceAsync(&deviceOutput, stream)
|
||||
|
||||
{{if eq .Field "bls12_381"}}
|
||||
expectedString := "48fe0b1331196f6cdb33a7c6e5af61b76fd388e1ef1d3d418be5147f0e4613d4" //This result is from https://github.com/triplewz/poseidon
|
||||
outputString := formatOutput(output[0])
|
||||
|
||||
assert.Equal(t, outputString, expectedString, "Poseidon hash does not match expected result")
|
||||
{{end}}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ exclude = [
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "2.2.0"
|
||||
version = "2.3.0"
|
||||
edition = "2021"
|
||||
authors = [ "Ingonyama" ]
|
||||
homepage = "https://www.ingonyama.com"
|
||||
|
||||
Reference in New Issue
Block a user