13 releases (6 breaking)

0.7.0 Jun 8, 2023
0.5.2 Mar 3, 2023
0.5.1 Dec 1, 2022
0.5.0 Nov 17, 2022
0.1.2 Nov 16, 2021

#489 in Cryptography

Download history 2993/week @ 2023-12-11 1199/week @ 2023-12-18 431/week @ 2023-12-25 1441/week @ 2024-01-01 2088/week @ 2024-01-08 2540/week @ 2024-01-15 2392/week @ 2024-01-22 2199/week @ 2024-01-29 2003/week @ 2024-02-05 2216/week @ 2024-02-12 2629/week @ 2024-02-19 3035/week @ 2024-02-26 2815/week @ 2024-03-04 2606/week @ 2024-03-11 3259/week @ 2024-03-18 2028/week @ 2024-03-25

10,842 downloads per month
Used in 49 crates (2 directly)

MIT/Apache

98KB
2K SLoC

CUDA/OpenCL code generator for finite-field arithmetic over prime fields and elliptic curve arithmetic constructed with Rust.

There is also support for Fast Fourier Transform and Multiexponentiation.

This crate usually creates GPU kernels at compile-time. CUDA generates a fatbin, which OpenCL only generates the source code, which is then compiled at run-time.

In order to make things easier to use, there are helper functions available. You would put some code into build.rs, that generates the kernels, and some code into your library which then consumes those generated kernels. The kernels will be directly embedded into your program/library. If something goes wrong, you will get an error at compile-time.

In this example we will make use of the FFT functionality. Add to your build.rs:

use blstrs::Scalar;
use ec_gpu_gen::SourceBuilder;

let source_builder = SourceBuilder::new().add_fft::<Scalar>();
ec_gpu_gen::generate(&source_builder);

The ec_gpu_gen::generate() takes care of the actual code generation/compilation. It will automatically create a CUDA and/or OpenCL kernel. It will define two environment variables, which are meant for internal use. _EC_GPU_CUDA_KERNEL_FATBIN that points to the compiled CUDA kernel, and _EC_GPU_OPENCL_KERNEL_SOURCE that points to the generated OpenCL source.

Those variables are then picked up by the ec_gpu_gen::program!() macro, which generates a program, for a given GPU device. Using FFT within your library would then look like this:

use blstrs::Scalar;
use ec_gpu_gen::{
    rust_gpu_tools::Device,
};

let devices = Device::all();
let programs = devices
    .iter()
    .map(|device| ec_gpu_gen::program!(device))
    .collect::<Result<_, _>>()
    .expect("Cannot create programs!");

let mut kern = FftKernel::<Scalar>::create(programs).expect("Cannot initialize kernel!");
kern.radix_fft_many(&mut [&mut coeffs], &[omega], &[log_d]).expect("GPU FFT failed!");

Feature flags

CUDA and OpenCL are supprted, each be enabled with the cuda and opencl feature flags.

Dependencies

~4–13MB
~145K SLoC