mirror of
https://github.com/pseXperiments/icicle.git
synced 2026-01-13 01:17:57 -05:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eced32b28b | ||
|
|
b316e4d4f7 | ||
|
|
b9ab19826a | ||
|
|
e3f9237ceb | ||
|
|
0aef5f2f70 | ||
|
|
396c5f3c7b | ||
|
|
f183dacfd6 | ||
|
|
10a638fba5 | ||
|
|
9e8f0ec8f2 | ||
|
|
53a63bb5ad | ||
|
|
c108f5cc90 | ||
|
|
af90ab0961 | ||
|
|
845a529423 | ||
|
|
071c24ce5a | ||
|
|
08c34a5183 | ||
|
|
c13b003720 | ||
|
|
25a4eebc0a | ||
|
|
e41de7dec7 | ||
|
|
472a9f5107 | ||
|
|
689b4814e1 | ||
|
|
7ace91528a | ||
|
|
e0f5eac3a8 | ||
|
|
55b0faa0f3 |
@@ -1,38 +0,0 @@
|
||||
Language: Cpp
|
||||
AlignAfterOpenBracket: AlwaysBreak
|
||||
AlignConsecutiveMacros: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: true
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: true
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackArguments: true
|
||||
BinPackParameters: false
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterFunction: true
|
||||
BreakBeforeBinaryOperators: false
|
||||
BreakBeforeTernaryOperators: true
|
||||
ColumnLimit: 120
|
||||
ContinuationIndentWidth: 2
|
||||
Cpp11BracedListStyle: true
|
||||
DisableFormat: false
|
||||
IndentFunctionDeclarationAfterType: false
|
||||
IndentWidth: 2
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: All
|
||||
PointerAlignment: Left
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
Standard: c++17
|
||||
UseTab: Never
|
||||
@@ -4,4 +4,4 @@ This PR...
|
||||
|
||||
## Linked Issues
|
||||
|
||||
Resolves #
|
||||
Closes #
|
||||
40
.github/workflows/build-dev.yml
vendored
40
.github/workflows/build-dev.yml
vendored
@@ -1,40 +0,0 @@
|
||||
name: Build Dev
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- dev
|
||||
paths:
|
||||
- icicle/**
|
||||
- src/**
|
||||
- Cargo.toml
|
||||
- build.rs
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
ARCH_TYPE: sm_70
|
||||
|
||||
jobs:
|
||||
build-linux:
|
||||
runs-on: [self-hosted, Linux, X64, icicle]
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v3
|
||||
- name: Build
|
||||
run: cargo build --release --verbose
|
||||
|
||||
|
||||
build-windows:
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v3
|
||||
- name: Download and Install Cuda
|
||||
uses: Jimver/cuda-toolkit@v0.2.11
|
||||
with:
|
||||
cuda: '12.0.0'
|
||||
method: 'network'
|
||||
# https://docs.nvidia.com/cuda/archive/12.0.0/cuda-installation-guide-microsoft-windows/index.html
|
||||
sub-packages: '["cudart", "nvcc", "thrust"]'
|
||||
- name: Build
|
||||
run: cargo build --release --verbose
|
||||
47
.github/workflows/build.yml
vendored
47
.github/workflows/build.yml
vendored
@@ -1,17 +1,13 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- ready_for_review
|
||||
- opened
|
||||
branches:
|
||||
- main
|
||||
branches: [ "main" ]
|
||||
paths:
|
||||
- icicle/**
|
||||
- src/**
|
||||
- Cargo.toml
|
||||
- build.rs
|
||||
- "icicle/**"
|
||||
- "src/**"
|
||||
- "Cargo.toml"
|
||||
- "build.rs"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
@@ -19,25 +15,32 @@ env:
|
||||
|
||||
jobs:
|
||||
build-linux:
|
||||
runs-on: [self-hosted, Linux, X64, icicle]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v3
|
||||
# Checkout code
|
||||
- uses: actions/checkout@v3
|
||||
# Download (or from cache) and install CUDA Toolkit 12.1.0
|
||||
- uses: Jimver/cuda-toolkit@v0.2.9
|
||||
id: cuda-toolkit
|
||||
with:
|
||||
cuda: '12.1.0'
|
||||
use-github-cache: true
|
||||
# Build from cargo - Rust utils are preinstalled on latest images
|
||||
# https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2204-Readme.md#rust-tools
|
||||
- name: Build
|
||||
run: cargo build --release --verbose
|
||||
|
||||
|
||||
build-windows:
|
||||
runs-on: windows-2022
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v3
|
||||
- name: Download and Install Cuda
|
||||
uses: Jimver/cuda-toolkit@v0.2.11
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Jimver/cuda-toolkit@v0.2.9
|
||||
id: cuda-toolkit
|
||||
with:
|
||||
cuda: '12.0.0'
|
||||
method: 'network'
|
||||
# https://docs.nvidia.com/cuda/archive/12.0.0/cuda-installation-guide-microsoft-windows/index.html
|
||||
sub-packages: '["cudart", "nvcc", "thrust"]'
|
||||
cuda: '12.1.0'
|
||||
use-github-cache: true
|
||||
- name: Build
|
||||
run: cargo build --release --verbose
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -5,9 +5,6 @@
|
||||
*.cubin
|
||||
*.bin
|
||||
*.fatbin
|
||||
*.so
|
||||
*.nsys-rep
|
||||
*.ncu-rep
|
||||
**/target
|
||||
**/.vscode
|
||||
**/.*lock*csv#
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# https://github.com/rust-lang/rustfmt/blob/master/Configurations.md
|
||||
|
||||
# Stable Configs
|
||||
chain_width = 0
|
||||
max_width = 120
|
||||
merge_derives = true
|
||||
use_field_init_shorthand = true
|
||||
use_try_shorthand = true
|
||||
|
||||
# Unstable Configs
|
||||
@@ -27,10 +27,6 @@ ark-bls12-381 = "0.3.0"
|
||||
ark-bls12-377 = "0.3.0"
|
||||
ark-bn254 = "0.3.0"
|
||||
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_derive = "1.0"
|
||||
serde_cbor = "0.11.2"
|
||||
|
||||
rustacuda = "0.1"
|
||||
rustacuda_core = "0.1"
|
||||
rustacuda_derive = "0.1"
|
||||
|
||||
68
README.md
68
README.md
@@ -4,15 +4,6 @@
|
||||
|
||||

|
||||
|
||||
|
||||
<div align="center">
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
</div>
|
||||
|
||||
## Background
|
||||
|
||||
Zero Knowledge Proofs (ZKPs) are considered one of the greatest achievements of modern cryptography. Accordingly, ZKPs are expected to disrupt a number of industries and will usher in an era of trustless and privacy preserving services and infrastructure.
|
||||
@@ -45,7 +36,7 @@ ICICLE is a CUDA implementation of general functions widely used in ZKP. ICICLE
|
||||
|
||||
```sh
|
||||
mkdir -p build
|
||||
nvcc -o build/<binary_name> ./icicle/curves/index.cu -lib -arch=native
|
||||
nvcc -o build/<ENTER_DIR_NAME> ./icicle/appUtils/ntt/ntt.cu ./icicle/appUtils/msm/msm.cu ./icicle/appUtils/vector_manipulation/ve_mod_mult.cu ./icicle/primitives/projective.cu -lib -arch=native
|
||||
```
|
||||
|
||||
### Testing the CUDA code
|
||||
@@ -104,74 +95,52 @@ Supporting additional curves can be done as follows:
|
||||
|
||||
Create a JSON file with the curve parameters. The curve is defined by the following parameters:
|
||||
- ``curve_name`` - e.g. ``bls12_381``.
|
||||
- ``modulus_p`` - scalar field modulus (in decimal).
|
||||
- ``bit_count_p`` - number of bits needed to represent `` modulus_p`` .
|
||||
- ``limb_p`` - number of bytes needed to represent `` modulus_p`` (rounded).
|
||||
- ``modolus_p`` - scalar field modolus (in decimal).
|
||||
- ``bit_count_p`` - number of bits needed to represent `` modolus_p`` .
|
||||
- ``limb_p`` - number of bytes needed to represent `` modolus_p`` (rounded).
|
||||
- ``ntt_size`` - log of the maximal size subgroup of the scalar field.
|
||||
- ``modulus_q`` - base field modulus (in decimal).
|
||||
- ``bit_count_q`` - number of bits needed to represent `` modulus_q`` .
|
||||
- ``limb_q`` number of bytes needed to represent `` modulus_p`` (rounded).
|
||||
- ``modolus_q`` - base field modulus (in decimal).
|
||||
- ``bit_count_q`` - number of bits needed to represent `` modolus_q`` .
|
||||
- ``limb_q`` number of bytes needed to represent `` modolus_p`` (rounded).
|
||||
- ``weierstrass_b`` - Weierstrauss constant of the curve.
|
||||
- ``weierstrass_b_g2_re`` - Weierstrauss real constant of the g2 curve.
|
||||
- ``weierstrass_b_g2_im`` - Weierstrauss imaginary constant of the g2 curve.
|
||||
- ``gen_x`` - x-value of a generator element for the curve.
|
||||
- ``gen_y`` - y-value of a generator element for the curve.
|
||||
- ``gen_x_re`` - real x-value of a generator element for the g2 curve.
|
||||
- ``gen_x_im`` - imaginary x-value of a generator element for the g2 curve.
|
||||
- ``gen_y_re`` - real y-value of a generator element for the g2 curve.
|
||||
- ``gen_y_im`` - imaginary y-value of a generator element for the g2 curve.
|
||||
|
||||
Here's an example for BLS12-381.
|
||||
```
|
||||
{
|
||||
"curve_name" : "bls12_381",
|
||||
"modulus_p" : 52435875175126190479447740508185965837690552500527637822603658699938581184513,
|
||||
"modolus_p" : 52435875175126190479447740508185965837690552500527637822603658699938581184513,
|
||||
"bit_count_p" : 255,
|
||||
"limb_p" : 8,
|
||||
"ntt_size" : 32,
|
||||
"modulus_q" : 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787,
|
||||
"modolus_q" : 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787,
|
||||
"bit_count_q" : 381,
|
||||
"limb_q" : 12,
|
||||
"weierstrass_b" : 4,
|
||||
"weierstrass_b_g2_re":4,
|
||||
"weierstrass_b_g2_im":4,
|
||||
"gen_x" : 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507,
|
||||
"gen_y" : 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569,
|
||||
"gen_x_re" : 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160,
|
||||
"gen_x_im" : 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758,
|
||||
"gen_y_re" : 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905,
|
||||
"gen_y_im" : 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582
|
||||
"gen_y" : 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569
|
||||
}
|
||||
```
|
||||
|
||||
Save the parameters JSON file under the ``curve_parameters`` directory.
|
||||
Save the parameters JSON file in ``curve_parameters``.
|
||||
|
||||
Then run the Python script ``new_curve_script.py `` from the root folder:
|
||||
Then run the Python script ``new_curve_script.py `` from the main icicle folder:
|
||||
|
||||
```
|
||||
python3 ./curve_parameters/new_curve_script.py ./curve_parameters/bls12_381.json
|
||||
python3 ./curve_parameters/new_curve_script_rust.py ./curve_parameters/bls12_381.json
|
||||
```
|
||||
|
||||
The script does the following:
|
||||
- Creates a folder in ``icicle/curves`` with the curve name, which contains all of the files needed for the supported operations in cuda.
|
||||
- Adds the curve's exported operations to ``icicle/curves/index.cu``.
|
||||
- Adds the curve exported operations to ``icicle/curves/index.cu``.
|
||||
- Creates a file with the curve name in ``src/curves`` with the relevant objects for the curve.
|
||||
- Creates a test file with the curve name in ``src``.
|
||||
|
||||
Testing the new curve could be done by running the tests in ``tests_curve_name`` (e.g. ``tests_bls12_381``).
|
||||
## Contributions
|
||||
|
||||
Join our [Discord Server][DISCORD] and find us on the icicle channel. We will be happy to work together to support your use case and talk features, bugs and design.
|
||||
|
||||
### Development Contributions
|
||||
|
||||
If you are changing code, please make sure to change your [git hooks path][HOOKS_DOCS] to the repo's [hooks directory][HOOKS_PATH] by running the following command:
|
||||
|
||||
```sh
|
||||
git config core.hooksPath ./scripts/hooks
|
||||
```
|
||||
|
||||
This will ensure our custom hooks are run and will make it easier to follow our coding guidelines.
|
||||
Join our [Discord Server](https://discord.gg/Y4SkbDf2Ff) and find us on the icicle channel. We will be happy to work together to support your use case and talk features, bugs and design.
|
||||
|
||||
### Hall of Fame
|
||||
|
||||
@@ -184,18 +153,13 @@ ICICLE is distributed under the terms of the MIT License.
|
||||
See [LICENSE-MIT][LMIT] for details.
|
||||
|
||||
<!-- Begin Links -->
|
||||
[BLS12-381]: ./icicle/curves/bls12_381/supported_operations.cu
|
||||
[BLS12-377]: ./icicle/curves/bls12_377/supported_operations.cu
|
||||
[BN254]: ./icicle/curves/bn254/supported_operations.cu
|
||||
[BLS12-381]: ./icicle/curves/bls12_381.cuh
|
||||
[NVCC]: https://docs.nvidia.com/cuda/#installation-guides
|
||||
[CRV_TEMPLATE]: ./icicle/curves/curve_template.cuh
|
||||
[CRV_CONFIG]: ./icicle/curves/curve_config.cuh
|
||||
[B_SCRIPT]: ./build.rs
|
||||
[FDI]: https://github.com/ingonyama-zk/fast-danksharding
|
||||
[LMIT]: ./LICENSE
|
||||
[DISCORD]: https://discord.gg/Y4SkbDf2Ff
|
||||
[googletest]: https://github.com/google/googletest/
|
||||
[HOOKS_DOCS]: https://git-scm.com/docs/githooks
|
||||
[HOOKS_PATH]: ./scripts/hooks/
|
||||
|
||||
<!-- End Links -->
|
||||
|
||||
@@ -2,15 +2,13 @@ extern crate criterion;
|
||||
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
|
||||
use icicle_utils::test_bls12_381::{
|
||||
commit_batch_bls12_381, generate_random_points_bls12_381, set_up_scalars_bls12_381,
|
||||
};
|
||||
use icicle_utils::utils::*;
|
||||
use icicle_utils::{set_up_scalars, generate_random_points, commit_batch, get_rng, field::BaseField};
|
||||
#[cfg(feature = "g2")]
|
||||
use icicle_utils::{commit_batch_g2, field::ExtensionField};
|
||||
|
||||
use rustacuda::prelude::*;
|
||||
|
||||
|
||||
const LOG_MSM_SIZES: [usize; 1] = [12];
|
||||
const BATCH_SIZES: [usize; 2] = [128, 256];
|
||||
|
||||
@@ -19,11 +17,11 @@ fn bench_msm(c: &mut Criterion) {
|
||||
for log_msm_size in LOG_MSM_SIZES {
|
||||
for batch_size in BATCH_SIZES {
|
||||
let msm_size = 1 << log_msm_size;
|
||||
let (scalars, _, _) = set_up_scalars_bls12_381(msm_size, 0, false);
|
||||
let (scalars, _, _) = set_up_scalars(msm_size, 0, false);
|
||||
let batch_scalars = vec![scalars; batch_size].concat();
|
||||
let mut d_scalars = DeviceBuffer::from_slice(&batch_scalars[..]).unwrap();
|
||||
|
||||
let points = generate_random_points_bls12_381(msm_size, get_rng(None));
|
||||
let points = generate_random_points::<BaseField>(msm_size, get_rng(None));
|
||||
let batch_points = vec![points; batch_size].concat();
|
||||
let mut d_points = DeviceBuffer::from_slice(&batch_points[..]).unwrap();
|
||||
|
||||
@@ -34,23 +32,19 @@ fn bench_msm(c: &mut Criterion) {
|
||||
#[cfg(feature = "g2")]
|
||||
let mut d_g2_points = DeviceBuffer::from_slice(&g2_batch_points[..]).unwrap();
|
||||
|
||||
group
|
||||
.sample_size(30)
|
||||
.bench_function(
|
||||
&format!("MSM of size 2^{} in batch {}", log_msm_size, batch_size),
|
||||
|b| b.iter(|| commit_batch_bls12_381(&mut d_points, &mut d_scalars, batch_size)),
|
||||
);
|
||||
group.sample_size(30).bench_function(
|
||||
&format!("MSM of size 2^{} in batch {}", log_msm_size, batch_size),
|
||||
|b| b.iter(|| commit_batch(&mut d_points, &mut d_scalars, batch_size))
|
||||
);
|
||||
|
||||
#[cfg(feature = "g2")]
|
||||
group
|
||||
.sample_size(10)
|
||||
.bench_function(
|
||||
&format!("G2 MSM of size 2^{} in batch {}", log_msm_size, batch_size),
|
||||
|b| b.iter(|| commit_batch_g2(&mut d_g2_points, &mut d_scalars, batch_size)),
|
||||
);
|
||||
group.sample_size(10).bench_function(
|
||||
&format!("G2 MSM of size 2^{} in batch {}", log_msm_size, batch_size),
|
||||
|b| b.iter(|| commit_batch_g2(&mut d_g2_points, &mut d_scalars, batch_size))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
criterion_group!(msm_benches, bench_msm);
|
||||
criterion_main!(msm_benches);
|
||||
criterion_main!(msm_benches);
|
||||
@@ -2,81 +2,29 @@ extern crate criterion;
|
||||
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
|
||||
use icicle_utils::test_bls12_381::*;
|
||||
use icicle_utils::{interpolate_scalars_batch, interpolate_points_batch, set_up_scalars, set_up_points};
|
||||
|
||||
const LOG_NTT_SIZES: [usize; 3] = [20, 9, 10];
|
||||
const BATCH_SIZES: [usize; 3] = [1, 512, 1024];
|
||||
|
||||
const LOG_NTT_SIZES: [usize; 1] = [15];
|
||||
const BATCH_SIZES: [usize; 2] = [8, 16];
|
||||
|
||||
fn bench_ntt(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("NTT");
|
||||
for log_ntt_size in LOG_NTT_SIZES {
|
||||
for batch_size in BATCH_SIZES {
|
||||
let ntt_size = 1 << log_ntt_size;
|
||||
let (_, mut d_evals, mut d_domain) = set_up_scalars(ntt_size * batch_size, log_ntt_size, true);
|
||||
let (_, mut d_points_evals, _) = set_up_points(ntt_size * batch_size, log_ntt_size, true);
|
||||
|
||||
if ntt_size * batch_size > 1 << 25 {
|
||||
continue;
|
||||
}
|
||||
group.sample_size(100).bench_function(
|
||||
&format!("Scalar NTT of size 2^{} in batch {}", log_ntt_size, batch_size),
|
||||
|b| b.iter(|| interpolate_scalars_batch(&mut d_evals, &mut d_domain, batch_size))
|
||||
);
|
||||
|
||||
let scalar_samples = 20;
|
||||
|
||||
let (_, mut d_evals, mut d_domain) = set_up_scalars_bls12_381(ntt_size * batch_size, log_ntt_size, true);
|
||||
|
||||
group
|
||||
.sample_size(scalar_samples)
|
||||
.bench_function(
|
||||
&format!("Scalar NTT of size 2^{} in batch {}", log_ntt_size, batch_size),
|
||||
|b| b.iter(|| evaluate_scalars_batch_bls12_381(&mut d_evals, &mut d_domain, batch_size)),
|
||||
);
|
||||
|
||||
group
|
||||
.sample_size(scalar_samples)
|
||||
.bench_function(
|
||||
&format!("Scalar iNTT of size 2^{} in batch {}", log_ntt_size, batch_size),
|
||||
|b| b.iter(|| interpolate_scalars_batch_bls12_381(&mut d_evals, &mut d_domain, batch_size)),
|
||||
);
|
||||
|
||||
group
|
||||
.sample_size(scalar_samples)
|
||||
.bench_function(
|
||||
&format!("Scalar inplace NTT of size 2^{} in batch {}", log_ntt_size, batch_size),
|
||||
|b| b.iter(|| ntt_inplace_batch_bls12_381(&mut d_evals, &mut d_domain, batch_size, false, 0)),
|
||||
);
|
||||
|
||||
group
|
||||
.sample_size(scalar_samples)
|
||||
.bench_function(
|
||||
&format!("Scalar inplace iNTT of size 2^{} in batch {}", log_ntt_size, batch_size),
|
||||
|b| b.iter(|| ntt_inplace_batch_bls12_381(&mut d_evals, &mut d_domain, batch_size, true, 0)),
|
||||
);
|
||||
|
||||
drop(d_evals);
|
||||
drop(d_domain);
|
||||
|
||||
if ntt_size * batch_size > 1 << 18 {
|
||||
continue;
|
||||
}
|
||||
|
||||
let point_samples = 10;
|
||||
|
||||
let (_, mut d_points_evals, mut d_domain) =
|
||||
set_up_points_bls12_381(ntt_size * batch_size, log_ntt_size, true);
|
||||
|
||||
group
|
||||
.sample_size(point_samples)
|
||||
.bench_function(
|
||||
&format!("EC NTT of size 2^{} in batch {}", log_ntt_size, batch_size),
|
||||
|b| b.iter(|| interpolate_points_batch_bls12_381(&mut d_points_evals, &mut d_domain, batch_size)),
|
||||
);
|
||||
|
||||
group
|
||||
.sample_size(point_samples)
|
||||
.bench_function(
|
||||
&format!("EC iNTT of size 2^{} in batch {}", log_ntt_size, batch_size),
|
||||
|b| b.iter(|| evaluate_points_batch_bls12_381(&mut d_points_evals, &mut d_domain, batch_size)),
|
||||
);
|
||||
|
||||
drop(d_points_evals);
|
||||
drop(d_domain);
|
||||
group.sample_size(10).bench_function(
|
||||
&format!("EC NTT of size 2^{} in batch {}", log_ntt_size, batch_size),
|
||||
|b| b.iter(|| interpolate_points_batch(&mut d_points_evals, &mut d_domain, batch_size))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
8
build.rs
8
build.rs
@@ -8,12 +8,9 @@ fn main() {
|
||||
println!("cargo:rerun-if-changed=./icicle");
|
||||
|
||||
let arch_type = env::var("ARCH_TYPE").unwrap_or(String::from("native"));
|
||||
let stream_type = env::var("DEFAULT_STREAM").unwrap_or(String::from("legacy"));
|
||||
|
||||
let mut arch = String::from("-arch=");
|
||||
arch.push_str(&arch_type);
|
||||
let mut stream = String::from("-default-stream=");
|
||||
stream.push_str(&stream_type);
|
||||
|
||||
let mut nvcc = cc::Build::new();
|
||||
|
||||
@@ -25,7 +22,8 @@ fn main() {
|
||||
nvcc.cuda(true);
|
||||
nvcc.debug(false);
|
||||
nvcc.flag(&arch);
|
||||
nvcc.flag(&stream);
|
||||
nvcc.files(["./icicle/curves/index.cu"]);
|
||||
nvcc.files([
|
||||
"./icicle/curves/index.cu",
|
||||
]);
|
||||
nvcc.compile("ingo_icicle"); //TODO: extension??
|
||||
}
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
{
|
||||
"curve_name" : "bls12_377",
|
||||
"modulus_p" : 8444461749428370424248824938781546531375899335154063827935233455917409239041,
|
||||
"modolus_p" : 8444461749428370424248824938781546531375899335154063827935233455917409239041,
|
||||
"bit_count_p" : 253,
|
||||
"limb_p" : 8,
|
||||
"ntt_size" : 32,
|
||||
"modulus_q" : 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177,
|
||||
"modolus_q" : 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177,
|
||||
"bit_count_q" : 377,
|
||||
"limb_q" : 12,
|
||||
"root_of_unity" : 5928890464389279575069867463136436689218492512582288454256978381122364252082,
|
||||
"weierstrass_b" : 1,
|
||||
"weierstrass_b_g2_re" : 0,
|
||||
"weierstrass_b_g2_im" : 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906,
|
||||
"g1_gen_x" : 81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695,
|
||||
"g1_gen_y" : 241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030,
|
||||
"g2_gen_x_re" : 233578398248691099356572568220835526895379068987715365179118596935057653620464273615301663571204657964920925606294,
|
||||
"g2_gen_x_im" : 140913150380207355837477652521042157274541796891053068589147167627541651775299824604154852141315666357241556069118,
|
||||
"g2_gen_y_re" : 63160294768292073209381361943935198908131692476676907196754037919244929611450776219210369229519898517858833747423,
|
||||
"g2_gen_y_im" : 149157405641012693445398062341192467754805999074082136895788947234480009303640899064710353187729182149407503257491
|
||||
"gen_x" : 81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695,
|
||||
"gen_y" : 241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030
|
||||
}
|
||||
@@ -1,20 +1,13 @@
|
||||
{
|
||||
"curve_name" : "bls12_381",
|
||||
"modulus_p" : 52435875175126190479447740508185965837690552500527637822603658699938581184513,
|
||||
"modolus_p" : 52435875175126190479447740508185965837690552500527637822603658699938581184513,
|
||||
"bit_count_p" : 255,
|
||||
"limb_p" : 8,
|
||||
"ntt_size" : 32,
|
||||
"modulus_q" : 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787,
|
||||
"modolus_q" : 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787,
|
||||
"bit_count_q" : 381,
|
||||
"limb_q" : 12,
|
||||
"root_of_unity" : 937917089079007706106976984802249742464848817460758522850752807661925904159,
|
||||
"weierstrass_b" : 4,
|
||||
"weierstrass_b_g2_re":4,
|
||||
"weierstrass_b_g2_im":4,
|
||||
"g1_gen_x" : 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507,
|
||||
"g1_gen_y" : 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569,
|
||||
"g2_gen_x_re" : 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160,
|
||||
"g2_gen_x_im" : 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758,
|
||||
"g2_gen_y_re" : 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905,
|
||||
"g2_gen_y_im" : 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582
|
||||
"gen_x" : 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507,
|
||||
"gen_y" : 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569
|
||||
}
|
||||
@@ -1,20 +1,13 @@
|
||||
{
|
||||
"curve_name" : "bn254",
|
||||
"modulus_p" : 21888242871839275222246405745257275088548364400416034343698204186575808495617,
|
||||
"modolus_p" : 21888242871839275222246405745257275088548364400416034343698204186575808495617,
|
||||
"bit_count_p" : 254,
|
||||
"limb_p" : 8,
|
||||
"ntt_size" : 20,
|
||||
"modulus_q" : 21888242871839275222246405745257275088696311157297823662689037894645226208583,
|
||||
"ntt_size" : 16,
|
||||
"modolus_q" : 21888242871839275222246405745257275088696311157297823662689037894645226208583,
|
||||
"bit_count_q" : 254,
|
||||
"limb_q" : 8,
|
||||
"root_of_unity" : 19032961837237948602743626455740240236231119053033140765040043513661803148152,
|
||||
"weierstrass_b" : 3,
|
||||
"weierstrass_b_g2_re" : 19485874751759354771024239261021720505790618469301721065564631296452457478373,
|
||||
"weierstrass_b_g2_im" : 266929791119991161246907387137283842545076965332900288569378510910307636690,
|
||||
"g1_gen_x" : 1,
|
||||
"g1_gen_y" : 2,
|
||||
"g2_gen_x_re" : 10857046999023057135944570762232829481370756359578518086990519993285655852781,
|
||||
"g2_gen_x_im" : 11559732032986387107991004021392285783925812861821192530917403151452391805634,
|
||||
"g2_gen_y_re" : 8495653923123431417604973247489272438418190587263600148770280649306958101930,
|
||||
"g2_gen_y_im" : 4082367875863433681332203403145435568316851327593401208105741076214120093531
|
||||
"gen_x" : 1,
|
||||
"gen_y" : 2
|
||||
}
|
||||
@@ -1,12 +1,30 @@
|
||||
import json
|
||||
import math
|
||||
import os
|
||||
from string import Template
|
||||
from sympy.ntheory import isprime, primitive_root
|
||||
import subprocess
|
||||
import random
|
||||
import sys
|
||||
|
||||
data = None
|
||||
with open(sys.argv[1]) as json_file:
|
||||
data = json.load(json_file)
|
||||
|
||||
def to_hex(val: int, length):
|
||||
x = hex(val)[2:]
|
||||
curve_name = data["curve_name"]
|
||||
modolus_p = data["modolus_p"]
|
||||
bit_count_p = data["bit_count_p"]
|
||||
limb_p = data["limb_p"]
|
||||
ntt_size = data["ntt_size"]
|
||||
modolus_q = data["modolus_q"]
|
||||
bit_count_q = data["bit_count_q"]
|
||||
limb_q = data["limb_q"]
|
||||
weierstrass_b = data["weierstrass_b"]
|
||||
gen_x = data["gen_x"]
|
||||
gen_y = data["gen_y"]
|
||||
|
||||
|
||||
def to_hex(val, length):
|
||||
x = str(hex(val))[2:]
|
||||
if len(x) % 8 != 0:
|
||||
x = "0" * (8-len(x) % 8) + x
|
||||
if len(x) != length:
|
||||
@@ -15,260 +33,133 @@ def to_hex(val: int, length):
|
||||
chunks = [x[i:i+n] for i in range(0, len(x), n)][::-1]
|
||||
s = ""
|
||||
for c in chunks:
|
||||
s += f'0x{c}, '
|
||||
|
||||
return s[:-2]
|
||||
s += "0x" + c + ", "
|
||||
return s
|
||||
|
||||
|
||||
def compute_values(modulus, modulus_bit_count, limbs):
|
||||
limb_size = 8*limbs
|
||||
modulus_ = to_hex(modulus,limb_size)
|
||||
modulus_2 = to_hex(modulus*2,limb_size)
|
||||
modulus_4 = to_hex(modulus*4,limb_size)
|
||||
modulus_wide = to_hex(modulus,limb_size*2)
|
||||
modulus_squared = to_hex(modulus*modulus,limb_size)
|
||||
modulus_squared_2 = to_hex(modulus*modulus*2,limb_size)
|
||||
modulus_squared_4 = to_hex(modulus*modulus*4,limb_size)
|
||||
m_raw = int(math.floor(int(pow(2,2*modulus_bit_count) // modulus)))
|
||||
m = to_hex(m_raw,limb_size)
|
||||
one = to_hex(1,limb_size)
|
||||
zero = to_hex(0,limb_size)
|
||||
def get_root_of_unity(order: int) -> int:
|
||||
assert (modolus_p - 1) % order == 0
|
||||
return pow(5, (modolus_p - 1) // order, modolus_p)
|
||||
|
||||
return (
|
||||
modulus_,
|
||||
modulus_2,
|
||||
modulus_4,
|
||||
modulus_wide,
|
||||
modulus_squared,
|
||||
modulus_squared_2,
|
||||
modulus_squared_4,
|
||||
m,
|
||||
one,
|
||||
zero
|
||||
)
|
||||
def create_field_parameters_struct(modulus, modulus_bits_count,limbs,ntt,size,name):
|
||||
s = " struct "+name+"{\n"
|
||||
s += " static constexpr unsigned limbs_count = " + str(limbs)+";\n"
|
||||
s += " static constexpr storage<limbs_count> modulus = {"+to_hex(modulus,8*limbs)[:-2]+"};\n"
|
||||
s += " static constexpr storage<limbs_count> modulus_2 = {"+to_hex(modulus*2,8*limbs)[:-2]+"};\n"
|
||||
s += " static constexpr storage<limbs_count> modulus_4 = {"+to_hex(modulus*4,8*limbs)[:-2]+"};\n"
|
||||
s += " static constexpr storage<2*limbs_count> modulus_wide = {"+to_hex(modulus,8*limbs*2)[:-2]+"};\n"
|
||||
s += " static constexpr storage<2*limbs_count> modulus_sqared = {"+to_hex(modulus*modulus,8*limbs)[:-2]+"};\n"
|
||||
s += " static constexpr storage<2*limbs_count> modulus_sqared_2 = {"+to_hex(modulus*modulus*2,8*limbs)[:-2]+"};\n"
|
||||
s += " static constexpr storage<2*limbs_count> modulus_sqared_4 = {"+to_hex(modulus*modulus*2*2,8*limbs)[:-2]+"};\n"
|
||||
s += " static constexpr unsigned modulus_bits_count = "+str(modulus_bits_count)+";\n"
|
||||
m = int(math.floor(int(pow(2,2*modulus_bits_count) // modulus)))
|
||||
s += " static constexpr storage<limbs_count> m = {"+ to_hex(m,8*limbs)[:-2] +"};\n"
|
||||
s += " static constexpr storage<limbs_count> one = {"+ to_hex(1,8*limbs)[:-2] +"};\n"
|
||||
s += " static constexpr storage<limbs_count> zero = {"+ to_hex(0,8*limbs)[:-2] +"};\n"
|
||||
|
||||
|
||||
def get_fq_params(modulus, modulus_bit_count, limbs, g1_gen_x, g1_gen_y, g2_gen_x_re, g2_gen_x_im, g2_gen_y_re, g2_gen_y_im):
|
||||
(
|
||||
modulus,
|
||||
modulus_2,
|
||||
modulus_4,
|
||||
modulus_wide,
|
||||
modulus_squared,
|
||||
modulus_squared_2,
|
||||
modulus_squared_4,
|
||||
m,
|
||||
one,
|
||||
zero
|
||||
) = compute_values(modulus, modulus_bit_count, limbs)
|
||||
|
||||
limb_size = 8*limbs
|
||||
return {
|
||||
'fq_modulus': modulus,
|
||||
'fq_modulus_2': modulus_2,
|
||||
'fq_modulus_4': modulus_4,
|
||||
'fq_modulus_wide': modulus_wide,
|
||||
'fq_modulus_squared': modulus_squared,
|
||||
'fq_modulus_squared_2': modulus_squared_2,
|
||||
'fq_modulus_squared_4': modulus_squared_4,
|
||||
'fq_m': m,
|
||||
'fq_one': one,
|
||||
'fq_zero': zero,
|
||||
'fq_gen_x': to_hex(g1_gen_x, limb_size),
|
||||
'fq_gen_y': to_hex(g1_gen_y, limb_size),
|
||||
'fq_gen_x_re': to_hex(g2_gen_x_re, limb_size),
|
||||
'fq_gen_x_im': to_hex(g2_gen_x_im, limb_size),
|
||||
'fq_gen_y_re': to_hex(g2_gen_y_re, limb_size),
|
||||
'fq_gen_y_im': to_hex(g2_gen_y_im, limb_size)
|
||||
}
|
||||
|
||||
|
||||
def get_fp_params(modulus, modulus_bit_count, limbs, root_of_unity, size=0):
|
||||
(
|
||||
modulus_,
|
||||
modulus_2,
|
||||
modulus_4,
|
||||
modulus_wide,
|
||||
modulus_squared,
|
||||
modulus_squared_2,
|
||||
modulus_squared_4,
|
||||
m,
|
||||
one,
|
||||
zero
|
||||
) = compute_values(modulus, modulus_bit_count, limbs)
|
||||
limb_size = 8*limbs
|
||||
if size > 0:
|
||||
omega = ''
|
||||
omega_inv = ''
|
||||
inv = ''
|
||||
omegas = []
|
||||
omegas_inv = []
|
||||
if ntt:
|
||||
for k in range(size):
|
||||
if k == 0:
|
||||
om = root_of_unity
|
||||
else:
|
||||
om = pow(om, 2, modulus)
|
||||
omegas.append(om)
|
||||
omegas_inv.append(pow(om, -1, modulus))
|
||||
omegas.reverse()
|
||||
omegas_inv.reverse()
|
||||
omega = get_root_of_unity(int(pow(2,k+1)))
|
||||
s += " static constexpr storage<limbs_count> omega"+str(k+1)+"= {"+ to_hex(omega,8*limbs)[:-2]+"};\n"
|
||||
for k in range(size):
|
||||
omega += "\n {"+ to_hex(omegas[k],limb_size)+"}," if k>0 else " {"+ to_hex(omegas[k],limb_size)+"},"
|
||||
omega_inv += "\n {"+ to_hex(omegas_inv[k],limb_size)+"}," if k>0 else " {"+ to_hex(omegas_inv[k],limb_size)+"},"
|
||||
inv += "\n {"+ to_hex(pow(int(pow(2,k+1)), -1, modulus),limb_size)+"}," if k>0 else " {"+ to_hex(pow(int(pow(2,k+1)), -1, modulus),limb_size)+"},"
|
||||
|
||||
|
||||
return {
|
||||
'fp_modulus': modulus_,
|
||||
'fp_modulus_2': modulus_2,
|
||||
'fp_modulus_4': modulus_4,
|
||||
'fp_modulus_wide': modulus_wide,
|
||||
'fp_modulus_squared': modulus_squared,
|
||||
'fp_modulus_squared_2': modulus_squared_2,
|
||||
'fp_modulus_squared_4': modulus_squared_4,
|
||||
'fp_m': m,
|
||||
'fp_one': one,
|
||||
'fp_zero': zero,
|
||||
'omega': omega[:-1],
|
||||
'omega_inv': omega_inv[:-1],
|
||||
'inv': inv[:-1],
|
||||
}
|
||||
omega = get_root_of_unity(int(pow(2,k+1)))
|
||||
s += " static constexpr storage<limbs_count> omega_inv"+str(k+1)+"= {"+ to_hex(pow(omega, -1, modulus),8*limbs)[:-2]+"};\n"
|
||||
for k in range(size):
|
||||
s += " static constexpr storage<limbs_count> inv"+str(k+1)+"= {"+ to_hex(pow(int(pow(2,k+1)), -1, modulus),8*limbs)[:-2]+"};\n"
|
||||
s+=" };\n"
|
||||
return s
|
||||
|
||||
def create_gen():
|
||||
s = " struct group_generator {\n"
|
||||
s += " static constexpr storage<fq_config::limbs_count> generator_x = {"+to_hex(gen_x,8*limb_q)[:-2]+ "};\n"
|
||||
s += " static constexpr storage<fq_config::limbs_count> generator_y = {"+to_hex(gen_y,8*limb_q)[:-2]+ "};\n"
|
||||
s+=" };\n"
|
||||
return s
|
||||
|
||||
def get_weier_params(weierstrass_b, weierstrass_b_g2_re, weierstrass_b_g2_im, size):
|
||||
|
||||
return {
|
||||
'weier_b': to_hex(weierstrass_b, size),
|
||||
'weier_b_g2_re': to_hex(weierstrass_b_g2_re, size),
|
||||
'weier_b_g2_im': to_hex(weierstrass_b_g2_im, size),
|
||||
}
|
||||
def get_config_file_content(modolus_p, bit_count_p, limb_p, ntt_size, modolus_q, bit_count_q, limb_q, weierstrass_b):
|
||||
file_content = ""
|
||||
file_content += "#pragma once\n#include \"../../utils/storage.cuh\"\n"
|
||||
file_content += "namespace PARAMS_"+curve_name.upper()+"{\n"
|
||||
file_content += create_field_parameters_struct(modolus_p,bit_count_p,limb_p,True,ntt_size,"fp_config")
|
||||
file_content += create_field_parameters_struct(modolus_q,bit_count_q,limb_q,False,0,"fq_config")
|
||||
file_content += " static constexpr unsigned weierstrass_b = " + str(weierstrass_b)+ ";\n"
|
||||
file_content += create_gen()
|
||||
file_content+="}\n"
|
||||
return file_content
|
||||
|
||||
|
||||
def get_params(config):
|
||||
global ntt_size
|
||||
curve_name = config["curve_name"]
|
||||
modulus_p = config["modulus_p"]
|
||||
bit_count_p = config["bit_count_p"]
|
||||
limb_p = config["limb_p"]
|
||||
ntt_size = config["ntt_size"]
|
||||
modulus_q = config["modulus_q"]
|
||||
bit_count_q = config["bit_count_q"]
|
||||
limb_q = config["limb_q"]
|
||||
root_of_unity = config["root_of_unity"]
|
||||
if root_of_unity == modulus_p:
|
||||
sys.exit("Invalid root_of_unity value; please update in curve parameters")
|
||||
|
||||
weierstrass_b = config["weierstrass_b"]
|
||||
weierstrass_b_g2_re = config["weierstrass_b_g2_re"]
|
||||
weierstrass_b_g2_im = config["weierstrass_b_g2_im"]
|
||||
g1_gen_x = config["g1_gen_x"]
|
||||
g1_gen_y = config["g1_gen_y"]
|
||||
g2_generator_x_re = config["g2_gen_x_re"]
|
||||
g2_generator_x_im = config["g2_gen_x_im"]
|
||||
g2_generator_y_re = config["g2_gen_y_re"]
|
||||
g2_generator_y_im = config["g2_gen_y_im"]
|
||||
|
||||
params = {
|
||||
'curve_name_U': curve_name.upper(),
|
||||
'fp_num_limbs': limb_p,
|
||||
'fq_num_limbs': limb_q,
|
||||
'fp_modulus_bit_count': bit_count_p,
|
||||
'fq_modulus_bit_count': bit_count_q,
|
||||
'num_omegas': ntt_size
|
||||
}
|
||||
|
||||
fp_params = get_fp_params(modulus_p, bit_count_p, limb_p, root_of_unity, ntt_size)
|
||||
fq_params = get_fq_params(modulus_q, bit_count_q, limb_q, g1_gen_x, g1_gen_y, g2_generator_x_re, g2_generator_x_im, g2_generator_y_re, g2_generator_y_im)
|
||||
weier_params = get_weier_params(weierstrass_b, weierstrass_b_g2_re, weierstrass_b_g2_im, 8*limb_q)
|
||||
|
||||
return {
|
||||
**params,
|
||||
**fp_params,
|
||||
**fq_params,
|
||||
**weier_params
|
||||
}
|
||||
|
||||
|
||||
config = None
|
||||
with open(sys.argv[1]) as json_file:
|
||||
config = json.load(json_file)
|
||||
|
||||
curve_name_lower = config["curve_name"].lower()
|
||||
curve_name_upper = config["curve_name"].upper()
|
||||
limb_q = config["limb_q"]
|
||||
limb_p = config["limb_p"]
|
||||
|
||||
# Create Cuda interface
|
||||
|
||||
newpath = f'./icicle/curves/{curve_name_lower}'
|
||||
newpath = "./icicle/curves/"+curve_name
|
||||
if not os.path.exists(newpath):
|
||||
os.makedirs(newpath)
|
||||
|
||||
with open("./icicle/curves/curve_template/params.cuh.tmpl", "r") as params_file:
|
||||
params_file_template = Template(params_file.read())
|
||||
params = get_params(config)
|
||||
params_content = params_file_template.safe_substitute(params)
|
||||
with open(f'./icicle/curves/{curve_name_lower}/params.cuh', 'w') as f:
|
||||
f.write(params_content)
|
||||
fc = get_config_file_content(modolus_p, bit_count_p, limb_p, ntt_size, modolus_q, bit_count_q, limb_q, weierstrass_b)
|
||||
text_file = open("./icicle/curves/"+curve_name+"/params.cuh", "w")
|
||||
n = text_file.write(fc)
|
||||
text_file.close()
|
||||
|
||||
with open("./icicle/curves/curve_template/lde.cu.tmpl", "r") as lde_file:
|
||||
template_content = Template(lde_file.read())
|
||||
lde_content = template_content.safe_substitute(
|
||||
CURVE_NAME_U=curve_name_upper,
|
||||
CURVE_NAME_L=curve_name_lower
|
||||
)
|
||||
with open(f'./icicle/curves/{curve_name_lower}/lde.cu', 'w') as f:
|
||||
f.write(lde_content)
|
||||
with open("./icicle/curves/curve_template/lde.cu", "r") as lde_file:
|
||||
content = lde_file.read()
|
||||
content = content.replace("CURVE_NAME_U",curve_name.upper())
|
||||
content = content.replace("CURVE_NAME_L",curve_name.lower())
|
||||
text_file = open("./icicle/curves/"+curve_name+"/lde.cu", "w")
|
||||
n = text_file.write(content)
|
||||
text_file.close()
|
||||
|
||||
with open("./icicle/curves/curve_template/msm.cu.tmpl", "r") as msm_file:
|
||||
template_content = Template(msm_file.read())
|
||||
msm_content = template_content.safe_substitute(
|
||||
CURVE_NAME_U=curve_name_upper,
|
||||
CURVE_NAME_L=curve_name_lower
|
||||
)
|
||||
with open(f'./icicle/curves/{curve_name_lower}/msm.cu', 'w') as f:
|
||||
f.write(msm_content)
|
||||
with open("./icicle/curves/curve_template/msm.cu", "r") as msm_file:
|
||||
content = msm_file.read()
|
||||
content = content.replace("CURVE_NAME_U",curve_name.upper())
|
||||
content = content.replace("CURVE_NAME_L",curve_name.lower())
|
||||
text_file = open("./icicle/curves/"+curve_name+"/msm.cu", "w")
|
||||
n = text_file.write(content)
|
||||
text_file.close()
|
||||
|
||||
with open("./icicle/curves/curve_template/ve_mod_mult.cu.tmpl", "r") as ve_mod_mult_file:
|
||||
template_content = Template(ve_mod_mult_file.read())
|
||||
ve_mod_mult_content = template_content.safe_substitute(
|
||||
CURVE_NAME_U=curve_name_upper,
|
||||
CURVE_NAME_L=curve_name_lower
|
||||
)
|
||||
with open(f'./icicle/curves/{curve_name_lower}/ve_mod_mult.cu', 'w') as f:
|
||||
f.write(ve_mod_mult_content)
|
||||
with open("./icicle/curves/curve_template/ve_mod_mult.cu", "r") as ve_mod_mult_file:
|
||||
content = ve_mod_mult_file.read()
|
||||
content = content.replace("CURVE_NAME_U",curve_name.upper())
|
||||
content = content.replace("CURVE_NAME_L",curve_name.lower())
|
||||
text_file = open("./icicle/curves/"+curve_name+"/ve_mod_mult.cu", "w")
|
||||
n = text_file.write(content)
|
||||
text_file.close()
|
||||
|
||||
|
||||
with open(f'./icicle/curves/curve_template/curve_config.cuh.tmpl', 'r') as cc:
|
||||
template_content = Template(cc.read())
|
||||
cc_content = template_content.safe_substitute(
|
||||
CURVE_NAME_U=curve_name_upper,
|
||||
)
|
||||
with open(f'./icicle/curves/{curve_name_lower}/curve_config.cuh', 'w') as f:
|
||||
f.write(cc_content)
|
||||
namespace = '#include "params.cuh"\n'+'''namespace CURVE_NAME_U {
|
||||
typedef Field<PARAMS_CURVE_NAME_U::fp_config> scalar_field_t;\
|
||||
typedef scalar_field_t scalar_t;\
|
||||
typedef Field<PARAMS_CURVE_NAME_U::fq_config> point_field_t;
|
||||
typedef Projective<point_field_t, scalar_field_t, PARAMS_CURVE_NAME_U::group_generator, PARAMS_CURVE_NAME_U::weierstrass_b> projective_t;
|
||||
typedef Affine<point_field_t> affine_t;
|
||||
}'''
|
||||
|
||||
with open('./icicle/curves/'+curve_name+'/curve_config.cuh', 'w') as f:
|
||||
f.write(namespace.replace("CURVE_NAME_U",curve_name.upper()))
|
||||
|
||||
|
||||
eq = '''
|
||||
#include <cuda.h>\n
|
||||
#include "curve_config.cuh"\n
|
||||
#include "../../primitives/projective.cuh"\n
|
||||
extern "C" bool eq_CURVE_NAME_L(CURVE_NAME_U::projective_t *point1, CURVE_NAME_U::projective_t *point2)
|
||||
{
|
||||
return (*point1 == *point2);
|
||||
}'''
|
||||
|
||||
with open(f'./icicle/curves/curve_template/projective.cu.tmpl', 'r') as proj:
|
||||
template_content = Template(proj.read())
|
||||
proj_content = template_content.safe_substitute(
|
||||
CURVE_NAME_U=curve_name_upper,
|
||||
CURVE_NAME_L=curve_name_lower
|
||||
)
|
||||
with open(f'./icicle/curves/{curve_name_lower}/projective.cu', 'w') as f:
|
||||
f.write(proj_content)
|
||||
with open('./icicle/curves/'+curve_name+'/projective.cu', 'w') as f:
|
||||
f.write(eq.replace("CURVE_NAME_U",curve_name.upper()).replace("CURVE_NAME_L",curve_name.lower()))
|
||||
|
||||
supported_operations = '''
|
||||
#include "projective.cu"
|
||||
#include "lde.cu"
|
||||
#include "msm.cu"
|
||||
#include "ve_mod_mult.cu"
|
||||
'''
|
||||
|
||||
with open(f'./icicle/curves/curve_template/supported_operations.cu.tmpl', 'r') as supp_ops:
|
||||
template_content = Template(supp_ops.read())
|
||||
supp_ops_content = template_content.safe_substitute()
|
||||
with open(f'./icicle/curves/{curve_name_lower}/supported_operations.cu', 'w') as f:
|
||||
f.write(supp_ops_content)
|
||||
|
||||
|
||||
with open('./icicle/curves/index.cu', 'r+') as f:
|
||||
index_text = f.read()
|
||||
if index_text.find(curve_name_lower) == -1:
|
||||
f.write(f'\n#include "{curve_name_lower}/supported_operations.cu"')
|
||||
with open('./icicle/curves/'+curve_name+'/supported_operations.cu', 'w') as f:
|
||||
f.write(supported_operations.replace("CURVE_NAME_U",curve_name.upper()).replace("CURVE_NAME_L",curve_name.lower()))
|
||||
|
||||
with open('./icicle/curves/index.cu', 'a') as f:
|
||||
f.write('\n#include "'+curve_name.lower()+'/supported_operations.cu"')
|
||||
|
||||
|
||||
|
||||
@@ -277,40 +168,36 @@ with open('./icicle/curves/index.cu', 'r+') as f:
|
||||
if limb_p == limb_q:
|
||||
with open("./src/curve_templates/curve_same_limbs.rs", "r") as curve_file:
|
||||
content = curve_file.read()
|
||||
content = content.replace("CURVE_NAME_U",curve_name_upper)
|
||||
content = content.replace("CURVE_NAME_L",curve_name_lower)
|
||||
content = content.replace("CURVE_NAME_U",curve_name.upper())
|
||||
content = content.replace("CURVE_NAME_L",curve_name.lower())
|
||||
content = content.replace("_limbs_p",str(limb_p * 8 * 4))
|
||||
content = content.replace("limbs_p",str(limb_p))
|
||||
text_file = open("./src/curves/"+curve_name_lower+".rs", "w")
|
||||
text_file = open("./src/curves/"+curve_name+".rs", "w")
|
||||
n = text_file.write(content)
|
||||
text_file.close()
|
||||
else:
|
||||
with open("./src/curve_templates/curve_different_limbs.rs", "r") as curve_file:
|
||||
content = curve_file.read()
|
||||
content = content.replace("CURVE_NAME_U",curve_name_upper)
|
||||
content = content.replace("CURVE_NAME_L",curve_name_lower)
|
||||
content = content.replace("CURVE_NAME_U",curve_name.upper())
|
||||
content = content.replace("CURVE_NAME_L",curve_name.lower())
|
||||
content = content.replace("_limbs_p",str(limb_p * 8 * 4))
|
||||
content = content.replace("limbs_p",str(limb_p))
|
||||
content = content.replace("_limbs_q",str(limb_q * 8 * 4))
|
||||
content = content.replace("limbs_q",str(limb_q))
|
||||
text_file = open("./src/curves/"+curve_name_lower+".rs", "w")
|
||||
text_file = open("./src/curves/"+curve_name+".rs", "w")
|
||||
n = text_file.write(content)
|
||||
text_file.close()
|
||||
|
||||
with open("./src/curve_templates/test.rs", "r") as test_file:
|
||||
content = test_file.read()
|
||||
content = content.replace("CURVE_NAME_U",curve_name_upper)
|
||||
content = content.replace("CURVE_NAME_L",curve_name_lower)
|
||||
text_file = open("./src/test_"+curve_name_lower+".rs", "w")
|
||||
content = content.replace("CURVE_NAME_U",curve_name.upper())
|
||||
content = content.replace("CURVE_NAME_L",curve_name.lower())
|
||||
text_file = open("./src/test_"+curve_name+".rs", "w")
|
||||
n = text_file.write(content)
|
||||
text_file.close()
|
||||
|
||||
with open('./src/curves/mod.rs', 'r+') as f:
|
||||
mod_text = f.read()
|
||||
if mod_text.find(curve_name_lower) == -1:
|
||||
f.write('\npub mod ' + curve_name_lower + ';')
|
||||
with open('./src/curves/mod.rs', 'a') as f:
|
||||
f.write('\n pub mod ' + curve_name + ';')
|
||||
|
||||
with open('./src/lib.rs', 'r+') as f:
|
||||
lib_text = f.read()
|
||||
if lib_text.find(curve_name_lower) == -1:
|
||||
f.write('\npub mod ' + curve_name_lower + ';')
|
||||
with open('./src/lib.rs', 'a') as f:
|
||||
f.write('\npub mod ' + curve_name + ';')
|
||||
@@ -1,156 +0,0 @@
|
||||
use std::time::Instant;
|
||||
|
||||
use icicle_utils::{curves::bls12_381::ScalarField_BLS12_381, test_bls12_381::*};
|
||||
use rustacuda::prelude::DeviceBuffer;
|
||||
|
||||
const LOG_NTT_SIZES: [usize; 3] = [20, 10, 9];
|
||||
const BATCH_SIZES: [usize; 3] = [1, 1 << 9, 1 << 10];
|
||||
|
||||
const MAX_POINTS_LOG2: usize = 18;
|
||||
const MAX_SCALARS_LOG2: usize = 26;
|
||||
|
||||
fn bench_lde() {
|
||||
for log_ntt_size in LOG_NTT_SIZES {
|
||||
for batch_size in BATCH_SIZES {
|
||||
let ntt_size = 1 << log_ntt_size;
|
||||
|
||||
fn ntt_scalars_batch_bls12_381(
|
||||
d_inout: &mut DeviceBuffer<ScalarField_BLS12_381>,
|
||||
d_twiddles: &mut DeviceBuffer<ScalarField_BLS12_381>,
|
||||
batch_size: usize,
|
||||
) -> i32 {
|
||||
ntt_inplace_batch_bls12_381(d_inout, d_twiddles, batch_size, false, 0);
|
||||
0
|
||||
}
|
||||
|
||||
fn intt_scalars_batch_bls12_381(
|
||||
d_inout: &mut DeviceBuffer<ScalarField_BLS12_381>,
|
||||
d_twiddles: &mut DeviceBuffer<ScalarField_BLS12_381>,
|
||||
batch_size: usize,
|
||||
) -> i32 {
|
||||
ntt_inplace_batch_bls12_381(d_inout, d_twiddles, batch_size, true, 0);
|
||||
0
|
||||
}
|
||||
|
||||
// copy
|
||||
bench_ntt_template(
|
||||
MAX_SCALARS_LOG2,
|
||||
ntt_size,
|
||||
batch_size,
|
||||
log_ntt_size,
|
||||
set_up_scalars_bls12_381,
|
||||
evaluate_scalars_batch_bls12_381,
|
||||
"NTT",
|
||||
false,
|
||||
100,
|
||||
);
|
||||
|
||||
bench_ntt_template(
|
||||
MAX_SCALARS_LOG2,
|
||||
ntt_size,
|
||||
batch_size,
|
||||
log_ntt_size,
|
||||
set_up_scalars_bls12_381,
|
||||
interpolate_scalars_batch_bls12_381,
|
||||
"iNTT",
|
||||
true,
|
||||
100,
|
||||
);
|
||||
|
||||
bench_ntt_template(
|
||||
MAX_POINTS_LOG2,
|
||||
ntt_size,
|
||||
batch_size,
|
||||
log_ntt_size,
|
||||
set_up_points_bls12_381,
|
||||
evaluate_points_batch_bls12_381,
|
||||
"EC NTT",
|
||||
false,
|
||||
20,
|
||||
);
|
||||
|
||||
bench_ntt_template(
|
||||
MAX_POINTS_LOG2,
|
||||
ntt_size,
|
||||
batch_size,
|
||||
log_ntt_size,
|
||||
set_up_points_bls12_381,
|
||||
interpolate_points_batch_bls12_381,
|
||||
"EC iNTT",
|
||||
true,
|
||||
20,
|
||||
);
|
||||
|
||||
// inplace
|
||||
bench_ntt_template(
|
||||
MAX_SCALARS_LOG2,
|
||||
ntt_size,
|
||||
batch_size,
|
||||
log_ntt_size,
|
||||
set_up_scalars_bls12_381,
|
||||
ntt_scalars_batch_bls12_381,
|
||||
"NTT inplace",
|
||||
false,
|
||||
100,
|
||||
);
|
||||
|
||||
bench_ntt_template(
|
||||
MAX_SCALARS_LOG2,
|
||||
ntt_size,
|
||||
batch_size,
|
||||
log_ntt_size,
|
||||
set_up_scalars_bls12_381,
|
||||
intt_scalars_batch_bls12_381,
|
||||
"iNTT inplace",
|
||||
true,
|
||||
100,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn bench_ntt_template<E, S, R>(
|
||||
log_max_size: usize,
|
||||
ntt_size: usize,
|
||||
batch_size: usize,
|
||||
log_ntt_size: usize,
|
||||
set_data: fn(test_size: usize, log_domain_size: usize, inverse: bool) -> (Vec<E>, DeviceBuffer<E>, DeviceBuffer<S>),
|
||||
bench_fn: fn(d_evaluations: &mut DeviceBuffer<E>, d_domain: &mut DeviceBuffer<S>, batch_size: usize) -> R,
|
||||
id: &str,
|
||||
inverse: bool,
|
||||
samples: usize,
|
||||
) -> Option<(Vec<E>, R)> {
|
||||
let count = ntt_size * batch_size;
|
||||
|
||||
let bench_id = format!("{} of size 2^{} in batch {}", id, log_ntt_size, batch_size);
|
||||
|
||||
if count > 1 << log_max_size {
|
||||
println!("Bench size exceeded: {}", bench_id);
|
||||
return None;
|
||||
}
|
||||
|
||||
println!("{}", bench_id);
|
||||
|
||||
let (input, mut d_evals, mut d_domain) = set_data(ntt_size * batch_size, log_ntt_size, inverse);
|
||||
|
||||
let first = bench_fn(&mut d_evals, &mut d_domain, batch_size);
|
||||
|
||||
let start = Instant::now();
|
||||
for _ in 0..samples {
|
||||
bench_fn(&mut d_evals, &mut d_domain, batch_size);
|
||||
}
|
||||
let elapsed = start.elapsed();
|
||||
println!(
|
||||
"{} {:0?} us x {} = {:?}",
|
||||
bench_id,
|
||||
elapsed.as_micros() as f32 / (samples as f32),
|
||||
samples,
|
||||
elapsed
|
||||
);
|
||||
|
||||
Some((input, first))
|
||||
}
|
||||
|
||||
fn main() {
|
||||
bench_lde();
|
||||
}
|
||||
23
go.mod
23
go.mod
@@ -1,23 +0,0 @@
|
||||
module github.com/ingonyama-zk/icicle
|
||||
|
||||
go 1.20
|
||||
|
||||
require github.com/consensys/gnark-crypto v0.11.0
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/jfeliu007/goplantuml v1.6.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/spf13/afero v1.8.2 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/bits-and-blooms/bitset v1.5.0 // indirect
|
||||
github.com/consensys/bavard v0.1.13
|
||||
github.com/mmcloughlin/addchain v0.4.0 // indirect
|
||||
github.com/stretchr/testify v1.8.3
|
||||
golang.org/x/sys v0.2.0 // indirect
|
||||
rsc.io/tmplfunc v0.0.3 // indirect
|
||||
)
|
||||
459
go.sum
459
go.sum
@@ -1,459 +0,0 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
||||
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8=
|
||||
github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ=
|
||||
github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI=
|
||||
github.com/consensys/gnark-crypto v0.11.0 h1:QqzHQlwEqlQr5jfWblGDkwlKHpT+4QodYqqExkAtyks=
|
||||
github.com/consensys/gnark-crypto v0.11.0/go.mod h1:Iq/P3HHl0ElSjsg2E1gsMwhAyxnxoKK5nVyZKd+/KhU=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/jfeliu007/goplantuml v1.6.2 h1:WggxwLIBLF8P9OU/G/H2+IeHpEx5I7QK780jb78twEM=
|
||||
github.com/jfeliu007/goplantuml v1.6.2/go.mod h1:GnvyYGyIXD68akNFe2FBlNBypwfbpeNmVUQ4ZxJw8iI=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
|
||||
github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY=
|
||||
github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU=
|
||||
github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo=
|
||||
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
|
||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU=
|
||||
rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA=
|
||||
@@ -1,29 +0,0 @@
|
||||
CUDA_ROOT_DIR = /usr/local/cuda
|
||||
NVCC = $(CUDA_ROOT_DIR)/bin/nvcc
|
||||
CFLAGS = -Xcompiler -fPIC -std=c++17
|
||||
LDFLAGS = -shared
|
||||
FEATURES = -DG2_DEFINED
|
||||
|
||||
TARGET_BN254 = libbn254.so
|
||||
TARGET_BLS12_381 = libbls12_381.so
|
||||
TARGET_BLS12_377 = libbls12_377.so
|
||||
|
||||
VPATH = ../icicle/curves/bn254:../icicle/curves/bls12_377:../icicle/curves/bls12_381
|
||||
|
||||
SRCS_BN254 = lde.cu msm.cu projective.cu ve_mod_mult.cu
|
||||
SRCS_BLS12_381 = lde.cu msm.cu projective.cu ve_mod_mult.cu poseidon.cu
|
||||
SRCS_BLS12_377 = lde.cu msm.cu projective.cu ve_mod_mult.cu
|
||||
|
||||
all: $(TARGET_BN254) $(TARGET_BLS12_381) $(TARGET_BLS12_377)
|
||||
|
||||
$(TARGET_BN254):
|
||||
$(NVCC) $(FEATURES) $(CFLAGS) $(LDFLAGS) $(addprefix ../icicle/curves/bn254/, $(SRCS_BN254)) -o $@
|
||||
|
||||
$(TARGET_BLS12_381):
|
||||
$(NVCC) $(FEATURES) $(CFLAGS) $(LDFLAGS) $(addprefix ../icicle/curves/bls12_381/, $(SRCS_BLS12_381)) -o $@
|
||||
|
||||
$(TARGET_BLS12_377):
|
||||
$(NVCC) $(FEATURES) $(CFLAGS) $(LDFLAGS) $(addprefix ../icicle/curves/bls12_377/, $(SRCS_BLS12_377)) -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET_BN254) $(TARGET_BLS12_381) $(TARGET_BLS12_377)
|
||||
@@ -1,49 +0,0 @@
|
||||
# ICICLE CUDA to Golang Binding Guide
|
||||
|
||||
This guide provides instructions on how to compile CUDA code using the provided Makefile, and then how to use the resulting shared libraries to bind Golang to ICICLE's CUDA code.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
To compile the CUDA files, you will need:
|
||||
|
||||
- CUDA toolkit installed. The Makefile assumes CUDA is installed in `/usr/local/cuda`. If CUDA is installed in a different location, please adjust the `CUDA_ROOT_DIR` variable accordingly.
|
||||
- A compatible GPU and corresponding driver installed on your machine.
|
||||
|
||||
## Structure of the Makefile
|
||||
|
||||
The Makefile is designed to compile CUDA files for three curves: BN254, BLS12_381, and BLS12_377. The source files are located in the `icicle/curves/` directory.
|
||||
|
||||
## Compiling CUDA Code
|
||||
|
||||
1. Navigate to the directory containing the Makefile in your terminal.
|
||||
2. To compile all curve libraries, use the `make all` command. This will create three shared libraries: `libbn254.so`, `libbls12_381.so`, and `libbls12_377.so`.
|
||||
3. If you want to compile a specific curve, you can do so by specifying the target. For example, to compile only the BN254 curve, use `make libbn254.so`. Replace `libbn254.so` with `libbls12_381.so` or `libbls12_377.so` to compile those curves instead.
|
||||
|
||||
The resulting `.so` files are the compiled shared libraries for each curve.
|
||||
|
||||
## Golang Binding
|
||||
|
||||
The shared libraries produced from the CUDA code compilation are used to bind Golang to ICICLE's CUDA code.
|
||||
|
||||
1. These shared libraries (`libbn254.so`, `libbls12_381.so`, `libbls12_377.so`) can be imported in your Go project to leverage the GPU accelerated functionalities provided by ICICLE.
|
||||
|
||||
2. In your Go project, you can use `cgo` to link these shared libraries. Here's a basic example on how you can use `cgo` to link these libraries:
|
||||
|
||||
```go
|
||||
/*
|
||||
#cgo LDFLAGS: -L/path/to/shared/libs -lbn254 -lbls12_381 -lbls12_377
|
||||
#include "icicle.h" // make sure you use the correct header file(s)
|
||||
*/
|
||||
import "C"
|
||||
|
||||
func main() {
|
||||
// Now you can call the C functions from the ICICLE libraries.
|
||||
// Note that C function calls are prefixed with 'C.' in Go code.
|
||||
}
|
||||
```
|
||||
|
||||
Replace `/path/to/shared/libs` with the actual path where the shared libraries are located on your system.
|
||||
|
||||
## Cleaning up
|
||||
|
||||
If you want to remove the compiled files, you can use the `make clean` command. This will remove the `libbn254.so`, `libbls12_381.so`, and `libbls12_377.so` files.
|
||||
@@ -1,324 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bls12377
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ -lbls12_377
|
||||
// #include "projective.h"
|
||||
// #include "ve_mod_mult.h"
|
||||
import "C"
|
||||
|
||||
const SCALAR_SIZE = 8
|
||||
const BASE_SIZE = 12
|
||||
|
||||
type G1ScalarField struct {
|
||||
S [SCALAR_SIZE]uint32
|
||||
}
|
||||
|
||||
type G1BaseField struct {
|
||||
S [BASE_SIZE]uint32
|
||||
}
|
||||
|
||||
/*
|
||||
* BaseField Constrctors
|
||||
*/
|
||||
|
||||
func (f *G1BaseField) SetZero() *G1BaseField {
|
||||
var S [BASE_SIZE]uint32
|
||||
f.S = S
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *G1BaseField) SetOne() *G1BaseField {
|
||||
var S [BASE_SIZE]uint32
|
||||
|
||||
S[0] = 1
|
||||
|
||||
f.S = S
|
||||
return f
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) FromAffine(affine *G1PointAffine) *G1ProjectivePoint {
|
||||
out := (*C.BLS12_377_projective_t)(unsafe.Pointer(p))
|
||||
in := (*C.BLS12_377_affine_t)(unsafe.Pointer(affine))
|
||||
|
||||
C.projective_from_affine_bls12_377(out, in)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (f *G1BaseField) FromLimbs(limbs [BASE_SIZE]uint32) *G1BaseField {
|
||||
copy(f.S[:], limbs[:])
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
/*
|
||||
* BaseField methods
|
||||
*/
|
||||
|
||||
func (f *G1BaseField) Limbs() [BASE_SIZE]uint32 {
|
||||
return f.S
|
||||
}
|
||||
|
||||
func (f *G1BaseField) ToBytesLe() []byte {
|
||||
bytes := make([]byte, len(f.S)*4)
|
||||
for i, v := range f.S {
|
||||
binary.LittleEndian.PutUint32(bytes[i*4:], v)
|
||||
}
|
||||
|
||||
return bytes
|
||||
}
|
||||
|
||||
/*
|
||||
* ScalarField methods
|
||||
*/
|
||||
|
||||
func (p *G1ScalarField) Random() *G1ScalarField {
|
||||
outC := (*C.BLS12_377_scalar_t)(unsafe.Pointer(p))
|
||||
C.random_scalar_bls12_377(outC)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (f *G1ScalarField) SetZero() *G1ScalarField {
|
||||
var S [SCALAR_SIZE]uint32
|
||||
f.S = S
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *G1ScalarField) SetOne() *G1ScalarField {
|
||||
var S [SCALAR_SIZE]uint32
|
||||
S[0] = 1
|
||||
f.S = S
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (a *G1ScalarField) Eq(b *G1ScalarField) bool {
|
||||
for i, v := range a.S {
|
||||
if b.S[i] != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/*
|
||||
* ScalarField methods
|
||||
*/
|
||||
|
||||
func (f *G1ScalarField) Limbs() [SCALAR_SIZE]uint32 {
|
||||
return f.S
|
||||
}
|
||||
|
||||
func (f *G1ScalarField) ToBytesLe() []byte {
|
||||
bytes := make([]byte, len(f.S)*4)
|
||||
for i, v := range f.S {
|
||||
binary.LittleEndian.PutUint32(bytes[i*4:], v)
|
||||
}
|
||||
|
||||
return bytes
|
||||
}
|
||||
|
||||
/*
|
||||
* PointBLS12_377
|
||||
*/
|
||||
|
||||
type G1ProjectivePoint struct {
|
||||
X, Y, Z G1BaseField
|
||||
}
|
||||
|
||||
func (f *G1ProjectivePoint) SetZero() *G1ProjectivePoint {
|
||||
var yOne G1BaseField
|
||||
yOne.SetOne()
|
||||
|
||||
var xZero G1BaseField
|
||||
xZero.SetZero()
|
||||
|
||||
var zZero G1BaseField
|
||||
zZero.SetZero()
|
||||
|
||||
f.X = xZero
|
||||
f.Y = yOne
|
||||
f.Z = zZero
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) Eq(pCompare *G1ProjectivePoint) bool {
|
||||
// Cast *PointBLS12_377 to *C.BLS12_377_projective_t
|
||||
// The unsafe.Pointer cast is necessary because Go doesn't allow direct casts
|
||||
// between different pointer types.
|
||||
// It'S your responsibility to ensure that the types are compatible.
|
||||
pC := (*C.BLS12_377_projective_t)(unsafe.Pointer(p))
|
||||
pCompareC := (*C.BLS12_377_projective_t)(unsafe.Pointer(pCompare))
|
||||
|
||||
// Call the C function
|
||||
// The C function doesn't keep any references to the data,
|
||||
// so it'S fine if the Go garbage collector moves or deletes the data later.
|
||||
return bool(C.eq_bls12_377(pC, pCompareC))
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) IsOnCurve() bool {
|
||||
point := (*C.BLS12_377_projective_t)(unsafe.Pointer(p))
|
||||
res := C.projective_is_on_curve_bls12_377(point)
|
||||
|
||||
return bool(res)
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) Random() *G1ProjectivePoint {
|
||||
outC := (*C.BLS12_377_projective_t)(unsafe.Pointer(p))
|
||||
C.random_projective_bls12_377(outC)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) StripZ() *G1PointAffine {
|
||||
return &G1PointAffine{
|
||||
X: p.X,
|
||||
Y: p.Y,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) FromLimbs(x, y, z *[]uint32) *G1ProjectivePoint {
|
||||
var _x G1BaseField
|
||||
var _y G1BaseField
|
||||
var _z G1BaseField
|
||||
|
||||
_x.FromLimbs(GetFixedLimbs(x))
|
||||
_y.FromLimbs(GetFixedLimbs(y))
|
||||
_z.FromLimbs(GetFixedLimbs(z))
|
||||
|
||||
p.X = _x
|
||||
p.Y = _y
|
||||
p.Z = _z
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
/*
|
||||
* PointAffineNoInfinityBLS12_377
|
||||
*/
|
||||
|
||||
type G1PointAffine struct {
|
||||
X, Y G1BaseField
|
||||
}
|
||||
|
||||
func (p *G1PointAffine) FromProjective(projective *G1ProjectivePoint) *G1PointAffine {
|
||||
in := (*C.BLS12_377_projective_t)(unsafe.Pointer(projective))
|
||||
out := (*C.BLS12_377_affine_t)(unsafe.Pointer(p))
|
||||
|
||||
C.projective_to_affine_bls12_377(out, in)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G1PointAffine) ToProjective() *G1ProjectivePoint {
|
||||
var Z G1BaseField
|
||||
Z.SetOne()
|
||||
|
||||
return &G1ProjectivePoint{
|
||||
X: p.X,
|
||||
Y: p.Y,
|
||||
Z: Z,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *G1PointAffine) FromLimbs(X, Y *[]uint32) *G1PointAffine {
|
||||
var _x G1BaseField
|
||||
var _y G1BaseField
|
||||
|
||||
_x.FromLimbs(GetFixedLimbs(X))
|
||||
_y.FromLimbs(GetFixedLimbs(Y))
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiplication
|
||||
*/
|
||||
|
||||
func MultiplyVec(a []G1ProjectivePoint, b []G1ScalarField, deviceID int) {
|
||||
if len(a) != len(b) {
|
||||
panic("a and b have different lengths")
|
||||
}
|
||||
|
||||
pointsC := (*C.BLS12_377_projective_t)(unsafe.Pointer(&a[0]))
|
||||
scalarsC := (*C.BLS12_377_scalar_t)(unsafe.Pointer(&b[0]))
|
||||
deviceIdC := C.size_t(deviceID)
|
||||
nElementsC := C.size_t(len(a))
|
||||
|
||||
C.vec_mod_mult_point_bls12_377(pointsC, scalarsC, nElementsC, deviceIdC)
|
||||
}
|
||||
|
||||
func MultiplyScalar(a []G1ScalarField, b []G1ScalarField, deviceID int) {
|
||||
if len(a) != len(b) {
|
||||
panic("a and b have different lengths")
|
||||
}
|
||||
|
||||
aC := (*C.BLS12_377_scalar_t)(unsafe.Pointer(&a[0]))
|
||||
bC := (*C.BLS12_377_scalar_t)(unsafe.Pointer(&b[0]))
|
||||
deviceIdC := C.size_t(deviceID)
|
||||
nElementsC := C.size_t(len(a))
|
||||
|
||||
C.vec_mod_mult_scalar_bls12_377(aC, bC, nElementsC, deviceIdC)
|
||||
}
|
||||
|
||||
// Multiply a matrix by a scalar:
|
||||
//
|
||||
// `a` - flattenned matrix;
|
||||
// `b` - vector to multiply `a` by;
|
||||
func MultiplyMatrix(a []G1ScalarField, b []G1ScalarField, deviceID int) {
|
||||
c := make([]G1ScalarField, len(b))
|
||||
for i := range c {
|
||||
var p G1ScalarField
|
||||
p.SetZero()
|
||||
|
||||
c[i] = p
|
||||
}
|
||||
|
||||
aC := (*C.BLS12_377_scalar_t)(unsafe.Pointer(&a[0]))
|
||||
bC := (*C.BLS12_377_scalar_t)(unsafe.Pointer(&b[0]))
|
||||
cC := (*C.BLS12_377_scalar_t)(unsafe.Pointer(&c[0]))
|
||||
deviceIdC := C.size_t(deviceID)
|
||||
nElementsC := C.size_t(len(a))
|
||||
|
||||
C.matrix_vec_mod_mult_bls12_377(aC, bC, cC, nElementsC, deviceIdC)
|
||||
}
|
||||
|
||||
/*
|
||||
* Utils
|
||||
*/
|
||||
|
||||
func GetFixedLimbs(slice *[]uint32) [BASE_SIZE]uint32 {
|
||||
if len(*slice) <= BASE_SIZE {
|
||||
limbs := [BASE_SIZE]uint32{}
|
||||
copy(limbs[:len(*slice)], *slice)
|
||||
return limbs
|
||||
}
|
||||
|
||||
panic("slice has too many elements")
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bls12377
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNewFieldBLS12_377One(t *testing.T) {
|
||||
var oneField G1BaseField
|
||||
oneField.SetOne()
|
||||
|
||||
rawOneField := [8]uint32([8]uint32{0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0})
|
||||
|
||||
assert.Equal(t, oneField.S, rawOneField)
|
||||
}
|
||||
|
||||
func TestNewFieldBLS12_377Zero(t *testing.T) {
|
||||
var zeroField G1BaseField
|
||||
zeroField.SetZero()
|
||||
|
||||
rawZeroField := [8]uint32([8]uint32{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0})
|
||||
|
||||
assert.Equal(t, zeroField.S, rawZeroField)
|
||||
}
|
||||
|
||||
func TestFieldBLS12_377ToBytesLe(t *testing.T) {
|
||||
var p G1ProjectivePoint
|
||||
p.Random()
|
||||
|
||||
expected := make([]byte, len(p.X.S)*4) // each uint32 takes 4 bytes
|
||||
for i, v := range p.X.S {
|
||||
binary.LittleEndian.PutUint32(expected[i*4:], v)
|
||||
}
|
||||
|
||||
assert.Equal(t, p.X.ToBytesLe(), expected)
|
||||
assert.Equal(t, len(p.X.ToBytesLe()), 32)
|
||||
}
|
||||
|
||||
func TestNewPointBLS12_377Zero(t *testing.T) {
|
||||
var pointZero G1ProjectivePoint
|
||||
pointZero.SetZero()
|
||||
|
||||
var baseOne G1BaseField
|
||||
baseOne.SetOne()
|
||||
|
||||
var zeroSanity G1BaseField
|
||||
zeroSanity.SetZero()
|
||||
|
||||
assert.Equal(t, pointZero.X, zeroSanity)
|
||||
assert.Equal(t, pointZero.Y, baseOne)
|
||||
assert.Equal(t, pointZero.Z, zeroSanity)
|
||||
}
|
||||
|
||||
func TestFromProjectiveToAffine(t *testing.T) {
|
||||
var projective G1ProjectivePoint
|
||||
var affine G1PointAffine
|
||||
|
||||
projective.Random()
|
||||
|
||||
affine.FromProjective(&projective)
|
||||
var projective2 G1ProjectivePoint
|
||||
projective2.FromAffine(&affine)
|
||||
|
||||
assert.True(t, projective.IsOnCurve())
|
||||
assert.True(t, projective2.IsOnCurve())
|
||||
assert.True(t, projective.Eq(&projective2))
|
||||
}
|
||||
|
||||
func TestBLS12_377Eq(t *testing.T) {
|
||||
var p1 G1ProjectivePoint
|
||||
p1.Random()
|
||||
var p2 G1ProjectivePoint
|
||||
p2.Random()
|
||||
|
||||
assert.Equal(t, p1.Eq(&p1), true)
|
||||
assert.Equal(t, p1.Eq(&p2), false)
|
||||
}
|
||||
|
||||
func TestBLS12_377StripZ(t *testing.T) {
|
||||
var p1 G1ProjectivePoint
|
||||
p1.Random()
|
||||
|
||||
p2ZLess := p1.StripZ()
|
||||
|
||||
assert.IsType(t, G1PointAffine{}, *p2ZLess)
|
||||
assert.Equal(t, p1.X, p2ZLess.X)
|
||||
assert.Equal(t, p1.Y, p2ZLess.Y)
|
||||
}
|
||||
|
||||
func TestPointBLS12_377fromLimbs(t *testing.T) {
|
||||
var p G1ProjectivePoint
|
||||
p.Random()
|
||||
|
||||
x := p.X.Limbs()
|
||||
y := p.Y.Limbs()
|
||||
z := p.Z.Limbs()
|
||||
|
||||
xSlice := x[:]
|
||||
ySlice := y[:]
|
||||
zSlice := z[:]
|
||||
|
||||
var pFromLimbs G1ProjectivePoint
|
||||
pFromLimbs.FromLimbs(&xSlice, &ySlice, &zSlice)
|
||||
|
||||
assert.Equal(t, pFromLimbs, p)
|
||||
}
|
||||
|
||||
func TestNewPointAffineNoInfinityBLS12_377Zero(t *testing.T) {
|
||||
var zeroP G1PointAffine
|
||||
|
||||
var zeroSanity G1BaseField
|
||||
zeroSanity.SetZero()
|
||||
|
||||
assert.Equal(t, zeroP.X, zeroSanity)
|
||||
assert.Equal(t, zeroP.Y, zeroSanity)
|
||||
}
|
||||
|
||||
func TestPointAffineNoInfinityBLS12_377FromLimbs(t *testing.T) {
|
||||
// Initialize your test values
|
||||
x := [8]uint32{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
y := [8]uint32{9, 10, 11, 12, 13, 14, 15, 16}
|
||||
xSlice := x[:]
|
||||
ySlice := y[:]
|
||||
|
||||
// Execute your function
|
||||
var result G1PointAffine
|
||||
result.FromLimbs(&xSlice, &ySlice)
|
||||
|
||||
var xBase G1BaseField
|
||||
var yBase G1BaseField
|
||||
xBase.FromLimbs(x)
|
||||
yBase.FromLimbs(y)
|
||||
|
||||
// Define your expected result
|
||||
expected := &G1PointAffine{
|
||||
X: xBase,
|
||||
Y: yBase,
|
||||
}
|
||||
|
||||
// Test if result is as expected
|
||||
assert.Equal(t, result, expected)
|
||||
}
|
||||
|
||||
func TestGetFixedLimbs(t *testing.T) {
|
||||
t.Run("case of valid input of length less than 8", func(t *testing.T) {
|
||||
slice := []uint32{1, 2, 3, 4, 5, 6, 7}
|
||||
expected := [8]uint32{1, 2, 3, 4, 5, 6, 7, 0}
|
||||
|
||||
result := GetFixedLimbs(&slice)
|
||||
assert.Equal(t, result, expected)
|
||||
})
|
||||
|
||||
t.Run("case of valid input of length 8", func(t *testing.T) {
|
||||
slice := []uint32{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
expected := [8]uint32{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
|
||||
result := GetFixedLimbs(&slice)
|
||||
assert.Equal(t, result, expected)
|
||||
})
|
||||
|
||||
t.Run("case of empty input", func(t *testing.T) {
|
||||
slice := []uint32{}
|
||||
expected := [8]uint32{0, 0, 0, 0, 0, 0, 0, 0}
|
||||
|
||||
result := GetFixedLimbs(&slice)
|
||||
assert.Equal(t, result, expected)
|
||||
})
|
||||
|
||||
t.Run("case of input length greater than 8", func(t *testing.T) {
|
||||
slice := []uint32{1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("the code did not panic")
|
||||
}
|
||||
}()
|
||||
|
||||
GetFixedLimbs(&slice)
|
||||
})
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bls12377
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ -lbls12_377
|
||||
// #include "projective.h"
|
||||
// #include "ve_mod_mult.h"
|
||||
import "C"
|
||||
|
||||
// G2 extension field
|
||||
|
||||
type G2Element [6]uint64
|
||||
|
||||
type ExtentionField struct {
|
||||
A0, A1 G2Element
|
||||
}
|
||||
|
||||
type G2PointAffine struct {
|
||||
X, Y ExtentionField
|
||||
}
|
||||
|
||||
type G2Point struct {
|
||||
X, Y, Z ExtentionField
|
||||
}
|
||||
|
||||
func (p *G2Point) Random() *G2Point {
|
||||
outC := (*C.BLS12_377_g2_projective_t)(unsafe.Pointer(p))
|
||||
C.random_g2_projective_bls12_377(outC)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G2Point) FromAffine(affine *G2PointAffine) *G2Point {
|
||||
out := (*C.BLS12_377_g2_projective_t)(unsafe.Pointer(p))
|
||||
in := (*C.BLS12_377_g2_affine_t)(unsafe.Pointer(affine))
|
||||
|
||||
C.g2_projective_from_affine_bls12_377(out, in)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G2Point) Eq(pCompare *G2Point) bool {
|
||||
// Cast *PointBLS12_377 to *C.BLS12_377_projective_t
|
||||
// The unsafe.Pointer cast is necessary because Go doesn't allow direct casts
|
||||
// between different pointer types.
|
||||
// It's your responsibility to ensure that the types are compatible.
|
||||
pC := (*C.BLS12_377_g2_projective_t)(unsafe.Pointer(p))
|
||||
pCompareC := (*C.BLS12_377_g2_projective_t)(unsafe.Pointer(pCompare))
|
||||
|
||||
// Call the C function
|
||||
// The C function doesn't keep any references to the data,
|
||||
// so it's fine if the Go garbage collector moves or deletes the data later.
|
||||
return bool(C.eq_g2_bls12_377(pC, pCompareC))
|
||||
}
|
||||
|
||||
func (f *G2Element) ToBytesLe() []byte {
|
||||
var bytes []byte
|
||||
for _, val := range f {
|
||||
buf := make([]byte, 8) // 8 bytes because uint64 is 64-bit
|
||||
binary.LittleEndian.PutUint64(buf, val)
|
||||
bytes = append(bytes, buf...)
|
||||
}
|
||||
return bytes
|
||||
}
|
||||
|
||||
func (p *G2PointAffine) ToProjective() G2Point {
|
||||
return G2Point{
|
||||
X: p.X,
|
||||
Y: p.Y,
|
||||
Z: ExtentionField{
|
||||
A0: G2Element{1, 0, 0, 0},
|
||||
A1: G2Element{0, 0, 0, 0},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *G2PointAffine) FromProjective(projective *G2Point) *G2PointAffine {
|
||||
out := (*C.BLS12_377_g2_affine_t)(unsafe.Pointer(p))
|
||||
in := (*C.BLS12_377_g2_projective_t)(unsafe.Pointer(projective))
|
||||
|
||||
C.g2_projective_to_affine_bls12_377(out, in)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G2Point) IsOnCurve() bool {
|
||||
// Directly copy memory from the C struct to the Go struct
|
||||
point := (*C.BLS12_377_g2_projective_t)(unsafe.Pointer(p))
|
||||
res := C.g2_projective_is_on_curve_bls12_377(point)
|
||||
|
||||
return bool(res)
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bls12377
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestG2Eqg2(t *testing.T) {
|
||||
var point G2Point
|
||||
|
||||
point.Random()
|
||||
|
||||
assert.True(t, point.Eq(&point))
|
||||
}
|
||||
|
||||
func TestG2FromProjectiveToAffine(t *testing.T) {
|
||||
var projective G2Point
|
||||
var affine G2PointAffine
|
||||
|
||||
projective.Random()
|
||||
|
||||
affine.FromProjective(&projective)
|
||||
var projective2 G2Point
|
||||
projective2.FromAffine(&affine)
|
||||
|
||||
assert.True(t, projective.IsOnCurve())
|
||||
assert.True(t, projective2.IsOnCurve())
|
||||
assert.True(t, projective.Eq(&projective2))
|
||||
}
|
||||
|
||||
func TestG2Eqg2NotEqual(t *testing.T) {
|
||||
var point G2Point
|
||||
point.Random()
|
||||
|
||||
var point2 G2Point
|
||||
point2.Random()
|
||||
|
||||
assert.False(t, point.Eq(&point2))
|
||||
}
|
||||
|
||||
func TestG2ToBytes(t *testing.T) {
|
||||
element := G2Element{0x6546098ea84b6298, 0x4a384533d1f68aca, 0xaa0666972d771336, 0x1569e4a34321993}
|
||||
bytes := element.ToBytesLe()
|
||||
|
||||
assert.Equal(t, bytes, []byte{0x98, 0x62, 0x4b, 0xa8, 0x8e, 0x9, 0x46, 0x65, 0xca, 0x8a, 0xf6, 0xd1, 0x33, 0x45, 0x38, 0x4a, 0x36, 0x13, 0x77, 0x2d, 0x97, 0x66, 0x6, 0xaa, 0x93, 0x19, 0x32, 0x34, 0x4a, 0x9e, 0x56, 0x1})
|
||||
}
|
||||
|
||||
func TestG2ShouldConvertToProjective(t *testing.T) {
|
||||
var pointProjective G2Point
|
||||
var pointAffine G2PointAffine
|
||||
|
||||
pointProjective.Random()
|
||||
pointAffine.FromProjective(&pointProjective)
|
||||
|
||||
proj := pointAffine.ToProjective()
|
||||
|
||||
assert.True(t, proj.IsOnCurve())
|
||||
assert.True(t, pointProjective.Eq(&proj))
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
#include <cuda.h>
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
// msm.h
|
||||
|
||||
#ifndef _BLS12_377_MSM_H
|
||||
#define _BLS12_377_MSM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Incomplete declaration of BLS12_377 projective and affine structs
|
||||
typedef struct BLS12_377_projective_t BLS12_377_projective_t;
|
||||
typedef struct BLS12_377_g2_projective_t BLS12_377_g2_projective_t;
|
||||
typedef struct BLS12_377_affine_t BLS12_377_affine_t;
|
||||
typedef struct BLS12_377_g2_affine_t BLS12_377_g2_affine_t;
|
||||
typedef struct BLS12_377_scalar_t BLS12_377_scalar_t;
|
||||
typedef cudaStream_t CudaStream_t;
|
||||
|
||||
int msm_cuda_bls12_377(
|
||||
BLS12_377_projective_t* out, BLS12_377_affine_t* points, BLS12_377_scalar_t* scalars, size_t count, size_t device_id);
|
||||
|
||||
int msm_batch_cuda_bls12_377(
|
||||
BLS12_377_projective_t* out,
|
||||
BLS12_377_affine_t* points,
|
||||
BLS12_377_scalar_t* scalars,
|
||||
size_t batch_size,
|
||||
size_t msm_size,
|
||||
size_t device_id);
|
||||
|
||||
int commit_cuda_bls12_377(
|
||||
BLS12_377_projective_t* d_out,
|
||||
BLS12_377_scalar_t* d_scalars,
|
||||
BLS12_377_affine_t* d_points,
|
||||
size_t count,
|
||||
unsigned large_bucket_factor,
|
||||
size_t device_id);
|
||||
|
||||
int commit_batch_cuda_bls12_377(
|
||||
BLS12_377_projective_t* d_out,
|
||||
BLS12_377_scalar_t* d_scalars,
|
||||
BLS12_377_affine_t* d_points,
|
||||
size_t count,
|
||||
size_t batch_size,
|
||||
size_t device_id);
|
||||
|
||||
int msm_g2_cuda_bls12_377(
|
||||
BLS12_377_g2_projective_t* out,
|
||||
BLS12_377_g2_affine_t* points,
|
||||
BLS12_377_scalar_t* scalars,
|
||||
size_t count,
|
||||
size_t device_id);
|
||||
int msm_batch_g2_cuda_bls12_377(
|
||||
BLS12_377_g2_projective_t* out,
|
||||
BLS12_377_g2_affine_t* points,
|
||||
BLS12_377_scalar_t* scalars,
|
||||
size_t batch_size,
|
||||
size_t msm_size,
|
||||
size_t device_id);
|
||||
int commit_g2_cuda_bls12_377(
|
||||
BLS12_377_g2_projective_t* d_out,
|
||||
BLS12_377_scalar_t* d_scalars,
|
||||
BLS12_377_g2_affine_t* d_points,
|
||||
size_t count,
|
||||
unsigned large_bucket_factor,
|
||||
size_t device_id);
|
||||
int commit_batch_g2_cuda_bls12_377(
|
||||
BLS12_377_g2_projective_t* d_out,
|
||||
BLS12_377_scalar_t* d_scalars,
|
||||
BLS12_377_g2_affine_t* d_points,
|
||||
size_t count,
|
||||
size_t batch_size,
|
||||
size_t device_id,
|
||||
cudaStream_t stream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BLS12_377_MSM_H */
|
||||
@@ -1,195 +0,0 @@
|
||||
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
#include <cuda.h>
|
||||
#include <stdbool.h>
|
||||
// ntt.h
|
||||
|
||||
#ifndef _BLS12_377_NTT_H
|
||||
#define _BLS12_377_NTT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Incomplete declaration of BLS12_377 projective and affine structs
|
||||
typedef struct BLS12_377_projective_t BLS12_377_projective_t;
|
||||
typedef struct BLS12_377_affine_t BLS12_377_affine_t;
|
||||
typedef struct BLS12_377_scalar_t BLS12_377_scalar_t;
|
||||
|
||||
typedef struct BLS12_377_g2_projective_t BLS12_377_g2_projective_t;
|
||||
typedef struct BLS12_377_g2_affine_t BLS12_377_g2_affine_t;
|
||||
|
||||
int ntt_cuda_bls12_377(BLS12_377_scalar_t* arr, uint32_t n, bool inverse, size_t device_id);
|
||||
int ntt_batch_cuda_bls12_377(
|
||||
BLS12_377_scalar_t* arr, uint32_t arr_size, uint32_t batch_size, bool inverse, size_t device_id);
|
||||
|
||||
int ecntt_cuda_bls12_377(BLS12_377_projective_t* arr, uint32_t n, bool inverse, size_t device_id);
|
||||
int ecntt_batch_cuda_bls12_377(
|
||||
BLS12_377_projective_t* arr, uint32_t arr_size, uint32_t batch_size, bool inverse, size_t device_id);
|
||||
|
||||
BLS12_377_scalar_t*
|
||||
build_domain_cuda_bls12_377(uint32_t domain_size, uint32_t logn, bool inverse, size_t device_id, size_t stream);
|
||||
int interpolate_scalars_cuda_bls12_377(
|
||||
BLS12_377_scalar_t* d_out,
|
||||
BLS12_377_scalar_t* d_evaluations,
|
||||
BLS12_377_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned device_id,
|
||||
size_t stream);
|
||||
int interpolate_scalars_batch_cuda_bls12_377(
|
||||
BLS12_377_scalar_t* d_out,
|
||||
BLS12_377_scalar_t* d_evaluations,
|
||||
BLS12_377_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int interpolate_points_cuda_bls12_377(
|
||||
BLS12_377_projective_t* d_out,
|
||||
BLS12_377_projective_t* d_evaluations,
|
||||
BLS12_377_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int interpolate_points_batch_cuda_bls12_377(
|
||||
BLS12_377_projective_t* d_out,
|
||||
BLS12_377_projective_t* d_evaluations,
|
||||
BLS12_377_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int interpolate_scalars_on_coset_cuda_bls12_377(
|
||||
BLS12_377_scalar_t* d_out,
|
||||
BLS12_377_scalar_t* d_evaluations,
|
||||
BLS12_377_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
BLS12_377_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int interpolate_scalars_batch_on_coset_cuda_bls12_377(
|
||||
BLS12_377_scalar_t* d_out,
|
||||
BLS12_377_scalar_t* d_evaluations,
|
||||
BLS12_377_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
BLS12_377_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_scalars_cuda_bls12_377(
|
||||
BLS12_377_scalar_t* d_out,
|
||||
BLS12_377_scalar_t* d_coefficients,
|
||||
BLS12_377_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned device_id,
|
||||
size_t stream);
|
||||
int evaluate_scalars_batch_cuda_bls12_377(
|
||||
BLS12_377_scalar_t* d_out,
|
||||
BLS12_377_scalar_t* d_coefficients,
|
||||
BLS12_377_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_points_cuda_bls12_377(
|
||||
BLS12_377_projective_t* d_out,
|
||||
BLS12_377_projective_t* d_coefficients,
|
||||
BLS12_377_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_points_batch_cuda_bls12_377(
|
||||
BLS12_377_projective_t* d_out,
|
||||
BLS12_377_projective_t* d_coefficients,
|
||||
BLS12_377_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_scalars_on_coset_cuda_bls12_377(
|
||||
BLS12_377_scalar_t* d_out,
|
||||
BLS12_377_scalar_t* d_coefficients,
|
||||
BLS12_377_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
BLS12_377_scalar_t* coset_powers,
|
||||
unsigned device_id,
|
||||
size_t stream);
|
||||
int evaluate_scalars_on_coset_batch_cuda_bls12_377(
|
||||
BLS12_377_scalar_t* d_out,
|
||||
BLS12_377_scalar_t* d_coefficients,
|
||||
BLS12_377_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
BLS12_377_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_points_on_coset_cuda_bls12_377(
|
||||
BLS12_377_projective_t* d_out,
|
||||
BLS12_377_projective_t* d_coefficients,
|
||||
BLS12_377_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
BLS12_377_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_points_on_coset_batch_cuda_bls12_377(
|
||||
BLS12_377_projective_t* d_out,
|
||||
BLS12_377_projective_t* d_coefficients,
|
||||
BLS12_377_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
BLS12_377_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int reverse_order_scalars_cuda_bls12_377(BLS12_377_scalar_t* arr, int n, size_t device_id, size_t stream);
|
||||
int reverse_order_scalars_batch_cuda_bls12_377(
|
||||
BLS12_377_scalar_t* arr, int n, int batch_size, size_t device_id, size_t stream);
|
||||
int reverse_order_points_cuda_bls12_377(BLS12_377_projective_t* arr, int n, size_t device_id, size_t stream);
|
||||
int reverse_order_points_batch_cuda_bls12_377(
|
||||
BLS12_377_projective_t* arr, int n, int batch_size, size_t device_id, size_t stream);
|
||||
int add_scalars_cuda_bls12_377(
|
||||
BLS12_377_scalar_t* d_out, BLS12_377_scalar_t* d_in1, BLS12_377_scalar_t* d_in2, unsigned n, size_t stream);
|
||||
int sub_scalars_cuda_bls12_377(
|
||||
BLS12_377_scalar_t* d_out, BLS12_377_scalar_t* d_in1, BLS12_377_scalar_t* d_in2, unsigned n, size_t stream);
|
||||
int to_montgomery_scalars_cuda_bls12_377(BLS12_377_scalar_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_scalars_cuda_bls12_377(BLS12_377_scalar_t* d_inout, unsigned n, size_t stream);
|
||||
|
||||
// points g1
|
||||
int to_montgomery_proj_points_cuda_bls12_377(BLS12_377_projective_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_proj_points_cuda_bls12_377(BLS12_377_projective_t* d_inout, unsigned n, size_t stream);
|
||||
int to_montgomery_aff_points_cuda_bls12_377(BLS12_377_affine_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_aff_points_cuda_bls12_377(BLS12_377_affine_t* d_inout, unsigned n, size_t stream);
|
||||
|
||||
// points g2
|
||||
int to_montgomery_proj_points_g2_cuda_bls12_377(BLS12_377_g2_projective_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_proj_points_g2_cuda_bls12_377(BLS12_377_g2_projective_t* d_inout, unsigned n, size_t stream);
|
||||
int to_montgomery_aff_points_g2_cuda_bls12_377(BLS12_377_g2_affine_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_aff_points_g2_cuda_bls12_377(BLS12_377_g2_affine_t* d_inout, unsigned n, size_t stream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BLS12_377_NTT_H */
|
||||
@@ -1,50 +0,0 @@
|
||||
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
#include <cuda.h>
|
||||
#include <stdbool.h>
|
||||
// projective.h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct BLS12_377_projective_t BLS12_377_projective_t;
|
||||
typedef struct BLS12_377_g2_projective_t BLS12_377_g2_projective_t;
|
||||
typedef struct BLS12_377_affine_t BLS12_377_affine_t;
|
||||
typedef struct BLS12_377_g2_affine_t BLS12_377_g2_affine_t;
|
||||
typedef struct BLS12_377_scalar_t BLS12_377_scalar_t;
|
||||
|
||||
bool projective_is_on_curve_bls12_377(BLS12_377_projective_t* point1);
|
||||
|
||||
int random_scalar_bls12_377(BLS12_377_scalar_t* out);
|
||||
int random_projective_bls12_377(BLS12_377_projective_t* out);
|
||||
BLS12_377_projective_t* projective_zero_bls12_377();
|
||||
int projective_to_affine_bls12_377(BLS12_377_affine_t* out, BLS12_377_projective_t* point1);
|
||||
int projective_from_affine_bls12_377(BLS12_377_projective_t* out, BLS12_377_affine_t* point1);
|
||||
|
||||
int random_g2_projective_bls12_377(BLS12_377_g2_projective_t* out);
|
||||
int g2_projective_to_affine_bls12_377(BLS12_377_g2_affine_t* out, BLS12_377_g2_projective_t* point1);
|
||||
int g2_projective_from_affine_bls12_377(BLS12_377_g2_projective_t* out, BLS12_377_g2_affine_t* point1);
|
||||
bool g2_projective_is_on_curve_bls12_377(BLS12_377_g2_projective_t* point1);
|
||||
|
||||
bool eq_bls12_377(BLS12_377_projective_t* point1, BLS12_377_projective_t* point2);
|
||||
bool eq_g2_bls12_377(BLS12_377_g2_projective_t* point1, BLS12_377_g2_projective_t* point2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,49 +0,0 @@
|
||||
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
#include <cuda.h>
|
||||
#include <stdbool.h>
|
||||
// ve_mod_mult.h
|
||||
|
||||
#ifndef _BLS12_377_VEC_MULT_H
|
||||
#define _BLS12_377_VEC_MULT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct BLS12_377_projective_t BLS12_377_projective_t;
|
||||
typedef struct BLS12_377_scalar_t BLS12_377_scalar_t;
|
||||
|
||||
int32_t vec_mod_mult_point_bls12_377(
|
||||
BLS12_377_projective_t* inout, BLS12_377_scalar_t* scalar_vec, size_t n_elments, size_t device_id);
|
||||
int32_t vec_mod_mult_scalar_bls12_377(
|
||||
BLS12_377_scalar_t* inout, BLS12_377_scalar_t* scalar_vec, size_t n_elments, size_t device_id);
|
||||
int32_t vec_mod_mult_device_scalar_bls12_377(
|
||||
BLS12_377_scalar_t* inout, BLS12_377_scalar_t* scalar_vec, size_t n_elements, size_t device_id);
|
||||
int32_t matrix_vec_mod_mult_bls12_377(
|
||||
BLS12_377_scalar_t* matrix_flattened,
|
||||
BLS12_377_scalar_t* input,
|
||||
BLS12_377_scalar_t* output,
|
||||
size_t n_elments,
|
||||
size_t device_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BLS12_377_VEC_MULT_H */
|
||||
@@ -1,208 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bls12377
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ -lbls12_377
|
||||
// #include "msm.h"
|
||||
import "C"
|
||||
|
||||
func Msm(out *G1ProjectivePoint, points []G1PointAffine, scalars []G1ScalarField, device_id int) (*G1ProjectivePoint, error) {
|
||||
if len(points) != len(scalars) {
|
||||
return nil, errors.New("error on: len(points) != len(scalars)")
|
||||
}
|
||||
|
||||
pointsC := (*C.BLS12_377_affine_t)(unsafe.Pointer(&points[0]))
|
||||
scalarsC := (*C.BLS12_377_scalar_t)(unsafe.Pointer(&scalars[0]))
|
||||
outC := (*C.BLS12_377_projective_t)(unsafe.Pointer(out))
|
||||
ret := C.msm_cuda_bls12_377(outC, pointsC, scalarsC, C.size_t(len(points)), C.size_t(device_id))
|
||||
|
||||
if ret != 0 {
|
||||
return nil, fmt.Errorf("msm_cuda_bls12_377 returned error code: %d", ret)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func MsmG2(out *G2Point, points []G2PointAffine, scalars []G1ScalarField, device_id int) (*G2Point, error) {
|
||||
if len(points) != len(scalars) {
|
||||
return nil, errors.New("error on: len(points) != len(scalars)")
|
||||
}
|
||||
|
||||
pointsC := (*C.BLS12_377_g2_affine_t)(unsafe.Pointer(&points[0]))
|
||||
scalarsC := (*C.BLS12_377_scalar_t)(unsafe.Pointer(&scalars[0]))
|
||||
outC := (*C.BLS12_377_g2_projective_t)(unsafe.Pointer(out))
|
||||
|
||||
ret := C.msm_g2_cuda_bls12_377(outC, pointsC, scalarsC, C.size_t(len(points)), C.size_t(device_id))
|
||||
|
||||
if ret != 0 {
|
||||
return nil, fmt.Errorf("msm_g2_cuda_bls12_377 returned error code: %d", ret)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func MsmBatch(points *[]G1PointAffine, scalars *[]G1ScalarField, batchSize, deviceId int) ([]*G1ProjectivePoint, error) {
|
||||
// Check for nil pointers
|
||||
if points == nil || scalars == nil {
|
||||
return nil, errors.New("points or scalars is nil")
|
||||
}
|
||||
|
||||
if len(*points) != len(*scalars) {
|
||||
return nil, errors.New("error on: len(points) != len(scalars)")
|
||||
}
|
||||
|
||||
// Check for empty slices
|
||||
if len(*points) == 0 || len(*scalars) == 0 {
|
||||
return nil, errors.New("points or scalars is empty")
|
||||
}
|
||||
|
||||
// Check for zero batchSize
|
||||
if batchSize <= 0 {
|
||||
return nil, errors.New("error on: batchSize must be greater than zero")
|
||||
}
|
||||
|
||||
out := make([]*G1ProjectivePoint, batchSize)
|
||||
|
||||
for i := 0; i < len(out); i++ {
|
||||
var p G1ProjectivePoint
|
||||
p.SetZero()
|
||||
|
||||
out[i] = &p
|
||||
}
|
||||
|
||||
outC := (*C.BLS12_377_projective_t)(unsafe.Pointer(&out[0]))
|
||||
pointsC := (*C.BLS12_377_affine_t)(unsafe.Pointer(&(*points)[0]))
|
||||
scalarsC := (*C.BLS12_377_scalar_t)(unsafe.Pointer(&(*scalars)[0]))
|
||||
msmSizeC := C.size_t(len(*points) / batchSize)
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
batchSizeC := C.size_t(batchSize)
|
||||
|
||||
ret := C.msm_batch_cuda_bls12_377(outC, pointsC, scalarsC, batchSizeC, msmSizeC, deviceIdC)
|
||||
if ret != 0 {
|
||||
return nil, fmt.Errorf("msm_batch_cuda_bls12_377 returned error code: %d", ret)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func MsmG2Batch(points *[]G2PointAffine, scalars *[]G1ScalarField, batchSize, deviceId int) ([]*G2Point, error) {
|
||||
// Check for nil pointers
|
||||
if points == nil || scalars == nil {
|
||||
return nil, errors.New("points or scalars is nil")
|
||||
}
|
||||
|
||||
if len(*points) != len(*scalars) {
|
||||
return nil, errors.New("error on: len(points) != len(scalars)")
|
||||
}
|
||||
|
||||
// Check for empty slices
|
||||
if len(*points) == 0 || len(*scalars) == 0 {
|
||||
return nil, errors.New("points or scalars is empty")
|
||||
}
|
||||
|
||||
// Check for zero batchSize
|
||||
if batchSize <= 0 {
|
||||
return nil, errors.New("error on: batchSize must be greater than zero")
|
||||
}
|
||||
|
||||
out := make([]*G2Point, batchSize)
|
||||
|
||||
outC := (*C.BLS12_377_g2_projective_t)(unsafe.Pointer(&out[0]))
|
||||
pointsC := (*C.BLS12_377_g2_affine_t)(unsafe.Pointer(&(*points)[0]))
|
||||
scalarsC := (*C.BLS12_377_scalar_t)(unsafe.Pointer(&(*scalars)[0]))
|
||||
msmSizeC := C.size_t(len(*points) / batchSize)
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
batchSizeC := C.size_t(batchSize)
|
||||
|
||||
ret := C.msm_batch_g2_cuda_bls12_377(outC, pointsC, scalarsC, batchSizeC, msmSizeC, deviceIdC)
|
||||
if ret != 0 {
|
||||
return nil, fmt.Errorf("msm_batch_cuda_bls12_377 returned error code: %d", ret)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func Commit(d_out, d_scalars, d_points unsafe.Pointer, count, bucketFactor int) int {
|
||||
d_outC := (*C.BLS12_377_projective_t)(d_out)
|
||||
scalarsC := (*C.BLS12_377_scalar_t)(d_scalars)
|
||||
pointsC := (*C.BLS12_377_affine_t)(d_points)
|
||||
countC := (C.size_t)(count)
|
||||
largeBucketFactorC := C.uint(bucketFactor)
|
||||
|
||||
ret := C.commit_cuda_bls12_377(d_outC, scalarsC, pointsC, countC, largeBucketFactorC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func CommitG2(d_out, d_scalars, d_points unsafe.Pointer, count, bucketFactor int) int {
|
||||
d_outC := (*C.BLS12_377_g2_projective_t)(d_out)
|
||||
scalarsC := (*C.BLS12_377_scalar_t)(d_scalars)
|
||||
pointsC := (*C.BLS12_377_g2_affine_t)(d_points)
|
||||
countC := (C.size_t)(count)
|
||||
largeBucketFactorC := C.uint(bucketFactor)
|
||||
|
||||
ret := C.commit_g2_cuda_bls12_377(d_outC, scalarsC, pointsC, countC, largeBucketFactorC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func CommitBatch(d_out, d_scalars, d_points unsafe.Pointer, count, batch_size int) int {
|
||||
d_outC := (*C.BLS12_377_projective_t)(d_out)
|
||||
scalarsC := (*C.BLS12_377_scalar_t)(d_scalars)
|
||||
pointsC := (*C.BLS12_377_affine_t)(d_points)
|
||||
countC := (C.size_t)(count)
|
||||
batch_sizeC := (C.size_t)(batch_size)
|
||||
|
||||
ret := C.commit_batch_cuda_bls12_377(d_outC, scalarsC, pointsC, countC, batch_sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func CommitG2Batch(d_out, d_scalars, d_points unsafe.Pointer, count, batch_size int) int {
|
||||
d_outC := (*C.BLS12_377_g2_projective_t)(d_out)
|
||||
scalarsC := (*C.BLS12_377_scalar_t)(d_scalars)
|
||||
pointsC := (*C.BLS12_377_g2_affine_t)(d_points)
|
||||
countC := (C.size_t)(count)
|
||||
batch_sizeC := (C.size_t)(batch_size)
|
||||
|
||||
ret := C.msm_batch_g2_cuda_bls12_377(d_outC, pointsC, scalarsC, countC, batch_sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -1,355 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bls12377
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"testing"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/goicicle"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func GeneratePoints(count int) []G1PointAffine {
|
||||
// Declare a slice of integers
|
||||
var points []G1PointAffine
|
||||
|
||||
// populate the slice
|
||||
for i := 0; i < 10; i++ {
|
||||
var pointProjective G1ProjectivePoint
|
||||
pointProjective.Random()
|
||||
|
||||
var pointAffine G1PointAffine
|
||||
pointAffine.FromProjective(&pointProjective)
|
||||
|
||||
points = append(points, pointAffine)
|
||||
}
|
||||
|
||||
log2_10 := math.Log2(10)
|
||||
log2Count := math.Log2(float64(count))
|
||||
log2Size := int(math.Ceil(log2Count - log2_10))
|
||||
|
||||
for i := 0; i < log2Size; i++ {
|
||||
points = append(points, points...)
|
||||
}
|
||||
|
||||
return points[:count]
|
||||
}
|
||||
|
||||
func GeneratePointsProj(count int) []G1ProjectivePoint {
|
||||
// Declare a slice of integers
|
||||
var points []G1ProjectivePoint
|
||||
// Use a loop to populate the slice
|
||||
for i := 0; i < count; i++ {
|
||||
var p G1ProjectivePoint
|
||||
p.Random()
|
||||
|
||||
points = append(points, p)
|
||||
}
|
||||
|
||||
return points
|
||||
}
|
||||
|
||||
func GenerateScalars(count int, skewed bool) []G1ScalarField {
|
||||
// Declare a slice of integers
|
||||
var scalars []G1ScalarField
|
||||
|
||||
var rand G1ScalarField
|
||||
var zero G1ScalarField
|
||||
var one G1ScalarField
|
||||
var randLarge G1ScalarField
|
||||
|
||||
zero.SetZero()
|
||||
one.SetOne()
|
||||
randLarge.Random()
|
||||
|
||||
if skewed && count > 1_200_000 {
|
||||
for i := 0; i < count-1_200_000; i++ {
|
||||
rand.Random()
|
||||
scalars = append(scalars, rand)
|
||||
}
|
||||
|
||||
for i := 0; i < 600_000; i++ {
|
||||
scalars = append(scalars, randLarge)
|
||||
}
|
||||
for i := 0; i < 400_000; i++ {
|
||||
scalars = append(scalars, zero)
|
||||
}
|
||||
for i := 0; i < 200_000; i++ {
|
||||
scalars = append(scalars, one)
|
||||
}
|
||||
} else {
|
||||
for i := 0; i < count; i++ {
|
||||
rand.Random()
|
||||
scalars = append(scalars, rand)
|
||||
}
|
||||
}
|
||||
|
||||
return scalars[:count]
|
||||
}
|
||||
|
||||
func TestMSM(t *testing.T) {
|
||||
for _, v := range []int{24} {
|
||||
count := 1 << v
|
||||
|
||||
points := GeneratePoints(count)
|
||||
fmt.Print("Finished generating points\n")
|
||||
scalars := GenerateScalars(count, true)
|
||||
fmt.Print("Finished generating scalars\n")
|
||||
|
||||
out := new(G1ProjectivePoint)
|
||||
startTime := time.Now()
|
||||
_, e := Msm(out, points, scalars, 0) // non mont
|
||||
fmt.Printf("icicle MSM took: %d ms\n", time.Since(startTime).Milliseconds())
|
||||
|
||||
assert.Equal(t, e, nil, "error should be nil")
|
||||
|
||||
assert.True(t, out.IsOnCurve())
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommitMSM(t *testing.T) {
|
||||
for _, v := range []int{24} {
|
||||
count := 1<<v - 1
|
||||
|
||||
points := GeneratePoints(count)
|
||||
fmt.Print("Finished generating points\n")
|
||||
scalars := GenerateScalars(count, true)
|
||||
fmt.Print("Finished generating scalars\n")
|
||||
|
||||
out_d, _ := goicicle.CudaMalloc(96)
|
||||
|
||||
pointsBytes := count * 64
|
||||
points_d, _ := goicicle.CudaMalloc(pointsBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1PointAffine](points_d, points, pointsBytes)
|
||||
|
||||
scalarBytes := count * 32
|
||||
scalars_d, _ := goicicle.CudaMalloc(scalarBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1ScalarField](scalars_d, scalars, scalarBytes)
|
||||
|
||||
startTime := time.Now()
|
||||
e := Commit(out_d, scalars_d, points_d, count, 10)
|
||||
fmt.Printf("icicle MSM took: %d ms\n", time.Since(startTime).Milliseconds())
|
||||
|
||||
outHost := make([]G1ProjectivePoint, 1)
|
||||
goicicle.CudaMemCpyDtoH[G1ProjectivePoint](outHost, out_d, 96)
|
||||
|
||||
assert.Equal(t, e, 0, "error should be 0")
|
||||
assert.True(t, outHost[0].IsOnCurve())
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCommit(b *testing.B) {
|
||||
LOG_MSM_SIZES := []int{20, 21, 22, 23, 24, 25, 26}
|
||||
|
||||
for _, logMsmSize := range LOG_MSM_SIZES {
|
||||
msmSize := 1 << logMsmSize
|
||||
points := GeneratePoints(msmSize)
|
||||
scalars := GenerateScalars(msmSize, false)
|
||||
|
||||
out_d, _ := goicicle.CudaMalloc(96)
|
||||
|
||||
pointsBytes := msmSize * 64
|
||||
points_d, _ := goicicle.CudaMalloc(pointsBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1PointAffine](points_d, points, pointsBytes)
|
||||
|
||||
scalarBytes := msmSize * 32
|
||||
scalars_d, _ := goicicle.CudaMalloc(scalarBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1ScalarField](scalars_d, scalars, scalarBytes)
|
||||
|
||||
b.Run(fmt.Sprintf("MSM %d", logMsmSize), func(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
e := Commit(out_d, scalars_d, points_d, msmSize, 10)
|
||||
|
||||
if e != 0 {
|
||||
panic("Error occured")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBenchMSM(t *testing.T) {
|
||||
for _, batchPow2 := range []int{2, 4} {
|
||||
for _, pow2 := range []int{4, 6} {
|
||||
msmSize := 1 << pow2
|
||||
batchSize := 1 << batchPow2
|
||||
count := msmSize * batchSize
|
||||
|
||||
points := GeneratePoints(count)
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
a, e := MsmBatch(&points, &scalars, batchSize, 0)
|
||||
|
||||
if e != nil {
|
||||
t.Errorf("MsmBatchBLS12_377 returned an error: %v", e)
|
||||
}
|
||||
|
||||
if len(a) != batchSize {
|
||||
t.Errorf("Expected length %d, but got %d", batchSize, len(a))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMSM(b *testing.B) {
|
||||
LOG_MSM_SIZES := []int{20, 21, 22, 23, 24, 25, 26}
|
||||
|
||||
for _, logMsmSize := range LOG_MSM_SIZES {
|
||||
msmSize := 1 << logMsmSize
|
||||
points := GeneratePoints(msmSize)
|
||||
scalars := GenerateScalars(msmSize, false)
|
||||
b.Run(fmt.Sprintf("MSM %d", logMsmSize), func(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
out := new(G1ProjectivePoint)
|
||||
_, e := Msm(out, points, scalars, 0)
|
||||
|
||||
if e != nil {
|
||||
panic("Error occured")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// G2
|
||||
func GenerateG2Points(count int) []G2PointAffine {
|
||||
// Declare a slice of integers
|
||||
var points []G2PointAffine
|
||||
|
||||
// populate the slice
|
||||
for i := 0; i < 10; i++ {
|
||||
var p G2Point
|
||||
p.Random()
|
||||
var affine G2PointAffine
|
||||
affine.FromProjective(&p)
|
||||
|
||||
points = append(points, affine)
|
||||
}
|
||||
|
||||
log2_10 := math.Log2(10)
|
||||
log2Count := math.Log2(float64(count))
|
||||
log2Size := int(math.Ceil(log2Count - log2_10))
|
||||
|
||||
for i := 0; i < log2Size; i++ {
|
||||
points = append(points, points...)
|
||||
}
|
||||
|
||||
return points[:count]
|
||||
}
|
||||
|
||||
func TestMsmG2BLS12_377(t *testing.T) {
|
||||
for _, v := range []int{24} {
|
||||
count := 1 << v
|
||||
points := GenerateG2Points(count)
|
||||
fmt.Print("Finished generating points\n")
|
||||
scalars := GenerateScalars(count, false)
|
||||
fmt.Print("Finished generating scalars\n")
|
||||
|
||||
out := new(G2Point)
|
||||
_, e := MsmG2(out, points, scalars, 0)
|
||||
assert.Equal(t, e, nil, "error should be nil")
|
||||
assert.True(t, out.IsOnCurve())
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMsmG2BLS12_377(b *testing.B) {
|
||||
LOG_MSM_SIZES := []int{20, 21, 22, 23, 24, 25, 26}
|
||||
|
||||
for _, logMsmSize := range LOG_MSM_SIZES {
|
||||
msmSize := 1 << logMsmSize
|
||||
points := GenerateG2Points(msmSize)
|
||||
scalars := GenerateScalars(msmSize, false)
|
||||
b.Run(fmt.Sprintf("MSM G2 %d", logMsmSize), func(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
out := new(G2Point)
|
||||
_, e := MsmG2(out, points, scalars, 0)
|
||||
|
||||
if e != nil {
|
||||
panic("Error occured")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommitG2MSM(t *testing.T) {
|
||||
for _, v := range []int{24} {
|
||||
count := 1 << v
|
||||
|
||||
points := GenerateG2Points(count)
|
||||
fmt.Print("Finished generating points\n")
|
||||
scalars := GenerateScalars(count, true)
|
||||
fmt.Print("Finished generating scalars\n")
|
||||
|
||||
var sizeCheckG2PointAffine G2PointAffine
|
||||
inputPointsBytes := count * int(unsafe.Sizeof(sizeCheckG2PointAffine))
|
||||
|
||||
var sizeCheckG2Point G2Point
|
||||
out_d, _ := goicicle.CudaMalloc(int(unsafe.Sizeof(sizeCheckG2Point)))
|
||||
|
||||
points_d, _ := goicicle.CudaMalloc(inputPointsBytes)
|
||||
goicicle.CudaMemCpyHtoD[G2PointAffine](points_d, points, inputPointsBytes)
|
||||
|
||||
scalarBytes := count * 32
|
||||
scalars_d, _ := goicicle.CudaMalloc(scalarBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1ScalarField](scalars_d, scalars, scalarBytes)
|
||||
|
||||
startTime := time.Now()
|
||||
e := CommitG2(out_d, scalars_d, points_d, count, 10)
|
||||
fmt.Printf("icicle MSM took: %d ms\n", time.Since(startTime).Milliseconds())
|
||||
|
||||
outHost := make([]G2Point, 1)
|
||||
goicicle.CudaMemCpyDtoH[G2Point](outHost, out_d, int(unsafe.Sizeof(sizeCheckG2Point)))
|
||||
|
||||
assert.Equal(t, e, 0, "error should be 0")
|
||||
assert.Equal(t, len(outHost), 1)
|
||||
result := outHost[0]
|
||||
|
||||
assert.True(t, result.IsOnCurve())
|
||||
}
|
||||
}
|
||||
|
||||
func TestBatchG2MSM(t *testing.T) {
|
||||
for _, batchPow2 := range []int{2, 4} {
|
||||
for _, pow2 := range []int{4, 6} {
|
||||
msmSize := 1 << pow2
|
||||
batchSize := 1 << batchPow2
|
||||
count := msmSize * batchSize
|
||||
|
||||
points := GenerateG2Points(count)
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
pointsResults, e := MsmG2Batch(&points, &scalars, batchSize, 0)
|
||||
|
||||
if e != nil {
|
||||
t.Errorf("MsmBatchBLS12_377 returned an error: %v", e)
|
||||
}
|
||||
|
||||
if len(pointsResults) != batchSize {
|
||||
t.Errorf("Expected length %d, but got %d", batchSize, len(pointsResults))
|
||||
}
|
||||
|
||||
for _, s := range pointsResults {
|
||||
assert.True(t, s.IsOnCurve())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,221 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bls12377
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/goicicle"
|
||||
)
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ -lbls12_377
|
||||
// #include "ntt.h"
|
||||
import "C"
|
||||
|
||||
const (
|
||||
NONE = 0
|
||||
DIF = 1
|
||||
DIT = 2
|
||||
)
|
||||
|
||||
func Ntt(scalars *[]G1ScalarField, isInverse bool, deviceId int) uint64 {
|
||||
scalarsC := (*C.BLS12_377_scalar_t)(unsafe.Pointer(&(*scalars)[0]))
|
||||
|
||||
ret := C.ntt_cuda_bls12_377(scalarsC, C.uint32_t(len(*scalars)), C.bool(isInverse), C.size_t(deviceId))
|
||||
|
||||
return uint64(ret)
|
||||
}
|
||||
|
||||
func NttBatch(scalars *[]G1ScalarField, isInverse bool, batchSize, deviceId int) uint64 {
|
||||
scalarsC := (*C.BLS12_377_scalar_t)(unsafe.Pointer(&(*scalars)[0]))
|
||||
isInverseC := C.bool(isInverse)
|
||||
batchSizeC := C.uint32_t(batchSize)
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
|
||||
ret := C.ntt_batch_cuda_bls12_377(scalarsC, C.uint32_t(len(*scalars)), batchSizeC, isInverseC, deviceIdC)
|
||||
|
||||
return uint64(ret)
|
||||
}
|
||||
|
||||
func EcNtt(values *[]G1ProjectivePoint, isInverse bool, deviceId int) uint64 {
|
||||
valuesC := (*C.BLS12_377_projective_t)(unsafe.Pointer(&(*values)[0]))
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
isInverseC := C.bool(isInverse)
|
||||
n := C.uint32_t(len(*values))
|
||||
|
||||
ret := C.ecntt_cuda_bls12_377(valuesC, n, isInverseC, deviceIdC)
|
||||
|
||||
return uint64(ret)
|
||||
}
|
||||
|
||||
func EcNttBatch(values *[]G1ProjectivePoint, isInverse bool, batchSize, deviceId int) uint64 {
|
||||
valuesC := (*C.BLS12_377_projective_t)(unsafe.Pointer(&(*values)[0]))
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
isInverseC := C.bool(isInverse)
|
||||
n := C.uint32_t(len(*values))
|
||||
batchSizeC := C.uint32_t(batchSize)
|
||||
|
||||
ret := C.ecntt_batch_cuda_bls12_377(valuesC, n, batchSizeC, isInverseC, deviceIdC)
|
||||
|
||||
return uint64(ret)
|
||||
}
|
||||
|
||||
func GenerateTwiddles(d_size int, log_d_size int, inverse bool) (up unsafe.Pointer, err error) {
|
||||
domain_size := C.uint32_t(d_size)
|
||||
logn := C.uint32_t(log_d_size)
|
||||
is_inverse := C.bool(inverse)
|
||||
|
||||
dp := C.build_domain_cuda_bls12_377(domain_size, logn, is_inverse, 0, 0)
|
||||
|
||||
if dp == nil {
|
||||
err = errors.New("nullptr returned from generating twiddles")
|
||||
return unsafe.Pointer(nil), err
|
||||
}
|
||||
|
||||
return unsafe.Pointer(dp), nil
|
||||
}
|
||||
|
||||
// Reverses d_scalars in-place
|
||||
func ReverseScalars(d_scalars unsafe.Pointer, len int) (int, error) {
|
||||
scalarsC := (*C.BLS12_377_scalar_t)(d_scalars)
|
||||
lenC := C.int(len)
|
||||
if success := C.reverse_order_scalars_cuda_bls12_377(scalarsC, lenC, 0, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func Interpolate(scalars, twiddles, cosetPowers unsafe.Pointer, size int, isCoset bool) unsafe.Pointer {
|
||||
size_d := size * 32
|
||||
dp, err := goicicle.CudaMalloc(size_d)
|
||||
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
d_out := (*C.BLS12_377_scalar_t)(dp)
|
||||
scalarsC := (*C.BLS12_377_scalar_t)(scalars)
|
||||
twiddlesC := (*C.BLS12_377_scalar_t)(twiddles)
|
||||
cosetPowersC := (*C.BLS12_377_scalar_t)(cosetPowers)
|
||||
sizeC := C.uint(size)
|
||||
|
||||
var ret C.int
|
||||
if isCoset {
|
||||
ret = C.interpolate_scalars_on_coset_cuda_bls12_377(d_out, scalarsC, twiddlesC, sizeC, cosetPowersC, 0, 0)
|
||||
} else {
|
||||
ret = C.interpolate_scalars_cuda_bls12_377(d_out, scalarsC, twiddlesC, sizeC, 0, 0)
|
||||
}
|
||||
if ret != 0 {
|
||||
fmt.Print("error interpolating")
|
||||
}
|
||||
|
||||
return unsafe.Pointer(d_out)
|
||||
}
|
||||
|
||||
func Evaluate(scalars_out, scalars, twiddles, coset_powers unsafe.Pointer, scalars_size, twiddles_size int, isCoset bool) int {
|
||||
scalars_outC := (*C.BLS12_377_scalar_t)(scalars_out)
|
||||
scalarsC := (*C.BLS12_377_scalar_t)(scalars)
|
||||
twiddlesC := (*C.BLS12_377_scalar_t)(twiddles)
|
||||
coset_powersC := (*C.BLS12_377_scalar_t)(coset_powers)
|
||||
sizeC := C.uint(scalars_size)
|
||||
twiddlesC_size := C.uint(twiddles_size)
|
||||
|
||||
var ret C.int
|
||||
if isCoset {
|
||||
ret = C.evaluate_scalars_on_coset_cuda_bls12_377(scalars_outC, scalarsC, twiddlesC, twiddlesC_size, sizeC, coset_powersC, 0, 0)
|
||||
} else {
|
||||
ret = C.evaluate_scalars_cuda_bls12_377(scalars_outC, scalarsC, twiddlesC, twiddlesC_size, sizeC, 0, 0)
|
||||
}
|
||||
|
||||
if ret != 0 {
|
||||
fmt.Print("error interpolating")
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func VecScalarAdd(in1_d, in2_d unsafe.Pointer, size int) int {
|
||||
in1_dC := (*C.BLS12_377_scalar_t)(in1_d)
|
||||
in2_dC := (*C.BLS12_377_scalar_t)(in2_d)
|
||||
sizeC := C.uint(size)
|
||||
|
||||
ret := C.add_scalars_cuda_bls12_377(in1_dC, in1_dC, in2_dC, sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
fmt.Print("error adding scalar vectors")
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func VecScalarSub(in1_d, in2_d unsafe.Pointer, size int) int {
|
||||
in1_dC := (*C.BLS12_377_scalar_t)(in1_d)
|
||||
in2_dC := (*C.BLS12_377_scalar_t)(in2_d)
|
||||
sizeC := C.uint(size)
|
||||
|
||||
ret := C.sub_scalars_cuda_bls12_377(in1_dC, in1_dC, in2_dC, sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
fmt.Print("error subtracting scalar vectors")
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func ToMontgomery(d_scalars unsafe.Pointer, len int) (int, error) {
|
||||
scalarsC := (*C.BLS12_377_scalar_t)(d_scalars)
|
||||
lenC := C.uint(len)
|
||||
if success := C.to_montgomery_scalars_cuda_bls12_377(scalarsC, lenC, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func FromMontgomery(d_scalars unsafe.Pointer, len int) (int, error) {
|
||||
scalarsC := (*C.BLS12_377_scalar_t)(d_scalars)
|
||||
lenC := C.uint(len)
|
||||
if success := C.from_montgomery_scalars_cuda_bls12_377(scalarsC, lenC, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func AffinePointFromMontgomery(d_points unsafe.Pointer, len int) (int, error) {
|
||||
pointsC := (*C.BLS12_377_affine_t)(d_points)
|
||||
lenC := C.uint(len)
|
||||
|
||||
if success := C.from_montgomery_aff_points_cuda_bls12_377(pointsC, lenC, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func G2AffinePointFromMontgomery(d_points unsafe.Pointer, len int) (int, error) {
|
||||
pointsC := (*C.BLS12_377_g2_affine_t)(d_points)
|
||||
lenC := C.uint(len)
|
||||
|
||||
if success := C.from_montgomery_aff_points_g2_cuda_bls12_377(pointsC, lenC, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bls12377
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNttBLS12_377BBB(t *testing.T) {
|
||||
count := 1 << 20
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, scalars)
|
||||
NttBatch(&nttResult, false, count, 0)
|
||||
assert.NotEqual(t, nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, nttResult)
|
||||
}
|
||||
|
||||
func TestNttBLS12_377CompareToGnarkDIF(t *testing.T) {
|
||||
count := 1 << 2
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, scalars)
|
||||
Ntt(&nttResult, false, DIF, 0)
|
||||
assert.NotEqual(t, nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, nttResult)
|
||||
}
|
||||
|
||||
func TestINttBLS12_377CompareToGnarkDIT(t *testing.T) {
|
||||
count := 1 << 3
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, scalars)
|
||||
Ntt(&nttResult, true, DIT, 0)
|
||||
assert.NotEqual(t, nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, nttResult)
|
||||
}
|
||||
|
||||
func TestNttBLS12_377(t *testing.T) {
|
||||
count := 1 << 3
|
||||
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, scalars)
|
||||
Ntt(&nttResult, false, NONE, 0)
|
||||
assert.NotEqual(t, nttResult, scalars)
|
||||
|
||||
inttResult := make([]G1ScalarField, len(nttResult))
|
||||
copy(inttResult, nttResult)
|
||||
|
||||
assert.Equal(t, inttResult, nttResult)
|
||||
Ntt(&inttResult, true, NONE, 0)
|
||||
assert.Equal(t, inttResult, scalars)
|
||||
}
|
||||
|
||||
func TestNttBatchBLS12_377(t *testing.T) {
|
||||
count := 1 << 5
|
||||
batches := 4
|
||||
|
||||
scalars := GenerateScalars(count*batches, false)
|
||||
|
||||
var scalarVecOfVec [][]G1ScalarField = make([][]G1ScalarField, 0)
|
||||
|
||||
for i := 0; i < batches; i++ {
|
||||
start := i * count
|
||||
end := (i + 1) * count
|
||||
batch := make([]G1ScalarField, len(scalars[start:end]))
|
||||
copy(batch, scalars[start:end])
|
||||
scalarVecOfVec = append(scalarVecOfVec, batch)
|
||||
}
|
||||
|
||||
nttBatchResult := make([]G1ScalarField, len(scalars))
|
||||
copy(nttBatchResult, scalars)
|
||||
|
||||
NttBatch(&nttBatchResult, false, count, 0)
|
||||
|
||||
var nttResultVecOfVec [][]G1ScalarField
|
||||
|
||||
for i := 0; i < batches; i++ {
|
||||
// Clone the slice
|
||||
clone := make([]G1ScalarField, len(scalarVecOfVec[i]))
|
||||
copy(clone, scalarVecOfVec[i])
|
||||
|
||||
// Add it to the result vector of vectors
|
||||
nttResultVecOfVec = append(nttResultVecOfVec, clone)
|
||||
|
||||
// Call the ntt_bls12_377 function
|
||||
Ntt(&nttResultVecOfVec[i], false, NONE, 0)
|
||||
}
|
||||
|
||||
assert.NotEqual(t, nttBatchResult, scalars)
|
||||
|
||||
// Check that the ntt of each vec of scalars is equal to the intt of the specific batch
|
||||
for i := 0; i < batches; i++ {
|
||||
if !reflect.DeepEqual(nttResultVecOfVec[i], nttBatchResult[i*count:((i+1)*count)]) {
|
||||
t.Errorf("ntt of vec of scalars not equal to intt of specific batch")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkNTT(b *testing.B) {
|
||||
LOG_NTT_SIZES := []int{12, 15, 20, 21, 22, 23, 24, 25, 26}
|
||||
|
||||
for _, logNTTSize := range LOG_NTT_SIZES {
|
||||
nttSize := 1 << logNTTSize
|
||||
b.Run(fmt.Sprintf("NTT %d", logNTTSize), func(b *testing.B) {
|
||||
scalars := GenerateScalars(nttSize, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
for n := 0; n < b.N; n++ {
|
||||
Ntt(&nttResult, false, NONE, 0)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package bls12377
|
||||
|
||||
import "encoding/binary"
|
||||
|
||||
// Function to convert [8]uint32 to [4]uint64
|
||||
func ConvertUint32ArrToUint64Arr(arr32 [8]uint32) [4]uint64 {
|
||||
var arr64 [4]uint64
|
||||
for i := 0; i < len(arr32); i += 2 {
|
||||
arr64[i/2] = (uint64(arr32[i]) << 32) | uint64(arr32[i+1])
|
||||
}
|
||||
return arr64
|
||||
}
|
||||
|
||||
func ConvertUint64ArrToUint32Arr4(arr64 [4]uint64) [8]uint32 {
|
||||
var arr32 [8]uint32
|
||||
for i, v := range arr64 {
|
||||
b := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(b, v)
|
||||
|
||||
arr32[i*2] = binary.LittleEndian.Uint32(b[0:4])
|
||||
arr32[i*2+1] = binary.LittleEndian.Uint32(b[4:8])
|
||||
}
|
||||
|
||||
return arr32
|
||||
}
|
||||
|
||||
func ConvertUint64ArrToUint32Arr6(arr64 [6]uint64) [12]uint32 {
|
||||
var arr32 [12]uint32
|
||||
for i, v := range arr64 {
|
||||
b := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(b, v)
|
||||
|
||||
arr32[i*2] = binary.LittleEndian.Uint32(b[0:4])
|
||||
arr32[i*2+1] = binary.LittleEndian.Uint32(b[4:8])
|
||||
}
|
||||
|
||||
return arr32
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bls12377
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ -lbls12_377
|
||||
// #include "ve_mod_mult.h"
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func VecScalarMulMod(scalarVec1, scalarVec2 unsafe.Pointer, size int) int {
|
||||
scalarVec1C := (*C.BLS12_377_scalar_t)(scalarVec1)
|
||||
scalarVec2C := (*C.BLS12_377_scalar_t)(scalarVec2)
|
||||
sizeC := C.size_t(size)
|
||||
|
||||
ret := C.vec_mod_mult_device_scalar_bls12_377(scalarVec1C, scalarVec2C, sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
fmt.Print("error multiplying scalar vectors")
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -1,324 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bls12381
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ -lbls12_381
|
||||
// #include "projective.h"
|
||||
// #include "ve_mod_mult.h"
|
||||
import "C"
|
||||
|
||||
const SCALAR_SIZE = 8
|
||||
const BASE_SIZE = 12
|
||||
|
||||
type G1ScalarField struct {
|
||||
S [SCALAR_SIZE]uint32
|
||||
}
|
||||
|
||||
type G1BaseField struct {
|
||||
S [BASE_SIZE]uint32
|
||||
}
|
||||
|
||||
/*
|
||||
* BaseField Constrctors
|
||||
*/
|
||||
|
||||
func (f *G1BaseField) SetZero() *G1BaseField {
|
||||
var S [BASE_SIZE]uint32
|
||||
f.S = S
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *G1BaseField) SetOne() *G1BaseField {
|
||||
var S [BASE_SIZE]uint32
|
||||
|
||||
S[0] = 1
|
||||
|
||||
f.S = S
|
||||
return f
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) FromAffine(affine *G1PointAffine) *G1ProjectivePoint {
|
||||
out := (*C.BLS12_381_projective_t)(unsafe.Pointer(p))
|
||||
in := (*C.BLS12_381_affine_t)(unsafe.Pointer(affine))
|
||||
|
||||
C.projective_from_affine_bls12_381(out, in)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (f *G1BaseField) FromLimbs(limbs [BASE_SIZE]uint32) *G1BaseField {
|
||||
copy(f.S[:], limbs[:])
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
/*
|
||||
* BaseField methods
|
||||
*/
|
||||
|
||||
func (f *G1BaseField) Limbs() [BASE_SIZE]uint32 {
|
||||
return f.S
|
||||
}
|
||||
|
||||
func (f *G1BaseField) ToBytesLe() []byte {
|
||||
bytes := make([]byte, len(f.S)*4)
|
||||
for i, v := range f.S {
|
||||
binary.LittleEndian.PutUint32(bytes[i*4:], v)
|
||||
}
|
||||
|
||||
return bytes
|
||||
}
|
||||
|
||||
/*
|
||||
* ScalarField methods
|
||||
*/
|
||||
|
||||
func (p *G1ScalarField) Random() *G1ScalarField {
|
||||
outC := (*C.BLS12_381_scalar_t)(unsafe.Pointer(p))
|
||||
C.random_scalar_bls12_381(outC)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (f *G1ScalarField) SetZero() *G1ScalarField {
|
||||
var S [SCALAR_SIZE]uint32
|
||||
f.S = S
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *G1ScalarField) SetOne() *G1ScalarField {
|
||||
var S [SCALAR_SIZE]uint32
|
||||
S[0] = 1
|
||||
f.S = S
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (a *G1ScalarField) Eq(b *G1ScalarField) bool {
|
||||
for i, v := range a.S {
|
||||
if b.S[i] != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/*
|
||||
* ScalarField methods
|
||||
*/
|
||||
|
||||
func (f *G1ScalarField) Limbs() [SCALAR_SIZE]uint32 {
|
||||
return f.S
|
||||
}
|
||||
|
||||
func (f *G1ScalarField) ToBytesLe() []byte {
|
||||
bytes := make([]byte, len(f.S)*4)
|
||||
for i, v := range f.S {
|
||||
binary.LittleEndian.PutUint32(bytes[i*4:], v)
|
||||
}
|
||||
|
||||
return bytes
|
||||
}
|
||||
|
||||
/*
|
||||
* PointBLS12_381
|
||||
*/
|
||||
|
||||
type G1ProjectivePoint struct {
|
||||
X, Y, Z G1BaseField
|
||||
}
|
||||
|
||||
func (f *G1ProjectivePoint) SetZero() *G1ProjectivePoint {
|
||||
var yOne G1BaseField
|
||||
yOne.SetOne()
|
||||
|
||||
var xZero G1BaseField
|
||||
xZero.SetZero()
|
||||
|
||||
var zZero G1BaseField
|
||||
zZero.SetZero()
|
||||
|
||||
f.X = xZero
|
||||
f.Y = yOne
|
||||
f.Z = zZero
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) Eq(pCompare *G1ProjectivePoint) bool {
|
||||
// Cast *PointBLS12_381 to *C.BLS12_381_projective_t
|
||||
// The unsafe.Pointer cast is necessary because Go doesn't allow direct casts
|
||||
// between different pointer types.
|
||||
// It'S your responsibility to ensure that the types are compatible.
|
||||
pC := (*C.BLS12_381_projective_t)(unsafe.Pointer(p))
|
||||
pCompareC := (*C.BLS12_381_projective_t)(unsafe.Pointer(pCompare))
|
||||
|
||||
// Call the C function
|
||||
// The C function doesn't keep any references to the data,
|
||||
// so it'S fine if the Go garbage collector moves or deletes the data later.
|
||||
return bool(C.eq_bls12_381(pC, pCompareC))
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) IsOnCurve() bool {
|
||||
point := (*C.BLS12_381_projective_t)(unsafe.Pointer(p))
|
||||
res := C.projective_is_on_curve_bls12_381(point)
|
||||
|
||||
return bool(res)
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) Random() *G1ProjectivePoint {
|
||||
outC := (*C.BLS12_381_projective_t)(unsafe.Pointer(p))
|
||||
C.random_projective_bls12_381(outC)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) StripZ() *G1PointAffine {
|
||||
return &G1PointAffine{
|
||||
X: p.X,
|
||||
Y: p.Y,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) FromLimbs(x, y, z *[]uint32) *G1ProjectivePoint {
|
||||
var _x G1BaseField
|
||||
var _y G1BaseField
|
||||
var _z G1BaseField
|
||||
|
||||
_x.FromLimbs(GetFixedLimbs(x))
|
||||
_y.FromLimbs(GetFixedLimbs(y))
|
||||
_z.FromLimbs(GetFixedLimbs(z))
|
||||
|
||||
p.X = _x
|
||||
p.Y = _y
|
||||
p.Z = _z
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
/*
|
||||
* PointAffineNoInfinityBLS12_381
|
||||
*/
|
||||
|
||||
type G1PointAffine struct {
|
||||
X, Y G1BaseField
|
||||
}
|
||||
|
||||
func (p *G1PointAffine) FromProjective(projective *G1ProjectivePoint) *G1PointAffine {
|
||||
in := (*C.BLS12_381_projective_t)(unsafe.Pointer(projective))
|
||||
out := (*C.BLS12_381_affine_t)(unsafe.Pointer(p))
|
||||
|
||||
C.projective_to_affine_bls12_381(out, in)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G1PointAffine) ToProjective() *G1ProjectivePoint {
|
||||
var Z G1BaseField
|
||||
Z.SetOne()
|
||||
|
||||
return &G1ProjectivePoint{
|
||||
X: p.X,
|
||||
Y: p.Y,
|
||||
Z: Z,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *G1PointAffine) FromLimbs(X, Y *[]uint32) *G1PointAffine {
|
||||
var _x G1BaseField
|
||||
var _y G1BaseField
|
||||
|
||||
_x.FromLimbs(GetFixedLimbs(X))
|
||||
_y.FromLimbs(GetFixedLimbs(Y))
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiplication
|
||||
*/
|
||||
|
||||
func MultiplyVec(a []G1ProjectivePoint, b []G1ScalarField, deviceID int) {
|
||||
if len(a) != len(b) {
|
||||
panic("a and b have different lengths")
|
||||
}
|
||||
|
||||
pointsC := (*C.BLS12_381_projective_t)(unsafe.Pointer(&a[0]))
|
||||
scalarsC := (*C.BLS12_381_scalar_t)(unsafe.Pointer(&b[0]))
|
||||
deviceIdC := C.size_t(deviceID)
|
||||
nElementsC := C.size_t(len(a))
|
||||
|
||||
C.vec_mod_mult_point_bls12_381(pointsC, scalarsC, nElementsC, deviceIdC)
|
||||
}
|
||||
|
||||
func MultiplyScalar(a []G1ScalarField, b []G1ScalarField, deviceID int) {
|
||||
if len(a) != len(b) {
|
||||
panic("a and b have different lengths")
|
||||
}
|
||||
|
||||
aC := (*C.BLS12_381_scalar_t)(unsafe.Pointer(&a[0]))
|
||||
bC := (*C.BLS12_381_scalar_t)(unsafe.Pointer(&b[0]))
|
||||
deviceIdC := C.size_t(deviceID)
|
||||
nElementsC := C.size_t(len(a))
|
||||
|
||||
C.vec_mod_mult_scalar_bls12_381(aC, bC, nElementsC, deviceIdC)
|
||||
}
|
||||
|
||||
// Multiply a matrix by a scalar:
|
||||
//
|
||||
// `a` - flattenned matrix;
|
||||
// `b` - vector to multiply `a` by;
|
||||
func MultiplyMatrix(a []G1ScalarField, b []G1ScalarField, deviceID int) {
|
||||
c := make([]G1ScalarField, len(b))
|
||||
for i := range c {
|
||||
var p G1ScalarField
|
||||
p.SetZero()
|
||||
|
||||
c[i] = p
|
||||
}
|
||||
|
||||
aC := (*C.BLS12_381_scalar_t)(unsafe.Pointer(&a[0]))
|
||||
bC := (*C.BLS12_381_scalar_t)(unsafe.Pointer(&b[0]))
|
||||
cC := (*C.BLS12_381_scalar_t)(unsafe.Pointer(&c[0]))
|
||||
deviceIdC := C.size_t(deviceID)
|
||||
nElementsC := C.size_t(len(a))
|
||||
|
||||
C.matrix_vec_mod_mult_bls12_381(aC, bC, cC, nElementsC, deviceIdC)
|
||||
}
|
||||
|
||||
/*
|
||||
* Utils
|
||||
*/
|
||||
|
||||
func GetFixedLimbs(slice *[]uint32) [BASE_SIZE]uint32 {
|
||||
if len(*slice) <= BASE_SIZE {
|
||||
limbs := [BASE_SIZE]uint32{}
|
||||
copy(limbs[:len(*slice)], *slice)
|
||||
return limbs
|
||||
}
|
||||
|
||||
panic("slice has too many elements")
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bls12381
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNewFieldBLS12_381One(t *testing.T) {
|
||||
var oneField G1BaseField
|
||||
oneField.SetOne()
|
||||
|
||||
rawOneField := [8]uint32([8]uint32{0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0})
|
||||
|
||||
assert.Equal(t, oneField.S, rawOneField)
|
||||
}
|
||||
|
||||
func TestNewFieldBLS12_381Zero(t *testing.T) {
|
||||
var zeroField G1BaseField
|
||||
zeroField.SetZero()
|
||||
|
||||
rawZeroField := [8]uint32([8]uint32{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0})
|
||||
|
||||
assert.Equal(t, zeroField.S, rawZeroField)
|
||||
}
|
||||
|
||||
func TestFieldBLS12_381ToBytesLe(t *testing.T) {
|
||||
var p G1ProjectivePoint
|
||||
p.Random()
|
||||
|
||||
expected := make([]byte, len(p.X.S)*4) // each uint32 takes 4 bytes
|
||||
for i, v := range p.X.S {
|
||||
binary.LittleEndian.PutUint32(expected[i*4:], v)
|
||||
}
|
||||
|
||||
assert.Equal(t, p.X.ToBytesLe(), expected)
|
||||
assert.Equal(t, len(p.X.ToBytesLe()), 32)
|
||||
}
|
||||
|
||||
func TestNewPointBLS12_381Zero(t *testing.T) {
|
||||
var pointZero G1ProjectivePoint
|
||||
pointZero.SetZero()
|
||||
|
||||
var baseOne G1BaseField
|
||||
baseOne.SetOne()
|
||||
|
||||
var zeroSanity G1BaseField
|
||||
zeroSanity.SetZero()
|
||||
|
||||
assert.Equal(t, pointZero.X, zeroSanity)
|
||||
assert.Equal(t, pointZero.Y, baseOne)
|
||||
assert.Equal(t, pointZero.Z, zeroSanity)
|
||||
}
|
||||
|
||||
func TestFromProjectiveToAffine(t *testing.T) {
|
||||
var projective G1ProjectivePoint
|
||||
var affine G1PointAffine
|
||||
|
||||
projective.Random()
|
||||
|
||||
affine.FromProjective(&projective)
|
||||
var projective2 G1ProjectivePoint
|
||||
projective2.FromAffine(&affine)
|
||||
|
||||
assert.True(t, projective.IsOnCurve())
|
||||
assert.True(t, projective2.IsOnCurve())
|
||||
assert.True(t, projective.Eq(&projective2))
|
||||
}
|
||||
|
||||
func TestBLS12_381Eq(t *testing.T) {
|
||||
var p1 G1ProjectivePoint
|
||||
p1.Random()
|
||||
var p2 G1ProjectivePoint
|
||||
p2.Random()
|
||||
|
||||
assert.Equal(t, p1.Eq(&p1), true)
|
||||
assert.Equal(t, p1.Eq(&p2), false)
|
||||
}
|
||||
|
||||
func TestBLS12_381StripZ(t *testing.T) {
|
||||
var p1 G1ProjectivePoint
|
||||
p1.Random()
|
||||
|
||||
p2ZLess := p1.StripZ()
|
||||
|
||||
assert.IsType(t, G1PointAffine{}, *p2ZLess)
|
||||
assert.Equal(t, p1.X, p2ZLess.X)
|
||||
assert.Equal(t, p1.Y, p2ZLess.Y)
|
||||
}
|
||||
|
||||
func TestPointBLS12_381fromLimbs(t *testing.T) {
|
||||
var p G1ProjectivePoint
|
||||
p.Random()
|
||||
|
||||
x := p.X.Limbs()
|
||||
y := p.Y.Limbs()
|
||||
z := p.Z.Limbs()
|
||||
|
||||
xSlice := x[:]
|
||||
ySlice := y[:]
|
||||
zSlice := z[:]
|
||||
|
||||
var pFromLimbs G1ProjectivePoint
|
||||
pFromLimbs.FromLimbs(&xSlice, &ySlice, &zSlice)
|
||||
|
||||
assert.Equal(t, pFromLimbs, p)
|
||||
}
|
||||
|
||||
func TestNewPointAffineNoInfinityBLS12_381Zero(t *testing.T) {
|
||||
var zeroP G1PointAffine
|
||||
|
||||
var zeroSanity G1BaseField
|
||||
zeroSanity.SetZero()
|
||||
|
||||
assert.Equal(t, zeroP.X, zeroSanity)
|
||||
assert.Equal(t, zeroP.Y, zeroSanity)
|
||||
}
|
||||
|
||||
func TestPointAffineNoInfinityBLS12_381FromLimbs(t *testing.T) {
|
||||
// Initialize your test values
|
||||
x := [12]uint32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
|
||||
y := [12]uint32{9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
|
||||
xSlice := x[:]
|
||||
ySlice := y[:]
|
||||
|
||||
// Execute your function
|
||||
var result G1PointAffine
|
||||
result.FromLimbs(&xSlice, &ySlice)
|
||||
|
||||
var xBase G1BaseField
|
||||
var yBase G1BaseField
|
||||
xBase.FromLimbs(x)
|
||||
yBase.FromLimbs(y)
|
||||
|
||||
// Define your expected result
|
||||
expected := &G1PointAffine{
|
||||
X: xBase,
|
||||
Y: yBase,
|
||||
}
|
||||
|
||||
// Test if result is as expected
|
||||
assert.Equal(t, result, expected)
|
||||
}
|
||||
|
||||
func TestGetFixedLimbs(t *testing.T) {
|
||||
t.Run("case of valid input of length less than 8", func(t *testing.T) {
|
||||
slice := []uint32{1, 2, 3, 4, 5, 6, 7}
|
||||
expected := [8]uint32{1, 2, 3, 4, 5, 6, 7, 0}
|
||||
|
||||
result := GetFixedLimbs(&slice)
|
||||
assert.Equal(t, result, expected)
|
||||
})
|
||||
|
||||
t.Run("case of valid input of length 8", func(t *testing.T) {
|
||||
slice := []uint32{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
expected := [8]uint32{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
|
||||
result := GetFixedLimbs(&slice)
|
||||
assert.Equal(t, result, expected)
|
||||
})
|
||||
|
||||
t.Run("case of empty input", func(t *testing.T) {
|
||||
slice := []uint32{}
|
||||
expected := [8]uint32{0, 0, 0, 0, 0, 0, 0, 0}
|
||||
|
||||
result := GetFixedLimbs(&slice)
|
||||
assert.Equal(t, result, expected)
|
||||
})
|
||||
|
||||
t.Run("case of input length greater than 8", func(t *testing.T) {
|
||||
slice := []uint32{1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("the code did not panic")
|
||||
}
|
||||
}()
|
||||
|
||||
GetFixedLimbs(&slice)
|
||||
})
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bls12381
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ -lbls12_381
|
||||
// #include "projective.h"
|
||||
// #include "ve_mod_mult.h"
|
||||
import "C"
|
||||
|
||||
// G2 extension field
|
||||
|
||||
type G2Element [6]uint64
|
||||
|
||||
type ExtentionField struct {
|
||||
A0, A1 G2Element
|
||||
}
|
||||
|
||||
type G2PointAffine struct {
|
||||
X, Y ExtentionField
|
||||
}
|
||||
|
||||
type G2Point struct {
|
||||
X, Y, Z ExtentionField
|
||||
}
|
||||
|
||||
func (p *G2Point) Random() *G2Point {
|
||||
outC := (*C.BLS12_381_g2_projective_t)(unsafe.Pointer(p))
|
||||
C.random_g2_projective_bls12_381(outC)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G2Point) FromAffine(affine *G2PointAffine) *G2Point {
|
||||
out := (*C.BLS12_381_g2_projective_t)(unsafe.Pointer(p))
|
||||
in := (*C.BLS12_381_g2_affine_t)(unsafe.Pointer(affine))
|
||||
|
||||
C.g2_projective_from_affine_bls12_381(out, in)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G2Point) Eq(pCompare *G2Point) bool {
|
||||
// Cast *PointBLS12_381 to *C.BLS12_381_projective_t
|
||||
// The unsafe.Pointer cast is necessary because Go doesn't allow direct casts
|
||||
// between different pointer types.
|
||||
// It's your responsibility to ensure that the types are compatible.
|
||||
pC := (*C.BLS12_381_g2_projective_t)(unsafe.Pointer(p))
|
||||
pCompareC := (*C.BLS12_381_g2_projective_t)(unsafe.Pointer(pCompare))
|
||||
|
||||
// Call the C function
|
||||
// The C function doesn't keep any references to the data,
|
||||
// so it's fine if the Go garbage collector moves or deletes the data later.
|
||||
return bool(C.eq_g2_bls12_381(pC, pCompareC))
|
||||
}
|
||||
|
||||
func (f *G2Element) ToBytesLe() []byte {
|
||||
var bytes []byte
|
||||
for _, val := range f {
|
||||
buf := make([]byte, 8) // 8 bytes because uint64 is 64-bit
|
||||
binary.LittleEndian.PutUint64(buf, val)
|
||||
bytes = append(bytes, buf...)
|
||||
}
|
||||
return bytes
|
||||
}
|
||||
|
||||
func (p *G2PointAffine) ToProjective() G2Point {
|
||||
return G2Point{
|
||||
X: p.X,
|
||||
Y: p.Y,
|
||||
Z: ExtentionField{
|
||||
A0: G2Element{1, 0, 0, 0},
|
||||
A1: G2Element{0, 0, 0, 0},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *G2PointAffine) FromProjective(projective *G2Point) *G2PointAffine {
|
||||
out := (*C.BLS12_381_g2_affine_t)(unsafe.Pointer(p))
|
||||
in := (*C.BLS12_381_g2_projective_t)(unsafe.Pointer(projective))
|
||||
|
||||
C.g2_projective_to_affine_bls12_381(out, in)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G2Point) IsOnCurve() bool {
|
||||
// Directly copy memory from the C struct to the Go struct
|
||||
point := (*C.BLS12_381_g2_projective_t)(unsafe.Pointer(p))
|
||||
res := C.g2_projective_is_on_curve_bls12_381(point)
|
||||
|
||||
return bool(res)
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bls12381
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestG2Eqg2(t *testing.T) {
|
||||
var point G2Point
|
||||
|
||||
point.Random()
|
||||
|
||||
assert.True(t, point.Eq(&point))
|
||||
}
|
||||
|
||||
func TestG2FromProjectiveToAffine(t *testing.T) {
|
||||
var projective G2Point
|
||||
var affine G2PointAffine
|
||||
|
||||
projective.Random()
|
||||
|
||||
affine.FromProjective(&projective)
|
||||
var projective2 G2Point
|
||||
projective2.FromAffine(&affine)
|
||||
|
||||
assert.True(t, projective.IsOnCurve())
|
||||
assert.True(t, projective2.IsOnCurve())
|
||||
assert.True(t, projective.Eq(&projective2))
|
||||
}
|
||||
|
||||
func TestG2Eqg2NotEqual(t *testing.T) {
|
||||
var point G2Point
|
||||
point.Random()
|
||||
|
||||
var point2 G2Point
|
||||
point2.Random()
|
||||
|
||||
assert.False(t, point.Eq(&point2))
|
||||
}
|
||||
|
||||
func TestG2ToBytes(t *testing.T) {
|
||||
element := G2Element{0x6546098ea84b6298, 0x4a384533d1f68aca, 0xaa0666972d771336, 0x1569e4a34321993}
|
||||
bytes := element.ToBytesLe()
|
||||
|
||||
assert.Equal(t, bytes, []byte{0x98, 0x62, 0x4b, 0xa8, 0x8e, 0x9, 0x46, 0x65, 0xca, 0x8a, 0xf6, 0xd1, 0x33, 0x45, 0x38, 0x4a, 0x36, 0x13, 0x77, 0x2d, 0x97, 0x66, 0x6, 0xaa, 0x93, 0x19, 0x32, 0x34, 0x4a, 0x9e, 0x56, 0x1})
|
||||
}
|
||||
|
||||
func TestG2ShouldConvertToProjective(t *testing.T) {
|
||||
var pointProjective G2Point
|
||||
var pointAffine G2PointAffine
|
||||
|
||||
pointProjective.Random()
|
||||
pointAffine.FromProjective(&pointProjective)
|
||||
|
||||
proj := pointAffine.ToProjective()
|
||||
|
||||
assert.True(t, proj.IsOnCurve())
|
||||
assert.True(t, pointProjective.Eq(&proj))
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
#include <cuda.h>
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
// msm.h
|
||||
|
||||
#ifndef _BLS12_381_MSM_H
|
||||
#define _BLS12_381_MSM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Incomplete declaration of BLS12_381 projective and affine structs
|
||||
typedef struct BLS12_381_projective_t BLS12_381_projective_t;
|
||||
typedef struct BLS12_381_g2_projective_t BLS12_381_g2_projective_t;
|
||||
typedef struct BLS12_381_affine_t BLS12_381_affine_t;
|
||||
typedef struct BLS12_381_g2_affine_t BLS12_381_g2_affine_t;
|
||||
typedef struct BLS12_381_scalar_t BLS12_381_scalar_t;
|
||||
typedef cudaStream_t CudaStream_t;
|
||||
|
||||
int msm_cuda_bls12_381(
|
||||
BLS12_381_projective_t* out, BLS12_381_affine_t* points, BLS12_381_scalar_t* scalars, size_t count, size_t device_id);
|
||||
|
||||
int msm_batch_cuda_bls12_381(
|
||||
BLS12_381_projective_t* out,
|
||||
BLS12_381_affine_t* points,
|
||||
BLS12_381_scalar_t* scalars,
|
||||
size_t batch_size,
|
||||
size_t msm_size,
|
||||
size_t device_id);
|
||||
|
||||
int commit_cuda_bls12_381(
|
||||
BLS12_381_projective_t* d_out,
|
||||
BLS12_381_scalar_t* d_scalars,
|
||||
BLS12_381_affine_t* d_points,
|
||||
size_t count,
|
||||
unsigned large_bucket_factor,
|
||||
size_t device_id);
|
||||
|
||||
int commit_batch_cuda_bls12_381(
|
||||
BLS12_381_projective_t* d_out,
|
||||
BLS12_381_scalar_t* d_scalars,
|
||||
BLS12_381_affine_t* d_points,
|
||||
size_t count,
|
||||
size_t batch_size,
|
||||
size_t device_id);
|
||||
|
||||
int msm_g2_cuda_bls12_381(
|
||||
BLS12_381_g2_projective_t* out,
|
||||
BLS12_381_g2_affine_t* points,
|
||||
BLS12_381_scalar_t* scalars,
|
||||
size_t count,
|
||||
size_t device_id);
|
||||
int msm_batch_g2_cuda_bls12_381(
|
||||
BLS12_381_g2_projective_t* out,
|
||||
BLS12_381_g2_affine_t* points,
|
||||
BLS12_381_scalar_t* scalars,
|
||||
size_t batch_size,
|
||||
size_t msm_size,
|
||||
size_t device_id);
|
||||
int commit_g2_cuda_bls12_381(
|
||||
BLS12_381_g2_projective_t* d_out,
|
||||
BLS12_381_scalar_t* d_scalars,
|
||||
BLS12_381_g2_affine_t* d_points,
|
||||
size_t count,
|
||||
unsigned large_bucket_factor,
|
||||
size_t device_id);
|
||||
int commit_batch_g2_cuda_bls12_381(
|
||||
BLS12_381_g2_projective_t* d_out,
|
||||
BLS12_381_scalar_t* d_scalars,
|
||||
BLS12_381_g2_affine_t* d_points,
|
||||
size_t count,
|
||||
size_t batch_size,
|
||||
size_t device_id,
|
||||
cudaStream_t stream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BLS12_381_MSM_H */
|
||||
@@ -1,195 +0,0 @@
|
||||
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
#include <cuda.h>
|
||||
#include <stdbool.h>
|
||||
// ntt.h
|
||||
|
||||
#ifndef _BLS12_381_NTT_H
|
||||
#define _BLS12_381_NTT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Incomplete declaration of BLS12_381 projective and affine structs
|
||||
typedef struct BLS12_381_projective_t BLS12_381_projective_t;
|
||||
typedef struct BLS12_381_affine_t BLS12_381_affine_t;
|
||||
typedef struct BLS12_381_scalar_t BLS12_381_scalar_t;
|
||||
|
||||
typedef struct BLS12_381_g2_projective_t BLS12_381_g2_projective_t;
|
||||
typedef struct BLS12_381_g2_affine_t BLS12_381_g2_affine_t;
|
||||
|
||||
int ntt_cuda_bls12_381(BLS12_381_scalar_t* arr, uint32_t n, bool inverse, size_t device_id);
|
||||
int ntt_batch_cuda_bls12_381(
|
||||
BLS12_381_scalar_t* arr, uint32_t arr_size, uint32_t batch_size, bool inverse, size_t device_id);
|
||||
|
||||
int ecntt_cuda_bls12_381(BLS12_381_projective_t* arr, uint32_t n, bool inverse, size_t device_id);
|
||||
int ecntt_batch_cuda_bls12_381(
|
||||
BLS12_381_projective_t* arr, uint32_t arr_size, uint32_t batch_size, bool inverse, size_t device_id);
|
||||
|
||||
BLS12_381_scalar_t*
|
||||
build_domain_cuda_bls12_381(uint32_t domain_size, uint32_t logn, bool inverse, size_t device_id, size_t stream);
|
||||
int interpolate_scalars_cuda_bls12_381(
|
||||
BLS12_381_scalar_t* d_out,
|
||||
BLS12_381_scalar_t* d_evaluations,
|
||||
BLS12_381_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned device_id,
|
||||
size_t stream);
|
||||
int interpolate_scalars_batch_cuda_bls12_381(
|
||||
BLS12_381_scalar_t* d_out,
|
||||
BLS12_381_scalar_t* d_evaluations,
|
||||
BLS12_381_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int interpolate_points_cuda_bls12_381(
|
||||
BLS12_381_projective_t* d_out,
|
||||
BLS12_381_projective_t* d_evaluations,
|
||||
BLS12_381_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int interpolate_points_batch_cuda_bls12_381(
|
||||
BLS12_381_projective_t* d_out,
|
||||
BLS12_381_projective_t* d_evaluations,
|
||||
BLS12_381_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int interpolate_scalars_on_coset_cuda_bls12_381(
|
||||
BLS12_381_scalar_t* d_out,
|
||||
BLS12_381_scalar_t* d_evaluations,
|
||||
BLS12_381_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
BLS12_381_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int interpolate_scalars_batch_on_coset_cuda_bls12_381(
|
||||
BLS12_381_scalar_t* d_out,
|
||||
BLS12_381_scalar_t* d_evaluations,
|
||||
BLS12_381_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
BLS12_381_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_scalars_cuda_bls12_381(
|
||||
BLS12_381_scalar_t* d_out,
|
||||
BLS12_381_scalar_t* d_coefficients,
|
||||
BLS12_381_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned device_id,
|
||||
size_t stream);
|
||||
int evaluate_scalars_batch_cuda_bls12_381(
|
||||
BLS12_381_scalar_t* d_out,
|
||||
BLS12_381_scalar_t* d_coefficients,
|
||||
BLS12_381_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_points_cuda_bls12_381(
|
||||
BLS12_381_projective_t* d_out,
|
||||
BLS12_381_projective_t* d_coefficients,
|
||||
BLS12_381_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_points_batch_cuda_bls12_381(
|
||||
BLS12_381_projective_t* d_out,
|
||||
BLS12_381_projective_t* d_coefficients,
|
||||
BLS12_381_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_scalars_on_coset_cuda_bls12_381(
|
||||
BLS12_381_scalar_t* d_out,
|
||||
BLS12_381_scalar_t* d_coefficients,
|
||||
BLS12_381_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
BLS12_381_scalar_t* coset_powers,
|
||||
unsigned device_id,
|
||||
size_t stream);
|
||||
int evaluate_scalars_on_coset_batch_cuda_bls12_381(
|
||||
BLS12_381_scalar_t* d_out,
|
||||
BLS12_381_scalar_t* d_coefficients,
|
||||
BLS12_381_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
BLS12_381_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_points_on_coset_cuda_bls12_381(
|
||||
BLS12_381_projective_t* d_out,
|
||||
BLS12_381_projective_t* d_coefficients,
|
||||
BLS12_381_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
BLS12_381_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_points_on_coset_batch_cuda_bls12_381(
|
||||
BLS12_381_projective_t* d_out,
|
||||
BLS12_381_projective_t* d_coefficients,
|
||||
BLS12_381_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
BLS12_381_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int reverse_order_scalars_cuda_bls12_381(BLS12_381_scalar_t* arr, int n, size_t device_id, size_t stream);
|
||||
int reverse_order_scalars_batch_cuda_bls12_381(
|
||||
BLS12_381_scalar_t* arr, int n, int batch_size, size_t device_id, size_t stream);
|
||||
int reverse_order_points_cuda_bls12_381(BLS12_381_projective_t* arr, int n, size_t device_id, size_t stream);
|
||||
int reverse_order_points_batch_cuda_bls12_381(
|
||||
BLS12_381_projective_t* arr, int n, int batch_size, size_t device_id, size_t stream);
|
||||
int add_scalars_cuda_bls12_381(
|
||||
BLS12_381_scalar_t* d_out, BLS12_381_scalar_t* d_in1, BLS12_381_scalar_t* d_in2, unsigned n, size_t stream);
|
||||
int sub_scalars_cuda_bls12_381(
|
||||
BLS12_381_scalar_t* d_out, BLS12_381_scalar_t* d_in1, BLS12_381_scalar_t* d_in2, unsigned n, size_t stream);
|
||||
int to_montgomery_scalars_cuda_bls12_381(BLS12_381_scalar_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_scalars_cuda_bls12_381(BLS12_381_scalar_t* d_inout, unsigned n, size_t stream);
|
||||
|
||||
// points g1
|
||||
int to_montgomery_proj_points_cuda_bls12_381(BLS12_381_projective_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_proj_points_cuda_bls12_381(BLS12_381_projective_t* d_inout, unsigned n, size_t stream);
|
||||
int to_montgomery_aff_points_cuda_bls12_381(BLS12_381_affine_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_aff_points_cuda_bls12_381(BLS12_381_affine_t* d_inout, unsigned n, size_t stream);
|
||||
|
||||
// points g2
|
||||
int to_montgomery_proj_points_g2_cuda_bls12_381(BLS12_381_g2_projective_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_proj_points_g2_cuda_bls12_381(BLS12_381_g2_projective_t* d_inout, unsigned n, size_t stream);
|
||||
int to_montgomery_aff_points_g2_cuda_bls12_381(BLS12_381_g2_affine_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_aff_points_g2_cuda_bls12_381(BLS12_381_g2_affine_t* d_inout, unsigned n, size_t stream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BLS12_381_NTT_H */
|
||||
@@ -1,50 +0,0 @@
|
||||
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
#include <cuda.h>
|
||||
#include <stdbool.h>
|
||||
// projective.h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct BLS12_381_projective_t BLS12_381_projective_t;
|
||||
typedef struct BLS12_381_g2_projective_t BLS12_381_g2_projective_t;
|
||||
typedef struct BLS12_381_affine_t BLS12_381_affine_t;
|
||||
typedef struct BLS12_381_g2_affine_t BLS12_381_g2_affine_t;
|
||||
typedef struct BLS12_381_scalar_t BLS12_381_scalar_t;
|
||||
|
||||
bool projective_is_on_curve_bls12_381(BLS12_381_projective_t* point1);
|
||||
|
||||
int random_scalar_bls12_381(BLS12_381_scalar_t* out);
|
||||
int random_projective_bls12_381(BLS12_381_projective_t* out);
|
||||
BLS12_381_projective_t* projective_zero_bls12_381();
|
||||
int projective_to_affine_bls12_381(BLS12_381_affine_t* out, BLS12_381_projective_t* point1);
|
||||
int projective_from_affine_bls12_381(BLS12_381_projective_t* out, BLS12_381_affine_t* point1);
|
||||
|
||||
int random_g2_projective_bls12_381(BLS12_381_g2_projective_t* out);
|
||||
int g2_projective_to_affine_bls12_381(BLS12_381_g2_affine_t* out, BLS12_381_g2_projective_t* point1);
|
||||
int g2_projective_from_affine_bls12_381(BLS12_381_g2_projective_t* out, BLS12_381_g2_affine_t* point1);
|
||||
bool g2_projective_is_on_curve_bls12_381(BLS12_381_g2_projective_t* point1);
|
||||
|
||||
bool eq_bls12_381(BLS12_381_projective_t* point1, BLS12_381_projective_t* point2);
|
||||
bool eq_g2_bls12_381(BLS12_381_g2_projective_t* point1, BLS12_381_g2_projective_t* point2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,49 +0,0 @@
|
||||
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
#include <cuda.h>
|
||||
#include <stdbool.h>
|
||||
// ve_mod_mult.h
|
||||
|
||||
#ifndef _BLS12_381_VEC_MULT_H
|
||||
#define _BLS12_381_VEC_MULT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct BLS12_381_projective_t BLS12_381_projective_t;
|
||||
typedef struct BLS12_381_scalar_t BLS12_381_scalar_t;
|
||||
|
||||
int32_t vec_mod_mult_point_bls12_381(
|
||||
BLS12_381_projective_t* inout, BLS12_381_scalar_t* scalar_vec, size_t n_elments, size_t device_id);
|
||||
int32_t vec_mod_mult_scalar_bls12_381(
|
||||
BLS12_381_scalar_t* inout, BLS12_381_scalar_t* scalar_vec, size_t n_elments, size_t device_id);
|
||||
int32_t vec_mod_mult_device_scalar_bls12_381(
|
||||
BLS12_381_scalar_t* inout, BLS12_381_scalar_t* scalar_vec, size_t n_elements, size_t device_id);
|
||||
int32_t matrix_vec_mod_mult_bls12_381(
|
||||
BLS12_381_scalar_t* matrix_flattened,
|
||||
BLS12_381_scalar_t* input,
|
||||
BLS12_381_scalar_t* output,
|
||||
size_t n_elments,
|
||||
size_t device_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BLS12_381_VEC_MULT_H */
|
||||
@@ -1,208 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bls12381
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ -lbls12_381
|
||||
// #include "msm.h"
|
||||
import "C"
|
||||
|
||||
func Msm(out *G1ProjectivePoint, points []G1PointAffine, scalars []G1ScalarField, device_id int) (*G1ProjectivePoint, error) {
|
||||
if len(points) != len(scalars) {
|
||||
return nil, errors.New("error on: len(points) != len(scalars)")
|
||||
}
|
||||
|
||||
pointsC := (*C.BLS12_381_affine_t)(unsafe.Pointer(&points[0]))
|
||||
scalarsC := (*C.BLS12_381_scalar_t)(unsafe.Pointer(&scalars[0]))
|
||||
outC := (*C.BLS12_381_projective_t)(unsafe.Pointer(out))
|
||||
ret := C.msm_cuda_bls12_381(outC, pointsC, scalarsC, C.size_t(len(points)), C.size_t(device_id))
|
||||
|
||||
if ret != 0 {
|
||||
return nil, fmt.Errorf("msm_cuda_bls12_381 returned error code: %d", ret)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func MsmG2(out *G2Point, points []G2PointAffine, scalars []G1ScalarField, device_id int) (*G2Point, error) {
|
||||
if len(points) != len(scalars) {
|
||||
return nil, errors.New("error on: len(points) != len(scalars)")
|
||||
}
|
||||
|
||||
pointsC := (*C.BLS12_381_g2_affine_t)(unsafe.Pointer(&points[0]))
|
||||
scalarsC := (*C.BLS12_381_scalar_t)(unsafe.Pointer(&scalars[0]))
|
||||
outC := (*C.BLS12_381_g2_projective_t)(unsafe.Pointer(out))
|
||||
|
||||
ret := C.msm_g2_cuda_bls12_381(outC, pointsC, scalarsC, C.size_t(len(points)), C.size_t(device_id))
|
||||
|
||||
if ret != 0 {
|
||||
return nil, fmt.Errorf("msm_g2_cuda_bls12_381 returned error code: %d", ret)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func MsmBatch(points *[]G1PointAffine, scalars *[]G1ScalarField, batchSize, deviceId int) ([]*G1ProjectivePoint, error) {
|
||||
// Check for nil pointers
|
||||
if points == nil || scalars == nil {
|
||||
return nil, errors.New("points or scalars is nil")
|
||||
}
|
||||
|
||||
if len(*points) != len(*scalars) {
|
||||
return nil, errors.New("error on: len(points) != len(scalars)")
|
||||
}
|
||||
|
||||
// Check for empty slices
|
||||
if len(*points) == 0 || len(*scalars) == 0 {
|
||||
return nil, errors.New("points or scalars is empty")
|
||||
}
|
||||
|
||||
// Check for zero batchSize
|
||||
if batchSize <= 0 {
|
||||
return nil, errors.New("error on: batchSize must be greater than zero")
|
||||
}
|
||||
|
||||
out := make([]*G1ProjectivePoint, batchSize)
|
||||
|
||||
for i := 0; i < len(out); i++ {
|
||||
var p G1ProjectivePoint
|
||||
p.SetZero()
|
||||
|
||||
out[i] = &p
|
||||
}
|
||||
|
||||
outC := (*C.BLS12_381_projective_t)(unsafe.Pointer(&out[0]))
|
||||
pointsC := (*C.BLS12_381_affine_t)(unsafe.Pointer(&(*points)[0]))
|
||||
scalarsC := (*C.BLS12_381_scalar_t)(unsafe.Pointer(&(*scalars)[0]))
|
||||
msmSizeC := C.size_t(len(*points) / batchSize)
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
batchSizeC := C.size_t(batchSize)
|
||||
|
||||
ret := C.msm_batch_cuda_bls12_381(outC, pointsC, scalarsC, batchSizeC, msmSizeC, deviceIdC)
|
||||
if ret != 0 {
|
||||
return nil, fmt.Errorf("msm_batch_cuda_bls12_381 returned error code: %d", ret)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func MsmG2Batch(points *[]G2PointAffine, scalars *[]G1ScalarField, batchSize, deviceId int) ([]*G2Point, error) {
|
||||
// Check for nil pointers
|
||||
if points == nil || scalars == nil {
|
||||
return nil, errors.New("points or scalars is nil")
|
||||
}
|
||||
|
||||
if len(*points) != len(*scalars) {
|
||||
return nil, errors.New("error on: len(points) != len(scalars)")
|
||||
}
|
||||
|
||||
// Check for empty slices
|
||||
if len(*points) == 0 || len(*scalars) == 0 {
|
||||
return nil, errors.New("points or scalars is empty")
|
||||
}
|
||||
|
||||
// Check for zero batchSize
|
||||
if batchSize <= 0 {
|
||||
return nil, errors.New("error on: batchSize must be greater than zero")
|
||||
}
|
||||
|
||||
out := make([]*G2Point, batchSize)
|
||||
|
||||
outC := (*C.BLS12_381_g2_projective_t)(unsafe.Pointer(&out[0]))
|
||||
pointsC := (*C.BLS12_381_g2_affine_t)(unsafe.Pointer(&(*points)[0]))
|
||||
scalarsC := (*C.BLS12_381_scalar_t)(unsafe.Pointer(&(*scalars)[0]))
|
||||
msmSizeC := C.size_t(len(*points) / batchSize)
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
batchSizeC := C.size_t(batchSize)
|
||||
|
||||
ret := C.msm_batch_g2_cuda_bls12_381(outC, pointsC, scalarsC, batchSizeC, msmSizeC, deviceIdC)
|
||||
if ret != 0 {
|
||||
return nil, fmt.Errorf("msm_batch_cuda_bls12_381 returned error code: %d", ret)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func Commit(d_out, d_scalars, d_points unsafe.Pointer, count, bucketFactor int) int {
|
||||
d_outC := (*C.BLS12_381_projective_t)(d_out)
|
||||
scalarsC := (*C.BLS12_381_scalar_t)(d_scalars)
|
||||
pointsC := (*C.BLS12_381_affine_t)(d_points)
|
||||
countC := (C.size_t)(count)
|
||||
largeBucketFactorC := C.uint(bucketFactor)
|
||||
|
||||
ret := C.commit_cuda_bls12_381(d_outC, scalarsC, pointsC, countC, largeBucketFactorC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func CommitG2(d_out, d_scalars, d_points unsafe.Pointer, count, bucketFactor int) int {
|
||||
d_outC := (*C.BLS12_381_g2_projective_t)(d_out)
|
||||
scalarsC := (*C.BLS12_381_scalar_t)(d_scalars)
|
||||
pointsC := (*C.BLS12_381_g2_affine_t)(d_points)
|
||||
countC := (C.size_t)(count)
|
||||
largeBucketFactorC := C.uint(bucketFactor)
|
||||
|
||||
ret := C.commit_g2_cuda_bls12_381(d_outC, scalarsC, pointsC, countC, largeBucketFactorC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func CommitBatch(d_out, d_scalars, d_points unsafe.Pointer, count, batch_size int) int {
|
||||
d_outC := (*C.BLS12_381_projective_t)(d_out)
|
||||
scalarsC := (*C.BLS12_381_scalar_t)(d_scalars)
|
||||
pointsC := (*C.BLS12_381_affine_t)(d_points)
|
||||
countC := (C.size_t)(count)
|
||||
batch_sizeC := (C.size_t)(batch_size)
|
||||
|
||||
ret := C.commit_batch_cuda_bls12_381(d_outC, scalarsC, pointsC, countC, batch_sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func CommitG2Batch(d_out, d_scalars, d_points unsafe.Pointer, count, batch_size int) int {
|
||||
d_outC := (*C.BLS12_381_g2_projective_t)(d_out)
|
||||
scalarsC := (*C.BLS12_381_scalar_t)(d_scalars)
|
||||
pointsC := (*C.BLS12_381_g2_affine_t)(d_points)
|
||||
countC := (C.size_t)(count)
|
||||
batch_sizeC := (C.size_t)(batch_size)
|
||||
|
||||
ret := C.msm_batch_g2_cuda_bls12_381(d_outC, pointsC, scalarsC, countC, batch_sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -1,355 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bls12381
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"testing"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/goicicle"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func GeneratePoints(count int) []G1PointAffine {
|
||||
// Declare a slice of integers
|
||||
var points []G1PointAffine
|
||||
|
||||
// populate the slice
|
||||
for i := 0; i < 10; i++ {
|
||||
var pointProjective G1ProjectivePoint
|
||||
pointProjective.Random()
|
||||
|
||||
var pointAffine G1PointAffine
|
||||
pointAffine.FromProjective(&pointProjective)
|
||||
|
||||
points = append(points, pointAffine)
|
||||
}
|
||||
|
||||
log2_10 := math.Log2(10)
|
||||
log2Count := math.Log2(float64(count))
|
||||
log2Size := int(math.Ceil(log2Count - log2_10))
|
||||
|
||||
for i := 0; i < log2Size; i++ {
|
||||
points = append(points, points...)
|
||||
}
|
||||
|
||||
return points[:count]
|
||||
}
|
||||
|
||||
func GeneratePointsProj(count int) []G1ProjectivePoint {
|
||||
// Declare a slice of integers
|
||||
var points []G1ProjectivePoint
|
||||
// Use a loop to populate the slice
|
||||
for i := 0; i < count; i++ {
|
||||
var p G1ProjectivePoint
|
||||
p.Random()
|
||||
|
||||
points = append(points, p)
|
||||
}
|
||||
|
||||
return points
|
||||
}
|
||||
|
||||
func GenerateScalars(count int, skewed bool) []G1ScalarField {
|
||||
// Declare a slice of integers
|
||||
var scalars []G1ScalarField
|
||||
|
||||
var rand G1ScalarField
|
||||
var zero G1ScalarField
|
||||
var one G1ScalarField
|
||||
var randLarge G1ScalarField
|
||||
|
||||
zero.SetZero()
|
||||
one.SetOne()
|
||||
randLarge.Random()
|
||||
|
||||
if skewed && count > 1_200_000 {
|
||||
for i := 0; i < count-1_200_000; i++ {
|
||||
rand.Random()
|
||||
scalars = append(scalars, rand)
|
||||
}
|
||||
|
||||
for i := 0; i < 600_000; i++ {
|
||||
scalars = append(scalars, randLarge)
|
||||
}
|
||||
for i := 0; i < 400_000; i++ {
|
||||
scalars = append(scalars, zero)
|
||||
}
|
||||
for i := 0; i < 200_000; i++ {
|
||||
scalars = append(scalars, one)
|
||||
}
|
||||
} else {
|
||||
for i := 0; i < count; i++ {
|
||||
rand.Random()
|
||||
scalars = append(scalars, rand)
|
||||
}
|
||||
}
|
||||
|
||||
return scalars[:count]
|
||||
}
|
||||
|
||||
func TestMSM(t *testing.T) {
|
||||
for _, v := range []int{24} {
|
||||
count := 1 << v
|
||||
|
||||
points := GeneratePoints(count)
|
||||
fmt.Print("Finished generating points\n")
|
||||
scalars := GenerateScalars(count, true)
|
||||
fmt.Print("Finished generating scalars\n")
|
||||
|
||||
out := new(G1ProjectivePoint)
|
||||
startTime := time.Now()
|
||||
_, e := Msm(out, points, scalars, 0) // non mont
|
||||
fmt.Printf("icicle MSM took: %d ms\n", time.Since(startTime).Milliseconds())
|
||||
|
||||
assert.Equal(t, e, nil, "error should be nil")
|
||||
|
||||
assert.True(t, out.IsOnCurve())
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommitMSM(t *testing.T) {
|
||||
for _, v := range []int{24} {
|
||||
count := 1<<v - 1
|
||||
|
||||
points := GeneratePoints(count)
|
||||
fmt.Print("Finished generating points\n")
|
||||
scalars := GenerateScalars(count, true)
|
||||
fmt.Print("Finished generating scalars\n")
|
||||
|
||||
out_d, _ := goicicle.CudaMalloc(96)
|
||||
|
||||
pointsBytes := count * 64
|
||||
points_d, _ := goicicle.CudaMalloc(pointsBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1PointAffine](points_d, points, pointsBytes)
|
||||
|
||||
scalarBytes := count * 32
|
||||
scalars_d, _ := goicicle.CudaMalloc(scalarBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1ScalarField](scalars_d, scalars, scalarBytes)
|
||||
|
||||
startTime := time.Now()
|
||||
e := Commit(out_d, scalars_d, points_d, count, 10)
|
||||
fmt.Printf("icicle MSM took: %d ms\n", time.Since(startTime).Milliseconds())
|
||||
|
||||
outHost := make([]G1ProjectivePoint, 1)
|
||||
goicicle.CudaMemCpyDtoH[G1ProjectivePoint](outHost, out_d, 96)
|
||||
|
||||
assert.Equal(t, e, 0, "error should be 0")
|
||||
assert.True(t, outHost[0].IsOnCurve())
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCommit(b *testing.B) {
|
||||
LOG_MSM_SIZES := []int{20, 21, 22, 23, 24, 25, 26}
|
||||
|
||||
for _, logMsmSize := range LOG_MSM_SIZES {
|
||||
msmSize := 1 << logMsmSize
|
||||
points := GeneratePoints(msmSize)
|
||||
scalars := GenerateScalars(msmSize, false)
|
||||
|
||||
out_d, _ := goicicle.CudaMalloc(96)
|
||||
|
||||
pointsBytes := msmSize * 64
|
||||
points_d, _ := goicicle.CudaMalloc(pointsBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1PointAffine](points_d, points, pointsBytes)
|
||||
|
||||
scalarBytes := msmSize * 32
|
||||
scalars_d, _ := goicicle.CudaMalloc(scalarBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1ScalarField](scalars_d, scalars, scalarBytes)
|
||||
|
||||
b.Run(fmt.Sprintf("MSM %d", logMsmSize), func(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
e := Commit(out_d, scalars_d, points_d, msmSize, 10)
|
||||
|
||||
if e != 0 {
|
||||
panic("Error occured")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBenchMSM(t *testing.T) {
|
||||
for _, batchPow2 := range []int{2, 4} {
|
||||
for _, pow2 := range []int{4, 6} {
|
||||
msmSize := 1 << pow2
|
||||
batchSize := 1 << batchPow2
|
||||
count := msmSize * batchSize
|
||||
|
||||
points := GeneratePoints(count)
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
a, e := MsmBatch(&points, &scalars, batchSize, 0)
|
||||
|
||||
if e != nil {
|
||||
t.Errorf("MsmBatchBLS12_381 returned an error: %v", e)
|
||||
}
|
||||
|
||||
if len(a) != batchSize {
|
||||
t.Errorf("Expected length %d, but got %d", batchSize, len(a))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMSM(b *testing.B) {
|
||||
LOG_MSM_SIZES := []int{20, 21, 22, 23, 24, 25, 26}
|
||||
|
||||
for _, logMsmSize := range LOG_MSM_SIZES {
|
||||
msmSize := 1 << logMsmSize
|
||||
points := GeneratePoints(msmSize)
|
||||
scalars := GenerateScalars(msmSize, false)
|
||||
b.Run(fmt.Sprintf("MSM %d", logMsmSize), func(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
out := new(G1ProjectivePoint)
|
||||
_, e := Msm(out, points, scalars, 0)
|
||||
|
||||
if e != nil {
|
||||
panic("Error occured")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// G2
|
||||
func GenerateG2Points(count int) []G2PointAffine {
|
||||
// Declare a slice of integers
|
||||
var points []G2PointAffine
|
||||
|
||||
// populate the slice
|
||||
for i := 0; i < 10; i++ {
|
||||
var p G2Point
|
||||
p.Random()
|
||||
var affine G2PointAffine
|
||||
affine.FromProjective(&p)
|
||||
|
||||
points = append(points, affine)
|
||||
}
|
||||
|
||||
log2_10 := math.Log2(10)
|
||||
log2Count := math.Log2(float64(count))
|
||||
log2Size := int(math.Ceil(log2Count - log2_10))
|
||||
|
||||
for i := 0; i < log2Size; i++ {
|
||||
points = append(points, points...)
|
||||
}
|
||||
|
||||
return points[:count]
|
||||
}
|
||||
|
||||
func TestMsmG2BLS12381(t *testing.T) {
|
||||
for _, v := range []int{24} {
|
||||
count := 1 << v
|
||||
points := GenerateG2Points(count)
|
||||
fmt.Print("Finished generating points\n")
|
||||
scalars := GenerateScalars(count, false)
|
||||
fmt.Print("Finished generating scalars\n")
|
||||
|
||||
out := new(G2Point)
|
||||
_, e := MsmG2(out, points, scalars, 0)
|
||||
assert.Equal(t, e, nil, "error should be nil")
|
||||
assert.True(t, out.IsOnCurve())
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMsmG2BLS12381(b *testing.B) {
|
||||
LOG_MSM_SIZES := []int{20, 21, 22, 23, 24, 25, 26}
|
||||
|
||||
for _, logMsmSize := range LOG_MSM_SIZES {
|
||||
msmSize := 1 << logMsmSize
|
||||
points := GenerateG2Points(msmSize)
|
||||
scalars := GenerateScalars(msmSize, false)
|
||||
b.Run(fmt.Sprintf("MSM G2 %d", logMsmSize), func(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
out := new(G2Point)
|
||||
_, e := MsmG2(out, points, scalars, 0)
|
||||
|
||||
if e != nil {
|
||||
panic("Error occured")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommitG2MSM(t *testing.T) {
|
||||
for _, v := range []int{24} {
|
||||
count := 1 << v
|
||||
|
||||
points := GenerateG2Points(count)
|
||||
fmt.Print("Finished generating points\n")
|
||||
scalars := GenerateScalars(count, true)
|
||||
fmt.Print("Finished generating scalars\n")
|
||||
|
||||
var sizeCheckG2PointAffine G2PointAffine
|
||||
inputPointsBytes := count * int(unsafe.Sizeof(sizeCheckG2PointAffine))
|
||||
|
||||
var sizeCheckG2Point G2Point
|
||||
out_d, _ := goicicle.CudaMalloc(int(unsafe.Sizeof(sizeCheckG2Point)))
|
||||
|
||||
points_d, _ := goicicle.CudaMalloc(inputPointsBytes)
|
||||
goicicle.CudaMemCpyHtoD[G2PointAffine](points_d, points, inputPointsBytes)
|
||||
|
||||
scalarBytes := count * 32
|
||||
scalars_d, _ := goicicle.CudaMalloc(scalarBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1ScalarField](scalars_d, scalars, scalarBytes)
|
||||
|
||||
startTime := time.Now()
|
||||
e := CommitG2(out_d, scalars_d, points_d, count, 10)
|
||||
fmt.Printf("icicle MSM took: %d ms\n", time.Since(startTime).Milliseconds())
|
||||
|
||||
outHost := make([]G2Point, 1)
|
||||
goicicle.CudaMemCpyDtoH[G2Point](outHost, out_d, int(unsafe.Sizeof(sizeCheckG2Point)))
|
||||
|
||||
assert.Equal(t, e, 0, "error should be 0")
|
||||
assert.Equal(t, len(outHost), 1)
|
||||
result := outHost[0]
|
||||
|
||||
assert.True(t, result.IsOnCurve())
|
||||
}
|
||||
}
|
||||
|
||||
func TestBatchG2MSM(t *testing.T) {
|
||||
for _, batchPow2 := range []int{2, 4} {
|
||||
for _, pow2 := range []int{4, 6} {
|
||||
msmSize := 1 << pow2
|
||||
batchSize := 1 << batchPow2
|
||||
count := msmSize * batchSize
|
||||
|
||||
points := GenerateG2Points(count)
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
pointsResults, e := MsmG2Batch(&points, &scalars, batchSize, 0)
|
||||
|
||||
if e != nil {
|
||||
t.Errorf("MsmBatchBLS12_381 returned an error: %v", e)
|
||||
}
|
||||
|
||||
if len(pointsResults) != batchSize {
|
||||
t.Errorf("Expected length %d, but got %d", batchSize, len(pointsResults))
|
||||
}
|
||||
|
||||
for _, s := range pointsResults {
|
||||
assert.True(t, s.IsOnCurve())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,221 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bls12381
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/goicicle"
|
||||
)
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ -lbls12_381
|
||||
// #include "ntt.h"
|
||||
import "C"
|
||||
|
||||
const (
|
||||
NONE = 0
|
||||
DIF = 1
|
||||
DIT = 2
|
||||
)
|
||||
|
||||
func Ntt(scalars *[]G1ScalarField, isInverse bool, deviceId int) uint64 {
|
||||
scalarsC := (*C.BLS12_381_scalar_t)(unsafe.Pointer(&(*scalars)[0]))
|
||||
|
||||
ret := C.ntt_cuda_bls12_381(scalarsC, C.uint32_t(len(*scalars)), C.bool(isInverse), C.size_t(deviceId))
|
||||
|
||||
return uint64(ret)
|
||||
}
|
||||
|
||||
func NttBatch(scalars *[]G1ScalarField, isInverse bool, batchSize, deviceId int) uint64 {
|
||||
scalarsC := (*C.BLS12_381_scalar_t)(unsafe.Pointer(&(*scalars)[0]))
|
||||
isInverseC := C.bool(isInverse)
|
||||
batchSizeC := C.uint32_t(batchSize)
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
|
||||
ret := C.ntt_batch_cuda_bls12_381(scalarsC, C.uint32_t(len(*scalars)), batchSizeC, isInverseC, deviceIdC)
|
||||
|
||||
return uint64(ret)
|
||||
}
|
||||
|
||||
func EcNtt(values *[]G1ProjectivePoint, isInverse bool, deviceId int) uint64 {
|
||||
valuesC := (*C.BLS12_381_projective_t)(unsafe.Pointer(&(*values)[0]))
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
isInverseC := C.bool(isInverse)
|
||||
n := C.uint32_t(len(*values))
|
||||
|
||||
ret := C.ecntt_cuda_bls12_381(valuesC, n, isInverseC, deviceIdC)
|
||||
|
||||
return uint64(ret)
|
||||
}
|
||||
|
||||
func EcNttBatch(values *[]G1ProjectivePoint, isInverse bool, batchSize, deviceId int) uint64 {
|
||||
valuesC := (*C.BLS12_381_projective_t)(unsafe.Pointer(&(*values)[0]))
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
isInverseC := C.bool(isInverse)
|
||||
n := C.uint32_t(len(*values))
|
||||
batchSizeC := C.uint32_t(batchSize)
|
||||
|
||||
ret := C.ecntt_batch_cuda_bls12_381(valuesC, n, batchSizeC, isInverseC, deviceIdC)
|
||||
|
||||
return uint64(ret)
|
||||
}
|
||||
|
||||
func GenerateTwiddles(d_size int, log_d_size int, inverse bool) (up unsafe.Pointer, err error) {
|
||||
domain_size := C.uint32_t(d_size)
|
||||
logn := C.uint32_t(log_d_size)
|
||||
is_inverse := C.bool(inverse)
|
||||
|
||||
dp := C.build_domain_cuda_bls12_381(domain_size, logn, is_inverse, 0, 0)
|
||||
|
||||
if dp == nil {
|
||||
err = errors.New("nullptr returned from generating twiddles")
|
||||
return unsafe.Pointer(nil), err
|
||||
}
|
||||
|
||||
return unsafe.Pointer(dp), nil
|
||||
}
|
||||
|
||||
// Reverses d_scalars in-place
|
||||
func ReverseScalars(d_scalars unsafe.Pointer, len int) (int, error) {
|
||||
scalarsC := (*C.BLS12_381_scalar_t)(d_scalars)
|
||||
lenC := C.int(len)
|
||||
if success := C.reverse_order_scalars_cuda_bls12_381(scalarsC, lenC, 0, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func Interpolate(scalars, twiddles, cosetPowers unsafe.Pointer, size int, isCoset bool) unsafe.Pointer {
|
||||
size_d := size * 32
|
||||
dp, err := goicicle.CudaMalloc(size_d)
|
||||
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
d_out := (*C.BLS12_381_scalar_t)(dp)
|
||||
scalarsC := (*C.BLS12_381_scalar_t)(scalars)
|
||||
twiddlesC := (*C.BLS12_381_scalar_t)(twiddles)
|
||||
cosetPowersC := (*C.BLS12_381_scalar_t)(cosetPowers)
|
||||
sizeC := C.uint(size)
|
||||
|
||||
var ret C.int
|
||||
if isCoset {
|
||||
ret = C.interpolate_scalars_on_coset_cuda_bls12_381(d_out, scalarsC, twiddlesC, sizeC, cosetPowersC, 0, 0)
|
||||
} else {
|
||||
ret = C.interpolate_scalars_cuda_bls12_381(d_out, scalarsC, twiddlesC, sizeC, 0, 0)
|
||||
}
|
||||
if ret != 0 {
|
||||
fmt.Print("error interpolating")
|
||||
}
|
||||
|
||||
return unsafe.Pointer(d_out)
|
||||
}
|
||||
|
||||
func Evaluate(scalars_out, scalars, twiddles, coset_powers unsafe.Pointer, scalars_size, twiddles_size int, isCoset bool) int {
|
||||
scalars_outC := (*C.BLS12_381_scalar_t)(scalars_out)
|
||||
scalarsC := (*C.BLS12_381_scalar_t)(scalars)
|
||||
twiddlesC := (*C.BLS12_381_scalar_t)(twiddles)
|
||||
coset_powersC := (*C.BLS12_381_scalar_t)(coset_powers)
|
||||
sizeC := C.uint(scalars_size)
|
||||
twiddlesC_size := C.uint(twiddles_size)
|
||||
|
||||
var ret C.int
|
||||
if isCoset {
|
||||
ret = C.evaluate_scalars_on_coset_cuda_bls12_381(scalars_outC, scalarsC, twiddlesC, twiddlesC_size, sizeC, coset_powersC, 0, 0)
|
||||
} else {
|
||||
ret = C.evaluate_scalars_cuda_bls12_381(scalars_outC, scalarsC, twiddlesC, twiddlesC_size, sizeC, 0, 0)
|
||||
}
|
||||
|
||||
if ret != 0 {
|
||||
fmt.Print("error interpolating")
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func VecScalarAdd(in1_d, in2_d unsafe.Pointer, size int) int {
|
||||
in1_dC := (*C.BLS12_381_scalar_t)(in1_d)
|
||||
in2_dC := (*C.BLS12_381_scalar_t)(in2_d)
|
||||
sizeC := C.uint(size)
|
||||
|
||||
ret := C.add_scalars_cuda_bls12_381(in1_dC, in1_dC, in2_dC, sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
fmt.Print("error adding scalar vectors")
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func VecScalarSub(in1_d, in2_d unsafe.Pointer, size int) int {
|
||||
in1_dC := (*C.BLS12_381_scalar_t)(in1_d)
|
||||
in2_dC := (*C.BLS12_381_scalar_t)(in2_d)
|
||||
sizeC := C.uint(size)
|
||||
|
||||
ret := C.sub_scalars_cuda_bls12_381(in1_dC, in1_dC, in2_dC, sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
fmt.Print("error subtracting scalar vectors")
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func ToMontgomery(d_scalars unsafe.Pointer, len int) (int, error) {
|
||||
scalarsC := (*C.BLS12_381_scalar_t)(d_scalars)
|
||||
lenC := C.uint(len)
|
||||
if success := C.to_montgomery_scalars_cuda_bls12_381(scalarsC, lenC, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func FromMontgomery(d_scalars unsafe.Pointer, len int) (int, error) {
|
||||
scalarsC := (*C.BLS12_381_scalar_t)(d_scalars)
|
||||
lenC := C.uint(len)
|
||||
if success := C.from_montgomery_scalars_cuda_bls12_381(scalarsC, lenC, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func AffinePointFromMontgomery(d_points unsafe.Pointer, len int) (int, error) {
|
||||
pointsC := (*C.BLS12_381_affine_t)(d_points)
|
||||
lenC := C.uint(len)
|
||||
|
||||
if success := C.from_montgomery_aff_points_cuda_bls12_381(pointsC, lenC, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func G2AffinePointFromMontgomery(d_points unsafe.Pointer, len int) (int, error) {
|
||||
pointsC := (*C.BLS12_381_g2_affine_t)(d_points)
|
||||
lenC := C.uint(len)
|
||||
|
||||
if success := C.from_montgomery_aff_points_g2_cuda_bls12_381(pointsC, lenC, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bls12381
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNttBLS12381BBB(t *testing.T) {
|
||||
count := 1 << 20
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, scalars)
|
||||
NttBatch(&nttResult, false, count, 0)
|
||||
assert.NotEqual(t, nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, nttResult)
|
||||
}
|
||||
|
||||
func TestNttBLS12381CompareToGnarkDIF(t *testing.T) {
|
||||
count := 1 << 2
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, scalars)
|
||||
Ntt(&nttResult, false, DIF, 0)
|
||||
assert.NotEqual(t, nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, nttResult)
|
||||
}
|
||||
|
||||
func TestINttBLS12381CompareToGnarkDIT(t *testing.T) {
|
||||
count := 1 << 3
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, scalars)
|
||||
Ntt(&nttResult, true, DIT, 0)
|
||||
assert.NotEqual(t, nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, nttResult)
|
||||
}
|
||||
|
||||
func TestNttBLS12381(t *testing.T) {
|
||||
count := 1 << 3
|
||||
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, scalars)
|
||||
Ntt(&nttResult, false, NONE, 0)
|
||||
assert.NotEqual(t, nttResult, scalars)
|
||||
|
||||
inttResult := make([]G1ScalarField, len(nttResult))
|
||||
copy(inttResult, nttResult)
|
||||
|
||||
assert.Equal(t, inttResult, nttResult)
|
||||
Ntt(&inttResult, true, NONE, 0)
|
||||
assert.Equal(t, inttResult, scalars)
|
||||
}
|
||||
|
||||
func TestNttBatchBLS12381(t *testing.T) {
|
||||
count := 1 << 5
|
||||
batches := 4
|
||||
|
||||
scalars := GenerateScalars(count*batches, false)
|
||||
|
||||
var scalarVecOfVec [][]G1ScalarField = make([][]G1ScalarField, 0)
|
||||
|
||||
for i := 0; i < batches; i++ {
|
||||
start := i * count
|
||||
end := (i + 1) * count
|
||||
batch := make([]G1ScalarField, len(scalars[start:end]))
|
||||
copy(batch, scalars[start:end])
|
||||
scalarVecOfVec = append(scalarVecOfVec, batch)
|
||||
}
|
||||
|
||||
nttBatchResult := make([]G1ScalarField, len(scalars))
|
||||
copy(nttBatchResult, scalars)
|
||||
|
||||
NttBatch(&nttBatchResult, false, count, 0)
|
||||
|
||||
var nttResultVecOfVec [][]G1ScalarField
|
||||
|
||||
for i := 0; i < batches; i++ {
|
||||
// Clone the slice
|
||||
clone := make([]G1ScalarField, len(scalarVecOfVec[i]))
|
||||
copy(clone, scalarVecOfVec[i])
|
||||
|
||||
// Add it to the result vector of vectors
|
||||
nttResultVecOfVec = append(nttResultVecOfVec, clone)
|
||||
|
||||
// Call the ntt_bls12_381 function
|
||||
Ntt(&nttResultVecOfVec[i], false, NONE, 0)
|
||||
}
|
||||
|
||||
assert.NotEqual(t, nttBatchResult, scalars)
|
||||
|
||||
// Check that the ntt of each vec of scalars is equal to the intt of the specific batch
|
||||
for i := 0; i < batches; i++ {
|
||||
if !reflect.DeepEqual(nttResultVecOfVec[i], nttBatchResult[i*count:((i+1)*count)]) {
|
||||
t.Errorf("ntt of vec of scalars not equal to intt of specific batch")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkNTT(b *testing.B) {
|
||||
LOG_NTT_SIZES := []int{12, 15, 20, 21, 22, 23, 24, 25, 26}
|
||||
|
||||
for _, logNTTSize := range LOG_NTT_SIZES {
|
||||
nttSize := 1 << logNTTSize
|
||||
b.Run(fmt.Sprintf("NTT %d", logNTTSize), func(b *testing.B) {
|
||||
scalars := GenerateScalars(nttSize, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
for n := 0; n < b.N; n++ {
|
||||
Ntt(&nttResult, false, NONE, 0)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package bls12381
|
||||
|
||||
import "encoding/binary"
|
||||
|
||||
// Function to convert [8]uint32 to [4]uint64
|
||||
func ConvertUint32ArrToUint64Arr(arr32 [8]uint32) [4]uint64 {
|
||||
var arr64 [4]uint64
|
||||
for i := 0; i < len(arr32); i += 2 {
|
||||
arr64[i/2] = (uint64(arr32[i]) << 32) | uint64(arr32[i+1])
|
||||
}
|
||||
return arr64
|
||||
}
|
||||
|
||||
func ConvertUint64ArrToUint32Arr4(arr64 [4]uint64) [8]uint32 {
|
||||
var arr32 [8]uint32
|
||||
for i, v := range arr64 {
|
||||
b := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(b, v)
|
||||
|
||||
arr32[i*2] = binary.LittleEndian.Uint32(b[0:4])
|
||||
arr32[i*2+1] = binary.LittleEndian.Uint32(b[4:8])
|
||||
}
|
||||
|
||||
return arr32
|
||||
}
|
||||
|
||||
func ConvertUint64ArrToUint32Arr6(arr64 [6]uint64) [12]uint32 {
|
||||
var arr32 [12]uint32
|
||||
for i, v := range arr64 {
|
||||
b := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(b, v)
|
||||
|
||||
arr32[i*2] = binary.LittleEndian.Uint32(b[0:4])
|
||||
arr32[i*2+1] = binary.LittleEndian.Uint32(b[4:8])
|
||||
}
|
||||
|
||||
return arr32
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
package bls12381
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConvertUint32ArrToUint64Arr(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
input [8]uint32
|
||||
want [4]uint64
|
||||
}{
|
||||
{
|
||||
name: "Test with incremental array",
|
||||
input: [8]uint32{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
want: [4]uint64{4294967298, 12884901892, 21474836486, 30064771080},
|
||||
},
|
||||
{
|
||||
name: "Test with all zeros",
|
||||
input: [8]uint32{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
want: [4]uint64{0, 0, 0, 0},
|
||||
},
|
||||
{
|
||||
name: "Test with maximum uint32 values",
|
||||
input: [8]uint32{4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295},
|
||||
want: [4]uint64{18446744073709551615, 18446744073709551615, 18446744073709551615, 18446744073709551615},
|
||||
},
|
||||
{
|
||||
name: "Test with alternating min and max uint32 values",
|
||||
input: [8]uint32{0, 4294967295, 0, 4294967295, 0, 4294967295, 0, 4294967295},
|
||||
want: [4]uint64{4294967295, 4294967295, 4294967295, 4294967295},
|
||||
},
|
||||
{
|
||||
name: "Test with alternating max and min uint32 values",
|
||||
input: [8]uint32{4294967295, 0, 4294967295, 0, 4294967295, 0, 4294967295, 0},
|
||||
want: [4]uint64{18446744069414584320, 18446744069414584320, 18446744069414584320, 18446744069414584320},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got := ConvertUint32ArrToUint64Arr(tc.input)
|
||||
if got != tc.want {
|
||||
t.Errorf("got %v, want %v", got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertUint64ArrToUint32Arr(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
input [6]uint64
|
||||
expected [12]uint32
|
||||
}{
|
||||
{
|
||||
name: "test one",
|
||||
input: [6]uint64{1, 2, 3, 4, 5, 6},
|
||||
expected: [12]uint32{1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0},
|
||||
},
|
||||
{
|
||||
name: "test two",
|
||||
input: [6]uint64{100, 200, 300, 400, 500, 600},
|
||||
expected: [12]uint32{100, 0, 200, 0, 300, 0, 400, 0, 500, 0, 600, 0},
|
||||
},
|
||||
{
|
||||
name: "test three",
|
||||
input: [6]uint64{1000, 2000, 3000, 4000, 5000, 6000},
|
||||
expected: [12]uint32{1000, 0, 2000, 0, 3000, 0, 4000, 0, 5000, 0, 6000, 0},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got := ConvertUint64ArrToUint32Arr6(tc.input)
|
||||
if got != tc.expected {
|
||||
t.Errorf("got %v, want %v", got, tc.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bls12381
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ -lbls12_381
|
||||
// #include "ve_mod_mult.h"
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func VecScalarMulMod(scalarVec1, scalarVec2 unsafe.Pointer, size int) int {
|
||||
scalarVec1C := (*C.BLS12_381_scalar_t)(scalarVec1)
|
||||
scalarVec2C := (*C.BLS12_381_scalar_t)(scalarVec2)
|
||||
sizeC := C.size_t(size)
|
||||
|
||||
ret := C.vec_mod_mult_device_scalar_bls12_381(scalarVec1C, scalarVec2C, sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
fmt.Print("error multiplying scalar vectors")
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -1,324 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bn254
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ -lbn254
|
||||
// #include "projective.h"
|
||||
// #include "ve_mod_mult.h"
|
||||
import "C"
|
||||
|
||||
const SCALAR_SIZE = 8
|
||||
const BASE_SIZE = 8
|
||||
|
||||
type G1ScalarField struct {
|
||||
S [SCALAR_SIZE]uint32
|
||||
}
|
||||
|
||||
type G1BaseField struct {
|
||||
S [BASE_SIZE]uint32
|
||||
}
|
||||
|
||||
/*
|
||||
* BaseField Constrctors
|
||||
*/
|
||||
|
||||
func (f *G1BaseField) SetZero() *G1BaseField {
|
||||
var S [BASE_SIZE]uint32
|
||||
f.S = S
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *G1BaseField) SetOne() *G1BaseField {
|
||||
var S [BASE_SIZE]uint32
|
||||
|
||||
S[0] = 1
|
||||
|
||||
f.S = S
|
||||
return f
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) FromAffine(affine *G1PointAffine) *G1ProjectivePoint {
|
||||
out := (*C.BN254_projective_t)(unsafe.Pointer(p))
|
||||
in := (*C.BN254_affine_t)(unsafe.Pointer(affine))
|
||||
|
||||
C.projective_from_affine_bn254(out, in)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (f *G1BaseField) FromLimbs(limbs [BASE_SIZE]uint32) *G1BaseField {
|
||||
copy(f.S[:], limbs[:])
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
/*
|
||||
* BaseField methods
|
||||
*/
|
||||
|
||||
func (f *G1BaseField) Limbs() [BASE_SIZE]uint32 {
|
||||
return f.S
|
||||
}
|
||||
|
||||
func (f *G1BaseField) ToBytesLe() []byte {
|
||||
bytes := make([]byte, len(f.S)*4)
|
||||
for i, v := range f.S {
|
||||
binary.LittleEndian.PutUint32(bytes[i*4:], v)
|
||||
}
|
||||
|
||||
return bytes
|
||||
}
|
||||
|
||||
/*
|
||||
* ScalarField methods
|
||||
*/
|
||||
|
||||
func (p *G1ScalarField) Random() *G1ScalarField {
|
||||
outC := (*C.BN254_scalar_t)(unsafe.Pointer(p))
|
||||
C.random_scalar_bn254(outC)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (f *G1ScalarField) SetZero() *G1ScalarField {
|
||||
var S [SCALAR_SIZE]uint32
|
||||
f.S = S
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *G1ScalarField) SetOne() *G1ScalarField {
|
||||
var S [SCALAR_SIZE]uint32
|
||||
S[0] = 1
|
||||
f.S = S
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (a *G1ScalarField) Eq(b *G1ScalarField) bool {
|
||||
for i, v := range a.S {
|
||||
if b.S[i] != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/*
|
||||
* ScalarField methods
|
||||
*/
|
||||
|
||||
func (f *G1ScalarField) Limbs() [SCALAR_SIZE]uint32 {
|
||||
return f.S
|
||||
}
|
||||
|
||||
func (f *G1ScalarField) ToBytesLe() []byte {
|
||||
bytes := make([]byte, len(f.S)*4)
|
||||
for i, v := range f.S {
|
||||
binary.LittleEndian.PutUint32(bytes[i*4:], v)
|
||||
}
|
||||
|
||||
return bytes
|
||||
}
|
||||
|
||||
/*
|
||||
* PointBN254
|
||||
*/
|
||||
|
||||
type G1ProjectivePoint struct {
|
||||
X, Y, Z G1BaseField
|
||||
}
|
||||
|
||||
func (f *G1ProjectivePoint) SetZero() *G1ProjectivePoint {
|
||||
var yOne G1BaseField
|
||||
yOne.SetOne()
|
||||
|
||||
var xZero G1BaseField
|
||||
xZero.SetZero()
|
||||
|
||||
var zZero G1BaseField
|
||||
zZero.SetZero()
|
||||
|
||||
f.X = xZero
|
||||
f.Y = yOne
|
||||
f.Z = zZero
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) Eq(pCompare *G1ProjectivePoint) bool {
|
||||
// Cast *PointBN254 to *C.BN254_projective_t
|
||||
// The unsafe.Pointer cast is necessary because Go doesn't allow direct casts
|
||||
// between different pointer types.
|
||||
// It'S your responsibility to ensure that the types are compatible.
|
||||
pC := (*C.BN254_projective_t)(unsafe.Pointer(p))
|
||||
pCompareC := (*C.BN254_projective_t)(unsafe.Pointer(pCompare))
|
||||
|
||||
// Call the C function
|
||||
// The C function doesn't keep any references to the data,
|
||||
// so it'S fine if the Go garbage collector moves or deletes the data later.
|
||||
return bool(C.eq_bn254(pC, pCompareC))
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) IsOnCurve() bool {
|
||||
point := (*C.BN254_projective_t)(unsafe.Pointer(p))
|
||||
res := C.projective_is_on_curve_bn254(point)
|
||||
|
||||
return bool(res)
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) Random() *G1ProjectivePoint {
|
||||
outC := (*C.BN254_projective_t)(unsafe.Pointer(p))
|
||||
C.random_projective_bn254(outC)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) StripZ() *G1PointAffine {
|
||||
return &G1PointAffine{
|
||||
X: p.X,
|
||||
Y: p.Y,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) FromLimbs(x, y, z *[]uint32) *G1ProjectivePoint {
|
||||
var _x G1BaseField
|
||||
var _y G1BaseField
|
||||
var _z G1BaseField
|
||||
|
||||
_x.FromLimbs(GetFixedLimbs(x))
|
||||
_y.FromLimbs(GetFixedLimbs(y))
|
||||
_z.FromLimbs(GetFixedLimbs(z))
|
||||
|
||||
p.X = _x
|
||||
p.Y = _y
|
||||
p.Z = _z
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
/*
|
||||
* PointAffineNoInfinityBN254
|
||||
*/
|
||||
|
||||
type G1PointAffine struct {
|
||||
X, Y G1BaseField
|
||||
}
|
||||
|
||||
func (p *G1PointAffine) FromProjective(projective *G1ProjectivePoint) *G1PointAffine {
|
||||
in := (*C.BN254_projective_t)(unsafe.Pointer(projective))
|
||||
out := (*C.BN254_affine_t)(unsafe.Pointer(p))
|
||||
|
||||
C.projective_to_affine_bn254(out,in)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G1PointAffine) ToProjective() *G1ProjectivePoint {
|
||||
var Z G1BaseField
|
||||
Z.SetOne()
|
||||
|
||||
return &G1ProjectivePoint{
|
||||
X: p.X,
|
||||
Y: p.Y,
|
||||
Z: Z,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *G1PointAffine) FromLimbs(X, Y *[]uint32) *G1PointAffine {
|
||||
var _x G1BaseField
|
||||
var _y G1BaseField
|
||||
|
||||
_x.FromLimbs(GetFixedLimbs(X))
|
||||
_y.FromLimbs(GetFixedLimbs(Y))
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiplication
|
||||
*/
|
||||
|
||||
func MultiplyVec(a []G1ProjectivePoint, b []G1ScalarField, deviceID int) {
|
||||
if len(a) != len(b) {
|
||||
panic("a and b have different lengths")
|
||||
}
|
||||
|
||||
pointsC := (*C.BN254_projective_t)(unsafe.Pointer(&a[0]))
|
||||
scalarsC := (*C.BN254_scalar_t)(unsafe.Pointer(&b[0]))
|
||||
deviceIdC := C.size_t(deviceID)
|
||||
nElementsC := C.size_t(len(a))
|
||||
|
||||
C.vec_mod_mult_point_bn254(pointsC, scalarsC, nElementsC, deviceIdC)
|
||||
}
|
||||
|
||||
func MultiplyScalar(a []G1ScalarField, b []G1ScalarField, deviceID int) {
|
||||
if len(a) != len(b) {
|
||||
panic("a and b have different lengths")
|
||||
}
|
||||
|
||||
aC := (*C.BN254_scalar_t)(unsafe.Pointer(&a[0]))
|
||||
bC := (*C.BN254_scalar_t)(unsafe.Pointer(&b[0]))
|
||||
deviceIdC := C.size_t(deviceID)
|
||||
nElementsC := C.size_t(len(a))
|
||||
|
||||
C.vec_mod_mult_scalar_bn254(aC, bC, nElementsC, deviceIdC)
|
||||
}
|
||||
|
||||
// Multiply a matrix by a scalar:
|
||||
//
|
||||
// `a` - flattenned matrix;
|
||||
// `b` - vector to multiply `a` by;
|
||||
func MultiplyMatrix(a []G1ScalarField, b []G1ScalarField, deviceID int) {
|
||||
c := make([]G1ScalarField, len(b))
|
||||
for i := range c {
|
||||
var p G1ScalarField
|
||||
p.SetZero()
|
||||
|
||||
c[i] = p
|
||||
}
|
||||
|
||||
aC := (*C.BN254_scalar_t)(unsafe.Pointer(&a[0]))
|
||||
bC := (*C.BN254_scalar_t)(unsafe.Pointer(&b[0]))
|
||||
cC := (*C.BN254_scalar_t)(unsafe.Pointer(&c[0]))
|
||||
deviceIdC := C.size_t(deviceID)
|
||||
nElementsC := C.size_t(len(a))
|
||||
|
||||
C.matrix_vec_mod_mult_bn254(aC, bC, cC, nElementsC, deviceIdC)
|
||||
}
|
||||
|
||||
/*
|
||||
* Utils
|
||||
*/
|
||||
|
||||
func GetFixedLimbs(slice *[]uint32) [BASE_SIZE]uint32 {
|
||||
if len(*slice) <= BASE_SIZE {
|
||||
limbs := [BASE_SIZE]uint32{}
|
||||
copy(limbs[:len(*slice)], *slice)
|
||||
return limbs
|
||||
}
|
||||
|
||||
panic("slice has too many elements")
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bn254
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNewFieldBN254One(t *testing.T) {
|
||||
var oneField G1BaseField
|
||||
oneField.SetOne()
|
||||
|
||||
rawOneField := [8]uint32([8]uint32{0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0})
|
||||
|
||||
assert.Equal(t, oneField.S, rawOneField)
|
||||
}
|
||||
|
||||
func TestNewFieldBN254Zero(t *testing.T) {
|
||||
var zeroField G1BaseField
|
||||
zeroField.SetZero()
|
||||
|
||||
rawZeroField := [8]uint32([8]uint32{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0})
|
||||
|
||||
assert.Equal(t, zeroField.S, rawZeroField)
|
||||
}
|
||||
|
||||
func TestFieldBN254ToBytesLe(t *testing.T) {
|
||||
var p G1ProjectivePoint
|
||||
p.Random()
|
||||
|
||||
expected := make([]byte, len(p.X.S)*4) // each uint32 takes 4 bytes
|
||||
for i, v := range p.X.S {
|
||||
binary.LittleEndian.PutUint32(expected[i*4:], v)
|
||||
}
|
||||
|
||||
assert.Equal(t, p.X.ToBytesLe(), expected)
|
||||
assert.Equal(t, len(p.X.ToBytesLe()), 32)
|
||||
}
|
||||
|
||||
func TestNewPointBN254Zero(t *testing.T) {
|
||||
var pointZero G1ProjectivePoint
|
||||
pointZero.SetZero()
|
||||
|
||||
var baseOne G1BaseField
|
||||
baseOne.SetOne()
|
||||
|
||||
var zeroSanity G1BaseField
|
||||
zeroSanity.SetZero()
|
||||
|
||||
assert.Equal(t, pointZero.X, zeroSanity)
|
||||
assert.Equal(t, pointZero.Y, baseOne)
|
||||
assert.Equal(t, pointZero.Z, zeroSanity)
|
||||
}
|
||||
|
||||
func TestFromProjectiveToAffine(t *testing.T) {
|
||||
var projective G1ProjectivePoint
|
||||
var affine G1PointAffine
|
||||
|
||||
projective.Random()
|
||||
|
||||
affine.FromProjective(&projective)
|
||||
var projective2 G1ProjectivePoint
|
||||
projective2.FromAffine(&affine)
|
||||
|
||||
assert.True(t, projective.IsOnCurve())
|
||||
assert.True(t, projective2.IsOnCurve())
|
||||
assert.True(t, projective.Eq(&projective2))
|
||||
}
|
||||
|
||||
func TestBN254Eq(t *testing.T) {
|
||||
var p1 G1ProjectivePoint
|
||||
p1.Random()
|
||||
var p2 G1ProjectivePoint
|
||||
p2.Random()
|
||||
|
||||
assert.Equal(t, p1.Eq(&p1), true)
|
||||
assert.Equal(t, p1.Eq(&p2), false)
|
||||
}
|
||||
|
||||
func TestBN254StripZ(t *testing.T) {
|
||||
var p1 G1ProjectivePoint
|
||||
p1.Random()
|
||||
|
||||
p2ZLess := p1.StripZ()
|
||||
|
||||
assert.IsType(t, G1PointAffine{}, *p2ZLess)
|
||||
assert.Equal(t, p1.X, p2ZLess.X)
|
||||
assert.Equal(t, p1.Y, p2ZLess.Y)
|
||||
}
|
||||
|
||||
func TestPointBN254fromLimbs(t *testing.T) {
|
||||
var p G1ProjectivePoint
|
||||
p.Random()
|
||||
|
||||
x := p.X.Limbs()
|
||||
y := p.Y.Limbs()
|
||||
z := p.Z.Limbs()
|
||||
|
||||
xSlice := x[:]
|
||||
ySlice := y[:]
|
||||
zSlice := z[:]
|
||||
|
||||
var pFromLimbs G1ProjectivePoint
|
||||
pFromLimbs.FromLimbs(&xSlice, &ySlice, &zSlice)
|
||||
|
||||
assert.Equal(t, pFromLimbs, p)
|
||||
}
|
||||
|
||||
func TestNewPointAffineNoInfinityBN254Zero(t *testing.T) {
|
||||
var zeroP G1PointAffine
|
||||
|
||||
var zeroSanity G1BaseField
|
||||
zeroSanity.SetZero()
|
||||
|
||||
assert.Equal(t, zeroP.X, zeroSanity)
|
||||
assert.Equal(t, zeroP.Y, zeroSanity)
|
||||
}
|
||||
|
||||
func TestPointAffineNoInfinityBN254FromLimbs(t *testing.T) {
|
||||
// Initialize your test values
|
||||
x := [8]uint32{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
y := [8]uint32{9, 10, 11, 12, 13, 14, 15, 16}
|
||||
xSlice := x[:]
|
||||
ySlice := y[:]
|
||||
|
||||
// Execute your function
|
||||
var result G1PointAffine
|
||||
result.FromLimbs(&xSlice, &ySlice)
|
||||
|
||||
var xBase G1BaseField
|
||||
var yBase G1BaseField
|
||||
xBase.FromLimbs(x)
|
||||
yBase.FromLimbs(y)
|
||||
|
||||
// Define your expected result
|
||||
expected := &G1PointAffine{
|
||||
X: xBase,
|
||||
Y: yBase,
|
||||
}
|
||||
|
||||
// Test if result is as expected
|
||||
assert.Equal(t, result, expected)
|
||||
}
|
||||
|
||||
func TestGetFixedLimbs(t *testing.T) {
|
||||
t.Run("case of valid input of length less than 8", func(t *testing.T) {
|
||||
slice := []uint32{1, 2, 3, 4, 5, 6, 7}
|
||||
expected := [8]uint32{1, 2, 3, 4, 5, 6, 7, 0}
|
||||
|
||||
result := GetFixedLimbs(&slice)
|
||||
assert.Equal(t, result, expected)
|
||||
})
|
||||
|
||||
t.Run("case of valid input of length 8", func(t *testing.T) {
|
||||
slice := []uint32{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
expected := [8]uint32{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
|
||||
result := GetFixedLimbs(&slice)
|
||||
assert.Equal(t, result, expected)
|
||||
})
|
||||
|
||||
t.Run("case of empty input", func(t *testing.T) {
|
||||
slice := []uint32{}
|
||||
expected := [8]uint32{0, 0, 0, 0, 0, 0, 0, 0}
|
||||
|
||||
result := GetFixedLimbs(&slice)
|
||||
assert.Equal(t, result, expected)
|
||||
})
|
||||
|
||||
t.Run("case of input length greater than 8", func(t *testing.T) {
|
||||
slice := []uint32{1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("the code did not panic")
|
||||
}
|
||||
}()
|
||||
|
||||
GetFixedLimbs(&slice)
|
||||
})
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bn254
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ -lbn254
|
||||
// #include "projective.h"
|
||||
// #include "ve_mod_mult.h"
|
||||
import "C"
|
||||
|
||||
// G2 extension field
|
||||
|
||||
type G2Element [4]uint64
|
||||
|
||||
type ExtentionField struct {
|
||||
A0, A1 G2Element
|
||||
}
|
||||
|
||||
type G2PointAffine struct {
|
||||
X, Y ExtentionField
|
||||
}
|
||||
|
||||
type G2Point struct {
|
||||
X, Y, Z ExtentionField
|
||||
}
|
||||
|
||||
|
||||
func (p *G2Point) Random() *G2Point {
|
||||
outC := (*C.BN254_g2_projective_t)(unsafe.Pointer(p))
|
||||
C.random_g2_projective_bn254(outC)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G2Point) FromAffine(affine *G2PointAffine) *G2Point {
|
||||
out := (*C.BN254_g2_projective_t)(unsafe.Pointer(p))
|
||||
in := (*C.BN254_g2_affine_t)(unsafe.Pointer(affine))
|
||||
|
||||
C.g2_projective_from_affine_bn254(out, in)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G2Point) Eq(pCompare *G2Point) bool {
|
||||
// Cast *PointBN254 to *C.BN254_projective_t
|
||||
// The unsafe.Pointer cast is necessary because Go doesn't allow direct casts
|
||||
// between different pointer types.
|
||||
// It's your responsibility to ensure that the types are compatible.
|
||||
pC := (*C.BN254_g2_projective_t)(unsafe.Pointer(p))
|
||||
pCompareC := (*C.BN254_g2_projective_t)(unsafe.Pointer(pCompare))
|
||||
|
||||
// Call the C function
|
||||
// The C function doesn't keep any references to the data,
|
||||
// so it's fine if the Go garbage collector moves or deletes the data later.
|
||||
return bool(C.eq_g2_bn254(pC, pCompareC))
|
||||
}
|
||||
|
||||
func (f *G2Element) ToBytesLe() []byte {
|
||||
var bytes []byte
|
||||
for _, val := range f {
|
||||
buf := make([]byte, 8) // 8 bytes because uint64 is 64-bit
|
||||
binary.LittleEndian.PutUint64(buf, val)
|
||||
bytes = append(bytes, buf...)
|
||||
}
|
||||
return bytes
|
||||
}
|
||||
|
||||
func (p *G2PointAffine) ToProjective() G2Point {
|
||||
return G2Point{
|
||||
X: p.X,
|
||||
Y: p.Y,
|
||||
Z: ExtentionField{
|
||||
A0: G2Element{1, 0, 0, 0},
|
||||
A1: G2Element{0, 0, 0, 0},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *G2PointAffine) FromProjective(projective *G2Point) *G2PointAffine {
|
||||
out := (*C.BN254_g2_affine_t)(unsafe.Pointer(p))
|
||||
in := (*C.BN254_g2_projective_t)(unsafe.Pointer(projective))
|
||||
|
||||
C.g2_projective_to_affine_bn254(out, in)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G2Point) IsOnCurve() bool {
|
||||
// Directly copy memory from the C struct to the Go struct
|
||||
point := (*C.BN254_g2_projective_t)(unsafe.Pointer(p))
|
||||
res := C.g2_projective_is_on_curve_bn254(point)
|
||||
|
||||
return bool(res)
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bn254
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestG2Eqg2(t *testing.T) {
|
||||
var point G2Point
|
||||
|
||||
point.Random()
|
||||
|
||||
assert.True(t, point.Eq(&point))
|
||||
}
|
||||
|
||||
func TestG2FromProjectiveToAffine(t *testing.T) {
|
||||
var projective G2Point
|
||||
var affine G2PointAffine
|
||||
|
||||
projective.Random()
|
||||
|
||||
affine.FromProjective(&projective)
|
||||
var projective2 G2Point
|
||||
projective2.FromAffine(&affine)
|
||||
|
||||
|
||||
assert.True(t, projective.IsOnCurve())
|
||||
assert.True(t, projective2.IsOnCurve())
|
||||
assert.True(t, projective.Eq(&projective2))
|
||||
}
|
||||
|
||||
func TestG2Eqg2NotEqual(t *testing.T) {
|
||||
var point G2Point
|
||||
point.Random()
|
||||
|
||||
var point2 G2Point
|
||||
point2.Random()
|
||||
|
||||
assert.False(t, point.Eq(&point2))
|
||||
}
|
||||
|
||||
func TestG2ToBytes(t *testing.T) {
|
||||
element := G2Element{0x6546098ea84b6298, 0x4a384533d1f68aca, 0xaa0666972d771336, 0x1569e4a34321993}
|
||||
bytes := element.ToBytesLe()
|
||||
|
||||
assert.Equal(t, bytes, []byte{0x98, 0x62, 0x4b, 0xa8, 0x8e, 0x9, 0x46, 0x65, 0xca, 0x8a, 0xf6, 0xd1, 0x33, 0x45, 0x38, 0x4a, 0x36, 0x13, 0x77, 0x2d, 0x97, 0x66, 0x6, 0xaa, 0x93, 0x19, 0x32, 0x34, 0x4a, 0x9e, 0x56, 0x1})
|
||||
}
|
||||
|
||||
func TestG2ShouldConvertToProjective(t *testing.T) {
|
||||
var pointProjective G2Point
|
||||
var pointAffine G2PointAffine
|
||||
|
||||
pointProjective.Random()
|
||||
pointAffine.FromProjective(&pointProjective)
|
||||
|
||||
proj := pointAffine.ToProjective()
|
||||
|
||||
assert.True(t, proj.IsOnCurve())
|
||||
assert.True(t, pointProjective.Eq(&proj))
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
#include <cuda.h>
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
// msm.h
|
||||
|
||||
#ifndef _BN254_MSM_H
|
||||
#define _BN254_MSM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Incomplete declaration of BN254 projective and affine structs
|
||||
typedef struct BN254_projective_t BN254_projective_t;
|
||||
typedef struct BN254_g2_projective_t BN254_g2_projective_t;
|
||||
typedef struct BN254_affine_t BN254_affine_t;
|
||||
typedef struct BN254_g2_affine_t BN254_g2_affine_t;
|
||||
typedef struct BN254_scalar_t BN254_scalar_t;
|
||||
typedef cudaStream_t CudaStream_t;
|
||||
|
||||
int msm_cuda_bn254(
|
||||
BN254_projective_t* out, BN254_affine_t* points, BN254_scalar_t* scalars, size_t count, size_t device_id);
|
||||
|
||||
int msm_batch_cuda_bn254(
|
||||
BN254_projective_t* out,
|
||||
BN254_affine_t* points,
|
||||
BN254_scalar_t* scalars,
|
||||
size_t batch_size,
|
||||
size_t msm_size,
|
||||
size_t device_id);
|
||||
|
||||
int commit_cuda_bn254(
|
||||
BN254_projective_t* d_out,
|
||||
BN254_scalar_t* d_scalars,
|
||||
BN254_affine_t* d_points,
|
||||
size_t count,
|
||||
unsigned large_bucket_factor,
|
||||
size_t device_id);
|
||||
|
||||
int commit_batch_cuda_bn254(
|
||||
BN254_projective_t* d_out,
|
||||
BN254_scalar_t* d_scalars,
|
||||
BN254_affine_t* d_points,
|
||||
size_t count,
|
||||
size_t batch_size,
|
||||
size_t device_id);
|
||||
|
||||
int msm_g2_cuda_bn254(
|
||||
BN254_g2_projective_t* out, BN254_g2_affine_t* points, BN254_scalar_t* scalars, size_t count, size_t device_id);
|
||||
int msm_batch_g2_cuda_bn254(
|
||||
BN254_g2_projective_t* out,
|
||||
BN254_g2_affine_t* points,
|
||||
BN254_scalar_t* scalars,
|
||||
size_t batch_size,
|
||||
size_t msm_size,
|
||||
size_t device_id);
|
||||
int commit_g2_cuda_bn254(
|
||||
BN254_g2_projective_t* d_out,
|
||||
BN254_scalar_t* d_scalars,
|
||||
BN254_g2_affine_t* d_points,
|
||||
size_t count,
|
||||
unsigned large_bucket_factor,
|
||||
size_t device_id);
|
||||
int commit_batch_g2_cuda_bn254(
|
||||
BN254_g2_projective_t* d_out,
|
||||
BN254_scalar_t* d_scalars,
|
||||
BN254_g2_affine_t* d_points,
|
||||
size_t count,
|
||||
size_t batch_size,
|
||||
size_t device_id,
|
||||
cudaStream_t stream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BN254_MSM_H */
|
||||
@@ -1,193 +0,0 @@
|
||||
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
#include <cuda.h>
|
||||
#include <stdbool.h>
|
||||
// ntt.h
|
||||
|
||||
#ifndef _BN254_NTT_H
|
||||
#define _BN254_NTT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Incomplete declaration of BN254 projective and affine structs
|
||||
typedef struct BN254_projective_t BN254_projective_t;
|
||||
typedef struct BN254_affine_t BN254_affine_t;
|
||||
typedef struct BN254_scalar_t BN254_scalar_t;
|
||||
|
||||
typedef struct BN254_g2_projective_t BN254_g2_projective_t;
|
||||
typedef struct BN254_g2_affine_t BN254_g2_affine_t;
|
||||
|
||||
int ntt_cuda_bn254(BN254_scalar_t* arr, uint32_t n, bool inverse, size_t device_id);
|
||||
int ntt_batch_cuda_bn254(BN254_scalar_t* arr, uint32_t arr_size, uint32_t batch_size, bool inverse, size_t device_id);
|
||||
|
||||
int ecntt_cuda_bn254(BN254_projective_t* arr, uint32_t n, bool inverse, size_t device_id);
|
||||
int ecntt_batch_cuda_bn254(
|
||||
BN254_projective_t* arr, uint32_t arr_size, uint32_t batch_size, bool inverse, size_t device_id);
|
||||
|
||||
BN254_scalar_t*
|
||||
build_domain_cuda_bn254(uint32_t domain_size, uint32_t logn, bool inverse, size_t device_id, size_t stream);
|
||||
int interpolate_scalars_cuda_bn254(
|
||||
BN254_scalar_t* d_out,
|
||||
BN254_scalar_t* d_evaluations,
|
||||
BN254_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned device_id,
|
||||
size_t stream);
|
||||
int interpolate_scalars_batch_cuda_bn254(
|
||||
BN254_scalar_t* d_out,
|
||||
BN254_scalar_t* d_evaluations,
|
||||
BN254_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int interpolate_points_cuda_bn254(
|
||||
BN254_projective_t* d_out,
|
||||
BN254_projective_t* d_evaluations,
|
||||
BN254_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int interpolate_points_batch_cuda_bn254(
|
||||
BN254_projective_t* d_out,
|
||||
BN254_projective_t* d_evaluations,
|
||||
BN254_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int interpolate_scalars_on_coset_cuda_bn254(
|
||||
BN254_scalar_t* d_out,
|
||||
BN254_scalar_t* d_evaluations,
|
||||
BN254_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
BN254_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int interpolate_scalars_batch_on_coset_cuda_bn254(
|
||||
BN254_scalar_t* d_out,
|
||||
BN254_scalar_t* d_evaluations,
|
||||
BN254_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
BN254_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_scalars_cuda_bn254(
|
||||
BN254_scalar_t* d_out,
|
||||
BN254_scalar_t* d_coefficients,
|
||||
BN254_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned device_id,
|
||||
size_t stream);
|
||||
int evaluate_scalars_batch_cuda_bn254(
|
||||
BN254_scalar_t* d_out,
|
||||
BN254_scalar_t* d_coefficients,
|
||||
BN254_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_points_cuda_bn254(
|
||||
BN254_projective_t* d_out,
|
||||
BN254_projective_t* d_coefficients,
|
||||
BN254_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_points_batch_cuda_bn254(
|
||||
BN254_projective_t* d_out,
|
||||
BN254_projective_t* d_coefficients,
|
||||
BN254_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_scalars_on_coset_cuda_bn254(
|
||||
BN254_scalar_t* d_out,
|
||||
BN254_scalar_t* d_coefficients,
|
||||
BN254_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
BN254_scalar_t* coset_powers,
|
||||
unsigned device_id,
|
||||
size_t stream);
|
||||
int evaluate_scalars_on_coset_batch_cuda_bn254(
|
||||
BN254_scalar_t* d_out,
|
||||
BN254_scalar_t* d_coefficients,
|
||||
BN254_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
BN254_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_points_on_coset_cuda_bn254(
|
||||
BN254_projective_t* d_out,
|
||||
BN254_projective_t* d_coefficients,
|
||||
BN254_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
BN254_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_points_on_coset_batch_cuda_bn254(
|
||||
BN254_projective_t* d_out,
|
||||
BN254_projective_t* d_coefficients,
|
||||
BN254_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
BN254_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int reverse_order_scalars_cuda_bn254(BN254_scalar_t* arr, int n, size_t device_id, size_t stream);
|
||||
int reverse_order_scalars_batch_cuda_bn254(BN254_scalar_t* arr, int n, int batch_size, size_t device_id, size_t stream);
|
||||
int reverse_order_points_cuda_bn254(BN254_projective_t* arr, int n, size_t device_id, size_t stream);
|
||||
int reverse_order_points_batch_cuda_bn254(
|
||||
BN254_projective_t* arr, int n, int batch_size, size_t device_id, size_t stream);
|
||||
int add_scalars_cuda_bn254(
|
||||
BN254_scalar_t* d_out, BN254_scalar_t* d_in1, BN254_scalar_t* d_in2, unsigned n, size_t stream);
|
||||
int sub_scalars_cuda_bn254(
|
||||
BN254_scalar_t* d_out, BN254_scalar_t* d_in1, BN254_scalar_t* d_in2, unsigned n, size_t stream);
|
||||
int to_montgomery_scalars_cuda_bn254(BN254_scalar_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_scalars_cuda_bn254(BN254_scalar_t* d_inout, unsigned n, size_t stream);
|
||||
|
||||
// points g1
|
||||
int to_montgomery_proj_points_cuda_bn254(BN254_projective_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_proj_points_cuda_bn254(BN254_projective_t* d_inout, unsigned n, size_t stream);
|
||||
int to_montgomery_aff_points_cuda_bn254(BN254_affine_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_aff_points_cuda_bn254(BN254_affine_t* d_inout, unsigned n, size_t stream);
|
||||
|
||||
// points g2
|
||||
int to_montgomery_proj_points_g2_cuda_bn254(BN254_g2_projective_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_proj_points_g2_cuda_bn254(BN254_g2_projective_t* d_inout, unsigned n, size_t stream);
|
||||
int to_montgomery_aff_points_g2_cuda_bn254(BN254_g2_affine_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_aff_points_g2_cuda_bn254(BN254_g2_affine_t* d_inout, unsigned n, size_t stream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BN254_NTT_H */
|
||||
@@ -1,50 +0,0 @@
|
||||
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
#include <cuda.h>
|
||||
#include <stdbool.h>
|
||||
// projective.h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct BN254_projective_t BN254_projective_t;
|
||||
typedef struct BN254_g2_projective_t BN254_g2_projective_t;
|
||||
typedef struct BN254_affine_t BN254_affine_t;
|
||||
typedef struct BN254_g2_affine_t BN254_g2_affine_t;
|
||||
typedef struct BN254_scalar_t BN254_scalar_t;
|
||||
|
||||
bool projective_is_on_curve_bn254(BN254_projective_t* point1);
|
||||
|
||||
int random_scalar_bn254(BN254_scalar_t* out);
|
||||
int random_projective_bn254(BN254_projective_t* out);
|
||||
BN254_projective_t* projective_zero_bn254();
|
||||
int projective_to_affine_bn254(BN254_affine_t* out, BN254_projective_t* point1);
|
||||
int projective_from_affine_bn254(BN254_projective_t* out, BN254_affine_t* point1);
|
||||
|
||||
int random_g2_projective_bn254(BN254_g2_projective_t* out);
|
||||
int g2_projective_to_affine_bn254(BN254_g2_affine_t* out, BN254_g2_projective_t* point1);
|
||||
int g2_projective_from_affine_bn254(BN254_g2_projective_t* out, BN254_g2_affine_t* point1);
|
||||
bool g2_projective_is_on_curve_bn254(BN254_g2_projective_t* point1);
|
||||
|
||||
bool eq_bn254(BN254_projective_t* point1, BN254_projective_t* point2);
|
||||
bool eq_g2_bn254(BN254_g2_projective_t* point1, BN254_g2_projective_t* point2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,45 +0,0 @@
|
||||
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
#include <cuda.h>
|
||||
#include <stdbool.h>
|
||||
// ve_mod_mult.h
|
||||
|
||||
#ifndef _BN254_VEC_MULT_H
|
||||
#define _BN254_VEC_MULT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct BN254_projective_t BN254_projective_t;
|
||||
typedef struct BN254_scalar_t BN254_scalar_t;
|
||||
|
||||
int32_t
|
||||
vec_mod_mult_point_bn254(BN254_projective_t* inout, BN254_scalar_t* scalar_vec, size_t n_elments, size_t device_id);
|
||||
int32_t
|
||||
vec_mod_mult_scalar_bn254(BN254_scalar_t* inout, BN254_scalar_t* scalar_vec, size_t n_elments, size_t device_id);
|
||||
int32_t vec_mod_mult_device_scalar_bn254(
|
||||
BN254_scalar_t* inout, BN254_scalar_t* scalar_vec, size_t n_elements, size_t device_id);
|
||||
int32_t matrix_vec_mod_mult_bn254(
|
||||
BN254_scalar_t* matrix_flattened, BN254_scalar_t* input, BN254_scalar_t* output, size_t n_elments, size_t device_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BN254_VEC_MULT_H */
|
||||
@@ -1,208 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bn254
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ -lbn254
|
||||
// #include "msm.h"
|
||||
import "C"
|
||||
|
||||
func Msm(out *G1ProjectivePoint, points []G1PointAffine, scalars []G1ScalarField, device_id int) (*G1ProjectivePoint, error) {
|
||||
if len(points) != len(scalars) {
|
||||
return nil, errors.New("error on: len(points) != len(scalars)")
|
||||
}
|
||||
|
||||
pointsC := (*C.BN254_affine_t)(unsafe.Pointer(&points[0]))
|
||||
scalarsC := (*C.BN254_scalar_t)(unsafe.Pointer(&scalars[0]))
|
||||
outC := (*C.BN254_projective_t)(unsafe.Pointer(out))
|
||||
ret := C.msm_cuda_bn254(outC, pointsC, scalarsC, C.size_t(len(points)), C.size_t(device_id))
|
||||
|
||||
if ret != 0 {
|
||||
return nil, fmt.Errorf("msm_cuda_bn254 returned error code: %d", ret)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func MsmG2(out *G2Point, points []G2PointAffine, scalars []G1ScalarField, device_id int) (*G2Point, error) {
|
||||
if len(points) != len(scalars) {
|
||||
return nil, errors.New("error on: len(points) != len(scalars)")
|
||||
}
|
||||
|
||||
pointsC := (*C.BN254_g2_affine_t)(unsafe.Pointer(&points[0]))
|
||||
scalarsC := (*C.BN254_scalar_t)(unsafe.Pointer(&scalars[0]))
|
||||
outC := (*C.BN254_g2_projective_t)(unsafe.Pointer(out))
|
||||
|
||||
ret := C.msm_g2_cuda_bn254(outC, pointsC, scalarsC, C.size_t(len(points)), C.size_t(device_id))
|
||||
|
||||
if ret != 0 {
|
||||
return nil, fmt.Errorf("msm_g2_cuda_bn254 returned error code: %d", ret)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func MsmBatch(points *[]G1PointAffine, scalars *[]G1ScalarField, batchSize, deviceId int) ([]*G1ProjectivePoint, error) {
|
||||
// Check for nil pointers
|
||||
if points == nil || scalars == nil {
|
||||
return nil, errors.New("points or scalars is nil")
|
||||
}
|
||||
|
||||
if len(*points) != len(*scalars) {
|
||||
return nil, errors.New("error on: len(points) != len(scalars)")
|
||||
}
|
||||
|
||||
// Check for empty slices
|
||||
if len(*points) == 0 || len(*scalars) == 0 {
|
||||
return nil, errors.New("points or scalars is empty")
|
||||
}
|
||||
|
||||
// Check for zero batchSize
|
||||
if batchSize <= 0 {
|
||||
return nil, errors.New("error on: batchSize must be greater than zero")
|
||||
}
|
||||
|
||||
out := make([]*G1ProjectivePoint, batchSize)
|
||||
|
||||
for i := 0; i < len(out); i++ {
|
||||
var p G1ProjectivePoint
|
||||
p.SetZero()
|
||||
|
||||
out[i] = &p
|
||||
}
|
||||
|
||||
outC := (*C.BN254_projective_t)(unsafe.Pointer(&out[0]))
|
||||
pointsC := (*C.BN254_affine_t)(unsafe.Pointer(&(*points)[0]))
|
||||
scalarsC := (*C.BN254_scalar_t)(unsafe.Pointer(&(*scalars)[0]))
|
||||
msmSizeC := C.size_t(len(*points) / batchSize)
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
batchSizeC := C.size_t(batchSize)
|
||||
|
||||
ret := C.msm_batch_cuda_bn254(outC, pointsC, scalarsC, batchSizeC, msmSizeC, deviceIdC)
|
||||
if ret != 0 {
|
||||
return nil, fmt.Errorf("msm_batch_cuda_bn254 returned error code: %d", ret)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func MsmG2Batch(points *[]G2PointAffine, scalars *[]G1ScalarField, batchSize, deviceId int) ([]*G2Point, error) {
|
||||
// Check for nil pointers
|
||||
if points == nil || scalars == nil {
|
||||
return nil, errors.New("points or scalars is nil")
|
||||
}
|
||||
|
||||
if len(*points) != len(*scalars) {
|
||||
return nil, errors.New("error on: len(points) != len(scalars)")
|
||||
}
|
||||
|
||||
// Check for empty slices
|
||||
if len(*points) == 0 || len(*scalars) == 0 {
|
||||
return nil, errors.New("points or scalars is empty")
|
||||
}
|
||||
|
||||
// Check for zero batchSize
|
||||
if batchSize <= 0 {
|
||||
return nil, errors.New("error on: batchSize must be greater than zero")
|
||||
}
|
||||
|
||||
out := make([]*G2Point, batchSize)
|
||||
|
||||
outC := (*C.BN254_g2_projective_t)(unsafe.Pointer(&out[0]))
|
||||
pointsC := (*C.BN254_g2_affine_t)(unsafe.Pointer(&(*points)[0]))
|
||||
scalarsC := (*C.BN254_scalar_t)(unsafe.Pointer(&(*scalars)[0]))
|
||||
msmSizeC := C.size_t(len(*points) / batchSize)
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
batchSizeC := C.size_t(batchSize)
|
||||
|
||||
ret := C.msm_batch_g2_cuda_bn254(outC, pointsC, scalarsC, batchSizeC, msmSizeC, deviceIdC)
|
||||
if ret != 0 {
|
||||
return nil, fmt.Errorf("msm_batch_cuda_bn254 returned error code: %d", ret)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func Commit(d_out, d_scalars, d_points unsafe.Pointer, count, bucketFactor int) int {
|
||||
d_outC := (*C.BN254_projective_t)(d_out)
|
||||
scalarsC := (*C.BN254_scalar_t)(d_scalars)
|
||||
pointsC := (*C.BN254_affine_t)(d_points)
|
||||
countC := (C.size_t)(count)
|
||||
largeBucketFactorC := C.uint(bucketFactor)
|
||||
|
||||
ret := C.commit_cuda_bn254(d_outC, scalarsC, pointsC, countC, largeBucketFactorC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func CommitG2(d_out, d_scalars, d_points unsafe.Pointer, count, bucketFactor int) int {
|
||||
d_outC := (*C.BN254_g2_projective_t)(d_out)
|
||||
scalarsC := (*C.BN254_scalar_t)(d_scalars)
|
||||
pointsC := (*C.BN254_g2_affine_t)(d_points)
|
||||
countC := (C.size_t)(count)
|
||||
largeBucketFactorC := C.uint(bucketFactor)
|
||||
|
||||
ret := C.commit_g2_cuda_bn254(d_outC, scalarsC, pointsC, countC, largeBucketFactorC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func CommitBatch(d_out, d_scalars, d_points unsafe.Pointer, count, batch_size int) int {
|
||||
d_outC := (*C.BN254_projective_t)(d_out)
|
||||
scalarsC := (*C.BN254_scalar_t)(d_scalars)
|
||||
pointsC := (*C.BN254_affine_t)(d_points)
|
||||
countC := (C.size_t)(count)
|
||||
batch_sizeC := (C.size_t)(batch_size)
|
||||
|
||||
ret := C.commit_batch_cuda_bn254(d_outC, scalarsC, pointsC, countC, batch_sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func CommitG2Batch(d_out, d_scalars, d_points unsafe.Pointer, count, batch_size int) int {
|
||||
d_outC := (*C.BN254_g2_projective_t)(d_out)
|
||||
scalarsC := (*C.BN254_scalar_t)(d_scalars)
|
||||
pointsC := (*C.BN254_g2_affine_t)(d_points)
|
||||
countC := (C.size_t)(count)
|
||||
batch_sizeC := (C.size_t)(batch_size)
|
||||
|
||||
ret := C.msm_batch_g2_cuda_bn254(d_outC, pointsC, scalarsC, countC, batch_sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -1,355 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bn254
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"testing"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/goicicle"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func GeneratePoints(count int) []G1PointAffine {
|
||||
// Declare a slice of integers
|
||||
var points []G1PointAffine
|
||||
|
||||
// populate the slice
|
||||
for i := 0; i < 10; i++ {
|
||||
var pointProjective G1ProjectivePoint
|
||||
pointProjective.Random()
|
||||
|
||||
var pointAffine G1PointAffine
|
||||
pointAffine.FromProjective(&pointProjective)
|
||||
|
||||
points = append(points, pointAffine)
|
||||
}
|
||||
|
||||
log2_10 := math.Log2(10)
|
||||
log2Count := math.Log2(float64(count))
|
||||
log2Size := int(math.Ceil(log2Count - log2_10))
|
||||
|
||||
for i := 0; i < log2Size; i++ {
|
||||
points = append(points, points...)
|
||||
}
|
||||
|
||||
return points[:count]
|
||||
}
|
||||
|
||||
func GeneratePointsProj(count int) []G1ProjectivePoint {
|
||||
// Declare a slice of integers
|
||||
var points []G1ProjectivePoint
|
||||
// Use a loop to populate the slice
|
||||
for i := 0; i < count; i++ {
|
||||
var p G1ProjectivePoint
|
||||
p.Random()
|
||||
|
||||
points = append(points, p)
|
||||
}
|
||||
|
||||
return points
|
||||
}
|
||||
|
||||
func GenerateScalars(count int, skewed bool) []G1ScalarField {
|
||||
// Declare a slice of integers
|
||||
var scalars []G1ScalarField
|
||||
|
||||
var rand G1ScalarField
|
||||
var zero G1ScalarField
|
||||
var one G1ScalarField
|
||||
var randLarge G1ScalarField
|
||||
|
||||
zero.SetZero()
|
||||
one.SetOne()
|
||||
randLarge.Random()
|
||||
|
||||
if skewed && count > 1_200_000 {
|
||||
for i := 0; i < count-1_200_000; i++ {
|
||||
rand.Random()
|
||||
scalars = append(scalars, rand)
|
||||
}
|
||||
|
||||
for i := 0; i < 600_000; i++ {
|
||||
scalars = append(scalars, randLarge)
|
||||
}
|
||||
for i := 0; i < 400_000; i++ {
|
||||
scalars = append(scalars, zero)
|
||||
}
|
||||
for i := 0; i < 200_000; i++ {
|
||||
scalars = append(scalars, one)
|
||||
}
|
||||
} else {
|
||||
for i := 0; i < count; i++ {
|
||||
rand.Random()
|
||||
scalars = append(scalars, rand)
|
||||
}
|
||||
}
|
||||
|
||||
return scalars[:count]
|
||||
}
|
||||
|
||||
func TestMSM(t *testing.T) {
|
||||
for _, v := range []int{24} {
|
||||
count := 1 << v
|
||||
|
||||
points := GeneratePoints(count)
|
||||
fmt.Print("Finished generating points\n")
|
||||
scalars := GenerateScalars(count, true)
|
||||
fmt.Print("Finished generating scalars\n")
|
||||
|
||||
out := new(G1ProjectivePoint)
|
||||
startTime := time.Now()
|
||||
_, e := Msm(out, points, scalars, 0) // non mont
|
||||
fmt.Printf("icicle MSM took: %d ms\n", time.Since(startTime).Milliseconds())
|
||||
|
||||
assert.Equal(t, e, nil, "error should be nil")
|
||||
|
||||
assert.True(t, out.IsOnCurve())
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommitMSM(t *testing.T) {
|
||||
for _, v := range []int{24} {
|
||||
count := 1<<v - 1
|
||||
|
||||
points := GeneratePoints(count)
|
||||
fmt.Print("Finished generating points\n")
|
||||
scalars := GenerateScalars(count, true)
|
||||
fmt.Print("Finished generating scalars\n")
|
||||
|
||||
out_d, _ := goicicle.CudaMalloc(96)
|
||||
|
||||
pointsBytes := count * 64
|
||||
points_d, _ := goicicle.CudaMalloc(pointsBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1PointAffine](points_d, points, pointsBytes)
|
||||
|
||||
scalarBytes := count * 32
|
||||
scalars_d, _ := goicicle.CudaMalloc(scalarBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1ScalarField](scalars_d, scalars, scalarBytes)
|
||||
|
||||
startTime := time.Now()
|
||||
e := Commit(out_d, scalars_d, points_d, count, 10)
|
||||
fmt.Printf("icicle MSM took: %d ms\n", time.Since(startTime).Milliseconds())
|
||||
|
||||
outHost := make([]G1ProjectivePoint, 1)
|
||||
goicicle.CudaMemCpyDtoH[G1ProjectivePoint](outHost, out_d, 96)
|
||||
|
||||
assert.Equal(t, e, 0, "error should be 0")
|
||||
assert.True(t, outHost[0].IsOnCurve())
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCommit(b *testing.B) {
|
||||
LOG_MSM_SIZES := []int{20, 21, 22, 23, 24, 25, 26}
|
||||
|
||||
for _, logMsmSize := range LOG_MSM_SIZES {
|
||||
msmSize := 1 << logMsmSize
|
||||
points := GeneratePoints(msmSize)
|
||||
scalars := GenerateScalars(msmSize, false)
|
||||
|
||||
out_d, _ := goicicle.CudaMalloc(96)
|
||||
|
||||
pointsBytes := msmSize * 64
|
||||
points_d, _ := goicicle.CudaMalloc(pointsBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1PointAffine](points_d, points, pointsBytes)
|
||||
|
||||
scalarBytes := msmSize * 32
|
||||
scalars_d, _ := goicicle.CudaMalloc(scalarBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1ScalarField](scalars_d, scalars, scalarBytes)
|
||||
|
||||
b.Run(fmt.Sprintf("MSM %d", logMsmSize), func(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
e := Commit(out_d, scalars_d, points_d, msmSize, 10)
|
||||
|
||||
if e != 0 {
|
||||
panic("Error occured")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBenchMSM(t *testing.T) {
|
||||
for _, batchPow2 := range []int{2, 4} {
|
||||
for _, pow2 := range []int{4, 6} {
|
||||
msmSize := 1 << pow2
|
||||
batchSize := 1 << batchPow2
|
||||
count := msmSize * batchSize
|
||||
|
||||
points := GeneratePoints(count)
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
a, e := MsmBatch(&points, &scalars, batchSize, 0)
|
||||
|
||||
if e != nil {
|
||||
t.Errorf("MsmBatchBN254 returned an error: %v", e)
|
||||
}
|
||||
|
||||
if len(a) != batchSize {
|
||||
t.Errorf("Expected length %d, but got %d", batchSize, len(a))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMSM(b *testing.B) {
|
||||
LOG_MSM_SIZES := []int{20, 21, 22, 23, 24, 25, 26}
|
||||
|
||||
for _, logMsmSize := range LOG_MSM_SIZES {
|
||||
msmSize := 1 << logMsmSize
|
||||
points := GeneratePoints(msmSize)
|
||||
scalars := GenerateScalars(msmSize, false)
|
||||
b.Run(fmt.Sprintf("MSM %d", logMsmSize), func(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
out := new(G1ProjectivePoint)
|
||||
_, e := Msm(out, points, scalars, 0)
|
||||
|
||||
if e != nil {
|
||||
panic("Error occured")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// G2
|
||||
func GenerateG2Points(count int) []G2PointAffine {
|
||||
// Declare a slice of integers
|
||||
var points []G2PointAffine
|
||||
|
||||
// populate the slice
|
||||
for i := 0; i < 10; i++ {
|
||||
var p G2Point
|
||||
p.Random()
|
||||
var affine G2PointAffine
|
||||
affine.FromProjective(&p)
|
||||
|
||||
points = append(points, affine)
|
||||
}
|
||||
|
||||
log2_10 := math.Log2(10)
|
||||
log2Count := math.Log2(float64(count))
|
||||
log2Size := int(math.Ceil(log2Count - log2_10))
|
||||
|
||||
for i := 0; i < log2Size; i++ {
|
||||
points = append(points, points...)
|
||||
}
|
||||
|
||||
return points[:count]
|
||||
}
|
||||
|
||||
func TestMsmG2BN254(t *testing.T) {
|
||||
for _, v := range []int{24} {
|
||||
count := 1 << v
|
||||
points := GenerateG2Points(count)
|
||||
fmt.Print("Finished generating points\n")
|
||||
scalars := GenerateScalars(count, false)
|
||||
fmt.Print("Finished generating scalars\n")
|
||||
|
||||
out := new(G2Point)
|
||||
_, e := MsmG2(out, points, scalars, 0)
|
||||
assert.Equal(t, e, nil, "error should be nil")
|
||||
assert.True(t, out.IsOnCurve())
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMsmG2BN254(b *testing.B) {
|
||||
LOG_MSM_SIZES := []int{20, 21, 22, 23, 24, 25, 26}
|
||||
|
||||
for _, logMsmSize := range LOG_MSM_SIZES {
|
||||
msmSize := 1 << logMsmSize
|
||||
points := GenerateG2Points(msmSize)
|
||||
scalars := GenerateScalars(msmSize, false)
|
||||
b.Run(fmt.Sprintf("MSM G2 %d", logMsmSize), func(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
out := new(G2Point)
|
||||
_, e := MsmG2(out, points, scalars, 0)
|
||||
|
||||
if e != nil {
|
||||
panic("Error occured")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommitG2MSM(t *testing.T) {
|
||||
for _, v := range []int{24} {
|
||||
count := 1 << v
|
||||
|
||||
points := GenerateG2Points(count)
|
||||
fmt.Print("Finished generating points\n")
|
||||
scalars := GenerateScalars(count, true)
|
||||
fmt.Print("Finished generating scalars\n")
|
||||
|
||||
var sizeCheckG2PointAffine G2PointAffine
|
||||
inputPointsBytes := count * int(unsafe.Sizeof(sizeCheckG2PointAffine))
|
||||
|
||||
var sizeCheckG2Point G2Point
|
||||
out_d, _ := goicicle.CudaMalloc(int(unsafe.Sizeof(sizeCheckG2Point)))
|
||||
|
||||
points_d, _ := goicicle.CudaMalloc(inputPointsBytes)
|
||||
goicicle.CudaMemCpyHtoD[G2PointAffine](points_d, points, inputPointsBytes)
|
||||
|
||||
scalarBytes := count * 32
|
||||
scalars_d, _ := goicicle.CudaMalloc(scalarBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1ScalarField](scalars_d, scalars, scalarBytes)
|
||||
|
||||
startTime := time.Now()
|
||||
e := CommitG2(out_d, scalars_d, points_d, count, 10)
|
||||
fmt.Printf("icicle MSM took: %d ms\n", time.Since(startTime).Milliseconds())
|
||||
|
||||
outHost := make([]G2Point, 1)
|
||||
goicicle.CudaMemCpyDtoH[G2Point](outHost, out_d, int(unsafe.Sizeof(sizeCheckG2Point)))
|
||||
|
||||
assert.Equal(t, e, 0, "error should be 0")
|
||||
assert.Equal(t, len(outHost), 1)
|
||||
result := outHost[0]
|
||||
|
||||
assert.True(t, result.IsOnCurve())
|
||||
}
|
||||
}
|
||||
|
||||
func TestBatchG2MSM(t *testing.T) {
|
||||
for _, batchPow2 := range []int{2, 4} {
|
||||
for _, pow2 := range []int{4, 6} {
|
||||
msmSize := 1 << pow2
|
||||
batchSize := 1 << batchPow2
|
||||
count := msmSize * batchSize
|
||||
|
||||
points := GenerateG2Points(count)
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
pointsResults, e := MsmG2Batch(&points, &scalars, batchSize, 0)
|
||||
|
||||
if e != nil {
|
||||
t.Errorf("MsmBatchBN254 returned an error: %v", e)
|
||||
}
|
||||
|
||||
if len(pointsResults) != batchSize {
|
||||
t.Errorf("Expected length %d, but got %d", batchSize, len(pointsResults))
|
||||
}
|
||||
|
||||
for _, s := range pointsResults {
|
||||
assert.True(t, s.IsOnCurve())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,221 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bn254
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/goicicle"
|
||||
)
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ -lbn254
|
||||
// #include "ntt.h"
|
||||
import "C"
|
||||
|
||||
const (
|
||||
NONE = 0
|
||||
DIF = 1
|
||||
DIT = 2
|
||||
)
|
||||
|
||||
func Ntt(scalars *[]G1ScalarField, isInverse bool, deviceId int) uint64 {
|
||||
scalarsC := (*C.BN254_scalar_t)(unsafe.Pointer(&(*scalars)[0]))
|
||||
|
||||
ret := C.ntt_cuda_bn254(scalarsC, C.uint32_t(len(*scalars)), C.bool(isInverse), C.size_t(deviceId))
|
||||
|
||||
return uint64(ret)
|
||||
}
|
||||
|
||||
func NttBatch(scalars *[]G1ScalarField, isInverse bool, batchSize, deviceId int) uint64 {
|
||||
scalarsC := (*C.BN254_scalar_t)(unsafe.Pointer(&(*scalars)[0]))
|
||||
isInverseC := C.bool(isInverse)
|
||||
batchSizeC := C.uint32_t(batchSize)
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
|
||||
ret := C.ntt_batch_cuda_bn254(scalarsC, C.uint32_t(len(*scalars)), batchSizeC, isInverseC, deviceIdC)
|
||||
|
||||
return uint64(ret)
|
||||
}
|
||||
|
||||
func EcNtt(values *[]G1ProjectivePoint, isInverse bool, deviceId int) uint64 {
|
||||
valuesC := (*C.BN254_projective_t)(unsafe.Pointer(&(*values)[0]))
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
isInverseC := C.bool(isInverse)
|
||||
n := C.uint32_t(len(*values))
|
||||
|
||||
ret := C.ecntt_cuda_bn254(valuesC, n, isInverseC, deviceIdC)
|
||||
|
||||
return uint64(ret)
|
||||
}
|
||||
|
||||
func EcNttBatch(values *[]G1ProjectivePoint, isInverse bool, batchSize, deviceId int) uint64 {
|
||||
valuesC := (*C.BN254_projective_t)(unsafe.Pointer(&(*values)[0]))
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
isInverseC := C.bool(isInverse)
|
||||
n := C.uint32_t(len(*values))
|
||||
batchSizeC := C.uint32_t(batchSize)
|
||||
|
||||
ret := C.ecntt_batch_cuda_bn254(valuesC, n, batchSizeC, isInverseC, deviceIdC)
|
||||
|
||||
return uint64(ret)
|
||||
}
|
||||
|
||||
func GenerateTwiddles(d_size int, log_d_size int, inverse bool) (up unsafe.Pointer, err error) {
|
||||
domain_size := C.uint32_t(d_size)
|
||||
logn := C.uint32_t(log_d_size)
|
||||
is_inverse := C.bool(inverse)
|
||||
|
||||
dp := C.build_domain_cuda_bn254(domain_size, logn, is_inverse, 0, 0)
|
||||
|
||||
if dp == nil {
|
||||
err = errors.New("nullptr returned from generating twiddles")
|
||||
return unsafe.Pointer(nil), err
|
||||
}
|
||||
|
||||
return unsafe.Pointer(dp), nil
|
||||
}
|
||||
|
||||
// Reverses d_scalars in-place
|
||||
func ReverseScalars(d_scalars unsafe.Pointer, len int) (int, error) {
|
||||
scalarsC := (*C.BN254_scalar_t)(d_scalars)
|
||||
lenC := C.int(len)
|
||||
if success := C.reverse_order_scalars_cuda_bn254(scalarsC, lenC, 0, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func Interpolate(scalars, twiddles, cosetPowers unsafe.Pointer, size int, isCoset bool) unsafe.Pointer {
|
||||
size_d := size * 32
|
||||
dp, err := goicicle.CudaMalloc(size_d)
|
||||
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
d_out := (*C.BN254_scalar_t)(dp)
|
||||
scalarsC := (*C.BN254_scalar_t)(scalars)
|
||||
twiddlesC := (*C.BN254_scalar_t)(twiddles)
|
||||
cosetPowersC := (*C.BN254_scalar_t)(cosetPowers)
|
||||
sizeC := C.uint(size)
|
||||
|
||||
var ret C.int
|
||||
if isCoset {
|
||||
ret = C.interpolate_scalars_on_coset_cuda_bn254(d_out, scalarsC, twiddlesC, sizeC, cosetPowersC, 0, 0)
|
||||
} else {
|
||||
ret = C.interpolate_scalars_cuda_bn254(d_out, scalarsC, twiddlesC, sizeC, 0, 0)
|
||||
}
|
||||
if ret != 0 {
|
||||
fmt.Print("error interpolating")
|
||||
}
|
||||
|
||||
return unsafe.Pointer(d_out)
|
||||
}
|
||||
|
||||
func Evaluate(scalars_out, scalars, twiddles, coset_powers unsafe.Pointer, scalars_size, twiddles_size int, isCoset bool) int {
|
||||
scalars_outC := (*C.BN254_scalar_t)(scalars_out)
|
||||
scalarsC := (*C.BN254_scalar_t)(scalars)
|
||||
twiddlesC := (*C.BN254_scalar_t)(twiddles)
|
||||
coset_powersC := (*C.BN254_scalar_t)(coset_powers)
|
||||
sizeC := C.uint(scalars_size)
|
||||
twiddlesC_size := C.uint(twiddles_size)
|
||||
|
||||
var ret C.int
|
||||
if isCoset {
|
||||
ret = C.evaluate_scalars_on_coset_cuda_bn254(scalars_outC, scalarsC, twiddlesC, twiddlesC_size, sizeC, coset_powersC, 0, 0)
|
||||
} else {
|
||||
ret = C.evaluate_scalars_cuda_bn254(scalars_outC, scalarsC, twiddlesC, twiddlesC_size, sizeC, 0, 0)
|
||||
}
|
||||
|
||||
if ret != 0 {
|
||||
fmt.Print("error interpolating")
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func VecScalarAdd(in1_d, in2_d unsafe.Pointer, size int) int {
|
||||
in1_dC := (*C.BN254_scalar_t)(in1_d)
|
||||
in2_dC := (*C.BN254_scalar_t)(in2_d)
|
||||
sizeC := C.uint(size)
|
||||
|
||||
ret := C.add_scalars_cuda_bn254(in1_dC, in1_dC, in2_dC, sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
fmt.Print("error adding scalar vectors")
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func VecScalarSub(in1_d, in2_d unsafe.Pointer, size int) int {
|
||||
in1_dC := (*C.BN254_scalar_t)(in1_d)
|
||||
in2_dC := (*C.BN254_scalar_t)(in2_d)
|
||||
sizeC := C.uint(size)
|
||||
|
||||
ret := C.sub_scalars_cuda_bn254(in1_dC, in1_dC, in2_dC, sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
fmt.Print("error subtracting scalar vectors")
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func ToMontgomery(d_scalars unsafe.Pointer, len int) (int, error) {
|
||||
scalarsC := (*C.BN254_scalar_t)(d_scalars)
|
||||
lenC := C.uint(len)
|
||||
if success := C.to_montgomery_scalars_cuda_bn254(scalarsC, lenC, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func FromMontgomery(d_scalars unsafe.Pointer, len int) (int, error) {
|
||||
scalarsC := (*C.BN254_scalar_t)(d_scalars)
|
||||
lenC := C.uint(len)
|
||||
if success := C.from_montgomery_scalars_cuda_bn254(scalarsC, lenC, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func AffinePointFromMontgomery(d_points unsafe.Pointer, len int) (int, error) {
|
||||
pointsC := (*C.BN254_affine_t)(d_points)
|
||||
lenC := C.uint(len)
|
||||
|
||||
if success := C.from_montgomery_aff_points_cuda_bn254(pointsC, lenC, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func G2AffinePointFromMontgomery(d_points unsafe.Pointer, len int) (int, error) {
|
||||
pointsC := (*C.BN254_g2_affine_t)(d_points)
|
||||
lenC := C.uint(len)
|
||||
|
||||
if success := C.from_montgomery_aff_points_g2_cuda_bn254(pointsC, lenC, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bn254
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNttBN254Batch(t *testing.T) {
|
||||
count := 1 << 20
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, scalars)
|
||||
NttBatch(&nttResult, false, count, 0)
|
||||
assert.NotEqual(t, nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, nttResult)
|
||||
}
|
||||
|
||||
func TestNttBN254CompareToGnarkDIF(t *testing.T) {
|
||||
count := 1 << 2
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, scalars)
|
||||
Ntt(&nttResult, false, DIF, 0)
|
||||
assert.NotEqual(t, nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, nttResult)
|
||||
}
|
||||
|
||||
func TestINttBN254CompareToGnarkDIT(t *testing.T) {
|
||||
count := 1 << 3
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, scalars)
|
||||
Ntt(&nttResult, true, DIT, 0)
|
||||
assert.NotEqual(t, nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, nttResult)
|
||||
}
|
||||
|
||||
func TestNttBN254(t *testing.T) {
|
||||
count := 1 << 3
|
||||
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, scalars)
|
||||
Ntt(&nttResult, false, NONE, 0)
|
||||
assert.NotEqual(t, nttResult, scalars)
|
||||
|
||||
inttResult := make([]G1ScalarField, len(nttResult))
|
||||
copy(inttResult, nttResult)
|
||||
|
||||
assert.Equal(t, inttResult, nttResult)
|
||||
Ntt(&inttResult, true, NONE, 0)
|
||||
assert.Equal(t, inttResult, scalars)
|
||||
}
|
||||
|
||||
func TestNttBatchBN254(t *testing.T) {
|
||||
count := 1 << 5
|
||||
batches := 4
|
||||
|
||||
scalars := GenerateScalars(count*batches, false)
|
||||
|
||||
var scalarVecOfVec [][]G1ScalarField = make([][]G1ScalarField, 0)
|
||||
|
||||
for i := 0; i < batches; i++ {
|
||||
start := i * count
|
||||
end := (i + 1) * count
|
||||
batch := make([]G1ScalarField, len(scalars[start:end]))
|
||||
copy(batch, scalars[start:end])
|
||||
scalarVecOfVec = append(scalarVecOfVec, batch)
|
||||
}
|
||||
|
||||
nttBatchResult := make([]G1ScalarField, len(scalars))
|
||||
copy(nttBatchResult, scalars)
|
||||
|
||||
NttBatch(&nttBatchResult, false, count, 0)
|
||||
|
||||
var nttResultVecOfVec [][]G1ScalarField
|
||||
|
||||
for i := 0; i < batches; i++ {
|
||||
// Clone the slice
|
||||
clone := make([]G1ScalarField, len(scalarVecOfVec[i]))
|
||||
copy(clone, scalarVecOfVec[i])
|
||||
|
||||
// Add it to the result vector of vectors
|
||||
nttResultVecOfVec = append(nttResultVecOfVec, clone)
|
||||
|
||||
// Call the ntt_bn254 function
|
||||
Ntt(&nttResultVecOfVec[i], false, NONE, 0)
|
||||
}
|
||||
|
||||
assert.NotEqual(t, nttBatchResult, scalars)
|
||||
|
||||
// Check that the ntt of each vec of scalars is equal to the intt of the specific batch
|
||||
for i := 0; i < batches; i++ {
|
||||
if !reflect.DeepEqual(nttResultVecOfVec[i], nttBatchResult[i*count:((i+1)*count)]) {
|
||||
t.Errorf("ntt of vec of scalars not equal to intt of specific batch")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkNTT(b *testing.B) {
|
||||
LOG_NTT_SIZES := []int{12, 15, 20, 21, 22, 23, 24, 25, 26}
|
||||
|
||||
for _, logNTTSize := range LOG_NTT_SIZES {
|
||||
nttSize := 1 << logNTTSize
|
||||
b.Run(fmt.Sprintf("NTT %d", logNTTSize), func(b *testing.B) {
|
||||
scalars := GenerateScalars(nttSize, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
for n := 0; n < b.N; n++ {
|
||||
Ntt(&nttResult, false, NONE, 0)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package bn254
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"log"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Function to convert [8]uint32 to [4]uint64
|
||||
func ConvertUint32ArrToUint64Arr(arr32 [8]uint32) [4]uint64 {
|
||||
var arr64 [4]uint64
|
||||
for i := 0; i < len(arr32); i += 2 {
|
||||
arr64[i/2] = (uint64(arr32[i]) << 32) | uint64(arr32[i+1])
|
||||
}
|
||||
return arr64
|
||||
}
|
||||
|
||||
func ConvertUint64ArrToUint32Arr(arr64 [4]uint64) [8]uint32 {
|
||||
var arr32 [8]uint32
|
||||
for i, v := range arr64 {
|
||||
b := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(b, v)
|
||||
|
||||
arr32[i*2] = binary.LittleEndian.Uint32(b[0:4])
|
||||
arr32[i*2+1] = binary.LittleEndian.Uint32(b[4:8])
|
||||
}
|
||||
|
||||
return arr32
|
||||
}
|
||||
|
||||
func TimeTrack(start time.Time) {
|
||||
elapsed := time.Since(start)
|
||||
|
||||
// Skip this function, and fetch the PC and file for its parent.
|
||||
pc, _, _, _ := runtime.Caller(1)
|
||||
|
||||
// Retrieve a function object this functions parent.
|
||||
funcObj := runtime.FuncForPC(pc)
|
||||
|
||||
// Regex to extract just the function name (and not the module path).
|
||||
runtimeFunc := regexp.MustCompile(`^.*\.(.*)$`)
|
||||
name := runtimeFunc.ReplaceAllString(funcObj.Name(), "$1")
|
||||
|
||||
log.Println(fmt.Sprintf("%s took %s", name, elapsed))
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
package bn254
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConvertUint32ArrToUint64Arr(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
input [8]uint32
|
||||
want [4]uint64
|
||||
}{
|
||||
{
|
||||
name: "Test with incremental array",
|
||||
input: [8]uint32{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
want: [4]uint64{4294967298, 12884901892, 21474836486, 30064771080},
|
||||
},
|
||||
{
|
||||
name: "Test with all zeros",
|
||||
input: [8]uint32{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
want: [4]uint64{0, 0, 0, 0},
|
||||
},
|
||||
{
|
||||
name: "Test with maximum uint32 values",
|
||||
input: [8]uint32{4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295},
|
||||
want: [4]uint64{18446744073709551615, 18446744073709551615, 18446744073709551615, 18446744073709551615},
|
||||
},
|
||||
{
|
||||
name: "Test with alternating min and max uint32 values",
|
||||
input: [8]uint32{0, 4294967295, 0, 4294967295, 0, 4294967295, 0, 4294967295},
|
||||
want: [4]uint64{4294967295, 4294967295, 4294967295, 4294967295},
|
||||
},
|
||||
{
|
||||
name: "Test with alternating max and min uint32 values",
|
||||
input: [8]uint32{4294967295, 0, 4294967295, 0, 4294967295, 0, 4294967295, 0},
|
||||
want: [4]uint64{18446744069414584320, 18446744069414584320, 18446744069414584320, 18446744069414584320},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got := ConvertUint32ArrToUint64Arr(tc.input)
|
||||
if got != tc.want {
|
||||
t.Errorf("got %v, want %v", got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertUint64ArrToUint32Arr(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
input [4]uint64
|
||||
expected [8]uint32
|
||||
}{
|
||||
{
|
||||
name: "test one",
|
||||
input: [4]uint64{1, 2, 3, 4},
|
||||
expected: [8]uint32{1, 0, 2, 0, 3, 0, 4, 0},
|
||||
},
|
||||
{
|
||||
name: "test two",
|
||||
input: [4]uint64{100, 200, 300, 400},
|
||||
expected: [8]uint32{100, 0, 200, 0, 300, 0, 400, 0},
|
||||
},
|
||||
{
|
||||
name: "test three",
|
||||
input: [4]uint64{1000, 2000, 3000, 4000},
|
||||
expected: [8]uint32{1000, 0, 2000, 0, 3000, 0, 4000, 0},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got := ConvertUint64ArrToUint32Arr(tc.input)
|
||||
if got != tc.expected {
|
||||
t.Errorf("got %v, want %v", got, tc.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
// Copyright 2023 Ingonyama
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by Ingonyama DO NOT EDIT
|
||||
|
||||
package bn254
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ -lbn254
|
||||
// #include "ve_mod_mult.h"
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func VecScalarMulMod(scalarVec1, scalarVec2 unsafe.Pointer, size int) int {
|
||||
scalarVec1C := (*C.BN254_scalar_t)(scalarVec1)
|
||||
scalarVec2C := (*C.BN254_scalar_t)(scalarVec2)
|
||||
sizeC := C.size_t(size)
|
||||
|
||||
ret := C.vec_mod_mult_device_scalar_bn254(scalarVec1C, scalarVec2C, sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
fmt.Print("error multiplying scalar vectors")
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
package goicicle
|
||||
|
||||
// This file implements CUDA driver context management
|
||||
|
||||
// #cgo CFLAGS: -I /usr/loca/cuda/include
|
||||
// #cgo LDFLAGS: -L/usr/local/cuda/lib64 -lcudart
|
||||
/*
|
||||
#include <cuda.h>
|
||||
#include <cuda_runtime.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func CudaMalloc(size int) (dp unsafe.Pointer, err error) {
|
||||
var p C.void
|
||||
dp = unsafe.Pointer(&p)
|
||||
if err := C.cudaMalloc(&dp, C.size_t(size)); err != 0 {
|
||||
return nil, errors.New("could not create memory space")
|
||||
}
|
||||
return dp, nil
|
||||
}
|
||||
|
||||
func CudaFree(dp unsafe.Pointer) int {
|
||||
if err := C.cudaFree(dp); err != 0 {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func CudaMemCpyHtoD[T any](dst_d unsafe.Pointer, src []T, size int) int {
|
||||
src_c := unsafe.Pointer(&src[0])
|
||||
if err := C.cudaMemcpy(dst_d, src_c, C.size_t(size), 1); err != 0 {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func CudaMemCpyDtoH[T any](dst []T, src_d unsafe.Pointer, size int) int {
|
||||
dst_c := unsafe.Pointer(&dst[0])
|
||||
|
||||
if err := C.cudaMemcpy(dst_c, src_d, C.size_t(size), 2); err != 0 {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
SUDO=''
|
||||
if [ "$EUID" != 0 ]; then
|
||||
echo "Icicle setup script should be run with root privileges, please run this as root"
|
||||
SUDO='sudo'
|
||||
fi
|
||||
|
||||
|
||||
TARGET_BN254="libbn254.so"
|
||||
TARGET_BLS12_381="libbls12_381.so"
|
||||
TARGET_BLS12_377="libbls12_377.so"
|
||||
|
||||
MAKE_FAIL=0
|
||||
|
||||
$SUDO make $1 || MAKE_FAIL=1
|
||||
|
||||
if [ $MAKE_FAIL != 0 ]; then
|
||||
echo "make failed, install dependencies and re-run setup script with root privileges"
|
||||
exit
|
||||
fi
|
||||
|
||||
TARGET_BN254_PATH=$(dirname "$(find `pwd` -name $TARGET_BN254 -print -quit)")/
|
||||
TARGET_BLS12_381_PATH=$(dirname "$(find `pwd` -name $TARGET_BLS12_381 -print -quit)")/
|
||||
TARGET_BLS12_377_PATH=$(dirname "$(find `pwd` -name $TARGET_BLS12_377 -print -quit)")/
|
||||
|
||||
|
||||
if [[ "$TARGET_BLS12_377_PATH" != "" ]]; then
|
||||
echo "BLS12_377 found @ $TARGET_BLS12_377_PATH"
|
||||
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:$TARGET_BLS12_377_PATH
|
||||
fi
|
||||
|
||||
if [[ "$TARGET_BN254_PATH" != "" ]]; then
|
||||
echo "BN254 found @ $TARGET_BN254_PATH"
|
||||
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:$TARGET_BN254_PATH
|
||||
fi
|
||||
|
||||
if [[ "$TARGET_BLS12_381_PATH" != "" ]]; then
|
||||
echo "BLS12_381_PATH found @ $TARGET_BLS12_381_PATH"
|
||||
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:$TARGET_BLS12_381_PATH
|
||||
fi
|
||||
@@ -1,42 +0,0 @@
|
||||
package config
|
||||
|
||||
// {{.SharedLib}}
|
||||
type Curve struct {
|
||||
PackageName string
|
||||
CurveNameUpperCase string
|
||||
CurveNameLowerCase string
|
||||
SharedLib string
|
||||
ScalarSize int
|
||||
BaseSize int
|
||||
G2ElementSize int
|
||||
}
|
||||
|
||||
var BN_254 = Curve{
|
||||
PackageName: "bn254",
|
||||
CurveNameUpperCase: "BN254",
|
||||
CurveNameLowerCase: "bn254",
|
||||
SharedLib: "-lbn254",
|
||||
ScalarSize: 8,
|
||||
BaseSize: 8,
|
||||
G2ElementSize: 4,
|
||||
}
|
||||
|
||||
var BLS_12_377 = Curve{
|
||||
PackageName: "bls12377",
|
||||
CurveNameUpperCase: "BLS12_377",
|
||||
CurveNameLowerCase: "bls12_377",
|
||||
SharedLib: "-lbls12_377",
|
||||
ScalarSize: 8,
|
||||
BaseSize: 12,
|
||||
G2ElementSize: 6,
|
||||
}
|
||||
|
||||
var BLS_12_381 = Curve{
|
||||
PackageName: "bls12381",
|
||||
CurveNameUpperCase: "BLS12_381",
|
||||
CurveNameLowerCase: "bls12_381",
|
||||
SharedLib: "-lbls12_381",
|
||||
ScalarSize: 8,
|
||||
BaseSize: 12,
|
||||
G2ElementSize: 6,
|
||||
}
|
||||
@@ -1,306 +0,0 @@
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ {{.SharedLib}}
|
||||
// #include "projective.h"
|
||||
// #include "ve_mod_mult.h"
|
||||
import "C"
|
||||
|
||||
const SCALAR_SIZE = {{.ScalarSize}}
|
||||
const BASE_SIZE = {{.BaseSize}}
|
||||
|
||||
type G1ScalarField struct {
|
||||
S [SCALAR_SIZE]uint32
|
||||
}
|
||||
|
||||
type G1BaseField struct {
|
||||
S [BASE_SIZE]uint32
|
||||
}
|
||||
|
||||
/*
|
||||
* BaseField Constrctors
|
||||
*/
|
||||
|
||||
func (f *G1BaseField) SetZero() *G1BaseField {
|
||||
var S [BASE_SIZE]uint32
|
||||
f.S = S
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *G1BaseField) SetOne() *G1BaseField {
|
||||
var S [BASE_SIZE]uint32
|
||||
|
||||
S[0] = 1
|
||||
|
||||
f.S = S
|
||||
return f
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) FromAffine(affine *G1PointAffine) *G1ProjectivePoint {
|
||||
out := (*C.{{.CurveNameUpperCase}}_projective_t)(unsafe.Pointer(p))
|
||||
in := (*C.{{.CurveNameUpperCase}}_affine_t)(unsafe.Pointer(affine))
|
||||
|
||||
C.projective_from_affine_{{.CurveNameLowerCase}}(out, in)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (f *G1BaseField) FromLimbs(limbs [BASE_SIZE]uint32) *G1BaseField {
|
||||
copy(f.S[:], limbs[:])
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
/*
|
||||
* BaseField methods
|
||||
*/
|
||||
|
||||
func (f *G1BaseField) Limbs() [BASE_SIZE]uint32 {
|
||||
return f.S
|
||||
}
|
||||
|
||||
func (f *G1BaseField) ToBytesLe() []byte {
|
||||
bytes := make([]byte, len(f.S)*4)
|
||||
for i, v := range f.S {
|
||||
binary.LittleEndian.PutUint32(bytes[i*4:], v)
|
||||
}
|
||||
|
||||
return bytes
|
||||
}
|
||||
|
||||
/*
|
||||
* ScalarField methods
|
||||
*/
|
||||
|
||||
func (p *G1ScalarField) Random() *G1ScalarField {
|
||||
outC := (*C.{{.CurveNameUpperCase}}_scalar_t)(unsafe.Pointer(p))
|
||||
C.random_scalar_{{.CurveNameLowerCase}}(outC)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (f *G1ScalarField) SetZero() *G1ScalarField {
|
||||
var S [SCALAR_SIZE]uint32
|
||||
f.S = S
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *G1ScalarField) SetOne() *G1ScalarField {
|
||||
var S [SCALAR_SIZE]uint32
|
||||
S[0] = 1
|
||||
f.S = S
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (a *G1ScalarField) Eq(b *G1ScalarField) bool {
|
||||
for i, v := range a.S {
|
||||
if b.S[i] != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/*
|
||||
* ScalarField methods
|
||||
*/
|
||||
|
||||
func (f *G1ScalarField) Limbs() [SCALAR_SIZE]uint32 {
|
||||
return f.S
|
||||
}
|
||||
|
||||
func (f *G1ScalarField) ToBytesLe() []byte {
|
||||
bytes := make([]byte, len(f.S)*4)
|
||||
for i, v := range f.S {
|
||||
binary.LittleEndian.PutUint32(bytes[i*4:], v)
|
||||
}
|
||||
|
||||
return bytes
|
||||
}
|
||||
|
||||
/*
|
||||
* Point{{.CurveNameUpperCase}}
|
||||
*/
|
||||
|
||||
type G1ProjectivePoint struct {
|
||||
X, Y, Z G1BaseField
|
||||
}
|
||||
|
||||
func (f *G1ProjectivePoint) SetZero() *G1ProjectivePoint {
|
||||
var yOne G1BaseField
|
||||
yOne.SetOne()
|
||||
|
||||
var xZero G1BaseField
|
||||
xZero.SetZero()
|
||||
|
||||
var zZero G1BaseField
|
||||
zZero.SetZero()
|
||||
|
||||
f.X = xZero
|
||||
f.Y = yOne
|
||||
f.Z = zZero
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) Eq(pCompare *G1ProjectivePoint) bool {
|
||||
// Cast *Point{{.CurveNameUpperCase}} to *C.{{.CurveNameUpperCase}}_projective_t
|
||||
// The unsafe.Pointer cast is necessary because Go doesn't allow direct casts
|
||||
// between different pointer types.
|
||||
// It'S your responsibility to ensure that the types are compatible.
|
||||
pC := (*C.{{.CurveNameUpperCase}}_projective_t)(unsafe.Pointer(p))
|
||||
pCompareC := (*C.{{.CurveNameUpperCase}}_projective_t)(unsafe.Pointer(pCompare))
|
||||
|
||||
// Call the C function
|
||||
// The C function doesn't keep any references to the data,
|
||||
// so it'S fine if the Go garbage collector moves or deletes the data later.
|
||||
return bool(C.eq_{{.CurveNameLowerCase}}(pC, pCompareC))
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) IsOnCurve() bool {
|
||||
point := (*C.{{.CurveNameUpperCase}}_projective_t)(unsafe.Pointer(p))
|
||||
res := C.projective_is_on_curve_{{.CurveNameLowerCase}}(point)
|
||||
|
||||
return bool(res)
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) Random() *G1ProjectivePoint {
|
||||
outC := (*C.{{.CurveNameUpperCase}}_projective_t)(unsafe.Pointer(p))
|
||||
C.random_projective_{{.CurveNameLowerCase}}(outC)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) StripZ() *G1PointAffine {
|
||||
return &G1PointAffine{
|
||||
X: p.X,
|
||||
Y: p.Y,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *G1ProjectivePoint) FromLimbs(x, y, z *[]uint32) *G1ProjectivePoint {
|
||||
var _x G1BaseField
|
||||
var _y G1BaseField
|
||||
var _z G1BaseField
|
||||
|
||||
_x.FromLimbs(GetFixedLimbs(x))
|
||||
_y.FromLimbs(GetFixedLimbs(y))
|
||||
_z.FromLimbs(GetFixedLimbs(z))
|
||||
|
||||
p.X = _x
|
||||
p.Y = _y
|
||||
p.Z = _z
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
/*
|
||||
* PointAffineNoInfinity{{.CurveNameUpperCase}}
|
||||
*/
|
||||
|
||||
type G1PointAffine struct {
|
||||
X, Y G1BaseField
|
||||
}
|
||||
|
||||
func (p *G1PointAffine) FromProjective(projective *G1ProjectivePoint) *G1PointAffine {
|
||||
in := (*C.{{.CurveNameUpperCase}}_projective_t)(unsafe.Pointer(projective))
|
||||
out := (*C.{{.CurveNameUpperCase}}_affine_t)(unsafe.Pointer(p))
|
||||
|
||||
C.projective_to_affine_{{.CurveNameLowerCase}}(out,in)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G1PointAffine) ToProjective() *G1ProjectivePoint {
|
||||
var Z G1BaseField
|
||||
Z.SetOne()
|
||||
|
||||
return &G1ProjectivePoint{
|
||||
X: p.X,
|
||||
Y: p.Y,
|
||||
Z: Z,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *G1PointAffine) FromLimbs(X, Y *[]uint32) *G1PointAffine {
|
||||
var _x G1BaseField
|
||||
var _y G1BaseField
|
||||
|
||||
_x.FromLimbs(GetFixedLimbs(X))
|
||||
_y.FromLimbs(GetFixedLimbs(Y))
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiplication
|
||||
*/
|
||||
|
||||
func MultiplyVec(a []G1ProjectivePoint, b []G1ScalarField, deviceID int) {
|
||||
if len(a) != len(b) {
|
||||
panic("a and b have different lengths")
|
||||
}
|
||||
|
||||
pointsC := (*C.{{.CurveNameUpperCase}}_projective_t)(unsafe.Pointer(&a[0]))
|
||||
scalarsC := (*C.{{.CurveNameUpperCase}}_scalar_t)(unsafe.Pointer(&b[0]))
|
||||
deviceIdC := C.size_t(deviceID)
|
||||
nElementsC := C.size_t(len(a))
|
||||
|
||||
C.vec_mod_mult_point_{{.CurveNameLowerCase}}(pointsC, scalarsC, nElementsC, deviceIdC)
|
||||
}
|
||||
|
||||
func MultiplyScalar(a []G1ScalarField, b []G1ScalarField, deviceID int) {
|
||||
if len(a) != len(b) {
|
||||
panic("a and b have different lengths")
|
||||
}
|
||||
|
||||
aC := (*C.{{.CurveNameUpperCase}}_scalar_t)(unsafe.Pointer(&a[0]))
|
||||
bC := (*C.{{.CurveNameUpperCase}}_scalar_t)(unsafe.Pointer(&b[0]))
|
||||
deviceIdC := C.size_t(deviceID)
|
||||
nElementsC := C.size_t(len(a))
|
||||
|
||||
C.vec_mod_mult_scalar_{{.CurveNameLowerCase}}(aC, bC, nElementsC, deviceIdC)
|
||||
}
|
||||
|
||||
// Multiply a matrix by a scalar:
|
||||
//
|
||||
// `a` - flattenned matrix;
|
||||
// `b` - vector to multiply `a` by;
|
||||
func MultiplyMatrix(a []G1ScalarField, b []G1ScalarField, deviceID int) {
|
||||
c := make([]G1ScalarField, len(b))
|
||||
for i := range c {
|
||||
var p G1ScalarField
|
||||
p.SetZero()
|
||||
|
||||
c[i] = p
|
||||
}
|
||||
|
||||
aC := (*C.{{.CurveNameUpperCase}}_scalar_t)(unsafe.Pointer(&a[0]))
|
||||
bC := (*C.{{.CurveNameUpperCase}}_scalar_t)(unsafe.Pointer(&b[0]))
|
||||
cC := (*C.{{.CurveNameUpperCase}}_scalar_t)(unsafe.Pointer(&c[0]))
|
||||
deviceIdC := C.size_t(deviceID)
|
||||
nElementsC := C.size_t(len(a))
|
||||
|
||||
C.matrix_vec_mod_mult_{{.CurveNameLowerCase}}(aC, bC, cC, nElementsC, deviceIdC)
|
||||
}
|
||||
|
||||
/*
|
||||
* Utils
|
||||
*/
|
||||
|
||||
func GetFixedLimbs(slice *[]uint32) [BASE_SIZE]uint32 {
|
||||
if len(*slice) <= BASE_SIZE {
|
||||
limbs := [BASE_SIZE]uint32{}
|
||||
copy(limbs[:len(*slice)], *slice)
|
||||
return limbs
|
||||
}
|
||||
|
||||
panic("slice has too many elements")
|
||||
}
|
||||
@@ -1,180 +0,0 @@
|
||||
import (
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNewField{{.CurveNameUpperCase}}One(t *testing.T) {
|
||||
var oneField G1BaseField
|
||||
oneField.SetOne()
|
||||
|
||||
rawOneField := [8]uint32([8]uint32{0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0})
|
||||
|
||||
assert.Equal(t, oneField.S, rawOneField)
|
||||
}
|
||||
|
||||
func TestNewField{{.CurveNameUpperCase}}Zero(t *testing.T) {
|
||||
var zeroField G1BaseField
|
||||
zeroField.SetZero()
|
||||
|
||||
rawZeroField := [8]uint32([8]uint32{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0})
|
||||
|
||||
assert.Equal(t, zeroField.S, rawZeroField)
|
||||
}
|
||||
|
||||
func TestField{{.CurveNameUpperCase}}ToBytesLe(t *testing.T) {
|
||||
var p G1ProjectivePoint
|
||||
p.Random()
|
||||
|
||||
expected := make([]byte, len(p.X.S)*4) // each uint32 takes 4 bytes
|
||||
for i, v := range p.X.S {
|
||||
binary.LittleEndian.PutUint32(expected[i*4:], v)
|
||||
}
|
||||
|
||||
assert.Equal(t, p.X.ToBytesLe(), expected)
|
||||
assert.Equal(t, len(p.X.ToBytesLe()), 32)
|
||||
}
|
||||
|
||||
func TestNewPoint{{.CurveNameUpperCase}}Zero(t *testing.T) {
|
||||
var pointZero G1ProjectivePoint
|
||||
pointZero.SetZero()
|
||||
|
||||
var baseOne G1BaseField
|
||||
baseOne.SetOne()
|
||||
|
||||
var zeroSanity G1BaseField
|
||||
zeroSanity.SetZero()
|
||||
|
||||
assert.Equal(t, pointZero.X, zeroSanity)
|
||||
assert.Equal(t, pointZero.Y, baseOne)
|
||||
assert.Equal(t, pointZero.Z, zeroSanity)
|
||||
}
|
||||
|
||||
func TestFromProjectiveToAffine(t *testing.T) {
|
||||
var projective G1ProjectivePoint
|
||||
var affine G1PointAffine
|
||||
|
||||
projective.Random()
|
||||
|
||||
affine.FromProjective(&projective)
|
||||
var projective2 G1ProjectivePoint
|
||||
projective2.FromAffine(&affine)
|
||||
|
||||
assert.True(t, projective.IsOnCurve())
|
||||
assert.True(t, projective2.IsOnCurve())
|
||||
assert.True(t, projective.Eq(&projective2))
|
||||
}
|
||||
|
||||
func Test{{.CurveNameUpperCase}}Eq(t *testing.T) {
|
||||
var p1 G1ProjectivePoint
|
||||
p1.Random()
|
||||
var p2 G1ProjectivePoint
|
||||
p2.Random()
|
||||
|
||||
assert.Equal(t, p1.Eq(&p1), true)
|
||||
assert.Equal(t, p1.Eq(&p2), false)
|
||||
}
|
||||
|
||||
func Test{{.CurveNameUpperCase}}StripZ(t *testing.T) {
|
||||
var p1 G1ProjectivePoint
|
||||
p1.Random()
|
||||
|
||||
p2ZLess := p1.StripZ()
|
||||
|
||||
assert.IsType(t, G1PointAffine{}, *p2ZLess)
|
||||
assert.Equal(t, p1.X, p2ZLess.X)
|
||||
assert.Equal(t, p1.Y, p2ZLess.Y)
|
||||
}
|
||||
|
||||
func TestPoint{{.CurveNameUpperCase}}fromLimbs(t *testing.T) {
|
||||
var p G1ProjectivePoint
|
||||
p.Random()
|
||||
|
||||
x := p.X.Limbs()
|
||||
y := p.Y.Limbs()
|
||||
z := p.Z.Limbs()
|
||||
|
||||
xSlice := x[:]
|
||||
ySlice := y[:]
|
||||
zSlice := z[:]
|
||||
|
||||
var pFromLimbs G1ProjectivePoint
|
||||
pFromLimbs.FromLimbs(&xSlice, &ySlice, &zSlice)
|
||||
|
||||
assert.Equal(t, pFromLimbs, p)
|
||||
}
|
||||
|
||||
func TestNewPointAffineNoInfinity{{.CurveNameUpperCase}}Zero(t *testing.T) {
|
||||
var zeroP G1PointAffine
|
||||
|
||||
var zeroSanity G1BaseField
|
||||
zeroSanity.SetZero()
|
||||
|
||||
assert.Equal(t, zeroP.X, zeroSanity)
|
||||
assert.Equal(t, zeroP.Y, zeroSanity)
|
||||
}
|
||||
|
||||
func TestPointAffineNoInfinity{{.CurveNameUpperCase}}FromLimbs(t *testing.T) {
|
||||
// Initialize your test values
|
||||
x := [8]uint32{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
y := [8]uint32{9, 10, 11, 12, 13, 14, 15, 16}
|
||||
xSlice := x[:]
|
||||
ySlice := y[:]
|
||||
|
||||
// Execute your function
|
||||
var result G1PointAffine
|
||||
result.FromLimbs(&xSlice, &ySlice)
|
||||
|
||||
var xBase G1BaseField
|
||||
var yBase G1BaseField
|
||||
xBase.FromLimbs(x)
|
||||
yBase.FromLimbs(y)
|
||||
|
||||
// Define your expected result
|
||||
expected := &G1PointAffine{
|
||||
X: xBase,
|
||||
Y: yBase,
|
||||
}
|
||||
|
||||
// Test if result is as expected
|
||||
assert.Equal(t, result, expected)
|
||||
}
|
||||
|
||||
func TestGetFixedLimbs(t *testing.T) {
|
||||
t.Run("case of valid input of length less than 8", func(t *testing.T) {
|
||||
slice := []uint32{1, 2, 3, 4, 5, 6, 7}
|
||||
expected := [8]uint32{1, 2, 3, 4, 5, 6, 7, 0}
|
||||
|
||||
result := GetFixedLimbs(&slice)
|
||||
assert.Equal(t, result, expected)
|
||||
})
|
||||
|
||||
t.Run("case of valid input of length 8", func(t *testing.T) {
|
||||
slice := []uint32{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
expected := [8]uint32{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
|
||||
result := GetFixedLimbs(&slice)
|
||||
assert.Equal(t, result, expected)
|
||||
})
|
||||
|
||||
t.Run("case of empty input", func(t *testing.T) {
|
||||
slice := []uint32{}
|
||||
expected := [8]uint32{0, 0, 0, 0, 0, 0, 0, 0}
|
||||
|
||||
result := GetFixedLimbs(&slice)
|
||||
assert.Equal(t, result, expected)
|
||||
})
|
||||
|
||||
t.Run("case of input length greater than 8", func(t *testing.T) {
|
||||
slice := []uint32{1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("the code did not panic")
|
||||
}
|
||||
}()
|
||||
|
||||
GetFixedLimbs(&slice)
|
||||
})
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
import (
|
||||
"encoding/binary"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ {{.SharedLib}}
|
||||
// #include "projective.h"
|
||||
// #include "ve_mod_mult.h"
|
||||
import "C"
|
||||
|
||||
// G2 extension field
|
||||
|
||||
type G2Element [{{.G2ElementSize}}]uint64
|
||||
|
||||
type ExtentionField struct {
|
||||
A0, A1 G2Element
|
||||
}
|
||||
|
||||
type G2PointAffine struct {
|
||||
X, Y ExtentionField
|
||||
}
|
||||
|
||||
type G2Point struct {
|
||||
X, Y, Z ExtentionField
|
||||
}
|
||||
|
||||
|
||||
func (p *G2Point) Random() *G2Point {
|
||||
outC := (*C.{{.CurveNameUpperCase}}_g2_projective_t)(unsafe.Pointer(p))
|
||||
C.random_g2_projective_{{.CurveNameLowerCase}}(outC)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G2Point) FromAffine(affine *G2PointAffine) *G2Point {
|
||||
out := (*C.{{.CurveNameUpperCase}}_g2_projective_t)(unsafe.Pointer(p))
|
||||
in := (*C.{{.CurveNameUpperCase}}_g2_affine_t)(unsafe.Pointer(affine))
|
||||
|
||||
C.g2_projective_from_affine_{{.CurveNameLowerCase}}(out, in)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G2Point) Eq(pCompare *G2Point) bool {
|
||||
// Cast *Point{{.CurveNameUpperCase}} to *C.{{.CurveNameUpperCase}}_projective_t
|
||||
// The unsafe.Pointer cast is necessary because Go doesn't allow direct casts
|
||||
// between different pointer types.
|
||||
// It's your responsibility to ensure that the types are compatible.
|
||||
pC := (*C.{{.CurveNameUpperCase}}_g2_projective_t)(unsafe.Pointer(p))
|
||||
pCompareC := (*C.{{.CurveNameUpperCase}}_g2_projective_t)(unsafe.Pointer(pCompare))
|
||||
|
||||
// Call the C function
|
||||
// The C function doesn't keep any references to the data,
|
||||
// so it's fine if the Go garbage collector moves or deletes the data later.
|
||||
return bool(C.eq_g2_{{.CurveNameLowerCase}}(pC, pCompareC))
|
||||
}
|
||||
|
||||
func (f *G2Element) ToBytesLe() []byte {
|
||||
var bytes []byte
|
||||
for _, val := range f {
|
||||
buf := make([]byte, 8) // 8 bytes because uint64 is 64-bit
|
||||
binary.LittleEndian.PutUint64(buf, val)
|
||||
bytes = append(bytes, buf...)
|
||||
}
|
||||
return bytes
|
||||
}
|
||||
|
||||
func (p *G2PointAffine) ToProjective() G2Point {
|
||||
return G2Point{
|
||||
X: p.X,
|
||||
Y: p.Y,
|
||||
Z: ExtentionField{
|
||||
A0: G2Element{1, 0, 0, 0},
|
||||
A1: G2Element{0, 0, 0, 0},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *G2PointAffine) FromProjective(projective *G2Point) *G2PointAffine {
|
||||
out := (*C.{{.CurveNameUpperCase}}_g2_affine_t)(unsafe.Pointer(p))
|
||||
in := (*C.{{.CurveNameUpperCase}}_g2_projective_t)(unsafe.Pointer(projective))
|
||||
|
||||
C.g2_projective_to_affine_{{.CurveNameLowerCase}}(out, in)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *G2Point) IsOnCurve() bool {
|
||||
// Directly copy memory from the C struct to the Go struct
|
||||
point := (*C.{{.CurveNameUpperCase}}_g2_projective_t)(unsafe.Pointer(p))
|
||||
res := C.g2_projective_is_on_curve_{{.CurveNameLowerCase}}(point)
|
||||
|
||||
return bool(res)
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestG2Eqg2(t *testing.T) {
|
||||
var point G2Point
|
||||
|
||||
point.Random()
|
||||
|
||||
assert.True(t, point.Eq(&point))
|
||||
}
|
||||
|
||||
func TestG2FromProjectiveToAffine(t *testing.T) {
|
||||
var projective G2Point
|
||||
var affine G2PointAffine
|
||||
|
||||
projective.Random()
|
||||
|
||||
affine.FromProjective(&projective)
|
||||
var projective2 G2Point
|
||||
projective2.FromAffine(&affine)
|
||||
|
||||
|
||||
assert.True(t, projective.IsOnCurve())
|
||||
assert.True(t, projective2.IsOnCurve())
|
||||
assert.True(t, projective.Eq(&projective2))
|
||||
}
|
||||
|
||||
func TestG2Eqg2NotEqual(t *testing.T) {
|
||||
var point G2Point
|
||||
point.Random()
|
||||
|
||||
var point2 G2Point
|
||||
point2.Random()
|
||||
|
||||
assert.False(t, point.Eq(&point2))
|
||||
}
|
||||
|
||||
func TestG2ToBytes(t *testing.T) {
|
||||
element := G2Element{0x6546098ea84b6298, 0x4a384533d1f68aca, 0xaa0666972d771336, 0x1569e4a34321993}
|
||||
bytes := element.ToBytesLe()
|
||||
|
||||
assert.Equal(t, bytes, []byte{0x98, 0x62, 0x4b, 0xa8, 0x8e, 0x9, 0x46, 0x65, 0xca, 0x8a, 0xf6, 0xd1, 0x33, 0x45, 0x38, 0x4a, 0x36, 0x13, 0x77, 0x2d, 0x97, 0x66, 0x6, 0xaa, 0x93, 0x19, 0x32, 0x34, 0x4a, 0x9e, 0x56, 0x1})
|
||||
}
|
||||
|
||||
func TestG2ShouldConvertToProjective(t *testing.T) {
|
||||
var pointProjective G2Point
|
||||
var pointAffine G2PointAffine
|
||||
|
||||
pointProjective.Random()
|
||||
pointAffine.FromProjective(&pointProjective)
|
||||
|
||||
proj := pointAffine.ToProjective()
|
||||
|
||||
assert.True(t, proj.IsOnCurve())
|
||||
assert.True(t, pointProjective.Eq(&proj))
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
#include <cuda.h>
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
// msm.h
|
||||
|
||||
#ifndef _{{.CurveNameUpperCase}}_MSM_H
|
||||
#define _{{.CurveNameUpperCase}}_MSM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Incomplete declaration of {{.CurveNameUpperCase}} projective and affine structs
|
||||
typedef struct {{.CurveNameUpperCase}}_projective_t {{.CurveNameUpperCase}}_projective_t;
|
||||
typedef struct {{.CurveNameUpperCase}}_g2_projective_t {{.CurveNameUpperCase}}_g2_projective_t;
|
||||
typedef struct {{.CurveNameUpperCase}}_affine_t {{.CurveNameUpperCase}}_affine_t;
|
||||
typedef struct {{.CurveNameUpperCase}}_g2_affine_t {{.CurveNameUpperCase}}_g2_affine_t;
|
||||
typedef struct {{.CurveNameUpperCase}}_scalar_t {{.CurveNameUpperCase}}_scalar_t;
|
||||
typedef cudaStream_t CudaStream_t;
|
||||
|
||||
int msm_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_projective_t* out, {{.CurveNameUpperCase}}_affine_t* points, {{.CurveNameUpperCase}}_scalar_t* scalars, size_t count, size_t device_id);
|
||||
|
||||
int msm_batch_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_projective_t* out,
|
||||
{{.CurveNameUpperCase}}_affine_t* points,
|
||||
{{.CurveNameUpperCase}}_scalar_t* scalars,
|
||||
size_t batch_size,
|
||||
size_t msm_size,
|
||||
size_t device_id);
|
||||
|
||||
int commit_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_projective_t* d_out,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_scalars,
|
||||
{{.CurveNameUpperCase}}_affine_t* d_points,
|
||||
size_t count,
|
||||
unsigned large_bucket_factor,
|
||||
size_t device_id);
|
||||
|
||||
int commit_batch_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_projective_t* d_out,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_scalars,
|
||||
{{.CurveNameUpperCase}}_affine_t* d_points,
|
||||
size_t count,
|
||||
size_t batch_size,
|
||||
size_t device_id);
|
||||
|
||||
int msm_g2_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_g2_projective_t* out,
|
||||
{{.CurveNameUpperCase}}_g2_affine_t* points,
|
||||
{{.CurveNameUpperCase}}_scalar_t* scalars,
|
||||
size_t count,
|
||||
size_t device_id);
|
||||
|
||||
int msm_batch_g2_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_g2_projective_t* out,
|
||||
{{.CurveNameUpperCase}}_g2_affine_t* points,
|
||||
{{.CurveNameUpperCase}}_scalar_t* scalars,
|
||||
size_t batch_size,
|
||||
size_t msm_size,
|
||||
size_t device_id);
|
||||
|
||||
int commit_g2_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_g2_projective_t* d_out,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_scalars,
|
||||
{{.CurveNameUpperCase}}_g2_affine_t* d_points,
|
||||
size_t count,
|
||||
unsigned large_bucket_factor,
|
||||
size_t device_id);
|
||||
|
||||
int commit_batch_g2_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_g2_projective_t* d_out,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_scalars,
|
||||
{{.CurveNameUpperCase}}_g2_affine_t* d_points,
|
||||
size_t count,
|
||||
size_t batch_size,
|
||||
size_t device_id,
|
||||
cudaStream_t stream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _{{.CurveNameUpperCase}}_MSM_H */
|
||||
@@ -1,181 +0,0 @@
|
||||
#include <cuda.h>
|
||||
#include <stdbool.h>
|
||||
// ntt.h
|
||||
|
||||
#ifndef _{{.CurveNameUpperCase}}_NTT_H
|
||||
#define _{{.CurveNameUpperCase}}_NTT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Incomplete declaration of {{.CurveNameUpperCase}} projective and affine structs
|
||||
typedef struct {{.CurveNameUpperCase}}_projective_t {{.CurveNameUpperCase}}_projective_t;
|
||||
typedef struct {{.CurveNameUpperCase}}_affine_t {{.CurveNameUpperCase}}_affine_t;
|
||||
typedef struct {{.CurveNameUpperCase}}_scalar_t {{.CurveNameUpperCase}}_scalar_t;
|
||||
|
||||
typedef struct {{.CurveNameUpperCase}}_g2_projective_t {{.CurveNameUpperCase}}_g2_projective_t;
|
||||
typedef struct {{.CurveNameUpperCase}}_g2_affine_t {{.CurveNameUpperCase}}_g2_affine_t;
|
||||
|
||||
int ntt_cuda_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_scalar_t* arr, uint32_t n, bool inverse, size_t device_id);
|
||||
int ntt_batch_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_scalar_t* arr, uint32_t arr_size, uint32_t batch_size, bool inverse, size_t device_id);
|
||||
|
||||
int ecntt_cuda_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_projective_t* arr, uint32_t n, bool inverse, size_t device_id);
|
||||
int ecntt_batch_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_projective_t* arr, uint32_t arr_size, uint32_t batch_size, bool inverse, size_t device_id);
|
||||
|
||||
{{.CurveNameUpperCase}}_scalar_t*
|
||||
build_domain_cuda_{{.CurveNameLowerCase}}(uint32_t domain_size, uint32_t logn, bool inverse, size_t device_id, size_t stream);
|
||||
|
||||
int interpolate_scalars_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_out,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_evaluations,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned device_id,
|
||||
size_t stream);
|
||||
int interpolate_scalars_batch_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_out,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_evaluations,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int interpolate_points_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_projective_t* d_out,
|
||||
{{.CurveNameUpperCase}}_projective_t* d_evaluations,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int interpolate_points_batch_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_projective_t* d_out,
|
||||
{{.CurveNameUpperCase}}_projective_t* d_evaluations,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int interpolate_scalars_on_coset_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_out,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_evaluations,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
{{.CurveNameUpperCase}}_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int interpolate_scalars_batch_on_coset_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_out,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_evaluations,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
{{.CurveNameUpperCase}}_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
|
||||
int evaluate_scalars_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_out,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_coefficients,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned device_id,
|
||||
size_t stream);
|
||||
int evaluate_scalars_batch_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_out,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_coefficients,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_points_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_projective_t* d_out,
|
||||
{{.CurveNameUpperCase}}_projective_t* d_coefficients,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_points_batch_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_projective_t* d_out,
|
||||
{{.CurveNameUpperCase}}_projective_t* d_coefficients,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_scalars_on_coset_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_out,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_coefficients,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
{{.CurveNameUpperCase}}_scalar_t* coset_powers,
|
||||
unsigned device_id,
|
||||
size_t stream);
|
||||
int evaluate_scalars_on_coset_batch_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_out,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_coefficients,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
{{.CurveNameUpperCase}}_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_points_on_coset_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_projective_t* d_out,
|
||||
{{.CurveNameUpperCase}}_projective_t* d_coefficients,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
{{.CurveNameUpperCase}}_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
int evaluate_points_on_coset_batch_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_projective_t* d_out,
|
||||
{{.CurveNameUpperCase}}_projective_t* d_coefficients,
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
{{.CurveNameUpperCase}}_scalar_t* coset_powers,
|
||||
size_t device_id,
|
||||
size_t stream);
|
||||
|
||||
int reverse_order_scalars_cuda_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_scalar_t* arr, int n, size_t device_id, size_t stream);
|
||||
int reverse_order_scalars_batch_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_scalar_t* arr, int n, int batch_size, size_t device_id, size_t stream);
|
||||
int reverse_order_points_cuda_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_projective_t* arr, int n, size_t device_id, size_t stream);
|
||||
int reverse_order_points_batch_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_projective_t* arr, int n, int batch_size, size_t device_id, size_t stream);
|
||||
int add_scalars_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_out, {{.CurveNameUpperCase}}_scalar_t* d_in1, {{.CurveNameUpperCase}}_scalar_t* d_in2, unsigned n, size_t stream);
|
||||
int sub_scalars_cuda_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_scalar_t* d_out, {{.CurveNameUpperCase}}_scalar_t* d_in1, {{.CurveNameUpperCase}}_scalar_t* d_in2, unsigned n, size_t stream);
|
||||
int to_montgomery_scalars_cuda_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_scalar_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_scalars_cuda_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_scalar_t* d_inout, unsigned n, size_t stream);
|
||||
|
||||
// points g1
|
||||
int to_montgomery_proj_points_cuda_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_projective_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_proj_points_cuda_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_projective_t* d_inout, unsigned n, size_t stream);
|
||||
int to_montgomery_aff_points_cuda_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_affine_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_aff_points_cuda_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_affine_t* d_inout, unsigned n, size_t stream);
|
||||
|
||||
// points g2
|
||||
int to_montgomery_proj_points_g2_cuda_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_g2_projective_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_proj_points_g2_cuda_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_g2_projective_t* d_inout, unsigned n, size_t stream);
|
||||
int to_montgomery_aff_points_g2_cuda_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_g2_affine_t* d_inout, unsigned n, size_t stream);
|
||||
int from_montgomery_aff_points_g2_cuda_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_g2_affine_t* d_inout, unsigned n, size_t stream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _{{.CurveNameUpperCase}}_NTT_H */
|
||||
@@ -1,33 +0,0 @@
|
||||
#include <cuda.h>
|
||||
#include <stdbool.h>
|
||||
// projective.h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {{.CurveNameUpperCase}}_projective_t {{.CurveNameUpperCase}}_projective_t;
|
||||
typedef struct {{.CurveNameUpperCase}}_g2_projective_t {{.CurveNameUpperCase}}_g2_projective_t;
|
||||
typedef struct {{.CurveNameUpperCase}}_affine_t {{.CurveNameUpperCase}}_affine_t;
|
||||
typedef struct {{.CurveNameUpperCase}}_g2_affine_t {{.CurveNameUpperCase}}_g2_affine_t;
|
||||
typedef struct {{.CurveNameUpperCase}}_scalar_t {{.CurveNameUpperCase}}_scalar_t;
|
||||
|
||||
bool projective_is_on_curve_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_projective_t* point1);
|
||||
|
||||
int random_scalar_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_scalar_t* out);
|
||||
int random_projective_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_projective_t* out);
|
||||
{{.CurveNameUpperCase}}_projective_t* projective_zero_{{.CurveNameLowerCase}}();
|
||||
int projective_to_affine_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_affine_t* out, {{.CurveNameUpperCase}}_projective_t* point1);
|
||||
int projective_from_affine_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_projective_t* out, {{.CurveNameUpperCase}}_affine_t* point1);
|
||||
|
||||
int random_g2_projective_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_g2_projective_t* out);
|
||||
int g2_projective_to_affine_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_g2_affine_t* out, {{.CurveNameUpperCase}}_g2_projective_t* point1);
|
||||
int g2_projective_from_affine_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_g2_projective_t* out, {{.CurveNameUpperCase}}_g2_affine_t* point1);
|
||||
bool g2_projective_is_on_curve_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_g2_projective_t* point1);
|
||||
|
||||
bool eq_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_projective_t* point1, {{.CurveNameUpperCase}}_projective_t* point2);
|
||||
bool eq_g2_{{.CurveNameLowerCase}}({{.CurveNameUpperCase}}_g2_projective_t* point1, {{.CurveNameUpperCase}}_g2_projective_t* point2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,32 +0,0 @@
|
||||
#include <stdbool.h>
|
||||
#include <cuda.h>
|
||||
// ve_mod_mult.h
|
||||
|
||||
#ifndef _{{.CurveNameUpperCase}}_VEC_MULT_H
|
||||
#define _{{.CurveNameUpperCase}}_VEC_MULT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {{.CurveNameUpperCase}}_projective_t {{.CurveNameUpperCase}}_projective_t;
|
||||
typedef struct {{.CurveNameUpperCase}}_scalar_t {{.CurveNameUpperCase}}_scalar_t;
|
||||
|
||||
int32_t vec_mod_mult_point_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_projective_t* inout, {{.CurveNameUpperCase}}_scalar_t* scalar_vec, size_t n_elments, size_t device_id);
|
||||
int32_t vec_mod_mult_scalar_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_scalar_t* inout, {{.CurveNameUpperCase}}_scalar_t* scalar_vec, size_t n_elments, size_t device_id);
|
||||
int32_t vec_mod_mult_device_scalar_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_scalar_t* inout, {{.CurveNameUpperCase}}_scalar_t* scalar_vec, size_t n_elements, size_t device_id);
|
||||
int32_t matrix_vec_mod_mult_{{.CurveNameLowerCase}}(
|
||||
{{.CurveNameUpperCase}}_scalar_t* matrix_flattened,
|
||||
{{.CurveNameUpperCase}}_scalar_t* input,
|
||||
{{.CurveNameUpperCase}}_scalar_t* output,
|
||||
size_t n_elments,
|
||||
size_t device_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _{{.CurveNameUpperCase}}_VEC_MULT_H */
|
||||
@@ -1,246 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/consensys/bavard"
|
||||
config "github.com/ingonyama-zk/icicle/goicicle/templates/curves"
|
||||
)
|
||||
|
||||
const (
|
||||
copyrightHolder = "Ingonyama"
|
||||
generatedBy = "Ingonyama"
|
||||
copyrightYear = 2023
|
||||
baseDir = "../curves/"
|
||||
)
|
||||
|
||||
var bgen = bavard.NewBatchGenerator(copyrightHolder, copyrightYear, generatedBy)
|
||||
|
||||
func genMainFiles() {
|
||||
bn254_entries := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bn254", "g1.go"), Templates: []string{"g1.go.tmpl"}},
|
||||
}
|
||||
|
||||
bls12377_entries := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12377", "g1.go"), Templates: []string{"g1.go.tmpl"}},
|
||||
}
|
||||
|
||||
bls12381_entries := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12381", "g1.go"), Templates: []string{"g1.go.tmpl"}},
|
||||
}
|
||||
|
||||
assertNoError(bgen.Generate(config.BLS_12_377, config.BLS_12_377.PackageName, "./curves/", bls12377_entries...))
|
||||
assertNoError(bgen.Generate(config.BN_254, config.BN_254.PackageName, "./curves/", bn254_entries...))
|
||||
assertNoError(bgen.Generate(config.BLS_12_381, config.BLS_12_381.PackageName, "./curves/", bls12381_entries...))
|
||||
|
||||
bn254_g2_entries := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bn254", "g2.go"), Templates: []string{"g2.go.tmpl"}},
|
||||
}
|
||||
|
||||
bls12377_g2_entries := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12377", "g2.go"), Templates: []string{"g2.go.tmpl"}},
|
||||
}
|
||||
|
||||
bls12381_g2_entries := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12381", "g2.go"), Templates: []string{"g2.go.tmpl"}},
|
||||
}
|
||||
|
||||
assertNoError(bgen.Generate(config.BLS_12_377, config.BLS_12_377.PackageName, "./curves/", bls12377_g2_entries...))
|
||||
assertNoError(bgen.Generate(config.BN_254, config.BN_254.PackageName, "./curves/", bn254_g2_entries...))
|
||||
assertNoError(bgen.Generate(config.BLS_12_381, config.BLS_12_381.PackageName, "./curves/", bls12381_g2_entries...))
|
||||
bn254_msm_entries := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bn254", "msm.go"), Templates: []string{"msm.go.tmpl"}},
|
||||
}
|
||||
|
||||
bls12377_msm_entries := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12377", "msm.go"), Templates: []string{"msm.go.tmpl"}},
|
||||
}
|
||||
|
||||
bls12381_msm_entries := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12381", "msm.go"), Templates: []string{"msm.go.tmpl"}},
|
||||
}
|
||||
|
||||
assertNoError(bgen.Generate(config.BLS_12_377, config.BLS_12_377.PackageName, "./msm/", bls12377_msm_entries...))
|
||||
assertNoError(bgen.Generate(config.BN_254, config.BN_254.PackageName, "./msm/", bn254_msm_entries...))
|
||||
assertNoError(bgen.Generate(config.BLS_12_381, config.BLS_12_381.PackageName, "./msm/", bls12381_msm_entries...))
|
||||
|
||||
bn254_ntt_entries := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bn254", "ntt.go"), Templates: []string{"ntt.go.tmpl"}},
|
||||
}
|
||||
|
||||
bls12377_ntt_entries := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12377", "ntt.go"), Templates: []string{"ntt.go.tmpl"}},
|
||||
}
|
||||
|
||||
bls12381_ntt_entries := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12381", "ntt.go"), Templates: []string{"ntt.go.tmpl"}},
|
||||
}
|
||||
|
||||
assertNoError(bgen.Generate(config.BLS_12_377, config.BLS_12_377.PackageName, "./ntt/", bls12377_ntt_entries...))
|
||||
assertNoError(bgen.Generate(config.BN_254, config.BN_254.PackageName, "./ntt/", bn254_ntt_entries...))
|
||||
assertNoError(bgen.Generate(config.BLS_12_381, config.BLS_12_381.PackageName, "./ntt/", bls12381_ntt_entries...))
|
||||
|
||||
bn254_vec_mod_entries := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bn254", "vec_mod.go"), Templates: []string{"vec_mod.go.tmpl"}},
|
||||
}
|
||||
|
||||
bls12377_vec_mod_entries := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12377", "vec_mod.go"), Templates: []string{"vec_mod.go.tmpl"}},
|
||||
}
|
||||
|
||||
bls12381_vec_mod_entries := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12381", "vec_mod.go"), Templates: []string{"vec_mod.go.tmpl"}},
|
||||
}
|
||||
|
||||
assertNoError(bgen.Generate(config.BLS_12_377, config.BLS_12_377.PackageName, "./ops/", bls12377_vec_mod_entries...))
|
||||
assertNoError(bgen.Generate(config.BN_254, config.BN_254.PackageName, "./ops/", bn254_vec_mod_entries...))
|
||||
assertNoError(bgen.Generate(config.BLS_12_381, config.BLS_12_381.PackageName, "./ops/", bls12381_vec_mod_entries...))
|
||||
|
||||
h_msm_bn254 := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bn254", "include", "msm.h"), Templates: []string{"msm.h.tmpl"}},
|
||||
}
|
||||
|
||||
h_msm_bls12377 := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12377", "include", "msm.h"), Templates: []string{"msm.h.tmpl"}},
|
||||
}
|
||||
|
||||
h_msm_bls12381 := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12381", "include", "msm.h"), Templates: []string{"msm.h.tmpl"}},
|
||||
}
|
||||
|
||||
assertNoError(bgen.Generate(config.BLS_12_377, config.BLS_12_377.PackageName, "./hfiles/", h_msm_bls12377...))
|
||||
assertNoError(bgen.Generate(config.BN_254, config.BN_254.PackageName, "./hfiles/", h_msm_bn254...))
|
||||
assertNoError(bgen.Generate(config.BLS_12_381, config.BLS_12_381.PackageName, "./hfiles/", h_msm_bls12381...))
|
||||
|
||||
h_ntt_bn254 := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bn254", "include", "ntt.h"), Templates: []string{"ntt.h.tmpl"}},
|
||||
}
|
||||
|
||||
h_ntt_bls12377 := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12377", "include", "ntt.h"), Templates: []string{"ntt.h.tmpl"}},
|
||||
}
|
||||
|
||||
h_ntt_bls12381 := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12381", "include", "ntt.h"), Templates: []string{"ntt.h.tmpl"}},
|
||||
}
|
||||
|
||||
assertNoError(bgen.Generate(config.BLS_12_377, config.BLS_12_377.PackageName, "./hfiles/", h_ntt_bls12377...))
|
||||
assertNoError(bgen.Generate(config.BN_254, config.BN_254.PackageName, "./hfiles/", h_ntt_bn254...))
|
||||
assertNoError(bgen.Generate(config.BLS_12_381, config.BLS_12_381.PackageName, "./hfiles/", h_ntt_bls12381...))
|
||||
|
||||
ve_mod_mult_h_bn254 := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bn254", "include", "ve_mod_mult.h"), Templates: []string{"ve_mod_mult.h.tmpl"}},
|
||||
}
|
||||
|
||||
ve_mod_mult_h_bls12377 := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12377", "include", "ve_mod_mult.h"), Templates: []string{"ve_mod_mult.h.tmpl"}},
|
||||
}
|
||||
|
||||
ve_mod_mult_ht_bls12381 := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12381", "include", "ve_mod_mult.h"), Templates: []string{"ve_mod_mult.h.tmpl"}},
|
||||
}
|
||||
|
||||
assertNoError(bgen.Generate(config.BLS_12_377, config.BLS_12_377.PackageName, "./hfiles/", ve_mod_mult_h_bls12377...))
|
||||
assertNoError(bgen.Generate(config.BN_254, config.BN_254.PackageName, "./hfiles/", ve_mod_mult_h_bn254...))
|
||||
assertNoError(bgen.Generate(config.BLS_12_381, config.BLS_12_381.PackageName, "./hfiles/", ve_mod_mult_ht_bls12381...))
|
||||
|
||||
projective_bn254 := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bn254", "include", "projective.h"), Templates: []string{"projective.h.tmpl"}},
|
||||
}
|
||||
|
||||
projective_bls12377 := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12377", "include", "projective.h"), Templates: []string{"projective.h.tmpl"}},
|
||||
}
|
||||
|
||||
projective_bls12381 := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12381", "include", "projective.h"), Templates: []string{"projective.h.tmpl"}},
|
||||
}
|
||||
|
||||
assertNoError(bgen.Generate(config.BLS_12_377, config.BLS_12_377.PackageName, "./hfiles/", projective_bls12377...))
|
||||
assertNoError(bgen.Generate(config.BN_254, config.BN_254.PackageName, "./hfiles/", projective_bn254...))
|
||||
assertNoError(bgen.Generate(config.BLS_12_381, config.BLS_12_381.PackageName, "./hfiles/", projective_bls12381...))
|
||||
}
|
||||
|
||||
func genTestFiles() {
|
||||
// G1 TESTS
|
||||
bn254_entries := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bn254", "g1_test.go"), Templates: []string{"g1_test.go.tmpl"}},
|
||||
}
|
||||
|
||||
bls12377_entries := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12377", "g1_test.go"), Templates: []string{"g1_test.go.tmpl"}},
|
||||
}
|
||||
|
||||
bls12381_entries := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12381", "g1_test.go"), Templates: []string{"g1_test.go.tmpl"}},
|
||||
}
|
||||
|
||||
assertNoError(bgen.Generate(config.BLS_12_377, config.BLS_12_377.PackageName, "./curves/", bls12377_entries...))
|
||||
assertNoError(bgen.Generate(config.BN_254, config.BN_254.PackageName, "./curves/", bn254_entries...))
|
||||
assertNoError(bgen.Generate(config.BLS_12_381, config.BLS_12_381.PackageName, "./curves/", bls12381_entries...))
|
||||
|
||||
// G2 TESTS
|
||||
bn254_entries_g2_test := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bn254", "g2_test.go"), Templates: []string{"g2_test.go.tmpl"}},
|
||||
}
|
||||
|
||||
bls12377_entries_g2_test := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12377", "g2_test.go"), Templates: []string{"g2_test.go.tmpl"}},
|
||||
}
|
||||
|
||||
bls12381_entries_g2_test := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12381", "g2_test.go"), Templates: []string{"g2_test.go.tmpl"}},
|
||||
}
|
||||
|
||||
assertNoError(bgen.Generate(config.BLS_12_377, config.BLS_12_377.PackageName, "./curves/", bls12377_entries_g2_test...))
|
||||
assertNoError(bgen.Generate(config.BN_254, config.BN_254.PackageName, "./curves/", bn254_entries_g2_test...))
|
||||
assertNoError(bgen.Generate(config.BLS_12_381, config.BLS_12_381.PackageName, "./curves/", bls12381_entries_g2_test...))
|
||||
|
||||
// MSM TEST
|
||||
bn254_entries_msm_test := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bn254", "msm_test.go"), Templates: []string{"msm_test.go.tmpl"}},
|
||||
}
|
||||
|
||||
bls12377_entries_msm_test := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12377", "msm_test.go"), Templates: []string{"msm_test.go.tmpl"}},
|
||||
}
|
||||
|
||||
bls12381_entries_msm_test := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12381", "msm_test.go"), Templates: []string{"msm_test.go.tmpl"}},
|
||||
}
|
||||
|
||||
assertNoError(bgen.Generate(config.BLS_12_377, config.BLS_12_377.PackageName, "./msm/", bls12377_entries_msm_test...))
|
||||
assertNoError(bgen.Generate(config.BN_254, config.BN_254.PackageName, "./msm/", bn254_entries_msm_test...))
|
||||
assertNoError(bgen.Generate(config.BLS_12_381, config.BLS_12_381.PackageName, "./msm/", bls12381_entries_msm_test...))
|
||||
|
||||
// FFT TEST
|
||||
bn254_entries_fft_test := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bn254", "ntt_test.go"), Templates: []string{"ntt_test.go.tmpl"}},
|
||||
}
|
||||
|
||||
bls12377_entries_fft_test := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12377", "ntt_test.go"), Templates: []string{"ntt_test.go.tmpl"}},
|
||||
}
|
||||
|
||||
bls12381_entries_fft_test := []bavard.Entry{
|
||||
{File: filepath.Join(baseDir, "bls12381", "ntt_test.go"), Templates: []string{"ntt_test.go.tmpl"}},
|
||||
}
|
||||
|
||||
assertNoError(bgen.Generate(config.BLS_12_377, config.BLS_12_377.PackageName, "./ntt/", bls12377_entries_fft_test...))
|
||||
assertNoError(bgen.Generate(config.BN_254, config.BN_254.PackageName, "./ntt/", bn254_entries_fft_test...))
|
||||
assertNoError(bgen.Generate(config.BLS_12_381, config.BLS_12_381.PackageName, "./ntt/", bls12381_entries_fft_test...))
|
||||
}
|
||||
|
||||
func main() {
|
||||
genMainFiles()
|
||||
genTestFiles()
|
||||
}
|
||||
|
||||
func assertNoError(err error) {
|
||||
if err != nil {
|
||||
fmt.Printf("\n%s\n", err.Error())
|
||||
os.Exit(-1)
|
||||
}
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ {{.SharedLib}}
|
||||
// #include "msm.h"
|
||||
import "C"
|
||||
|
||||
func Msm(out *G1ProjectivePoint, points []G1PointAffine, scalars []G1ScalarField, device_id int) (*G1ProjectivePoint, error) {
|
||||
if len(points) != len(scalars) {
|
||||
return nil, errors.New("error on: len(points) != len(scalars)")
|
||||
}
|
||||
|
||||
pointsC := (*C.{{.CurveNameUpperCase}}_affine_t)(unsafe.Pointer(&points[0]))
|
||||
scalarsC := (*C.{{.CurveNameUpperCase}}_scalar_t)(unsafe.Pointer(&scalars[0]))
|
||||
outC := (*C.{{.CurveNameUpperCase}}_projective_t)(unsafe.Pointer(out))
|
||||
ret := C.msm_cuda_{{.CurveNameLowerCase}}(outC, pointsC, scalarsC, C.size_t(len(points)), C.size_t(device_id))
|
||||
|
||||
if ret != 0 {
|
||||
return nil, fmt.Errorf("msm_cuda_{{.CurveNameLowerCase}} returned error code: %d", ret)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func MsmG2(out *G2Point, points []G2PointAffine, scalars []G1ScalarField, device_id int) (*G2Point, error) {
|
||||
if len(points) != len(scalars) {
|
||||
return nil, errors.New("error on: len(points) != len(scalars)")
|
||||
}
|
||||
|
||||
pointsC := (*C.{{.CurveNameUpperCase}}_g2_affine_t)(unsafe.Pointer(&points[0]))
|
||||
scalarsC := (*C.{{.CurveNameUpperCase}}_scalar_t)(unsafe.Pointer(&scalars[0]))
|
||||
outC := (*C.{{.CurveNameUpperCase}}_g2_projective_t)(unsafe.Pointer(out))
|
||||
|
||||
ret := C.msm_g2_cuda_{{.CurveNameLowerCase}}(outC, pointsC, scalarsC, C.size_t(len(points)), C.size_t(device_id))
|
||||
|
||||
if ret != 0 {
|
||||
return nil, fmt.Errorf("msm_g2_cuda_{{.CurveNameLowerCase}} returned error code: %d", ret)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func MsmBatch(points *[]G1PointAffine, scalars *[]G1ScalarField, batchSize, deviceId int) ([]*G1ProjectivePoint, error) {
|
||||
// Check for nil pointers
|
||||
if points == nil || scalars == nil {
|
||||
return nil, errors.New("points or scalars is nil")
|
||||
}
|
||||
|
||||
if len(*points) != len(*scalars) {
|
||||
return nil, errors.New("error on: len(points) != len(scalars)")
|
||||
}
|
||||
|
||||
// Check for empty slices
|
||||
if len(*points) == 0 || len(*scalars) == 0 {
|
||||
return nil, errors.New("points or scalars is empty")
|
||||
}
|
||||
|
||||
// Check for zero batchSize
|
||||
if batchSize <= 0 {
|
||||
return nil, errors.New("error on: batchSize must be greater than zero")
|
||||
}
|
||||
|
||||
out := make([]*G1ProjectivePoint, batchSize)
|
||||
|
||||
for i := 0; i < len(out); i++ {
|
||||
var p G1ProjectivePoint
|
||||
p.SetZero()
|
||||
|
||||
out[i] = &p
|
||||
}
|
||||
|
||||
outC := (*C.{{.CurveNameUpperCase}}_projective_t)(unsafe.Pointer(&out[0]))
|
||||
pointsC := (*C.{{.CurveNameUpperCase}}_affine_t)(unsafe.Pointer(&(*points)[0]))
|
||||
scalarsC := (*C.{{.CurveNameUpperCase}}_scalar_t)(unsafe.Pointer(&(*scalars)[0]))
|
||||
msmSizeC := C.size_t(len(*points) / batchSize)
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
batchSizeC := C.size_t(batchSize)
|
||||
|
||||
ret := C.msm_batch_cuda_{{.CurveNameLowerCase}}(outC, pointsC, scalarsC, batchSizeC, msmSizeC, deviceIdC)
|
||||
if ret != 0 {
|
||||
return nil, fmt.Errorf("msm_batch_cuda_{{.CurveNameLowerCase}} returned error code: %d", ret)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func MsmG2Batch(points *[]G2PointAffine, scalars *[]G1ScalarField, batchSize, deviceId int) ([]*G2Point, error) {
|
||||
// Check for nil pointers
|
||||
if points == nil || scalars == nil {
|
||||
return nil, errors.New("points or scalars is nil")
|
||||
}
|
||||
|
||||
if len(*points) != len(*scalars) {
|
||||
return nil, errors.New("error on: len(points) != len(scalars)")
|
||||
}
|
||||
|
||||
// Check for empty slices
|
||||
if len(*points) == 0 || len(*scalars) == 0 {
|
||||
return nil, errors.New("points or scalars is empty")
|
||||
}
|
||||
|
||||
// Check for zero batchSize
|
||||
if batchSize <= 0 {
|
||||
return nil, errors.New("error on: batchSize must be greater than zero")
|
||||
}
|
||||
|
||||
out := make([]*G2Point, batchSize)
|
||||
|
||||
outC := (*C.{{.CurveNameUpperCase}}_g2_projective_t)(unsafe.Pointer(&out[0]))
|
||||
pointsC := (*C.{{.CurveNameUpperCase}}_g2_affine_t)(unsafe.Pointer(&(*points)[0]))
|
||||
scalarsC := (*C.{{.CurveNameUpperCase}}_scalar_t)(unsafe.Pointer(&(*scalars)[0]))
|
||||
msmSizeC := C.size_t(len(*points) / batchSize)
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
batchSizeC := C.size_t(batchSize)
|
||||
|
||||
ret := C.msm_batch_g2_cuda_{{.CurveNameLowerCase}}(outC, pointsC, scalarsC, batchSizeC, msmSizeC, deviceIdC)
|
||||
if ret != 0 {
|
||||
return nil, fmt.Errorf("msm_batch_cuda_{{.CurveNameLowerCase}} returned error code: %d", ret)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func Commit(d_out, d_scalars, d_points unsafe.Pointer, count, bucketFactor int) int {
|
||||
d_outC := (*C.{{.CurveNameUpperCase}}_projective_t)(d_out)
|
||||
scalarsC := (*C.{{.CurveNameUpperCase}}_scalar_t)(d_scalars)
|
||||
pointsC := (*C.{{.CurveNameUpperCase}}_affine_t)(d_points)
|
||||
countC := (C.size_t)(count)
|
||||
largeBucketFactorC := C.uint(bucketFactor)
|
||||
|
||||
ret := C.commit_cuda_{{.CurveNameLowerCase}}(d_outC, scalarsC, pointsC, countC, largeBucketFactorC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func CommitG2(d_out, d_scalars, d_points unsafe.Pointer, count, bucketFactor int) int {
|
||||
d_outC := (*C.{{.CurveNameUpperCase}}_g2_projective_t)(d_out)
|
||||
scalarsC := (*C.{{.CurveNameUpperCase}}_scalar_t)(d_scalars)
|
||||
pointsC := (*C.{{.CurveNameUpperCase}}_g2_affine_t)(d_points)
|
||||
countC := (C.size_t)(count)
|
||||
largeBucketFactorC := C.uint(bucketFactor)
|
||||
|
||||
ret := C.commit_g2_cuda_{{.CurveNameLowerCase}}(d_outC, scalarsC, pointsC, countC, largeBucketFactorC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func CommitBatch(d_out, d_scalars, d_points unsafe.Pointer, count, batch_size int) int {
|
||||
d_outC := (*C.{{.CurveNameUpperCase}}_projective_t)(d_out)
|
||||
scalarsC := (*C.{{.CurveNameUpperCase}}_scalar_t)(d_scalars)
|
||||
pointsC := (*C.{{.CurveNameUpperCase}}_affine_t)(d_points)
|
||||
countC := (C.size_t)(count)
|
||||
batch_sizeC := (C.size_t)(batch_size)
|
||||
|
||||
ret := C.commit_batch_cuda_{{.CurveNameLowerCase}}(d_outC, scalarsC, pointsC, countC, batch_sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func CommitG2Batch(d_out, d_scalars, d_points unsafe.Pointer, count, batch_size int) int {
|
||||
d_outC := (*C.{{.CurveNameUpperCase}}_g2_projective_t)(d_out)
|
||||
scalarsC := (*C.{{.CurveNameUpperCase}}_scalar_t)(d_scalars)
|
||||
pointsC := (*C.{{.CurveNameUpperCase}}_g2_affine_t)(d_points)
|
||||
countC := (C.size_t)(count)
|
||||
batch_sizeC := (C.size_t)(batch_size)
|
||||
|
||||
ret := C.msm_batch_g2_cuda_{{.CurveNameLowerCase}}(d_outC, pointsC, scalarsC, countC, batch_sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -1,337 +0,0 @@
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"testing"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/goicicle"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func GeneratePoints(count int) []G1PointAffine {
|
||||
// Declare a slice of integers
|
||||
var points []G1PointAffine
|
||||
|
||||
// populate the slice
|
||||
for i := 0; i < 10; i++ {
|
||||
var pointProjective G1ProjectivePoint
|
||||
pointProjective.Random()
|
||||
|
||||
var pointAffine G1PointAffine
|
||||
pointAffine.FromProjective(&pointProjective)
|
||||
|
||||
points = append(points, pointAffine)
|
||||
}
|
||||
|
||||
log2_10 := math.Log2(10)
|
||||
log2Count := math.Log2(float64(count))
|
||||
log2Size := int(math.Ceil(log2Count - log2_10))
|
||||
|
||||
for i := 0; i < log2Size; i++ {
|
||||
points = append(points, points...)
|
||||
}
|
||||
|
||||
return points[:count]
|
||||
}
|
||||
|
||||
func GeneratePointsProj(count int) []G1ProjectivePoint {
|
||||
// Declare a slice of integers
|
||||
var points []G1ProjectivePoint
|
||||
// Use a loop to populate the slice
|
||||
for i := 0; i < count; i++ {
|
||||
var p G1ProjectivePoint
|
||||
p.Random()
|
||||
|
||||
points = append(points, p)
|
||||
}
|
||||
|
||||
return points
|
||||
}
|
||||
|
||||
func GenerateScalars(count int, skewed bool) []G1ScalarField {
|
||||
// Declare a slice of integers
|
||||
var scalars []G1ScalarField
|
||||
|
||||
var rand G1ScalarField
|
||||
var zero G1ScalarField
|
||||
var one G1ScalarField
|
||||
var randLarge G1ScalarField
|
||||
|
||||
zero.SetZero()
|
||||
one.SetOne()
|
||||
randLarge.Random()
|
||||
|
||||
if skewed && count > 1_200_000 {
|
||||
for i := 0; i < count-1_200_000; i++ {
|
||||
rand.Random()
|
||||
scalars = append(scalars, rand)
|
||||
}
|
||||
|
||||
for i := 0; i < 600_000; i++ {
|
||||
scalars = append(scalars, randLarge)
|
||||
}
|
||||
for i := 0; i < 400_000; i++ {
|
||||
scalars = append(scalars, zero)
|
||||
}
|
||||
for i := 0; i < 200_000; i++ {
|
||||
scalars = append(scalars, one)
|
||||
}
|
||||
} else {
|
||||
for i := 0; i < count; i++ {
|
||||
rand.Random()
|
||||
scalars = append(scalars, rand)
|
||||
}
|
||||
}
|
||||
|
||||
return scalars[:count]
|
||||
}
|
||||
|
||||
func TestMSM(t *testing.T) {
|
||||
for _, v := range []int{24} {
|
||||
count := 1 << v
|
||||
|
||||
points := GeneratePoints(count)
|
||||
fmt.Print("Finished generating points\n")
|
||||
scalars := GenerateScalars(count, true)
|
||||
fmt.Print("Finished generating scalars\n")
|
||||
|
||||
out := new(G1ProjectivePoint)
|
||||
startTime := time.Now()
|
||||
_, e := Msm(out, points, scalars, 0) // non mont
|
||||
fmt.Printf("icicle MSM took: %d ms\n", time.Since(startTime).Milliseconds())
|
||||
|
||||
assert.Equal(t, e, nil, "error should be nil")
|
||||
|
||||
assert.True(t, out.IsOnCurve())
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommitMSM(t *testing.T) {
|
||||
for _, v := range []int{24} {
|
||||
count := 1<<v - 1
|
||||
|
||||
points := GeneratePoints(count)
|
||||
fmt.Print("Finished generating points\n")
|
||||
scalars := GenerateScalars(count, true)
|
||||
fmt.Print("Finished generating scalars\n")
|
||||
|
||||
out_d, _ := goicicle.CudaMalloc(96)
|
||||
|
||||
pointsBytes := count * 64
|
||||
points_d, _ := goicicle.CudaMalloc(pointsBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1PointAffine](points_d, points, pointsBytes)
|
||||
|
||||
scalarBytes := count * 32
|
||||
scalars_d, _ := goicicle.CudaMalloc(scalarBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1ScalarField](scalars_d, scalars, scalarBytes)
|
||||
|
||||
startTime := time.Now()
|
||||
e := Commit(out_d, scalars_d, points_d, count, 10)
|
||||
fmt.Printf("icicle MSM took: %d ms\n", time.Since(startTime).Milliseconds())
|
||||
|
||||
outHost := make([]G1ProjectivePoint, 1)
|
||||
goicicle.CudaMemCpyDtoH[G1ProjectivePoint](outHost, out_d, 96)
|
||||
|
||||
assert.Equal(t, e, 0, "error should be 0")
|
||||
assert.True(t, outHost[0].IsOnCurve())
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCommit(b *testing.B) {
|
||||
LOG_MSM_SIZES := []int{20, 21, 22, 23, 24, 25, 26}
|
||||
|
||||
for _, logMsmSize := range LOG_MSM_SIZES {
|
||||
msmSize := 1 << logMsmSize
|
||||
points := GeneratePoints(msmSize)
|
||||
scalars := GenerateScalars(msmSize, false)
|
||||
|
||||
out_d, _ := goicicle.CudaMalloc(96)
|
||||
|
||||
pointsBytes := msmSize * 64
|
||||
points_d, _ := goicicle.CudaMalloc(pointsBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1PointAffine](points_d, points, pointsBytes)
|
||||
|
||||
scalarBytes := msmSize * 32
|
||||
scalars_d, _ := goicicle.CudaMalloc(scalarBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1ScalarField](scalars_d, scalars, scalarBytes)
|
||||
|
||||
b.Run(fmt.Sprintf("MSM %d", logMsmSize), func(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
e := Commit(out_d, scalars_d, points_d, msmSize, 10)
|
||||
|
||||
if e != 0 {
|
||||
panic("Error occured")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBenchMSM(t *testing.T) {
|
||||
for _, batchPow2 := range []int{2, 4} {
|
||||
for _, pow2 := range []int{4, 6} {
|
||||
msmSize := 1 << pow2
|
||||
batchSize := 1 << batchPow2
|
||||
count := msmSize * batchSize
|
||||
|
||||
points := GeneratePoints(count)
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
a, e := MsmBatch(&points, &scalars, batchSize, 0)
|
||||
|
||||
if e != nil {
|
||||
t.Errorf("MsmBatch{{.CurveNameUpperCase}} returned an error: %v", e)
|
||||
}
|
||||
|
||||
if len(a) != batchSize {
|
||||
t.Errorf("Expected length %d, but got %d", batchSize, len(a))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMSM(b *testing.B) {
|
||||
LOG_MSM_SIZES := []int{20, 21, 22, 23, 24, 25, 26}
|
||||
|
||||
for _, logMsmSize := range LOG_MSM_SIZES {
|
||||
msmSize := 1 << logMsmSize
|
||||
points := GeneratePoints(msmSize)
|
||||
scalars := GenerateScalars(msmSize, false)
|
||||
b.Run(fmt.Sprintf("MSM %d", logMsmSize), func(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
out := new(G1ProjectivePoint)
|
||||
_, e := Msm(out, points, scalars, 0)
|
||||
|
||||
if e != nil {
|
||||
panic("Error occured")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// G2
|
||||
func GenerateG2Points(count int) []G2PointAffine {
|
||||
// Declare a slice of integers
|
||||
var points []G2PointAffine
|
||||
|
||||
// populate the slice
|
||||
for i := 0; i < 10; i++ {
|
||||
var p G2Point
|
||||
p.Random()
|
||||
var affine G2PointAffine
|
||||
affine.FromProjective(&p)
|
||||
|
||||
points = append(points, affine)
|
||||
}
|
||||
|
||||
log2_10 := math.Log2(10)
|
||||
log2Count := math.Log2(float64(count))
|
||||
log2Size := int(math.Ceil(log2Count - log2_10))
|
||||
|
||||
for i := 0; i < log2Size; i++ {
|
||||
points = append(points, points...)
|
||||
}
|
||||
|
||||
return points[:count]
|
||||
}
|
||||
|
||||
func TestMsmG2{{.CurveNameUpperCase}}(t *testing.T) {
|
||||
for _, v := range []int{24} {
|
||||
count := 1 << v
|
||||
points := GenerateG2Points(count)
|
||||
fmt.Print("Finished generating points\n")
|
||||
scalars := GenerateScalars(count, false)
|
||||
fmt.Print("Finished generating scalars\n")
|
||||
|
||||
out := new(G2Point)
|
||||
_, e := MsmG2(out, points, scalars, 0)
|
||||
assert.Equal(t, e, nil, "error should be nil")
|
||||
assert.True(t, out.IsOnCurve())
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMsmG2{{.CurveNameUpperCase}}(b *testing.B) {
|
||||
LOG_MSM_SIZES := []int{20, 21, 22, 23, 24, 25, 26}
|
||||
|
||||
for _, logMsmSize := range LOG_MSM_SIZES {
|
||||
msmSize := 1 << logMsmSize
|
||||
points := GenerateG2Points(msmSize)
|
||||
scalars := GenerateScalars(msmSize, false)
|
||||
b.Run(fmt.Sprintf("MSM G2 %d", logMsmSize), func(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
out := new(G2Point)
|
||||
_, e := MsmG2(out, points, scalars, 0)
|
||||
|
||||
if e != nil {
|
||||
panic("Error occured")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommitG2MSM(t *testing.T) {
|
||||
for _, v := range []int{24} {
|
||||
count := 1 << v
|
||||
|
||||
points := GenerateG2Points(count)
|
||||
fmt.Print("Finished generating points\n")
|
||||
scalars := GenerateScalars(count, true)
|
||||
fmt.Print("Finished generating scalars\n")
|
||||
|
||||
var sizeCheckG2PointAffine G2PointAffine
|
||||
inputPointsBytes := count * int(unsafe.Sizeof(sizeCheckG2PointAffine))
|
||||
|
||||
var sizeCheckG2Point G2Point
|
||||
out_d, _ := goicicle.CudaMalloc(int(unsafe.Sizeof(sizeCheckG2Point)))
|
||||
|
||||
points_d, _ := goicicle.CudaMalloc(inputPointsBytes)
|
||||
goicicle.CudaMemCpyHtoD[G2PointAffine](points_d, points, inputPointsBytes)
|
||||
|
||||
scalarBytes := count * 32
|
||||
scalars_d, _ := goicicle.CudaMalloc(scalarBytes)
|
||||
goicicle.CudaMemCpyHtoD[G1ScalarField](scalars_d, scalars, scalarBytes)
|
||||
|
||||
startTime := time.Now()
|
||||
e := CommitG2(out_d, scalars_d, points_d, count, 10)
|
||||
fmt.Printf("icicle MSM took: %d ms\n", time.Since(startTime).Milliseconds())
|
||||
|
||||
outHost := make([]G2Point, 1)
|
||||
goicicle.CudaMemCpyDtoH[G2Point](outHost, out_d, int(unsafe.Sizeof(sizeCheckG2Point)))
|
||||
|
||||
assert.Equal(t, e, 0, "error should be 0")
|
||||
assert.Equal(t, len(outHost), 1)
|
||||
result := outHost[0]
|
||||
|
||||
assert.True(t, result.IsOnCurve())
|
||||
}
|
||||
}
|
||||
|
||||
func TestBatchG2MSM(t *testing.T) {
|
||||
for _, batchPow2 := range []int{2, 4} {
|
||||
for _, pow2 := range []int{4, 6} {
|
||||
msmSize := 1 << pow2
|
||||
batchSize := 1 << batchPow2
|
||||
count := msmSize * batchSize
|
||||
|
||||
points := GenerateG2Points(count)
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
pointsResults, e := MsmG2Batch(&points, &scalars, batchSize, 0)
|
||||
|
||||
if e != nil {
|
||||
t.Errorf("MsmBatch{{.CurveNameUpperCase}} returned an error: %v", e)
|
||||
}
|
||||
|
||||
if len(pointsResults) != batchSize {
|
||||
t.Errorf("Expected length %d, but got %d", batchSize, len(pointsResults))
|
||||
}
|
||||
|
||||
for _, s := range pointsResults {
|
||||
assert.True(t, s.IsOnCurve())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,203 +0,0 @@
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/goicicle"
|
||||
)
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ {{.SharedLib}}
|
||||
// #include "ntt.h"
|
||||
import "C"
|
||||
|
||||
const (
|
||||
NONE = 0
|
||||
DIF = 1
|
||||
DIT = 2
|
||||
)
|
||||
|
||||
func Ntt(scalars *[]G1ScalarField, isInverse bool, deviceId int) uint64 {
|
||||
scalarsC := (*C.{{.CurveNameUpperCase}}_scalar_t)(unsafe.Pointer(&(*scalars)[0]))
|
||||
|
||||
ret := C.ntt_cuda_{{.CurveNameLowerCase}}(scalarsC, C.uint32_t(len(*scalars)), C.bool(isInverse), C.size_t(deviceId))
|
||||
|
||||
return uint64(ret)
|
||||
}
|
||||
|
||||
func NttBatch(scalars *[]G1ScalarField, isInverse bool, batchSize, deviceId int) uint64 {
|
||||
scalarsC := (*C.{{.CurveNameUpperCase}}_scalar_t)(unsafe.Pointer(&(*scalars)[0]))
|
||||
isInverseC := C.bool(isInverse)
|
||||
batchSizeC := C.uint32_t(batchSize)
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
|
||||
ret := C.ntt_batch_cuda_{{.CurveNameLowerCase}}(scalarsC, C.uint32_t(len(*scalars)), batchSizeC, isInverseC, deviceIdC)
|
||||
|
||||
return uint64(ret)
|
||||
}
|
||||
|
||||
func EcNtt(values *[]G1ProjectivePoint, isInverse bool, deviceId int) uint64 {
|
||||
valuesC := (*C.{{.CurveNameUpperCase}}_projective_t)(unsafe.Pointer(&(*values)[0]))
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
isInverseC := C.bool(isInverse)
|
||||
n := C.uint32_t(len(*values))
|
||||
|
||||
ret := C.ecntt_cuda_{{.CurveNameLowerCase}}(valuesC, n, isInverseC, deviceIdC)
|
||||
|
||||
return uint64(ret)
|
||||
}
|
||||
|
||||
func EcNttBatch(values *[]G1ProjectivePoint, isInverse bool, batchSize, deviceId int) uint64 {
|
||||
valuesC := (*C.{{.CurveNameUpperCase}}_projective_t)(unsafe.Pointer(&(*values)[0]))
|
||||
deviceIdC := C.size_t(deviceId)
|
||||
isInverseC := C.bool(isInverse)
|
||||
n := C.uint32_t(len(*values))
|
||||
batchSizeC := C.uint32_t(batchSize)
|
||||
|
||||
ret := C.ecntt_batch_cuda_{{.CurveNameLowerCase}}(valuesC, n, batchSizeC, isInverseC, deviceIdC)
|
||||
|
||||
return uint64(ret)
|
||||
}
|
||||
|
||||
func GenerateTwiddles(d_size int, log_d_size int, inverse bool) (up unsafe.Pointer, err error) {
|
||||
domain_size := C.uint32_t(d_size)
|
||||
logn := C.uint32_t(log_d_size)
|
||||
is_inverse := C.bool(inverse)
|
||||
|
||||
dp := C.build_domain_cuda_{{.CurveNameLowerCase}}(domain_size, logn, is_inverse, 0, 0)
|
||||
|
||||
if dp == nil {
|
||||
err = errors.New("nullptr returned from generating twiddles")
|
||||
return unsafe.Pointer(nil), err
|
||||
}
|
||||
|
||||
return unsafe.Pointer(dp), nil
|
||||
}
|
||||
|
||||
// Reverses d_scalars in-place
|
||||
func ReverseScalars(d_scalars unsafe.Pointer, len int) (int, error) {
|
||||
scalarsC := (*C.{{.CurveNameUpperCase}}_scalar_t)(d_scalars)
|
||||
lenC := C.int(len)
|
||||
if success := C.reverse_order_scalars_cuda_{{.CurveNameLowerCase}}(scalarsC, lenC, 0, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func Interpolate(scalars, twiddles, cosetPowers unsafe.Pointer, size int, isCoset bool) unsafe.Pointer {
|
||||
size_d := size * 32
|
||||
dp, err := goicicle.CudaMalloc(size_d)
|
||||
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
d_out := (*C.{{.CurveNameUpperCase}}_scalar_t)(dp)
|
||||
scalarsC := (*C.{{.CurveNameUpperCase}}_scalar_t)(scalars)
|
||||
twiddlesC := (*C.{{.CurveNameUpperCase}}_scalar_t)(twiddles)
|
||||
cosetPowersC := (*C.{{.CurveNameUpperCase}}_scalar_t)(cosetPowers)
|
||||
sizeC := C.uint(size)
|
||||
|
||||
var ret C.int
|
||||
if isCoset {
|
||||
ret = C.interpolate_scalars_on_coset_cuda_{{.CurveNameLowerCase}}(d_out, scalarsC, twiddlesC, sizeC, cosetPowersC, 0, 0)
|
||||
} else {
|
||||
ret = C.interpolate_scalars_cuda_{{.CurveNameLowerCase}}(d_out, scalarsC, twiddlesC, sizeC, 0, 0)
|
||||
}
|
||||
if ret != 0 {
|
||||
fmt.Print("error interpolating")
|
||||
}
|
||||
|
||||
return unsafe.Pointer(d_out)
|
||||
}
|
||||
|
||||
func Evaluate(scalars_out, scalars, twiddles, coset_powers unsafe.Pointer, scalars_size, twiddles_size int, isCoset bool) int {
|
||||
scalars_outC := (*C.{{.CurveNameUpperCase}}_scalar_t)(scalars_out)
|
||||
scalarsC := (*C.{{.CurveNameUpperCase}}_scalar_t)(scalars)
|
||||
twiddlesC := (*C.{{.CurveNameUpperCase}}_scalar_t)(twiddles)
|
||||
coset_powersC := (*C.{{.CurveNameUpperCase}}_scalar_t)(coset_powers)
|
||||
sizeC := C.uint(scalars_size)
|
||||
twiddlesC_size := C.uint(twiddles_size)
|
||||
|
||||
var ret C.int
|
||||
if isCoset {
|
||||
ret = C.evaluate_scalars_on_coset_cuda_{{.CurveNameLowerCase}}(scalars_outC, scalarsC, twiddlesC, twiddlesC_size, sizeC, coset_powersC, 0, 0)
|
||||
} else {
|
||||
ret = C.evaluate_scalars_cuda_{{.CurveNameLowerCase}}(scalars_outC, scalarsC, twiddlesC, twiddlesC_size, sizeC, 0, 0)
|
||||
}
|
||||
|
||||
if ret != 0 {
|
||||
fmt.Print("error interpolating")
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func VecScalarAdd(in1_d, in2_d unsafe.Pointer, size int) int {
|
||||
in1_dC := (*C.{{.CurveNameUpperCase}}_scalar_t)(in1_d)
|
||||
in2_dC := (*C.{{.CurveNameUpperCase}}_scalar_t)(in2_d)
|
||||
sizeC := C.uint(size)
|
||||
|
||||
ret := C.add_scalars_cuda_{{.CurveNameLowerCase}}(in1_dC, in1_dC, in2_dC, sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
fmt.Print("error adding scalar vectors")
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func VecScalarSub(in1_d, in2_d unsafe.Pointer, size int) int {
|
||||
in1_dC := (*C.{{.CurveNameUpperCase}}_scalar_t)(in1_d)
|
||||
in2_dC := (*C.{{.CurveNameUpperCase}}_scalar_t)(in2_d)
|
||||
sizeC := C.uint(size)
|
||||
|
||||
ret := C.sub_scalars_cuda_{{.CurveNameLowerCase}}(in1_dC, in1_dC, in2_dC, sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
fmt.Print("error subtracting scalar vectors")
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func ToMontgomery(d_scalars unsafe.Pointer, len int) (int, error) {
|
||||
scalarsC := (*C.{{.CurveNameUpperCase}}_scalar_t)(d_scalars)
|
||||
lenC := C.uint(len)
|
||||
if success := C.to_montgomery_scalars_cuda_{{.CurveNameLowerCase}}(scalarsC, lenC, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func FromMontgomery(d_scalars unsafe.Pointer, len int) (int, error) {
|
||||
scalarsC := (*C.{{.CurveNameUpperCase}}_scalar_t)(d_scalars)
|
||||
lenC := C.uint(len)
|
||||
if success := C.from_montgomery_scalars_cuda_{{.CurveNameLowerCase}}(scalarsC, lenC, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func AffinePointFromMontgomery(d_points unsafe.Pointer, len int) (int, error) {
|
||||
pointsC := (*C.{{.CurveNameUpperCase}}_affine_t)(d_points)
|
||||
lenC := C.uint(len)
|
||||
|
||||
if success := C.from_montgomery_aff_points_cuda_{{.CurveNameLowerCase}}(pointsC, lenC, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func G2AffinePointFromMontgomery(d_points unsafe.Pointer, len int) (int, error) {
|
||||
pointsC := (*C.{{.CurveNameUpperCase}}_g2_affine_t)(d_points)
|
||||
lenC := C.uint(len)
|
||||
|
||||
if success := C.from_montgomery_aff_points_g2_cuda_{{.CurveNameLowerCase}}(pointsC, lenC, 0); success != 0 {
|
||||
return -1, errors.New("reversing failed")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNtt{{.CurveNameUpperCase}}Batch(t *testing.T) {
|
||||
count := 1 << 20
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, scalars)
|
||||
NttBatch(&nttResult, false, count, 0)
|
||||
assert.NotEqual(t, nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, nttResult)
|
||||
}
|
||||
|
||||
func TestNtt{{.CurveNameUpperCase}}CompareToGnarkDIF(t *testing.T) {
|
||||
count := 1 << 2
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, scalars)
|
||||
Ntt(&nttResult, false, DIF, 0)
|
||||
assert.NotEqual(t, nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, nttResult)
|
||||
}
|
||||
|
||||
func TestINtt{{.CurveNameUpperCase}}CompareToGnarkDIT(t *testing.T) {
|
||||
count := 1 << 3
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, scalars)
|
||||
Ntt(&nttResult, true, DIT, 0)
|
||||
assert.NotEqual(t, nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, nttResult)
|
||||
}
|
||||
|
||||
func TestNtt{{.CurveNameUpperCase}}(t *testing.T) {
|
||||
count := 1 << 3
|
||||
|
||||
scalars := GenerateScalars(count, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
|
||||
assert.Equal(t, nttResult, scalars)
|
||||
Ntt(&nttResult, false, NONE, 0)
|
||||
assert.NotEqual(t, nttResult, scalars)
|
||||
|
||||
inttResult := make([]G1ScalarField, len(nttResult))
|
||||
copy(inttResult, nttResult)
|
||||
|
||||
assert.Equal(t, inttResult, nttResult)
|
||||
Ntt(&inttResult, true, NONE, 0)
|
||||
assert.Equal(t, inttResult, scalars)
|
||||
}
|
||||
|
||||
func TestNttBatch{{.CurveNameUpperCase}}(t *testing.T) {
|
||||
count := 1 << 5
|
||||
batches := 4
|
||||
|
||||
scalars := GenerateScalars(count*batches, false)
|
||||
|
||||
var scalarVecOfVec [][]G1ScalarField = make([][]G1ScalarField, 0)
|
||||
|
||||
for i := 0; i < batches; i++ {
|
||||
start := i * count
|
||||
end := (i + 1) * count
|
||||
batch := make([]G1ScalarField, len(scalars[start:end]))
|
||||
copy(batch, scalars[start:end])
|
||||
scalarVecOfVec = append(scalarVecOfVec, batch)
|
||||
}
|
||||
|
||||
nttBatchResult := make([]G1ScalarField, len(scalars))
|
||||
copy(nttBatchResult, scalars)
|
||||
|
||||
NttBatch(&nttBatchResult, false, count, 0)
|
||||
|
||||
var nttResultVecOfVec [][]G1ScalarField
|
||||
|
||||
for i := 0; i < batches; i++ {
|
||||
// Clone the slice
|
||||
clone := make([]G1ScalarField, len(scalarVecOfVec[i]))
|
||||
copy(clone, scalarVecOfVec[i])
|
||||
|
||||
// Add it to the result vector of vectors
|
||||
nttResultVecOfVec = append(nttResultVecOfVec, clone)
|
||||
|
||||
// Call the ntt_{{.CurveNameLowerCase}} function
|
||||
Ntt(&nttResultVecOfVec[i], false, NONE, 0)
|
||||
}
|
||||
|
||||
assert.NotEqual(t, nttBatchResult, scalars)
|
||||
|
||||
// Check that the ntt of each vec of scalars is equal to the intt of the specific batch
|
||||
for i := 0; i < batches; i++ {
|
||||
if !reflect.DeepEqual(nttResultVecOfVec[i], nttBatchResult[i*count:((i+1)*count)]) {
|
||||
t.Errorf("ntt of vec of scalars not equal to intt of specific batch")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkNTT(b *testing.B) {
|
||||
LOG_NTT_SIZES := []int{12, 15, 20, 21, 22, 23, 24, 25, 26}
|
||||
|
||||
for _, logNTTSize := range LOG_NTT_SIZES {
|
||||
nttSize := 1 << logNTTSize
|
||||
b.Run(fmt.Sprintf("NTT %d", logNTTSize), func(b *testing.B) {
|
||||
scalars := GenerateScalars(nttSize, false)
|
||||
|
||||
nttResult := make([]G1ScalarField, len(scalars)) // Make a new slice with the same length
|
||||
copy(nttResult, scalars)
|
||||
for n := 0; n < b.N; n++ {
|
||||
Ntt(&nttResult, false, NONE, 0)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../ {{.SharedLib}}
|
||||
// #include "ve_mod_mult.h"
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func VecScalarMulMod(scalarVec1, scalarVec2 unsafe.Pointer, size int) int {
|
||||
scalarVec1C := (*C.{{.CurveNameUpperCase}}_scalar_t)(scalarVec1)
|
||||
scalarVec2C := (*C.{{.CurveNameUpperCase}}_scalar_t)(scalarVec2)
|
||||
sizeC := C.size_t(size)
|
||||
|
||||
ret := C.vec_mod_mult_device_scalar_{{.CurveNameLowerCase}}(scalarVec1C, scalarVec2C, sizeC, 0)
|
||||
|
||||
if ret != 0 {
|
||||
fmt.Print("error multiplying scalar vectors")
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# GoogleTest requires at least C++14
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CUDA_STANDARD 17)
|
||||
set(CMAKE_CUDA_STANDARD 14)
|
||||
set(CMAKE_CUDA_STANDARD_REQUIRED TRUE)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
|
||||
# add the target cuda architectures
|
||||
@@ -22,10 +22,6 @@ FetchContent_Declare(
|
||||
URL https://github.com/google/googletest/archive/refs/tags/v1.13.0.zip
|
||||
)
|
||||
# For Windows: Prevent overriding the parent project's compiler/linker settings
|
||||
|
||||
# boosting lib
|
||||
include_directories("/home/miner/include/boost_1_80_0")
|
||||
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
FetchContent_MakeAvailable(googletest)
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,46 +3,19 @@
|
||||
#pragma once
|
||||
|
||||
template <typename S, typename P, typename A>
|
||||
void bucket_method_msm(
|
||||
unsigned bitsize,
|
||||
unsigned c,
|
||||
S* scalars,
|
||||
A* points,
|
||||
unsigned size,
|
||||
P* final_result,
|
||||
bool on_device,
|
||||
bool big_triangle,
|
||||
cudaStream_t stream);
|
||||
void bucket_method_msm(unsigned bitsize, unsigned c, S *scalars, A *points, unsigned size, P* final_result, bool on_device);
|
||||
|
||||
template <typename S, typename P, typename A>
|
||||
void batched_bucket_method_msm(
|
||||
unsigned bitsize,
|
||||
unsigned c,
|
||||
S* scalars,
|
||||
A* points,
|
||||
unsigned batch_size,
|
||||
unsigned msm_size,
|
||||
P* final_results,
|
||||
bool on_device,
|
||||
cudaStream_t stream);
|
||||
void batched_bucket_method_msm(unsigned bitsize, unsigned c, S *scalars, A *points, unsigned batch_size, unsigned msm_size, P* final_results, bool on_device);
|
||||
|
||||
template <typename S, typename P, typename A>
|
||||
void batched_large_msm(
|
||||
S* scalars, A* points, unsigned batch_size, unsigned msm_size, P* result, bool on_device, cudaStream_t stream);
|
||||
void batched_large_msm(S* scalars, A* points, unsigned batch_size, unsigned msm_size, P* result, bool on_device);
|
||||
|
||||
template <typename S, typename P, typename A>
|
||||
void large_msm(
|
||||
S* scalars,
|
||||
A* points,
|
||||
unsigned size,
|
||||
P* result,
|
||||
bool on_device,
|
||||
bool big_triangle,
|
||||
unsigned large_bucket_factor,
|
||||
cudaStream_t stream);
|
||||
void large_msm(S* scalars, A* points, unsigned size, P* result, bool on_device);
|
||||
|
||||
template <typename S, typename P, typename A>
|
||||
void short_msm(S* h_scalars, A* h_points, unsigned size, P* h_final_result, cudaStream_t stream);
|
||||
void short_msm(S *h_scalars, A *h_points, unsigned size, P* h_final_result, bool on_device);
|
||||
|
||||
template <typename A, typename S, typename P>
|
||||
void reference_msm(S* scalars, A* a_points, unsigned size);
|
||||
|
||||
@@ -1,115 +1,181 @@
|
||||
#include "../../primitives/field.cuh"
|
||||
#include "../../primitives/projective.cuh"
|
||||
#include "../../utils/cuda_utils.cuh"
|
||||
#include "msm.cu"
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
// #include "../../curves/bls12_377/curve_config.cuh"
|
||||
#include "../../curves/bn254/curve_config.cuh"
|
||||
#include "msm.cu"
|
||||
#include "../../utils/cuda_utils.cuh"
|
||||
#include "../../primitives/projective.cuh"
|
||||
#include "../../primitives/field.cuh"
|
||||
#include "../../curves/bls12_381/curve_config.cuh"
|
||||
|
||||
// using namespace BLS12_377;
|
||||
using namespace BN254;
|
||||
using namespace BLS12_381;
|
||||
|
||||
class Dummy_Scalar
|
||||
struct fake_point
|
||||
{
|
||||
public:
|
||||
static constexpr unsigned NBITS = 32;
|
||||
unsigned val = 0;
|
||||
|
||||
unsigned x;
|
||||
unsigned p = 10;
|
||||
// unsigned p = 1<<30;
|
||||
|
||||
static HOST_DEVICE_INLINE Dummy_Scalar zero() { return {0}; }
|
||||
|
||||
static HOST_DEVICE_INLINE Dummy_Scalar one() { return {1}; }
|
||||
|
||||
friend HOST_INLINE std::ostream& operator<<(std::ostream& os, const Dummy_Scalar& scalar)
|
||||
{
|
||||
os << scalar.x;
|
||||
return os;
|
||||
}
|
||||
|
||||
HOST_DEVICE_INLINE unsigned get_scalar_digit(unsigned digit_num, unsigned digit_width)
|
||||
{
|
||||
return (x >> (digit_num * digit_width)) & ((1 << digit_width) - 1);
|
||||
}
|
||||
|
||||
friend HOST_DEVICE_INLINE Dummy_Scalar operator+(Dummy_Scalar p1, const Dummy_Scalar& p2)
|
||||
{
|
||||
return {(p1.x + p2.x) % p1.p};
|
||||
}
|
||||
|
||||
friend HOST_DEVICE_INLINE bool operator==(const Dummy_Scalar& p1, const Dummy_Scalar& p2) { return (p1.x == p2.x); }
|
||||
|
||||
friend HOST_DEVICE_INLINE bool operator==(const Dummy_Scalar& p1, const unsigned p2) { return (p1.x == p2); }
|
||||
|
||||
static HOST_DEVICE_INLINE Dummy_Scalar neg(const Dummy_Scalar& scalar) { return {scalar.p - scalar.x}; }
|
||||
static HOST_INLINE Dummy_Scalar rand_host()
|
||||
{
|
||||
return {(unsigned)rand() % 10};
|
||||
// return {(unsigned)rand()};
|
||||
}
|
||||
};
|
||||
|
||||
class Dummy_Projective
|
||||
{
|
||||
public:
|
||||
Dummy_Scalar x;
|
||||
|
||||
static HOST_DEVICE_INLINE Dummy_Projective zero() { return {0}; }
|
||||
|
||||
static HOST_DEVICE_INLINE Dummy_Projective one() { return {1}; }
|
||||
|
||||
static HOST_DEVICE_INLINE Dummy_Projective to_affine(const Dummy_Projective& point) { return {point.x}; }
|
||||
|
||||
static HOST_DEVICE_INLINE Dummy_Projective from_affine(const Dummy_Projective& point) { return {point.x}; }
|
||||
|
||||
static HOST_DEVICE_INLINE Dummy_Projective neg(const Dummy_Projective& point) { return {Dummy_Scalar::neg(point.x)}; }
|
||||
|
||||
friend HOST_DEVICE_INLINE Dummy_Projective operator+(Dummy_Projective p1, const Dummy_Projective& p2)
|
||||
{
|
||||
return {p1.x + p2.x};
|
||||
}
|
||||
|
||||
// friend HOST_DEVICE_INLINE Dummy_Projective operator-(Dummy_Projective p1, const Dummy_Projective& p2) {
|
||||
// return p1 + neg(p2);
|
||||
// }
|
||||
|
||||
friend HOST_INLINE std::ostream& operator<<(std::ostream& os, const Dummy_Projective& point)
|
||||
{
|
||||
os << point.x;
|
||||
return os;
|
||||
}
|
||||
|
||||
friend HOST_DEVICE_INLINE Dummy_Projective operator*(Dummy_Scalar scalar, const Dummy_Projective& point)
|
||||
{
|
||||
Dummy_Projective res = zero();
|
||||
#ifdef CUDA_ARCH
|
||||
#pragma unroll
|
||||
#endif
|
||||
for (int i = 0; i < Dummy_Scalar::NBITS; i++) {
|
||||
if (i > 0) { res = res + res; }
|
||||
if (scalar.get_scalar_digit(Dummy_Scalar::NBITS - i - 1, 1)) { res = res + point; }
|
||||
__host__ __device__ inline fake_point operator+(fake_point fp) {
|
||||
return {val+fp.val};
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
friend HOST_DEVICE_INLINE bool operator==(const Dummy_Projective& p1, const Dummy_Projective& p2)
|
||||
{
|
||||
return (p1.x == p2.x);
|
||||
}
|
||||
__host__ __device__ fake_point zero() {
|
||||
fake_point p;
|
||||
return p;
|
||||
}
|
||||
|
||||
static HOST_DEVICE_INLINE bool is_zero(const Dummy_Projective& point) { return point.x == 0; }
|
||||
|
||||
static HOST_INLINE Dummy_Projective rand_host()
|
||||
{
|
||||
return {(unsigned)rand() % 10};
|
||||
// return {(unsigned)rand()};
|
||||
}
|
||||
};
|
||||
|
||||
// switch between dummy and real:
|
||||
std::ostream& operator<<(std::ostream &strm, const fake_point &a) {
|
||||
return strm <<a.val;
|
||||
}
|
||||
|
||||
struct fake_scalar
|
||||
{
|
||||
unsigned val = 0;
|
||||
unsigned bitsize = 32;
|
||||
|
||||
// __host__ __device__ unsigned get_scalar_digit(unsigned digit_num, unsigned digit_width){
|
||||
|
||||
// return (val>>(digit_num*digit_width))&((1<<digit_width)-1);
|
||||
|
||||
// }
|
||||
__host__ __device__ int get_scalar_digit(int digit_num, int digit_width){
|
||||
|
||||
return (val>>(digit_num*digit_width))&((1<<digit_width)-1);
|
||||
|
||||
}
|
||||
|
||||
__host__ __device__ inline fake_point operator*(fake_point fp) {
|
||||
|
||||
fake_point p1;
|
||||
fake_point p2;
|
||||
unsigned x = val;
|
||||
if (x == 0) return fake_point().zero();
|
||||
|
||||
unsigned i = 1;
|
||||
unsigned c_bit = (x & (1<<(bitsize-1)))>>(bitsize-1);
|
||||
while (c_bit==0 && i<bitsize){
|
||||
i++;
|
||||
c_bit = (x & (1<<(bitsize-i)))>>(bitsize-i);
|
||||
}
|
||||
p1 = fp;
|
||||
p2 = p1+p1;
|
||||
while (i<bitsize){
|
||||
i++;
|
||||
c_bit = (x & (1<<(bitsize-i)))>>(bitsize-i);
|
||||
if (c_bit){
|
||||
p1 = p1 + p2;
|
||||
p2 = p2 + p2;
|
||||
}
|
||||
else {
|
||||
p2 = p1 + p2;
|
||||
p1 = p1 + p1;
|
||||
}
|
||||
}
|
||||
|
||||
return p1;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class Dummy_Scalar {
|
||||
public:
|
||||
static constexpr unsigned NBITS = 32;
|
||||
|
||||
unsigned x;
|
||||
|
||||
friend HOST_INLINE std::ostream& operator<<(std::ostream& os, const Dummy_Scalar& scalar) {
|
||||
os << scalar.x;
|
||||
return os;
|
||||
}
|
||||
|
||||
HOST_DEVICE_INLINE unsigned get_scalar_digit(unsigned digit_num, unsigned digit_width) {
|
||||
return (x>>(digit_num*digit_width))&((1<<digit_width)-1);
|
||||
}
|
||||
|
||||
friend HOST_DEVICE_INLINE Dummy_Scalar operator+(Dummy_Scalar p1, const Dummy_Scalar& p2) {
|
||||
return {p1.x+p2.x};
|
||||
}
|
||||
|
||||
friend HOST_DEVICE_INLINE bool operator==(const Dummy_Scalar& p1, const Dummy_Scalar& p2) {
|
||||
return (p1.x == p2.x);
|
||||
}
|
||||
|
||||
friend HOST_DEVICE_INLINE bool operator==(const Dummy_Scalar& p1, const unsigned p2) {
|
||||
return (p1.x == p2);
|
||||
}
|
||||
|
||||
// static HOST_DEVICE_INLINE Dummy_Scalar neg(const Dummy_Scalar &scalar) {
|
||||
// return {Dummy_Scalar::neg(point.x)};
|
||||
// }
|
||||
static HOST_INLINE Dummy_Scalar rand_host() {
|
||||
return {(unsigned)rand()};
|
||||
}
|
||||
};
|
||||
|
||||
class Dummy_Projective {
|
||||
|
||||
public:
|
||||
Dummy_Scalar x;
|
||||
|
||||
static HOST_DEVICE_INLINE Dummy_Projective zero() {
|
||||
return {0};
|
||||
}
|
||||
|
||||
static HOST_DEVICE_INLINE Dummy_Projective to_affine(const Dummy_Projective &point) {
|
||||
return {point.x};
|
||||
}
|
||||
|
||||
static HOST_DEVICE_INLINE Dummy_Projective from_affine(const Dummy_Projective &point) {
|
||||
return {point.x};
|
||||
}
|
||||
|
||||
// static HOST_DEVICE_INLINE Dummy_Projective neg(const Dummy_Projective &point) {
|
||||
// return {Dummy_Scalar::neg(point.x)};
|
||||
// }
|
||||
|
||||
friend HOST_DEVICE_INLINE Dummy_Projective operator+(Dummy_Projective p1, const Dummy_Projective& p2) {
|
||||
return {p1.x+p2.x};
|
||||
}
|
||||
|
||||
// friend HOST_DEVICE_INLINE Dummy_Projective operator-(Dummy_Projective p1, const Dummy_Projective& p2) {
|
||||
// return p1 + neg(p2);
|
||||
// }
|
||||
|
||||
friend HOST_INLINE std::ostream& operator<<(std::ostream& os, const Dummy_Projective& point) {
|
||||
os << point.x;
|
||||
return os;
|
||||
}
|
||||
|
||||
friend HOST_DEVICE_INLINE Dummy_Projective operator*(Dummy_Scalar scalar, const Dummy_Projective& point) {
|
||||
Dummy_Projective res = zero();
|
||||
#ifdef CUDA_ARCH
|
||||
#pragma unroll
|
||||
#endif
|
||||
for (int i = 0; i < Dummy_Scalar::NBITS; i++) {
|
||||
if (i > 0) {
|
||||
res = res + res;
|
||||
}
|
||||
if (scalar.get_scalar_digit(Dummy_Scalar::NBITS - i - 1, 1)) {
|
||||
res = res + point;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
friend HOST_DEVICE_INLINE bool operator==(const Dummy_Projective& p1, const Dummy_Projective& p2) {
|
||||
return (p1.x == p2.x);
|
||||
}
|
||||
|
||||
static HOST_DEVICE_INLINE bool is_zero(const Dummy_Projective &point) {
|
||||
return point.x == 0;
|
||||
}
|
||||
|
||||
static HOST_INLINE Dummy_Projective rand_host() {
|
||||
return {(unsigned)rand()};
|
||||
}
|
||||
};
|
||||
|
||||
//switch between dummy and real:
|
||||
|
||||
typedef scalar_t test_scalar;
|
||||
typedef projective_t test_projective;
|
||||
@@ -121,100 +187,63 @@ typedef affine_t test_affine;
|
||||
|
||||
int main()
|
||||
{
|
||||
unsigned batch_size = 1;
|
||||
// unsigned msm_size = 1<<21;
|
||||
unsigned msm_size = 12180757;
|
||||
unsigned N = batch_size * msm_size;
|
||||
unsigned batch_size = 4;
|
||||
unsigned msm_size = 1<<15;
|
||||
unsigned N = batch_size*msm_size;
|
||||
|
||||
test_scalar* scalars = new test_scalar[N];
|
||||
test_affine* points = new test_affine[N];
|
||||
|
||||
for (unsigned i = 0; i < N; i++) {
|
||||
// scalars[i] = (i%msm_size < 10)? test_scalar::rand_host() : scalars[i-10];
|
||||
points[i] = (i % msm_size < 10) ? test_projective::to_affine(test_projective::rand_host()) : points[i - 10];
|
||||
scalars[i] = test_scalar::rand_host();
|
||||
// scalars[i] = i < N/2? test_scalar::rand_host() : test_scalar::one();
|
||||
test_scalar *scalars = new test_scalar[N];
|
||||
test_affine *points = new test_affine[N];
|
||||
|
||||
for (unsigned i=0;i<N;i++){
|
||||
scalars[i] = (i%msm_size < 10)? test_scalar::rand_host() : scalars[i-10];
|
||||
points[i] = (i%msm_size < 10)? test_projective::to_affine(test_projective::rand_host()): points[i-10];
|
||||
// scalars[i] = test_scalar::rand_host();
|
||||
// points[i] = test_projective::to_affine(test_projective::rand_host());
|
||||
}
|
||||
std::cout << "finished generating" << std::endl;
|
||||
std::cout<<"finished generating"<<std::endl;
|
||||
|
||||
// projective_t *short_res = (projective_t*)malloc(sizeof(projective_t));
|
||||
// test_projective *large_res = (test_projective*)malloc(sizeof(test_projective));
|
||||
test_projective large_res[batch_size * 2];
|
||||
// test_projective batched_large_res[batch_size];
|
||||
test_projective large_res[batch_size];
|
||||
test_projective batched_large_res[batch_size];
|
||||
// fake_point *large_res = (fake_point*)malloc(sizeof(fake_point));
|
||||
// fake_point batched_large_res[256];
|
||||
|
||||
|
||||
// short_msm<scalar_t, projective_t, affine_t>(scalars, points, N, short_res);
|
||||
// for (unsigned i=0;i<batch_size;i++){
|
||||
// large_msm<test_scalar, test_projective, test_affine>(scalars+msm_size*i, points+msm_size*i, msm_size, large_res+i,
|
||||
// false); std::cout<<"final result large"<<std::endl; std::cout<<test_projective::to_affine(*large_res)<<std::endl;
|
||||
// }
|
||||
|
||||
test_scalar* scalars_d;
|
||||
test_affine* points_d;
|
||||
test_projective* large_res_d;
|
||||
|
||||
cudaMalloc(&scalars_d, sizeof(test_scalar) * msm_size);
|
||||
cudaMalloc(&points_d, sizeof(test_affine) * msm_size);
|
||||
cudaMalloc(&large_res_d, sizeof(test_projective));
|
||||
cudaMemcpy(scalars_d, scalars, sizeof(test_scalar) * msm_size, cudaMemcpyHostToDevice);
|
||||
cudaMemcpy(points_d, points, sizeof(test_affine) * msm_size, cudaMemcpyHostToDevice);
|
||||
|
||||
std::cout << "finished copying" << std::endl;
|
||||
|
||||
// batched_large_msm<test_scalar, test_projective, test_affine>(scalars, points, batch_size, msm_size,
|
||||
// batched_large_res, false);
|
||||
cudaStream_t stream1;
|
||||
cudaStream_t stream2;
|
||||
cudaStreamCreate(&stream1);
|
||||
cudaStreamCreate(&stream2);
|
||||
auto begin1 = std::chrono::high_resolution_clock::now();
|
||||
large_msm<test_scalar, test_projective, test_affine>(scalars, points, msm_size, large_res, false, true, stream1);
|
||||
auto end1 = std::chrono::high_resolution_clock::now();
|
||||
auto elapsed1 = std::chrono::duration_cast<std::chrono::nanoseconds>(end1 - begin1);
|
||||
printf("Big Triangle : %.3f seconds.\n", elapsed1.count() * 1e-9);
|
||||
// std::cout<<test_projective::to_affine(large_res[0])<<std::endl;
|
||||
for (unsigned i=0;i<batch_size;i++){
|
||||
large_msm<test_scalar, test_projective, test_affine>(scalars+msm_size*i, points+msm_size*i, msm_size, large_res+i, false);
|
||||
// std::cout<<"final result large"<<std::endl;
|
||||
// std::cout<<test_projective::to_affine(*large_res)<<std::endl;
|
||||
}
|
||||
auto begin = std::chrono::high_resolution_clock::now();
|
||||
large_msm<test_scalar, test_projective, test_affine>(
|
||||
scalars_d, points_d, msm_size, large_res_d, true, false, stream2);
|
||||
// test_reduce_triangle(scalars);
|
||||
// test_reduce_rectangle(scalars);
|
||||
// test_reduce_single(scalars);
|
||||
// test_reduce_var(scalars);
|
||||
batched_large_msm<test_scalar, test_projective, test_affine>(scalars, points, batch_size, msm_size, batched_large_res, false);
|
||||
// large_msm<test_scalar, test_projective, test_affine>(scalars, points, msm_size, large_res, false);
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);
|
||||
printf("On Device No Big Triangle: %.3f seconds.\n", elapsed.count() * 1e-9);
|
||||
cudaStreamSynchronize(stream1);
|
||||
cudaStreamSynchronize(stream2);
|
||||
cudaStreamDestroy(stream1);
|
||||
cudaStreamDestroy(stream2);
|
||||
printf("Time measured: %.3f seconds.\n", elapsed.count() * 1e-9);
|
||||
std::cout<<test_projective::to_affine(large_res[0])<<std::endl;
|
||||
|
||||
std::cout << test_projective::to_affine(large_res[0]) << std::endl;
|
||||
|
||||
cudaMemcpy(&large_res[1], large_res_d, sizeof(test_projective), cudaMemcpyDeviceToHost);
|
||||
std::cout << test_projective::to_affine(large_res[1]) << std::endl;
|
||||
|
||||
// reference_msm<test_affine, test_scalar, test_projective>(scalars, points, msm_size);
|
||||
|
||||
// std::cout<<"final results batched large"<<std::endl;
|
||||
// bool success = true;
|
||||
// for (unsigned i = 0; i < batch_size; i++)
|
||||
// {
|
||||
// std::cout<<test_projective::to_affine(batched_large_res[i])<<std::endl;
|
||||
// if (test_projective::to_affine(large_res[i])==test_projective::to_affine(batched_large_res[i])){
|
||||
// std::cout<<"good"<<std::endl;
|
||||
// }
|
||||
// else{
|
||||
// std::cout<<"miss"<<std::endl;
|
||||
// std::cout<<test_projective::to_affine(large_res[i])<<std::endl;
|
||||
// success = false;
|
||||
// }
|
||||
// }
|
||||
// if (success){
|
||||
// std::cout<<"success!"<<std::endl;
|
||||
// }
|
||||
// reference_msm<test_affine, test_scalar, test_projective>(scalars, points, msm_size);
|
||||
|
||||
std::cout<<"final results batched large"<<std::endl;
|
||||
bool success = true;
|
||||
for (unsigned i = 0; i < batch_size; i++)
|
||||
{
|
||||
std::cout<<test_projective::to_affine(batched_large_res[i])<<std::endl;
|
||||
if (test_projective::to_affine(large_res[i])==test_projective::to_affine(batched_large_res[i])){
|
||||
std::cout<<"good"<<std::endl;
|
||||
}
|
||||
else{
|
||||
std::cout<<"miss"<<std::endl;
|
||||
std::cout<<test_projective::to_affine(large_res[i])<<std::endl;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
if (success){
|
||||
std::cout<<"success!"<<std::endl;
|
||||
}
|
||||
|
||||
// std::cout<<batched_large_res[0]<<std::endl;
|
||||
// std::cout<<batched_large_res[1]<<std::endl;
|
||||
// std::cout<<projective_t::to_affine(batched_large_res[0])<<std::endl;
|
||||
|
||||
@@ -1,279 +1,182 @@
|
||||
#ifndef LDE
|
||||
#define LDE
|
||||
#include "../vector_manipulation/ve_mod_mult.cuh"
|
||||
#include "lde.cuh"
|
||||
#include "ntt.cuh"
|
||||
#include <cuda.h>
|
||||
#include "ntt.cuh"
|
||||
#include "lde.cuh"
|
||||
#include "../vector_manipulation/ve_mod_mult.cuh"
|
||||
|
||||
template <typename E, bool SUB>
|
||||
__global__ void add_sub_array(E* res, E* in1, E* in2, uint32_t n)
|
||||
{
|
||||
int tid = (blockIdx.x * blockDim.x) + threadIdx.x;
|
||||
if (tid < n) { res[tid] = SUB ? in1[tid] - in2[tid] : in1[tid] + in2[tid]; }
|
||||
}
|
||||
|
||||
template <typename E>
|
||||
int sub_polys(E* d_out, E* d_in1, E* d_in2, unsigned n, cudaStream_t stream)
|
||||
{
|
||||
uint32_t NUM_THREADS = MAX_THREADS_BATCH;
|
||||
uint32_t NUM_BLOCKS = (n + NUM_THREADS - 1) / NUM_THREADS;
|
||||
|
||||
add_sub_array<E, true><<<NUM_BLOCKS, NUM_THREADS, 0, stream>>>(d_out, d_in1, d_in2, n);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename E>
|
||||
int add_polys(E* d_out, E* d_in1, E* d_in2, unsigned n, cudaStream_t stream)
|
||||
{
|
||||
uint32_t NUM_THREADS = MAX_THREADS_BATCH;
|
||||
uint32_t NUM_BLOCKS = (n + NUM_THREADS - 1) / NUM_THREADS;
|
||||
|
||||
add_sub_array<E, false><<<NUM_BLOCKS, NUM_THREADS, 0, stream>>>(d_out, d_in1, d_in2, n);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpolate a batch of polynomials from their evaluations on the same subgroup.
|
||||
* Note: this function does not preform any bit-reverse permutations on its inputs or outputs.
|
||||
* @param d_out The variable to write coefficients of the resulting polynomials into (the coefficients are in
|
||||
* bit-reversed order if the evaluations weren't bit-reversed and vice-versa).
|
||||
* @param d_out The variable to write coefficients of the resulting polynomials into (the coefficients are in bit-reversed order if the evaluations weren't bit-reversed and vice-versa).
|
||||
* @param d_evaluations Input array of evaluations of all polynomials of type E (elements).
|
||||
* @param d_domain Domain on which the polynomials are evaluated. Must be a subgroup.
|
||||
* @param n Length of `d_domain` array, also equal to the number of evaluations of each polynomial.
|
||||
* @param batch_size The size of the batch; the length of `d_evaluations` is `n` * `batch_size`.
|
||||
*/
|
||||
template <typename E, typename S>
|
||||
int interpolate_batch(
|
||||
E* d_out,
|
||||
E* d_evaluations,
|
||||
S* d_domain,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
bool coset,
|
||||
S* coset_powers,
|
||||
cudaStream_t stream)
|
||||
{
|
||||
cudaMemcpyAsync(d_out, d_evaluations, sizeof(E) * n * batch_size, cudaMemcpyDeviceToDevice, stream);
|
||||
ntt_inplace_batch_template(d_out, d_domain, n, batch_size, true, coset, coset_powers, stream, true);
|
||||
template <typename E, typename S> int interpolate_batch(E * d_out, E * d_evaluations, S * d_domain, unsigned n, unsigned batch_size) {
|
||||
uint32_t logn = uint32_t(log(n) / log(2));
|
||||
cudaMemcpy(d_out, d_evaluations, sizeof(E) * n * batch_size, cudaMemcpyDeviceToDevice);
|
||||
|
||||
int NUM_THREADS = min(n / 2, MAX_THREADS_BATCH);
|
||||
int NUM_BLOCKS = batch_size * max(int((n / 2) / NUM_THREADS), 1);
|
||||
for (uint32_t s = 0; s < logn; s++) //TODO: this loop also can be unrolled
|
||||
{
|
||||
ntt_template_kernel <E, S> <<<NUM_BLOCKS, NUM_THREADS>>>(d_out, n, d_domain, n, NUM_BLOCKS, s, false);
|
||||
}
|
||||
|
||||
NUM_BLOCKS = (n * batch_size + NUM_THREADS - 1) / NUM_THREADS;
|
||||
template_normalize_kernel <E, S> <<<NUM_BLOCKS, NUM_THREADS>>> (d_out, n * batch_size, S::inv_log_size(logn));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpolate a polynomial from its evaluations on a subgroup.
|
||||
* Note: this function does not preform any bit-reverse permutations on its inputs or outputs.
|
||||
* @param d_out The variable to write coefficients of the resulting polynomial into (the coefficients are in
|
||||
* bit-reversed order if the evaluations weren't bit-reversed and vice-versa).
|
||||
* @param d_out The variable to write coefficients of the resulting polynomial into (the coefficients are in bit-reversed order if the evaluations weren't bit-reversed and vice-versa).
|
||||
* @param d_evaluations Input array of evaluations that have type E (elements).
|
||||
* @param d_domain Domain on which the polynomial is evaluated. Must be a subgroup.
|
||||
* @param n Length of `d_evaluations` and the size `d_domain` arrays (they should have equal length).
|
||||
*/
|
||||
template <typename E, typename S>
|
||||
int interpolate(E* d_out, E* d_evaluations, S* d_domain, unsigned n, bool coset, S* coset_powers, cudaStream_t stream)
|
||||
{
|
||||
return interpolate_batch<E, S>(d_out, d_evaluations, d_domain, n, 1, coset, coset_powers, stream);
|
||||
template <typename E, typename S> int interpolate(E * d_out, E * d_evaluations, S * d_domain, unsigned n) {
|
||||
return interpolate_batch <E, S> (d_out, d_evaluations, d_domain, n, 1);
|
||||
}
|
||||
|
||||
template <typename E>
|
||||
__global__ void fill_array(E* arr, E val, uint32_t n)
|
||||
{
|
||||
template < typename E > __global__ void fill_array(E * arr, E val, uint32_t n) {
|
||||
int tid = (blockIdx.x * blockDim.x) + threadIdx.x;
|
||||
if (tid < n) { arr[tid] = val; }
|
||||
if (tid < n) {
|
||||
arr[tid] = val;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate a batch of polynomials on the same coset.
|
||||
* @param d_out The evaluations of the polynomials on coset `u` * `d_domain`.
|
||||
* @param d_coefficients Input array of coefficients of all polynomials of type E (elements) to be evaluated in-place on
|
||||
* a coset.
|
||||
* @param d_coefficients Input array of coefficients of all polynomials of type E (elements) to be evaluated in-place on a coset.
|
||||
* @param d_domain Domain on which the polynomials are evaluated (see `coset` flag). Must be a subgroup.
|
||||
* @param domain_size Length of `d_domain` array, on which the polynomial is computed.
|
||||
* @param n The number of coefficients, which might be different from `domain_size`.
|
||||
* @param batch_size The size of the batch; the length of `d_coefficients` is `n` * `batch_size`.
|
||||
* @param coset The flag that indicates whether to evaluate on a coset. If false, evaluate on a subgroup `d_domain`.
|
||||
* @param coset_powers If `coset` is true, a list of powers `[1, u, u^2, ..., u^{n-1}]` where `u` is the generator of
|
||||
* the coset.
|
||||
* @param coset_powers If `coset` is true, a list of powers `[1, u, u^2, ..., u^{n-1}]` where `u` is the generator of the coset.
|
||||
*/
|
||||
template <typename E, typename S>
|
||||
int evaluate_batch(
|
||||
E* d_out,
|
||||
E* d_coefficients,
|
||||
S* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
bool coset,
|
||||
S* coset_powers,
|
||||
cudaStream_t stream)
|
||||
{
|
||||
int evaluate_batch(E * d_out, E * d_coefficients, S * d_domain, unsigned domain_size, unsigned n, unsigned batch_size, bool coset, S * coset_powers) {
|
||||
uint32_t logn = uint32_t(log(domain_size) / log(2));
|
||||
if (domain_size > n) {
|
||||
// allocate and initialize an array of stream handles to parallelize data copying across batches
|
||||
cudaStream_t* memcpy_streams = (cudaStream_t*)malloc(batch_size * sizeof(cudaStream_t));
|
||||
for (unsigned i = 0; i < batch_size; i++) {
|
||||
cudaStream_t *memcpy_streams = (cudaStream_t *) malloc(batch_size * sizeof(cudaStream_t));
|
||||
for (unsigned i = 0; i < batch_size; i++)
|
||||
{
|
||||
cudaStreamCreate(&(memcpy_streams[i]));
|
||||
|
||||
cudaMemcpyAsync(
|
||||
&d_out[i * domain_size], &d_coefficients[i * n], n * sizeof(E), cudaMemcpyDeviceToDevice, memcpy_streams[i]);
|
||||
cudaMemcpyAsync(&d_out[i * domain_size], &d_coefficients[i * n], n * sizeof(E), cudaMemcpyDeviceToDevice, memcpy_streams[i]);
|
||||
uint32_t NUM_THREADS = MAX_THREADS_BATCH;
|
||||
uint32_t NUM_BLOCKS = (domain_size - n + NUM_THREADS - 1) / NUM_THREADS;
|
||||
fill_array<E>
|
||||
<<<NUM_BLOCKS, NUM_THREADS, 0, memcpy_streams[i]>>>(&d_out[i * domain_size + n], E::zero(), domain_size - n);
|
||||
fill_array <E> <<<NUM_BLOCKS, NUM_THREADS, 0, memcpy_streams[i]>>> (&d_out[i * domain_size + n], E::zero(), domain_size - n);
|
||||
|
||||
cudaStreamSynchronize(memcpy_streams[i]);
|
||||
cudaStreamDestroy(memcpy_streams[i]);
|
||||
}
|
||||
} else
|
||||
cudaMemcpyAsync(d_out, d_coefficients, sizeof(E) * domain_size * batch_size, cudaMemcpyDeviceToDevice, stream);
|
||||
cudaMemcpy(d_out, d_coefficients, sizeof(E) * domain_size * batch_size, cudaMemcpyDeviceToDevice);
|
||||
|
||||
if (coset) batch_vector_mult(coset_powers, d_out, domain_size, batch_size, stream);
|
||||
if (coset)
|
||||
batch_vector_mult(coset_powers, d_out, domain_size, batch_size);
|
||||
|
||||
S* _null = nullptr;
|
||||
ntt_inplace_batch_template(d_out, d_domain, domain_size, batch_size, false, false, _null, stream, true);
|
||||
int NUM_THREADS = min(domain_size / 2, MAX_THREADS_BATCH);
|
||||
int chunks = max(int((domain_size / 2) / NUM_THREADS), 1);
|
||||
int NUM_BLOCKS = batch_size * chunks;
|
||||
for (uint32_t s = 0; s < logn; s++) //TODO: this loop also can be unrolled
|
||||
{
|
||||
ntt_template_kernel <E, S> <<<NUM_BLOCKS, NUM_THREADS>>>(d_out, domain_size, d_domain, domain_size, batch_size * chunks, logn - s - 1, true);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate a polynomial on a coset.
|
||||
* Note: this function does not preform any bit-reverse permutations on its inputs or outputs, so the order of outputs
|
||||
* is bit-reversed.
|
||||
* Note: this function does not preform any bit-reverse permutations on its inputs or outputs, so the order of outputs is bit-reversed.
|
||||
* @param d_out The evaluations of the polynomial on coset `u` * `d_domain`.
|
||||
* @param d_coefficients Input array of coefficients of a polynomial of type E (elements).
|
||||
* @param d_domain Domain on which the polynomial is evaluated (see `coset` flag). Must be a subgroup.
|
||||
* @param domain_size Length of `d_domain` array, on which the polynomial is computed.
|
||||
* @param n The number of coefficients, which might be different from `domain_size`.
|
||||
* @param coset The flag that indicates whether to evaluate on a coset. If false, evaluate on a subgroup `d_domain`.
|
||||
* @param coset_powers If `coset` is true, a list of powers `[1, u, u^2, ..., u^{n-1}]` where `u` is the generator of
|
||||
* the coset.
|
||||
* @param coset_powers If `coset` is true, a list of powers `[1, u, u^2, ..., u^{n-1}]` where `u` is the generator of the coset.
|
||||
*/
|
||||
template <typename E, typename S>
|
||||
int evaluate(
|
||||
E* d_out,
|
||||
E* d_coefficients,
|
||||
S* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
bool coset,
|
||||
S* coset_powers,
|
||||
cudaStream_t stream)
|
||||
{
|
||||
return evaluate_batch<E, S>(d_out, d_coefficients, d_domain, domain_size, n, 1, coset, coset_powers, stream);
|
||||
template <typename E, typename S>
|
||||
int evaluate(E * d_out, E * d_coefficients, S * d_domain, unsigned domain_size, unsigned n, bool coset, S * coset_powers) {
|
||||
return evaluate_batch <E, S> (d_out, d_coefficients, d_domain, domain_size, n, 1, coset, coset_powers);
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
int interpolate_scalars(S* d_out, S* d_evaluations, S* d_domain, unsigned n, cudaStream_t stream)
|
||||
{
|
||||
template <typename S>
|
||||
int interpolate_scalars(S* d_out, S* d_evaluations, S* d_domain, unsigned n) {
|
||||
return interpolate(d_out, d_evaluations, d_domain, n);
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
int interpolate_scalars_batch(S* d_out, S* d_evaluations, S* d_domain, unsigned n, unsigned batch_size) {
|
||||
return interpolate_batch(d_out, d_evaluations, d_domain, n, batch_size);
|
||||
}
|
||||
|
||||
template <typename E, typename S>
|
||||
int interpolate_points(E* d_out, E* d_evaluations, S* d_domain, unsigned n) {
|
||||
return interpolate(d_out, d_evaluations, d_domain, n);
|
||||
}
|
||||
|
||||
template <typename E, typename S>
|
||||
int interpolate_points_batch(E* d_out, E* d_evaluations, S* d_domain, unsigned n, unsigned batch_size) {
|
||||
return interpolate_batch(d_out, d_evaluations, d_domain, n, batch_size);
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
int evaluate_scalars(S* d_out, S* d_coefficients, S* d_domain, unsigned domain_size, unsigned n) {
|
||||
S* _null = nullptr;
|
||||
return interpolate(d_out, d_evaluations, d_domain, n, false, _null, stream);
|
||||
return evaluate(d_out, d_coefficients, d_domain, domain_size, n, false, _null);
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
int interpolate_scalars_batch(
|
||||
S* d_out, S* d_evaluations, S* d_domain, unsigned n, unsigned batch_size, cudaStream_t stream)
|
||||
{
|
||||
template <typename S>
|
||||
int evaluate_scalars_batch(S* d_out, S* d_coefficients, S* d_domain, unsigned domain_size, unsigned n, unsigned batch_size) {
|
||||
S* _null = nullptr;
|
||||
return interpolate_batch(d_out, d_evaluations, d_domain, n, batch_size, false, _null, stream);
|
||||
return evaluate_batch(d_out, d_coefficients, d_domain, domain_size, n, batch_size, false, _null);
|
||||
}
|
||||
|
||||
template <typename E, typename S>
|
||||
int interpolate_points(E* d_out, E* d_evaluations, S* d_domain, unsigned n, cudaStream_t stream)
|
||||
{
|
||||
template <typename E, typename S>
|
||||
int evaluate_points(E* d_out, E* d_coefficients, S* d_domain, unsigned domain_size, unsigned n) {
|
||||
S* _null = nullptr;
|
||||
return interpolate(d_out, d_evaluations, d_domain, n, false, _null, stream);
|
||||
return evaluate(d_out, d_coefficients, d_domain, domain_size, n, false, _null);
|
||||
}
|
||||
|
||||
template <typename E, typename S>
|
||||
int interpolate_points_batch(
|
||||
E* d_out, E* d_evaluations, S* d_domain, unsigned n, unsigned batch_size, cudaStream_t stream)
|
||||
{
|
||||
template <typename E, typename S>
|
||||
int evaluate_points_batch(E* d_out, E* d_coefficients, S* d_domain,
|
||||
unsigned domain_size, unsigned n, unsigned batch_size) {
|
||||
S* _null = nullptr;
|
||||
return interpolate_batch(d_out, d_evaluations, d_domain, n, batch_size, false, _null, stream);
|
||||
return evaluate_batch(d_out, d_coefficients, d_domain, domain_size, n, batch_size, false, _null);
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
int evaluate_scalars(S* d_out, S* d_coefficients, S* d_domain, unsigned domain_size, unsigned n, cudaStream_t stream)
|
||||
{
|
||||
S* _null = nullptr;
|
||||
return evaluate(d_out, d_coefficients, d_domain, domain_size, n, false, _null, stream);
|
||||
template <typename S>
|
||||
int evaluate_scalars_on_coset(S* d_out, S* d_coefficients, S* d_domain,
|
||||
unsigned domain_size, unsigned n, S* coset_powers) {
|
||||
return evaluate(d_out, d_coefficients, d_domain, domain_size, n, true, coset_powers);
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
int evaluate_scalars_batch(
|
||||
S* d_out, S* d_coefficients, S* d_domain, unsigned domain_size, unsigned n, unsigned batch_size, cudaStream_t stream)
|
||||
{
|
||||
S* _null = nullptr;
|
||||
return evaluate_batch(d_out, d_coefficients, d_domain, domain_size, n, batch_size, false, _null, stream);
|
||||
template <typename E, typename S>
|
||||
int evaluate_scalars_on_coset_batch(S* d_out, S* d_coefficients, S* d_domain, unsigned domain_size,
|
||||
unsigned n, unsigned batch_size, S* coset_powers) {
|
||||
return evaluate_batch(d_out, d_coefficients, d_domain, domain_size, n, batch_size, true, coset_powers);
|
||||
}
|
||||
|
||||
template <typename E, typename S>
|
||||
int evaluate_points(E* d_out, E* d_coefficients, S* d_domain, unsigned domain_size, unsigned n, cudaStream_t stream)
|
||||
{
|
||||
S* _null = nullptr;
|
||||
return evaluate(d_out, d_coefficients, d_domain, domain_size, n, false, _null, stream);
|
||||
template <typename E, typename S>
|
||||
int evaluate_points_on_coset(E* d_out, E* d_coefficients, S* d_domain,
|
||||
unsigned domain_size, unsigned n, S* coset_powers) {
|
||||
return evaluate(d_out, d_coefficients, d_domain, domain_size, n, true, coset_powers);
|
||||
}
|
||||
|
||||
template <typename E, typename S>
|
||||
int evaluate_points_batch(
|
||||
E* d_out, E* d_coefficients, S* d_domain, unsigned domain_size, unsigned n, unsigned batch_size, cudaStream_t stream)
|
||||
{
|
||||
S* _null = nullptr;
|
||||
return evaluate_batch(d_out, d_coefficients, d_domain, domain_size, n, batch_size, false, _null, stream);
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
int interpolate_scalars_on_coset(
|
||||
S* d_out, S* d_evaluations, S* d_domain, unsigned n, S* coset_powers, cudaStream_t stream)
|
||||
{
|
||||
return interpolate(d_out, d_evaluations, d_domain, n, true, coset_powers, stream);
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
int interpolate_scalars_on_coset_batch(
|
||||
S* d_out, S* d_evaluations, S* d_domain, unsigned n, unsigned batch_size, S* coset_powers, cudaStream_t stream)
|
||||
{
|
||||
return interpolate_batch(d_out, d_evaluations, d_domain, n, batch_size, true, coset_powers, stream);
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
int evaluate_scalars_on_coset(
|
||||
S* d_out, S* d_coefficients, S* d_domain, unsigned domain_size, unsigned n, S* coset_powers, cudaStream_t stream)
|
||||
{
|
||||
return evaluate(d_out, d_coefficients, d_domain, domain_size, n, true, coset_powers, stream);
|
||||
}
|
||||
|
||||
template <typename E, typename S>
|
||||
int evaluate_scalars_on_coset_batch(
|
||||
S* d_out,
|
||||
S* d_coefficients,
|
||||
S* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
S* coset_powers,
|
||||
cudaStream_t stream)
|
||||
{
|
||||
return evaluate_batch(d_out, d_coefficients, d_domain, domain_size, n, batch_size, true, coset_powers, stream);
|
||||
}
|
||||
|
||||
template <typename E, typename S>
|
||||
int evaluate_points_on_coset(
|
||||
E* d_out, E* d_coefficients, S* d_domain, unsigned domain_size, unsigned n, S* coset_powers, cudaStream_t stream)
|
||||
{
|
||||
return evaluate(d_out, d_coefficients, d_domain, domain_size, n, true, coset_powers, stream);
|
||||
}
|
||||
|
||||
template <typename E, typename S>
|
||||
int evaluate_points_on_coset_batch(
|
||||
E* d_out,
|
||||
E* d_coefficients,
|
||||
S* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
S* coset_powers,
|
||||
cudaStream_t stream)
|
||||
{
|
||||
return evaluate_batch(d_out, d_coefficients, d_domain, domain_size, n, batch_size, true, coset_powers, stream);
|
||||
template <typename E, typename S>
|
||||
int evaluate_points_on_coset_batch(E* d_out, E* d_coefficients, S* d_domain, unsigned domain_size,
|
||||
unsigned n, unsigned batch_size, S* coset_powers) {
|
||||
return evaluate_batch(d_out, d_coefficients, d_domain, domain_size, n, batch_size, true, coset_powers);
|
||||
}
|
||||
#endif
|
||||
@@ -2,62 +2,45 @@
|
||||
#define LDE_H
|
||||
#pragma once
|
||||
|
||||
template <typename S>
|
||||
int interpolate_scalars(S* d_out, S* d_evaluations, S* d_domain, unsigned n, cudaStream_t stream);
|
||||
template <typename S>
|
||||
int interpolate_scalars(S* d_out, S* d_evaluations, S* d_domain, unsigned n);
|
||||
|
||||
template <typename S>
|
||||
int interpolate_scalars_batch(
|
||||
S* d_out, S* d_evaluations, S* d_domain, unsigned n, unsigned batch_size, cudaStream_t stream);
|
||||
template <typename S>
|
||||
int interpolate_scalars_batch(S* d_out, S* d_evaluations, S* d_domain, unsigned n, unsigned batch_size);
|
||||
|
||||
template <typename E, typename S>
|
||||
int interpolate_points(E* d_out, E* d_evaluations, S* d_domain, unsigned n, cudaStream_t stream);
|
||||
template <typename E, typename S>
|
||||
int interpolate_points(E* d_out, E* d_evaluations, S* d_domain, unsigned n);
|
||||
|
||||
template <typename E, typename S>
|
||||
int interpolate_points_batch(
|
||||
E* d_out, E* d_evaluations, S* d_domain, unsigned n, unsigned batch_size, cudaStream_t stream);
|
||||
template <typename E, typename S>
|
||||
int interpolate_points_batch(E* d_out, E* d_evaluations, S* d_domain, unsigned n, unsigned batch_size);
|
||||
|
||||
template <typename S>
|
||||
int evaluate_scalars(S* d_out, S* d_coefficients, S* d_domain, unsigned domain_size, unsigned n, cudaStream_t stream);
|
||||
template <typename S>
|
||||
int evaluate_scalars(S* d_out, S* d_coefficients, S* d_domain, unsigned domain_size, unsigned n);
|
||||
|
||||
template <typename S>
|
||||
int evaluate_scalars_batch(
|
||||
S* d_out, S* d_coefficients, S* d_domain, unsigned domain_size, unsigned n, unsigned batch_size, cudaStream_t stream);
|
||||
template <typename S>
|
||||
int evaluate_scalars_batch(S* d_out, S* d_coefficients, S* d_domain, unsigned domain_size, unsigned n, unsigned batch_size);
|
||||
|
||||
template <typename E, typename S>
|
||||
int evaluate_points(E* d_out, E* d_coefficients, S* d_domain, unsigned domain_size, unsigned n, cudaStream_t stream);
|
||||
template <typename E, typename S>
|
||||
int evaluate_points(E* d_out, E* d_coefficients, S* d_domain, unsigned domain_size, unsigned n);
|
||||
|
||||
template <typename E, typename S>
|
||||
int evaluate_points_batch(
|
||||
E* d_out, E* d_coefficients, S* d_domain, unsigned domain_size, unsigned n, unsigned batch_size, cudaStream_t stream);
|
||||
template <typename E, typename S>
|
||||
int evaluate_points_batch(E* d_out, E* d_coefficients, S* d_domain,
|
||||
unsigned domain_size, unsigned n, unsigned batch_size);
|
||||
|
||||
template <typename S>
|
||||
int evaluate_scalars_on_coset(
|
||||
S* d_out, S* d_coefficients, S* d_domain, unsigned domain_size, unsigned n, S* coset_powers, cudaStream_t stream);
|
||||
template <typename S>
|
||||
int evaluate_scalars_on_coset(S* d_out, S* d_coefficients, S* d_domain,
|
||||
unsigned domain_size, unsigned n, S* coset_powers);
|
||||
|
||||
template <typename S>
|
||||
int evaluate_scalars_on_coset_batch(
|
||||
S* d_out,
|
||||
S* d_coefficients,
|
||||
S* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
S* coset_powers,
|
||||
cudaStream_t stream);
|
||||
template <typename S>
|
||||
int evaluate_scalars_on_coset_batch(S* d_out, S* d_coefficients, S* d_domain, unsigned domain_size,
|
||||
unsigned n, unsigned batch_size, S* coset_powers);
|
||||
|
||||
template <typename E, typename S>
|
||||
int evaluate_points_on_coset(
|
||||
E* d_out, E* d_coefficients, S* d_domain, unsigned domain_size, unsigned n, S* coset_powers, cudaStream_t stream);
|
||||
template <typename E, typename S>
|
||||
int evaluate_points_on_coset(E* d_out, E* d_coefficients, S* d_domain,
|
||||
unsigned domain_size, unsigned n, S* coset_powers);
|
||||
|
||||
template <typename E, typename S>
|
||||
int evaluate_points_on_coset_batch(
|
||||
E* d_out,
|
||||
E* d_coefficients,
|
||||
S* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
S* coset_powers,
|
||||
cudaStream_t stream);
|
||||
template <typename E, typename S>
|
||||
int evaluate_points_on_coset_batch(E* d_out, E* d_coefficients, S* d_domain, unsigned domain_size,
|
||||
unsigned n, unsigned batch_size, S* coset_powers);
|
||||
|
||||
#endif
|
||||
@@ -2,13 +2,8 @@
|
||||
#define NTT
|
||||
#pragma once
|
||||
|
||||
#include "../../utils/sharedmem.cuh"
|
||||
#include "../vector_manipulation/ve_mod_mult.cuh"
|
||||
|
||||
const uint32_t MAX_NUM_THREADS = 1024;
|
||||
const uint32_t MAX_THREADS_BATCH = 512; //TODO: allows 100% occupancy for scalar NTT for sm_86..sm_89
|
||||
const uint32_t MAX_SHARED_MEM_ELEMENT_SIZE = 32; //TODO: occupancy calculator, hardcoded for sm_86..sm_89
|
||||
const uint32_t MAX_SHARED_MEM = MAX_SHARED_MEM_ELEMENT_SIZE * 1024;
|
||||
const uint32_t MAX_THREADS_BATCH = 256;
|
||||
|
||||
/**
|
||||
* Computes the twiddle factors.
|
||||
@@ -33,15 +28,48 @@ const uint32_t MAX_SHARED_MEM = MAX_SHARED_MEM_ELEMENT_SIZE * 1024;
|
||||
* @param n_twiddles number of twiddle factors.
|
||||
* @param omega multiplying factor.
|
||||
*/
|
||||
template < typename S > S * fill_twiddle_factors_array(uint32_t n_twiddles, S omega, cudaStream_t stream) {
|
||||
template < typename S > S * fill_twiddle_factors_array(uint32_t n_twiddles, S omega) {
|
||||
size_t size_twiddles = n_twiddles * sizeof(S);
|
||||
S * d_twiddles;
|
||||
cudaMallocAsync(& d_twiddles, size_twiddles, stream);
|
||||
twiddle_factors_kernel<S> <<< 1, 1, 0, stream>>> (d_twiddles, n_twiddles, omega);
|
||||
cudaStreamSynchronize(stream);
|
||||
cudaMalloc( & d_twiddles, size_twiddles);
|
||||
twiddle_factors_kernel<S> <<< 1, 1 >>> (d_twiddles, n_twiddles, omega);
|
||||
return d_twiddles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bit reversed order of a number.
|
||||
* for example: on inputs num = 6 (110 in binary) and logn = 3
|
||||
* the function should return 3 (011 in binary.)
|
||||
* @param num some number with bit representation of size logn.
|
||||
* @param logn length of bit representation of `num`.
|
||||
* @return bit reveresed order or `num`.
|
||||
*/
|
||||
__device__ __host__ uint32_t reverseBits(uint32_t num, uint32_t logn) {
|
||||
unsigned int reverse_num = 0;
|
||||
for (uint32_t i = 0; i < logn; i++) {
|
||||
if ((num & (1 << i))) reverse_num |= 1 << ((logn - 1) - i);
|
||||
}
|
||||
return reverse_num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bit reversal ordering of the input array.
|
||||
* for example: on input ([a[0],a[1],a[2],a[3]], 4, 2) it returns
|
||||
* [a[0],a[3],a[2],a[1]] (elements in indices 3,1 swhich places).
|
||||
* @param arr array of some object of type T of size which is a power of 2.
|
||||
* @param n length of `arr`.
|
||||
* @param logn log(n).
|
||||
* @return A new array which is the bit reversed version of input array.
|
||||
*/
|
||||
template < typename T > T * template_reverse_order(T * arr, uint32_t n, uint32_t logn) {
|
||||
T * arrReversed = new T[n];
|
||||
for (uint32_t i = 0; i < n; i++) {
|
||||
uint32_t reversed = reverseBits(i, logn);
|
||||
arrReversed[i] = arr[reversed];
|
||||
}
|
||||
return arrReversed;
|
||||
}
|
||||
|
||||
template < typename T > __global__ void reverse_order_kernel(T* arr, T* arr_reversed, uint32_t n, uint32_t logn, uint32_t batch_size) {
|
||||
int threadId = (blockIdx.x * blockDim.x) + threadIdx.x;
|
||||
if (threadId < n * batch_size) {
|
||||
@@ -61,14 +89,14 @@ template < typename T > __global__ void reverse_order_kernel(T* arr, T* arr_reve
|
||||
* @param logn log(n).
|
||||
* @param batch_size the size of the batch.
|
||||
*/
|
||||
template < typename T > void reverse_order_batch(T* arr, uint32_t n, uint32_t logn, uint32_t batch_size, cudaStream_t stream) {
|
||||
template < typename T > void reverse_order_batch(T* arr, uint32_t n, uint32_t logn, uint32_t batch_size) {
|
||||
T* arr_reversed;
|
||||
cudaMallocAsync(&arr_reversed, n * batch_size * sizeof(T), stream);
|
||||
cudaMalloc(&arr_reversed, n * batch_size * sizeof(T));
|
||||
int number_of_threads = MAX_THREADS_BATCH;
|
||||
int number_of_blocks = (n * batch_size + number_of_threads - 1) / number_of_threads;
|
||||
reverse_order_kernel <<<number_of_blocks, number_of_threads, 0, stream>>> (arr, arr_reversed, n, logn, batch_size);
|
||||
cudaMemcpyAsync(arr, arr_reversed, n * batch_size * sizeof(T), cudaMemcpyDeviceToDevice, stream);
|
||||
cudaFreeAsync(arr_reversed, stream);
|
||||
reverse_order_kernel <<<number_of_blocks, number_of_threads>>> (arr, arr_reversed, n, logn, batch_size);
|
||||
cudaMemcpy(arr, arr_reversed, n * batch_size * sizeof(T), cudaMemcpyDeviceToDevice);
|
||||
cudaFree(arr_reversed);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,152 +107,159 @@ template < typename T > void reverse_order_batch(T* arr, uint32_t n, uint32_t lo
|
||||
* @param n length of `arr`.
|
||||
* @param logn log(n).
|
||||
*/
|
||||
template < typename T > void reverse_order(T* arr, uint32_t n, uint32_t logn, cudaStream_t stream) {
|
||||
reverse_order_batch(arr, n, logn, 1, stream);
|
||||
template < typename T > void reverse_order(T* arr, uint32_t n, uint32_t logn) {
|
||||
reverse_order_batch(arr, n, logn, 1);
|
||||
}
|
||||
|
||||
|
||||
enum Decimation {
|
||||
NONE = 0,
|
||||
DIF = 1,
|
||||
DIT = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* Cooley-Tuckey NTT.
|
||||
* NOTE! this function assumes that d_twiddles are located in the device memory.
|
||||
* @param arr input array of type E (elements).
|
||||
* @param n length of d_arr.
|
||||
* @param twiddles twiddle factors of type S (scalars) array allocated on the device memory (must be a power of 2).
|
||||
* @param n_twiddles length of twiddles.
|
||||
* @param max_task max count of parallel tasks.
|
||||
* @param s log2(n) loop index.
|
||||
* Cooley-Tukey butterfly kernel.
|
||||
* @param arr array of objects of type E (elements).
|
||||
* @param twiddles array of twiddle factors of type S (scalars).
|
||||
* @param n size of arr.
|
||||
* @param n_twiddles size of omegas.
|
||||
* @param m "pair distance" - indicate distance of butterflies inputs.
|
||||
* @param i Cooley-Tukey FFT stage number.
|
||||
* @param max_thread_num maximal number of threads in stage.
|
||||
*/
|
||||
template <typename E, typename S>
|
||||
__global__ void ntt_template_kernel_shared_rev(E *__restrict__ arr_g, uint32_t n, const S *__restrict__ r_twiddles, uint32_t n_twiddles, uint32_t max_task, uint32_t ss, uint32_t logn)
|
||||
{
|
||||
SharedMemory<E> smem;
|
||||
E *arr = smem.getPointer();
|
||||
|
||||
uint32_t task = blockIdx.x;
|
||||
uint32_t loop_limit = blockDim.x;
|
||||
uint32_t chunks = n / (loop_limit * 2);
|
||||
uint32_t offset = (task / chunks) * n;
|
||||
if (task < max_task)
|
||||
{
|
||||
// flattened loop allows parallel processing
|
||||
uint32_t l = threadIdx.x;
|
||||
|
||||
if (l < loop_limit)
|
||||
{
|
||||
#pragma unroll
|
||||
for (; ss < logn; ss++)
|
||||
{
|
||||
int s = logn - ss - 1;
|
||||
bool is_beginning = ss == 0;
|
||||
bool is_end = ss == (logn - 1);
|
||||
|
||||
uint32_t ntw_i = task % chunks;
|
||||
|
||||
uint32_t n_twiddles_div = n_twiddles >> (s + 1);
|
||||
|
||||
uint32_t shift_s = 1 << s;
|
||||
uint32_t shift2_s = 1 << (s + 1);
|
||||
|
||||
l = ntw_i * loop_limit + l; // to l from chunks to full
|
||||
|
||||
uint32_t j = l & (shift_s - 1); // Equivalent to: l % (1 << s)
|
||||
uint32_t i = ((l >> s) * shift2_s) & (n - 1); // (..) % n (assuming n is power of 2)
|
||||
uint32_t oij = i + j;
|
||||
uint32_t k = oij + shift_s;
|
||||
|
||||
S tw = r_twiddles[j * n_twiddles_div];
|
||||
|
||||
E u = is_beginning ? arr_g[offset + oij] : arr[oij];
|
||||
E v = is_beginning ? arr_g[offset + k] : arr[k];
|
||||
if (is_end)
|
||||
{
|
||||
arr_g[offset + oij] = u + v;
|
||||
arr_g[offset + k] = tw * (u - v);
|
||||
}
|
||||
else
|
||||
{
|
||||
arr[oij] = u + v;
|
||||
arr[k] = tw *(u - v);
|
||||
}
|
||||
|
||||
__syncthreads();
|
||||
}
|
||||
}
|
||||
template < typename E, typename S > __global__ void template_butterfly_kernel(E * arr, S * twiddles, uint32_t n, uint32_t n_twiddles, uint32_t m, uint32_t i, uint32_t max_thread_num) {
|
||||
int j = (blockIdx.x * blockDim.x) + threadIdx.x;
|
||||
if (j < max_thread_num) {
|
||||
uint32_t g = j * (n / m);
|
||||
uint32_t k = i + j + (m >> 1);
|
||||
E u = arr[i + j];
|
||||
E v = twiddles[g * n_twiddles / n] * arr[k];
|
||||
arr[i + j] = u + v;
|
||||
arr[k] = u - v;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cooley-Tuckey NTT.
|
||||
* NOTE! this function assumes that d_twiddles are located in the device memory.
|
||||
* @param arr input array of type E (elements).
|
||||
* @param n length of d_arr.
|
||||
* @param twiddles twiddle factors of type S (scalars) array allocated on the device memory (must be a power of 2).
|
||||
* @param n_twiddles length of twiddles.
|
||||
* @param max_task max count of parallel tasks.
|
||||
* @param s log2(n) loop index.
|
||||
* Multiply the elements of an input array by a scalar in-place.
|
||||
* @param arr input array.
|
||||
* @param n size of arr.
|
||||
* @param n_inv scalar of type S (scalar).
|
||||
*/
|
||||
template <typename E, typename S>
|
||||
__global__ void ntt_template_kernel_shared(E *__restrict__ arr_g, uint32_t n, const S *__restrict__ r_twiddles, uint32_t n_twiddles, uint32_t max_task, uint32_t s, uint32_t logn)
|
||||
{
|
||||
SharedMemory<E> smem;
|
||||
E *arr = smem.getPointer();
|
||||
template < typename E, typename S > __global__ void template_normalize_kernel(E * arr, uint32_t n, S scalar) {
|
||||
int tid = (blockIdx.x * blockDim.x) + threadIdx.x;
|
||||
if (tid < n) {
|
||||
arr[tid] = scalar * arr[tid];
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t task = blockIdx.x;
|
||||
uint32_t loop_limit = blockDim.x;
|
||||
uint32_t chunks = n / (loop_limit * 2);
|
||||
uint32_t offset = (task / chunks) * n;
|
||||
if (task < max_task)
|
||||
{
|
||||
// flattened loop allows parallel processing
|
||||
uint32_t l = threadIdx.x;
|
||||
/**
|
||||
* Cooley-Tukey NTT.
|
||||
* NOTE! this function assumes that d_arr and d_twiddles are located in the device memory.
|
||||
* @param d_arr input array of type E (elements) allocated on the device memory.
|
||||
* @param n length of d_arr.
|
||||
* @param logn log(n).
|
||||
* @param d_twiddles twiddle factors of type S (scalars) array allocated on the device memory (must be a power of 2).
|
||||
* @param n_twiddles length of d_twiddles.
|
||||
*/
|
||||
template < typename E, typename S > void template_ntt_on_device_memory(E * d_arr, uint32_t n, uint32_t logn, S * d_twiddles, uint32_t n_twiddles) {
|
||||
uint32_t m = 2;
|
||||
for (uint32_t s = 0; s < logn; s++) {
|
||||
for (uint32_t i = 0; i < n; i += m) {
|
||||
uint32_t shifted_m = m >> 1;
|
||||
uint32_t number_of_threads = MAX_NUM_THREADS ^ ((shifted_m ^ MAX_NUM_THREADS) & -(shifted_m < MAX_NUM_THREADS));
|
||||
uint32_t number_of_blocks = shifted_m / MAX_NUM_THREADS + 1;
|
||||
template_butterfly_kernel < E, S > <<< number_of_threads, number_of_blocks >>> (d_arr, d_twiddles, n, n_twiddles, m, i, m >> 1);
|
||||
}
|
||||
m <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (l < loop_limit)
|
||||
{
|
||||
#pragma unroll
|
||||
for (; s < logn; s++) // TODO: this loop also can be unrolled
|
||||
{
|
||||
uint32_t ntw_i = task % chunks;
|
||||
/**
|
||||
* Cooley-Tukey NTT.
|
||||
* NOTE! this function assumes that d_twiddles are located in the device memory.
|
||||
* @param arr input array of type E (elements).
|
||||
* @param n length of d_arr.
|
||||
* @param d_twiddles twiddle factors of type S (scalars) array allocated on the device memory (must be a power of 2).
|
||||
* @param n_twiddles length of d_twiddles.
|
||||
* @param inverse indicate if the result array should be normalized by n^(-1).
|
||||
*/
|
||||
template < typename E, typename S > E * ntt_template(E * arr, uint32_t n, S * d_twiddles, uint32_t n_twiddles, bool inverse) {
|
||||
uint32_t logn = uint32_t(log(n) / log(2));
|
||||
size_t size_E = n * sizeof(E);
|
||||
E * arrReversed = template_reverse_order < E > (arr, n, logn);
|
||||
E * d_arrReversed;
|
||||
cudaMalloc( & d_arrReversed, size_E);
|
||||
cudaMemcpy(d_arrReversed, arrReversed, size_E, cudaMemcpyHostToDevice);
|
||||
template_ntt_on_device_memory < E, S > (d_arrReversed, n, logn, d_twiddles, n_twiddles);
|
||||
if (inverse) {
|
||||
int NUM_THREADS = MAX_NUM_THREADS;
|
||||
int NUM_BLOCKS = (n + NUM_THREADS - 1) / NUM_THREADS;
|
||||
template_normalize_kernel < E, S > <<< NUM_THREADS, NUM_BLOCKS >>> (d_arrReversed, n, S::inv_log_size(logn));
|
||||
}
|
||||
cudaMemcpy(arrReversed, d_arrReversed, size_E, cudaMemcpyDeviceToHost);
|
||||
cudaFree(d_arrReversed);
|
||||
return arrReversed;
|
||||
}
|
||||
|
||||
uint32_t n_twiddles_div = n_twiddles >> (s + 1);
|
||||
|
||||
uint32_t shift_s = 1 << s;
|
||||
uint32_t shift2_s = 1 << (s + 1);
|
||||
|
||||
l = ntw_i * loop_limit + l; // to l from chunks to full
|
||||
|
||||
uint32_t j = l & (shift_s - 1); // Equivalent to: l % (1 << s)
|
||||
uint32_t i = ((l >> s) * shift2_s) & (n - 1); // (..) % n (assuming n is power of 2)
|
||||
uint32_t oij = i + j;
|
||||
uint32_t k = oij + shift_s;
|
||||
S tw = r_twiddles[j * n_twiddles_div];
|
||||
/**
|
||||
* Cooley-Tukey (scalar) NTT.
|
||||
* @param arr input array of type E (element).
|
||||
* @param n length of d_arr.
|
||||
* @param inverse indicate if the result array should be normalized by n^(-1).
|
||||
*/
|
||||
template<typename E,typename S> uint32_t ntt_end2end_template(E * arr, uint32_t n, bool inverse) {
|
||||
uint32_t logn = uint32_t(log(n) / log(2));
|
||||
uint32_t n_twiddles = n;
|
||||
S * twiddles = new S[n_twiddles];
|
||||
S * d_twiddles;
|
||||
if (inverse){
|
||||
d_twiddles = fill_twiddle_factors_array(n_twiddles, S::omega_inv(logn));
|
||||
} else{
|
||||
d_twiddles = fill_twiddle_factors_array(n_twiddles, S::omega(logn));
|
||||
}
|
||||
E * result = ntt_template < E, S > (arr, n, d_twiddles, n_twiddles, inverse);
|
||||
for(int i = 0; i < n; i++){
|
||||
arr[i] = result[i];
|
||||
}
|
||||
cudaFree(d_twiddles);
|
||||
return 0; // TODO add
|
||||
}
|
||||
|
||||
|
||||
E u = s == 0 ? arr_g[offset + oij] : arr[oij];
|
||||
E v = s == 0 ? arr_g[offset + k] : arr[k];
|
||||
v = tw * v;
|
||||
if (s == (logn - 1))
|
||||
{
|
||||
arr_g[offset + oij] = u + v;
|
||||
arr_g[offset + k] = u - v;
|
||||
}
|
||||
else
|
||||
{
|
||||
arr[oij] = u + v;
|
||||
arr[k] = u - v;
|
||||
}
|
||||
|
||||
__syncthreads();
|
||||
}
|
||||
/**
|
||||
* Returens the bit reversal ordering of the input array according to the batches *in place*.
|
||||
* The assumption is that arr is divided into N tasks of size n.
|
||||
* Tasks indicates the index of the task (out of N).
|
||||
* @param arr input array of type T.
|
||||
* @param n length of arr.
|
||||
* @param logn log(n).
|
||||
* @param task log(n).
|
||||
*/
|
||||
template < typename T > __device__ __host__ void reverseOrder_batch(T * arr, uint32_t n, uint32_t logn, uint32_t task) {
|
||||
for (uint32_t i = 0; i < n; i++) {
|
||||
uint32_t reversed = reverseBits(i, logn);
|
||||
if (reversed > i) {
|
||||
T tmp = arr[task * n + i];
|
||||
arr[task * n + i] = arr[task * n + reversed];
|
||||
arr[task * n + reversed] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cooley-Tukey butterfly kernel.
|
||||
* @param arr array of objects of type E (elements).
|
||||
* @param twiddles array of twiddle factors of type S (scalars).
|
||||
* @param n size of arr.
|
||||
* @param n_twiddles size of omegas.
|
||||
* @param m "pair distance" - indicate distance of butterflies inputs.
|
||||
* @param i Cooley-TUckey FFT stage number.
|
||||
* @param offset offset corr. to the specific taks (in batch).
|
||||
*/
|
||||
template < typename E, typename S > __device__ __host__ void butterfly(E * arrReversed, S * omegas, uint32_t n, uint32_t n_omegas, uint32_t m, uint32_t i, uint32_t j, uint32_t offset) {
|
||||
uint32_t g = j * (n / m);
|
||||
uint32_t k = i + j + (m >> 1);
|
||||
E u = arrReversed[offset + i + j];
|
||||
E v = omegas[g * n_omegas / n] * arrReversed[offset + k];
|
||||
arrReversed[offset + i + j] = u + v;
|
||||
arrReversed[offset + k] = u - v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cooley-Tukey NTT.
|
||||
* NOTE! this function assumes that d_twiddles are located in the device memory.
|
||||
@@ -257,80 +292,39 @@ __global__ void ntt_template_kernel(E *arr, uint32_t n, S *twiddles, uint32_t n_
|
||||
|
||||
l = ntw_i * blockDim.x + l; //to l from chunks to full
|
||||
|
||||
uint32_t j = l & (shift_s - 1); // Equivalent to: l % (1 << s)
|
||||
uint32_t i = ((l >> s) * shift2_s) & (n - 1); // (..) % n (assuming n is power of 2)
|
||||
uint32_t j = l & (shift_s - 1); // Equivalent to: l % (1 << s)
|
||||
uint32_t i = ((l / shift_s) * shift2_s) % n;
|
||||
uint32_t k = i + j + shift_s;
|
||||
|
||||
S tw = twiddles[j * n_twiddles_div];
|
||||
|
||||
uint32_t offset = (task / chunks) * n;
|
||||
E u = arr[offset + i + j];
|
||||
E v = arr[offset + k];
|
||||
if (!rev) v = tw * v;
|
||||
E v = rev ? arr[offset + k] : twiddles[j * n_twiddles_div] * arr[offset + k];
|
||||
arr[offset + i + j] = u + v;
|
||||
v = u - v;
|
||||
arr[offset + k] = rev ? tw * v : v;
|
||||
arr[offset + k] = u - v;
|
||||
if (rev)
|
||||
arr[offset + k] = twiddles[j * n_twiddles_div] * arr[offset + k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NTT/INTT inplace batch
|
||||
* Note: this function does not preform any bit-reverse permutations on its inputs or outputs.
|
||||
* @param d_inout Array for inplace processing
|
||||
* @param d_twiddles
|
||||
* @param n Length of `d_twiddles` array
|
||||
* @param batch_size The size of the batch; the length of `d_inout` is `n` * `batch_size`.
|
||||
* @param inverse true for iNTT
|
||||
* @param is_coset true for multiplication by coset
|
||||
* @param coset should be array of lenght n - or in case of lesser than n, right-padded with zeroes
|
||||
* @param stream CUDA stream
|
||||
* @param is_sync_needed do perform sync of the supplied CUDA stream at the end of processing
|
||||
* Cooley-Tukey NTT.
|
||||
* NOTE! this function assumes that d_twiddles are located in the device memory.
|
||||
* @param arr input array of type E (elements).
|
||||
* @param n length of arr.
|
||||
* @param logn log2(n).
|
||||
* @param max_task max count of parallel tasks.
|
||||
*/
|
||||
template <typename E, typename S> void ntt_inplace_batch_template(
|
||||
E * d_inout, S * d_twiddles, unsigned n, unsigned batch_size, bool inverse,
|
||||
bool is_coset, S * coset, cudaStream_t stream, bool is_sync_needed)
|
||||
template <typename E, typename S>
|
||||
__global__ void ntt_template_kernel_rev_ord(E *arr, uint32_t n, uint32_t logn, uint32_t max_task)
|
||||
{
|
||||
const int logn = int(log(n) / log(2));
|
||||
bool is_shared_mem_enabled = sizeof(E) <= MAX_SHARED_MEM_ELEMENT_SIZE;
|
||||
const int log2_shmem_elems = is_shared_mem_enabled ? int(log(int(MAX_SHARED_MEM / sizeof(E))) / log(2)) : logn;
|
||||
int num_threads = min(min(n / 2, MAX_THREADS_BATCH), 1 << (log2_shmem_elems - 1));
|
||||
const int chunks = max(int((n / 2) / num_threads), 1);
|
||||
const int total_tasks = batch_size * chunks;
|
||||
int num_blocks = total_tasks;
|
||||
const int shared_mem = 2 * num_threads * sizeof(E); // TODO: calculator, as shared mem size may be more efficient less then max to allow more concurrent blocks on SM
|
||||
const int logn_shmem = is_shared_mem_enabled ? int(log(2 * num_threads) / log(2)) : 0; //TODO: shared memory support only for types <= 32 bytes
|
||||
int task = (blockIdx.x * blockDim.x) + threadIdx.x;
|
||||
|
||||
// if (inverse)
|
||||
// {
|
||||
// if (is_shared_mem_enabled) ntt_template_kernel_shared<<<num_blocks, num_threads, shared_mem, stream>>>(d_inout, 1 << logn_shmem, d_twiddles, n, total_tasks, 0, logn_shmem);
|
||||
|
||||
// for (int s = logn_shmem; s < logn; s++) // TODO: this loop also can be unrolled
|
||||
// {
|
||||
// ntt_template_kernel <E, S> <<<num_blocks, num_threads, 0, stream>>>(d_inout, n, d_twiddles, n, total_tasks, s, false);
|
||||
// }
|
||||
|
||||
// if (is_coset) batch_vector_mult(coset, d_inout, n, batch_size, stream);
|
||||
|
||||
// num_threads = min(n / 2, MAX_NUM_THREADS);
|
||||
// num_blocks = (n * batch_size + num_threads - 1) / num_threads;
|
||||
// // template_normalize_kernel <E, S> <<<num_blocks, num_threads, 0, stream>>> (d_inout, n * batch_size, S::inv_log_size(logn));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
if (is_coset) batch_vector_mult(coset, d_inout, n, batch_size, stream);
|
||||
|
||||
for (int s = logn - 1; s >= logn_shmem; s--) // TODO: this loop also can be unrolled
|
||||
{
|
||||
ntt_template_kernel<<<num_blocks, num_threads, 0, stream>>>(d_inout, n, d_twiddles, n, total_tasks, s, true);
|
||||
}
|
||||
|
||||
if (is_shared_mem_enabled) ntt_template_kernel_shared_rev<<<num_blocks, num_threads, shared_mem, stream>>>(d_inout, 1 << logn_shmem, d_twiddles, n, total_tasks, 0, logn_shmem);
|
||||
// }
|
||||
|
||||
if (!is_sync_needed) return;
|
||||
|
||||
cudaStreamSynchronize(stream);
|
||||
if (task < max_task)
|
||||
{
|
||||
reverseOrder_batch<E>(arr, n, logn, task);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -342,41 +336,43 @@ template <typename E, typename S> void ntt_inplace_batch_template(
|
||||
* @param n size of batch.
|
||||
* @param inverse indicate if the result array should be normalized by n^(-1).
|
||||
*/
|
||||
template <typename E, typename S> uint32_t ntt_end2end_batch_template(E * arr, uint32_t arr_size, uint32_t n, bool inverse, cudaStream_t stream) {
|
||||
template <typename E, typename S> uint32_t ntt_end2end_batch_template(E * arr, uint32_t arr_size, uint32_t n, bool inverse) {
|
||||
int batches = int(arr_size / n);
|
||||
uint32_t logn = uint32_t(log(n) / log(2));
|
||||
uint32_t n_twiddles = n/2; // n_twiddles is set to 4096 as BLS12_381::scalar_t::omega() is of that order.
|
||||
uint32_t n_twiddles = n; // n_twiddles is set to 4096 as BLS12_381::scalar_t::omega() is of that order.
|
||||
size_t size_E = arr_size * sizeof(E);
|
||||
S * d_twiddles;
|
||||
if (inverse){
|
||||
d_twiddles = fill_twiddle_factors_array(n_twiddles, S::omega_inv(logn), stream);
|
||||
d_twiddles = fill_twiddle_factors_array(n_twiddles, S::omega_inv(logn));
|
||||
} else{
|
||||
d_twiddles = fill_twiddle_factors_array(n_twiddles, S::omega(logn), stream);
|
||||
d_twiddles = fill_twiddle_factors_array(n_twiddles, S::omega(logn));
|
||||
}
|
||||
E * d_arr;
|
||||
cudaMallocAsync( & d_arr, size_E, stream);
|
||||
cudaMemcpyAsync(d_arr, arr, size_E, cudaMemcpyHostToDevice, stream);
|
||||
cudaMalloc( & d_arr, size_E);
|
||||
cudaMemcpy(d_arr, arr, size_E, cudaMemcpyHostToDevice);
|
||||
int NUM_THREADS = MAX_THREADS_BATCH;
|
||||
int NUM_BLOCKS = (batches + NUM_THREADS - 1) / NUM_THREADS;
|
||||
|
||||
S* _null = nullptr;
|
||||
ntt_inplace_batch_template(d_arr, d_twiddles, n, batches, inverse, false, _null, stream, false);
|
||||
reverse_order_batch(d_arr, n, logn, batches, stream);
|
||||
cudaMemcpyAsync(arr, d_arr, size_E, cudaMemcpyDeviceToHost, stream);
|
||||
cudaFreeAsync(d_arr, stream);
|
||||
cudaFreeAsync(d_twiddles, stream);
|
||||
cudaStreamSynchronize(stream);
|
||||
ntt_template_kernel_rev_ord<E, S><<<NUM_BLOCKS, NUM_THREADS>>>(d_arr, n, logn, batches);
|
||||
|
||||
NUM_THREADS = min(n / 2, MAX_THREADS_BATCH);
|
||||
int chunks = max(int((n / 2) / NUM_THREADS), 1);
|
||||
int total_tasks = batches * chunks;
|
||||
NUM_BLOCKS = total_tasks;
|
||||
|
||||
for (uint32_t s = 0; s < logn; s++) //TODO: this loop also can be unrolled
|
||||
{
|
||||
ntt_template_kernel<E, S><<<NUM_BLOCKS, NUM_THREADS>>>(d_arr, n, d_twiddles, n_twiddles, total_tasks, s, false);
|
||||
}
|
||||
if (inverse == true)
|
||||
{
|
||||
NUM_THREADS = MAX_NUM_THREADS;
|
||||
NUM_BLOCKS = (arr_size + NUM_THREADS - 1) / NUM_THREADS;
|
||||
template_normalize_kernel < E, S > <<< NUM_THREADS, NUM_BLOCKS >>> (d_arr, arr_size, S::inv_log_size(logn));
|
||||
}
|
||||
cudaMemcpy(arr, d_arr, size_E, cudaMemcpyDeviceToHost);
|
||||
cudaFree(d_arr);
|
||||
cudaFree(d_twiddles);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cooley-Tukey (scalar) NTT.
|
||||
* @param arr input array of type E (element).
|
||||
* @param n length of d_arr.
|
||||
* @param inverse indicate if the result array should be normalized by n^(-1).
|
||||
*/
|
||||
template<typename E,typename S> uint32_t ntt_end2end_template(E * arr, uint32_t n, bool inverse, cudaStream_t stream) {
|
||||
return ntt_end2end_batch_template <E, S> (arr, n, n, inverse, stream);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,52 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "constants/constants_11.h"
|
||||
#include "constants/constants_2.h"
|
||||
#include "constants/constants_4.h"
|
||||
#include "constants/constants_8.h"
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
|
||||
uint32_t partial_rounds_number_from_arity(const uint32_t arity)
|
||||
{
|
||||
switch (arity) {
|
||||
case 2:
|
||||
return 55;
|
||||
case 4:
|
||||
return 56;
|
||||
case 8:
|
||||
return 57;
|
||||
case 11:
|
||||
return 57;
|
||||
default:
|
||||
throw std::invalid_argument("unsupported arity");
|
||||
}
|
||||
};
|
||||
|
||||
// TO-DO: change to mapping
|
||||
const uint32_t FULL_ROUNDS_DEFAULT = 4;
|
||||
|
||||
// TO-DO: for now, the constants are only generated in bls12_381
|
||||
template <typename S>
|
||||
S* load_constants(const uint32_t arity)
|
||||
{
|
||||
unsigned char* constants;
|
||||
switch (arity) {
|
||||
case 2:
|
||||
constants = constants_2;
|
||||
break;
|
||||
case 4:
|
||||
constants = constants_4;
|
||||
break;
|
||||
case 8:
|
||||
constants = constants_8;
|
||||
break;
|
||||
case 11:
|
||||
constants = constants_11;
|
||||
break;
|
||||
default:
|
||||
throw std::invalid_argument("unsupported arity");
|
||||
}
|
||||
return reinterpret_cast<S*>(constants);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,629 +0,0 @@
|
||||
unsigned char constants_2[] = {
|
||||
0xd8, 0xd3, 0x6e, 0x9d, 0x00, 0x0a, 0x32, 0xa7, 0x36, 0x8b, 0x75, 0xa2, 0x92, 0xac, 0x1e, 0x50, 0x24, 0x4a, 0xbb,
|
||||
0x1d, 0x86, 0x51, 0xbd, 0x23, 0x7a, 0xe1, 0x3a, 0xfa, 0x4b, 0x06, 0x9f, 0x66, 0x15, 0x3f, 0x9d, 0x2b, 0x84, 0xab,
|
||||
0x72, 0x6e, 0x34, 0x27, 0xac, 0x45, 0x96, 0x7c, 0xe6, 0xee, 0x6c, 0xa6, 0x4f, 0xc8, 0xf2, 0x7f, 0x53, 0xe4, 0x36,
|
||||
0xca, 0xac, 0xfb, 0xde, 0xa8, 0x61, 0x0a, 0xd5, 0x65, 0x81, 0x12, 0x71, 0x47, 0x23, 0x1e, 0x30, 0x49, 0xaa, 0x1a,
|
||||
0x4e, 0x2b, 0x29, 0x17, 0x5b, 0x27, 0xdf, 0x45, 0x8a, 0x1e, 0x1b, 0xf9, 0x09, 0x9d, 0xb8, 0x24, 0xfa, 0xce, 0xe9,
|
||||
0x21, 0xd1, 0xa0, 0x12, 0x2f, 0xca, 0x56, 0x5f, 0x2f, 0x1b, 0x40, 0x6c, 0x31, 0x90, 0x55, 0x2f, 0x1f, 0x2b, 0xd0,
|
||||
0xd2, 0xd2, 0xc9, 0x24, 0x26, 0x38, 0x05, 0x18, 0x53, 0x38, 0x1d, 0x42, 0xfc, 0x0b, 0xc8, 0xc5, 0x8b, 0x5a, 0xf3,
|
||||
0x19, 0xca, 0xff, 0xf5, 0x3b, 0xef, 0x15, 0x4e, 0xf4, 0xcc, 0xbe, 0xe8, 0x42, 0x69, 0x68, 0xf4, 0xfc, 0xd3, 0xc3,
|
||||
0xf0, 0x5d, 0x03, 0x89, 0x4a, 0xae, 0xb0, 0x13, 0x43, 0x39, 0xaa, 0x45, 0xb2, 0x41, 0x38, 0xf8, 0x20, 0x2d, 0xd1,
|
||||
0x1f, 0x3c, 0xc4, 0xaa, 0xf1, 0x40, 0xd0, 0x26, 0xe4, 0x81, 0x74, 0x41, 0xc1, 0xb4, 0xd0, 0x64, 0x8d, 0xf9, 0xdd,
|
||||
0x9a, 0x4b, 0x38, 0x45, 0x02, 0xcc, 0x01, 0x65, 0x25, 0x72, 0x24, 0x2b, 0xba, 0x3f, 0x2c, 0x1a, 0xbf, 0xc6, 0x3c,
|
||||
0xcf, 0xa1, 0xef, 0x9c, 0xda, 0x2e, 0x9b, 0x14, 0xc7, 0x81, 0x65, 0x85, 0xc3, 0x24, 0x2c, 0x65, 0xc6, 0x51, 0x3a,
|
||||
0xd3, 0xc1, 0xd1, 0xd5, 0x42, 0x8f, 0x2f, 0x3c, 0x0e, 0x61, 0xaf, 0xb8, 0xf6, 0x3c, 0x32, 0x1a, 0x9f, 0x28, 0x91,
|
||||
0x9d, 0x02, 0x18, 0x97, 0x47, 0x79, 0x21, 0xf9, 0x61, 0x40, 0x5c, 0x16, 0xa9, 0xc5, 0x6e, 0xca, 0x9f, 0x37, 0xf1,
|
||||
0x2a, 0x13, 0xf1, 0xf0, 0xf0, 0xef, 0xb4, 0x56, 0xf4, 0x08, 0x6a, 0x47, 0x52, 0x4a, 0x32, 0xbf, 0xb3, 0xab, 0xa5,
|
||||
0xdf, 0x36, 0x12, 0x63, 0x5f, 0x2e, 0xc2, 0xf4, 0x17, 0xa4, 0x0c, 0xfd, 0xeb, 0x3d, 0xe9, 0xc7, 0x1d, 0x97, 0x5e,
|
||||
0x52, 0x61, 0x75, 0x96, 0xfb, 0x11, 0x60, 0xcd, 0xf8, 0xca, 0xa8, 0x11, 0xdc, 0x6e, 0xcd, 0x59, 0xf3, 0x37, 0x41,
|
||||
0xd6, 0x61, 0xb3, 0x74, 0xe5, 0xa8, 0xc1, 0x51, 0xf5, 0xa2, 0x57, 0x2e, 0x32, 0xe4, 0x0e, 0xd2, 0xed, 0x73, 0xca,
|
||||
0x58, 0x7a, 0x81, 0x16, 0x9c, 0xa0, 0xa0, 0xc0, 0xaa, 0x65, 0xe0, 0x3f, 0x43, 0xb7, 0x03, 0xb0, 0x35, 0x84, 0x61,
|
||||
0xf6, 0x60, 0x0e, 0x18, 0xb3, 0x0a, 0xc0, 0x59, 0x98, 0x57, 0x80, 0x7e, 0x26, 0x8b, 0x26, 0x0f, 0x94, 0x44, 0xbc,
|
||||
0xc9, 0x71, 0xf8, 0x19, 0x9a, 0x3b, 0x0a, 0xea, 0x9a, 0xc0, 0x41, 0x26, 0x9b, 0x50, 0xe7, 0x5d, 0x1b, 0x59, 0x22,
|
||||
0x26, 0x79, 0x3a, 0xae, 0x39, 0x61, 0x13, 0x9c, 0x8f, 0x8e, 0xd0, 0xbf, 0x84, 0xb8, 0xca, 0x3f, 0x71, 0x41, 0x70,
|
||||
0x35, 0x88, 0x03, 0x63, 0x0d, 0xc5, 0x1a, 0xcb, 0x63, 0x11, 0x32, 0x90, 0xb6, 0xaa, 0xfb, 0xdc, 0xd9, 0xc3, 0xa1,
|
||||
0x93, 0x41, 0xe8, 0xa1, 0xfb, 0x2d, 0x88, 0x9e, 0xe6, 0x37, 0x21, 0xb2, 0xbe, 0xfc, 0x64, 0x18, 0x37, 0x87, 0xbc,
|
||||
0x36, 0xf2, 0xe4, 0x08, 0x5e, 0x87, 0x5f, 0x78, 0xbc, 0xbd, 0x4c, 0x91, 0x53, 0xb5, 0xf3, 0x3c, 0xe9, 0x8c, 0x1d,
|
||||
0xa7, 0x0a, 0x95, 0x90, 0x55, 0xfd, 0xfd, 0x61, 0xd1, 0x38, 0x21, 0xca, 0x5c, 0x8f, 0xc0, 0xc9, 0x39, 0x81, 0x8e,
|
||||
0x2d, 0x7c, 0xa7, 0xab, 0x84, 0xef, 0x09, 0xd3, 0x1f, 0xb2, 0xc8, 0xe7, 0x6a, 0x9c, 0xe5, 0x0d, 0xea, 0x15, 0x0f,
|
||||
0xdf, 0x55, 0x7e, 0x25, 0x01, 0xad, 0x36, 0xdc, 0xfe, 0x2c, 0xc2, 0xf5, 0xd1, 0x57, 0xef, 0xf2, 0x1d, 0xdd, 0x82,
|
||||
0xb0, 0x20, 0xbf, 0xfe, 0x8a, 0xa8, 0x4d, 0xb5, 0xd2, 0x03, 0x0d, 0x49, 0x43, 0xaf, 0x4a, 0xac, 0x95, 0x64, 0x6b,
|
||||
0x62, 0x6e, 0x75, 0x84, 0x85, 0x56, 0x8f, 0x99, 0x6d, 0xfa, 0xb4, 0x37, 0x30, 0xc4, 0x06, 0x82, 0x32, 0xf0, 0x86,
|
||||
0x6e, 0x5f, 0xde, 0x62, 0xa3, 0x61, 0xdc, 0x17, 0x37, 0x5c, 0xc8, 0x9b, 0x78, 0x6a, 0xf1, 0xa2, 0x77, 0x76, 0x44,
|
||||
0x93, 0xbe, 0x6b, 0x71, 0x39, 0x0a, 0x35, 0x86, 0xa3, 0x4c, 0x84, 0x0f, 0xb1, 0xbf, 0x51, 0x88, 0x18, 0x88, 0x57,
|
||||
0x09, 0x97, 0x55, 0xdf, 0x29, 0xe6, 0xff, 0xaa, 0xaf, 0x7b, 0x27, 0x29, 0xca, 0xf5, 0x11, 0x64, 0xa2, 0x2e, 0xb9,
|
||||
0x99, 0xc5, 0xc4, 0x56, 0x1b, 0x03, 0x0c, 0xf1, 0x7e, 0x9b, 0xf1, 0x8b, 0x57, 0xc7, 0x4c, 0x4a, 0x05, 0x84, 0x78,
|
||||
0x67, 0x3c, 0x82, 0xee, 0xe4, 0x55, 0xfb, 0xf2, 0x2e, 0xcb, 0x3a, 0x64, 0x88, 0x44, 0x15, 0x1b, 0x23, 0xaa, 0xe9,
|
||||
0x9a, 0x04, 0xbd, 0xb4, 0xbd, 0x34, 0x28, 0x84, 0x34, 0x55, 0x13, 0x2c, 0xbd, 0x43, 0x1c, 0x3b, 0xaf, 0x1d, 0x95,
|
||||
0x28, 0x18, 0x5f, 0xe7, 0x33, 0xa2, 0x4c, 0x58, 0xca, 0x42, 0xbe, 0x9e, 0x8e, 0x72, 0xae, 0xf1, 0x08, 0x40, 0x8f,
|
||||
0x55, 0x61, 0x68, 0xa3, 0x2e, 0xff, 0x75, 0xe7, 0x38, 0x44, 0x68, 0x4a, 0x40, 0x05, 0x3f, 0x64, 0xf2, 0xf3, 0xd7,
|
||||
0x8d, 0xd4, 0x3d, 0x69, 0x2e, 0xc9, 0x94, 0x3f, 0xc8, 0x75, 0xa1, 0xa1, 0xe5, 0x0b, 0x26, 0xec, 0x36, 0xe9, 0x29,
|
||||
0x67, 0x4b, 0xc9, 0x2b, 0x0f, 0x4b, 0xa0, 0x56, 0xaf, 0x8b, 0x81, 0xea, 0x11, 0xf5, 0x42, 0xd3, 0xf2, 0x6e, 0x91,
|
||||
0xf3, 0x35, 0x60, 0xe6, 0xa0, 0x80, 0x09, 0x45, 0xfe, 0x29, 0x4c, 0xde, 0x96, 0x76, 0x6e, 0x27, 0xfc, 0x64, 0xd3,
|
||||
0xf7, 0xb4, 0xbf, 0xfa, 0x8c, 0x13, 0x68, 0x52, 0xf7, 0x9c, 0x86, 0x74, 0xe1, 0x8a, 0x01, 0x97, 0x73, 0x69, 0x29,
|
||||
0x21, 0x0d, 0xae, 0xcf, 0xa7, 0x83, 0xf2, 0x8b, 0x93, 0x8d, 0xef, 0xf2, 0x7c, 0xc1, 0xfd, 0x50, 0xca, 0x95, 0x53,
|
||||
0x77, 0x46, 0xa8, 0xe0, 0xb9, 0x6f, 0x4e, 0xe5, 0x55, 0x35, 0x2b, 0x6b, 0x67, 0x5e, 0x4e, 0x24, 0x51, 0x85, 0xf3,
|
||||
0x19, 0x3d, 0x4c, 0x5c, 0x94, 0x7c, 0xb4, 0xe5, 0x49, 0xe8, 0xdf, 0xdd, 0x34, 0x4c, 0x64, 0x13, 0x6e, 0x67, 0x6a,
|
||||
0xc6, 0x5e, 0x82, 0x1f, 0xdc, 0x0e, 0xf6, 0x15, 0x2a, 0x6f, 0xdd, 0x3a, 0x5c, 0x7d, 0x20, 0xbf, 0xd5, 0x89, 0xa1,
|
||||
0x25, 0x2f, 0x59, 0xe7, 0xca, 0xa2, 0xb4, 0xde, 0x72, 0x2c, 0xe8, 0xe6, 0xc5, 0x3d, 0x93, 0xa5, 0xe0, 0x47, 0x7d,
|
||||
0xe5, 0x65, 0x58, 0x59, 0xec, 0x62, 0x79, 0xc5, 0x69, 0x21, 0xfb, 0x12, 0x45, 0xe7, 0xb3, 0xa0, 0x5c, 0xba, 0xfb,
|
||||
0x70, 0x38, 0x8b, 0x80, 0x95, 0x90, 0x72, 0x85, 0xf8, 0x61, 0xb3, 0x6f, 0x5f, 0x9d, 0x2d, 0x36, 0x9f, 0xe0, 0xeb,
|
||||
0xc2, 0xd2, 0xcd, 0x33, 0x5a, 0x26, 0x78, 0xa7, 0x7f, 0x24, 0x52, 0x52, 0x3a, 0xe6, 0xf6, 0xf4, 0xa0, 0x9c, 0x52,
|
||||
0x1d, 0xd5, 0x26, 0x5d, 0x9a, 0x7b, 0x9f, 0xba, 0x63, 0x6a, 0xda, 0xb9, 0xed, 0xec, 0x37, 0x8b, 0x24, 0x76, 0xcf,
|
||||
0x1d, 0xa0, 0x3e, 0x1e, 0xc7, 0x60, 0x73, 0xc5, 0x5b, 0x7f, 0x93, 0x84, 0x62, 0x9b, 0xe8, 0x28, 0x07, 0xac, 0x77,
|
||||
0xe7, 0xb3, 0x7d, 0x6f, 0x51, 0x91, 0xc7, 0xf3, 0x4d, 0x17, 0xeb, 0xe7, 0xc5, 0x31, 0x1e, 0x2d, 0x75, 0x2e, 0x30,
|
||||
0xd8, 0xe8, 0x75, 0x4c, 0x37, 0x7a, 0xd6, 0x5c, 0x75, 0x1d, 0xc0, 0xb4, 0x99, 0xa2, 0x49, 0xe0, 0x72, 0xe2, 0xb3,
|
||||
0x30, 0xed, 0x8b, 0xa7, 0x7e, 0x07, 0x79, 0x36, 0x77, 0xee, 0x15, 0x71, 0x1f, 0xe0, 0x0a, 0x98, 0x0a, 0xee, 0xcf,
|
||||
0x0c, 0x59, 0xcc, 0xc7, 0x48, 0x50, 0xd3, 0xea, 0x41, 0xe1, 0x66, 0xd4, 0x3b, 0x24, 0xe9, 0x63, 0x4c, 0x16, 0xec,
|
||||
0x51, 0x8e, 0x06, 0xc2, 0x11, 0x53, 0x58, 0x35, 0xd0, 0xd1, 0x77, 0x43, 0x59, 0x7f, 0xdb, 0x35, 0xe6, 0xea, 0x04,
|
||||
0x1b, 0x69, 0x2e, 0x03, 0x2e, 0x5e, 0xa9, 0x67, 0xc7, 0x24, 0x52, 0xef, 0x5e, 0x1d, 0x8c, 0xe8, 0xa3, 0xa4, 0x8e,
|
||||
0xc4, 0xcb, 0x5d, 0x8a, 0x57, 0x31, 0xdf, 0x3c, 0x38, 0xdf, 0xe6, 0xaf, 0x21, 0x77, 0x49, 0x02, 0xbc, 0x32, 0xde,
|
||||
0x1e, 0x9f, 0x6a, 0x95, 0x9f, 0x94, 0x3b, 0x84, 0xdc, 0xea, 0x0b, 0x09, 0x76, 0x2f, 0x93, 0x70, 0x12, 0x8c, 0xb6,
|
||||
0xd0, 0x20, 0xc3, 0xe2, 0x94, 0x8a, 0xb6, 0x2f, 0x9a, 0x03, 0xef, 0x5b, 0xc0, 0x47, 0xbf, 0xd0, 0xa7, 0x90, 0xe6,
|
||||
0x13, 0xac, 0xc9, 0x2e, 0x10, 0xef, 0x10, 0xd1, 0x81, 0x65, 0x5d, 0xfa, 0x50, 0x65, 0xc0, 0xd6, 0x59, 0x3a, 0xe0,
|
||||
0x5c, 0x94, 0xbd, 0xf8, 0xc6, 0x25, 0x85, 0x61, 0x2f, 0xa5, 0x5c, 0x0d, 0x7e, 0xe1, 0xa8, 0x04, 0x3b, 0x1f, 0x61,
|
||||
0x34, 0x4b, 0x30, 0xf3, 0x84, 0x8e, 0x89, 0xb1, 0x58, 0xe2, 0x48, 0xf4, 0x79, 0x7f, 0x5f, 0x95, 0x1d, 0xe7, 0x71,
|
||||
0x47, 0x5d, 0x43, 0x69, 0xd4, 0x7b, 0xe6, 0x87, 0x9e, 0x11, 0x12, 0x2a, 0x4f, 0xf7, 0x0c, 0xfb, 0x3c, 0x0b, 0x1d,
|
||||
0xe7, 0xa3, 0x0b, 0xdf, 0xc7, 0xd1, 0x35, 0xdb, 0x7d, 0x58, 0x7b, 0x46, 0x40, 0x3e, 0xf6, 0xc1, 0xb6, 0x22, 0x99,
|
||||
0x13, 0xd0, 0xd9, 0x3f, 0x28, 0xc5, 0xef, 0xeb, 0x6a, 0xda, 0xf5, 0xfb, 0x2d, 0x9d, 0x3c, 0x23, 0x23, 0x7d, 0x1f,
|
||||
0x81, 0x55, 0xaf, 0xd4, 0xec, 0x7b, 0x09, 0x79, 0xe1, 0x90, 0xde, 0xe3, 0xff, 0x9a, 0x13, 0x2b, 0x4e, 0x70, 0x5c,
|
||||
0x63, 0x72, 0x88, 0xfa, 0x74, 0x4f, 0xb7, 0xd1, 0x33, 0x3b, 0x8a, 0xec, 0x2e, 0x9b, 0x77, 0x0b, 0x8c, 0x3a, 0x91,
|
||||
0x2c, 0x63, 0x3c, 0x03, 0x40, 0x1e, 0x78, 0x83, 0x4c, 0xcc, 0x0a, 0x3b, 0x99, 0x8d, 0x10, 0x54, 0x79, 0x3e, 0x85,
|
||||
0x9d, 0xab, 0x2f, 0xd6, 0x9b, 0xab, 0x63, 0x85, 0x7a, 0x80, 0xe2, 0x43, 0xc0, 0x31, 0xa9, 0x77, 0x9a, 0x12, 0xf6,
|
||||
0xcb, 0x8d, 0xfb, 0x65, 0xed, 0xb7, 0x11, 0xff, 0x5c, 0xe0, 0x8f, 0x16, 0xc6, 0x9b, 0x36, 0x56, 0x2b, 0x8a, 0xe1,
|
||||
0x9b, 0xe1, 0xfc, 0x01, 0x3f, 0xa4, 0x49, 0x5d, 0x59, 0x19, 0xbd, 0xbe, 0x17, 0x49, 0xe5, 0xa1, 0xa7, 0xf7, 0x26,
|
||||
0x19, 0xa4, 0x0f, 0xd3, 0x5b, 0x74, 0xa9, 0xfe, 0x53, 0x88, 0x51, 0xa8, 0x9c, 0x3f, 0xde, 0xbd, 0x19, 0xa0, 0x40,
|
||||
0x31, 0x50, 0x1f, 0x8b, 0x92, 0x97, 0xb2, 0x1c, 0xc7, 0xb0, 0xdd, 0xd5, 0xae, 0x88, 0x92, 0x00, 0x4a, 0xd7, 0xb7,
|
||||
0xf8, 0x02, 0xaa, 0x25, 0xbb, 0x05, 0x89, 0x78, 0xda, 0x9c, 0x00, 0xb5, 0x48, 0x2c, 0x0d, 0xf3, 0xfa, 0xfc, 0x4e,
|
||||
0x6f, 0x3d, 0x96, 0x74, 0x92, 0xb5, 0x16, 0x01, 0x88, 0xb2, 0x4a, 0x9c, 0x43, 0x35, 0x75, 0xef, 0x3d, 0x6e, 0xd0,
|
||||
0x92, 0xc0, 0x24, 0xf6, 0xd6, 0xc0, 0x01, 0xef, 0x23, 0xb0, 0x6e, 0x27, 0x21, 0x5e, 0xa1, 0x8c, 0x0f, 0x69, 0xbc,
|
||||
0x09, 0x47, 0x2c, 0x13, 0x5d, 0xba, 0x32, 0x3c, 0x37, 0x62, 0x3a, 0xdf, 0x38, 0x5a, 0x17, 0xe2, 0xfc, 0xe3, 0x8e,
|
||||
0xe2, 0xd6, 0x6d, 0x50, 0x1b, 0xd1, 0xcc, 0x4b, 0x9d, 0x66, 0x0a, 0x90, 0x85, 0x01, 0x3b, 0xa2, 0x77, 0xd4, 0x95,
|
||||
0x90, 0x63, 0x49, 0x5e, 0x27, 0xe7, 0xab, 0xc5, 0xf1, 0xf9, 0xa8, 0xf2, 0x40, 0xb1, 0x14, 0x35, 0x4d, 0x69, 0x4c,
|
||||
0x51, 0x3b, 0x9b, 0x10, 0x50, 0x70, 0x34, 0xf4, 0xbe, 0x14, 0x88, 0xb5, 0x40, 0x1a, 0x68, 0x74, 0x40, 0x4c, 0xa3,
|
||||
0xa7, 0x0d, 0x32, 0x64, 0xaa, 0xef, 0xf5, 0x7b, 0x1a, 0x60, 0x1d, 0xfc, 0x33, 0xf2, 0x50, 0xc6, 0x39, 0x28, 0x53,
|
||||
0xe7, 0x98, 0xbf, 0xbd, 0x1e, 0xac, 0x80, 0x35, 0x5d, 0x7a, 0x18, 0x96, 0x8f, 0xb1, 0x41, 0xc2, 0xcb, 0x7d, 0xd0,
|
||||
0x75, 0xd4, 0xc2, 0x11, 0x78, 0xd8, 0xa1, 0x98, 0x53, 0x1c, 0x59, 0x72, 0xac, 0xc1, 0x37, 0x0f, 0x42, 0x13, 0x0b,
|
||||
0x98, 0xf9, 0x6e, 0x6f, 0x36, 0x53, 0x8d, 0x66, 0x46, 0x65, 0xf0, 0x27, 0xd3, 0xe3, 0xf0, 0x10, 0x5d, 0x1b, 0xae,
|
||||
0x8d, 0x49, 0xec, 0xe6, 0x40, 0xfc, 0xfa, 0xbe, 0x55, 0x60, 0x4b, 0xfe, 0xd0, 0xca, 0x6a, 0x45, 0xd0, 0xd5, 0xe1,
|
||||
0x5f, 0x20, 0x67, 0x09, 0x4e, 0x6d, 0x59, 0xef, 0xba, 0xec, 0x57, 0x41, 0xfa, 0x62, 0x1c, 0x54, 0xa4, 0x74, 0x46,
|
||||
0xd1, 0x91, 0x48, 0xc9, 0xa6, 0x07, 0x01, 0xd1, 0x43, 0xa0, 0xe7, 0x7f, 0x35, 0xa0, 0x6f, 0xe4, 0x57, 0xb0, 0xb8,
|
||||
0x99, 0x7c, 0x93, 0x4a, 0x0d, 0x4b, 0x0a, 0xd6, 0x24, 0xb2, 0x27, 0xd1, 0xa8, 0x2e, 0x5b, 0x3c, 0xcc, 0x17, 0xb2,
|
||||
0x8a, 0x70, 0x93, 0x2b, 0x00, 0x96, 0x2d, 0x90, 0x4d, 0x67, 0x62, 0xb8, 0xc6, 0xd1, 0x46, 0xda, 0x3b, 0x6d, 0xdf,
|
||||
0xd6, 0x03, 0xf2, 0x01, 0xa2, 0x89, 0x6c, 0x50, 0xd5, 0xf0, 0xb1, 0xd2, 0x24, 0xdd, 0x02, 0x42, 0xde, 0x1d, 0x5b,
|
||||
0x00, 0xe0, 0x5f, 0x5f, 0x31, 0xf8, 0x59, 0x9d, 0xc8, 0xa4, 0x70, 0x4d, 0x49, 0x54, 0xc3, 0x94, 0xbc, 0x58, 0x2e,
|
||||
0x03, 0x02, 0xba, 0x43, 0x2b, 0xfd, 0x0f, 0x9c, 0x0f, 0x91, 0x28, 0xf4, 0x3b, 0xe7, 0xb1, 0x3b, 0x69, 0xbd, 0x6a,
|
||||
0x8f, 0x20, 0xab, 0x8f, 0xd2, 0x5a, 0xf4, 0x00, 0x92, 0xcd, 0x45, 0xd5, 0x96, 0x37, 0x31, 0x0e, 0xfd, 0x75, 0xda,
|
||||
0xa4, 0x0c, 0x57, 0xcf, 0x7b, 0x1b, 0xf5, 0xa9, 0xcd, 0xff, 0xaf, 0xe8, 0x54, 0x52, 0x8a, 0x9e, 0x03, 0x97, 0x5e,
|
||||
0x62, 0x3f, 0x09, 0x6d, 0x54, 0x61, 0x7d, 0xfc, 0x7a, 0x33, 0x85, 0x38, 0x9a, 0x67, 0x4d, 0xb2, 0x24, 0xa7, 0x7d,
|
||||
0x33, 0xff, 0x3d, 0xe5, 0x7f, 0x7d, 0x09, 0x60, 0x87, 0xa6, 0xe4, 0x96, 0x2d, 0x3d, 0x1a, 0xa4, 0x3d, 0x2e, 0x49,
|
||||
0xcd, 0xb3, 0x62, 0x45, 0xa9, 0x84, 0xb3, 0xd8, 0xa5, 0x94, 0x07, 0xf0, 0x67, 0x39, 0xbc, 0x85, 0x9d, 0x3f, 0x14,
|
||||
0xd2, 0x53, 0x83, 0x2e, 0x85, 0x89, 0x69, 0xc7, 0xe7, 0x88, 0xbf, 0x3e, 0x1d, 0x40, 0x53, 0x95, 0xc8, 0x78, 0x03,
|
||||
0x87, 0x80, 0x93, 0x9c, 0x88, 0x32, 0x70, 0x2e, 0x91, 0x7b, 0x8f, 0x2b, 0x83, 0xd7, 0x32, 0x88, 0x5c, 0x94, 0x65,
|
||||
0x4b, 0x1a, 0x31, 0xe1, 0x16, 0x25, 0x03, 0x6e, 0xfd, 0x91, 0x7c, 0x33, 0x81, 0xcd, 0x36, 0xbb, 0xf5, 0xd2, 0x7a,
|
||||
0x65, 0x29, 0x34, 0xd7, 0x0e, 0x58, 0x75, 0xef, 0xda, 0x5e, 0xc0, 0x38, 0x16, 0x02, 0xff, 0x42, 0x1a, 0xad, 0xc5,
|
||||
0x17, 0x61, 0x89, 0x83, 0xe1, 0xc0, 0x2c, 0x5f, 0xae, 0xaa, 0x4e, 0x0f, 0x4c, 0xd6, 0xe6, 0x14, 0xf2, 0xe9, 0x06,
|
||||
0xc0, 0x16, 0x05, 0x9d, 0xd4, 0xa3, 0x32, 0x69, 0xa8, 0x8f, 0x51, 0x8c, 0x23, 0xfe, 0x66, 0x8b, 0x79, 0x79, 0xc2,
|
||||
0x6c, 0xe8, 0xff, 0x1f, 0x24, 0xf9, 0x7e, 0xe1, 0x17, 0x23, 0x65, 0xf1, 0x53, 0x8e, 0x74, 0xd5, 0xb8, 0xc8, 0x95,
|
||||
0x65, 0x00, 0xf3, 0x5f, 0x88, 0x99, 0x77, 0x8f, 0x71, 0xe5, 0xac, 0xee, 0x85, 0x4a, 0x22, 0x8b, 0x3b, 0xb9, 0xa6,
|
||||
0x71, 0x54, 0x0a, 0x03, 0x60, 0x21, 0x82, 0x2f, 0xd6, 0x20, 0x91, 0x5d, 0xd9, 0x33, 0x5e, 0x54, 0x48, 0xf7, 0xfb,
|
||||
0x6b, 0xd1, 0xef, 0x89, 0x0e, 0xd6, 0x4a, 0x18, 0x7d, 0x89, 0x19, 0x45, 0xae, 0x60, 0x2c, 0x91, 0x0a, 0x2e, 0x9c,
|
||||
0xae, 0x8b, 0xd4, 0xd8, 0x03, 0x3d, 0x33, 0xc1, 0x31, 0x68, 0x7e, 0xed, 0xa8, 0xe3, 0xa8, 0x13, 0x65, 0x64, 0xc6,
|
||||
0x5c, 0x5d, 0x60, 0xef, 0xfa, 0xf1, 0x2d, 0x33, 0x32, 0xcb, 0xc5, 0x4d, 0x0b, 0x48, 0xec, 0x84, 0x39, 0x92, 0x9a,
|
||||
0xdc, 0x60, 0x0b, 0x0a, 0x66, 0xd9, 0xaa, 0x04, 0x53, 0x84, 0xe4, 0xeb, 0x71, 0x40, 0x82, 0xc6, 0x6c, 0xb8, 0xc0,
|
||||
0xd1, 0x44, 0x9b, 0xb2, 0xb8, 0xa1, 0x5b, 0x14, 0x3d, 0xc7, 0x13, 0x1b, 0xee, 0x19, 0xb0, 0x60, 0xc5, 0x0a, 0xc6,
|
||||
0x40, 0x7f, 0x0c, 0x2e, 0x75, 0x3c, 0x6f, 0x49, 0xba, 0x38, 0x0d, 0x03, 0x54, 0x04, 0xa3, 0x51, 0x0e, 0xaf, 0x3e,
|
||||
0x34, 0xcb, 0x13, 0x22, 0x15, 0xfa, 0xc1, 0x16, 0x9e, 0x58, 0x78, 0x47, 0x9c, 0xad, 0x06, 0xcd, 0xf4, 0x10, 0xee,
|
||||
0x0d, 0x78, 0x64, 0x8d, 0x70, 0x45, 0x55, 0xc2, 0x76, 0x45, 0x40, 0xf0, 0xe2, 0xfc, 0x0e, 0x8a, 0xc4, 0x78, 0x56,
|
||||
0x7f, 0x8f, 0x05, 0x16, 0x31, 0xd3, 0x42, 0xd7, 0xfe, 0xbb, 0xaa, 0x89, 0x3c, 0x53, 0xd8, 0xa6, 0x95, 0x43, 0x72,
|
||||
0xa2, 0x00, 0x15, 0xe7, 0x83, 0xea, 0x9e, 0xad, 0x69, 0x93, 0xc5, 0x9d, 0xfc, 0xc2, 0x8d, 0x3c, 0x58, 0xd8, 0x70,
|
||||
0xd7, 0xcb, 0x65, 0x53, 0xc0, 0x9e, 0x83, 0x7e, 0x02, 0xbf, 0x6a, 0x90, 0x2f, 0xa2, 0xbe, 0x5d, 0x68, 0xeb, 0xbd,
|
||||
0xad, 0xaf, 0xee, 0x91, 0x8a, 0xeb, 0x4e, 0x98, 0xc9, 0xed, 0x24, 0x0d, 0x0d, 0x8d, 0xdf, 0x16, 0xf6, 0x8e, 0x10,
|
||||
0x59, 0x38, 0xa4, 0xd1, 0x0c, 0x09, 0x61, 0x06, 0x63, 0xcc, 0x5a, 0x84, 0x63, 0x1d, 0x90, 0xc8, 0xfb, 0x7b, 0x49,
|
||||
0xcb, 0xcf, 0x5b, 0x34, 0x47, 0x96, 0x4e, 0xb1, 0x13, 0x66, 0xd5, 0x1f, 0x18, 0x30, 0xdd, 0xd7, 0x9d, 0xb8, 0x98,
|
||||
0x41, 0xf2, 0x13, 0x1d, 0xc0, 0xbc, 0xf9, 0x03, 0x37, 0x48, 0x06, 0x89, 0xcf, 0xa8, 0x2e, 0x68, 0x3f, 0x16, 0xf3,
|
||||
0x41, 0x22, 0xfc, 0x11, 0x2d, 0xb2, 0x29, 0x5c, 0x56, 0x0f, 0xf9, 0x84, 0x22, 0xee, 0x59, 0xb3, 0x95, 0x0b, 0xc7,
|
||||
0xf0, 0x3a, 0xe4, 0x08, 0xce, 0x91, 0xdc, 0xa4, 0x1e, 0xad, 0x5e, 0x30, 0x9a, 0x0e, 0xe3, 0xb2, 0x81, 0x13, 0x97,
|
||||
0x57, 0x31, 0x8f, 0x9c, 0xe1, 0x92, 0xa3, 0xab, 0x69, 0x94, 0x02, 0x5c, 0x68, 0xe9, 0x41, 0x1a, 0xc7, 0x17, 0xde,
|
||||
0xaf, 0x77, 0xc5, 0x44, 0x2d, 0x6a, 0x2f, 0xd0, 0x16, 0x41, 0x40, 0x74, 0x57, 0x01, 0xd0, 0xaa, 0xe6, 0x70, 0x13,
|
||||
0xf5, 0x3f, 0x0a, 0x39, 0x4d, 0xb1, 0x82, 0x87, 0x9b, 0xd6, 0x2b, 0xbd, 0xec, 0xa7, 0xcb, 0xdb, 0x57, 0x4e, 0x49,
|
||||
0xa5, 0x8a, 0xa4, 0xbe, 0x83, 0xe6, 0x7c, 0x8b, 0x79, 0x4a, 0x7f, 0x39, 0x23, 0x07, 0xa8, 0xa9, 0x4e, 0xbd, 0xc3,
|
||||
0xbb, 0xcf, 0xbc, 0xe2, 0x48, 0xa3, 0x60, 0xc0, 0x2c, 0x8d, 0x60, 0x26, 0x49, 0x07, 0x92, 0x78, 0xdb, 0x99, 0x94,
|
||||
0x0e, 0x02, 0x27, 0x08, 0x9c, 0xc8, 0x23, 0x03, 0xfb, 0x6d, 0x18, 0x89, 0xe7, 0x3c, 0x08, 0xe5, 0x93, 0x31, 0xaa,
|
||||
0x06, 0xa9, 0x86, 0x70, 0x40, 0x9e, 0x08, 0x5d, 0x7d, 0x8d, 0xa8, 0xee, 0xa0, 0x31, 0x49, 0x35, 0x99, 0x78, 0xf3,
|
||||
0x97, 0x77, 0x05, 0x5f, 0xb2, 0xc8, 0xdc, 0xd8, 0xec, 0x9d, 0x48, 0xb5, 0xa4, 0x13, 0x01, 0x45, 0xe9, 0xe3, 0x84,
|
||||
0x1c, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5,
|
||||
0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x01, 0x00, 0x00, 0x40, 0xff,
|
||||
0xff, 0xff, 0x3f, 0xff, 0xc4, 0xfe, 0x3f, 0x02, 0x3b, 0xce, 0xfe, 0x03, 0x62, 0x39, 0x07, 0x06, 0x62, 0x6b, 0x26,
|
||||
0xf6, 0x1d, 0x36, 0x5f, 0x7e, 0x3d, 0xf2, 0x56, 0x34, 0x33, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xcc, 0x65, 0x6a, 0x65,
|
||||
0x66, 0x9b, 0x95, 0x3e, 0x32, 0x03, 0xe8, 0x2d, 0x6c, 0x9e, 0x81, 0xef, 0x51, 0x2b, 0x4b, 0x2b, 0x4c, 0x98, 0x97,
|
||||
0x8e, 0x45, 0x01, 0x00, 0x00, 0x40, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xc4, 0xfe, 0x3f, 0x02, 0x3b, 0xce, 0xfe, 0x03,
|
||||
0x62, 0x39, 0x07, 0x06, 0x62, 0x6b, 0x26, 0xf6, 0x1d, 0x36, 0x5f, 0x7e, 0x3d, 0xf2, 0x56, 0x34, 0x33, 0x33, 0x33,
|
||||
0xcc, 0xcc, 0xcc, 0xcc, 0x65, 0x6a, 0x65, 0x66, 0x9b, 0x95, 0x3e, 0x32, 0x03, 0xe8, 0x2d, 0x6c, 0x9e, 0x81, 0xef,
|
||||
0x51, 0x2b, 0x4b, 0x2b, 0x4c, 0x98, 0x97, 0x8e, 0x45, 0x01, 0x00, 0x00, 0x80, 0x54, 0x55, 0x55, 0xd5, 0xa9, 0x4c,
|
||||
0xa9, 0x2a, 0xad, 0x08, 0x1e, 0x1b, 0xaf, 0xde, 0x06, 0x08, 0x5c, 0x89, 0x05, 0x80, 0x11, 0x93, 0x58, 0x4d, 0xc5,
|
||||
0x60, 0x9b, 0x60, 0x34, 0x33, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xcc, 0x65, 0x6a, 0x65, 0x66, 0x9b, 0x95, 0x3e, 0x32,
|
||||
0x03, 0xe8, 0x2d, 0x6c, 0x9e, 0x81, 0xef, 0x51, 0x2b, 0x4b, 0x2b, 0x4c, 0x98, 0x97, 0x8e, 0x45, 0x01, 0x00, 0x00,
|
||||
0x80, 0x54, 0x55, 0x55, 0xd5, 0xa9, 0x4c, 0xa9, 0x2a, 0xad, 0x08, 0x1e, 0x1b, 0xaf, 0xde, 0x06, 0x08, 0x5c, 0x89,
|
||||
0x05, 0x80, 0x11, 0x93, 0x58, 0x4d, 0xc5, 0x60, 0x9b, 0x60, 0x25, 0x49, 0x92, 0x24, 0xdb, 0xb6, 0x6d, 0xdb, 0x48,
|
||||
0x1a, 0x24, 0x49, 0xdc, 0x2e, 0x36, 0xaa, 0x4a, 0x62, 0x77, 0x70, 0x4b, 0x62, 0xc7, 0x57, 0x82, 0x91, 0x51, 0xe7,
|
||||
0x60, 0x54, 0x1f, 0x21, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e,
|
||||
0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x3e, 0x2c,
|
||||
0xe4, 0xf5, 0x63, 0xa7, 0xf2, 0x0e, 0x51, 0x85, 0x27, 0x20, 0x86, 0xec, 0x5b, 0x36, 0xe4, 0xea, 0xf3, 0x0c, 0x61,
|
||||
0xaa, 0xc6, 0x06, 0x74, 0xa3, 0xcc, 0xc1, 0x24, 0x1c, 0x32, 0x69, 0x95, 0x82, 0xd1, 0xb0, 0xf9, 0x5d, 0x48, 0x7e,
|
||||
0x90, 0xf2, 0x18, 0x4e, 0xad, 0x05, 0x11, 0x3b, 0xc9, 0xfa, 0xfe, 0xf4, 0xe4, 0x3a, 0xfc, 0xd1, 0xb8, 0x4b, 0xee,
|
||||
0xab, 0x1c, 0x80, 0x90, 0x0d, 0x01, 0x00, 0x00, 0x40, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xc4, 0xfe, 0x3f, 0x02, 0x3b,
|
||||
0xce, 0xfe, 0x03, 0x62, 0x39, 0x07, 0x06, 0x62, 0x6b, 0x26, 0xf6, 0x1d, 0x36, 0x5f, 0x7e, 0x3d, 0xf2, 0x56, 0xa5,
|
||||
0xd2, 0xd6, 0x97, 0x8d, 0x8a, 0xf9, 0x2a, 0x81, 0x39, 0xfd, 0xef, 0xe5, 0xd1, 0x41, 0x7d, 0xb2, 0xa6, 0x20, 0x46,
|
||||
0x9a, 0xc4, 0x02, 0xcc, 0x8e, 0x38, 0xd8, 0xa2, 0x2d, 0x8f, 0xa7, 0x5e, 0xc2, 0x91, 0x1b, 0xf6, 0x2c, 0xb3, 0x21,
|
||||
0xed, 0x91, 0x8c, 0x3e, 0xb5, 0x8e, 0x10, 0x26, 0x1f, 0x86, 0x4d, 0xae, 0x08, 0x65, 0x72, 0x2b, 0x5d, 0x7c, 0x64,
|
||||
0x10, 0xfa, 0xc1, 0xa6, 0x20, 0x55, 0x34, 0x33, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xcc, 0x65, 0x6a, 0x65, 0x66, 0x9b,
|
||||
0x95, 0x3e, 0x32, 0x03, 0xe8, 0x2d, 0x6c, 0x9e, 0x81, 0xef, 0x51, 0x2b, 0x4b, 0x2b, 0x4c, 0x98, 0x97, 0x8e, 0x45,
|
||||
0xc2, 0x91, 0x1b, 0xf6, 0x2c, 0xb3, 0x21, 0xed, 0x91, 0x8c, 0x3e, 0xb5, 0x8e, 0x10, 0x26, 0x1f, 0x86, 0x4d, 0xae,
|
||||
0x08, 0x65, 0x72, 0x2b, 0x5d, 0x7c, 0x64, 0x10, 0xfa, 0xc1, 0xa6, 0x20, 0x55, 0x54, 0x24, 0x25, 0x3c, 0xb1, 0x71,
|
||||
0x3e, 0xfe, 0x4e, 0xcd, 0x04, 0x70, 0xb5, 0xcd, 0x65, 0x35, 0x9b, 0xb9, 0x69, 0x70, 0xfc, 0x9e, 0xc1, 0xa4, 0x2c,
|
||||
0xe6, 0xb5, 0xd6, 0x38, 0x75, 0x07, 0x52, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55,
|
||||
0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49,
|
||||
0x4d, 0xa2, 0x92, 0xa6, 0xd6, 0xd4, 0x73, 0x2f, 0x8d, 0x27, 0x96, 0x8a, 0xc6, 0xc2, 0xbe, 0x74, 0x03, 0x5f, 0x90,
|
||||
0x8e, 0xac, 0x46, 0x55, 0x68, 0x45, 0x37, 0x1a, 0xb9, 0xf9, 0x97, 0x93, 0xd3, 0x59, 0x64, 0xe7, 0x4f, 0xee, 0x6e,
|
||||
0x02, 0x20, 0x8d, 0xbb, 0xe5, 0x84, 0x23, 0xf2, 0x41, 0x5f, 0x9f, 0xb2, 0xcf, 0xe4, 0x7d, 0xa9, 0x3a, 0xde, 0xdf,
|
||||
0xd5, 0xb6, 0x90, 0xd5, 0x24, 0xa0, 0xe0, 0x47, 0xd4, 0xfc, 0x91, 0xd8, 0xff, 0x9b, 0x40, 0xeb, 0x00, 0x2b, 0x35,
|
||||
0x8c, 0x86, 0x3c, 0x71, 0xa0, 0x84, 0xfc, 0x18, 0xf1, 0x16, 0x08, 0x99, 0xe5, 0x0c, 0x47, 0x83, 0xcb, 0x7e, 0x7f,
|
||||
0x96, 0x58, 0x72, 0x40, 0x10, 0x59, 0x28, 0x31, 0x2f, 0x0c, 0x1c, 0xa1, 0x19, 0x7f, 0x78, 0x5a, 0x5b, 0x8b, 0x40,
|
||||
0xe2, 0x52, 0xa3, 0xda, 0xea, 0xec, 0x8f, 0x71, 0xbc, 0x5d, 0x9a, 0xb2, 0xe8, 0x86, 0x6b, 0x01, 0x00, 0x00, 0x00,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1,
|
||||
0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0xf6, 0xd4, 0x61, 0x0e, 0xe7, 0x6c, 0x28, 0x1a, 0x40, 0x1b,
|
||||
0x06, 0x94, 0x15, 0xb8, 0x36, 0x75, 0xd6, 0x24, 0xc8, 0x9b, 0x0d, 0xde, 0x46, 0xc4, 0x4d, 0x88, 0x8c, 0xb5, 0x17,
|
||||
0xfd, 0x3a, 0x6b, 0x8b, 0xfc, 0x1a, 0xd8, 0x20, 0x32, 0xfa, 0x3d, 0xe4, 0xac, 0xa3, 0xc4, 0x8c, 0xce, 0xac, 0xbf,
|
||||
0x42, 0x77, 0x63, 0x24, 0x8d, 0x33, 0x7f, 0xc1, 0x04, 0x61, 0x88, 0x6e, 0xae, 0x24, 0x52, 0x2f, 0xc6, 0xe7, 0x50,
|
||||
0x37, 0x91, 0x5c, 0xb7, 0x6a, 0x69, 0xeb, 0xfc, 0x51, 0x70, 0x80, 0xa5, 0x77, 0x83, 0xe5, 0x3e, 0xba, 0x99, 0xfa,
|
||||
0x5b, 0xfa, 0x44, 0xc2, 0x17, 0xe5, 0x7b, 0xab, 0xfe, 0x58, 0x07, 0x0a, 0x3e, 0x04, 0x21, 0x6c, 0x74, 0x03, 0x24,
|
||||
0x15, 0x15, 0x1a, 0x63, 0xa3, 0xf5, 0xaf, 0x38, 0xf9, 0xf0, 0x3f, 0x1c, 0xf2, 0x2f, 0xba, 0x9e, 0x7d, 0xac, 0x24,
|
||||
0x16, 0xc3, 0x93, 0x1e, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e,
|
||||
0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x7c, 0x21,
|
||||
0x29, 0xeb, 0xdd, 0xd9, 0xc2, 0xc2, 0x87, 0x30, 0x82, 0xe0, 0xe9, 0xa7, 0x35, 0x64, 0xc9, 0x67, 0xa9, 0xed, 0xd0,
|
||||
0xc5, 0x91, 0x3b, 0xc9, 0xf2, 0xd4, 0xd9, 0xc5, 0x89, 0x91, 0x4f, 0xc3, 0xd3, 0xbe, 0x3f, 0xb1, 0x31, 0x98, 0x25,
|
||||
0x25, 0x83, 0x24, 0xcd, 0x54, 0x99, 0xdb, 0x6f, 0xa7, 0x2d, 0x31, 0xc4, 0x53, 0xe1, 0x69, 0xa6, 0x35, 0xd5, 0x8d,
|
||||
0x11, 0x70, 0xfa, 0x26, 0x1e, 0x28, 0xbd, 0xfe, 0x69, 0x57, 0x63, 0x6c, 0x33, 0xe6, 0xb6, 0x10, 0x41, 0xb8, 0xbe,
|
||||
0x1f, 0xf6, 0x3a, 0xbe, 0xb5, 0x6a, 0x57, 0x66, 0xd0, 0xe4, 0x2a, 0x6b, 0xc3, 0xaa, 0x4f, 0xf2, 0xba, 0x5b, 0xd7,
|
||||
0xbe, 0xb3, 0xcc, 0x01, 0x81, 0x30, 0xdc, 0x9a, 0xd6, 0xab, 0x6a, 0x87, 0x56, 0x69, 0x23, 0xef, 0x37, 0xac, 0xbc,
|
||||
0xaf, 0xec, 0x35, 0xea, 0x74, 0xc9, 0xbf, 0x9d, 0x06, 0x76, 0xbc, 0x1d, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8,
|
||||
0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0xcb, 0xf6, 0x96, 0x28, 0xa7, 0x00, 0x6b, 0x60, 0x4b, 0xd1, 0x5a, 0x13, 0x03,
|
||||
0xa3, 0xda, 0x7d, 0xb6, 0x2d, 0xaa, 0x2b, 0x12, 0xf8, 0x5b, 0x0c, 0x81, 0xb4, 0x61, 0x51, 0x55, 0x40, 0x5c, 0x5e,
|
||||
0xb1, 0x5a, 0x71, 0xf9, 0x06, 0x13, 0xed, 0x2b, 0x89, 0xc0, 0x01, 0x55, 0xa8, 0xaa, 0x45, 0x36, 0xc8, 0x84, 0xfc,
|
||||
0x78, 0x69, 0x40, 0x55, 0x89, 0x88, 0xbf, 0x02, 0xd3, 0xa7, 0xd9, 0xc5, 0x48, 0x6a, 0x73, 0xaa, 0x9b, 0x54, 0x06,
|
||||
0x6c, 0x88, 0x2b, 0xef, 0x5a, 0x3f, 0x70, 0xbd, 0xb8, 0x38, 0x75, 0x9d, 0xe1, 0xf2, 0x8a, 0x8a, 0x69, 0x26, 0x6f,
|
||||
0x07, 0xf1, 0x5b, 0x00, 0x0a, 0x28, 0x41, 0x3a, 0xb1, 0xf8, 0x8d, 0xaa, 0x7f, 0xd5, 0x90, 0x34, 0xdf, 0xc9, 0xa0,
|
||||
0x59, 0x13, 0x36, 0x53, 0x28, 0x15, 0xed, 0x06, 0x7c, 0x1c, 0x2d, 0x43, 0xab, 0x50, 0x3c, 0xc9, 0x4b, 0x14, 0xda,
|
||||
0x36, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5,
|
||||
0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x7a, 0xc0, 0x5b, 0x5c, 0x19,
|
||||
0x50, 0x23, 0xa3, 0x8b, 0x3d, 0x80, 0x09, 0x63, 0x38, 0x5e, 0x65, 0x16, 0xd0, 0xa3, 0xa3, 0xe7, 0x28, 0x5a, 0x5f,
|
||||
0xa7, 0x0a, 0x4f, 0x0c, 0x34, 0x95, 0x26, 0x70, 0x85, 0x11, 0x97, 0x36, 0xa2, 0x76, 0x64, 0xd9, 0x7a, 0x8e, 0xa6,
|
||||
0xa1, 0x51, 0x9a, 0x89, 0xda, 0x38, 0x46, 0xd0, 0x68, 0x30, 0xde, 0x70, 0xf8, 0x88, 0x7d, 0xa9, 0x19, 0x45, 0x62,
|
||||
0xb0, 0x6f, 0xf3, 0xc4, 0xd7, 0xfd, 0x95, 0xb9, 0xd1, 0x1c, 0x7e, 0xb5, 0x58, 0xa6, 0x63, 0xaf, 0xcb, 0x4b, 0x52,
|
||||
0x83, 0x85, 0x0e, 0xed, 0x33, 0xfa, 0xb3, 0x61, 0x90, 0x61, 0x68, 0xc2, 0xba, 0x54, 0x5d, 0x23, 0xc8, 0xfb, 0x0e,
|
||||
0x7d, 0x7a, 0x8c, 0xa9, 0x09, 0x2a, 0x21, 0x4e, 0x23, 0x02, 0xf2, 0x0d, 0x84, 0xd1, 0xab, 0x8a, 0x13, 0x8c, 0x9a,
|
||||
0x6a, 0x20, 0xd2, 0x09, 0x82, 0xfb, 0x1e, 0xe6, 0x17, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d,
|
||||
0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37,
|
||||
0x1a, 0x49, 0x4d, 0xd1, 0x0f, 0xb4, 0xbd, 0x0e, 0x68, 0x31, 0x1a, 0x30, 0xc8, 0x92, 0xd8, 0xaa, 0xcd, 0x04, 0x05,
|
||||
0x87, 0x5c, 0x49, 0x68, 0xd2, 0xba, 0x3e, 0xb2, 0x09, 0xa3, 0xb0, 0x8a, 0x59, 0xcf, 0xd2, 0x4b, 0xeb, 0xf7, 0xaa,
|
||||
0x35, 0xf6, 0x48, 0x57, 0x40, 0x6b, 0x0e, 0x26, 0x37, 0x2a, 0x91, 0x0c, 0xea, 0x3f, 0x26, 0x97, 0xc8, 0xc4, 0x4a,
|
||||
0x18, 0xd3, 0x06, 0x12, 0x93, 0xa5, 0xad, 0x9a, 0x69, 0x6a, 0xc1, 0x4d, 0x2c, 0x31, 0x45, 0x03, 0x3a, 0x2e, 0x24,
|
||||
0xd5, 0xd0, 0xdf, 0xeb, 0xdb, 0xdf, 0xd0, 0x6f, 0x3d, 0x14, 0xa8, 0x7a, 0x5f, 0x53, 0xe3, 0x9e, 0xb8, 0x68, 0x4d,
|
||||
0x91, 0xe2, 0x0a, 0x48, 0x94, 0x73, 0xd9, 0x84, 0x9a, 0x55, 0x3e, 0x42, 0x99, 0xe7, 0x1e, 0x73, 0x64, 0xd4, 0x8d,
|
||||
0x26, 0xf0, 0x16, 0x36, 0x08, 0x7b, 0xde, 0x8c, 0xe9, 0x0a, 0x27, 0x3a, 0x90, 0x6f, 0x6c, 0x90, 0x66, 0x01, 0x00,
|
||||
0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0,
|
||||
0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0xd1, 0x81, 0xc0, 0x8c, 0xc5, 0x6d, 0x18, 0x32,
|
||||
0xd7, 0x82, 0x81, 0xb4, 0x0f, 0x0b, 0x34, 0x91, 0xe1, 0xec, 0x57, 0xf2, 0x17, 0xca, 0x56, 0x15, 0x1f, 0x7d, 0xa7,
|
||||
0x27, 0x3a, 0xaf, 0xc3, 0x24, 0x0e, 0x26, 0x24, 0x5e, 0x31, 0x77, 0x45, 0xfb, 0x9c, 0x71, 0xaf, 0x19, 0x73, 0xd0,
|
||||
0x33, 0x0b, 0x22, 0xd8, 0xde, 0xd0, 0x42, 0x79, 0xc0, 0x40, 0x23, 0x44, 0x1e, 0xa3, 0xdf, 0x65, 0x48, 0x50, 0x96,
|
||||
0xdc, 0xc5, 0x98, 0x9b, 0x13, 0xa8, 0x29, 0x6e, 0x79, 0x02, 0xef, 0x50, 0xd0, 0xdf, 0x71, 0x29, 0xd3, 0xa4, 0x3a,
|
||||
0xa4, 0x13, 0xc9, 0x0f, 0xa3, 0xff, 0x73, 0x25, 0xb0, 0xb8, 0xe0, 0x07, 0x02, 0xfd, 0xb5, 0x6f, 0xb4, 0x95, 0xc5,
|
||||
0x49, 0x8b, 0x13, 0xb4, 0xb9, 0x4f, 0xba, 0xd3, 0x83, 0xc2, 0x8c, 0x7a, 0xbe, 0x9a, 0x0b, 0x7d, 0x03, 0x75, 0xf6,
|
||||
0xbd, 0x84, 0xbd, 0xc0, 0xd4, 0x33, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57,
|
||||
0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d,
|
||||
0x60, 0x31, 0xd7, 0xab, 0x48, 0x21, 0x3b, 0x89, 0xc4, 0x3f, 0xe9, 0x30, 0xf6, 0xbc, 0x55, 0xf0, 0xcf, 0x49, 0x4d,
|
||||
0xf3, 0x3f, 0x66, 0xbe, 0x39, 0x3c, 0xcd, 0x53, 0x36, 0xc6, 0xd6, 0x04, 0x62, 0x37, 0x64, 0x6e, 0x86, 0x83, 0x2f,
|
||||
0x1a, 0xe3, 0xd8, 0xcb, 0x6b, 0xcc, 0x18, 0x8c, 0xbc, 0x89, 0x97, 0x69, 0xa7, 0xe9, 0x61, 0x1f, 0xe6, 0x92, 0x3e,
|
||||
0x34, 0x7b, 0xfa, 0xee, 0x9d, 0xcb, 0x03, 0x26, 0x8e, 0xd5, 0xc7, 0x11, 0xfb, 0x18, 0xc6, 0xe0, 0xd0, 0x7e, 0xb7,
|
||||
0x77, 0x2c, 0x6e, 0xc0, 0x48, 0x33, 0x34, 0x11, 0x1c, 0x7d, 0x55, 0xa5, 0xca, 0xb3, 0x2d, 0xc6, 0x06, 0x59, 0x9b,
|
||||
0x27, 0x8a, 0x1a, 0xd6, 0xa4, 0x5c, 0x48, 0x9f, 0x72, 0x20, 0x69, 0xdc, 0xbd, 0xf0, 0xba, 0x39, 0x4c, 0x70, 0xa5,
|
||||
0x78, 0xb5, 0x87, 0x9c, 0x00, 0xe0, 0xc8, 0xf1, 0x8c, 0x03, 0x3a, 0x2c, 0x1c, 0x2e, 0x01, 0x00, 0x00, 0x00, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc,
|
||||
0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x83, 0x09, 0xd7, 0x49, 0xb5, 0x30, 0x90, 0x05, 0x98, 0x2a, 0x2f,
|
||||
0x01, 0x25, 0x9f, 0x29, 0xf4, 0xa1, 0x30, 0x62, 0x62, 0x05, 0xbb, 0xa6, 0xda, 0x2f, 0x82, 0x41, 0xad, 0x2f, 0x4a,
|
||||
0x49, 0x2f, 0x06, 0x35, 0xd8, 0x2f, 0x0c, 0xfa, 0xa5, 0x8c, 0x8e, 0xe7, 0x8a, 0x31, 0x83, 0x67, 0xf4, 0x34, 0xa2,
|
||||
0xa2, 0x88, 0x6c, 0x71, 0xc7, 0xf1, 0x4c, 0xca, 0xba, 0x0d, 0x57, 0xc8, 0xef, 0x8f, 0x42, 0x9b, 0x2d, 0x86, 0x4a,
|
||||
0x6a, 0x2c, 0xe7, 0x42, 0x56, 0xe5, 0x36, 0x46, 0xf6, 0xa6, 0x25, 0x4c, 0x83, 0xc1, 0x46, 0x19, 0x22, 0xf9, 0xcd,
|
||||
0x19, 0x31, 0x55, 0xaa, 0x2b, 0xa5, 0x59, 0x78, 0x70, 0x90, 0x84, 0x93, 0x55, 0xb8, 0x46, 0x4d, 0x54, 0xaa, 0x13,
|
||||
0x1e, 0x5f, 0x72, 0x9a, 0xb5, 0x05, 0x48, 0x28, 0x3d, 0x78, 0xaf, 0xd3, 0x25, 0x46, 0x9b, 0xd1, 0x06, 0x60, 0x74,
|
||||
0x34, 0x4e, 0x38, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2,
|
||||
0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x79, 0xc6, 0x8a,
|
||||
0xe3, 0xae, 0xf7, 0xaf, 0x3a, 0xb6, 0xe4, 0xd3, 0xdd, 0x69, 0x6a, 0x24, 0x45, 0x6e, 0x16, 0x97, 0x1c, 0x3e, 0xb8,
|
||||
0x34, 0x46, 0xf3, 0xd2, 0x73, 0x3f, 0x83, 0x89, 0xd2, 0x0c, 0x5a, 0x95, 0x79, 0x68, 0x8d, 0x99, 0x66, 0xad, 0xfc,
|
||||
0x2d, 0x15, 0xfb, 0x2b, 0xce, 0x6d, 0x15, 0x95, 0x82, 0x9d, 0xae, 0x31, 0x31, 0x3b, 0xd5, 0x7a, 0xe3, 0x66, 0x40,
|
||||
0x34, 0x8b, 0xc0, 0x2f, 0x94, 0x52, 0x55, 0x33, 0xce, 0x37, 0x27, 0xe3, 0x35, 0x3f, 0x63, 0x58, 0x7f, 0x92, 0x2a,
|
||||
0x4e, 0xbd, 0x43, 0x10, 0x6e, 0xc6, 0xc3, 0x86, 0x31, 0xd8, 0xb8, 0xe0, 0x39, 0x48, 0xf1, 0xa0, 0x49, 0xec, 0x14,
|
||||
0x25, 0x1b, 0xf1, 0x2d, 0x6f, 0x1a, 0x96, 0xb2, 0x0c, 0x08, 0x86, 0x9b, 0x9f, 0xfa, 0xe5, 0x1a, 0x00, 0xb6, 0x54,
|
||||
0x35, 0xcd, 0x4a, 0xb2, 0x93, 0x6e, 0x09, 0xb4, 0xb1, 0x61, 0x4c, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13,
|
||||
0x71, 0x37, 0x1a, 0x49, 0x4d, 0xdb, 0x04, 0x30, 0x03, 0xcb, 0xf5, 0x5e, 0xe4, 0xbc, 0x0e, 0xcf, 0x6f, 0x40, 0x4d,
|
||||
0xfa, 0x18, 0x32, 0x71, 0x77, 0x86, 0x99, 0x1d, 0xb7, 0xb6, 0x34, 0x8a, 0x42, 0x0e, 0x08, 0x86, 0x14, 0x50, 0x2e,
|
||||
0x67, 0x22, 0x47, 0x1e, 0x39, 0xfb, 0x7d, 0x35, 0xc4, 0x12, 0x18, 0x0e, 0x30, 0x86, 0x19, 0xfb, 0x76, 0x16, 0x19,
|
||||
0x6d, 0x8c, 0x75, 0x95, 0x23, 0x69, 0x48, 0x28, 0xfd, 0x9b, 0x0b, 0x64, 0x91, 0xe6, 0x92, 0xd3, 0x1a, 0x8d, 0x5f,
|
||||
0x08, 0xa9, 0xee, 0x34, 0x8b, 0xe2, 0x71, 0x86, 0x8c, 0xf8, 0xa8, 0x27, 0x08, 0xd1, 0x00, 0x12, 0x77, 0xce, 0x0b,
|
||||
0xae, 0x05, 0x38, 0x38, 0x3b, 0x6f, 0xc8, 0xda, 0x82, 0x9c, 0x50, 0x72, 0x45, 0xaf, 0xad, 0x71, 0x4a, 0x6b, 0x19,
|
||||
0x6b, 0x7c, 0x1e, 0x6e, 0xe8, 0x87, 0xaa, 0x9b, 0xe5, 0x38, 0x9a, 0x22, 0x19, 0xd2, 0x9a, 0x94, 0x15, 0x70, 0x4c,
|
||||
0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b,
|
||||
0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0xd6, 0xbc, 0xf5, 0x83, 0xf1, 0xfe,
|
||||
0xde, 0xf5, 0xd8, 0xae, 0xf8, 0xb3, 0x54, 0x9d, 0x69, 0x55, 0x8b, 0x2b, 0xa9, 0x5e, 0x78, 0xaf, 0x24, 0x05, 0x58,
|
||||
0x70, 0x69, 0xcd, 0x88, 0xc4, 0x0f, 0x4f, 0x68, 0xc6, 0x43, 0x2f, 0xa6, 0x92, 0xea, 0x6e, 0xb9, 0x77, 0x74, 0xae,
|
||||
0x8c, 0xfd, 0x9f, 0x79, 0xc4, 0xe1, 0x7a, 0x07, 0x6c, 0x38, 0x40, 0xdd, 0xf9, 0x1c, 0x6d, 0x19, 0xc8, 0xf1, 0xe0,
|
||||
0x18, 0xc2, 0xa5, 0xf2, 0x5f, 0xde, 0x70, 0x37, 0x1c, 0x82, 0x56, 0x5e, 0xde, 0x09, 0x70, 0x48, 0xad, 0xb8, 0x73,
|
||||
0xe7, 0x90, 0x36, 0x88, 0x4d, 0x68, 0x32, 0x0b, 0x1d, 0x77, 0x71, 0x9a, 0x21, 0x1c, 0x12, 0x3a, 0x4e, 0x82, 0x34,
|
||||
0xc7, 0xfa, 0xa9, 0x2b, 0x10, 0xa1, 0x6b, 0x9b, 0x11, 0xdb, 0x82, 0x42, 0x91, 0x02, 0x88, 0xe4, 0xba, 0x5f, 0x57,
|
||||
0xd9, 0xac, 0x30, 0x98, 0x05, 0xa8, 0x2c, 0x4d, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54,
|
||||
0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a,
|
||||
0x49, 0x4d, 0xc5, 0xb5, 0x00, 0xde, 0x7e, 0x5c, 0xfe, 0x18, 0xec, 0xaa, 0x55, 0x85, 0xcb, 0x66, 0x55, 0x52, 0xad,
|
||||
0xcb, 0x74, 0x28, 0x93, 0x85, 0xd8, 0x94, 0x97, 0x4d, 0x64, 0x6e, 0xd8, 0xfe, 0x99, 0x3a, 0x57, 0x1d, 0x51, 0xc1,
|
||||
0xea, 0xdd, 0xd2, 0x38, 0xdd, 0x3d, 0xba, 0x2a, 0x71, 0x96, 0xa2, 0x97, 0xa6, 0x00, 0xc9, 0xc6, 0x65, 0xbb, 0xc6,
|
||||
0x27, 0xd6, 0x04, 0x49, 0x3a, 0x5c, 0xb3, 0xb0, 0x05, 0x05, 0xea, 0x70, 0x92, 0xe7, 0xf2, 0x43, 0x67, 0x49, 0x6b,
|
||||
0x96, 0x0f, 0x95, 0x7a, 0x15, 0x3a, 0x4f, 0x0f, 0xf5, 0xf6, 0xf1, 0x51, 0xe7, 0x12, 0x83, 0x8d, 0x2a, 0xad, 0xb3,
|
||||
0x29, 0x0b, 0x66, 0x20, 0x30, 0xf5, 0x8f, 0xb9, 0x81, 0x61, 0x2d, 0xb4, 0x44, 0xe7, 0x89, 0x89, 0x1b, 0x4b, 0xb8,
|
||||
0x90, 0x2d, 0x54, 0xa7, 0x8e, 0x58, 0x6c, 0x3c, 0xe1, 0x31, 0xba, 0x3e, 0xbf, 0xe2, 0xb4, 0x5c, 0x01, 0x00, 0x00,
|
||||
0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a,
|
||||
0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x72, 0xdc, 0xc0, 0xee, 0x8c, 0x48, 0x9a, 0x30, 0x4b,
|
||||
0x5f, 0xfc, 0x54, 0xe7, 0x0b, 0xc7, 0x1d, 0xfc, 0x66, 0x27, 0x13, 0x6d, 0x4d, 0x0c, 0x15, 0x76, 0x71, 0x51, 0xf3,
|
||||
0x25, 0xfd, 0x2c, 0x37, 0xf7, 0xc0, 0xce, 0xcc, 0xa3, 0x90, 0x0b, 0xbd, 0x5e, 0x6e, 0x09, 0x8a, 0xde, 0x6f, 0x9c,
|
||||
0x6d, 0xdc, 0xf1, 0xeb, 0x6b, 0xd0, 0x3d, 0x38, 0x8c, 0xd0, 0xbf, 0xaf, 0xbf, 0xe2, 0xb3, 0x95, 0x4f, 0x4e, 0x11,
|
||||
0x43, 0xe0, 0x90, 0x60, 0xca, 0x61, 0xc5, 0xab, 0xfc, 0xd5, 0x19, 0x02, 0xe6, 0xee, 0x32, 0xd3, 0x93, 0xc1, 0x6c,
|
||||
0x69, 0x07, 0xba, 0x37, 0x7a, 0x55, 0xed, 0xb3, 0xda, 0xbf, 0x3a, 0x56, 0x67, 0xbb, 0x94, 0xc3, 0x70, 0x3e, 0xf6,
|
||||
0x35, 0xdf, 0x5d, 0xf6, 0xec, 0x4c, 0x76, 0x88, 0x22, 0xcb, 0xb8, 0x87, 0x6f, 0x73, 0x48, 0xc5, 0xae, 0x2f, 0x89,
|
||||
0x18, 0xab, 0x89, 0x0c, 0x4e, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d,
|
||||
0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x62,
|
||||
0x6e, 0xaf, 0x1e, 0xc0, 0xc8, 0xa0, 0x0f, 0x41, 0x9c, 0x9a, 0x41, 0x06, 0xeb, 0x2e, 0xe5, 0x1a, 0xf4, 0x0d, 0x48,
|
||||
0x40, 0x95, 0x0e, 0xb0, 0xbb, 0xc3, 0x0c, 0x66, 0x7a, 0xd9, 0xb4, 0x0c, 0x5b, 0x03, 0x93, 0xa6, 0xa8, 0x9a, 0xea,
|
||||
0x96, 0x44, 0xcb, 0x12, 0xae, 0x40, 0x60, 0x03, 0xfc, 0xb7, 0x1b, 0x2d, 0xa0, 0x12, 0xd3, 0x30, 0x74, 0x66, 0xcc,
|
||||
0xa4, 0xfa, 0xca, 0x5b, 0x20, 0x25, 0x7f, 0x66, 0x6d, 0xad, 0x3a, 0x65, 0x13, 0xc3, 0x51, 0x00, 0x54, 0x5c, 0x61,
|
||||
0x0c, 0x76, 0xb7, 0x8b, 0xe6, 0x97, 0xb1, 0x94, 0x78, 0x4d, 0x2c, 0x33, 0xc7, 0xf0, 0x09, 0xba, 0x2d, 0xf5, 0x60,
|
||||
0x6d, 0x86, 0x75, 0x71, 0xed, 0xc9, 0x73, 0x2d, 0x73, 0x2d, 0x8a, 0xfb, 0x53, 0xa3, 0x1a, 0xc0, 0xe6, 0x8c, 0xd0,
|
||||
0x6f, 0x98, 0xfc, 0x00, 0xfe, 0x8e, 0xd9, 0x2a, 0x39, 0x5c, 0xef, 0x79, 0x1b, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda,
|
||||
0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x1b, 0x0e, 0xb3, 0x6e, 0xec, 0x41, 0x47, 0x9c, 0x86, 0x65, 0xba, 0x43,
|
||||
0xfd, 0xef, 0xb4, 0x42, 0xca, 0x96, 0x39, 0xec, 0x62, 0x22, 0x73, 0xf7, 0xed, 0xd3, 0x27, 0xef, 0x57, 0x7f, 0x9b,
|
||||
0x61, 0x98, 0x00, 0x63, 0xbb, 0x4f, 0x68, 0x42, 0x1e, 0xe3, 0xea, 0x08, 0xf3, 0xa4, 0xe2, 0x9e, 0x71, 0x0a, 0x45,
|
||||
0x90, 0x7f, 0x93, 0x18, 0x1d, 0x1e, 0xf1, 0x47, 0x79, 0x91, 0xe4, 0x73, 0xbf, 0x5f, 0x7e, 0xcb, 0x83, 0xde, 0xde,
|
||||
0x88, 0xa7, 0xe0, 0x65, 0x01, 0x5b, 0x94, 0x64, 0xa8, 0x12, 0xb3, 0xde, 0x22, 0x82, 0x62, 0x5d, 0x30, 0x11, 0xc7,
|
||||
0x7a, 0xa8, 0xa0, 0xd6, 0xab, 0x70, 0x88, 0x59, 0x92, 0x3f, 0xf2, 0x6b, 0x25, 0xbb, 0x11, 0xb8, 0xda, 0x29, 0x5e,
|
||||
0xde, 0x29, 0xf0, 0x50, 0x8d, 0xf2, 0x76, 0x05, 0xc0, 0xb8, 0x9f, 0xa1, 0xe7, 0x7e, 0x85, 0x07, 0xfa, 0xda, 0xed,
|
||||
0x97, 0x0a, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58,
|
||||
0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x0e, 0xa5, 0x09, 0x60,
|
||||
0x5e, 0xeb, 0xb2, 0x0a, 0xda, 0x15, 0x84, 0xad, 0xd7, 0xf2, 0x0e, 0x1a, 0xce, 0x93, 0xea, 0xfa, 0x1d, 0xf5, 0xfb,
|
||||
0x2d, 0x45, 0x02, 0x26, 0x89, 0xf5, 0x4a, 0x1f, 0x4a, 0x4b, 0x39, 0xfb, 0xdd, 0x38, 0xef, 0x39, 0x55, 0x55, 0xdf,
|
||||
0xc4, 0x5e, 0x23, 0x83, 0x02, 0x48, 0x60, 0xf7, 0x1b, 0xcc, 0xe8, 0x6f, 0x86, 0xdf, 0x0e, 0xcf, 0xa1, 0x3d, 0x6e,
|
||||
0xd4, 0xb4, 0x20, 0x5d, 0xee, 0xf2, 0xe7, 0x78, 0xb8, 0x40, 0xf7, 0xad, 0xe2, 0x81, 0xe7, 0xfa, 0x26, 0x92, 0x0f,
|
||||
0x24, 0x87, 0xc9, 0x44, 0x5f, 0x90, 0x9d, 0x25, 0xaa, 0xb7, 0x95, 0x76, 0x89, 0x53, 0xd5, 0x5f, 0xe8, 0xa6, 0x59,
|
||||
0xba, 0x77, 0xf1, 0x05, 0xe8, 0x2e, 0x5d, 0x24, 0x31, 0x59, 0xf8, 0x13, 0x02, 0xfe, 0x9e, 0x22, 0x7b, 0xa7, 0xb1,
|
||||
0xa1, 0xba, 0xb0, 0xb7, 0xbd, 0xd1, 0x12, 0x38, 0x99, 0x61, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54,
|
||||
0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71,
|
||||
0x37, 0x1a, 0x49, 0x4d, 0xb2, 0xcc, 0xab, 0x2f, 0x02, 0xe8, 0x24, 0xdd, 0x52, 0xf7, 0xe4, 0x98, 0x90, 0x56, 0x66,
|
||||
0x7c, 0xef, 0x7c, 0x42, 0xf3, 0x4a, 0x71, 0x47, 0x18, 0x17, 0x8c, 0x37, 0xac, 0x03, 0xde, 0xf7, 0x55, 0x75, 0xd4,
|
||||
0x7a, 0x60, 0x4e, 0xc3, 0xd0, 0xc4, 0xd4, 0x29, 0xd6, 0xc2, 0x5a, 0x10, 0x42, 0x98, 0x1f, 0xcd, 0x91, 0xe2, 0xe5,
|
||||
0xc3, 0x62, 0x26, 0x01, 0xda, 0x4b, 0xde, 0xf2, 0x37, 0xab, 0x37, 0x30, 0xaf, 0x44, 0x39, 0xb0, 0xa0, 0xa1, 0x84,
|
||||
0xbb, 0x01, 0x51, 0x77, 0x94, 0x9f, 0x1f, 0x67, 0x92, 0x39, 0x00, 0x69, 0x7a, 0x68, 0x79, 0xf4, 0x8e, 0x28, 0xde,
|
||||
0xe0, 0x4f, 0x0a, 0x4d, 0x00, 0xf0, 0xc3, 0xf8, 0x2a, 0xd3, 0x5e, 0xc2, 0x92, 0x9d, 0x1f, 0x7e, 0x77, 0x88, 0x25,
|
||||
0x9e, 0xd7, 0xaa, 0x95, 0xbd, 0x5a, 0x85, 0x61, 0x54, 0x41, 0xad, 0x8f, 0x8f, 0x02, 0x6b, 0xd5, 0x8d, 0x40, 0x01,
|
||||
0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06,
|
||||
0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0xc0, 0xb2, 0x14, 0x11, 0x7c, 0xd7, 0xd4,
|
||||
0x99, 0xa2, 0xd1, 0x3f, 0xf2, 0xf9, 0x9c, 0x7e, 0xd9, 0x72, 0x9b, 0x8b, 0x73, 0xeb, 0x6c, 0x2b, 0xc0, 0x16, 0x3b,
|
||||
0x8d, 0xa3, 0x36, 0x95, 0xfa, 0x44, 0xd9, 0xd8, 0x58, 0xfd, 0x23, 0x67, 0x7f, 0xa2, 0xc4, 0x67, 0x69, 0xbb, 0x18,
|
||||
0x52, 0xc8, 0x38, 0xef, 0xad, 0x36, 0x79, 0x0e, 0x43, 0x17, 0x87, 0x3d, 0x1e, 0x6e, 0xf7, 0x06, 0xa5, 0xc2, 0x10,
|
||||
0x55, 0x73, 0x3a, 0x04, 0x3a, 0x32, 0x33, 0xde, 0x21, 0x54, 0xbf, 0xde, 0xd0, 0x5f, 0x2d, 0xe8, 0x3a, 0x6f, 0x9b,
|
||||
0xcb, 0x59, 0x32, 0x95, 0xb7, 0x63, 0xea, 0x6a, 0x07, 0x64, 0xa7, 0x6f, 0x3d, 0x55, 0x2a, 0x89, 0x52, 0xda, 0x87,
|
||||
0xbf, 0xaa, 0xd4, 0xbf, 0x97, 0xc0, 0xea, 0xfc, 0xc3, 0x2f, 0x2f, 0xcf, 0x8f, 0xf5, 0x7d, 0xfe, 0x0f, 0xf3, 0x13,
|
||||
0x23, 0x91, 0x76, 0xa8, 0xc5, 0x61, 0x5a, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55,
|
||||
0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49,
|
||||
0x4d, 0x5c, 0xbf, 0x5f, 0xe9, 0x15, 0x89, 0xfb, 0xdb, 0xaf, 0x98, 0x7b, 0x9c, 0x9d, 0x4f, 0x11, 0xba, 0xaf, 0x71,
|
||||
0x71, 0xc8, 0x09, 0x4e, 0xaa, 0xbe, 0x20, 0x14, 0x24, 0xc8, 0x5d, 0xa1, 0x18, 0x3b, 0xf6, 0x48, 0xd9, 0x1a, 0x75,
|
||||
0x26, 0x54, 0xcf, 0xe7, 0xbe, 0xab, 0x24, 0x8f, 0x0c, 0x9c, 0xca, 0x23, 0x33, 0xb6, 0xd6, 0x42, 0x65, 0x37, 0x5f,
|
||||
0x35, 0xe9, 0x06, 0xe3, 0x0f, 0xb6, 0x73, 0x1e, 0x4f, 0x5e, 0x94, 0x44, 0x6e, 0xdf, 0xe1, 0x2a, 0x17, 0x97, 0x9a,
|
||||
0xa1, 0x19, 0x1b, 0x3f, 0xa3, 0x25, 0x7a, 0xf1, 0x51, 0xfa, 0xdd, 0x5f, 0x80, 0x35, 0xcc, 0x90, 0x2b, 0x8e, 0xa7,
|
||||
0x5b, 0x4d, 0x9d, 0x0f, 0x13, 0xc7, 0xa6, 0x87, 0x8a, 0xce, 0xe4, 0x45, 0xf9, 0xdc, 0xbf, 0xe8, 0xbc, 0xc1, 0x5b,
|
||||
0xfa, 0x51, 0x81, 0xa9, 0x7b, 0x26, 0xa9, 0xdd, 0xa8, 0xdf, 0xcf, 0x29, 0xb3, 0xbe, 0x14, 0x01, 0x00, 0x00, 0x00,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1,
|
||||
0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x4d, 0x90, 0x6a, 0xf7, 0xb0, 0xff, 0x6a, 0xac, 0xaf, 0x33,
|
||||
0xf0, 0x2d, 0x6c, 0x58, 0x3e, 0x8d, 0x45, 0x5f, 0x8b, 0xd9, 0x08, 0x69, 0x0e, 0x8d, 0x4f, 0x07, 0x87, 0x5b, 0xdb,
|
||||
0x17, 0xb9, 0x4e, 0xcb, 0x48, 0x41, 0x0c, 0x88, 0xa8, 0x23, 0x79, 0x4a, 0x9d, 0x9a, 0x31, 0x72, 0xe3, 0x1b, 0xd4,
|
||||
0x4d, 0xc5, 0xb1, 0x90, 0xdb, 0x9b, 0xef, 0x03, 0xff, 0x11, 0x42, 0x29, 0xb6, 0xc6, 0xc2, 0x1e, 0x70, 0x80, 0xaf,
|
||||
0xea, 0x0a, 0xd3, 0x2d, 0xb9, 0xea, 0x6e, 0xbd, 0x5c, 0xac, 0x97, 0xa9, 0x08, 0x7d, 0x51, 0xb3, 0x72, 0x62, 0x70,
|
||||
0x4f, 0x19, 0xa9, 0xee, 0xe4, 0xc7, 0x06, 0x3f, 0xe3, 0x3d, 0x1e, 0x02, 0x0e, 0xb5, 0x57, 0x3f, 0x14, 0x23, 0xda,
|
||||
0x5b, 0xf3, 0xf3, 0xf6, 0x62, 0x4e, 0x33, 0x72, 0x41, 0x4d, 0xb1, 0x87, 0xa6, 0xee, 0x68, 0x62, 0xb1, 0x71, 0x7e,
|
||||
0xb8, 0xa9, 0xa7, 0x6f, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e,
|
||||
0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0xa9, 0x53,
|
||||
0x42, 0x6f, 0xe4, 0x79, 0xbd, 0xc7, 0x37, 0x51, 0xc9, 0xe6, 0xfe, 0x9b, 0x63, 0x03, 0x25, 0xdb, 0xb6, 0xf9, 0xdb,
|
||||
0x80, 0x91, 0x01, 0x3f, 0xdd, 0xee, 0xe9, 0x9e, 0x60, 0xa6, 0x37, 0x43, 0x16, 0x9b, 0x92, 0x8b, 0xf9, 0xd9, 0x21,
|
||||
0xa7, 0xf9, 0x05, 0x21, 0x00, 0xaa, 0x35, 0x9c, 0x08, 0xa5, 0x66, 0xba, 0xcb, 0xe3, 0x45, 0xfd, 0x8e, 0xbb, 0x5e,
|
||||
0x97, 0x2a, 0xf9, 0x99, 0x6c, 0x8f, 0x92, 0xe8, 0x7d, 0x4f, 0x6d, 0x9c, 0x6d, 0xae, 0x17, 0xe1, 0x16, 0xde, 0x03,
|
||||
0x35, 0x01, 0x76, 0xe6, 0x5a, 0x3b, 0x45, 0xb5, 0x43, 0x21, 0x59, 0xa9, 0x87, 0x38, 0x2f, 0x07, 0x94, 0x60, 0x26,
|
||||
0xb9, 0xd2, 0xb5, 0xe3, 0x3b, 0x57, 0xa0, 0xb0, 0xb6, 0xfe, 0x10, 0x2e, 0xb6, 0xbd, 0xdf, 0x24, 0xe1, 0xc3, 0x8c,
|
||||
0xbb, 0x08, 0x62, 0x84, 0x7e, 0x37, 0x25, 0x5c, 0xd1, 0x65, 0xf2, 0x45, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8,
|
||||
0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x4f, 0x72, 0x7c, 0xfb, 0xb3, 0x7d, 0x0e, 0xa5, 0x2f, 0x39, 0x76, 0x80, 0xff,
|
||||
0x08, 0xac, 0xe7, 0x21, 0x18, 0x3f, 0x03, 0xab, 0xb2, 0xde, 0x9c, 0x83, 0x47, 0xa7, 0x90, 0x1e, 0x2c, 0xa3, 0x11,
|
||||
0x14, 0x4e, 0x27, 0x52, 0x70, 0x56, 0xa6, 0x87, 0x1a, 0x45, 0x52, 0xf4, 0x9f, 0xed, 0x73, 0xb2, 0xa2, 0x01, 0x55,
|
||||
0xbd, 0x6a, 0x32, 0xd4, 0x15, 0x2e, 0x7e, 0x05, 0xbb, 0xb5, 0x27, 0x46, 0x58, 0x49, 0x2b, 0xab, 0x60, 0x30, 0xbb,
|
||||
0x6d, 0x8a, 0xd8, 0x85, 0x78, 0x25, 0x19, 0x8a, 0x9d, 0xc9, 0x3e, 0xf2, 0xb0, 0x65, 0x1b, 0xe2, 0xfd, 0x30, 0x66,
|
||||
0x4b, 0xb5, 0x6b, 0xfd, 0x7e, 0xe3, 0x1c, 0x31, 0x08, 0xa6, 0xb2, 0xda, 0x48, 0x8d, 0xeb, 0xb0, 0xac, 0xf0, 0xf5,
|
||||
0x6e, 0xe5, 0x4b, 0xc7, 0xf9, 0xfb, 0xca, 0xbd, 0x8c, 0x4e, 0x28, 0xa1, 0xe9, 0xf6, 0x7f, 0x12, 0xd3, 0x5d, 0x88,
|
||||
0x0b, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5,
|
||||
0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x8b, 0x4e, 0xfd, 0x3f, 0x25,
|
||||
0xc1, 0xc0, 0x59, 0x5a, 0xd5, 0x46, 0xa0, 0x79, 0x62, 0x4e, 0x29, 0xc6, 0x1f, 0x75, 0x8a, 0x8c, 0x82, 0x5e, 0x15,
|
||||
0x72, 0xd5, 0x58, 0x66, 0x81, 0x74, 0x9c, 0x40, 0x1d, 0x98, 0x69, 0x66, 0xf6, 0xcb, 0x81, 0x16, 0xd4, 0xa4, 0xbc,
|
||||
0x13, 0xd6, 0x85, 0x54, 0x5d, 0xb3, 0x1b, 0x28, 0xa3, 0x56, 0x36, 0x46, 0xf6, 0xc2, 0x98, 0x24, 0xbb, 0x35, 0xfe,
|
||||
0xa2, 0x6a, 0x0b, 0xb7, 0x27, 0x6c, 0xb4, 0xda, 0x41, 0x1b, 0x37, 0x2f, 0x76, 0x99, 0x63, 0x28, 0x79, 0xc0, 0xc5,
|
||||
0x38, 0x5d, 0xf2, 0x16, 0x23, 0x40, 0xa5, 0xb7, 0x36, 0x5a, 0xd1, 0x91, 0x4a, 0xbe, 0x6f, 0x76, 0x8e, 0x06, 0x8f,
|
||||
0x7c, 0x29, 0x10, 0x51, 0x6a, 0x42, 0xde, 0x5b, 0xed, 0x80, 0x38, 0xf4, 0xf3, 0xf2, 0x5c, 0x76, 0xf2, 0x78, 0xbd,
|
||||
0x0d, 0x0c, 0xe8, 0x78, 0x68, 0xfc, 0x7c, 0x9c, 0x55, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d,
|
||||
0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37,
|
||||
0x1a, 0x49, 0x4d, 0x65, 0xfe, 0xff, 0xbf, 0x05, 0x2f, 0x3c, 0x1e, 0x02, 0xfa, 0x35, 0x81, 0xef, 0x42, 0xb9, 0xa8,
|
||||
0x5f, 0x6d, 0x50, 0xaf, 0x80, 0x74, 0xb5, 0x76, 0xad, 0xd0, 0x5a, 0xc0, 0x44, 0xb0, 0x49, 0x2a, 0x1c, 0x35, 0x33,
|
||||
0x93, 0x5f, 0x00, 0x08, 0x49, 0x94, 0xb7, 0xab, 0x66, 0xd3, 0xd7, 0xcc, 0xfe, 0x68, 0x9e, 0xf0, 0xae, 0x7e, 0x26,
|
||||
0x1d, 0x4a, 0x85, 0xf7, 0x0c, 0xaa, 0xd6, 0x4f, 0x0c, 0x6a, 0xde, 0xd6, 0x8b, 0xb8, 0xc0, 0xbe, 0x0b, 0xab, 0x9a,
|
||||
0x3f, 0xe4, 0x8a, 0x1c, 0x1b, 0x81, 0x1b, 0x8d, 0x6e, 0xeb, 0xa3, 0xac, 0x44, 0x9a, 0x51, 0x29, 0x50, 0x2d, 0x93,
|
||||
0xa0, 0x23, 0xb8, 0x30, 0x33, 0x15, 0xe0, 0x11, 0x8b, 0x6e, 0xe3, 0x6f, 0x62, 0xc1, 0xba, 0x8b, 0x25, 0xac, 0xd3,
|
||||
0x13, 0x47, 0xee, 0xc5, 0x56, 0x62, 0x9e, 0xbd, 0x5e, 0x03, 0xdb, 0x78, 0xde, 0x5e, 0xf9, 0xb9, 0x4e, 0x01, 0x00,
|
||||
0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0,
|
||||
0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x00, 0x00, 0x00, 0xd0, 0x87, 0x1a, 0x49, 0x23,
|
||||
0x54, 0x58, 0x48, 0x00, 0x80, 0x87, 0x16, 0x01, 0xa0, 0xbd, 0x8c, 0x8b, 0x01, 0x1a, 0xdc, 0xfc, 0x0f, 0xe2, 0x98,
|
||||
0xa5, 0x10, 0x78, 0x25, 0x6f, 0x9b, 0x99, 0x99, 0x59, 0x82, 0xef, 0x3b, 0xc0, 0xa7, 0xd6, 0x7c, 0xb6, 0x5e, 0xe0,
|
||||
0xd5, 0x9b, 0x31, 0x32, 0xf2, 0xf9, 0xde, 0x89, 0xa6, 0x89, 0x90, 0x6d, 0xa8, 0x10, 0xb0, 0x71, 0x7a, 0x1e, 0x85,
|
||||
0xb0, 0x81, 0x18, 0x2a, 0x71, 0xb1, 0x7b, 0xbd, 0x29, 0xdc, 0x08, 0x0e, 0xc6, 0xc5, 0xfd, 0x4d, 0xce, 0x87, 0x98,
|
||||
0xd2, 0xe6, 0x0f, 0x11, 0x2f, 0x7e, 0xf0, 0xe0, 0xd8, 0x47, 0x1d, 0x04, 0xc6, 0x9b, 0xde, 0x35, 0x20, 0x57, 0x3e,
|
||||
0xd4, 0x57, 0xb8, 0x20, 0x9d, 0x95, 0xae, 0xb6, 0x21, 0x82, 0xac, 0xde, 0xdd, 0x9b, 0x60, 0x94, 0xe9, 0x4b, 0xb4,
|
||||
0x59, 0xef, 0x06, 0xa7, 0xe4, 0x65, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57,
|
||||
0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d,
|
||||
0x00, 0x00, 0x00, 0x30, 0xc2, 0x35, 0xb2, 0xc0, 0xe8, 0x0e, 0x8a, 0xaf, 0x28, 0x09, 0x1e, 0x7e, 0x9e, 0x37, 0x96,
|
||||
0x87, 0x92, 0x36, 0x29, 0xd7, 0x70, 0xd5, 0x84, 0xef, 0xb7, 0x50, 0x42, 0x00, 0xcd, 0xcc, 0xcc, 0x04, 0x5a, 0x14,
|
||||
0xea, 0x45, 0xb8, 0x82, 0x05, 0x94, 0x10, 0x12, 0xd3, 0x2e, 0x7d, 0x94, 0x1b, 0x04, 0x9a, 0x3c, 0x6d, 0xa5, 0x6c,
|
||||
0xbb, 0xbd, 0x4e, 0x34, 0xe1, 0xe0, 0x16, 0xcb, 0x55, 0x94, 0x0a, 0x7a, 0x18, 0xa0, 0xdd, 0x7b, 0x74, 0xd0, 0x54,
|
||||
0x3c, 0xb9, 0xcd, 0x54, 0xd0, 0x97, 0xfd, 0xfa, 0xd5, 0x19, 0xe9, 0x34, 0x4e, 0x6c, 0xa1, 0xea, 0xf3, 0x7f, 0x31,
|
||||
0x5e, 0xf8, 0x88, 0xbe, 0xec, 0x02, 0xf0, 0xce, 0x75, 0xdb, 0x51, 0xfa, 0x68, 0x41, 0x49, 0x10, 0x03, 0xab, 0xff,
|
||||
0x7f, 0x3a, 0xf5, 0x29, 0xa9, 0x1c, 0xc3, 0x3d, 0x5f, 0x4d, 0x66, 0x9b, 0x65, 0x04, 0x01, 0x00, 0x00, 0x00, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc,
|
||||
0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x00, 0x00, 0x00, 0x24, 0x7a, 0x63, 0x86, 0x07, 0x09, 0xeb, 0x71,
|
||||
0x66, 0xa4, 0x43, 0x09, 0xeb, 0xbc, 0x2d, 0x8c, 0x2c, 0xae, 0xeb, 0x7e, 0xde, 0xbf, 0x45, 0x0a, 0x22, 0x91, 0x27,
|
||||
0x00, 0x00, 0x67, 0x66, 0x66, 0x76, 0xa0, 0x3c, 0xc5, 0xd4, 0xd2, 0xcf, 0xd3, 0x0d, 0x97, 0x92, 0x52, 0x7c, 0xf8,
|
||||
0x5c, 0x73, 0x4d, 0xc5, 0x31, 0x62, 0x40, 0x76, 0xe7, 0xb5, 0xfb, 0xaa, 0x68, 0x8e, 0x45, 0xc2, 0xf6, 0xff, 0x3b,
|
||||
0xf3, 0x53, 0xd0, 0x30, 0x9b, 0x29, 0x1d, 0x86, 0x25, 0xbd, 0x0f, 0xf9, 0x53, 0x91, 0x10, 0x4c, 0xf5, 0x4a, 0xf3,
|
||||
0x13, 0x04, 0xf4, 0x79, 0x12, 0xc1, 0x4a, 0x58, 0x21, 0x3c, 0x74, 0xe0, 0x5d, 0x22, 0x2e, 0x60, 0x2a, 0xca, 0x3d,
|
||||
0x5f, 0xc2, 0xcb, 0xf2, 0x47, 0x71, 0xd0, 0xd6, 0x63, 0xca, 0xf3, 0xd0, 0xe8, 0x39, 0x99, 0x3b, 0xff, 0x06, 0x3e,
|
||||
0xe5, 0xcd, 0x6b, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2,
|
||||
0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x00, 0x00, 0x00,
|
||||
0xac, 0x99, 0x37, 0xb3, 0x60, 0xfa, 0x50, 0xcb, 0x16, 0x8f, 0x95, 0x6b, 0xcc, 0x70, 0x69, 0x74, 0x2e, 0x07, 0xd5,
|
||||
0x81, 0x98, 0xee, 0x16, 0x88, 0x9b, 0x17, 0x00, 0x00, 0x00, 0x34, 0x33, 0x33, 0xa9, 0x30, 0x56, 0xe3, 0x6e, 0x00,
|
||||
0xe2, 0x23, 0x99, 0x51, 0x52, 0x76, 0xe2, 0x4c, 0x35, 0xcc, 0xf4, 0xbe, 0x8b, 0x0f, 0xdf, 0xbf, 0xaa, 0x2a, 0xbb,
|
||||
0x59, 0x1f, 0xbe, 0x5c, 0xc0, 0x27, 0xda, 0x2d, 0x45, 0x2e, 0x95, 0x8f, 0xb7, 0x50, 0x74, 0xd9, 0xec, 0x14, 0xb8,
|
||||
0x4c, 0x0d, 0x7b, 0xc9, 0xe0, 0x02, 0xd1, 0x9e, 0x56, 0xc9, 0x27, 0xf7, 0xa8, 0xa6, 0xa1, 0xdc, 0x38, 0x3f, 0xff,
|
||||
0xf9, 0x30, 0xfa, 0x8c, 0xc8, 0xab, 0x60, 0x86, 0xf0, 0x52, 0xc4, 0x01, 0xc2, 0x9c, 0xb3, 0x42, 0x51, 0x52, 0x54,
|
||||
0x35, 0x83, 0x05, 0xb2, 0xd5, 0xc6, 0x9b, 0x7a, 0x43, 0xa6, 0x6c, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13,
|
||||
0x71, 0x37, 0x1a, 0x49, 0x4d, 0x00, 0x00, 0x00, 0xa5, 0xd1, 0xee, 0x7c, 0xd0, 0xba, 0xcb, 0x9d, 0x26, 0x7f, 0xd1,
|
||||
0xed, 0xba, 0xb3, 0x89, 0xf0, 0x52, 0xc2, 0x4f, 0x0c, 0xf0, 0x23, 0xdd, 0x15, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x9a,
|
||||
0x99, 0x99, 0xe5, 0x87, 0xd2, 0xdc, 0x99, 0xaf, 0xaf, 0x6f, 0xca, 0x7f, 0x10, 0x1c, 0x8b, 0x6e, 0xb8, 0xd8, 0xc5,
|
||||
0x9e, 0xd0, 0x03, 0xce, 0x57, 0x95, 0xbd, 0xcc, 0xba, 0x0f, 0x5f, 0x2e, 0xbf, 0x91, 0x50, 0x10, 0xfb, 0xe2, 0x60,
|
||||
0x0a, 0x57, 0xb1, 0xc7, 0xdb, 0xc3, 0x18, 0x08, 0x02, 0x48, 0xc8, 0xea, 0xa0, 0x46, 0x32, 0xaa, 0x31, 0x46, 0x05,
|
||||
0xbb, 0xbc, 0x03, 0x8d, 0xee, 0x36, 0xff, 0xa5, 0x22, 0x99, 0x0d, 0xd2, 0x0a, 0x51, 0x1a, 0x45, 0x34, 0x44, 0x68,
|
||||
0x5d, 0x72, 0xde, 0x20, 0x7d, 0xa1, 0xa1, 0x77, 0xce, 0xd3, 0xc1, 0x91, 0xa1, 0x29, 0x1e, 0xc6, 0xe3, 0x35, 0x14,
|
||||
0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b,
|
||||
0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x00, 0x00, 0x00, 0x83, 0x1e, 0x97,
|
||||
0x8a, 0xf6, 0x06, 0xe2, 0xcb, 0xfe, 0xa5, 0x10, 0x1f, 0x59, 0x8b, 0xd6, 0x2f, 0x75, 0xeb, 0x3d, 0xff, 0xdf, 0x6e,
|
||||
0x67, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0xcc, 0x4c, 0xbc, 0x97, 0xb3, 0x89, 0x2c, 0x3e, 0x8b, 0x8b, 0xaf,
|
||||
0x9b, 0x36, 0xe5, 0x38, 0x1c, 0x8d, 0x76, 0x2b, 0xf5, 0x49, 0xe6, 0x15, 0x6c, 0x21, 0xaf, 0x6e, 0xdd, 0x87, 0x2f,
|
||||
0x17, 0xee, 0x4e, 0x3a, 0xda, 0x8f, 0x49, 0x3f, 0xd1, 0xcc, 0xc1, 0xd6, 0x95, 0x9e, 0x09, 0x52, 0x40, 0xab, 0xac,
|
||||
0x43, 0xc0, 0x04, 0x7a, 0x13, 0x51, 0x40, 0xae, 0xd1, 0x27, 0x84, 0xee, 0xf6, 0x4e, 0x8e, 0xd8, 0x03, 0x5c, 0x37,
|
||||
0x93, 0x2c, 0x43, 0x49, 0xac, 0x48, 0xd9, 0xa0, 0x82, 0x6b, 0x9f, 0x73, 0x22, 0xc6, 0x35, 0x95, 0x41, 0x89, 0x43,
|
||||
0xb1, 0x1f, 0x04, 0xfa, 0x25, 0x24, 0x59, 0x31, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54,
|
||||
0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a,
|
||||
0x49, 0x4d, 0x00, 0x00, 0x40, 0xe4, 0x16, 0xab, 0x32, 0x30, 0xf2, 0x5a, 0x04, 0x1d, 0x4c, 0x5c, 0xea, 0xfe, 0x39,
|
||||
0xbb, 0xe4, 0x26, 0x4f, 0x5e, 0x35, 0xa6, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x66, 0x66, 0xdb,
|
||||
0x44, 0x0e, 0xbd, 0xc1, 0x9b, 0x8c, 0x59, 0xb7, 0xb9, 0xc3, 0xb0, 0x7d, 0x2a, 0x27, 0x26, 0x19, 0x9e, 0xa2, 0x35,
|
||||
0xe4, 0x38, 0x45, 0x2b, 0x4c, 0x98, 0x97, 0x8e, 0x45, 0xbb, 0xda, 0xd7, 0xf5, 0xdc, 0xf5, 0xee, 0x05, 0x0b, 0x14,
|
||||
0x99, 0x1d, 0x2c, 0x77, 0x0b, 0xa8, 0xe0, 0x4c, 0x30, 0xd5, 0xe7, 0x25, 0xa5, 0x00, 0x81, 0x5f, 0xbf, 0x8a, 0x0c,
|
||||
0x7c, 0xdd, 0x18, 0xb0, 0x6c, 0xf4, 0x8f, 0x59, 0x92, 0xf6, 0x79, 0xf6, 0x8d, 0x23, 0xf9, 0xaa, 0xc2, 0x33, 0xf1,
|
||||
0x15, 0xa6, 0x48, 0x92, 0x1c, 0xd8, 0x44, 0x2d, 0xe3, 0xdf, 0x33, 0x4c, 0xab, 0x74, 0x9b, 0x1a, 0x01, 0x00, 0x00,
|
||||
0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a,
|
||||
0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x00, 0x00, 0xc0, 0x5a, 0x43, 0x4f, 0x54, 0x90, 0x5b,
|
||||
0x8f, 0x29, 0xf1, 0xbe, 0xb3, 0x8e, 0xbf, 0x2b, 0x63, 0x9b, 0xa4, 0x6d, 0x29, 0xe3, 0xfd, 0x02, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x34, 0x33, 0x93, 0x51, 0xa5, 0xa4, 0x2f, 0xc2, 0xf4, 0x64, 0x4f, 0xb1, 0x7e, 0xa0, 0x7e,
|
||||
0xc7, 0x62, 0x51, 0xe8, 0xcd, 0xbb, 0xdf, 0x39, 0x36, 0x36, 0x64, 0xe4, 0xba, 0x75, 0x1f, 0xbe, 0x5c, 0x26, 0xa3,
|
||||
0x44, 0xc5, 0xda, 0xd1, 0xc0, 0x1f, 0x86, 0x3b, 0x67, 0x70, 0xe2, 0x82, 0x02, 0x91, 0x2b, 0x40, 0xb0, 0x46, 0xe2,
|
||||
0xcf, 0xe7, 0x51, 0x2b, 0x63, 0x28, 0xac, 0x8c, 0x0d, 0x7e, 0x2f, 0xce, 0x8f, 0x89, 0x09, 0xf4, 0x60, 0xb2, 0x30,
|
||||
0xa1, 0xfd, 0x80, 0xf7, 0xf8, 0x2d, 0xa8, 0xa8, 0x0f, 0x4d, 0x4e, 0xaa, 0x92, 0x83, 0x95, 0xa1, 0x6b, 0x2c, 0xb2,
|
||||
0x3e, 0x6f, 0x3e, 0x33, 0x5c, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d,
|
||||
0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x00,
|
||||
0x00, 0xd0, 0xb0, 0xb1, 0x11, 0x5d, 0x5f, 0x5d, 0xc3, 0x95, 0x1a, 0x6e, 0xc2, 0xfe, 0xd5, 0xed, 0x59, 0xd2, 0x9f,
|
||||
0x2b, 0xf7, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x99, 0x59, 0xbf, 0xae, 0x61, 0x76,
|
||||
0x5e, 0x8d, 0xfd, 0x9d, 0xc7, 0xb2, 0xa0, 0x04, 0x7f, 0xbb, 0x90, 0x38, 0xa3, 0x7e, 0x5e, 0x2c, 0xdf, 0x1c, 0x32,
|
||||
0x72, 0xdd, 0xba, 0x0f, 0x5f, 0x2e, 0x1a, 0xc0, 0x6a, 0xe1, 0x44, 0x05, 0x40, 0x61, 0xb6, 0x93, 0x2b, 0x00, 0x16,
|
||||
0x8a, 0x70, 0x5b, 0xbe, 0x39, 0x1f, 0x89, 0xbd, 0x8f, 0x95, 0xd9, 0xad, 0x4a, 0x11, 0xe6, 0x30, 0xc0, 0xdb, 0x53,
|
||||
0x2a, 0xb9, 0x1b, 0x91, 0x35, 0x4b, 0x6b, 0xe3, 0x17, 0xdf, 0x05, 0x6f, 0xfd, 0xd9, 0x0a, 0xc7, 0x4d, 0x05, 0x6d,
|
||||
0x5e, 0x2d, 0xc9, 0x42, 0x0f, 0x43, 0x96, 0x20, 0xf6, 0x13, 0xd5, 0x35, 0x2d, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda,
|
||||
0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x00, 0x00, 0x30, 0x32, 0x38, 0x7a, 0x48, 0x1a, 0x77, 0x0f, 0x63, 0xf3,
|
||||
0x88, 0x03, 0x96, 0xed, 0xc5, 0x2c, 0x20, 0xd4, 0xa5, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xcd, 0xcc, 0x84, 0x26, 0x24, 0x60, 0xdd, 0x3b, 0x8b, 0xb9, 0x0a, 0xa7, 0x81, 0xbc, 0x27, 0xda, 0x6d, 0xbc,
|
||||
0x60, 0x76, 0xd7, 0xe7, 0xa3, 0x70, 0x0e, 0x19, 0xb9, 0x6e, 0xdd, 0x87, 0x2f, 0x17, 0xa4, 0x2d, 0x51, 0x76, 0xad,
|
||||
0x02, 0x00, 0xd3, 0xd3, 0x9a, 0x21, 0x0c, 0x03, 0x85, 0xab, 0x50, 0x0b, 0xbf, 0x2d, 0x26, 0x8b, 0x88, 0x87, 0xdd,
|
||||
0xb0, 0xc1, 0xe5, 0x0f, 0x6a, 0xf8, 0xca, 0x23, 0x3a, 0xb0, 0xb8, 0xed, 0x03, 0xb6, 0x19, 0x17, 0xb2, 0xd7, 0xaf,
|
||||
0x25, 0x0f, 0xe8, 0x5d, 0x96, 0x88, 0x6b, 0xd7, 0x7f, 0xe0, 0xb0, 0x41, 0x57, 0xa1, 0x14, 0x1d, 0x55, 0x14, 0x63,
|
||||
0xdb, 0x2a, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58,
|
||||
0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x00, 0x00, 0x64, 0x7f,
|
||||
0x44, 0x75, 0xc4, 0x97, 0x37, 0x63, 0x51, 0x19, 0x64, 0xd6, 0x26, 0x62, 0xe4, 0x5c, 0xc4, 0xac, 0xa2, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x66, 0xf6, 0x93, 0xf5, 0xd8, 0x74, 0xee, 0xd7, 0xdd,
|
||||
0xc1, 0x95, 0x0c, 0x6d, 0x23, 0x58, 0x1b, 0x30, 0xd1, 0x7c, 0xdd, 0x80, 0xef, 0x51, 0x2b, 0x4b, 0x2b, 0x4c, 0x98,
|
||||
0x97, 0x8e, 0x45, 0xd3, 0x87, 0x93, 0x2f, 0xa7, 0x92, 0xea, 0x68, 0xc2, 0x30, 0x3c, 0x9d, 0xfc, 0xe5, 0x9a, 0xe5,
|
||||
0x63, 0x86, 0xfe, 0xd6, 0x66, 0x52, 0x9b, 0xc9, 0x7e, 0x85, 0xd7, 0x18, 0x5e, 0x6c, 0x19, 0x6d, 0x74, 0x08, 0x36,
|
||||
0xf3, 0xae, 0xf9, 0x4c, 0xa7, 0xa7, 0x41, 0xb5, 0x25, 0x15, 0x62, 0xff, 0xae, 0x96, 0x82, 0xd3, 0x78, 0xf7, 0x79,
|
||||
0x28, 0x91, 0xd6, 0xb7, 0xed, 0x30, 0xea, 0x73, 0x77, 0x25, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54,
|
||||
0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71,
|
||||
0x37, 0x1a, 0x49, 0x4d, 0x00, 0x00, 0xac, 0xba, 0x36, 0xd5, 0x4b, 0x79, 0xf3, 0x04, 0xf5, 0x8c, 0x51, 0xd7, 0x9c,
|
||||
0xc4, 0x42, 0x49, 0x0f, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x33,
|
||||
0x09, 0xd5, 0x70, 0xac, 0x80, 0x04, 0x8f, 0xd9, 0xd8, 0xe8, 0xa6, 0xb4, 0x00, 0x28, 0x46, 0x98, 0xca, 0xc7, 0xd2,
|
||||
0xac, 0x94, 0xc2, 0x39, 0x64, 0xe4, 0xba, 0x75, 0x1f, 0xbe, 0x5c, 0xcf, 0x90, 0x68, 0xf1, 0x6e, 0x4c, 0xca, 0x87,
|
||||
0x8f, 0x21, 0x48, 0xa0, 0x16, 0x8b, 0x99, 0xd9, 0x87, 0x24, 0x9b, 0x40, 0x22, 0xa8, 0x2f, 0x78, 0xa6, 0xa1, 0x66,
|
||||
0xe9, 0x3d, 0x18, 0x20, 0x3d, 0x8f, 0xe7, 0x2a, 0x62, 0x9d, 0x7a, 0x59, 0x9f, 0x19, 0xad, 0x4c, 0x22, 0xf7, 0xd8,
|
||||
0xff, 0x2f, 0xd1, 0x08, 0x62, 0xfa, 0xea, 0x32, 0xde, 0xeb, 0x34, 0xb7, 0x2f, 0xce, 0x59, 0xae, 0x58, 0x5e, 0x01,
|
||||
0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06,
|
||||
0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x00, 0x00, 0xb5, 0x26, 0x62, 0x47, 0xcf,
|
||||
0x65, 0x84, 0xa1, 0x99, 0xdc, 0x4d, 0x33, 0x06, 0x56, 0x18, 0xe9, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x99, 0x05, 0xdc, 0x12, 0x36, 0xab, 0x88, 0x30, 0xba, 0x5f, 0xa0, 0xfb,
|
||||
0x47, 0x07, 0x26, 0x35, 0x41, 0x2f, 0x9d, 0x69, 0x56, 0x4a, 0xe1, 0x1c, 0x32, 0x72, 0xdd, 0xba, 0x0f, 0x5f, 0x2e,
|
||||
0x8a, 0xde, 0x53, 0x36, 0x9b, 0x28, 0xd7, 0xc2, 0x9a, 0xe9, 0x54, 0x8f, 0x12, 0x82, 0x62, 0x7c, 0x80, 0x95, 0xb6,
|
||||
0xe4, 0xb6, 0x95, 0x68, 0x3a, 0x12, 0x91, 0xc6, 0x53, 0x8d, 0xb2, 0x5f, 0x00, 0x98, 0x26, 0x75, 0x9a, 0x48, 0x00,
|
||||
0x22, 0x78, 0xd9, 0x15, 0xe9, 0x48, 0x9c, 0x41, 0x43, 0x00, 0x86, 0x64, 0xcf, 0xef, 0x41, 0xe0, 0x64, 0xc8, 0x06,
|
||||
0xbd, 0xf3, 0x38, 0x14, 0x4d, 0xb4, 0x29, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55,
|
||||
0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49,
|
||||
0x4d, 0x00, 0x00, 0x03, 0xc6, 0x05, 0x53, 0x9b, 0xa2, 0x22, 0xa8, 0x0c, 0xfa, 0x63, 0x9c, 0xc2, 0x5e, 0x8d, 0x22,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0x4c, 0x74, 0x4a, 0xab,
|
||||
0x56, 0x10, 0x49, 0x78, 0xb6, 0xd1, 0x04, 0x5c, 0xb0, 0x7e, 0x50, 0x06, 0xcf, 0xb9, 0xce, 0x34, 0x2b, 0xa5, 0x70,
|
||||
0x0e, 0x19, 0xb9, 0x6e, 0xdd, 0x87, 0x2f, 0x17, 0xa3, 0xd0, 0xde, 0x7e, 0x48, 0x51, 0x64, 0x73, 0x21, 0x48, 0x05,
|
||||
0xf8, 0xb9, 0xaf, 0xa6, 0xc6, 0xfa, 0xf1, 0xaa, 0xea, 0xdc, 0x98, 0xbb, 0xb0, 0x67, 0xa5, 0xd0, 0x60, 0x25, 0x56,
|
||||
0x02, 0x04, 0x13, 0x70, 0x85, 0x7a, 0x7e, 0xf8, 0xf8, 0x6c, 0x77, 0xe5, 0x5b, 0x32, 0x93, 0xdd, 0x77, 0x1c, 0xa8,
|
||||
0x36, 0x1c, 0x19, 0x15, 0xd6, 0x65, 0x8a, 0x9f, 0x83, 0x4a, 0xdf, 0x0f, 0x3c, 0x5c, 0x71, 0x01, 0x00, 0x00, 0x00,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1,
|
||||
0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x00, 0x40, 0x58, 0x89, 0xea, 0xfc, 0xd4, 0xce, 0xe7, 0xab,
|
||||
0x47, 0x2a, 0x12, 0x95, 0x93, 0x9d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x67, 0x66, 0xa3, 0xab, 0x8c, 0xef, 0x89, 0x25, 0x47, 0x52, 0x2b, 0x9e, 0xa5, 0x3b, 0xf4, 0xbe,
|
||||
0xea, 0xe7, 0x2d, 0x6c, 0x9e, 0x81, 0xef, 0x51, 0x2b, 0x4b, 0x2b, 0x4c, 0x98, 0x97, 0x8e, 0x45, 0xce, 0xc3, 0x34,
|
||||
0xb3, 0x70, 0x4e, 0x4d, 0xbe, 0xc5, 0x5a, 0x0c, 0x13, 0x5b, 0xee, 0x07, 0xbf, 0x95, 0x12, 0x7e, 0xed, 0x4d, 0xa4,
|
||||
0x8e, 0xc1, 0x70, 0x34, 0x9e, 0x6a, 0x3b, 0x06, 0xa6, 0x65, 0x0f, 0x2c, 0x93, 0x88, 0xf7, 0xef, 0xc9, 0x9c, 0x0d,
|
||||
0xd3, 0xa8, 0x1f, 0x8b, 0xd7, 0x35, 0xe3, 0xcb, 0xa0, 0x72, 0x39, 0x0b, 0xa8, 0x5a, 0x6f, 0x95, 0xeb, 0x29, 0x88,
|
||||
0x52, 0x3e, 0x01, 0x12, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e,
|
||||
0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x00, 0xc0,
|
||||
0x8a, 0x2f, 0x82, 0xda, 0x05, 0x96, 0x7e, 0x40, 0x9e, 0xef, 0x9e, 0xdb, 0x4c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x93, 0x07, 0x17, 0x22, 0x7d, 0xc9, 0xe4,
|
||||
0xa3, 0x4b, 0x66, 0x4e, 0x3b, 0x84, 0x67, 0x34, 0x04, 0xe0, 0xe7, 0x3a, 0xd3, 0xac, 0x94, 0xc2, 0x39, 0x64, 0xe4,
|
||||
0xba, 0x75, 0x1f, 0xbe, 0x5c, 0x0d, 0x88, 0x5f, 0xf8, 0xac, 0x4e, 0xb4, 0x30, 0x5c, 0xc6, 0xff, 0x6c, 0x72, 0xb2,
|
||||
0xcf, 0x0b, 0x70, 0xaf, 0x96, 0x28, 0xa9, 0x31, 0xaf, 0xbc, 0x71, 0x72, 0xf3, 0xf2, 0x77, 0x8e, 0xac, 0x18, 0x59,
|
||||
0xc0, 0x96, 0x6f, 0xa6, 0xde, 0x5d, 0x3b, 0x9f, 0x66, 0x1f, 0x89, 0xf0, 0x8b, 0xe8, 0x62, 0xe1, 0x64, 0x16, 0x30,
|
||||
0xad, 0xff, 0xfd, 0xd9, 0x7f, 0xd8, 0xb0, 0x25, 0x9b, 0x02, 0xa4, 0x00, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8,
|
||||
0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x00, 0xd0, 0x69, 0x1e, 0xe4, 0x15, 0x78, 0x19, 0x0a, 0xda, 0x1f, 0xdf, 0xc2,
|
||||
0x56, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9a, 0x59, 0xe1, 0xb5, 0xf5, 0x60, 0x05, 0x8f, 0x81, 0xda, 0xfd, 0xe9, 0x29, 0x5a, 0x76, 0x21, 0x02, 0xf0, 0x73,
|
||||
0x9d, 0x69, 0x56, 0x4a, 0xe1, 0x1c, 0x32, 0x72, 0xdd, 0xba, 0x0f, 0x5f, 0x2e, 0xfd, 0xdf, 0x81, 0x19, 0x3c, 0xad,
|
||||
0xc6, 0x8b, 0x58, 0xfe, 0x51, 0x28, 0xb5, 0xf8, 0xdd, 0x10, 0x20, 0x61, 0x30, 0xb3, 0xb5, 0xf5, 0x76, 0x71, 0xa8,
|
||||
0xc3, 0x57, 0xe4, 0x0c, 0xda, 0x70, 0x11, 0x1e, 0xbd, 0x07, 0x1a, 0xc6, 0xa1, 0x7e, 0x7c, 0xf2, 0x1c, 0xd0, 0x90,
|
||||
0x6d, 0x8f, 0x21, 0x11, 0xde, 0x84, 0x40, 0xb2, 0x19, 0x13, 0x42, 0x9c, 0xf6, 0xc4, 0x72, 0xf5, 0x9e, 0x74, 0xbe,
|
||||
0x50, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5,
|
||||
0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x00, 0x30, 0x32, 0x71, 0x23,
|
||||
0x2e, 0xdd, 0x8b, 0xf5, 0xda, 0xc1, 0xf5, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0x04, 0x3e, 0x2b, 0xd5, 0x66, 0x7c, 0x0c, 0x14, 0xe9, 0xcd,
|
||||
0x52, 0x02, 0x82, 0xbf, 0x10, 0x01, 0xf8, 0xb9, 0xce, 0x34, 0x2b, 0xa5, 0x70, 0x0e, 0x19, 0xb9, 0x6e, 0xdd, 0x87,
|
||||
0x2f, 0x17, 0xc0, 0x5b, 0xf8, 0x94, 0x48, 0x19, 0xd1, 0x27, 0xe0, 0x36, 0x2a, 0x8e, 0xe7, 0x18, 0x70, 0x0f, 0xe1,
|
||||
0x8e, 0xf4, 0x48, 0x72, 0x5c, 0x8e, 0x9c, 0xfb, 0xb9, 0x62, 0xb7, 0xa6, 0x15, 0x84, 0x5e, 0x6f, 0x6b, 0x14, 0xb3,
|
||||
0x43, 0x24, 0xad, 0xe3, 0x9e, 0x76, 0x84, 0x7a, 0x92, 0x8d, 0x04, 0x40, 0x51, 0x73, 0x6b, 0x18, 0xc1, 0x91, 0x25,
|
||||
0x20, 0x40, 0x67, 0x02, 0x0e, 0x72, 0x76, 0x27, 0x6b, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d,
|
||||
0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37,
|
||||
0x1a, 0x49, 0x4d, 0x00, 0xa4, 0xd8, 0x1d, 0xa2, 0x5e, 0xa7, 0x37, 0x70, 0xad, 0xd1, 0x9c, 0x02, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x76, 0x60,
|
||||
0xee, 0x6c, 0x59, 0x24, 0x5c, 0x74, 0x80, 0x2a, 0x4d, 0x98, 0x95, 0x3e, 0x32, 0x03, 0xe8, 0x2d, 0x6c, 0x9e, 0x81,
|
||||
0xef, 0x51, 0x2b, 0x4b, 0x2b, 0x4c, 0x98, 0x97, 0x8e, 0x45, 0x22, 0x62, 0xe0, 0xd7, 0x4f, 0x07, 0xfe, 0x3a, 0x15,
|
||||
0x87, 0xb6, 0x74, 0x37, 0x21, 0xa4, 0x0a, 0x98, 0x5e, 0x28, 0x12, 0x77, 0xf1, 0x1f, 0x50, 0xd9, 0x8f, 0xf9, 0x40,
|
||||
0x41, 0x6f, 0x0f, 0x4b, 0x87, 0x7d, 0x5e, 0x14, 0x57, 0xf5, 0xe8, 0x74, 0xc4, 0xd4, 0x27, 0xfc, 0x86, 0xd9, 0x56,
|
||||
0x66, 0x17, 0xd6, 0x97, 0xe5, 0x69, 0x2a, 0x6b, 0x03, 0x85, 0x38, 0xda, 0x70, 0xb2, 0xf6, 0xdd, 0x52, 0x01, 0x00,
|
||||
0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0,
|
||||
0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x00, 0xac, 0x7f, 0x7a, 0x7f, 0xcc, 0x6b, 0x89,
|
||||
0xc3, 0x0c, 0x8f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x69, 0x13, 0xea, 0xec, 0xb4, 0x88, 0x9c, 0xa2, 0x9b, 0x58, 0x31, 0xcf, 0x1c,
|
||||
0xfe, 0x42, 0x04, 0xe0, 0xe7, 0x3a, 0xd3, 0xac, 0x94, 0xc2, 0x39, 0x64, 0xe4, 0xba, 0x75, 0x1f, 0xbe, 0x5c, 0x4c,
|
||||
0x07, 0x42, 0x14, 0x93, 0xe2, 0x83, 0x93, 0xa3, 0xa9, 0x72, 0x37, 0xa9, 0xb2, 0x58, 0xa7, 0x6a, 0x94, 0x53, 0xb5,
|
||||
0xeb, 0xad, 0x3b, 0x56, 0x46, 0x6b, 0x61, 0xa3, 0x8c, 0x14, 0x56, 0x32, 0xd4, 0x10, 0xf3, 0xf6, 0x64, 0x82, 0xef,
|
||||
0xb0, 0x24, 0xd2, 0xc2, 0x79, 0xde, 0xb0, 0x42, 0x9e, 0x65, 0x05, 0x88, 0x74, 0x2f, 0x8b, 0x58, 0xd5, 0x42, 0x1a,
|
||||
0x06, 0xa3, 0xd4, 0xd1, 0xfc, 0x12, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57,
|
||||
0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d,
|
||||
0x00, 0xc5, 0x1c, 0xd9, 0xfc, 0x35, 0x0a, 0xad, 0x17, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x25, 0x9e, 0xe6, 0xbc, 0xaf,
|
||||
0xb1, 0x88, 0x37, 0xd7, 0x97, 0x99, 0x67, 0x0e, 0x7f, 0x21, 0x02, 0xf0, 0x73, 0x9d, 0x69, 0x56, 0x4a, 0xe1, 0x1c,
|
||||
0x32, 0x72, 0xdd, 0xba, 0x0f, 0x5f, 0x2e, 0x5d, 0x53, 0x09, 0xab, 0xc2, 0x58, 0x42, 0x94, 0x15, 0x71, 0x15, 0x1b,
|
||||
0xfa, 0xfb, 0xcd, 0xc6, 0xbc, 0xa4, 0x00, 0x49, 0x74, 0xd3, 0x9c, 0x04, 0x81, 0xd7, 0x09, 0x28, 0x7d, 0x37, 0x37,
|
||||
0x58, 0x8a, 0x94, 0x1a, 0x79, 0x8a, 0x7e, 0x94, 0x29, 0xbd, 0xab, 0x65, 0x5f, 0xc6, 0x94, 0xed, 0xdd, 0x94, 0xc1,
|
||||
0xf1, 0xd8, 0xed, 0x88, 0x80, 0x47, 0x31, 0x52, 0xda, 0x94, 0x30, 0x60, 0xac, 0x0a, 0x01, 0x00, 0x00, 0x00, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc,
|
||||
0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x00, 0x83, 0x86, 0xfc, 0xaf, 0x41, 0xb9, 0x0e, 0x8e, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x4d, 0xac, 0x2d, 0x08, 0x88, 0xfd, 0x14, 0x1e, 0x24, 0x78, 0xcc, 0xcc, 0x33, 0x87, 0xbf, 0x10, 0x01,
|
||||
0xf8, 0xb9, 0xce, 0x34, 0x2b, 0xa5, 0x70, 0x0e, 0x19, 0xb9, 0x6e, 0xdd, 0x87, 0x2f, 0x17, 0xbb, 0xc3, 0xc0, 0xea,
|
||||
0xbd, 0x9b, 0xd6, 0x22, 0x75, 0x96, 0x6c, 0xca, 0xc1, 0x2b, 0x45, 0x76, 0x2e, 0x4e, 0x2b, 0xf7, 0xfa, 0x9e, 0x64,
|
||||
0x2d, 0x4b, 0xd8, 0xd9, 0x06, 0x24, 0xa3, 0xce, 0x49, 0x17, 0xd6, 0x83, 0xe8, 0x15, 0xc0, 0xbf, 0x4f, 0xf8, 0x85,
|
||||
0x9d, 0xaf, 0xb6, 0x85, 0x62, 0x31, 0x89, 0x06, 0x10, 0xd3, 0x0a, 0xf1, 0xd5, 0x03, 0x50, 0x2c, 0x1e, 0xf4, 0xa8,
|
||||
0xb6, 0x91, 0x2e, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2,
|
||||
0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x40, 0x0c, 0xab,
|
||||
0x80, 0x53, 0x26, 0xc2, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x6b, 0xbb, 0x49, 0x36, 0x72, 0x46, 0x68, 0x65,
|
||||
0x6a, 0x65, 0x66, 0x9b, 0x95, 0x3e, 0x32, 0x03, 0xe8, 0x2d, 0x6c, 0x9e, 0x81, 0xef, 0x51, 0x2b, 0x4b, 0x2b, 0x4c,
|
||||
0x98, 0x97, 0x8e, 0x45, 0x80, 0x00, 0x64, 0x53, 0xae, 0xef, 0x99, 0x13, 0xc9, 0x1c, 0x53, 0x45, 0x0c, 0xdc, 0x97,
|
||||
0xd5, 0x80, 0x4b, 0x56, 0x86, 0xa3, 0xbc, 0x78, 0xc4, 0xc2, 0x0c, 0xf7, 0xaf, 0xfd, 0x42, 0xe9, 0x1b, 0x5f, 0x2f,
|
||||
0xa6, 0x4f, 0xa5, 0x53, 0xb5, 0xec, 0x36, 0x50, 0xc6, 0xd1, 0x3f, 0xdf, 0xaf, 0x63, 0x9f, 0x25, 0x1d, 0x40, 0xd2,
|
||||
0xb5, 0x83, 0x24, 0x67, 0x57, 0x4d, 0x0c, 0x7b, 0x8c, 0x90, 0x3d, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13,
|
||||
0x71, 0x37, 0x1a, 0x49, 0x4d, 0xc0, 0xfa, 0x49, 0xea, 0x2a, 0x92, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94,
|
||||
0x9d, 0x8c, 0xc4, 0x08, 0x6c, 0x2a, 0x66, 0x32, 0xe3, 0x31, 0x33, 0xcf, 0x1c, 0xfe, 0x42, 0x04, 0xe0, 0xe7, 0x3a,
|
||||
0xd3, 0xac, 0x94, 0xc2, 0x39, 0x64, 0xe4, 0xba, 0x75, 0x1f, 0xbe, 0x5c, 0x57, 0x7e, 0xfd, 0x4b, 0xb2, 0xe8, 0x7d,
|
||||
0x9b, 0x0e, 0x3c, 0x51, 0xa9, 0x15, 0xcb, 0x9e, 0xfa, 0x45, 0x73, 0x63, 0x75, 0xac, 0xb6, 0x70, 0xff, 0xcb, 0x0a,
|
||||
0xb6, 0xd9, 0xd9, 0xf6, 0x7d, 0x5e, 0x31, 0x38, 0x8e, 0xff, 0x0c, 0xba, 0x37, 0xee, 0x71, 0x85, 0x91, 0xa1, 0xc8,
|
||||
0x13, 0x11, 0xc4, 0x7c, 0x0f, 0x6e, 0xca, 0x37, 0x32, 0xdb, 0x2a, 0x5a, 0xf3, 0x69, 0x45, 0x0f, 0x15, 0xe4, 0x1e,
|
||||
0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b,
|
||||
0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0xd0, 0xb2, 0x9d, 0x4f, 0x2c, 0x1e,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x83, 0xa6, 0xa4, 0x69, 0x0f, 0x33, 0x33, 0x99, 0xf1, 0x98, 0x99,
|
||||
0x67, 0x0e, 0x7f, 0x21, 0x02, 0xf0, 0x73, 0x9d, 0x69, 0x56, 0x4a, 0xe1, 0x1c, 0x32, 0x72, 0xdd, 0xba, 0x0f, 0x5f,
|
||||
0x2e, 0xa0, 0xbc, 0x92, 0xcb, 0x0d, 0xff, 0xd0, 0xea, 0x29, 0x6b, 0x52, 0x84, 0x98, 0xe7, 0xf8, 0xf0, 0xfb, 0x66,
|
||||
0xbe, 0x18, 0xab, 0x4c, 0x1b, 0x71, 0x16, 0xec, 0xb7, 0x81, 0x69, 0x77, 0xeb, 0x57, 0x47, 0xad, 0x0d, 0x3a, 0x20,
|
||||
0x42, 0x92, 0xf1, 0xc1, 0xd3, 0xef, 0x25, 0xf5, 0x26, 0x55, 0xc3, 0x98, 0x49, 0x24, 0xec, 0xbe, 0x30, 0x09, 0xa8,
|
||||
0x07, 0x14, 0x8f, 0xce, 0x6f, 0xdd, 0xa9, 0x71, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54,
|
||||
0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a,
|
||||
0x49, 0x4d, 0x30, 0xc2, 0xb2, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xed, 0x68, 0x0c,
|
||||
0x84, 0x99, 0x99, 0x99, 0xcc, 0x78, 0xcc, 0xcc, 0x33, 0x87, 0xbf, 0x10, 0x01, 0xf8, 0xb9, 0xce, 0x34, 0x2b, 0xa5,
|
||||
0x70, 0x0e, 0x19, 0xb9, 0x6e, 0xdd, 0x87, 0x2f, 0x17, 0x88, 0x7c, 0xf4, 0x83, 0xfd, 0x16, 0xf9, 0xf0, 0x1a, 0xcc,
|
||||
0xc4, 0xea, 0xf5, 0xba, 0x03, 0x19, 0x4a, 0x1b, 0x5d, 0x52, 0xe2, 0xfd, 0x78, 0xb1, 0x3d, 0xd3, 0x03, 0x25, 0x35,
|
||||
0x11, 0x34, 0x47, 0x4d, 0xd6, 0x17, 0x27, 0xbf, 0xde, 0x87, 0x2c, 0xde, 0x46, 0x07, 0xcd, 0x2f, 0xa1, 0x31, 0x26,
|
||||
0xe5, 0x8d, 0x87, 0xe1, 0xda, 0xac, 0xfe, 0x37, 0x97, 0x79, 0x72, 0xc7, 0x3f, 0x28, 0x4a, 0x5e, 0x01, 0x00, 0x00,
|
||||
0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a,
|
||||
0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0xe4, 0xc5, 0xbd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xf7, 0xec, 0x75, 0x26, 0xcc, 0xcc, 0xcc, 0xcc, 0x65, 0x6a, 0x65, 0x66, 0x9b, 0x95, 0x3e,
|
||||
0x32, 0x03, 0xe8, 0x2d, 0x6c, 0x9e, 0x81, 0xef, 0x51, 0x2b, 0x4b, 0x2b, 0x4c, 0x98, 0x97, 0x8e, 0x45, 0xb3, 0xc4,
|
||||
0x59, 0xb6, 0x35, 0x71, 0xaf, 0xe7, 0x73, 0x4c, 0x03, 0xe2, 0x69, 0x50, 0x19, 0x36, 0x65, 0x43, 0xd5, 0x33, 0x7f,
|
||||
0x31, 0xf1, 0x0e, 0x89, 0xa3, 0x4f, 0x55, 0xdd, 0xf3, 0x67, 0x57, 0xf1, 0xcb, 0xe8, 0x3c, 0x7f, 0x68, 0x6a, 0x29,
|
||||
0xe5, 0x60, 0x35, 0x3e, 0x72, 0x40, 0x3c, 0x8b, 0x39, 0x01, 0xa5, 0x9e, 0x73, 0x99, 0x7f, 0x87, 0x18, 0xb4, 0x68,
|
||||
0xc6, 0xd2, 0x7b, 0xa9, 0x71, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d,
|
||||
0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0xac,
|
||||
0x68, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xff, 0x91, 0x99, 0x65, 0x66, 0x66,
|
||||
0x66, 0x32, 0xe3, 0x31, 0x33, 0xcf, 0x1c, 0xfe, 0x42, 0x04, 0xe0, 0xe7, 0x3a, 0xd3, 0xac, 0x94, 0xc2, 0x39, 0x64,
|
||||
0xe4, 0xba, 0x75, 0x1f, 0xbe, 0x5c, 0x71, 0x02, 0x27, 0x40, 0x1d, 0xe1, 0x11, 0xee, 0x3b, 0xc9, 0x13, 0xe2, 0x90,
|
||||
0x29, 0xf8, 0x0b, 0x70, 0x4b, 0x7b, 0xfa, 0xd2, 0xd6, 0xf5, 0x8f, 0x45, 0xff, 0xc8, 0xc4, 0xc9, 0x4c, 0xf9, 0x5e,
|
||||
0x0e, 0x66, 0x85, 0x5f, 0x88, 0xff, 0xd3, 0xb6, 0xd8, 0x0a, 0x67, 0xd6, 0x91, 0x18, 0x5b, 0xe5, 0xc9, 0xa9, 0xd9,
|
||||
0x55, 0xb4, 0x30, 0xde, 0x83, 0xe5, 0x10, 0x9a, 0x05, 0x55, 0x53, 0xde, 0x55, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58, 0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda,
|
||||
0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0xd5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x46, 0xc8, 0xcc, 0xcc, 0x32, 0x33, 0x33, 0x33, 0x99, 0xf1, 0x98, 0x99, 0x67, 0x0e, 0x7f, 0x21, 0x02, 0xf0,
|
||||
0x73, 0x9d, 0x69, 0x56, 0x4a, 0xe1, 0x1c, 0x32, 0x72, 0xdd, 0xba, 0x0f, 0x5f, 0x2e, 0x01, 0x00, 0x00, 0xc0, 0xa9,
|
||||
0xaa, 0xaa, 0x6a, 0x54, 0xd4, 0x53, 0x15, 0x58, 0xd6, 0x6d, 0x37, 0x5a, 0x5b, 0xd4, 0x08, 0xb2, 0xb0, 0x9f, 0xd9,
|
||||
0x2c, 0x08, 0x7b, 0x3b, 0x0c, 0x84, 0x44, 0x6a, 0x08, 0x75, 0x50, 0x67, 0x4d, 0xe0, 0x04, 0xae, 0x38, 0x92, 0x4a,
|
||||
0x99, 0x8b, 0x1e, 0xbb, 0x5f, 0x89, 0x70, 0x45, 0x82, 0x02, 0xe8, 0xe3, 0xe9, 0xea, 0x60, 0x2a, 0xd0, 0xa1, 0xe3,
|
||||
0x59, 0x47, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x3d, 0x54, 0x55, 0x57, 0x6d, 0x7e, 0xe2, 0x58,
|
||||
0xe5, 0x6b, 0x06, 0xb0, 0x3a, 0xd1, 0xcc, 0xda, 0xa8, 0x13, 0x71, 0x37, 0x1a, 0x49, 0x4d, 0x03, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x66, 0x66, 0xe6, 0x98, 0x99, 0x99, 0x19, 0xcc, 0xa6,
|
||||
0xcb, 0x4c, 0x35, 0x59, 0x9e, 0xba, 0x03, 0xe4, 0x8a, 0xd3, 0x38, 0x17, 0x42, 0x8a, 0xb2, 0xd7, 0x87, 0x03, 0x87,
|
||||
0x5b, 0x26, 0x51, 0x01, 0x00, 0x00, 0x40, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xc4, 0xfe, 0x3f, 0x02, 0x3b, 0xce, 0xfe,
|
||||
0x03, 0x62, 0x39, 0x07, 0x06, 0x62, 0x6b, 0x26, 0xf6, 0x1d, 0x36, 0x5f, 0x7e, 0x3d, 0xf2, 0x56, 0x34, 0x33, 0x33,
|
||||
0x33, 0xcc, 0xcc, 0xcc, 0xcc, 0x65, 0x6a, 0x65, 0x66, 0x9b, 0x95, 0x3e, 0x32, 0x03, 0xe8, 0x2d, 0x6c, 0x9e, 0x81,
|
||||
0xef, 0x51, 0x2b, 0x4b, 0x2b, 0x4c, 0x98, 0x97, 0x8e, 0x45};
|
||||
unsigned int constants_2_len = 11904;
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,266 +0,0 @@
|
||||
#include "poseidon.cuh"
|
||||
|
||||
template <typename S>
|
||||
__global__ void
|
||||
prepare_poseidon_states(S* states, size_t number_of_states, S domain_tag, const PoseidonConfiguration<S> config)
|
||||
{
|
||||
int idx = (blockIdx.x * blockDim.x) + threadIdx.x;
|
||||
int state_number = idx / config.t;
|
||||
if (state_number >= number_of_states) { return; }
|
||||
int element_number = idx % config.t;
|
||||
|
||||
S prepared_element;
|
||||
|
||||
// Domain separation
|
||||
if (element_number == 0) {
|
||||
prepared_element = domain_tag;
|
||||
} else {
|
||||
prepared_element = states[state_number * config.t + element_number - 1];
|
||||
}
|
||||
|
||||
// Add pre-round constant
|
||||
prepared_element = prepared_element + config.round_constants[element_number];
|
||||
|
||||
// Store element in state
|
||||
states[idx] = prepared_element;
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
__device__ __forceinline__ S sbox_alpha_five(S element)
|
||||
{
|
||||
S result = S::sqr(element);
|
||||
result = S::sqr(result);
|
||||
return result * element;
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
__device__ S vecs_mul_matrix(S element, S* matrix, int element_number, int vec_number, int size, S* shared_states)
|
||||
{
|
||||
shared_states[threadIdx.x] = element;
|
||||
__syncthreads();
|
||||
|
||||
element = S::zero();
|
||||
for (int i = 0; i < size; i++) {
|
||||
element = element + (shared_states[vec_number * size + i] * matrix[i * size + element_number]);
|
||||
}
|
||||
__syncthreads();
|
||||
return element;
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
__device__ S full_round(
|
||||
S element,
|
||||
size_t rc_offset,
|
||||
int local_state_number,
|
||||
int element_number,
|
||||
bool multiply_by_mds,
|
||||
bool add_round_constant,
|
||||
S* shared_states,
|
||||
const PoseidonConfiguration<S> config)
|
||||
{
|
||||
element = sbox_alpha_five(element);
|
||||
if (add_round_constant) { element = element + config.round_constants[rc_offset + element_number]; }
|
||||
|
||||
// Multiply all the states by mds matrix
|
||||
S* matrix = multiply_by_mds ? config.mds_matrix : config.non_sparse_matrix;
|
||||
return vecs_mul_matrix(element, matrix, element_number, local_state_number, config.t, shared_states);
|
||||
}
|
||||
|
||||
// Execute full rounds
|
||||
template <typename S>
|
||||
__global__ void full_rounds(
|
||||
S* states, size_t number_of_states, size_t rc_offset, bool first_half, const PoseidonConfiguration<S> config)
|
||||
{
|
||||
extern __shared__ S shared_states[];
|
||||
|
||||
int idx = (blockIdx.x * blockDim.x) + threadIdx.x;
|
||||
int state_number = idx / config.t;
|
||||
if (state_number >= number_of_states) { return; }
|
||||
int local_state_number = threadIdx.x / config.t;
|
||||
int element_number = idx % config.t;
|
||||
|
||||
for (int i = 0; i < config.full_rounds_half - 1; i++) {
|
||||
states[idx] =
|
||||
full_round(states[idx], rc_offset, local_state_number, element_number, true, true, shared_states, config);
|
||||
rc_offset += config.t;
|
||||
}
|
||||
|
||||
states[idx] = full_round(
|
||||
states[idx], rc_offset, local_state_number, element_number, !first_half, first_half, shared_states, config);
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
__device__ S partial_round(S* state, size_t rc_offset, int round_number, const PoseidonConfiguration<S> config)
|
||||
{
|
||||
S element = state[0];
|
||||
element = sbox_alpha_five(element);
|
||||
element = element + config.round_constants[rc_offset];
|
||||
|
||||
S* sparse_matrix = &config.sparse_matrices[(config.t * 2 - 1) * round_number];
|
||||
|
||||
state[0] = element * sparse_matrix[0];
|
||||
for (int i = 1; i < config.t; i++) {
|
||||
state[0] = state[0] + (state[i] * sparse_matrix[i]);
|
||||
}
|
||||
|
||||
for (int i = 1; i < config.t; i++) {
|
||||
state[i] = state[i] + (element * sparse_matrix[config.t + i - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
// Execute partial rounds
|
||||
template <typename S>
|
||||
__global__ void
|
||||
partial_rounds(S* states, size_t number_of_states, size_t rc_offset, const PoseidonConfiguration<S> config)
|
||||
{
|
||||
int idx = (blockIdx.x * blockDim.x) + threadIdx.x;
|
||||
if (idx >= number_of_states) { return; }
|
||||
|
||||
S* state = &states[idx * config.t];
|
||||
|
||||
for (int i = 0; i < config.partial_rounds; i++) {
|
||||
partial_round(state, rc_offset, i, config);
|
||||
rc_offset++;
|
||||
}
|
||||
}
|
||||
|
||||
// These function is just doing copy from the states to the output
|
||||
template <typename S>
|
||||
__global__ void get_hash_results(S* states, size_t number_of_states, S* out, int t)
|
||||
{
|
||||
int idx = (blockIdx.x * blockDim.x) + threadIdx.x;
|
||||
if (idx >= number_of_states) { return; }
|
||||
|
||||
out[idx] = states[idx * t + 1];
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
__host__ void Poseidon<S>::hash_blocks(const S* inp, size_t blocks, S* out, HashType hash_type, cudaStream_t stream)
|
||||
{
|
||||
S* states;
|
||||
|
||||
// allocate memory for {blocks} states of {t} scalars each
|
||||
if (cudaMallocAsync(&states, blocks * this->t * sizeof(S), stream) != cudaSuccess) {
|
||||
throw std::runtime_error("Failed memory allocation on the device");
|
||||
}
|
||||
|
||||
// This is where the input matrix of size Arity x NumberOfBlocks is
|
||||
// padded and coppied to device in a T x NumberOfBlocks matrix
|
||||
cudaMemcpy2DAsync(
|
||||
states, this->t * sizeof(S), // Device pointer and device pitch
|
||||
inp, (this->t - 1) * sizeof(S), // Host pointer and pitch
|
||||
(this->t - 1) * sizeof(S), blocks, // Size of the source matrix (Arity x NumberOfBlocks)
|
||||
cudaMemcpyHostToDevice, stream);
|
||||
|
||||
size_t rc_offset = 0;
|
||||
|
||||
// The logic behind this is that 1 thread only works on 1 element
|
||||
// We have {t} elements in each state, and {blocks} states total
|
||||
int number_of_threads = (256 / this->t) * this->t;
|
||||
int hashes_per_block = number_of_threads / this->t;
|
||||
int total_number_of_threads = blocks * this->t;
|
||||
int number_of_blocks =
|
||||
total_number_of_threads / number_of_threads + static_cast<bool>(total_number_of_threads % number_of_threads);
|
||||
|
||||
// The partial rounds operates on the whole state, so we define
|
||||
// the parallelism params for processing a single hash preimage per thread
|
||||
int singlehash_block_size = 128;
|
||||
int number_of_singlehash_blocks = blocks / singlehash_block_size + static_cast<bool>(blocks % singlehash_block_size);
|
||||
|
||||
// Pick the domain_tag accordinaly
|
||||
S domain_tag;
|
||||
switch (hash_type) {
|
||||
case HashType::ConstInputLen:
|
||||
domain_tag = this->const_input_no_pad_domain_tag;
|
||||
break;
|
||||
|
||||
case HashType::MerkleTree:
|
||||
domain_tag = this->tree_domain_tag;
|
||||
}
|
||||
|
||||
#if !defined(__CUDA_ARCH__) && defined(DEBUG)
|
||||
auto start_time = std::chrono::high_resolution_clock::now();
|
||||
#endif
|
||||
|
||||
// Domain separation and adding pre-round constants
|
||||
prepare_poseidon_states<<<number_of_blocks, number_of_threads, 0, stream>>>(states, blocks, domain_tag, this->config);
|
||||
rc_offset += this->t;
|
||||
|
||||
#if !defined(__CUDA_ARCH__) && defined(DEBUG)
|
||||
cudaStreamSynchronize(stream);
|
||||
std::cout << "Domain separation: " << rc_offset << std::endl;
|
||||
// print_buffer_from_cuda<S>(states, blocks * this->t);
|
||||
|
||||
auto end_time = std::chrono::high_resolution_clock::now();
|
||||
auto elapsed_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
|
||||
std::cout << "Elapsed time: " << elapsed_time.count() << " ms" << std::endl;
|
||||
start_time = std::chrono::high_resolution_clock::now();
|
||||
#endif
|
||||
|
||||
// execute half full rounds
|
||||
full_rounds<<<number_of_blocks, number_of_threads, sizeof(S) * hashes_per_block* this->t, stream>>>(
|
||||
states, blocks, rc_offset, true, this->config);
|
||||
rc_offset += this->t * this->config.full_rounds_half;
|
||||
|
||||
#if !defined(__CUDA_ARCH__) && defined(DEBUG)
|
||||
cudaStreamSynchronize(stream);
|
||||
std::cout << "Full rounds 1. RCOFFSET: " << rc_offset << std::endl;
|
||||
// print_buffer_from_cuda<S>(states, blocks * this->t);
|
||||
|
||||
end_time = std::chrono::high_resolution_clock::now();
|
||||
elapsed_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
|
||||
std::cout << "Elapsed time: " << elapsed_time.count() << " ms" << std::endl;
|
||||
start_time = std::chrono::high_resolution_clock::now();
|
||||
#endif
|
||||
|
||||
// execute partial rounds
|
||||
partial_rounds<<<number_of_singlehash_blocks, singlehash_block_size, 0, stream>>>(
|
||||
states, blocks, rc_offset, this->config);
|
||||
rc_offset += this->config.partial_rounds;
|
||||
|
||||
#if !defined(__CUDA_ARCH__) && defined(DEBUG)
|
||||
cudaStreamSynchronize(stream);
|
||||
std::cout << "Partial rounds. RCOFFSET: " << rc_offset << std::endl;
|
||||
// print_buffer_from_cuda<S>(states, blocks * this->t);
|
||||
|
||||
end_time = std::chrono::high_resolution_clock::now();
|
||||
elapsed_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
|
||||
std::cout << "Elapsed time: " << elapsed_time.count() << " ms" << std::endl;
|
||||
start_time = std::chrono::high_resolution_clock::now();
|
||||
#endif
|
||||
|
||||
// execute half full rounds
|
||||
full_rounds<<<number_of_blocks, number_of_threads, sizeof(S) * hashes_per_block* this->t, stream>>>(
|
||||
states, blocks, rc_offset, false, this->config);
|
||||
|
||||
#if !defined(__CUDA_ARCH__) && defined(DEBUG)
|
||||
cudaStreamSynchronize(stream);
|
||||
std::cout << "Full rounds 2. RCOFFSET: " << rc_offset << std::endl;
|
||||
// print_buffer_from_cuda<S>(states, blocks * this->t);
|
||||
end_time = std::chrono::high_resolution_clock::now();
|
||||
elapsed_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
|
||||
std::cout << "Elapsed time: " << elapsed_time.count() << " ms" << std::endl;
|
||||
start_time = std::chrono::high_resolution_clock::now();
|
||||
#endif
|
||||
|
||||
// get output
|
||||
S* out_device;
|
||||
cudaMalloc(&out_device, blocks * sizeof(S));
|
||||
get_hash_results<<<number_of_singlehash_blocks, singlehash_block_size, 0, stream>>>(
|
||||
states, blocks, out_device, this->config.t);
|
||||
|
||||
#if !defined(__CUDA_ARCH__) && defined(DEBUG)
|
||||
cudaStreamSynchronize(stream);
|
||||
std::cout << "Get hash results" << std::endl;
|
||||
end_time = std::chrono::high_resolution_clock::now();
|
||||
elapsed_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
|
||||
std::cout << "Elapsed time: " << elapsed_time.count() << " ms" << std::endl;
|
||||
#endif
|
||||
cudaMemcpyAsync(out, out_device, blocks * sizeof(S), cudaMemcpyDeviceToHost, stream);
|
||||
cudaFreeAsync(out_device, stream);
|
||||
cudaFreeAsync(states, stream);
|
||||
|
||||
#if !defined(__CUDA_ARCH__) && defined(DEBUG)
|
||||
cudaDeviceReset();
|
||||
#endif
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
#pragma once
|
||||
#include "constants.cuh"
|
||||
|
||||
#if !defined(__CUDA_ARCH__) && defined(DEBUG)
|
||||
#include <chrono>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
template <typename S>
|
||||
__host__ void print_buffer_from_cuda(S* device_ptr, size_t size, size_t t)
|
||||
{
|
||||
S* buffer = static_cast<S*>(malloc(size * sizeof(S)));
|
||||
cudaMemcpy(buffer, device_ptr, size * sizeof(S), cudaMemcpyDeviceToHost);
|
||||
|
||||
std::cout << "Start print" << std::endl;
|
||||
for (int i = 0; i < size / t; i++) {
|
||||
std::cout << "State #" << i << std::endl;
|
||||
for (int j = 0; j < t; j++) {
|
||||
std::cout << buffer[i * t + j] << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
free(buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
template <typename S>
|
||||
__device__ void print_scalar(S element, int data)
|
||||
{
|
||||
printf(
|
||||
"D# %d, T# %d: 0x%08x%08x%08x%08x%08x%08x%08x%08x\n", data, threadIdx.x, element.limbs_storage.limbs[0],
|
||||
element.limbs_storage.limbs[1], element.limbs_storage.limbs[2], element.limbs_storage.limbs[3],
|
||||
element.limbs_storage.limbs[4], element.limbs_storage.limbs[5], element.limbs_storage.limbs[6],
|
||||
element.limbs_storage.limbs[7]);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename S>
|
||||
struct PoseidonConfiguration {
|
||||
uint32_t partial_rounds, full_rounds_half, t;
|
||||
S *round_constants, *mds_matrix, *non_sparse_matrix, *sparse_matrices;
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
class Poseidon
|
||||
{
|
||||
public:
|
||||
uint32_t t;
|
||||
PoseidonConfiguration<S> config;
|
||||
|
||||
enum HashType {
|
||||
ConstInputLen,
|
||||
MerkleTree,
|
||||
};
|
||||
|
||||
Poseidon(const uint32_t arity, cudaStream_t stream)
|
||||
{
|
||||
t = arity + 1;
|
||||
this->config.t = t;
|
||||
this->stream = stream;
|
||||
|
||||
// Pre-calculate domain tags
|
||||
// Domain tags will vary for different applications of Poseidon
|
||||
uint32_t tree_domain_tag_value = 1;
|
||||
tree_domain_tag_value = (tree_domain_tag_value << arity) - tree_domain_tag_value;
|
||||
tree_domain_tag = S::from(tree_domain_tag_value);
|
||||
|
||||
const_input_no_pad_domain_tag = S::one();
|
||||
|
||||
// TO-DO: implement binary shifts for scalar type
|
||||
// const_input_no_pad_domain_tag = S::one() << 64;
|
||||
// const_input_no_pad_domain_tag *= S::from(arity);
|
||||
|
||||
this->config.full_rounds_half = FULL_ROUNDS_DEFAULT;
|
||||
this->config.partial_rounds = partial_rounds_number_from_arity(arity);
|
||||
|
||||
uint32_t round_constants_len = t * this->config.full_rounds_half * 2 + this->config.partial_rounds;
|
||||
uint32_t mds_matrix_len = t * t;
|
||||
uint32_t sparse_matrices_len = (t * 2 - 1) * this->config.partial_rounds;
|
||||
|
||||
// All the constants are stored in a single file
|
||||
S* constants = load_constants<S>(arity);
|
||||
|
||||
S* mds_offset = constants + round_constants_len;
|
||||
S* non_sparse_offset = mds_offset + mds_matrix_len;
|
||||
S* sparse_matrices_offset = non_sparse_offset + mds_matrix_len;
|
||||
|
||||
#if !defined(__CUDA_ARCH__) && defined(DEBUG)
|
||||
std::cout << "P: " << this->config.partial_rounds << " F: " << this->config.full_rounds_half << std::endl;
|
||||
#endif
|
||||
|
||||
// Create streams for copying constants
|
||||
cudaStream_t stream_copy_round_constants, stream_copy_mds_matrix, stream_copy_non_sparse,
|
||||
stream_copy_sparse_matrices;
|
||||
cudaStreamCreate(&stream_copy_round_constants);
|
||||
cudaStreamCreate(&stream_copy_mds_matrix);
|
||||
cudaStreamCreate(&stream_copy_non_sparse);
|
||||
cudaStreamCreate(&stream_copy_sparse_matrices);
|
||||
|
||||
// Create events for copying constants
|
||||
cudaEvent_t event_copied_round_constants, event_copy_mds_matrix, event_copy_non_sparse, event_copy_sparse_matrices;
|
||||
cudaEventCreateWithFlags(&event_copied_round_constants, cudaEventDisableTiming);
|
||||
cudaEventCreateWithFlags(&event_copy_mds_matrix, cudaEventDisableTiming);
|
||||
cudaEventCreateWithFlags(&event_copy_non_sparse, cudaEventDisableTiming);
|
||||
cudaEventCreateWithFlags(&event_copy_sparse_matrices, cudaEventDisableTiming);
|
||||
|
||||
// Malloc memory for copying constants
|
||||
cudaMallocAsync(&this->config.round_constants, sizeof(S) * round_constants_len, stream_copy_round_constants);
|
||||
cudaMallocAsync(&this->config.mds_matrix, sizeof(S) * mds_matrix_len, stream_copy_mds_matrix);
|
||||
cudaMallocAsync(&this->config.non_sparse_matrix, sizeof(S) * mds_matrix_len, stream_copy_non_sparse);
|
||||
cudaMallocAsync(&this->config.sparse_matrices, sizeof(S) * sparse_matrices_len, stream_copy_sparse_matrices);
|
||||
|
||||
// Copy constants
|
||||
cudaMemcpyAsync(
|
||||
this->config.round_constants, constants, sizeof(S) * round_constants_len, cudaMemcpyHostToDevice,
|
||||
stream_copy_round_constants);
|
||||
cudaMemcpyAsync(
|
||||
this->config.mds_matrix, mds_offset, sizeof(S) * mds_matrix_len, cudaMemcpyHostToDevice, stream_copy_mds_matrix);
|
||||
cudaMemcpyAsync(
|
||||
this->config.non_sparse_matrix, non_sparse_offset, sizeof(S) * mds_matrix_len, cudaMemcpyHostToDevice,
|
||||
stream_copy_non_sparse);
|
||||
cudaMemcpyAsync(
|
||||
this->config.sparse_matrices, sparse_matrices_offset, sizeof(S) * sparse_matrices_len, cudaMemcpyHostToDevice,
|
||||
stream_copy_sparse_matrices);
|
||||
|
||||
// Record finished copying event for streams
|
||||
cudaEventRecord(event_copied_round_constants, stream_copy_round_constants);
|
||||
cudaEventRecord(event_copy_mds_matrix, stream_copy_mds_matrix);
|
||||
cudaEventRecord(event_copy_non_sparse, stream_copy_non_sparse);
|
||||
cudaEventRecord(event_copy_sparse_matrices, stream_copy_sparse_matrices);
|
||||
|
||||
// Main stream waits for copying to finish
|
||||
cudaStreamWaitEvent(stream, event_copied_round_constants);
|
||||
cudaStreamWaitEvent(stream, event_copy_mds_matrix);
|
||||
cudaStreamWaitEvent(stream, event_copy_non_sparse);
|
||||
cudaStreamWaitEvent(stream, event_copy_sparse_matrices);
|
||||
}
|
||||
|
||||
~Poseidon()
|
||||
{
|
||||
cudaFreeAsync(this->config.round_constants, this->stream);
|
||||
cudaFreeAsync(this->config.mds_matrix, this->stream);
|
||||
cudaFreeAsync(this->config.non_sparse_matrix, this->stream);
|
||||
cudaFreeAsync(this->config.sparse_matrices, this->stream);
|
||||
}
|
||||
|
||||
// Hash multiple preimages in parallel
|
||||
void hash_blocks(const S* inp, size_t blocks, S* out, HashType hash_type, cudaStream_t stream);
|
||||
|
||||
private:
|
||||
S tree_domain_tag, const_input_no_pad_domain_tag;
|
||||
cudaStream_t stream;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,135 +1,113 @@
|
||||
#ifndef VEC_MULT
|
||||
#define VEC_MULT
|
||||
#pragma once
|
||||
#include <cuda.h>
|
||||
#include <stdexcept>
|
||||
#include <cuda.h>
|
||||
|
||||
|
||||
#define MAX_THREADS_PER_BLOCK 256
|
||||
|
||||
/**
|
||||
* Multiply the elements of an input array by a scalar in-place.
|
||||
* @param arr input array.
|
||||
* @param n size of arr.
|
||||
* @param n_inv scalar of type S (scalar).
|
||||
*/
|
||||
template <typename E, typename S>
|
||||
__global__ void template_normalize_kernel(E* arr, uint32_t n, S scalar)
|
||||
{
|
||||
int tid = (blockIdx.x * blockDim.x) + threadIdx.x;
|
||||
if (tid < n) { arr[tid] = scalar * arr[tid]; }
|
||||
}
|
||||
|
||||
// TODO: headers for prototypes and .c .cpp .cu files for implementations
|
||||
template <typename E, typename S>
|
||||
__global__ void vectorModMult(S* scalar_vec, E* element_vec, E* result, size_t n_elments)
|
||||
__global__ void vectorModMult(S *scalar_vec, E *element_vec, E *result, size_t n_elments)
|
||||
{
|
||||
int tid = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
if (tid < n_elments) { result[tid] = scalar_vec[tid] * element_vec[tid]; }
|
||||
int tid = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
if (tid < n_elments)
|
||||
{
|
||||
result[tid] = scalar_vec[tid] * element_vec[tid];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename E, typename S>
|
||||
int vector_mod_mult(S* vec_a, E* vec_b, E* result, size_t n_elments, cudaStream_t stream) // TODO: in place so no need
|
||||
// for third result vector
|
||||
int vector_mod_mult(S *vec_a, E *vec_b, E *result, size_t n_elments) // TODO: in place so no need for third result vector
|
||||
{
|
||||
// Set the grid and block dimensions
|
||||
int num_blocks = (int)ceil((float)n_elments / MAX_THREADS_PER_BLOCK);
|
||||
int threads_per_block = MAX_THREADS_PER_BLOCK;
|
||||
// Set the grid and block dimensions
|
||||
int num_blocks = (int)ceil((float)n_elments / MAX_THREADS_PER_BLOCK);
|
||||
int threads_per_block = MAX_THREADS_PER_BLOCK;
|
||||
|
||||
// Allocate memory on the device for the input vectors, the output vector, and the modulus
|
||||
S* d_vec_a;
|
||||
E *d_vec_b, *d_result;
|
||||
cudaMallocAsync(&d_vec_a, n_elments * sizeof(S), stream);
|
||||
cudaMallocAsync(&d_vec_b, n_elments * sizeof(E), stream);
|
||||
cudaMallocAsync(&d_result, n_elments * sizeof(E), stream);
|
||||
// Allocate memory on the device for the input vectors, the output vector, and the modulus
|
||||
S *d_vec_a;
|
||||
E *d_vec_b, *d_result;
|
||||
cudaMalloc(&d_vec_a, n_elments * sizeof(S));
|
||||
cudaMalloc(&d_vec_b, n_elments * sizeof(E));
|
||||
cudaMalloc(&d_result, n_elments * sizeof(E));
|
||||
|
||||
// Copy the input vectors and the modulus from the host to the device
|
||||
cudaMemcpyAsync(d_vec_a, vec_a, n_elments * sizeof(S), cudaMemcpyHostToDevice, stream);
|
||||
cudaMemcpyAsync(d_vec_b, vec_b, n_elments * sizeof(E), cudaMemcpyHostToDevice, stream);
|
||||
// Copy the input vectors and the modulus from the host to the device
|
||||
cudaMemcpy(d_vec_a, vec_a, n_elments * sizeof(S), cudaMemcpyHostToDevice);
|
||||
cudaMemcpy(d_vec_b, vec_b, n_elments * sizeof(E), cudaMemcpyHostToDevice);
|
||||
|
||||
// Call the kernel to perform element-wise modular multiplication
|
||||
vectorModMult<<<num_blocks, threads_per_block, 0, stream>>>(d_vec_a, d_vec_b, d_result, n_elments);
|
||||
// Call the kernel to perform element-wise modular multiplication
|
||||
vectorModMult<<<num_blocks, threads_per_block>>>(d_vec_a, d_vec_b, d_result, n_elments);
|
||||
|
||||
cudaMemcpyAsync(result, d_result, n_elments * sizeof(E), cudaMemcpyDeviceToHost, stream);
|
||||
cudaMemcpy(result, d_result, n_elments * sizeof(E), cudaMemcpyDeviceToHost);
|
||||
|
||||
cudaFreeAsync(d_vec_a, stream);
|
||||
cudaFreeAsync(d_vec_b, stream);
|
||||
cudaFreeAsync(d_result, stream);
|
||||
cudaFree(d_vec_a);
|
||||
cudaFree(d_vec_b);
|
||||
cudaFree(d_result);
|
||||
|
||||
cudaStreamSynchronize(stream);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename E, typename S>
|
||||
int vector_mod_mult_device(
|
||||
S* d_vec_a, E* d_vec_b, E* d_result, size_t n_elments) // TODO: in place so no need for third result vector
|
||||
__global__ void batchVectorMult(S *scalar_vec, E *element_vec, unsigned n_scalars, unsigned batch_size)
|
||||
{
|
||||
// Set the grid and block dimensions
|
||||
int num_blocks = (int)ceil((float)n_elments / MAX_THREADS_PER_BLOCK);
|
||||
int threads_per_block = MAX_THREADS_PER_BLOCK;
|
||||
|
||||
// Call the kernel to perform element-wise modular multiplication
|
||||
vectorModMult<<<num_blocks, threads_per_block>>>(d_vec_a, d_vec_b, d_result, n_elments);
|
||||
return 0;
|
||||
int tid = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
if (tid < n_scalars * batch_size)
|
||||
{
|
||||
int scalar_id = tid % n_scalars;
|
||||
element_vec[tid] = scalar_vec[scalar_id] * element_vec[tid];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename E, typename S>
|
||||
__global__ void batchVectorMult(S* scalar_vec, E* element_vec, unsigned n_scalars, unsigned batch_size)
|
||||
int batch_vector_mult(S *scalar_vec, E *element_vec, unsigned n_scalars, unsigned batch_size)
|
||||
{
|
||||
int tid = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
if (tid < n_scalars * batch_size) {
|
||||
int scalar_id = tid % n_scalars;
|
||||
element_vec[tid] = scalar_vec[scalar_id] * element_vec[tid];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename E, typename S>
|
||||
int batch_vector_mult(S* scalar_vec, E* element_vec, unsigned n_scalars, unsigned batch_size, cudaStream_t stream)
|
||||
{
|
||||
// Set the grid and block dimensions
|
||||
int NUM_THREADS = MAX_THREADS_PER_BLOCK;
|
||||
int NUM_BLOCKS = (n_scalars * batch_size + NUM_THREADS - 1) / NUM_THREADS;
|
||||
batchVectorMult<<<NUM_BLOCKS, NUM_THREADS, 0, stream>>>(scalar_vec, element_vec, n_scalars, batch_size);
|
||||
return 0;
|
||||
// Set the grid and block dimensions
|
||||
int NUM_THREADS = MAX_THREADS_PER_BLOCK;
|
||||
int NUM_BLOCKS = (n_scalars * batch_size + NUM_THREADS - 1) / NUM_THREADS;
|
||||
batchVectorMult<<<NUM_BLOCKS, NUM_THREADS>>>(scalar_vec, element_vec, n_scalars, batch_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename E>
|
||||
__global__ void matrixVectorMult(E* matrix_elements, E* vector_elements, E* result, size_t dim)
|
||||
__global__ void matrixVectorMult(E *matrix_elements, E *vector_elements, E *result, size_t dim)
|
||||
{
|
||||
int tid = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
if (tid < dim) {
|
||||
result[tid] = E::zero();
|
||||
for (int i = 0; i < dim; i++)
|
||||
result[tid] = result[tid] + matrix_elements[tid * dim + i] * vector_elements[i];
|
||||
}
|
||||
|
||||
int tid = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
if (tid < dim)
|
||||
{
|
||||
result[tid] = E::zero();
|
||||
for (int i = 0; i < dim; i++)
|
||||
result[tid] = result[tid] + matrix_elements[tid * dim + i] * vector_elements[i];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename E>
|
||||
int matrix_mod_mult(E* matrix_elements, E* vector_elements, E* result, size_t dim, cudaStream_t stream)
|
||||
int matrix_mod_mult(E *matrix_elements, E *vector_elements, E *result, size_t dim)
|
||||
{
|
||||
// Set the grid and block dimensions
|
||||
int num_blocks = (int)ceil((float)dim / MAX_THREADS_PER_BLOCK);
|
||||
int threads_per_block = MAX_THREADS_PER_BLOCK;
|
||||
// Set the grid and block dimensions
|
||||
int num_blocks = (int)ceil((float)dim / MAX_THREADS_PER_BLOCK);
|
||||
int threads_per_block = MAX_THREADS_PER_BLOCK;
|
||||
|
||||
// Allocate memory on the device for the input vectors, the output vector, and the modulus
|
||||
E *d_matrix, *d_vector, *d_result;
|
||||
cudaMallocAsync(&d_matrix, (dim * dim) * sizeof(E), stream);
|
||||
cudaMallocAsync(&d_vector, dim * sizeof(E), stream);
|
||||
cudaMallocAsync(&d_result, dim * sizeof(E), stream);
|
||||
// Allocate memory on the device for the input vectors, the output vector, and the modulus
|
||||
E *d_matrix, *d_vector, *d_result;
|
||||
cudaMalloc(&d_matrix, (dim * dim) * sizeof(E));
|
||||
cudaMalloc(&d_vector, dim * sizeof(E));
|
||||
cudaMalloc(&d_result, dim * sizeof(E));
|
||||
|
||||
// Copy the input vectors and the modulus from the host to the device
|
||||
cudaMemcpyAsync(d_matrix, matrix_elements, (dim * dim) * sizeof(E), cudaMemcpyHostToDevice, stream);
|
||||
cudaMemcpyAsync(d_vector, vector_elements, dim * sizeof(E), cudaMemcpyHostToDevice, stream);
|
||||
// Copy the input vectors and the modulus from the host to the device
|
||||
cudaMemcpy(d_matrix, matrix_elements, (dim * dim) * sizeof(E), cudaMemcpyHostToDevice);
|
||||
cudaMemcpy(d_vector, vector_elements, dim * sizeof(E), cudaMemcpyHostToDevice);
|
||||
|
||||
// Call the kernel to perform element-wise modular multiplication
|
||||
matrixVectorMult<<<num_blocks, threads_per_block, 0, stream>>>(d_matrix, d_vector, d_result, dim);
|
||||
// Call the kernel to perform element-wise modular multiplication
|
||||
matrixVectorMult<<<num_blocks, threads_per_block>>>(d_matrix, d_vector, d_result, dim);
|
||||
|
||||
cudaMemcpyAsync(result, d_result, dim * sizeof(E), cudaMemcpyDeviceToHost, stream);
|
||||
cudaMemcpy(result, d_result, dim * sizeof(E), cudaMemcpyDeviceToHost);
|
||||
|
||||
cudaFreeAsync(d_matrix, stream);
|
||||
cudaFreeAsync(d_vector, stream);
|
||||
cudaFreeAsync(d_result, stream);
|
||||
cudaFree(d_matrix);
|
||||
cudaFree(d_vector);
|
||||
cudaFree(d_result);
|
||||
|
||||
cudaStreamSynchronize(stream);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -2,24 +2,21 @@
|
||||
|
||||
#include "../../primitives/field.cuh"
|
||||
#include "../../primitives/projective.cuh"
|
||||
#if defined(G2_DEFINED)
|
||||
#include "../../primitives/extension_field.cuh"
|
||||
#endif
|
||||
|
||||
#include "params.cuh"
|
||||
|
||||
namespace BLS12_377 {
|
||||
typedef Field<PARAMS_BLS12_377::fp_config> scalar_field_t;
|
||||
typedef scalar_field_t scalar_t;
|
||||
typedef Field<PARAMS_BLS12_377::fq_config> point_field_t;
|
||||
static constexpr point_field_t b = point_field_t{PARAMS_BLS12_377::weierstrass_b};
|
||||
typedef Projective<point_field_t, scalar_field_t, b> projective_t;
|
||||
typedef Affine<point_field_t> affine_t;
|
||||
#if defined(G2_DEFINED)
|
||||
typedef ExtensionField<PARAMS_BLS12_377::fq_config> g2_point_field_t;
|
||||
static constexpr g2_point_field_t b_g2 = g2_point_field_t{
|
||||
point_field_t{PARAMS_BLS12_377::weierstrass_b_g2_re}, point_field_t{PARAMS_BLS12_377::weierstrass_b_g2_im}};
|
||||
typedef Projective<g2_point_field_t, scalar_field_t, b_g2> g2_projective_t;
|
||||
typedef Affine<g2_point_field_t> g2_affine_t;
|
||||
#endif
|
||||
} // namespace BLS12_377
|
||||
typedef Field<PARAMS_BLS12_377::fp_config> scalar_field_t;
|
||||
typedef scalar_field_t scalar_t;
|
||||
typedef Field<PARAMS_BLS12_377::fq_config> point_field_t;
|
||||
static constexpr point_field_t b = point_field_t{ PARAMS_BLS12_377::weierstrass_b };
|
||||
typedef Projective<point_field_t, scalar_field_t, b> projective_t;
|
||||
typedef Affine<point_field_t> affine_t;
|
||||
#if defined(G2_DEFINED)
|
||||
typedef ExtensionField<PARAMS_BLS12_377::fq_config> g2_point_field_t;
|
||||
static constexpr g2_point_field_t b_g2 = g2_point_field_t{ point_field_t{ PARAMS_BLS12_377::weierstrass_b_g2_re },
|
||||
point_field_t{ PARAMS_BLS12_377::weierstrass_b_g2_im }};
|
||||
typedef Projective<g2_point_field_t, scalar_field_t, b_g2> g2_projective_t;
|
||||
typedef Affine<g2_point_field_t> g2_affine_t;
|
||||
#endif
|
||||
}
|
||||
@@ -1,610 +1,308 @@
|
||||
#ifndef _BLS12_377_LDE
|
||||
#define _BLS12_377_LDE
|
||||
#include <cuda.h>
|
||||
#include "../../appUtils/ntt/lde.cu"
|
||||
#include "../../appUtils/ntt/ntt.cuh"
|
||||
#include "../../appUtils/vector_manipulation/ve_mod_mult.cuh"
|
||||
#include "../../utils/mont.cuh"
|
||||
#include "curve_config.cuh"
|
||||
#include <cuda.h>
|
||||
|
||||
extern "C" BLS12_377::scalar_t* build_domain_cuda_bls12_377(
|
||||
uint32_t domain_size, uint32_t logn, bool inverse, size_t device_id = 0, cudaStream_t stream = 0)
|
||||
extern "C" BLS12_377::scalar_t* build_domain_cuda_bls12_377(uint32_t domain_size, uint32_t logn, bool inverse, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
if (inverse) {
|
||||
return fill_twiddle_factors_array(domain_size, BLS12_377::scalar_t::omega_inv(logn), stream);
|
||||
} else {
|
||||
return fill_twiddle_factors_array(domain_size, BLS12_377::scalar_t::omega(logn), stream);
|
||||
try
|
||||
{
|
||||
if (inverse) {
|
||||
return fill_twiddle_factors_array(domain_size, BLS12_377::scalar_t::omega_inv(logn));
|
||||
} else {
|
||||
return fill_twiddle_factors_array(domain_size, BLS12_377::scalar_t::omega(logn));
|
||||
}
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return nullptr;
|
||||
}
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int ntt_cuda_bls12_377(
|
||||
BLS12_377::scalar_t* arr,
|
||||
uint32_t n,
|
||||
bool inverse,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int ntt_cuda_bls12_377(BLS12_377::scalar_t *arr, uint32_t n, bool inverse, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return ntt_end2end_template<BLS12_377::scalar_t, BLS12_377::scalar_t>(
|
||||
arr, n, inverse, stream); // TODO: pass device_id
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
return ntt_end2end_template<BLS12_377::scalar_t,BLS12_377::scalar_t>(arr, n, inverse); // TODO: pass device_id
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int ecntt_cuda_bls12_377(
|
||||
BLS12_377::projective_t* arr,
|
||||
uint32_t n,
|
||||
bool inverse,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int ecntt_cuda_bls12_377(BLS12_377::projective_t *arr, uint32_t n, bool inverse, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return ntt_end2end_template<BLS12_377::projective_t, BLS12_377::scalar_t>(
|
||||
arr, n, inverse, stream); // TODO: pass device_id
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
return ntt_end2end_template<BLS12_377::projective_t,BLS12_377::scalar_t>(arr, n, inverse); // TODO: pass device_id
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int ntt_batch_cuda_bls12_377(
|
||||
BLS12_377::scalar_t* arr,
|
||||
uint32_t arr_size,
|
||||
uint32_t batch_size,
|
||||
bool inverse,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int ntt_batch_cuda_bls12_377(BLS12_377::scalar_t *arr, uint32_t arr_size, uint32_t batch_size, bool inverse, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return ntt_end2end_batch_template<BLS12_377::scalar_t, BLS12_377::scalar_t>(
|
||||
arr, arr_size, batch_size, inverse, stream); // TODO: pass device_id
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
return ntt_end2end_batch_template<BLS12_377::scalar_t,BLS12_377::scalar_t>(arr, arr_size, batch_size, inverse); // TODO: pass device_id
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int ecntt_batch_cuda_bls12_377(
|
||||
BLS12_377::projective_t* arr,
|
||||
uint32_t arr_size,
|
||||
uint32_t batch_size,
|
||||
bool inverse,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int ecntt_batch_cuda_bls12_377(BLS12_377::projective_t *arr, uint32_t arr_size, uint32_t batch_size, bool inverse, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return ntt_end2end_batch_template<BLS12_377::projective_t, BLS12_377::scalar_t>(
|
||||
arr, arr_size, batch_size, inverse, stream); // TODO: pass device_id
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
return ntt_end2end_batch_template<BLS12_377::projective_t,BLS12_377::scalar_t>(arr, arr_size, batch_size, inverse); // TODO: pass device_id
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int interpolate_scalars_cuda_bls12_377(
|
||||
BLS12_377::scalar_t* d_out,
|
||||
BLS12_377::scalar_t* d_evaluations,
|
||||
BLS12_377::scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int interpolate_scalars_cuda_bls12_377(BLS12_377::scalar_t* d_out, BLS12_377::scalar_t *d_evaluations, BLS12_377::scalar_t *d_domain, unsigned n, unsigned device_id = 0)
|
||||
{
|
||||
try {
|
||||
BLS12_377::scalar_t* _null = nullptr;
|
||||
return interpolate(d_out, d_evaluations, d_domain, n, false, _null, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
return interpolate(d_out, d_evaluations, d_domain, n);
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int interpolate_scalars_batch_cuda_bls12_377(
|
||||
BLS12_377::scalar_t* d_out,
|
||||
BLS12_377::scalar_t* d_evaluations,
|
||||
BLS12_377::scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int interpolate_scalars_batch_cuda_bls12_377(BLS12_377::scalar_t* d_out, BLS12_377::scalar_t* d_evaluations, BLS12_377::scalar_t* d_domain, unsigned n,
|
||||
unsigned batch_size, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
BLS12_377::scalar_t* _null = nullptr;
|
||||
cudaStreamCreate(&stream);
|
||||
return interpolate_batch(d_out, d_evaluations, d_domain, n, batch_size, false, _null, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
return interpolate_batch(d_out, d_evaluations, d_domain, n, batch_size);
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int interpolate_scalars_on_coset_cuda_bls12_377(
|
||||
BLS12_377::scalar_t* d_out,
|
||||
BLS12_377::scalar_t* d_evaluations,
|
||||
BLS12_377::scalar_t* d_domain,
|
||||
unsigned n,
|
||||
BLS12_377::scalar_t* coset_powers,
|
||||
unsigned device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int interpolate_points_cuda_bls12_377(BLS12_377::projective_t* d_out, BLS12_377::projective_t *d_evaluations, BLS12_377::scalar_t *d_domain, unsigned n, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
return interpolate(d_out, d_evaluations, d_domain, n, true, coset_powers, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
return interpolate(d_out, d_evaluations, d_domain, n);
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int interpolate_scalars_batch_on_coset_cuda_bls12_377(
|
||||
BLS12_377::scalar_t* d_out,
|
||||
BLS12_377::scalar_t* d_evaluations,
|
||||
BLS12_377::scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
BLS12_377::scalar_t* coset_powers,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int interpolate_points_batch_cuda_bls12_377(BLS12_377::projective_t* d_out, BLS12_377::projective_t* d_evaluations, BLS12_377::scalar_t* d_domain,
|
||||
unsigned n, unsigned batch_size, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return interpolate_batch(d_out, d_evaluations, d_domain, n, batch_size, true, coset_powers, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
return interpolate_batch(d_out, d_evaluations, d_domain, n, batch_size);
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int interpolate_points_cuda_bls12_377(
|
||||
BLS12_377::projective_t* d_out,
|
||||
BLS12_377::projective_t* d_evaluations,
|
||||
BLS12_377::scalar_t* d_domain,
|
||||
unsigned n,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int evaluate_scalars_cuda_bls12_377(BLS12_377::scalar_t* d_out, BLS12_377::scalar_t *d_coefficients, BLS12_377::scalar_t *d_domain,
|
||||
unsigned domain_size, unsigned n, unsigned device_id = 0)
|
||||
{
|
||||
try {
|
||||
BLS12_377::scalar_t* _null = nullptr;
|
||||
return interpolate(d_out, d_evaluations, d_domain, n, false, _null, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
BLS12_377::scalar_t* _null = nullptr;
|
||||
return evaluate(d_out, d_coefficients, d_domain, domain_size, n, false, _null);
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int interpolate_points_batch_cuda_bls12_377(
|
||||
BLS12_377::projective_t* d_out,
|
||||
BLS12_377::projective_t* d_evaluations,
|
||||
BLS12_377::scalar_t* d_domain,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int evaluate_scalars_batch_cuda_bls12_377(BLS12_377::scalar_t* d_out, BLS12_377::scalar_t* d_coefficients, BLS12_377::scalar_t* d_domain, unsigned domain_size,
|
||||
unsigned n, unsigned batch_size, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
BLS12_377::scalar_t* _null = nullptr;
|
||||
cudaStreamCreate(&stream);
|
||||
return interpolate_batch(d_out, d_evaluations, d_domain, n, batch_size, false, _null, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
BLS12_377::scalar_t* _null = nullptr;
|
||||
return evaluate_batch(d_out, d_coefficients, d_domain, domain_size, n, batch_size, false, _null);
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int evaluate_scalars_cuda_bls12_377(
|
||||
BLS12_377::scalar_t* d_out,
|
||||
BLS12_377::scalar_t* d_coefficients,
|
||||
BLS12_377::scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int evaluate_points_cuda_bls12_377(BLS12_377::projective_t* d_out, BLS12_377::projective_t *d_coefficients, BLS12_377::scalar_t *d_domain,
|
||||
unsigned domain_size, unsigned n, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
BLS12_377::scalar_t* _null = nullptr;
|
||||
cudaStreamCreate(&stream);
|
||||
return evaluate(d_out, d_coefficients, d_domain, domain_size, n, false, _null, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
BLS12_377::scalar_t* _null = nullptr;
|
||||
return evaluate(d_out, d_coefficients, d_domain, domain_size, n, false, _null);
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int evaluate_scalars_batch_cuda_bls12_377(
|
||||
BLS12_377::scalar_t* d_out,
|
||||
BLS12_377::scalar_t* d_coefficients,
|
||||
BLS12_377::scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int evaluate_points_batch_cuda_bls12_377(BLS12_377::projective_t* d_out, BLS12_377::projective_t* d_coefficients, BLS12_377::scalar_t* d_domain, unsigned domain_size,
|
||||
unsigned n, unsigned batch_size, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
BLS12_377::scalar_t* _null = nullptr;
|
||||
cudaStreamCreate(&stream);
|
||||
return evaluate_batch(d_out, d_coefficients, d_domain, domain_size, n, batch_size, false, _null, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
BLS12_377::scalar_t* _null = nullptr;
|
||||
return evaluate_batch(d_out, d_coefficients, d_domain, domain_size, n, batch_size, false, _null);
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int evaluate_points_cuda_bls12_377(
|
||||
BLS12_377::projective_t* d_out,
|
||||
BLS12_377::projective_t* d_coefficients,
|
||||
BLS12_377::scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int evaluate_scalars_on_coset_cuda_bls12_377(BLS12_377::scalar_t* d_out, BLS12_377::scalar_t *d_coefficients, BLS12_377::scalar_t *d_domain, unsigned domain_size,
|
||||
unsigned n, BLS12_377::scalar_t *coset_powers, unsigned device_id = 0)
|
||||
{
|
||||
try {
|
||||
BLS12_377::scalar_t* _null = nullptr;
|
||||
cudaStreamCreate(&stream);
|
||||
return evaluate(d_out, d_coefficients, d_domain, domain_size, n, false, _null, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
return evaluate(d_out, d_coefficients, d_domain, domain_size, n, true, coset_powers);
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int evaluate_points_batch_cuda_bls12_377(
|
||||
BLS12_377::projective_t* d_out,
|
||||
BLS12_377::projective_t* d_coefficients,
|
||||
BLS12_377::scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int evaluate_scalars_on_coset_batch_cuda_bls12_377(BLS12_377::scalar_t* d_out, BLS12_377::scalar_t* d_coefficients, BLS12_377::scalar_t* d_domain, unsigned domain_size,
|
||||
unsigned n, unsigned batch_size, BLS12_377::scalar_t *coset_powers, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
BLS12_377::scalar_t* _null = nullptr;
|
||||
cudaStreamCreate(&stream);
|
||||
return evaluate_batch(d_out, d_coefficients, d_domain, domain_size, n, batch_size, false, _null, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
return evaluate_batch(d_out, d_coefficients, d_domain, domain_size, n, batch_size, true, coset_powers);
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int evaluate_scalars_on_coset_cuda_bls12_377(
|
||||
BLS12_377::scalar_t* d_out,
|
||||
BLS12_377::scalar_t* d_coefficients,
|
||||
BLS12_377::scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
BLS12_377::scalar_t* coset_powers,
|
||||
unsigned device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int evaluate_points_on_coset_cuda_bls12_377(BLS12_377::projective_t* d_out, BLS12_377::projective_t *d_coefficients, BLS12_377::scalar_t *d_domain, unsigned domain_size,
|
||||
unsigned n, BLS12_377::scalar_t *coset_powers, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return evaluate(d_out, d_coefficients, d_domain, domain_size, n, true, coset_powers, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
return evaluate(d_out, d_coefficients, d_domain, domain_size, n, true, coset_powers);
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int evaluate_scalars_on_coset_batch_cuda_bls12_377(
|
||||
BLS12_377::scalar_t* d_out,
|
||||
BLS12_377::scalar_t* d_coefficients,
|
||||
BLS12_377::scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
BLS12_377::scalar_t* coset_powers,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int evaluate_points_on_coset_batch_cuda_bls12_377(BLS12_377::projective_t* d_out, BLS12_377::projective_t* d_coefficients, BLS12_377::scalar_t* d_domain, unsigned domain_size,
|
||||
unsigned n, unsigned batch_size, BLS12_377::scalar_t *coset_powers, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return evaluate_batch(d_out, d_coefficients, d_domain, domain_size, n, batch_size, true, coset_powers, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
return evaluate_batch(d_out, d_coefficients, d_domain, domain_size, n, batch_size, true, coset_powers);
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int evaluate_points_on_coset_cuda_bls12_377(
|
||||
BLS12_377::projective_t* d_out,
|
||||
BLS12_377::projective_t* d_coefficients,
|
||||
BLS12_377::scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
BLS12_377::scalar_t* coset_powers,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int reverse_order_scalars_cuda_bls12_377(BLS12_377::scalar_t* arr, int n, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return evaluate(d_out, d_coefficients, d_domain, domain_size, n, true, coset_powers, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
uint32_t logn = uint32_t(log(n) / log(2));
|
||||
reverse_order(arr, n, logn);
|
||||
return 0;
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int evaluate_points_on_coset_batch_cuda_bls12_377(
|
||||
BLS12_377::projective_t* d_out,
|
||||
BLS12_377::projective_t* d_coefficients,
|
||||
BLS12_377::scalar_t* d_domain,
|
||||
unsigned domain_size,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
BLS12_377::scalar_t* coset_powers,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int reverse_order_scalars_batch_cuda_bls12_377(BLS12_377::scalar_t* arr, int n, int batch_size, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return evaluate_batch(d_out, d_coefficients, d_domain, domain_size, n, batch_size, true, coset_powers, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
uint32_t logn = uint32_t(log(n) / log(2));
|
||||
reverse_order_batch(arr, n, logn, batch_size);
|
||||
return 0;
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int ntt_inplace_batch_cuda_bls12_377(
|
||||
BLS12_377::scalar_t* d_inout,
|
||||
BLS12_377::scalar_t* d_twiddles,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
bool inverse,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int reverse_order_points_cuda_bls12_377(BLS12_377::projective_t* arr, int n, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
BLS12_377::scalar_t* _null = nullptr;
|
||||
ntt_inplace_batch_template(d_inout, d_twiddles, n, batch_size, inverse, false, _null, stream, true);
|
||||
return CUDA_SUCCESS; // TODO: we should implement this https://leimao.github.io/blog/Proper-CUDA-Error-Checking/
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
uint32_t logn = uint32_t(log(n) / log(2));
|
||||
reverse_order(arr, n, logn);
|
||||
return 0;
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int ntt_inplace_coset_batch_cuda_bls12_377(
|
||||
BLS12_377::scalar_t* d_inout,
|
||||
BLS12_377::scalar_t* d_twiddles,
|
||||
unsigned n,
|
||||
unsigned batch_size,
|
||||
bool inverse,
|
||||
bool is_coset,
|
||||
BLS12_377::scalar_t* coset,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int reverse_order_points_batch_cuda_bls12_377(BLS12_377::projective_t* arr, int n, int batch_size, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
ntt_inplace_batch_template(d_inout, d_twiddles, n, batch_size, inverse, is_coset, coset, stream, true);
|
||||
return CUDA_SUCCESS; // TODO: we should implement this https://leimao.github.io/blog/Proper-CUDA-Error-Checking/
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
uint32_t logn = uint32_t(log(n) / log(2));
|
||||
reverse_order_batch(arr, n, logn, batch_size);
|
||||
return 0;
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int sub_scalars_cuda_bls12_377(
|
||||
BLS12_377::scalar_t* d_out,
|
||||
BLS12_377::scalar_t* d_in1,
|
||||
BLS12_377::scalar_t* d_in2,
|
||||
unsigned n,
|
||||
cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return sub_polys(d_out, d_in1, d_in2, n, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int add_scalars_cuda_bls12_377(
|
||||
BLS12_377::scalar_t* d_out,
|
||||
BLS12_377::scalar_t* d_in1,
|
||||
BLS12_377::scalar_t* d_in2,
|
||||
unsigned n,
|
||||
cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return add_polys(d_out, d_in1, d_in2, n, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int to_montgomery_scalars_cuda_bls12_377(BLS12_377::scalar_t* d_inout, unsigned n, cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return to_montgomery(d_inout, n, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int from_montgomery_scalars_cuda_bls12_377(BLS12_377::scalar_t* d_inout, unsigned n, cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return from_montgomery(d_inout, n, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
to_montgomery_proj_points_cuda_bls12_377(BLS12_377::projective_t* d_inout, unsigned n, cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return to_montgomery((BLS12_377::point_field_t*)d_inout, 3 * n, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
from_montgomery_proj_points_cuda_bls12_377(BLS12_377::projective_t* d_inout, unsigned n, cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return from_montgomery((BLS12_377::point_field_t*)d_inout, 3 * n, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
to_montgomery_aff_points_cuda_bls12_377(BLS12_377::affine_t* d_inout, unsigned n, cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return to_montgomery((BLS12_377::point_field_t*)d_inout, 2 * n, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
from_montgomery_aff_points_cuda_bls12_377(BLS12_377::affine_t* d_inout, unsigned n, cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return from_montgomery((BLS12_377::point_field_t*)d_inout, 2 * n, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(G2_DEFINED)
|
||||
extern "C" int
|
||||
to_montgomery_proj_points_g2_cuda_bls12_377(BLS12_377::g2_projective_t* d_inout, unsigned n, cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return to_montgomery((BLS12_377::point_field_t*)d_inout, 6 * n, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
from_montgomery_proj_points_g2_cuda_bls12_377(BLS12_377::g2_projective_t* d_inout, unsigned n, cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return from_montgomery((BLS12_377::point_field_t*)d_inout, 6 * n, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
to_montgomery_aff_points_g2_cuda_bls12_377(BLS12_377::g2_affine_t* d_inout, unsigned n, cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return to_montgomery((BLS12_377::point_field_t*)d_inout, 4 * n, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
from_montgomery_aff_points_g2_cuda_bls12_377(BLS12_377::g2_affine_t* d_inout, unsigned n, cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
return from_montgomery((BLS12_377::point_field_t*)d_inout, 4 * n, stream);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" int
|
||||
reverse_order_scalars_cuda_bls12_377(BLS12_377::scalar_t* arr, int n, size_t device_id = 0, cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
uint32_t logn = uint32_t(log(n) / log(2));
|
||||
cudaStreamCreate(&stream);
|
||||
reverse_order(arr, n, logn, stream);
|
||||
cudaStreamSynchronize(stream);
|
||||
return 0;
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int reverse_order_scalars_batch_cuda_bls12_377(
|
||||
BLS12_377::scalar_t* arr, int n, int batch_size, size_t device_id = 0, cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
uint32_t logn = uint32_t(log(n) / log(2));
|
||||
cudaStreamCreate(&stream);
|
||||
reverse_order_batch(arr, n, logn, batch_size, stream);
|
||||
return 0;
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
reverse_order_points_cuda_bls12_377(BLS12_377::projective_t* arr, int n, size_t device_id = 0, cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
uint32_t logn = uint32_t(log(n) / log(2));
|
||||
cudaStreamCreate(&stream);
|
||||
reverse_order(arr, n, logn, stream);
|
||||
return 0;
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int reverse_order_points_batch_cuda_bls12_377(
|
||||
BLS12_377::projective_t* arr, int n, int batch_size, size_t device_id = 0, cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
uint32_t logn = uint32_t(log(n) / log(2));
|
||||
cudaStreamCreate(&stream);
|
||||
reverse_order_batch(arr, n, logn, batch_size, stream);
|
||||
return 0;
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,47 +1,37 @@
|
||||
#ifndef _BLS12_377_MSM
|
||||
#define _BLS12_377_MSM
|
||||
#include "../../appUtils/msm/msm.cu"
|
||||
#include "curve_config.cuh"
|
||||
#include <cuda.h>
|
||||
#include <stdexcept>
|
||||
#include <cuda.h>
|
||||
#include "curve_config.cuh"
|
||||
|
||||
extern "C" int msm_cuda_bls12_377(
|
||||
BLS12_377::projective_t* out,
|
||||
BLS12_377::affine_t points[],
|
||||
BLS12_377::scalar_t scalars[],
|
||||
size_t count,
|
||||
unsigned large_bucket_factor,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
|
||||
extern "C"
|
||||
int msm_cuda_bls12_377(BLS12_377::projective_t *out, BLS12_377::affine_t points[],
|
||||
BLS12_377::scalar_t scalars[], size_t count, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
large_msm<BLS12_377::scalar_t, BLS12_377::projective_t, BLS12_377::affine_t>(
|
||||
scalars, points, count, out, false, false, large_bucket_factor, stream);
|
||||
cudaStreamSynchronize(stream);
|
||||
return CUDA_SUCCESS;
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
large_msm<BLS12_377::scalar_t, BLS12_377::projective_t, BLS12_377::affine_t>(scalars, points, count, out, false);
|
||||
return CUDA_SUCCESS;
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int msm_batch_cuda_bls12_377(
|
||||
BLS12_377::projective_t* out,
|
||||
BLS12_377::affine_t points[],
|
||||
BLS12_377::scalar_t scalars[],
|
||||
size_t batch_size,
|
||||
size_t msm_size,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
extern "C" int msm_batch_cuda_bls12_377(BLS12_377::projective_t* out, BLS12_377::affine_t points[],
|
||||
BLS12_377::scalar_t scalars[], size_t batch_size, size_t msm_size, size_t device_id = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
batched_large_msm<BLS12_377::scalar_t, BLS12_377::projective_t, BLS12_377::affine_t>(
|
||||
scalars, points, batch_size, msm_size, out, false, stream);
|
||||
cudaStreamSynchronize(stream);
|
||||
try
|
||||
{
|
||||
batched_large_msm<BLS12_377::scalar_t, BLS12_377::projective_t, BLS12_377::affine_t>(scalars, points, batch_size, msm_size, out, false);
|
||||
return CUDA_SUCCESS;
|
||||
} catch (const std::runtime_error& ex) {
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
@@ -49,168 +39,49 @@ extern "C" int msm_batch_cuda_bls12_377(
|
||||
|
||||
/**
|
||||
* Commit to a polynomial using the MSM.
|
||||
* Note: this function just calls the MSM, it doesn't convert between evaluation and coefficient form of scalars or
|
||||
* points.
|
||||
* Note: this function just calls the MSM, it doesn't convert between evaluation and coefficient form of scalars or points.
|
||||
* @param d_out Ouptut point to write the result to.
|
||||
* @param d_scalars Scalars for the MSM. Must be on device.
|
||||
* @param d_points Points for the MSM. Must be on device.
|
||||
* @param count Length of `d_scalars` and `d_points` arrays (they should have equal length).
|
||||
*/
|
||||
extern "C" int commit_cuda_bls12_377(
|
||||
BLS12_377::projective_t* d_out,
|
||||
BLS12_377::scalar_t* d_scalars,
|
||||
BLS12_377::affine_t* d_points,
|
||||
size_t count,
|
||||
unsigned large_bucket_factor,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
large_msm(d_scalars, d_points, count, d_out, true, false, large_bucket_factor, stream);
|
||||
cudaStreamSynchronize(stream);
|
||||
return CUDA_SUCCESS;
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
extern "C"
|
||||
int commit_cuda_bls12_377(BLS12_377::projective_t* d_out, BLS12_377::scalar_t* d_scalars, BLS12_377::affine_t* d_points, size_t count, size_t device_id = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
large_msm<BLS12_377::scalar_t, BLS12_377::projective_t, BLS12_377::affine_t>(d_scalars, d_points, count, d_out, true);
|
||||
return 0;
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit to a batch of polynomials using the MSM.
|
||||
* Note: this function just calls the MSM, it doesn't convert between evaluation and coefficient form of scalars or points.
|
||||
* @param d_out Ouptut point to write the results to.
|
||||
* @param d_scalars Scalars for the MSMs of all polynomials. Must be on device.
|
||||
* @param d_points Points for the MSMs. Must be on device. It is assumed that this set of bases is used for each MSM.
|
||||
* @param count Length of `d_points` array, `d_scalar` has length `count` * `batch_size`.
|
||||
* @param batch_size Size of the batch.
|
||||
*/
|
||||
extern "C"
|
||||
int commit_batch_cuda_bls12_377(BLS12_377::projective_t* d_out, BLS12_377::scalar_t* d_scalars, BLS12_377::affine_t* d_points, size_t count, size_t batch_size, size_t device_id = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
batched_large_msm(d_scalars, d_points, batch_size, count, d_out, true);
|
||||
return 0;
|
||||
}
|
||||
catch (const std::runtime_error &ex)
|
||||
{
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit to a batch of polynomials using the MSM.
|
||||
* Note: this function just calls the MSM, it doesn't convert between evaluation and coefficient form of scalars or
|
||||
* points.
|
||||
* @param d_out Ouptut point to write the results to.
|
||||
* @param d_scalars Scalars for the MSMs of all polynomials. Must be on device.
|
||||
* @param d_points Points for the MSMs. Must be on device. It is assumed that this set of bases is used for each MSM.
|
||||
* @param count Length of `d_points` array, `d_scalar` has length `count` * `batch_size`.
|
||||
* @param batch_size Size of the batch.
|
||||
*/
|
||||
extern "C" int commit_batch_cuda_bls12_377(
|
||||
BLS12_377::projective_t* d_out,
|
||||
BLS12_377::scalar_t* d_scalars,
|
||||
BLS12_377::affine_t* d_points,
|
||||
size_t count,
|
||||
size_t batch_size,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
batched_large_msm(d_scalars, d_points, batch_size, count, d_out, true, stream);
|
||||
cudaStreamSynchronize(stream);
|
||||
return CUDA_SUCCESS;
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(G2_DEFINED)
|
||||
extern "C" int msm_g2_cuda_bls12_377(
|
||||
BLS12_377::g2_projective_t* out,
|
||||
BLS12_377::g2_affine_t points[],
|
||||
BLS12_377::scalar_t scalars[],
|
||||
size_t count,
|
||||
unsigned large_bucket_factor,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
large_msm<BLS12_377::scalar_t, BLS12_377::g2_projective_t, BLS12_377::g2_affine_t>(
|
||||
scalars, points, count, out, false, false, large_bucket_factor, stream);
|
||||
cudaStreamSynchronize(stream);
|
||||
return CUDA_SUCCESS;
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int msm_batch_g2_cuda_bls12_377(
|
||||
BLS12_377::g2_projective_t* out,
|
||||
BLS12_377::g2_affine_t points[],
|
||||
BLS12_377::scalar_t scalars[],
|
||||
size_t batch_size,
|
||||
size_t msm_size,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
{
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
batched_large_msm<BLS12_377::scalar_t, BLS12_377::g2_projective_t, BLS12_377::g2_affine_t>(
|
||||
scalars, points, batch_size, msm_size, out, false, stream);
|
||||
cudaStreamSynchronize(stream);
|
||||
return CUDA_SUCCESS;
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit to a polynomial using the MSM in G2 group.
|
||||
* Note: this function just calls the MSM, it doesn't convert between evaluation and coefficient form of scalars or
|
||||
* points.
|
||||
* @param d_out Ouptut G2 point to write the result to.
|
||||
* @param d_scalars Scalars for the MSM. Must be on device.
|
||||
* @param d_points G2 affine points for the MSM. Must be on device.
|
||||
* @param count Length of `d_scalars` and `d_points` arrays (they should have equal length).
|
||||
*/
|
||||
extern "C" int commit_g2_cuda_bls12_377(
|
||||
BLS12_377::g2_projective_t* d_out,
|
||||
BLS12_377::scalar_t* d_scalars,
|
||||
BLS12_377::g2_affine_t* d_points,
|
||||
size_t count,
|
||||
unsigned large_bucket_factor,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
{
|
||||
// TODO: use device_id when working with multiple devices
|
||||
(void)device_id;
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
large_msm(d_scalars, d_points, count, d_out, true, false, large_bucket_factor, stream);
|
||||
cudaStreamSynchronize(stream);
|
||||
return CUDA_SUCCESS;
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit to a batch of polynomials using the MSM.
|
||||
* Note: this function just calls the MSM, it doesn't convert between evaluation and coefficient form of scalars or
|
||||
* points.
|
||||
* @param d_out Ouptut G2 point to write the results to.
|
||||
* @param d_scalars Scalars for the MSMs of all polynomials. Must be on device.
|
||||
* @param d_points G2 affine points for the MSMs. Must be on device. It is assumed that this set of bases is used for
|
||||
* each MSM.
|
||||
* @param count Length of `d_points` array, `d_scalar` has length `count` * `batch_size`.
|
||||
* @param batch_size Size of the batch.
|
||||
*/
|
||||
extern "C" int commit_batch_g2_cuda_bls12_377(
|
||||
BLS12_377::g2_projective_t* d_out,
|
||||
BLS12_377::scalar_t* d_scalars,
|
||||
BLS12_377::g2_affine_t* d_points,
|
||||
size_t count,
|
||||
size_t batch_size,
|
||||
size_t device_id = 0,
|
||||
cudaStream_t stream = 0)
|
||||
{
|
||||
// TODO: use device_id when working with multiple devices
|
||||
(void)device_id;
|
||||
try {
|
||||
cudaStreamCreate(&stream);
|
||||
batched_large_msm(d_scalars, d_points, batch_size, count, d_out, true, stream);
|
||||
cudaStreamSynchronize(stream);
|
||||
return CUDA_SUCCESS;
|
||||
} catch (const std::runtime_error& ex) {
|
||||
printf("error %s", ex.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user