mirror of
https://github.com/pseXperiments/icicle.git
synced 2026-01-08 23:17:54 -05:00
ICICLE V2 Release (#492)
This PR introduces major updates for ICICLE Core, Rust and Golang bindings --------- Co-authored-by: Yuval Shekel <yshekel@gmail.com> Co-authored-by: DmytroTym <dmytrotym1@gmail.com> Co-authored-by: Otsar <122266060+Otsar-Raikou@users.noreply.github.com> Co-authored-by: VitaliiH <vhnatyk@gmail.com> Co-authored-by: release-bot <release-bot@ingonyama.com> Co-authored-by: Stas <spolonsky@icloud.com> Co-authored-by: Jeremy Felder <jeremy.felder1@gmail.com> Co-authored-by: ImmanuelSegol <3ditds@gmail.com> Co-authored-by: JimmyHongjichuan <45908291+JimmyHongjichuan@users.noreply.github.com> Co-authored-by: pierre <pierreuu@gmail.com> Co-authored-by: Leon Hibnik <107353745+LeonHibnik@users.noreply.github.com> Co-authored-by: nonam3e <timur@ingonyama.com> Co-authored-by: Vlad <88586482+vladfdp@users.noreply.github.com> Co-authored-by: LeonHibnik <leon@ingonyama.com> Co-authored-by: nonam3e <71525212+nonam3e@users.noreply.github.com> Co-authored-by: vladfdp <vlad.heintz@gmail.com>
This commit is contained in:
@@ -4,57 +4,60 @@ In order to build the underlying ICICLE libraries you should run the build scrip
|
||||
|
||||
Build script USAGE
|
||||
|
||||
```
|
||||
./build <curve> [G2_enabled]
|
||||
```bash
|
||||
./build.sh [-curve=<curve> | -field=<field>] [-cuda_version=<version>] [-g2] [-ecntt] [-devmode]
|
||||
|
||||
curve - The name of the curve to build or "all" to build all curves
|
||||
G2_enabled - Optional - To build with G2 enabled
|
||||
field - The name of the field to build or "all" to build all fields
|
||||
-g2 - Optional - build with G2 enabled
|
||||
-ecntt - Optional - build with ECNTT enabled
|
||||
-devmode - Optional - build in devmode
|
||||
```
|
||||
|
||||
To build ICICLE libraries for all supported curves with G2 enabled.
|
||||
To build ICICLE libraries for all supported curves with G2 and ECNTT enabled.
|
||||
|
||||
```
|
||||
./build.sh all ON
|
||||
./build.sh all -g2 -ecntt
|
||||
```
|
||||
|
||||
If you wish to build for a specific curve, for example bn254, without G2 enabled.
|
||||
If you wish to build for a specific curve, for example bn254, without G2 or ECNTT enabled.
|
||||
|
||||
```
|
||||
./build.sh bn254
|
||||
```
|
||||
|
||||
>[!NOTE]
|
||||
>Current supported curves are `bn254`, `bls12_381`, `bls12_377` and `bw6_671`
|
||||
>Current supported curves are `bn254`, `bls12_381`, `bls12_377`, `bw6_671` and `grumpkin`
|
||||
>Current supported fields are `babybear`
|
||||
|
||||
>[!NOTE]
|
||||
>G2 is enabled by building your golang project with the build tag `g2`
|
||||
>Make sure to add it to your build tags if you want it enabled
|
||||
>G2 and ECNTT are located in nested packages
|
||||
|
||||
## Running golang tests
|
||||
|
||||
To run the tests for curve bn254.
|
||||
|
||||
```
|
||||
```bash
|
||||
go test ./wrappers/golang/curves/bn254 -count=1
|
||||
```
|
||||
|
||||
To run all the tests in the golang bindings
|
||||
|
||||
```
|
||||
go test --tags=g2 ./... -count=1
|
||||
```bash
|
||||
go test ./... -count=1
|
||||
```
|
||||
|
||||
## How do Golang bindings work?
|
||||
|
||||
The libraries produced from the CUDA code compilation are used to bind Golang to ICICLE's CUDA code.
|
||||
|
||||
1. These libraries (named `libingo_<curve>.a`) can be imported in your Go project to leverage the GPU accelerated functionalities provided by ICICLE.
|
||||
1. These libraries (named `libingo_curve_<curve>.a` and `libingo_field_<curve>.a`) 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 libraries. Here's a basic example on how you can use `cgo` to link these libraries:
|
||||
|
||||
```go
|
||||
/*
|
||||
#cgo LDFLAGS: -L/path/to/shared/libs -lingo_bn254
|
||||
#cgo LDFLAGS: -L$/path/to/shared/libs -lingo_curve_bn254 -L$/path/to/shared/libs -lingo_field_bn254 -lstdc++ -lm
|
||||
#include "icicle.h" // make sure you use the correct header file(s)
|
||||
*/
|
||||
import "C"
|
||||
|
||||
@@ -2,32 +2,106 @@
|
||||
|
||||
G2_DEFINED=OFF
|
||||
ECNTT_DEFINED=OFF
|
||||
CUDA_COMPILER_PATH=/usr/local/cuda/bin/nvcc
|
||||
DEVMODE=OFF
|
||||
EXT_FIELD=OFF
|
||||
BUILD_CURVES=( )
|
||||
BUILD_FIELDS=( )
|
||||
|
||||
if [[ $2 == "ON" ]]
|
||||
then
|
||||
G2_DEFINED=ON
|
||||
SUPPORTED_CURVES=("bn254" "bls12_377" "bls12_381" "bw6_761", "grumpkin")
|
||||
SUPPORTED_FIELDS=("babybear")
|
||||
|
||||
if [[ $1 == "-help" ]]; then
|
||||
echo "Build script for building ICICLE cpp libraries"
|
||||
echo ""
|
||||
echo "If more than one curve or more than one field is supplied, the last one supplied will be built"
|
||||
echo ""
|
||||
echo "USAGE: ./build.sh [OPTION...]"
|
||||
echo ""
|
||||
echo "OPTIONS:"
|
||||
echo " -curve=<curve_name> The curve that should be built. If \"all\" is supplied,"
|
||||
echo " all curves will be built with any other supplied curve options"
|
||||
echo " -g2 Builds the curve lib with G2 enabled"
|
||||
echo " -ecntt Builds the curve lib with ECNTT enabled"
|
||||
echo " -field=<field_name> The field that should be built. If \"all\" is supplied,"
|
||||
echo " all fields will be built with any other supplied field options"
|
||||
echo " -field-ext Builds the field lib with the extension field enabled"
|
||||
echo " -devmode Enables devmode debugging and fast build times"
|
||||
echo " -cuda_version=<version> The version of cuda to use for compiling"
|
||||
echo ""
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ $3 ]]
|
||||
then
|
||||
ECNTT_DEFINED=ON
|
||||
fi
|
||||
for arg in "$@"
|
||||
do
|
||||
arg_lower=$(echo "$arg" | tr '[:upper:]' '[:lower:]')
|
||||
case "$arg_lower" in
|
||||
-cuda_version=*)
|
||||
cuda_version=$(echo "$arg" | cut -d'=' -f2)
|
||||
CUDA_COMPILER_PATH=/usr/local/cuda-$cuda_version/bin/nvcc
|
||||
;;
|
||||
-ecntt)
|
||||
ECNTT_DEFINED=ON
|
||||
;;
|
||||
-g2)
|
||||
G2_DEFINED=ON
|
||||
;;
|
||||
-curve=*)
|
||||
curve=$(echo "$arg_lower" | cut -d'=' -f2)
|
||||
if [[ $curve == "all" ]]
|
||||
then
|
||||
BUILD_CURVES=("${SUPPORTED_CURVES[@]}")
|
||||
else
|
||||
BUILD_CURVES=( $curve )
|
||||
fi
|
||||
;;
|
||||
-field=*)
|
||||
field=$(echo "$arg_lower" | cut -d'=' -f2)
|
||||
if [[ $field == "all" ]]
|
||||
then
|
||||
BUILD_FIELDS=("${SUPPORTED_FIELDS[@]}")
|
||||
else
|
||||
BUILD_FIELDS=( $field )
|
||||
fi
|
||||
;;
|
||||
-field-ext)
|
||||
EXT_FIELD=ON
|
||||
;;
|
||||
-devmode)
|
||||
DEVMODE=ON
|
||||
;;
|
||||
*)
|
||||
echo "Unknown argument: $arg"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
BUILD_DIR=$(realpath "$PWD/../../icicle/build")
|
||||
SUPPORTED_CURVES=("bn254" "bls12_377" "bls12_381" "bw6_761")
|
||||
|
||||
if [[ $1 == "all" ]]
|
||||
then
|
||||
BUILD_CURVES=("${SUPPORTED_CURVES[@]}")
|
||||
else
|
||||
BUILD_CURVES=( $1 )
|
||||
fi
|
||||
|
||||
cd ../../icicle
|
||||
mkdir -p build
|
||||
rm -f "$BUILD_DIR/CMakeCache.txt"
|
||||
|
||||
for CURVE in "${BUILD_CURVES[@]}"
|
||||
do
|
||||
cmake -DCURVE=$CURVE -DG2_DEFINED=$G2_DEFINED -DECNTT_DEFINED=$ECNTT_DEFINED -DCMAKE_BUILD_TYPE=Release -S . -B build
|
||||
cmake --build build -j8
|
||||
done
|
||||
echo "CURVE=${CURVE}" > build_config.txt
|
||||
echo "ECNTT=${ECNTT_DEFINED}" >> build_config.txt
|
||||
echo "G2=${G2_DEFINED}" >> build_config.txt
|
||||
echo "DEVMODE=${DEVMODE}" >> build_config.txt
|
||||
cmake -DCMAKE_CUDA_COMPILER=$CUDA_COMPILER_PATH -DCURVE=$CURVE -DG2=$G2_DEFINED -DECNTT=$ECNTT_DEFINED -DDEVMODE=$DEVMODE -DCMAKE_BUILD_TYPE=Release -S . -B build
|
||||
cmake --build build -j8 && rm build_config.txt
|
||||
done
|
||||
|
||||
# Needs to remove the CMakeCache.txt file to allow building fields after curves
|
||||
# have been built since CURVE and FIELD cannot both be defined
|
||||
rm -f "$BUILD_DIR/CMakeCache.txt"
|
||||
|
||||
for FIELD in "${BUILD_FIELDS[@]}"
|
||||
do
|
||||
echo "FIELD=${FIELD}" > build_config.txt
|
||||
echo "DEVMODE=${DEVMODE}" >> build_config.txt
|
||||
cmake -DCMAKE_CUDA_COMPILER=$CUDA_COMPILER_PATH -DFIELD=$FIELD -DEXT_FIELD=$EXT_FIELD -DDEVMODE=$DEVMODE -DCMAKE_BUILD_TYPE=Release -S . -B build
|
||||
cmake --build build -j8 && rm build_config.txt
|
||||
done
|
||||
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMockAffineZero(t *testing.T) {
|
||||
var fieldZero = MockField{}
|
||||
|
||||
var affineZero MockAffine
|
||||
assert.Equal(t, affineZero.X, fieldZero)
|
||||
assert.Equal(t, affineZero.Y, fieldZero)
|
||||
|
||||
x := generateRandomLimb(int(BASE_LIMBS))
|
||||
y := generateRandomLimb(int(BASE_LIMBS))
|
||||
var affine MockAffine
|
||||
affine.FromLimbs(x, y)
|
||||
|
||||
affine.Zero()
|
||||
assert.Equal(t, affine.X, fieldZero)
|
||||
assert.Equal(t, affine.Y, fieldZero)
|
||||
}
|
||||
|
||||
func TestMockAffineFromLimbs(t *testing.T) {
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs2 := generateRandomLimb(int(BASE_LIMBS))
|
||||
|
||||
var affine MockAffine
|
||||
affine.FromLimbs(randLimbs, randLimbs2)
|
||||
|
||||
assert.ElementsMatch(t, randLimbs, affine.X.GetLimbs())
|
||||
assert.ElementsMatch(t, randLimbs2, affine.Y.GetLimbs())
|
||||
}
|
||||
|
||||
func TestMockAffineToProjective(t *testing.T) {
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs2 := generateRandomLimb(int(BASE_LIMBS))
|
||||
var fieldOne MockField
|
||||
fieldOne.One()
|
||||
|
||||
var expected MockProjective
|
||||
expected.FromLimbs(randLimbs, randLimbs2, fieldOne.limbs[:])
|
||||
|
||||
var affine MockAffine
|
||||
affine.FromLimbs(randLimbs, randLimbs2)
|
||||
|
||||
projectivePoint := affine.ToProjective()
|
||||
assert.Equal(t, expected, projectivePoint)
|
||||
}
|
||||
|
||||
func TestMockProjectiveZero(t *testing.T) {
|
||||
var projectiveZero MockProjective
|
||||
projectiveZero.Zero()
|
||||
var fieldZero = MockField{}
|
||||
var fieldOne MockField
|
||||
fieldOne.One()
|
||||
|
||||
assert.Equal(t, projectiveZero.X, fieldZero)
|
||||
assert.Equal(t, projectiveZero.Y, fieldOne)
|
||||
assert.Equal(t, projectiveZero.Z, fieldZero)
|
||||
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
var projective MockProjective
|
||||
projective.FromLimbs(randLimbs, randLimbs, randLimbs)
|
||||
|
||||
projective.Zero()
|
||||
assert.Equal(t, projective.X, fieldZero)
|
||||
assert.Equal(t, projective.Y, fieldOne)
|
||||
assert.Equal(t, projective.Z, fieldZero)
|
||||
}
|
||||
|
||||
func TestMockProjectiveFromLimbs(t *testing.T) {
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs2 := generateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs3 := generateRandomLimb(int(BASE_LIMBS))
|
||||
|
||||
var projective MockProjective
|
||||
projective.FromLimbs(randLimbs, randLimbs2, randLimbs3)
|
||||
|
||||
assert.ElementsMatch(t, randLimbs, projective.X.GetLimbs())
|
||||
assert.ElementsMatch(t, randLimbs2, projective.Y.GetLimbs())
|
||||
assert.ElementsMatch(t, randLimbs3, projective.Z.GetLimbs())
|
||||
}
|
||||
|
||||
func TestMockProjectiveFromAffine(t *testing.T) {
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs2 := generateRandomLimb(int(BASE_LIMBS))
|
||||
var fieldOne MockField
|
||||
fieldOne.One()
|
||||
|
||||
var expected MockProjective
|
||||
expected.FromLimbs(randLimbs, randLimbs2, fieldOne.limbs[:])
|
||||
|
||||
var affine MockAffine
|
||||
affine.FromLimbs(randLimbs, randLimbs2)
|
||||
|
||||
var projectivePoint MockProjective
|
||||
projectivePoint.FromAffine(affine)
|
||||
assert.Equal(t, expected, projectivePoint)
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMockFieldFromLimbs(t *testing.T) {
|
||||
emptyField := MockField{}
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
assert.ElementsMatch(t, randLimbs, emptyField.limbs, "Limbs do not match; there was an issue with setting the MockField's limbs")
|
||||
randLimbs[0] = 100
|
||||
assert.NotEqual(t, randLimbs, emptyField.limbs)
|
||||
}
|
||||
|
||||
func TestMockFieldGetLimbs(t *testing.T) {
|
||||
emptyField := MockField{}
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.ElementsMatch(t, randLimbs, emptyField.GetLimbs(), "Limbs do not match; there was an issue with setting the MockField's limbs")
|
||||
}
|
||||
|
||||
func TestMockFieldOne(t *testing.T) {
|
||||
var emptyField MockField
|
||||
emptyField.One()
|
||||
limbOne := generateLimbOne(int(BASE_LIMBS))
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbOne, "Empty field to field one did not work")
|
||||
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
emptyField.One()
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbOne, "MockField with limbs to field one did not work")
|
||||
}
|
||||
|
||||
func TestMockFieldZero(t *testing.T) {
|
||||
var emptyField MockField
|
||||
emptyField.Zero()
|
||||
limbsZero := make([]uint32, BASE_LIMBS)
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbsZero, "Empty field to field zero failed")
|
||||
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
emptyField.Zero()
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbsZero, "MockField with limbs to field zero failed")
|
||||
}
|
||||
|
||||
func TestMockFieldSize(t *testing.T) {
|
||||
var emptyField MockField
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.Equal(t, len(randLimbs)*4, emptyField.Size(), "Size returned an incorrect value of bytes")
|
||||
}
|
||||
|
||||
func TestMockFieldAsPointer(t *testing.T) {
|
||||
var emptyField MockField
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.Equal(t, randLimbs[0], *emptyField.AsPointer(), "AsPointer returned pointer to incorrect value")
|
||||
}
|
||||
|
||||
func TestMockFieldFromBytes(t *testing.T) {
|
||||
var emptyField MockField
|
||||
bytes, expected := generateBytesArray(int(BASE_LIMBS))
|
||||
|
||||
emptyField.FromBytesLittleEndian(bytes)
|
||||
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), expected, "FromBytes returned incorrect values")
|
||||
}
|
||||
|
||||
func TestMockFieldToBytes(t *testing.T) {
|
||||
var emptyField MockField
|
||||
expected, limbs := generateBytesArray(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(limbs)
|
||||
|
||||
assert.ElementsMatch(t, emptyField.ToBytesLittleEndian(), expected, "ToBytes returned incorrect values")
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
func generateRandomLimb(size int) []uint32 {
|
||||
limbs := make([]uint32, size)
|
||||
for i := range limbs {
|
||||
limbs[i] = rand.Uint32()
|
||||
}
|
||||
return limbs
|
||||
}
|
||||
|
||||
func generateLimbOne(size int) []uint32 {
|
||||
limbs := make([]uint32, size)
|
||||
limbs[0] = 1
|
||||
return limbs
|
||||
}
|
||||
|
||||
func generateBytesArray(size int) ([]byte, []uint32) {
|
||||
baseBytes := []byte{1, 2, 3, 4}
|
||||
var bytes []byte
|
||||
var limbs []uint32
|
||||
for i := 0; i < size; i++ {
|
||||
bytes = append(bytes, baseBytes...)
|
||||
limbs = append(limbs, 67305985)
|
||||
}
|
||||
|
||||
return bytes, limbs
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package internal
|
||||
|
||||
type MockProjective struct {
|
||||
X, Y, Z MockField
|
||||
X, Y, Z MockBaseField
|
||||
}
|
||||
|
||||
func (p MockProjective) Size() int {
|
||||
@@ -29,7 +29,7 @@ func (p *MockProjective) FromLimbs(x, y, z []uint32) MockProjective {
|
||||
}
|
||||
|
||||
func (p *MockProjective) FromAffine(a MockAffine) MockProjective {
|
||||
z := MockField{}
|
||||
z := MockBaseField{}
|
||||
z.One()
|
||||
|
||||
p.X = a.X
|
||||
@@ -40,7 +40,7 @@ func (p *MockProjective) FromAffine(a MockAffine) MockProjective {
|
||||
}
|
||||
|
||||
type MockAffine struct {
|
||||
X, Y MockField
|
||||
X, Y MockBaseField
|
||||
}
|
||||
|
||||
func (a MockAffine) Size() int {
|
||||
@@ -66,7 +66,7 @@ func (a *MockAffine) FromLimbs(x, y []uint32) MockAffine {
|
||||
}
|
||||
|
||||
func (a MockAffine) ToProjective() MockProjective {
|
||||
var z MockField
|
||||
var z MockBaseField
|
||||
|
||||
return MockProjective{
|
||||
X: a.X,
|
||||
84
wrappers/golang/core/internal/mock_field.go
Normal file
84
wrappers/golang/core/internal/mock_field.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const (
|
||||
MOCKBASE_LIMBS int = 4
|
||||
)
|
||||
|
||||
type MockBaseField struct {
|
||||
limbs [MOCKBASE_LIMBS]uint32
|
||||
}
|
||||
|
||||
func (f MockBaseField) Len() int {
|
||||
return int(MOCKBASE_LIMBS)
|
||||
}
|
||||
|
||||
func (f MockBaseField) Size() int {
|
||||
return int(MOCKBASE_LIMBS * 4)
|
||||
}
|
||||
|
||||
func (f MockBaseField) GetLimbs() []uint32 {
|
||||
return f.limbs[:]
|
||||
}
|
||||
|
||||
func (f MockBaseField) AsPointer() *uint32 {
|
||||
return &f.limbs[0]
|
||||
}
|
||||
|
||||
func (f *MockBaseField) FromUint32(v uint32) MockBaseField {
|
||||
f.limbs[0] = v
|
||||
return *f
|
||||
}
|
||||
|
||||
func (f *MockBaseField) FromLimbs(limbs []uint32) MockBaseField {
|
||||
if len(limbs) != f.Len() {
|
||||
panic("Called FromLimbs with limbs of different length than field")
|
||||
}
|
||||
for i := range f.limbs {
|
||||
f.limbs[i] = limbs[i]
|
||||
}
|
||||
|
||||
return *f
|
||||
}
|
||||
|
||||
func (f *MockBaseField) Zero() MockBaseField {
|
||||
for i := range f.limbs {
|
||||
f.limbs[i] = 0
|
||||
}
|
||||
|
||||
return *f
|
||||
}
|
||||
|
||||
func (f *MockBaseField) One() MockBaseField {
|
||||
for i := range f.limbs {
|
||||
f.limbs[i] = 0
|
||||
}
|
||||
f.limbs[0] = 1
|
||||
|
||||
return *f
|
||||
}
|
||||
|
||||
func (f *MockBaseField) FromBytesLittleEndian(bytes []byte) MockBaseField {
|
||||
if len(bytes)/4 != f.Len() {
|
||||
panic(fmt.Sprintf("Called FromBytesLittleEndian with incorrect bytes length; expected %d - got %d", f.Len()*4, len(bytes)))
|
||||
}
|
||||
|
||||
for i := range f.limbs {
|
||||
f.limbs[i] = binary.LittleEndian.Uint32(bytes[i*4 : i*4+4])
|
||||
}
|
||||
|
||||
return *f
|
||||
}
|
||||
|
||||
func (f MockBaseField) ToBytesLittleEndian() []byte {
|
||||
bytes := make([]byte, f.Len()*4)
|
||||
for i, v := range f.limbs {
|
||||
binary.LittleEndian.PutUint32(bytes[i*4:], v)
|
||||
}
|
||||
|
||||
return bytes
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
)
|
||||
@@ -75,7 +76,7 @@ func GetDefaultMSMConfig() MSMConfig {
|
||||
}
|
||||
}
|
||||
|
||||
func MsmCheck(scalars HostOrDeviceSlice, points HostOrDeviceSlice, cfg *MSMConfig, results HostOrDeviceSlice) {
|
||||
func MsmCheck(scalars HostOrDeviceSlice, points HostOrDeviceSlice, cfg *MSMConfig, results HostOrDeviceSlice) (unsafe.Pointer, unsafe.Pointer, unsafe.Pointer, int, unsafe.Pointer) {
|
||||
scalarsLength, pointsLength, resultsLength := scalars.Len(), points.Len()/int(cfg.PrecomputeFactor), results.Len()
|
||||
if scalarsLength%pointsLength != 0 {
|
||||
errorString := fmt.Sprintf(
|
||||
@@ -98,9 +99,24 @@ func MsmCheck(scalars HostOrDeviceSlice, points HostOrDeviceSlice, cfg *MSMConfi
|
||||
cfg.areScalarsOnDevice = scalars.IsOnDevice()
|
||||
cfg.arePointsOnDevice = points.IsOnDevice()
|
||||
cfg.areResultsOnDevice = results.IsOnDevice()
|
||||
|
||||
if scalars.IsOnDevice() {
|
||||
scalars.(DeviceSlice).CheckDevice()
|
||||
}
|
||||
|
||||
if points.IsOnDevice() {
|
||||
points.(DeviceSlice).CheckDevice()
|
||||
}
|
||||
|
||||
if results.IsOnDevice() {
|
||||
results.(DeviceSlice).CheckDevice()
|
||||
}
|
||||
|
||||
size := scalars.Len() / results.Len()
|
||||
return scalars.AsUnsafePointer(), points.AsUnsafePointer(), results.AsUnsafePointer(), size, unsafe.Pointer(cfg)
|
||||
}
|
||||
|
||||
func PrecomputeBasesCheck(points HostOrDeviceSlice, precomputeFactor int32, outputBases DeviceSlice) {
|
||||
func PrecomputeBasesCheck(points HostOrDeviceSlice, precomputeFactor int32, outputBases DeviceSlice) (unsafe.Pointer, unsafe.Pointer) {
|
||||
outputBasesLength, pointsLength := outputBases.Len(), points.Len()
|
||||
if outputBasesLength != pointsLength*int(precomputeFactor) {
|
||||
errorString := fmt.Sprintf(
|
||||
@@ -110,4 +126,10 @@ func PrecomputeBasesCheck(points HostOrDeviceSlice, precomputeFactor int32, outp
|
||||
)
|
||||
panic(errorString)
|
||||
}
|
||||
|
||||
if points.IsOnDevice() {
|
||||
points.(DeviceSlice).CheckDevice()
|
||||
}
|
||||
|
||||
return points.AsUnsafePointer(), outputBases.AsUnsafePointer()
|
||||
}
|
||||
|
||||
@@ -36,19 +36,19 @@ func TestMSMDefaultConfig(t *testing.T) {
|
||||
func TestMSMCheckHostSlices(t *testing.T) {
|
||||
cfg := GetDefaultMSMConfig()
|
||||
|
||||
randLimbs := []uint32{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
rawScalars := make([]internal.MockField, 10)
|
||||
rawScalars := make([]internal.MockBaseField, 10)
|
||||
for i := range rawScalars {
|
||||
var emptyField internal.MockField
|
||||
emptyField.FromLimbs(randLimbs)
|
||||
var emptyField internal.MockBaseField
|
||||
emptyField.One()
|
||||
|
||||
rawScalars[i] = emptyField
|
||||
}
|
||||
scalars := HostSliceFromElements[internal.MockField](rawScalars)
|
||||
scalars := HostSliceFromElements[internal.MockBaseField](rawScalars)
|
||||
|
||||
affine := internal.MockAffine{}
|
||||
limbs := []uint32{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
affine.FromLimbs(limbs, limbs)
|
||||
var emptyField internal.MockBaseField
|
||||
emptyField.One()
|
||||
affine.FromLimbs(emptyField.GetLimbs(), emptyField.GetLimbs())
|
||||
rawAffinePoints := make([]internal.MockAffine, 10)
|
||||
for i := range rawAffinePoints {
|
||||
rawAffinePoints[i] = affine
|
||||
@@ -69,21 +69,21 @@ func TestMSMCheckHostSlices(t *testing.T) {
|
||||
func TestMSMCheckDeviceSlices(t *testing.T) {
|
||||
cfg := GetDefaultMSMConfig()
|
||||
|
||||
randLimbs := []uint32{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
rawScalars := make([]internal.MockField, 10)
|
||||
rawScalars := make([]internal.MockBaseField, 10)
|
||||
for i := range rawScalars {
|
||||
var emptyField internal.MockField
|
||||
emptyField.FromLimbs(randLimbs)
|
||||
var emptyField internal.MockBaseField
|
||||
emptyField.One()
|
||||
|
||||
rawScalars[i] = emptyField
|
||||
}
|
||||
scalars := HostSliceFromElements[internal.MockField](rawScalars)
|
||||
scalars := HostSliceFromElements[internal.MockBaseField](rawScalars)
|
||||
var scalarsOnDevice DeviceSlice
|
||||
scalars.CopyToDevice(&scalarsOnDevice, true)
|
||||
|
||||
affine := internal.MockAffine{}
|
||||
limbs := []uint32{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
affine.FromLimbs(limbs, limbs)
|
||||
var emptyField internal.MockBaseField
|
||||
emptyField.One()
|
||||
affine.FromLimbs(emptyField.GetLimbs(), emptyField.GetLimbs())
|
||||
rawAffinePoints := make([]internal.MockAffine, 10)
|
||||
for i := range rawAffinePoints {
|
||||
rawAffinePoints[i] = affine
|
||||
|
||||
@@ -2,6 +2,7 @@ package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
)
|
||||
@@ -67,7 +68,7 @@ func GetDefaultNTTConfig[T any](cosetGen T) NTTConfig[T] {
|
||||
}
|
||||
}
|
||||
|
||||
func NttCheck[T any](input HostOrDeviceSlice, cfg *NTTConfig[T], output HostOrDeviceSlice) {
|
||||
func NttCheck[T any](input HostOrDeviceSlice, cfg *NTTConfig[T], output HostOrDeviceSlice) (unsafe.Pointer, unsafe.Pointer, int, unsafe.Pointer) {
|
||||
inputLen, outputLen := input.Len(), output.Len()
|
||||
if inputLen != outputLen {
|
||||
errorString := fmt.Sprintf(
|
||||
@@ -79,4 +80,17 @@ func NttCheck[T any](input HostOrDeviceSlice, cfg *NTTConfig[T], output HostOrDe
|
||||
}
|
||||
cfg.areInputsOnDevice = input.IsOnDevice()
|
||||
cfg.areOutputsOnDevice = output.IsOnDevice()
|
||||
|
||||
if input.IsOnDevice() {
|
||||
input.(DeviceSlice).CheckDevice()
|
||||
}
|
||||
|
||||
if output.IsOnDevice() {
|
||||
output.(DeviceSlice).CheckDevice()
|
||||
}
|
||||
|
||||
size := input.Len() / int(cfg.BatchSize)
|
||||
cfgPointer := unsafe.Pointer(cfg)
|
||||
|
||||
return input.AsUnsafePointer(), output.AsUnsafePointer(), size, cfgPointer
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
// "unsafe"
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core/internal"
|
||||
@@ -10,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
func TestNTTDefaultConfig(t *testing.T) {
|
||||
var cosetGenField internal.MockField
|
||||
var cosetGenField internal.MockBaseField
|
||||
cosetGenField.One()
|
||||
var cosetGen [1]uint32
|
||||
copy(cosetGen[:], cosetGenField.GetLimbs())
|
||||
@@ -33,56 +32,52 @@ func TestNTTDefaultConfig(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNTTCheckHostScalars(t *testing.T) {
|
||||
randLimbs := []uint32{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
|
||||
var cosetGen internal.MockField
|
||||
cosetGen.FromLimbs(randLimbs)
|
||||
var cosetGen internal.MockBaseField
|
||||
cosetGen.One()
|
||||
cfg := GetDefaultNTTConfig(&cosetGen)
|
||||
|
||||
rawInput := make([]internal.MockField, 10)
|
||||
var emptyField internal.MockField
|
||||
emptyField.FromLimbs(randLimbs)
|
||||
rawInput := make([]internal.MockBaseField, 10)
|
||||
var emptyField internal.MockBaseField
|
||||
emptyField.One()
|
||||
|
||||
for i := range rawInput {
|
||||
rawInput[i] = emptyField
|
||||
}
|
||||
|
||||
input := HostSliceFromElements[internal.MockField](rawInput)
|
||||
output := HostSliceFromElements[internal.MockField](rawInput)
|
||||
input := HostSliceFromElements[internal.MockBaseField](rawInput)
|
||||
output := HostSliceFromElements[internal.MockBaseField](rawInput)
|
||||
assert.NotPanics(t, func() { NttCheck(input, &cfg, output) })
|
||||
assert.False(t, cfg.areInputsOnDevice)
|
||||
assert.False(t, cfg.areOutputsOnDevice)
|
||||
|
||||
rawInputLarger := make([]internal.MockField, 11)
|
||||
rawInputLarger := make([]internal.MockBaseField, 11)
|
||||
for i := range rawInputLarger {
|
||||
rawInputLarger[i] = emptyField
|
||||
}
|
||||
output2 := HostSliceFromElements[internal.MockField](rawInputLarger)
|
||||
output2 := HostSliceFromElements[internal.MockBaseField](rawInputLarger)
|
||||
assert.Panics(t, func() { NttCheck(input, &cfg, output2) })
|
||||
}
|
||||
|
||||
func TestNTTCheckDeviceScalars(t *testing.T) {
|
||||
randLimbs := []uint32{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
|
||||
var cosetGen internal.MockField
|
||||
cosetGen.FromLimbs(randLimbs)
|
||||
var cosetGen internal.MockBaseField
|
||||
cosetGen.One()
|
||||
cfg := GetDefaultNTTConfig(cosetGen)
|
||||
|
||||
fieldBytesSize := 16
|
||||
numFields := 10
|
||||
rawInput := make([]internal.MockField, numFields)
|
||||
rawInput := make([]internal.MockBaseField, numFields)
|
||||
for i := range rawInput {
|
||||
var emptyField internal.MockField
|
||||
emptyField.FromLimbs(randLimbs)
|
||||
var emptyField internal.MockBaseField
|
||||
emptyField.One()
|
||||
|
||||
rawInput[i] = emptyField
|
||||
}
|
||||
|
||||
hostElements := HostSliceFromElements[internal.MockField](rawInput)
|
||||
hostElements := HostSliceFromElements[internal.MockBaseField](rawInput)
|
||||
|
||||
var input DeviceSlice
|
||||
hostElements.CopyToDevice(&input, true)
|
||||
|
||||
fieldBytesSize := hostElements.SizeOfElement()
|
||||
var output DeviceSlice
|
||||
output.Malloc(numFields*fieldBytesSize, fieldBytesSize)
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ type HostOrDeviceSlice interface {
|
||||
Cap() int
|
||||
IsEmpty() bool
|
||||
IsOnDevice() bool
|
||||
AsUnsafePointer() unsafe.Pointer
|
||||
}
|
||||
|
||||
type DevicePointer = unsafe.Pointer
|
||||
@@ -35,7 +36,7 @@ func (d DeviceSlice) IsEmpty() bool {
|
||||
return d.length == 0
|
||||
}
|
||||
|
||||
func (d DeviceSlice) AsPointer() unsafe.Pointer {
|
||||
func (d DeviceSlice) AsUnsafePointer() unsafe.Pointer {
|
||||
return d.inner
|
||||
}
|
||||
|
||||
@@ -188,6 +189,14 @@ func (h HostSlice[T]) SizeOfElement() int {
|
||||
return int(unsafe.Sizeof(h[0]))
|
||||
}
|
||||
|
||||
func (h HostSlice[T]) AsPointer() *T {
|
||||
return &h[0]
|
||||
}
|
||||
|
||||
func (h HostSlice[T]) AsUnsafePointer() unsafe.Pointer {
|
||||
return unsafe.Pointer(&h[0])
|
||||
}
|
||||
|
||||
func (h HostSlice[T]) CopyToDevice(dst *DeviceSlice, shouldAllocate bool) *DeviceSlice {
|
||||
size := h.Len() * h.SizeOfElement()
|
||||
if shouldAllocate {
|
||||
@@ -198,8 +207,7 @@ func (h HostSlice[T]) CopyToDevice(dst *DeviceSlice, shouldAllocate bool) *Devic
|
||||
panic("Number of bytes to copy is too large for destination")
|
||||
}
|
||||
|
||||
hostSrc := unsafe.Pointer(&h[0])
|
||||
cr.CopyToDevice(dst.inner, hostSrc, uint(size))
|
||||
cr.CopyToDevice(dst.inner, h.AsUnsafePointer(), uint(size))
|
||||
dst.length = h.Len()
|
||||
return dst
|
||||
}
|
||||
@@ -214,8 +222,7 @@ func (h HostSlice[T]) CopyToDeviceAsync(dst *DeviceSlice, stream cr.CudaStream,
|
||||
panic("Number of bytes to copy is too large for destination")
|
||||
}
|
||||
|
||||
hostSrc := unsafe.Pointer(&h[0])
|
||||
cr.CopyToDeviceAsync(dst.inner, hostSrc, uint(size), stream)
|
||||
cr.CopyToDeviceAsync(dst.inner, h.AsUnsafePointer(), uint(size), stream)
|
||||
dst.length = h.Len()
|
||||
return dst
|
||||
}
|
||||
@@ -226,7 +233,7 @@ func (h HostSlice[T]) CopyFromDevice(src *DeviceSlice) {
|
||||
panic("destination and source slices have different lengths")
|
||||
}
|
||||
bytesSize := src.Len() * h.SizeOfElement()
|
||||
cr.CopyFromDevice(unsafe.Pointer(&h[0]), src.inner, uint(bytesSize))
|
||||
cr.CopyFromDevice(h.AsUnsafePointer(), src.inner, uint(bytesSize))
|
||||
}
|
||||
|
||||
func (h HostSlice[T]) CopyFromDeviceAsync(src *DeviceSlice, stream cr.Stream) {
|
||||
@@ -235,5 +242,5 @@ func (h HostSlice[T]) CopyFromDeviceAsync(src *DeviceSlice, stream cr.Stream) {
|
||||
panic("destination and source slices have different lengths")
|
||||
}
|
||||
bytesSize := src.Len() * h.SizeOfElement()
|
||||
cr.CopyFromDeviceAsync(unsafe.Pointer(&h[0]), src.inner, uint(bytesSize), stream)
|
||||
cr.CopyFromDeviceAsync(h.AsUnsafePointer(), src.inner, uint(bytesSize), stream)
|
||||
}
|
||||
|
||||
@@ -9,20 +9,20 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func randomField(size int) internal.MockField {
|
||||
func randomField(size int) internal.MockBaseField {
|
||||
limbs := make([]uint32, size)
|
||||
for i := range limbs {
|
||||
limbs[i] = rand.Uint32()
|
||||
}
|
||||
|
||||
var field internal.MockField
|
||||
var field internal.MockBaseField
|
||||
field.FromLimbs(limbs)
|
||||
|
||||
return field
|
||||
}
|
||||
|
||||
func randomFields(numFields, fieldSize int) []internal.MockField {
|
||||
var randFields []internal.MockField
|
||||
func randomFields(numFields, fieldSize int) []internal.MockBaseField {
|
||||
var randFields []internal.MockBaseField
|
||||
|
||||
for i := 0; i < numFields; i++ {
|
||||
randFields = append(randFields, randomField(fieldSize))
|
||||
@@ -67,12 +67,12 @@ func randomAffinePoints(numPoints, fieldSize int) []internal.MockAffine {
|
||||
const (
|
||||
numPoints = 4
|
||||
numFields = 4
|
||||
fieldSize = 8
|
||||
fieldSize = 4
|
||||
fieldBytesSize = fieldSize * 4
|
||||
)
|
||||
|
||||
func TestHostSlice(t *testing.T) {
|
||||
var emptyHostSlice HostSlice[internal.MockField]
|
||||
var emptyHostSlice HostSlice[internal.MockBaseField]
|
||||
assert.Equal(t, emptyHostSlice.Len(), 0)
|
||||
assert.Equal(t, emptyHostSlice.Cap(), 0)
|
||||
|
||||
@@ -82,13 +82,13 @@ func TestHostSlice(t *testing.T) {
|
||||
assert.Equal(t, hostSlice.Len(), 4)
|
||||
assert.Equal(t, hostSlice.Cap(), 4)
|
||||
|
||||
hostSliceCasted := (HostSlice[internal.MockField])(randFields)
|
||||
hostSliceCasted := (HostSlice[internal.MockBaseField])(randFields)
|
||||
assert.Equal(t, hostSliceCasted.Len(), 4)
|
||||
assert.Equal(t, hostSliceCasted.Cap(), 4)
|
||||
}
|
||||
|
||||
func TestHostSliceIsEmpty(t *testing.T) {
|
||||
var emptyHostSlice HostSlice[*internal.MockField]
|
||||
var emptyHostSlice HostSlice[*internal.MockBaseField]
|
||||
assert.True(t, emptyHostSlice.IsEmpty())
|
||||
|
||||
randFields := randomFields(numFields, fieldSize)
|
||||
@@ -98,7 +98,7 @@ func TestHostSliceIsEmpty(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHostSliceIsOnDevice(t *testing.T) {
|
||||
var emptyHostSlice HostSlice[*internal.MockField]
|
||||
var emptyHostSlice HostSlice[*internal.MockBaseField]
|
||||
assert.False(t, emptyHostSlice.IsOnDevice())
|
||||
}
|
||||
|
||||
@@ -112,17 +112,17 @@ func TestDeviceSlice(t *testing.T) {
|
||||
var emptyDeviceSlice DeviceSlice
|
||||
assert.Equal(t, 0, emptyDeviceSlice.Len())
|
||||
assert.Equal(t, 0, emptyDeviceSlice.Cap())
|
||||
assert.Equal(t, unsafe.Pointer(nil), emptyDeviceSlice.AsPointer())
|
||||
assert.Equal(t, unsafe.Pointer(nil), emptyDeviceSlice.AsUnsafePointer())
|
||||
|
||||
emptyDeviceSlice.Malloc(numFields*fieldBytesSize, fieldBytesSize)
|
||||
assert.Equal(t, numFields, emptyDeviceSlice.Len())
|
||||
assert.Equal(t, numFields*fieldBytesSize, emptyDeviceSlice.Cap())
|
||||
assert.NotEqual(t, unsafe.Pointer(nil), emptyDeviceSlice.AsPointer())
|
||||
assert.NotEqual(t, unsafe.Pointer(nil), emptyDeviceSlice.AsUnsafePointer())
|
||||
|
||||
emptyDeviceSlice.Free()
|
||||
assert.Equal(t, 0, emptyDeviceSlice.Len())
|
||||
assert.Equal(t, 0, emptyDeviceSlice.Cap())
|
||||
assert.Equal(t, unsafe.Pointer(nil), emptyDeviceSlice.AsPointer())
|
||||
assert.Equal(t, unsafe.Pointer(nil), emptyDeviceSlice.AsUnsafePointer())
|
||||
}
|
||||
|
||||
func TestDeviceSliceIsEmpty(t *testing.T) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
)
|
||||
@@ -23,8 +24,6 @@ type VecOpsConfig struct {
|
||||
isBOnDevice bool
|
||||
/* If true, output is preserved on device, otherwise on host. Default value: false. */
|
||||
isResultOnDevice bool
|
||||
/* True if `result` vector should be in Montgomery form and false otherwise. Default value: false. */
|
||||
IsResultMontgomeryForm bool
|
||||
/* Whether to run the vector operations asynchronously. If set to `true`, the function will be
|
||||
* non-blocking and you'll need to synchronize it explicitly by calling
|
||||
* `SynchronizeStream`. If set to false, the function will block the current CPU thread. */
|
||||
@@ -42,14 +41,13 @@ func DefaultVecOpsConfig() VecOpsConfig {
|
||||
false, // isAOnDevice
|
||||
false, // isBOnDevice
|
||||
false, // isResultOnDevice
|
||||
false, // IsResultMontgomeryForm
|
||||
false, // IsAsync
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
func VecOpCheck(a, b, out HostOrDeviceSlice, cfg *VecOpsConfig) {
|
||||
func VecOpCheck(a, b, out HostOrDeviceSlice, cfg *VecOpsConfig) (unsafe.Pointer, unsafe.Pointer, unsafe.Pointer, unsafe.Pointer, int) {
|
||||
aLen, bLen, outLen := a.Len(), b.Len(), out.Len()
|
||||
if aLen != bLen {
|
||||
errorString := fmt.Sprintf(
|
||||
@@ -68,7 +66,45 @@ func VecOpCheck(a, b, out HostOrDeviceSlice, cfg *VecOpsConfig) {
|
||||
panic(errorString)
|
||||
}
|
||||
|
||||
if a.IsOnDevice() {
|
||||
a.(DeviceSlice).CheckDevice()
|
||||
}
|
||||
if b.IsOnDevice() {
|
||||
b.(DeviceSlice).CheckDevice()
|
||||
}
|
||||
if out.IsOnDevice() {
|
||||
out.(DeviceSlice).CheckDevice()
|
||||
}
|
||||
|
||||
cfg.isAOnDevice = a.IsOnDevice()
|
||||
cfg.isBOnDevice = b.IsOnDevice()
|
||||
cfg.isResultOnDevice = out.IsOnDevice()
|
||||
|
||||
return a.AsUnsafePointer(), b.AsUnsafePointer(), out.AsUnsafePointer(), unsafe.Pointer(cfg), a.Len()
|
||||
}
|
||||
|
||||
func TransposeCheck(in, out HostOrDeviceSlice, onDevice bool) {
|
||||
inLen, outLen := in.Len(), out.Len()
|
||||
|
||||
if inLen != outLen {
|
||||
errorString := fmt.Sprintf(
|
||||
"in and out vector lengths %d; %d are not equal",
|
||||
inLen,
|
||||
outLen,
|
||||
)
|
||||
panic(errorString)
|
||||
}
|
||||
if (onDevice != in.IsOnDevice()) || (onDevice != out.IsOnDevice()) {
|
||||
errorString := fmt.Sprintf(
|
||||
"onDevice is set to %t, but in.IsOnDevice():%t and out.IsOnDevice():%t",
|
||||
onDevice,
|
||||
in.IsOnDevice(),
|
||||
out.IsOnDevice(),
|
||||
)
|
||||
panic(errorString)
|
||||
}
|
||||
if onDevice {
|
||||
in.(DeviceSlice).CheckDevice()
|
||||
out.(DeviceSlice).CheckDevice()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestVecOpsDefaultConfig(t *testing.T) {
|
||||
@@ -13,7 +14,6 @@ func TestVecOpsDefaultConfig(t *testing.T) {
|
||||
false, // isAOnDevice
|
||||
false, // isBOnDevice
|
||||
false, // isResultOnDevice
|
||||
false, // IsResultMontgomeryForm
|
||||
false, // IsAsync
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
BASE_LIMBS int8 = 12
|
||||
BASE_LIMBS int = 12
|
||||
)
|
||||
|
||||
type BaseField struct {
|
||||
@@ -29,6 +29,11 @@ func (f BaseField) AsPointer() *uint32 {
|
||||
return &f.limbs[0]
|
||||
}
|
||||
|
||||
func (f *BaseField) FromUint32(v uint32) BaseField {
|
||||
f.limbs[0] = v
|
||||
return *f
|
||||
}
|
||||
|
||||
func (f *BaseField) FromLimbs(limbs []uint32) BaseField {
|
||||
if len(limbs) != f.Len() {
|
||||
panic("Called FromLimbs with limbs of different length than field")
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
package bls12377
|
||||
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../../../icicle/build -lingo_bls12_377 -lstdc++ -lm
|
||||
import "C"
|
||||
@@ -53,7 +53,7 @@ func (p *Projective) FromAffine(a Affine) Projective {
|
||||
func (p Projective) ProjectiveEq(p2 *Projective) bool {
|
||||
cP := (*C.projective_t)(unsafe.Pointer(&p))
|
||||
cP2 := (*C.projective_t)(unsafe.Pointer(&p2))
|
||||
__ret := C.bls12_377Eq(cP, cP2)
|
||||
__ret := C.bls12_377_eq(cP, cP2)
|
||||
return __ret == (C._Bool)(true)
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ func (p *Projective) ProjectiveToAffine() Affine {
|
||||
|
||||
cA := (*C.affine_t)(unsafe.Pointer(&a))
|
||||
cP := (*C.projective_t)(unsafe.Pointer(&p))
|
||||
C.bls12_377ToAffine(cP, cA)
|
||||
C.bls12_377_to_affine(cP, cA)
|
||||
return a
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ func GenerateProjectivePoints(size int) core.HostSlice[Projective] {
|
||||
pointsSlice := core.HostSliceFromElements[Projective](points)
|
||||
pPoints := (*C.projective_t)(unsafe.Pointer(&pointsSlice[0]))
|
||||
cSize := (C.int)(size)
|
||||
C.bls12_377GenerateProjectivePoints(pPoints, cSize)
|
||||
C.bls12_377_generate_projective_points(pPoints, cSize)
|
||||
|
||||
return pointsSlice
|
||||
}
|
||||
@@ -129,18 +129,18 @@ func GenerateAffinePoints(size int) core.HostSlice[Affine] {
|
||||
pointsSlice := core.HostSliceFromElements[Affine](points)
|
||||
cPoints := (*C.affine_t)(unsafe.Pointer(&pointsSlice[0]))
|
||||
cSize := (C.int)(size)
|
||||
C.bls12_377GenerateAffinePoints(cPoints, cSize)
|
||||
C.bls12_377_generate_affine_points(cPoints, cSize)
|
||||
|
||||
return pointsSlice
|
||||
}
|
||||
|
||||
func convertAffinePointsMontgomery(points *core.DeviceSlice, isInto bool) cr.CudaError {
|
||||
cValues := (*C.affine_t)(points.AsPointer())
|
||||
cValues := (*C.affine_t)(points.AsUnsafePointer())
|
||||
cSize := (C.size_t)(points.Len())
|
||||
cIsInto := (C._Bool)(isInto)
|
||||
defaultCtx, _ := cr.GetDefaultDeviceContext()
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&defaultCtx))
|
||||
__ret := C.bls12_377AffineConvertMontgomery(cValues, cSize, cIsInto, cCtx)
|
||||
__ret := C.bls12_377_affine_convert_montgomery(cValues, cSize, cIsInto, cCtx)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
@@ -156,12 +156,12 @@ func AffineFromMontgomery(points *core.DeviceSlice) cr.CudaError {
|
||||
}
|
||||
|
||||
func convertProjectivePointsMontgomery(points *core.DeviceSlice, isInto bool) cr.CudaError {
|
||||
cValues := (*C.projective_t)(points.AsPointer())
|
||||
cValues := (*C.projective_t)(points.AsUnsafePointer())
|
||||
cSize := (C.size_t)(points.Len())
|
||||
cIsInto := (C._Bool)(isInto)
|
||||
defaultCtx, _ := cr.GetDefaultDeviceContext()
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&defaultCtx))
|
||||
__ret := C.bls12_377ProjectiveConvertMontgomery(cValues, cSize, cIsInto, cCtx)
|
||||
__ret := C.bls12_377_projective_convert_montgomery(cValues, cSize, cIsInto, cCtx)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
24
wrappers/golang/curves/bls12377/ecntt/ecntt.go
Normal file
24
wrappers/golang/curves/bls12377/ecntt/ecntt.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package ecntt
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "ecntt.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
)
|
||||
|
||||
func ECNtt[T any](points core.HostOrDeviceSlice, dir core.NTTDir, cfg *core.NTTConfig[T], results core.HostOrDeviceSlice) core.IcicleError {
|
||||
pointsPointer, resultsPointer, size, cfgPointer := core.NttCheck[T](points, cfg, results)
|
||||
|
||||
cPoints := (*C.projective_t)(pointsPointer)
|
||||
cSize := (C.int)(size)
|
||||
cDir := (C.int)(dir)
|
||||
cCfg := (*C.NTTConfig)(cfgPointer)
|
||||
cResults := (*C.projective_t)(resultsPointer)
|
||||
|
||||
__ret := C.bls12_377_ecntt_cuda(cPoints, cSize, cDir, cCfg, cResults)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
19
wrappers/golang/curves/bls12377/ecntt/include/ecntt.h
Normal file
19
wrappers/golang/curves/bls12377/ecntt/include/ecntt.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <cuda_runtime.h>
|
||||
|
||||
#ifndef _BLS12_377_ECNTT_H
|
||||
#define _BLS12_377_ECNTT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct NTTConfig NTTConfig;
|
||||
typedef struct projective_t projective_t;
|
||||
|
||||
cudaError_t bls12_377_ecntt_cuda(const projective_t* input, int size, int dir, NTTConfig* config, projective_t* output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,9 +1,7 @@
|
||||
//go:build g2
|
||||
|
||||
package bls12381
|
||||
package g2
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "g2_curve.h"
|
||||
// #include "curve.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
@@ -55,7 +53,7 @@ func (p *G2Projective) FromAffine(a G2Affine) G2Projective {
|
||||
func (p G2Projective) ProjectiveEq(p2 *G2Projective) bool {
|
||||
cP := (*C.g2_projective_t)(unsafe.Pointer(&p))
|
||||
cP2 := (*C.g2_projective_t)(unsafe.Pointer(&p2))
|
||||
__ret := C.bls12_381G2Eq(cP, cP2)
|
||||
__ret := C.bls12_377_g2_eq(cP, cP2)
|
||||
return __ret == (C._Bool)(true)
|
||||
}
|
||||
|
||||
@@ -64,7 +62,7 @@ func (p *G2Projective) ProjectiveToAffine() G2Affine {
|
||||
|
||||
cA := (*C.g2_affine_t)(unsafe.Pointer(&a))
|
||||
cP := (*C.g2_projective_t)(unsafe.Pointer(&p))
|
||||
C.bls12_381G2ToAffine(cP, cA)
|
||||
C.bls12_377_g2_to_affine(cP, cA)
|
||||
return a
|
||||
}
|
||||
|
||||
@@ -77,7 +75,7 @@ func G2GenerateProjectivePoints(size int) core.HostSlice[G2Projective] {
|
||||
pointsSlice := core.HostSliceFromElements[G2Projective](points)
|
||||
pPoints := (*C.g2_projective_t)(unsafe.Pointer(&pointsSlice[0]))
|
||||
cSize := (C.int)(size)
|
||||
C.bls12_381G2GenerateProjectivePoints(pPoints, cSize)
|
||||
C.bls12_377_g2_generate_projective_points(pPoints, cSize)
|
||||
|
||||
return pointsSlice
|
||||
}
|
||||
@@ -131,18 +129,18 @@ func G2GenerateAffinePoints(size int) core.HostSlice[G2Affine] {
|
||||
pointsSlice := core.HostSliceFromElements[G2Affine](points)
|
||||
cPoints := (*C.g2_affine_t)(unsafe.Pointer(&pointsSlice[0]))
|
||||
cSize := (C.int)(size)
|
||||
C.bls12_381G2GenerateAffinePoints(cPoints, cSize)
|
||||
C.bls12_377_g2_generate_affine_points(cPoints, cSize)
|
||||
|
||||
return pointsSlice
|
||||
}
|
||||
|
||||
func convertG2AffinePointsMontgomery(points *core.DeviceSlice, isInto bool) cr.CudaError {
|
||||
cValues := (*C.g2_affine_t)(points.AsPointer())
|
||||
cValues := (*C.g2_affine_t)(points.AsUnsafePointer())
|
||||
cSize := (C.size_t)(points.Len())
|
||||
cIsInto := (C._Bool)(isInto)
|
||||
defaultCtx, _ := cr.GetDefaultDeviceContext()
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&defaultCtx))
|
||||
__ret := C.bls12_381G2AffineConvertMontgomery(cValues, cSize, cIsInto, cCtx)
|
||||
__ret := C.bls12_377_g2_affine_convert_montgomery(cValues, cSize, cIsInto, cCtx)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
@@ -158,12 +156,12 @@ func G2AffineFromMontgomery(points *core.DeviceSlice) cr.CudaError {
|
||||
}
|
||||
|
||||
func convertG2ProjectivePointsMontgomery(points *core.DeviceSlice, isInto bool) cr.CudaError {
|
||||
cValues := (*C.g2_projective_t)(points.AsPointer())
|
||||
cValues := (*C.g2_projective_t)(points.AsUnsafePointer())
|
||||
cSize := (C.size_t)(points.Len())
|
||||
cIsInto := (C._Bool)(isInto)
|
||||
defaultCtx, _ := cr.GetDefaultDeviceContext()
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&defaultCtx))
|
||||
__ret := C.bls12_381G2ProjectiveConvertMontgomery(cValues, cSize, cIsInto, cCtx)
|
||||
__ret := C.bls12_377_g2_projective_convert_montgomery(cValues, cSize, cIsInto, cCtx)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
//go:build g2
|
||||
|
||||
package bn254
|
||||
package g2
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
@@ -8,19 +6,19 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
G2_BASE_LIMBS int8 = 16
|
||||
G2BASE_LIMBS int = 24
|
||||
)
|
||||
|
||||
type G2BaseField struct {
|
||||
limbs [G2_BASE_LIMBS]uint32
|
||||
limbs [G2BASE_LIMBS]uint32
|
||||
}
|
||||
|
||||
func (f G2BaseField) Len() int {
|
||||
return int(G2_BASE_LIMBS)
|
||||
return int(G2BASE_LIMBS)
|
||||
}
|
||||
|
||||
func (f G2BaseField) Size() int {
|
||||
return int(G2_BASE_LIMBS * 4)
|
||||
return int(G2BASE_LIMBS * 4)
|
||||
}
|
||||
|
||||
func (f G2BaseField) GetLimbs() []uint32 {
|
||||
@@ -31,6 +29,11 @@ func (f G2BaseField) AsPointer() *uint32 {
|
||||
return &f.limbs[0]
|
||||
}
|
||||
|
||||
func (f *G2BaseField) FromUint32(v uint32) G2BaseField {
|
||||
f.limbs[0] = v
|
||||
return *f
|
||||
}
|
||||
|
||||
func (f *G2BaseField) FromLimbs(limbs []uint32) G2BaseField {
|
||||
if len(limbs) != f.Len() {
|
||||
panic("Called FromLimbs with limbs of different length than field")
|
||||
26
wrappers/golang/curves/bls12377/g2/include/curve.h
Normal file
26
wrappers/golang/curves/bls12377/g2/include/curve.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_377_G2CURVE_H
|
||||
#define _BLS12_377_G2CURVE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct g2_projective_t g2_projective_t;
|
||||
typedef struct g2_affine_t g2_affine_t;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
|
||||
bool bls12_377_g2_eq(g2_projective_t* point1, g2_projective_t* point2);
|
||||
void bls12_377_g2_to_affine(g2_projective_t* point, g2_affine_t* point_out);
|
||||
void bls12_377_g2_generate_projective_points(g2_projective_t* points, int size);
|
||||
void bls12_377_g2_generate_affine_points(g2_affine_t* points, int size);
|
||||
cudaError_t bls12_377_g2_affine_convert_montgomery(g2_affine_t* points, size_t n, bool is_into, DeviceContext* ctx);
|
||||
cudaError_t bls12_377_g2_projective_convert_montgomery(g2_projective_t* points, size_t n, bool is_into, DeviceContext* ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
24
wrappers/golang/curves/bls12377/g2/include/msm.h
Normal file
24
wrappers/golang/curves/bls12377/g2/include/msm.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_377_G2MSM_H
|
||||
#define _BLS12_377_G2MSM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct scalar_t scalar_t;
|
||||
typedef struct g2_projective_t g2_projective_t;
|
||||
typedef struct g2_affine_t g2_affine_t;
|
||||
typedef struct MSMConfig MSMConfig;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
|
||||
cudaError_t bls12_377_g2_msm_cuda(const scalar_t* scalars,const g2_affine_t* points, int count, MSMConfig* config, g2_projective_t* out);
|
||||
cudaError_t bls12_377_g2_precompute_msm_bases_cuda(g2_affine_t* points, int count, int precompute_factor, int _c, bool bases_on_device, DeviceContext* ctx, g2_affine_t* out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
21
wrappers/golang/curves/bls12377/g2/include/scalar_field.h
Normal file
21
wrappers/golang/curves/bls12377/g2/include/scalar_field.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_377_FIELD_H
|
||||
#define _BLS12_377_FIELD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct scalar_t scalar_t;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
|
||||
void bls12_377_generate_scalars(scalar_t* scalars, int size);
|
||||
cudaError_t bls12_377_scalar_convert_montgomery(scalar_t* d_inout, size_t n, bool is_into, DeviceContext* ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
45
wrappers/golang/curves/bls12377/g2/msm.go
Normal file
45
wrappers/golang/curves/bls12377/g2/msm.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package g2
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "msm.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func G2GetDefaultMSMConfig() core.MSMConfig {
|
||||
return core.GetDefaultMSMConfig()
|
||||
}
|
||||
|
||||
func G2Msm(scalars core.HostOrDeviceSlice, points core.HostOrDeviceSlice, cfg *core.MSMConfig, results core.HostOrDeviceSlice) cr.CudaError {
|
||||
scalarsPointer, pointsPointer, resultsPointer, size, cfgPointer := core.MsmCheck(scalars, points, cfg, results)
|
||||
|
||||
cScalars := (*C.scalar_t)(scalarsPointer)
|
||||
cPoints := (*C.g2_affine_t)(pointsPointer)
|
||||
cResults := (*C.g2_projective_t)(resultsPointer)
|
||||
cSize := (C.int)(size)
|
||||
cCfg := (*C.MSMConfig)(cfgPointer)
|
||||
|
||||
__ret := C.bls12_377_g2_msm_cuda(cScalars, cPoints, cSize, cCfg, cResults)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
func G2PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c int32, ctx *cr.DeviceContext, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputeBasesCheck(points, precomputeFactor, outputBases)
|
||||
|
||||
cPoints := (*C.g2_affine_t)(pointsPointer)
|
||||
cPointsLen := (C.int)(points.Len())
|
||||
cPrecomputeFactor := (C.int)(precomputeFactor)
|
||||
cC := (C.int)(c)
|
||||
cPointsIsOnDevice := (C._Bool)(points.IsOnDevice())
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(ctx))
|
||||
cOutputBases := (*C.g2_affine_t)(outputBasesPointer)
|
||||
|
||||
__ret := C.bls12_377_g2_precompute_msm_bases_cuda(cPoints, cPointsLen, cPrecomputeFactor, cC, cPointsIsOnDevice, cCtx, cOutputBases)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
//go:build g2
|
||||
|
||||
package bls12377
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "g2_msm.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func G2GetDefaultMSMConfig() core.MSMConfig {
|
||||
return core.GetDefaultMSMConfig()
|
||||
}
|
||||
|
||||
func G2Msm(scalars core.HostOrDeviceSlice, points core.HostOrDeviceSlice, cfg *core.MSMConfig, results core.HostOrDeviceSlice) cr.CudaError {
|
||||
core.MsmCheck(scalars, points, cfg, results)
|
||||
var scalarsPointer unsafe.Pointer
|
||||
if scalars.IsOnDevice() {
|
||||
scalarsDevice := scalars.(core.DeviceSlice)
|
||||
scalarsDevice.CheckDevice()
|
||||
scalarsPointer = scalarsDevice.AsPointer()
|
||||
} else {
|
||||
scalarsPointer = unsafe.Pointer(&scalars.(core.HostSlice[ScalarField])[0])
|
||||
}
|
||||
cScalars := (*C.scalar_t)(scalarsPointer)
|
||||
|
||||
var pointsPointer unsafe.Pointer
|
||||
if points.IsOnDevice() {
|
||||
pointsDevice := points.(core.DeviceSlice)
|
||||
pointsDevice.CheckDevice()
|
||||
pointsPointer = pointsDevice.AsPointer()
|
||||
} else {
|
||||
pointsPointer = unsafe.Pointer(&points.(core.HostSlice[G2Affine])[0])
|
||||
}
|
||||
cPoints := (*C.g2_affine_t)(pointsPointer)
|
||||
|
||||
var resultsPointer unsafe.Pointer
|
||||
if results.IsOnDevice() {
|
||||
resultsDevice := results.(core.DeviceSlice)
|
||||
resultsDevice.CheckDevice()
|
||||
resultsPointer = resultsDevice.AsPointer()
|
||||
} else {
|
||||
resultsPointer = unsafe.Pointer(&results.(core.HostSlice[G2Projective])[0])
|
||||
}
|
||||
cResults := (*C.g2_projective_t)(resultsPointer)
|
||||
|
||||
cSize := (C.int)(scalars.Len() / results.Len())
|
||||
cCfg := (*C.MSMConfig)(unsafe.Pointer(cfg))
|
||||
|
||||
__ret := C.bls12_377G2MSMCuda(cScalars, cPoints, cSize, cCfg, cResults)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
func G2PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c int32, ctx *cr.DeviceContext, outputBases core.DeviceSlice) cr.CudaError {
|
||||
core.PrecomputeBasesCheck(points, precomputeFactor, outputBases)
|
||||
|
||||
var pointsPointer unsafe.Pointer
|
||||
if points.IsOnDevice() {
|
||||
pointsPointer = points.(core.DeviceSlice).AsPointer()
|
||||
} else {
|
||||
pointsPointer = unsafe.Pointer(&points.(core.HostSlice[G2Affine])[0])
|
||||
}
|
||||
cPoints := (*C.g2_affine_t)(pointsPointer)
|
||||
|
||||
cPointsLen := (C.int)(points.Len())
|
||||
cPrecomputeFactor := (C.int)(precomputeFactor)
|
||||
cC := (C.int)(c)
|
||||
cPointsIsOnDevice := (C._Bool)(points.IsOnDevice())
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(ctx))
|
||||
|
||||
outputBasesPointer := outputBases.AsPointer()
|
||||
cOutputBases := (*C.g2_affine_t)(outputBasesPointer)
|
||||
|
||||
__ret := C.bls12_377G2PrecomputeMSMBases(cPoints, cPointsLen, cPrecomputeFactor, cC, cPointsIsOnDevice, cCtx, cOutputBases)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package bls12377
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
func generateRandomLimb(size int) []uint32 {
|
||||
limbs := make([]uint32, size)
|
||||
for i := range limbs {
|
||||
limbs[i] = rand.Uint32()
|
||||
}
|
||||
return limbs
|
||||
}
|
||||
|
||||
func generateLimbOne(size int) []uint32 {
|
||||
limbs := make([]uint32, size)
|
||||
limbs[0] = 1
|
||||
return limbs
|
||||
}
|
||||
|
||||
func generateBytesArray(size int) ([]byte, []uint32) {
|
||||
baseBytes := []byte{1, 2, 3, 4}
|
||||
var bytes []byte
|
||||
var limbs []uint32
|
||||
for i := 0; i < size; i++ {
|
||||
bytes = append(bytes, baseBytes...)
|
||||
limbs = append(limbs, 67305985)
|
||||
}
|
||||
|
||||
return bytes, limbs
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include "../../include/types.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_377_CURVE_H
|
||||
@@ -9,12 +8,16 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool bls12_377Eq(projective_t* point1, projective_t* point2);
|
||||
void bls12_377ToAffine(projective_t* point, affine_t* point_out);
|
||||
void bls12_377GenerateProjectivePoints(projective_t* points, int size);
|
||||
void bls12_377GenerateAffinePoints(affine_t* points, int size);
|
||||
cudaError_t bls12_377AffineConvertMontgomery(affine_t* points, size_t n, bool is_into, DeviceContext* ctx);
|
||||
cudaError_t bls12_377ProjectiveConvertMontgomery(projective_t* points, size_t n, bool is_into, DeviceContext* ctx);
|
||||
typedef struct projective_t projective_t;
|
||||
typedef struct affine_t affine_t;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
|
||||
bool bls12_377_eq(projective_t* point1, projective_t* point2);
|
||||
void bls12_377_to_affine(projective_t* point, affine_t* point_out);
|
||||
void bls12_377_generate_projective_points(projective_t* points, int size);
|
||||
void bls12_377_generate_affine_points(affine_t* points, int size);
|
||||
cudaError_t bls12_377_affine_convert_montgomery(affine_t* points, size_t n, bool is_into, DeviceContext* ctx);
|
||||
cudaError_t bls12_377_projective_convert_montgomery(projective_t* points, size_t n, bool is_into, DeviceContext* ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include "../../include/types.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_377_G2CURVE_H
|
||||
#define _BLS12_377_G2CURVE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool bls12_377G2Eq(g2_projective_t* point1, g2_projective_t* point2);
|
||||
void bls12_377G2ToAffine(g2_projective_t* point, g2_affine_t* point_out);
|
||||
void bls12_377G2GenerateProjectivePoints(g2_projective_t* points, int size);
|
||||
void bls12_377G2GenerateAffinePoints(g2_affine_t* points, int size);
|
||||
cudaError_t bls12_377G2AffineConvertMontgomery(g2_affine_t* points, size_t n, bool is_into, DeviceContext* ctx);
|
||||
cudaError_t bls12_377G2ProjectiveConvertMontgomery(g2_projective_t* points, size_t n, bool is_into, DeviceContext* ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,19 +0,0 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include "../../include/types.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_377_G2MSM_H
|
||||
#define _BLS12_377_G2MSM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
cudaError_t bls12_377G2MSMCuda(const scalar_t* scalars,const g2_affine_t* points, int count, MSMConfig* config, g2_projective_t* out);
|
||||
cudaError_t bls12_377G2PrecomputeMSMBases(g2_affine_t* points, int count, int precompute_factor, int _c, bool bases_on_device, DeviceContext* ctx, g2_affine_t* out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,19 +0,0 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include "../../include/types.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_377_MSM_H
|
||||
#define _BLS12_377_MSM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
cudaError_t bls12_377MSMCuda(const scalar_t* scalars, const affine_t* points, int count, MSMConfig* config, projective_t* out);
|
||||
cudaError_t bls12_377PrecomputeMSMBases(affine_t* points, int bases_size, int precompute_factor, int _c, bool are_bases_on_device, DeviceContext* ctx, affine_t* output_bases);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,21 +0,0 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include "../../include/types.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_377_NTT_H
|
||||
#define _BLS12_377_NTT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
cudaError_t bls12_377NTTCuda(const scalar_t* input, int size, int dir, NTTConfig* config, scalar_t* output);
|
||||
cudaError_t bls12_377ECNTTCuda(const projective_t* input, int size, int dir, NTTConfig* config, projective_t* output);
|
||||
cudaError_t bls12_377InitializeDomain(scalar_t* primitive_root, DeviceContext* ctx, bool fast_twiddles);
|
||||
cudaError_t bls12_377ReleaseDomain(DeviceContext* ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,4 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include "../../include/types.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_377_FIELD_H
|
||||
@@ -9,8 +8,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void bls12_377GenerateScalars(scalar_t* scalars, int size);
|
||||
cudaError_t bls12_377ScalarConvertMontgomery(scalar_t* d_inout, size_t n, bool is_into, DeviceContext* ctx);
|
||||
typedef struct scalar_t scalar_t;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
|
||||
void bls12_377_generate_scalars(scalar_t* scalars, int size);
|
||||
cudaError_t bls12_377_scalar_convert_montgomery(scalar_t* d_inout, size_t n, bool is_into, DeviceContext* ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
4
wrappers/golang/curves/bls12377/main.go
Normal file
4
wrappers/golang/curves/bls12377/main.go
Normal file
@@ -0,0 +1,4 @@
|
||||
package bls12377
|
||||
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../../../icicle/build/lib -lingo_curve_bls12_377 -lingo_field_bls12_377 -lstdc++ -lm
|
||||
import "C"
|
||||
@@ -1,80 +0,0 @@
|
||||
package bls12377
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "msm.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func GetDefaultMSMConfig() core.MSMConfig {
|
||||
return core.GetDefaultMSMConfig()
|
||||
}
|
||||
|
||||
func Msm(scalars core.HostOrDeviceSlice, points core.HostOrDeviceSlice, cfg *core.MSMConfig, results core.HostOrDeviceSlice) cr.CudaError {
|
||||
core.MsmCheck(scalars, points, cfg, results)
|
||||
var scalarsPointer unsafe.Pointer
|
||||
if scalars.IsOnDevice() {
|
||||
scalarsDevice := scalars.(core.DeviceSlice)
|
||||
scalarsDevice.CheckDevice()
|
||||
scalarsPointer = scalarsDevice.AsPointer()
|
||||
} else {
|
||||
scalarsPointer = unsafe.Pointer(&scalars.(core.HostSlice[ScalarField])[0])
|
||||
}
|
||||
cScalars := (*C.scalar_t)(scalarsPointer)
|
||||
|
||||
var pointsPointer unsafe.Pointer
|
||||
if points.IsOnDevice() {
|
||||
pointsDevice := points.(core.DeviceSlice)
|
||||
pointsDevice.CheckDevice()
|
||||
pointsPointer = pointsDevice.AsPointer()
|
||||
} else {
|
||||
pointsPointer = unsafe.Pointer(&points.(core.HostSlice[Affine])[0])
|
||||
}
|
||||
cPoints := (*C.affine_t)(pointsPointer)
|
||||
|
||||
var resultsPointer unsafe.Pointer
|
||||
if results.IsOnDevice() {
|
||||
resultsDevice := results.(core.DeviceSlice)
|
||||
resultsDevice.CheckDevice()
|
||||
resultsPointer = resultsDevice.AsPointer()
|
||||
} else {
|
||||
resultsPointer = unsafe.Pointer(&results.(core.HostSlice[Projective])[0])
|
||||
}
|
||||
cResults := (*C.projective_t)(resultsPointer)
|
||||
|
||||
cSize := (C.int)(scalars.Len() / results.Len())
|
||||
cCfg := (*C.MSMConfig)(unsafe.Pointer(cfg))
|
||||
|
||||
__ret := C.bls12_377MSMCuda(cScalars, cPoints, cSize, cCfg, cResults)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
func PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c int32, ctx *cr.DeviceContext, outputBases core.DeviceSlice) cr.CudaError {
|
||||
core.PrecomputeBasesCheck(points, precomputeFactor, outputBases)
|
||||
|
||||
var pointsPointer unsafe.Pointer
|
||||
if points.IsOnDevice() {
|
||||
pointsPointer = points.(core.DeviceSlice).AsPointer()
|
||||
} else {
|
||||
pointsPointer = unsafe.Pointer(&points.(core.HostSlice[Affine])[0])
|
||||
}
|
||||
cPoints := (*C.affine_t)(pointsPointer)
|
||||
|
||||
cPointsLen := (C.int)(points.Len())
|
||||
cPrecomputeFactor := (C.int)(precomputeFactor)
|
||||
cC := (C.int)(c)
|
||||
cPointsIsOnDevice := (C._Bool)(points.IsOnDevice())
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(ctx))
|
||||
|
||||
outputBasesPointer := outputBases.AsPointer()
|
||||
cOutputBases := (*C.affine_t)(outputBasesPointer)
|
||||
|
||||
__ret := C.bls12_377PrecomputeMSMBases(cPoints, cPointsLen, cPrecomputeFactor, cC, cPointsIsOnDevice, cCtx, cOutputBases)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
24
wrappers/golang/curves/bls12377/msm/include/msm.h
Normal file
24
wrappers/golang/curves/bls12377/msm/include/msm.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_377_MSM_H
|
||||
#define _BLS12_377_MSM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct scalar_t scalar_t;
|
||||
typedef struct projective_t projective_t;
|
||||
typedef struct affine_t affine_t;
|
||||
typedef struct MSMConfig MSMConfig;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
|
||||
cudaError_t bls12_377_msm_cuda(const scalar_t* scalars,const affine_t* points, int count, MSMConfig* config, projective_t* out);
|
||||
cudaError_t bls12_377_precompute_msm_bases_cuda(affine_t* points, int count, int precompute_factor, int _c, bool bases_on_device, DeviceContext* ctx, affine_t* out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
45
wrappers/golang/curves/bls12377/msm/msm.go
Normal file
45
wrappers/golang/curves/bls12377/msm/msm.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package msm
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "msm.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func GetDefaultMSMConfig() core.MSMConfig {
|
||||
return core.GetDefaultMSMConfig()
|
||||
}
|
||||
|
||||
func Msm(scalars core.HostOrDeviceSlice, points core.HostOrDeviceSlice, cfg *core.MSMConfig, results core.HostOrDeviceSlice) cr.CudaError {
|
||||
scalarsPointer, pointsPointer, resultsPointer, size, cfgPointer := core.MsmCheck(scalars, points, cfg, results)
|
||||
|
||||
cScalars := (*C.scalar_t)(scalarsPointer)
|
||||
cPoints := (*C.affine_t)(pointsPointer)
|
||||
cResults := (*C.projective_t)(resultsPointer)
|
||||
cSize := (C.int)(size)
|
||||
cCfg := (*C.MSMConfig)(cfgPointer)
|
||||
|
||||
__ret := C.bls12_377_msm_cuda(cScalars, cPoints, cSize, cCfg, cResults)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
func PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c int32, ctx *cr.DeviceContext, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputeBasesCheck(points, precomputeFactor, outputBases)
|
||||
|
||||
cPoints := (*C.affine_t)(pointsPointer)
|
||||
cPointsLen := (C.int)(points.Len())
|
||||
cPrecomputeFactor := (C.int)(precomputeFactor)
|
||||
cC := (C.int)(c)
|
||||
cPointsIsOnDevice := (C._Bool)(points.IsOnDevice())
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(ctx))
|
||||
cOutputBases := (*C.affine_t)(outputBasesPointer)
|
||||
|
||||
__ret := C.bls12_377_precompute_msm_bases_cuda(cPoints, cPointsLen, cPrecomputeFactor, cC, cPointsIsOnDevice, cCtx, cOutputBases)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
package bls12377
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "ntt.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
)
|
||||
|
||||
func GetDefaultNttConfig() core.NTTConfig[[SCALAR_LIMBS]uint32] {
|
||||
cosetGenField := ScalarField{}
|
||||
cosetGenField.One()
|
||||
var cosetGen [SCALAR_LIMBS]uint32
|
||||
for i, v := range cosetGenField.GetLimbs() {
|
||||
cosetGen[i] = v
|
||||
}
|
||||
|
||||
return core.GetDefaultNTTConfig(cosetGen)
|
||||
}
|
||||
|
||||
func Ntt[T any](scalars core.HostOrDeviceSlice, dir core.NTTDir, cfg *core.NTTConfig[T], results core.HostOrDeviceSlice) core.IcicleError {
|
||||
core.NttCheck[T](scalars, cfg, results)
|
||||
|
||||
var scalarsPointer unsafe.Pointer
|
||||
if scalars.IsOnDevice() {
|
||||
scalarsDevice := scalars.(core.DeviceSlice)
|
||||
scalarsDevice.CheckDevice()
|
||||
scalarsPointer = scalarsDevice.AsPointer()
|
||||
} else {
|
||||
scalarsPointer = unsafe.Pointer(&scalars.(core.HostSlice[ScalarField])[0])
|
||||
}
|
||||
cScalars := (*C.scalar_t)(scalarsPointer)
|
||||
cSize := (C.int)(scalars.Len() / int(cfg.BatchSize))
|
||||
cDir := (C.int)(dir)
|
||||
cCfg := (*C.NTTConfig)(unsafe.Pointer(cfg))
|
||||
|
||||
var resultsPointer unsafe.Pointer
|
||||
if results.IsOnDevice() {
|
||||
resultsDevice := results.(core.DeviceSlice)
|
||||
resultsDevice.CheckDevice()
|
||||
resultsPointer = resultsDevice.AsPointer()
|
||||
} else {
|
||||
resultsPointer = unsafe.Pointer(&results.(core.HostSlice[ScalarField])[0])
|
||||
}
|
||||
cResults := (*C.scalar_t)(resultsPointer)
|
||||
|
||||
__ret := C.bls12_377NTTCuda(cScalars, cSize, cDir, cCfg, cResults)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func ECNtt[T any](points core.HostOrDeviceSlice, dir core.NTTDir, cfg *core.NTTConfig[T], results core.HostOrDeviceSlice) core.IcicleError {
|
||||
core.NttCheck[T](points, cfg, results)
|
||||
|
||||
var pointsPointer unsafe.Pointer
|
||||
if points.IsOnDevice() {
|
||||
pointsPointer = points.(core.DeviceSlice).AsPointer()
|
||||
} else {
|
||||
pointsPointer = unsafe.Pointer(&points.(core.HostSlice[Projective])[0])
|
||||
}
|
||||
cPoints := (*C.projective_t)(pointsPointer)
|
||||
cSize := (C.int)(points.Len() / int(cfg.BatchSize))
|
||||
cDir := (C.int)(dir)
|
||||
cCfg := (*C.NTTConfig)(unsafe.Pointer(cfg))
|
||||
|
||||
var resultsPointer unsafe.Pointer
|
||||
if results.IsOnDevice() {
|
||||
resultsPointer = results.(core.DeviceSlice).AsPointer()
|
||||
} else {
|
||||
resultsPointer = unsafe.Pointer(&results.(core.HostSlice[Projective])[0])
|
||||
}
|
||||
cResults := (*C.projective_t)(resultsPointer)
|
||||
|
||||
__ret := C.bls12_377ECNTTCuda(cPoints, cSize, cDir, cCfg, cResults)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func InitDomain(primitiveRoot ScalarField, ctx cr.DeviceContext, fastTwiddles bool) core.IcicleError {
|
||||
cPrimitiveRoot := (*C.scalar_t)(unsafe.Pointer(primitiveRoot.AsPointer()))
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
cFastTwiddles := (C._Bool)(fastTwiddles)
|
||||
__ret := C.bls12_377InitializeDomain(cPrimitiveRoot, cCtx, cFastTwiddles)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func ReleaseDomain(ctx cr.DeviceContext) core.IcicleError {
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
__ret := C.bls12_377ReleaseDomain(cCtx)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
23
wrappers/golang/curves/bls12377/ntt/include/ntt.h
Normal file
23
wrappers/golang/curves/bls12377/ntt/include/ntt.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_377_NTT_H
|
||||
#define _BLS12_377_NTT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct scalar_t scalar_t;
|
||||
typedef struct NTTConfig NTTConfig;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
|
||||
cudaError_t bls12_377_ntt_cuda(const scalar_t* input, int size, int dir, NTTConfig* config, scalar_t* output);
|
||||
cudaError_t bls12_377_initialize_domain(scalar_t* primitive_root, DeviceContext* ctx, bool fast_twiddles);
|
||||
cudaError_t bls12_377_release_domain(DeviceContext* ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
56
wrappers/golang/curves/bls12377/ntt/ntt.go
Normal file
56
wrappers/golang/curves/bls12377/ntt/ntt.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package ntt
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "ntt.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
bls12_377 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377"
|
||||
)
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func Ntt[T any](scalars core.HostOrDeviceSlice, dir core.NTTDir, cfg *core.NTTConfig[T], results core.HostOrDeviceSlice) core.IcicleError {
|
||||
scalarsPointer, resultsPointer, size, cfgPointer := core.NttCheck[T](scalars, cfg, results)
|
||||
|
||||
cScalars := (*C.scalar_t)(scalarsPointer)
|
||||
cSize := (C.int)(size)
|
||||
cDir := (C.int)(dir)
|
||||
cCfg := (*C.NTTConfig)(cfgPointer)
|
||||
cResults := (*C.scalar_t)(resultsPointer)
|
||||
|
||||
__ret := C.bls12_377_ntt_cuda(cScalars, cSize, cDir, cCfg, cResults)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func GetDefaultNttConfig() core.NTTConfig[[bls12_377.SCALAR_LIMBS]uint32] {
|
||||
cosetGenField := bls12_377.ScalarField{}
|
||||
cosetGenField.One()
|
||||
var cosetGen [bls12_377.SCALAR_LIMBS]uint32
|
||||
for i, v := range cosetGenField.GetLimbs() {
|
||||
cosetGen[i] = v
|
||||
}
|
||||
|
||||
return core.GetDefaultNTTConfig(cosetGen)
|
||||
}
|
||||
|
||||
func InitDomain(primitiveRoot bls12_377.ScalarField, ctx cr.DeviceContext, fastTwiddles bool) core.IcicleError {
|
||||
cPrimitiveRoot := (*C.scalar_t)(unsafe.Pointer(primitiveRoot.AsPointer()))
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
cFastTwiddles := (C._Bool)(fastTwiddles)
|
||||
__ret := C.bls12_377_initialize_domain(cPrimitiveRoot, cCtx, cFastTwiddles)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func ReleaseDomain(ctx cr.DeviceContext) core.IcicleError {
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
__ret := C.bls12_377_release_domain(cCtx)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_377_POLY_H
|
||||
#define _BLS12_377_POLY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct scalar_t scalar_t;
|
||||
typedef struct PolynomialInst PolynomialInst;
|
||||
typedef struct IntegrityPointer IntegrityPointer;
|
||||
|
||||
bool bls12_377_polynomial_init_cuda_backend();
|
||||
PolynomialInst* bls12_377_polynomial_create_from_coefficients(scalar_t* coeffs, size_t size);
|
||||
PolynomialInst* bls12_377_polynomial_create_from_rou_evaluations(scalar_t* evals, size_t size);
|
||||
PolynomialInst* bls12_377_polynomial_clone(const PolynomialInst* p);
|
||||
void bls12_377_polynomial_print(PolynomialInst* p);
|
||||
void bls12_377_polynomial_delete(PolynomialInst* instance);
|
||||
PolynomialInst* bls12_377_polynomial_add(const PolynomialInst* a, const PolynomialInst* b);
|
||||
void bls12_377_polynomial_add_inplace(PolynomialInst* a, const PolynomialInst* b);
|
||||
PolynomialInst* bls12_377_polynomial_subtract(const PolynomialInst* a, const PolynomialInst* b);
|
||||
PolynomialInst* bls12_377_polynomial_multiply(const PolynomialInst* a, const PolynomialInst* b);
|
||||
PolynomialInst* bls12_377_polynomial_multiply_by_scalar(const PolynomialInst* a, const scalar_t* scalar);
|
||||
void bls12_377_polynomial_division(const PolynomialInst* a, const PolynomialInst* b, PolynomialInst** q /*OUT*/, PolynomialInst** r /*OUT*/);
|
||||
PolynomialInst* bls12_377_polynomial_quotient(const PolynomialInst* a, const PolynomialInst* b);
|
||||
PolynomialInst* bls12_377_polynomial_remainder(const PolynomialInst* a, const PolynomialInst* b);
|
||||
PolynomialInst* bls12_377_polynomial_divide_by_vanishing(const PolynomialInst* p, size_t vanishing_poly_degree);
|
||||
void bls12_377_polynomial_add_monomial_inplace(PolynomialInst* p, const scalar_t* monomial_coeff, size_t monomial);
|
||||
void bls12_377_polynomial_sub_monomial_inplace(PolynomialInst* p, const scalar_t* monomial_coeff, size_t monomial);
|
||||
void bls12_377_polynomial_evaluate_on_domain(const PolynomialInst* p, scalar_t* domain, size_t domain_size, scalar_t* evals /*OUT*/);
|
||||
size_t bls12_377_polynomial_degree(PolynomialInst* p);
|
||||
size_t bls12_377_polynomial_copy_coeffs_range(PolynomialInst* p, scalar_t* memory, size_t start_idx, size_t end_idx);
|
||||
PolynomialInst* bls12_377_polynomial_even(PolynomialInst* p);
|
||||
PolynomialInst* bls12_377_polynomial_odd(PolynomialInst* p);
|
||||
|
||||
// scalar_t* bls12_377_polynomial_get_coeffs_raw_ptr(PolynomialInst* p, size_t* size /*OUT*/, size_t* device_id /*OUT*/);
|
||||
// PolynomialInst* bls12_377_polynomial_slice(PolynomialInst* p, size_t offset, size_t stride, size_t size);
|
||||
// IntegrityPointer* bls12_377_polynomial_get_coeff_view(PolynomialInst* p, size_t* size /*OUT*/, size_t* device_id /*OUT*/);
|
||||
// IntegrityPointer* bls12_377_polynomial_get_rou_evaluations_view(PolynomialInst* p, size_t nof_evals, bool is_reversed, size_t* size /*OUT*/, size_t* device_id /*OUT*/);
|
||||
// const scalar_t* bls12_377_polynomial_intergrity_ptr_get(IntegrityPointer* p);
|
||||
// bool bls12_377_polynomial_intergrity_ptr_is_valid(IntegrityPointer* p);
|
||||
// void bls12_377_polynomial_intergrity_ptr_destroy(IntegrityPointer* p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
176
wrappers/golang/curves/bls12377/polynomial/polynomial.go
Normal file
176
wrappers/golang/curves/bls12377/polynomial/polynomial.go
Normal file
@@ -0,0 +1,176 @@
|
||||
package polynomial
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "polynomial.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
bls12_377 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377"
|
||||
)
|
||||
|
||||
type PolynomialHandle = C.struct_PolynomialInst
|
||||
|
||||
type DensePolynomial struct {
|
||||
handle *PolynomialHandle
|
||||
}
|
||||
|
||||
func InitPolyBackend() bool {
|
||||
return (bool)(C.bls12_377_polynomial_init_cuda_backend())
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Print() {
|
||||
C.bls12_377_polynomial_print(up.handle)
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) CreateFromCoeffecitients(coeffs core.HostOrDeviceSlice) DensePolynomial {
|
||||
if coeffs.IsOnDevice() {
|
||||
coeffs.(core.DeviceSlice).CheckDevice()
|
||||
}
|
||||
coeffsPointer := (*C.scalar_t)(coeffs.AsUnsafePointer())
|
||||
cSize := (C.size_t)(coeffs.Len())
|
||||
up.handle = C.bls12_377_polynomial_create_from_coefficients(coeffsPointer, cSize)
|
||||
return *up
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) CreateFromROUEvaluations(evals core.HostOrDeviceSlice) DensePolynomial {
|
||||
evalsPointer := (*C.scalar_t)(evals.AsUnsafePointer())
|
||||
cSize := (C.size_t)(evals.Len())
|
||||
up.handle = C.bls12_377_polynomial_create_from_coefficients(evalsPointer, cSize)
|
||||
return *up
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Clone() DensePolynomial {
|
||||
return DensePolynomial{
|
||||
handle: C.bls12_377_polynomial_clone(up.handle),
|
||||
}
|
||||
}
|
||||
|
||||
// TODO @jeremyfelder: Maybe this should be in a SetFinalizer that is set on Create functions?
|
||||
func (up *DensePolynomial) Delete() {
|
||||
C.bls12_377_polynomial_delete(up.handle)
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Add(b *DensePolynomial) DensePolynomial {
|
||||
return DensePolynomial{
|
||||
handle: C.bls12_377_polynomial_add(up.handle, b.handle),
|
||||
}
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) AddInplace(b *DensePolynomial) {
|
||||
C.bls12_377_polynomial_add_inplace(up.handle, b.handle)
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Subtract(b *DensePolynomial) DensePolynomial {
|
||||
return DensePolynomial{
|
||||
handle: C.bls12_377_polynomial_subtract(up.handle, b.handle),
|
||||
}
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Multiply(b *DensePolynomial) DensePolynomial {
|
||||
return DensePolynomial{
|
||||
handle: C.bls12_377_polynomial_multiply(up.handle, b.handle),
|
||||
}
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) MultiplyByScalar(scalar bls12_377.ScalarField) DensePolynomial {
|
||||
cScalar := (*C.scalar_t)(unsafe.Pointer(scalar.AsPointer()))
|
||||
return DensePolynomial{
|
||||
handle: C.bls12_377_polynomial_multiply_by_scalar(up.handle, cScalar),
|
||||
}
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Divide(b *DensePolynomial) (DensePolynomial, DensePolynomial) {
|
||||
var q, r *PolynomialHandle
|
||||
C.bls12_377_polynomial_division(up.handle, b.handle, &q, &r)
|
||||
return DensePolynomial{
|
||||
handle: q,
|
||||
}, DensePolynomial{
|
||||
handle: r,
|
||||
}
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Quotient(b *DensePolynomial) DensePolynomial {
|
||||
return DensePolynomial{
|
||||
handle: C.bls12_377_polynomial_quotient(up.handle, b.handle),
|
||||
}
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Remainder(b *DensePolynomial) DensePolynomial {
|
||||
return DensePolynomial{
|
||||
handle: C.bls12_377_polynomial_remainder(up.handle, b.handle),
|
||||
}
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) DivideByVanishing(vanishing_degree uint64) DensePolynomial {
|
||||
cVanishingDegree := (C.ulong)(vanishing_degree)
|
||||
return DensePolynomial{
|
||||
handle: C.bls12_377_polynomial_divide_by_vanishing(up.handle, cVanishingDegree),
|
||||
}
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) AddMonomial(monomialCoeff bls12_377.ScalarField, monomial uint64) DensePolynomial {
|
||||
hs := core.HostSliceFromElements([]bls12_377.ScalarField{monomialCoeff})
|
||||
cMonomialCoeff := (*C.scalar_t)(hs.AsUnsafePointer())
|
||||
cMonomial := (C.ulong)(monomial)
|
||||
C.bls12_377_polynomial_add_monomial_inplace(up.handle, cMonomialCoeff, cMonomial)
|
||||
return *up
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) SubMonomial(monomialCoeff bls12_377.ScalarField, monomial uint64) DensePolynomial {
|
||||
hs := core.HostSliceFromElements([]bls12_377.ScalarField{monomialCoeff})
|
||||
cMonomialCoeff := (*C.scalar_t)(hs.AsUnsafePointer())
|
||||
cMonomial := (C.ulong)(monomial)
|
||||
C.bls12_377_polynomial_sub_monomial_inplace(up.handle, cMonomialCoeff, cMonomial)
|
||||
return *up
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Eval(x bls12_377.ScalarField) bls12_377.ScalarField {
|
||||
domains := make(core.HostSlice[bls12_377.ScalarField], 1)
|
||||
domains[0] = x
|
||||
evals := make(core.HostSlice[bls12_377.ScalarField], 1)
|
||||
up.EvalOnDomain(domains, evals)
|
||||
return evals[0]
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) EvalOnDomain(domain, evals core.HostOrDeviceSlice) core.HostOrDeviceSlice {
|
||||
cDomain := (*C.scalar_t)(domain.AsUnsafePointer())
|
||||
cDomainSize := (C.size_t)(domain.Len())
|
||||
cEvals := (*C.scalar_t)(evals.AsUnsafePointer())
|
||||
C.bls12_377_polynomial_evaluate_on_domain(up.handle, cDomain, cDomainSize, cEvals)
|
||||
return evals
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Degree() int {
|
||||
return int(C.bls12_377_polynomial_degree(up.handle))
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) CopyCoeffsRange(start, end int, out core.HostOrDeviceSlice) (int, core.HostOrDeviceSlice) {
|
||||
cStart := (C.size_t)(start)
|
||||
cEnd := (C.size_t)(end)
|
||||
cScalarOut := (*C.scalar_t)(out.AsUnsafePointer())
|
||||
__cNumCoeffsRead := C.bls12_377_polynomial_copy_coeffs_range(up.handle, cScalarOut, cStart, cEnd)
|
||||
return int(__cNumCoeffsRead), out
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) GetCoeff(idx int) bls12_377.ScalarField {
|
||||
out := make(core.HostSlice[bls12_377.ScalarField], 1)
|
||||
up.CopyCoeffsRange(idx, idx, out)
|
||||
return out[0]
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Even() DensePolynomial {
|
||||
evenPoly := C.bls12_377_polynomial_even(up.handle)
|
||||
return DensePolynomial{
|
||||
handle: evenPoly,
|
||||
}
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Odd() DensePolynomial {
|
||||
oddPoly := C.bls12_377_polynomial_odd(up.handle)
|
||||
return DensePolynomial{
|
||||
handle: oddPoly,
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
SCALAR_LIMBS int8 = 8
|
||||
SCALAR_LIMBS int = 8
|
||||
)
|
||||
|
||||
type ScalarField struct {
|
||||
@@ -35,6 +35,11 @@ func (f ScalarField) AsPointer() *uint32 {
|
||||
return &f.limbs[0]
|
||||
}
|
||||
|
||||
func (f *ScalarField) FromUint32(v uint32) ScalarField {
|
||||
f.limbs[0] = v
|
||||
return *f
|
||||
}
|
||||
|
||||
func (f *ScalarField) FromLimbs(limbs []uint32) ScalarField {
|
||||
if len(limbs) != f.Len() {
|
||||
panic("Called FromLimbs with limbs of different length than field")
|
||||
@@ -89,18 +94,18 @@ func GenerateScalars(size int) core.HostSlice[ScalarField] {
|
||||
|
||||
cScalars := (*C.scalar_t)(unsafe.Pointer(&scalarSlice[0]))
|
||||
cSize := (C.int)(size)
|
||||
C.bls12_377GenerateScalars(cScalars, cSize)
|
||||
C.bls12_377_generate_scalars(cScalars, cSize)
|
||||
|
||||
return scalarSlice
|
||||
}
|
||||
|
||||
func convertScalarsMontgomery(scalars *core.DeviceSlice, isInto bool) cr.CudaError {
|
||||
cValues := (*C.scalar_t)(scalars.AsPointer())
|
||||
cValues := (*C.scalar_t)(scalars.AsUnsafePointer())
|
||||
cSize := (C.size_t)(scalars.Len())
|
||||
cIsInto := (C._Bool)(isInto)
|
||||
defaultCtx, _ := cr.GetDefaultDeviceContext()
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&defaultCtx))
|
||||
__ret := C.bls12_377ScalarConvertMontgomery(cValues, cSize, cIsInto, cCtx)
|
||||
__ret := C.bls12_377_scalar_convert_montgomery(cValues, cSize, cIsInto, cCtx)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,34 +1,40 @@
|
||||
package bw6761
|
||||
package tests
|
||||
|
||||
import (
|
||||
bls12_377 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
BASE_LIMBS = bls12_377.BASE_LIMBS
|
||||
)
|
||||
|
||||
func TestBaseFieldFromLimbs(t *testing.T) {
|
||||
emptyField := BaseField{}
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField := bls12_377.BaseField{}
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
assert.ElementsMatch(t, randLimbs, emptyField.limbs, "Limbs do not match; there was an issue with setting the BaseField's limbs")
|
||||
assert.ElementsMatch(t, randLimbs, emptyField.GetLimbs(), "Limbs do not match; there was an issue with setting the BaseField's limbs")
|
||||
randLimbs[0] = 100
|
||||
assert.NotEqual(t, randLimbs, emptyField.limbs)
|
||||
assert.NotEqual(t, randLimbs, emptyField.GetLimbs())
|
||||
}
|
||||
|
||||
func TestBaseFieldGetLimbs(t *testing.T) {
|
||||
emptyField := BaseField{}
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField := bls12_377.BaseField{}
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.ElementsMatch(t, randLimbs, emptyField.GetLimbs(), "Limbs do not match; there was an issue with setting the BaseField's limbs")
|
||||
}
|
||||
|
||||
func TestBaseFieldOne(t *testing.T) {
|
||||
var emptyField BaseField
|
||||
var emptyField bls12_377.BaseField
|
||||
emptyField.One()
|
||||
limbOne := generateLimbOne(int(BASE_LIMBS))
|
||||
limbOne := test_helpers.GenerateLimbOne(int(BASE_LIMBS))
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbOne, "Empty field to field one did not work")
|
||||
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
emptyField.One()
|
||||
@@ -36,12 +42,12 @@ func TestBaseFieldOne(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBaseFieldZero(t *testing.T) {
|
||||
var emptyField BaseField
|
||||
var emptyField bls12_377.BaseField
|
||||
emptyField.Zero()
|
||||
limbsZero := make([]uint32, BASE_LIMBS)
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbsZero, "Empty field to field zero failed")
|
||||
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
emptyField.Zero()
|
||||
@@ -49,24 +55,24 @@ func TestBaseFieldZero(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBaseFieldSize(t *testing.T) {
|
||||
var emptyField BaseField
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
var emptyField bls12_377.BaseField
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.Equal(t, len(randLimbs)*4, emptyField.Size(), "Size returned an incorrect value of bytes")
|
||||
}
|
||||
|
||||
func TestBaseFieldAsPointer(t *testing.T) {
|
||||
var emptyField BaseField
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
var emptyField bls12_377.BaseField
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.Equal(t, randLimbs[0], *emptyField.AsPointer(), "AsPointer returned pointer to incorrect value")
|
||||
}
|
||||
|
||||
func TestBaseFieldFromBytes(t *testing.T) {
|
||||
var emptyField BaseField
|
||||
bytes, expected := generateBytesArray(int(BASE_LIMBS))
|
||||
var emptyField bls12_377.BaseField
|
||||
bytes, expected := test_helpers.GenerateBytesArray(int(BASE_LIMBS))
|
||||
|
||||
emptyField.FromBytesLittleEndian(bytes)
|
||||
|
||||
@@ -74,8 +80,8 @@ func TestBaseFieldFromBytes(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBaseFieldToBytes(t *testing.T) {
|
||||
var emptyField BaseField
|
||||
expected, limbs := generateBytesArray(int(BASE_LIMBS))
|
||||
var emptyField bls12_377.BaseField
|
||||
expected, limbs := test_helpers.GenerateBytesArray(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(limbs)
|
||||
|
||||
assert.ElementsMatch(t, emptyField.ToBytesLittleEndian(), expected, "ToBytes returned incorrect values")
|
||||
@@ -1,20 +1,22 @@
|
||||
package bn254
|
||||
package tests
|
||||
|
||||
import (
|
||||
bls12_377 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAffineZero(t *testing.T) {
|
||||
var fieldZero = BaseField{}
|
||||
var fieldZero = bls12_377.BaseField{}
|
||||
|
||||
var affineZero Affine
|
||||
var affineZero bls12_377.Affine
|
||||
assert.Equal(t, affineZero.X, fieldZero)
|
||||
assert.Equal(t, affineZero.Y, fieldZero)
|
||||
|
||||
x := generateRandomLimb(int(BASE_LIMBS))
|
||||
y := generateRandomLimb(int(BASE_LIMBS))
|
||||
var affine Affine
|
||||
x := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
y := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
var affine bls12_377.Affine
|
||||
affine.FromLimbs(x, y)
|
||||
|
||||
affine.Zero()
|
||||
@@ -23,10 +25,10 @@ func TestAffineZero(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAffineFromLimbs(t *testing.T) {
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs2 := generateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs2 := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
|
||||
var affine Affine
|
||||
var affine bls12_377.Affine
|
||||
affine.FromLimbs(randLimbs, randLimbs2)
|
||||
|
||||
assert.ElementsMatch(t, randLimbs, affine.X.GetLimbs())
|
||||
@@ -34,15 +36,15 @@ func TestAffineFromLimbs(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAffineToProjective(t *testing.T) {
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs2 := generateRandomLimb(int(BASE_LIMBS))
|
||||
var fieldOne BaseField
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs2 := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
var fieldOne bls12_377.BaseField
|
||||
fieldOne.One()
|
||||
|
||||
var expected Projective
|
||||
expected.FromLimbs(randLimbs, randLimbs2, fieldOne.limbs[:])
|
||||
var expected bls12_377.Projective
|
||||
expected.FromLimbs(randLimbs, randLimbs2, fieldOne.GetLimbs()[:])
|
||||
|
||||
var affine Affine
|
||||
var affine bls12_377.Affine
|
||||
affine.FromLimbs(randLimbs, randLimbs2)
|
||||
|
||||
projectivePoint := affine.ToProjective()
|
||||
@@ -50,18 +52,18 @@ func TestAffineToProjective(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestProjectiveZero(t *testing.T) {
|
||||
var projectiveZero Projective
|
||||
var projectiveZero bls12_377.Projective
|
||||
projectiveZero.Zero()
|
||||
var fieldZero = BaseField{}
|
||||
var fieldOne BaseField
|
||||
var fieldZero = bls12_377.BaseField{}
|
||||
var fieldOne bls12_377.BaseField
|
||||
fieldOne.One()
|
||||
|
||||
assert.Equal(t, projectiveZero.X, fieldZero)
|
||||
assert.Equal(t, projectiveZero.Y, fieldOne)
|
||||
assert.Equal(t, projectiveZero.Z, fieldZero)
|
||||
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
var projective Projective
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
var projective bls12_377.Projective
|
||||
projective.FromLimbs(randLimbs, randLimbs, randLimbs)
|
||||
|
||||
projective.Zero()
|
||||
@@ -71,11 +73,11 @@ func TestProjectiveZero(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestProjectiveFromLimbs(t *testing.T) {
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs2 := generateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs3 := generateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs2 := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs3 := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
|
||||
var projective Projective
|
||||
var projective bls12_377.Projective
|
||||
projective.FromLimbs(randLimbs, randLimbs2, randLimbs3)
|
||||
|
||||
assert.ElementsMatch(t, randLimbs, projective.X.GetLimbs())
|
||||
@@ -84,18 +86,18 @@ func TestProjectiveFromLimbs(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestProjectiveFromAffine(t *testing.T) {
|
||||
randLimbs := generateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs2 := generateRandomLimb(int(BASE_LIMBS))
|
||||
var fieldOne BaseField
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs2 := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
var fieldOne bls12_377.BaseField
|
||||
fieldOne.One()
|
||||
|
||||
var expected Projective
|
||||
expected.FromLimbs(randLimbs, randLimbs2, fieldOne.limbs[:])
|
||||
var expected bls12_377.Projective
|
||||
expected.FromLimbs(randLimbs, randLimbs2, fieldOne.GetLimbs()[:])
|
||||
|
||||
var affine Affine
|
||||
var affine bls12_377.Affine
|
||||
affine.FromLimbs(randLimbs, randLimbs2)
|
||||
|
||||
var projectivePoint Projective
|
||||
var projectivePoint bls12_377.Projective
|
||||
projectivePoint.FromAffine(affine)
|
||||
assert.Equal(t, expected, projectivePoint)
|
||||
}
|
||||
30
wrappers/golang/curves/bls12377/tests/ecntt_test.go
Normal file
30
wrappers/golang/curves/bls12377/tests/ecntt_test.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
bls12_377 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377"
|
||||
ecntt "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377/ecntt"
|
||||
ntt "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377/ntt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestECNtt(t *testing.T) {
|
||||
cfg := ntt.GetDefaultNttConfig()
|
||||
points := bls12_377.GenerateProjectivePoints(1 << largestTestSize)
|
||||
|
||||
for _, size := range []int{4, 5, 6, 7, 8} {
|
||||
for _, v := range [4]core.Ordering{core.KNN, core.KNR, core.KRN, core.KRR} {
|
||||
testSize := 1 << size
|
||||
|
||||
pointsCopy := core.HostSliceFromElements[bls12_377.Projective](points[:testSize])
|
||||
cfg.Ordering = v
|
||||
cfg.NttAlgorithm = core.Radix2
|
||||
|
||||
output := make(core.HostSlice[bls12_377.Projective], testSize)
|
||||
e := ecntt.ECNtt(pointsCopy, core.KForward, &cfg, output)
|
||||
assert.Equal(t, core.IcicleErrorCode(0), e.IcicleErrorCode, "ECNtt failed")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,22 @@
|
||||
//go:build g2
|
||||
|
||||
package bw6761
|
||||
package tests
|
||||
|
||||
import (
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377/g2"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestG2AffineZero(t *testing.T) {
|
||||
var fieldZero = G2BaseField{}
|
||||
var fieldZero = g2.G2BaseField{}
|
||||
|
||||
var affineZero G2Affine
|
||||
var affineZero g2.G2Affine
|
||||
assert.Equal(t, affineZero.X, fieldZero)
|
||||
assert.Equal(t, affineZero.Y, fieldZero)
|
||||
|
||||
x := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
y := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
var affine G2Affine
|
||||
x := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
y := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
var affine g2.G2Affine
|
||||
affine.FromLimbs(x, y)
|
||||
|
||||
affine.Zero()
|
||||
@@ -25,10 +25,10 @@ func TestG2AffineZero(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestG2AffineFromLimbs(t *testing.T) {
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
randLimbs2 := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
randLimbs2 := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
|
||||
var affine G2Affine
|
||||
var affine g2.G2Affine
|
||||
affine.FromLimbs(randLimbs, randLimbs2)
|
||||
|
||||
assert.ElementsMatch(t, randLimbs, affine.X.GetLimbs())
|
||||
@@ -36,15 +36,15 @@ func TestG2AffineFromLimbs(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestG2AffineToProjective(t *testing.T) {
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
randLimbs2 := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
var fieldOne G2BaseField
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
randLimbs2 := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
var fieldOne g2.G2BaseField
|
||||
fieldOne.One()
|
||||
|
||||
var expected G2Projective
|
||||
expected.FromLimbs(randLimbs, randLimbs2, fieldOne.limbs[:])
|
||||
var expected g2.G2Projective
|
||||
expected.FromLimbs(randLimbs, randLimbs2, fieldOne.GetLimbs()[:])
|
||||
|
||||
var affine G2Affine
|
||||
var affine g2.G2Affine
|
||||
affine.FromLimbs(randLimbs, randLimbs2)
|
||||
|
||||
projectivePoint := affine.ToProjective()
|
||||
@@ -52,18 +52,18 @@ func TestG2AffineToProjective(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestG2ProjectiveZero(t *testing.T) {
|
||||
var projectiveZero G2Projective
|
||||
var projectiveZero g2.G2Projective
|
||||
projectiveZero.Zero()
|
||||
var fieldZero = G2BaseField{}
|
||||
var fieldOne G2BaseField
|
||||
var fieldZero = g2.G2BaseField{}
|
||||
var fieldOne g2.G2BaseField
|
||||
fieldOne.One()
|
||||
|
||||
assert.Equal(t, projectiveZero.X, fieldZero)
|
||||
assert.Equal(t, projectiveZero.Y, fieldOne)
|
||||
assert.Equal(t, projectiveZero.Z, fieldZero)
|
||||
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
var projective G2Projective
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
var projective g2.G2Projective
|
||||
projective.FromLimbs(randLimbs, randLimbs, randLimbs)
|
||||
|
||||
projective.Zero()
|
||||
@@ -73,11 +73,11 @@ func TestG2ProjectiveZero(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestG2ProjectiveFromLimbs(t *testing.T) {
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
randLimbs2 := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
randLimbs3 := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
randLimbs2 := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
randLimbs3 := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
|
||||
var projective G2Projective
|
||||
var projective g2.G2Projective
|
||||
projective.FromLimbs(randLimbs, randLimbs2, randLimbs3)
|
||||
|
||||
assert.ElementsMatch(t, randLimbs, projective.X.GetLimbs())
|
||||
@@ -86,18 +86,18 @@ func TestG2ProjectiveFromLimbs(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestG2ProjectiveFromAffine(t *testing.T) {
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
randLimbs2 := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
var fieldOne G2BaseField
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
randLimbs2 := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
var fieldOne g2.G2BaseField
|
||||
fieldOne.One()
|
||||
|
||||
var expected G2Projective
|
||||
expected.FromLimbs(randLimbs, randLimbs2, fieldOne.limbs[:])
|
||||
var expected g2.G2Projective
|
||||
expected.FromLimbs(randLimbs, randLimbs2, fieldOne.GetLimbs()[:])
|
||||
|
||||
var affine G2Affine
|
||||
var affine g2.G2Affine
|
||||
affine.FromLimbs(randLimbs, randLimbs2)
|
||||
|
||||
var projectivePoint G2Projective
|
||||
var projectivePoint g2.G2Projective
|
||||
projectivePoint.FromAffine(affine)
|
||||
assert.Equal(t, expected, projectivePoint)
|
||||
}
|
||||
@@ -1,36 +1,40 @@
|
||||
//go:build g2
|
||||
|
||||
package bn254
|
||||
package tests
|
||||
|
||||
import (
|
||||
bls12_377 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377/g2"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
G2BASE_LIMBS = bls12_377.G2BASE_LIMBS
|
||||
)
|
||||
|
||||
func TestG2BaseFieldFromLimbs(t *testing.T) {
|
||||
emptyField := G2BaseField{}
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
emptyField := bls12_377.G2BaseField{}
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
assert.ElementsMatch(t, randLimbs, emptyField.limbs, "Limbs do not match; there was an issue with setting the G2BaseField's limbs")
|
||||
assert.ElementsMatch(t, randLimbs, emptyField.GetLimbs(), "Limbs do not match; there was an issue with setting the G2BaseField's limbs")
|
||||
randLimbs[0] = 100
|
||||
assert.NotEqual(t, randLimbs, emptyField.limbs)
|
||||
assert.NotEqual(t, randLimbs, emptyField.GetLimbs())
|
||||
}
|
||||
|
||||
func TestG2BaseFieldGetLimbs(t *testing.T) {
|
||||
emptyField := G2BaseField{}
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
emptyField := bls12_377.G2BaseField{}
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.ElementsMatch(t, randLimbs, emptyField.GetLimbs(), "Limbs do not match; there was an issue with setting the G2BaseField's limbs")
|
||||
}
|
||||
|
||||
func TestG2BaseFieldOne(t *testing.T) {
|
||||
var emptyField G2BaseField
|
||||
var emptyField bls12_377.G2BaseField
|
||||
emptyField.One()
|
||||
limbOne := generateLimbOne(int(G2_BASE_LIMBS))
|
||||
limbOne := test_helpers.GenerateLimbOne(int(G2BASE_LIMBS))
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbOne, "Empty field to field one did not work")
|
||||
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
emptyField.One()
|
||||
@@ -38,12 +42,12 @@ func TestG2BaseFieldOne(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestG2BaseFieldZero(t *testing.T) {
|
||||
var emptyField G2BaseField
|
||||
var emptyField bls12_377.G2BaseField
|
||||
emptyField.Zero()
|
||||
limbsZero := make([]uint32, G2_BASE_LIMBS)
|
||||
limbsZero := make([]uint32, G2BASE_LIMBS)
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbsZero, "Empty field to field zero failed")
|
||||
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
emptyField.Zero()
|
||||
@@ -51,24 +55,24 @@ func TestG2BaseFieldZero(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestG2BaseFieldSize(t *testing.T) {
|
||||
var emptyField G2BaseField
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
var emptyField bls12_377.G2BaseField
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.Equal(t, len(randLimbs)*4, emptyField.Size(), "Size returned an incorrect value of bytes")
|
||||
}
|
||||
|
||||
func TestG2BaseFieldAsPointer(t *testing.T) {
|
||||
var emptyField G2BaseField
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
var emptyField bls12_377.G2BaseField
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.Equal(t, randLimbs[0], *emptyField.AsPointer(), "AsPointer returned pointer to incorrect value")
|
||||
}
|
||||
|
||||
func TestG2BaseFieldFromBytes(t *testing.T) {
|
||||
var emptyField G2BaseField
|
||||
bytes, expected := generateBytesArray(int(G2_BASE_LIMBS))
|
||||
var emptyField bls12_377.G2BaseField
|
||||
bytes, expected := test_helpers.GenerateBytesArray(int(G2BASE_LIMBS))
|
||||
|
||||
emptyField.FromBytesLittleEndian(bytes)
|
||||
|
||||
@@ -76,8 +80,8 @@ func TestG2BaseFieldFromBytes(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestG2BaseFieldToBytes(t *testing.T) {
|
||||
var emptyField G2BaseField
|
||||
expected, limbs := generateBytesArray(int(G2_BASE_LIMBS))
|
||||
var emptyField bls12_377.G2BaseField
|
||||
expected, limbs := test_helpers.GenerateBytesArray(int(G2BASE_LIMBS))
|
||||
emptyField.FromLimbs(limbs)
|
||||
|
||||
assert.ElementsMatch(t, emptyField.ToBytesLittleEndian(), expected, "ToBytes returned incorrect values")
|
||||
@@ -1,6 +1,4 @@
|
||||
//go:build g2
|
||||
|
||||
package bls12377
|
||||
package tests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -9,16 +7,18 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
|
||||
"github.com/consensys/gnark-crypto/ecc"
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-377"
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-377/fp"
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-377/fr"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
icicleBls12_377 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377/g2"
|
||||
)
|
||||
|
||||
func projectiveToGnarkAffineG2(p G2Projective) bls12377.G2Affine {
|
||||
func projectiveToGnarkAffineG2(p g2.G2Projective) bls12377.G2Affine {
|
||||
pxBytes := p.X.ToBytesLittleEndian()
|
||||
pxA0, _ := fp.LittleEndian.Element((*[fp.Bytes]byte)(pxBytes[:fp.Bytes]))
|
||||
pxA1, _ := fp.LittleEndian.Element((*[fp.Bytes]byte)(pxBytes[fp.Bytes:]))
|
||||
@@ -62,7 +62,7 @@ func projectiveToGnarkAffineG2(p G2Projective) bls12377.G2Affine {
|
||||
return *g2Affine.FromJacobian(&g2Jac)
|
||||
}
|
||||
|
||||
func testAgainstGnarkCryptoMsmG2(scalars core.HostSlice[ScalarField], points core.HostSlice[G2Affine], out G2Projective) bool {
|
||||
func testAgainstGnarkCryptoMsmG2(scalars core.HostSlice[icicleBls12_377.ScalarField], points core.HostSlice[g2.G2Affine], out g2.G2Projective) bool {
|
||||
scalarsFr := make([]fr.Element, len(scalars))
|
||||
for i, v := range scalars {
|
||||
slice64, _ := fr.LittleEndian.Element((*[fr.Bytes]byte)(v.ToBytesLittleEndian()))
|
||||
@@ -73,6 +73,11 @@ func testAgainstGnarkCryptoMsmG2(scalars core.HostSlice[ScalarField], points cor
|
||||
for i, v := range points {
|
||||
pointsFp[i] = projectiveToGnarkAffineG2(v.ToProjective())
|
||||
}
|
||||
|
||||
return testAgainstGnarkCryptoMsmG2GnarkCryptoTypes(scalarsFr, pointsFp, out)
|
||||
}
|
||||
|
||||
func testAgainstGnarkCryptoMsmG2GnarkCryptoTypes(scalarsFr core.HostSlice[fr.Element], pointsFp core.HostSlice[bls12377.G2Affine], out g2.G2Projective) bool {
|
||||
var msmRes bls12377.G2Jac
|
||||
msmRes.MultiExp(pointsFp, scalarsFr, ecc.MultiExpConfig{})
|
||||
|
||||
@@ -83,54 +88,117 @@ func testAgainstGnarkCryptoMsmG2(scalars core.HostSlice[ScalarField], points cor
|
||||
return msmRes.Equal(&icicleResAsJac)
|
||||
}
|
||||
|
||||
func convertIcicleG2AffineToG2Affine(iciclePoints []g2.G2Affine) []bls12377.G2Affine {
|
||||
points := make([]bls12377.G2Affine, len(iciclePoints))
|
||||
for index, iciclePoint := range iciclePoints {
|
||||
xBytes := ([fp.Bytes * 2]byte)(iciclePoint.X.ToBytesLittleEndian())
|
||||
xA0Bytes := ([fp.Bytes]byte)(xBytes[:fp.Bytes])
|
||||
xA1Bytes := ([fp.Bytes]byte)(xBytes[fp.Bytes:])
|
||||
xA0Elem, _ := fp.LittleEndian.Element(&xA0Bytes)
|
||||
xA1Elem, _ := fp.LittleEndian.Element(&xA1Bytes)
|
||||
|
||||
yBytes := ([fp.Bytes * 2]byte)(iciclePoint.Y.ToBytesLittleEndian())
|
||||
yA0Bytes := ([fp.Bytes]byte)(yBytes[:fp.Bytes])
|
||||
yA1Bytes := ([fp.Bytes]byte)(yBytes[fp.Bytes:])
|
||||
yA0Elem, _ := fp.LittleEndian.Element(&yA0Bytes)
|
||||
yA1Elem, _ := fp.LittleEndian.Element(&yA1Bytes)
|
||||
|
||||
points[index] = bls12377.G2Affine{
|
||||
X: bls12377.E2{
|
||||
A0: xA0Elem,
|
||||
A1: xA1Elem,
|
||||
},
|
||||
Y: bls12377.E2{
|
||||
A0: yA0Elem,
|
||||
A1: yA1Elem,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return points
|
||||
}
|
||||
|
||||
func TestMSMG2(t *testing.T) {
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := g2.G2GetDefaultMSMConfig()
|
||||
cfg.IsAsync = true
|
||||
for _, power := range []int{2, 3, 4, 5, 6, 7, 8, 10, 18} {
|
||||
size := 1 << power
|
||||
|
||||
scalars := GenerateScalars(size)
|
||||
points := G2GenerateAffinePoints(size)
|
||||
scalars := icicleBls12_377.GenerateScalars(size)
|
||||
points := g2.G2GenerateAffinePoints(size)
|
||||
|
||||
stream, _ := cr.CreateStream()
|
||||
var p G2Projective
|
||||
var p g2.G2Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.MallocAsync(p.Size(), p.Size(), stream)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
cfg.Ctx.Stream = &stream
|
||||
|
||||
e = G2Msm(scalars, points, &cfg, out)
|
||||
e = g2.G2Msm(scalars, points, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[G2Projective], 1)
|
||||
outHost := make(core.HostSlice[g2.G2Projective], 1)
|
||||
outHost.CopyFromDeviceAsync(&out, stream)
|
||||
out.FreeAsync(stream)
|
||||
|
||||
cr.SynchronizeStream(&stream)
|
||||
// Check with gnark-crypto
|
||||
assert.True(t, testAgainstGnarkCryptoMsmG2(scalars, points, outHost[0]))
|
||||
|
||||
}
|
||||
}
|
||||
func TestMSMG2GnarkCryptoTypes(t *testing.T) {
|
||||
cfg := g2.G2GetDefaultMSMConfig()
|
||||
for _, power := range []int{3} {
|
||||
size := 1 << power
|
||||
|
||||
scalars := make([]fr.Element, size)
|
||||
var x fr.Element
|
||||
for i := 0; i < size; i++ {
|
||||
x.SetRandom()
|
||||
scalars[i] = x
|
||||
}
|
||||
scalarsHost := (core.HostSlice[fr.Element])(scalars)
|
||||
points := g2.G2GenerateAffinePoints(size)
|
||||
pointsGnark := convertIcicleG2AffineToG2Affine(points)
|
||||
pointsHost := (core.HostSlice[bls12377.G2Affine])(pointsGnark)
|
||||
|
||||
var p g2.G2Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.Malloc(p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
cfg.ArePointsMontgomeryForm = true
|
||||
cfg.AreScalarsMontgomeryForm = true
|
||||
|
||||
e = g2.G2Msm(scalarsHost, pointsHost, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[g2.G2Projective], 1)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
// Check with gnark-crypto
|
||||
assert.True(t, testAgainstGnarkCryptoMsmG2GnarkCryptoTypes(scalarsHost, pointsHost, outHost[0]))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMSMG2Batch(t *testing.T) {
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := g2.G2GetDefaultMSMConfig()
|
||||
for _, power := range []int{10, 16} {
|
||||
for _, batchSize := range []int{1, 3, 16} {
|
||||
size := 1 << power
|
||||
totalSize := size * batchSize
|
||||
scalars := GenerateScalars(totalSize)
|
||||
points := G2GenerateAffinePoints(totalSize)
|
||||
scalars := icicleBls12_377.GenerateScalars(totalSize)
|
||||
points := g2.G2GenerateAffinePoints(totalSize)
|
||||
|
||||
var p G2Projective
|
||||
var p g2.G2Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.Malloc(batchSize*p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
e = G2Msm(scalars, points, &cfg, out)
|
||||
e = g2.G2Msm(scalars, points, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[G2Projective], batchSize)
|
||||
outHost := make(core.HostSlice[g2.G2Projective], batchSize)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
// Check with gnark-crypto
|
||||
for i := 0; i < batchSize; i++ {
|
||||
scalarsSlice := scalars[i*size : (i+1)*size]
|
||||
@@ -143,36 +211,35 @@ func TestMSMG2Batch(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPrecomputeBaseG2(t *testing.T) {
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := g2.G2GetDefaultMSMConfig()
|
||||
const precomputeFactor = 8
|
||||
for _, power := range []int{10, 16} {
|
||||
for _, batchSize := range []int{1, 3, 16} {
|
||||
size := 1 << power
|
||||
totalSize := size * batchSize
|
||||
scalars := GenerateScalars(totalSize)
|
||||
points := G2GenerateAffinePoints(totalSize)
|
||||
scalars := icicleBls12_377.GenerateScalars(totalSize)
|
||||
points := g2.G2GenerateAffinePoints(totalSize)
|
||||
|
||||
var precomputeOut core.DeviceSlice
|
||||
_, e := precomputeOut.Malloc(points[0].Size()*points.Len()*int(precomputeFactor), points[0].Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
|
||||
e = G2PrecomputeBases(points, precomputeFactor, 0, &cfg.Ctx, precomputeOut)
|
||||
e = g2.G2PrecomputeBases(points, precomputeFactor, 0, &cfg.Ctx, precomputeOut)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "PrecomputeBases failed")
|
||||
|
||||
var p G2Projective
|
||||
var p g2.G2Projective
|
||||
var out core.DeviceSlice
|
||||
_, e = out.Malloc(batchSize*p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
|
||||
e = G2Msm(scalars, precomputeOut, &cfg, out)
|
||||
e = g2.G2Msm(scalars, precomputeOut, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[G2Projective], batchSize)
|
||||
outHost := make(core.HostSlice[g2.G2Projective], batchSize)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
precomputeOut.Free()
|
||||
|
||||
// Check with gnark-crypto
|
||||
for i := 0; i < batchSize; i++ {
|
||||
scalarsSlice := scalars[i*size : (i+1)*size]
|
||||
@@ -185,30 +252,29 @@ func TestPrecomputeBaseG2(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMSMG2SkewedDistribution(t *testing.T) {
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := g2.G2GetDefaultMSMConfig()
|
||||
for _, power := range []int{2, 3, 4, 5, 6, 7, 8, 10, 18} {
|
||||
size := 1 << power
|
||||
|
||||
scalars := GenerateScalars(size)
|
||||
scalars := icicleBls12_377.GenerateScalars(size)
|
||||
for i := size / 4; i < size; i++ {
|
||||
scalars[i].One()
|
||||
}
|
||||
points := G2GenerateAffinePoints(size)
|
||||
points := g2.G2GenerateAffinePoints(size)
|
||||
for i := 0; i < size/4; i++ {
|
||||
points[i].Zero()
|
||||
}
|
||||
|
||||
var p G2Projective
|
||||
var p g2.G2Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.Malloc(p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
e = G2Msm(scalars, points, &cfg, out)
|
||||
e = g2.G2Msm(scalars, points, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[G2Projective], 1)
|
||||
outHost := make(core.HostSlice[g2.G2Projective], 1)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
// Check with gnark-crypto
|
||||
assert.True(t, testAgainstGnarkCryptoMsmG2(scalars, points, outHost[0]))
|
||||
}
|
||||
@@ -225,23 +291,23 @@ func TestMSMG2MultiDevice(t *testing.T) {
|
||||
wg.Add(1)
|
||||
cr.RunOnDevice(i, func(args ...any) {
|
||||
defer wg.Done()
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := g2.G2GetDefaultMSMConfig()
|
||||
cfg.IsAsync = true
|
||||
for _, power := range []int{2, 3, 4, 5, 6, 7, 8, 10, 18} {
|
||||
size := 1 << power
|
||||
scalars := GenerateScalars(size)
|
||||
points := G2GenerateAffinePoints(size)
|
||||
scalars := icicleBls12_377.GenerateScalars(size)
|
||||
points := g2.G2GenerateAffinePoints(size)
|
||||
|
||||
stream, _ := cr.CreateStream()
|
||||
var p G2Projective
|
||||
var p g2.G2Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.MallocAsync(p.Size(), p.Size(), stream)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
cfg.Ctx.Stream = &stream
|
||||
|
||||
e = G2Msm(scalars, points, &cfg, out)
|
||||
e = g2.G2Msm(scalars, points, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[G2Projective], 1)
|
||||
outHost := make(core.HostSlice[g2.G2Projective], 1)
|
||||
outHost.CopyFromDeviceAsync(&out, stream)
|
||||
out.FreeAsync(stream)
|
||||
|
||||
48
wrappers/golang/curves/bls12377/tests/main_test.go
Normal file
48
wrappers/golang/curves/bls12377/tests/main_test.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
bls12_377 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377"
|
||||
ntt "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377/ntt"
|
||||
poly "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377/polynomial"
|
||||
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-377/fr/fft"
|
||||
)
|
||||
|
||||
const (
|
||||
largestTestSize = 20
|
||||
)
|
||||
|
||||
func initDomain[T any](largestTestSize int, cfg core.NTTConfig[T]) core.IcicleError {
|
||||
rouMont, _ := fft.Generator(uint64(1 << largestTestSize))
|
||||
rou := rouMont.Bits()
|
||||
rouIcicle := bls12_377.ScalarField{}
|
||||
limbs := core.ConvertUint64ArrToUint32Arr(rou[:])
|
||||
|
||||
rouIcicle.FromLimbs(limbs)
|
||||
e := ntt.InitDomain(rouIcicle, cfg.Ctx, false)
|
||||
return e
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
poly.InitPolyBackend()
|
||||
|
||||
// setup domain
|
||||
cfg := ntt.GetDefaultNttConfig()
|
||||
e := initDomain(largestTestSize, cfg)
|
||||
if e.IcicleErrorCode != core.IcicleErrorCode(0) {
|
||||
panic("initDomain failed")
|
||||
}
|
||||
|
||||
// execute tests
|
||||
os.Exit(m.Run())
|
||||
|
||||
// release domain
|
||||
e = ntt.ReleaseDomain(cfg.Ctx)
|
||||
if e.IcicleErrorCode != core.IcicleErrorCode(0) {
|
||||
panic("ReleaseDomain failed")
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package bls12377
|
||||
package tests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -7,16 +7,18 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
|
||||
"github.com/consensys/gnark-crypto/ecc"
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-377"
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-377/fp"
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-377/fr"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
icicleBls12_377 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377/msm"
|
||||
)
|
||||
|
||||
func projectiveToGnarkAffine(p Projective) bls12377.G1Affine {
|
||||
func projectiveToGnarkAffine(p icicleBls12_377.Projective) bls12377.G1Affine {
|
||||
px, _ := fp.LittleEndian.Element((*[fp.Bytes]byte)((&p.X).ToBytesLittleEndian()))
|
||||
py, _ := fp.LittleEndian.Element((*[fp.Bytes]byte)((&p.Y).ToBytesLittleEndian()))
|
||||
pz, _ := fp.LittleEndian.Element((*[fp.Bytes]byte)((&p.Z).ToBytesLittleEndian()))
|
||||
@@ -33,7 +35,7 @@ func projectiveToGnarkAffine(p Projective) bls12377.G1Affine {
|
||||
return bls12377.G1Affine{X: *x, Y: *y}
|
||||
}
|
||||
|
||||
func testAgainstGnarkCryptoMsm(scalars core.HostSlice[ScalarField], points core.HostSlice[Affine], out Projective) bool {
|
||||
func testAgainstGnarkCryptoMsm(scalars core.HostSlice[icicleBls12_377.ScalarField], points core.HostSlice[icicleBls12_377.Affine], out icicleBls12_377.Projective) bool {
|
||||
scalarsFr := make([]fr.Element, len(scalars))
|
||||
for i, v := range scalars {
|
||||
slice64, _ := fr.LittleEndian.Element((*[fr.Bytes]byte)(v.ToBytesLittleEndian()))
|
||||
@@ -44,6 +46,11 @@ func testAgainstGnarkCryptoMsm(scalars core.HostSlice[ScalarField], points core.
|
||||
for i, v := range points {
|
||||
pointsFp[i] = projectiveToGnarkAffine(v.ToProjective())
|
||||
}
|
||||
|
||||
return testAgainstGnarkCryptoMsmGnarkCryptoTypes(scalarsFr, pointsFp, out)
|
||||
}
|
||||
|
||||
func testAgainstGnarkCryptoMsmGnarkCryptoTypes(scalarsFr core.HostSlice[fr.Element], pointsFp core.HostSlice[bls12377.G1Affine], out icicleBls12_377.Projective) bool {
|
||||
var msmRes bls12377.G1Jac
|
||||
msmRes.MultiExp(pointsFp, scalarsFr, ecc.MultiExpConfig{})
|
||||
|
||||
@@ -54,54 +61,104 @@ func testAgainstGnarkCryptoMsm(scalars core.HostSlice[ScalarField], points core.
|
||||
return msmRes.Equal(&icicleResAsJac)
|
||||
}
|
||||
|
||||
func convertIcicleAffineToG1Affine(iciclePoints []icicleBls12_377.Affine) []bls12377.G1Affine {
|
||||
points := make([]bls12377.G1Affine, len(iciclePoints))
|
||||
for index, iciclePoint := range iciclePoints {
|
||||
xBytes := ([fp.Bytes]byte)(iciclePoint.X.ToBytesLittleEndian())
|
||||
fpXElem, _ := fp.LittleEndian.Element(&xBytes)
|
||||
|
||||
yBytes := ([fp.Bytes]byte)(iciclePoint.Y.ToBytesLittleEndian())
|
||||
fpYElem, _ := fp.LittleEndian.Element(&yBytes)
|
||||
points[index] = bls12377.G1Affine{
|
||||
X: fpXElem,
|
||||
Y: fpYElem,
|
||||
}
|
||||
}
|
||||
|
||||
return points
|
||||
}
|
||||
|
||||
func TestMSM(t *testing.T) {
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := msm.GetDefaultMSMConfig()
|
||||
cfg.IsAsync = true
|
||||
for _, power := range []int{2, 3, 4, 5, 6, 7, 8, 10, 18} {
|
||||
size := 1 << power
|
||||
|
||||
scalars := GenerateScalars(size)
|
||||
points := GenerateAffinePoints(size)
|
||||
scalars := icicleBls12_377.GenerateScalars(size)
|
||||
points := icicleBls12_377.GenerateAffinePoints(size)
|
||||
|
||||
stream, _ := cr.CreateStream()
|
||||
var p Projective
|
||||
var p icicleBls12_377.Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.MallocAsync(p.Size(), p.Size(), stream)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
cfg.Ctx.Stream = &stream
|
||||
|
||||
e = Msm(scalars, points, &cfg, out)
|
||||
e = msm.Msm(scalars, points, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[Projective], 1)
|
||||
outHost := make(core.HostSlice[icicleBls12_377.Projective], 1)
|
||||
outHost.CopyFromDeviceAsync(&out, stream)
|
||||
out.FreeAsync(stream)
|
||||
|
||||
cr.SynchronizeStream(&stream)
|
||||
// Check with gnark-crypto
|
||||
assert.True(t, testAgainstGnarkCryptoMsm(scalars, points, outHost[0]))
|
||||
|
||||
}
|
||||
}
|
||||
func TestMSMGnarkCryptoTypes(t *testing.T) {
|
||||
cfg := msm.GetDefaultMSMConfig()
|
||||
for _, power := range []int{3} {
|
||||
size := 1 << power
|
||||
|
||||
scalars := make([]fr.Element, size)
|
||||
var x fr.Element
|
||||
for i := 0; i < size; i++ {
|
||||
x.SetRandom()
|
||||
scalars[i] = x
|
||||
}
|
||||
scalarsHost := (core.HostSlice[fr.Element])(scalars)
|
||||
points := icicleBls12_377.GenerateAffinePoints(size)
|
||||
pointsGnark := convertIcicleAffineToG1Affine(points)
|
||||
pointsHost := (core.HostSlice[bls12377.G1Affine])(pointsGnark)
|
||||
|
||||
var p icicleBls12_377.Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.Malloc(p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
cfg.ArePointsMontgomeryForm = true
|
||||
cfg.AreScalarsMontgomeryForm = true
|
||||
|
||||
e = msm.Msm(scalarsHost, pointsHost, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[icicleBls12_377.Projective], 1)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
// Check with gnark-crypto
|
||||
assert.True(t, testAgainstGnarkCryptoMsmGnarkCryptoTypes(scalarsHost, pointsHost, outHost[0]))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMSMBatch(t *testing.T) {
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := msm.GetDefaultMSMConfig()
|
||||
for _, power := range []int{10, 16} {
|
||||
for _, batchSize := range []int{1, 3, 16} {
|
||||
size := 1 << power
|
||||
totalSize := size * batchSize
|
||||
scalars := GenerateScalars(totalSize)
|
||||
points := GenerateAffinePoints(totalSize)
|
||||
scalars := icicleBls12_377.GenerateScalars(totalSize)
|
||||
points := icicleBls12_377.GenerateAffinePoints(totalSize)
|
||||
|
||||
var p Projective
|
||||
var p icicleBls12_377.Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.Malloc(batchSize*p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
e = Msm(scalars, points, &cfg, out)
|
||||
e = msm.Msm(scalars, points, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[Projective], batchSize)
|
||||
outHost := make(core.HostSlice[icicleBls12_377.Projective], batchSize)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
// Check with gnark-crypto
|
||||
for i := 0; i < batchSize; i++ {
|
||||
scalarsSlice := scalars[i*size : (i+1)*size]
|
||||
@@ -114,36 +171,35 @@ func TestMSMBatch(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPrecomputeBase(t *testing.T) {
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := msm.GetDefaultMSMConfig()
|
||||
const precomputeFactor = 8
|
||||
for _, power := range []int{10, 16} {
|
||||
for _, batchSize := range []int{1, 3, 16} {
|
||||
size := 1 << power
|
||||
totalSize := size * batchSize
|
||||
scalars := GenerateScalars(totalSize)
|
||||
points := GenerateAffinePoints(totalSize)
|
||||
scalars := icicleBls12_377.GenerateScalars(totalSize)
|
||||
points := icicleBls12_377.GenerateAffinePoints(totalSize)
|
||||
|
||||
var precomputeOut core.DeviceSlice
|
||||
_, e := precomputeOut.Malloc(points[0].Size()*points.Len()*int(precomputeFactor), points[0].Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
|
||||
e = PrecomputeBases(points, precomputeFactor, 0, &cfg.Ctx, precomputeOut)
|
||||
e = msm.PrecomputeBases(points, precomputeFactor, 0, &cfg.Ctx, precomputeOut)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "PrecomputeBases failed")
|
||||
|
||||
var p Projective
|
||||
var p icicleBls12_377.Projective
|
||||
var out core.DeviceSlice
|
||||
_, e = out.Malloc(batchSize*p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
|
||||
e = Msm(scalars, precomputeOut, &cfg, out)
|
||||
e = msm.Msm(scalars, precomputeOut, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[Projective], batchSize)
|
||||
outHost := make(core.HostSlice[icicleBls12_377.Projective], batchSize)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
precomputeOut.Free()
|
||||
|
||||
// Check with gnark-crypto
|
||||
for i := 0; i < batchSize; i++ {
|
||||
scalarsSlice := scalars[i*size : (i+1)*size]
|
||||
@@ -156,30 +212,29 @@ func TestPrecomputeBase(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMSMSkewedDistribution(t *testing.T) {
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := msm.GetDefaultMSMConfig()
|
||||
for _, power := range []int{2, 3, 4, 5, 6, 7, 8, 10, 18} {
|
||||
size := 1 << power
|
||||
|
||||
scalars := GenerateScalars(size)
|
||||
scalars := icicleBls12_377.GenerateScalars(size)
|
||||
for i := size / 4; i < size; i++ {
|
||||
scalars[i].One()
|
||||
}
|
||||
points := GenerateAffinePoints(size)
|
||||
points := icicleBls12_377.GenerateAffinePoints(size)
|
||||
for i := 0; i < size/4; i++ {
|
||||
points[i].Zero()
|
||||
}
|
||||
|
||||
var p Projective
|
||||
var p icicleBls12_377.Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.Malloc(p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
e = Msm(scalars, points, &cfg, out)
|
||||
e = msm.Msm(scalars, points, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[Projective], 1)
|
||||
outHost := make(core.HostSlice[icicleBls12_377.Projective], 1)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
// Check with gnark-crypto
|
||||
assert.True(t, testAgainstGnarkCryptoMsm(scalars, points, outHost[0]))
|
||||
}
|
||||
@@ -196,23 +251,23 @@ func TestMSMMultiDevice(t *testing.T) {
|
||||
wg.Add(1)
|
||||
cr.RunOnDevice(i, func(args ...any) {
|
||||
defer wg.Done()
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := msm.GetDefaultMSMConfig()
|
||||
cfg.IsAsync = true
|
||||
for _, power := range []int{2, 3, 4, 5, 6, 7, 8, 10, 18} {
|
||||
size := 1 << power
|
||||
scalars := GenerateScalars(size)
|
||||
points := GenerateAffinePoints(size)
|
||||
scalars := icicleBls12_377.GenerateScalars(size)
|
||||
points := icicleBls12_377.GenerateAffinePoints(size)
|
||||
|
||||
stream, _ := cr.CreateStream()
|
||||
var p Projective
|
||||
var p icicleBls12_377.Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.MallocAsync(p.Size(), p.Size(), stream)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
cfg.Ctx.Stream = &stream
|
||||
|
||||
e = Msm(scalars, points, &cfg, out)
|
||||
e = msm.Msm(scalars, points, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[Projective], 1)
|
||||
outHost := make(core.HostSlice[icicleBls12_377.Projective], 1)
|
||||
outHost.CopyFromDeviceAsync(&out, stream)
|
||||
out.FreeAsync(stream)
|
||||
|
||||
@@ -1,40 +1,20 @@
|
||||
package bls12377
|
||||
package tests
|
||||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-377/fr"
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-377/fr/fft"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
bls12_377 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377"
|
||||
ntt "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377/ntt"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
const (
|
||||
largestTestSize = 17
|
||||
)
|
||||
|
||||
func init() {
|
||||
cfg := GetDefaultNttConfig()
|
||||
initDomain(largestTestSize, cfg)
|
||||
}
|
||||
|
||||
func initDomain[T any](largestTestSize int, cfg core.NTTConfig[T]) core.IcicleError {
|
||||
rouMont, _ := fft.Generator(uint64(1 << largestTestSize))
|
||||
rou := rouMont.Bits()
|
||||
rouIcicle := ScalarField{}
|
||||
limbs := core.ConvertUint64ArrToUint32Arr(rou[:])
|
||||
|
||||
rouIcicle.FromLimbs(limbs)
|
||||
e := InitDomain(rouIcicle, cfg.Ctx, false)
|
||||
return e
|
||||
}
|
||||
|
||||
func testAgainstGnarkCryptoNtt(size int, scalars core.HostSlice[ScalarField], output core.HostSlice[ScalarField], order core.Ordering, direction core.NTTDir) bool {
|
||||
domainWithPrecompute := fft.NewDomain(uint64(size))
|
||||
func testAgainstGnarkCryptoNtt(size int, scalars core.HostSlice[bls12_377.ScalarField], output core.HostSlice[bls12_377.ScalarField], order core.Ordering, direction core.NTTDir) bool {
|
||||
scalarsFr := make([]fr.Element, size)
|
||||
for i, v := range scalars {
|
||||
slice64, _ := fr.LittleEndian.Element((*[fr.Bytes]byte)(v.ToBytesLittleEndian()))
|
||||
@@ -46,6 +26,11 @@ func testAgainstGnarkCryptoNtt(size int, scalars core.HostSlice[ScalarField], ou
|
||||
outputAsFr[i] = slice64
|
||||
}
|
||||
|
||||
return testAgainstGnarkCryptoNttGnarkTypes(size, scalarsFr, outputAsFr, order, direction)
|
||||
}
|
||||
|
||||
func testAgainstGnarkCryptoNttGnarkTypes(size int, scalarsFr core.HostSlice[fr.Element], outputAsFr core.HostSlice[fr.Element], order core.Ordering, direction core.NTTDir) bool {
|
||||
domainWithPrecompute := fft.NewDomain(uint64(size))
|
||||
// DIT + BitReverse == Ordering.kRR
|
||||
// DIT == Ordering.kRN
|
||||
// DIF + BitReverse == Ordering.kNN
|
||||
@@ -68,72 +53,77 @@ func testAgainstGnarkCryptoNtt(size int, scalars core.HostSlice[ScalarField], ou
|
||||
}
|
||||
return reflect.DeepEqual(scalarsFr, outputAsFr)
|
||||
}
|
||||
|
||||
func TestNTTGetDefaultConfig(t *testing.T) {
|
||||
actual := GetDefaultNttConfig()
|
||||
expected := generateLimbOne(int(SCALAR_LIMBS))
|
||||
actual := ntt.GetDefaultNttConfig()
|
||||
expected := test_helpers.GenerateLimbOne(int(bls12_377.SCALAR_LIMBS))
|
||||
assert.Equal(t, expected, actual.CosetGen[:])
|
||||
|
||||
cosetGenField := ScalarField{}
|
||||
cosetGenField := bls12_377.ScalarField{}
|
||||
cosetGenField.One()
|
||||
assert.ElementsMatch(t, cosetGenField.GetLimbs(), actual.CosetGen)
|
||||
}
|
||||
|
||||
func TestInitDomain(t *testing.T) {
|
||||
t.Skip("Skipped because each test requires the domain to be initialized before running. We ensure this using the TestMain() function")
|
||||
cfg := GetDefaultNttConfig()
|
||||
cfg := ntt.GetDefaultNttConfig()
|
||||
assert.NotPanics(t, func() { initDomain(largestTestSize, cfg) })
|
||||
}
|
||||
|
||||
func TestNtt(t *testing.T) {
|
||||
cfg := GetDefaultNttConfig()
|
||||
scalars := GenerateScalars(1 << largestTestSize)
|
||||
cfg := ntt.GetDefaultNttConfig()
|
||||
scalars := bls12_377.GenerateScalars(1 << largestTestSize)
|
||||
|
||||
for _, size := range []int{4, largestTestSize} {
|
||||
for _, v := range [4]core.Ordering{core.KNN, core.KNR, core.KRN, core.KRR} {
|
||||
testSize := 1 << size
|
||||
|
||||
scalarsCopy := core.HostSliceFromElements[ScalarField](scalars[:testSize])
|
||||
scalarsCopy := core.HostSliceFromElements[bls12_377.ScalarField](scalars[:testSize])
|
||||
cfg.Ordering = v
|
||||
|
||||
// run ntt
|
||||
output := make(core.HostSlice[ScalarField], testSize)
|
||||
Ntt(scalarsCopy, core.KForward, &cfg, output)
|
||||
output := make(core.HostSlice[bls12_377.ScalarField], testSize)
|
||||
ntt.Ntt(scalarsCopy, core.KForward, &cfg, output)
|
||||
|
||||
// Compare with gnark-crypto
|
||||
assert.True(t, testAgainstGnarkCryptoNtt(testSize, scalarsCopy, output, v, core.KForward))
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestNttFrElement(t *testing.T) {
|
||||
cfg := ntt.GetDefaultNttConfig()
|
||||
scalars := make([]fr.Element, 4)
|
||||
var x fr.Element
|
||||
for i := 0; i < 4; i++ {
|
||||
x.SetRandom()
|
||||
scalars[i] = x
|
||||
}
|
||||
|
||||
func TestECNtt(t *testing.T) {
|
||||
cfg := GetDefaultNttConfig()
|
||||
points := GenerateProjectivePoints(1 << largestTestSize)
|
||||
for _, size := range []int{4} {
|
||||
for _, v := range [1]core.Ordering{core.KNN} {
|
||||
testSize := size
|
||||
|
||||
for _, size := range []int{4, 5, 6, 7, 8} {
|
||||
for _, v := range [4]core.Ordering{core.KNN, core.KNR, core.KRN, core.KRR} {
|
||||
testSize := 1 << size
|
||||
|
||||
pointsCopy := core.HostSliceFromElements[Projective](points[:testSize])
|
||||
scalarsCopy := (core.HostSlice[fr.Element])(scalars[:testSize])
|
||||
cfg.Ordering = v
|
||||
cfg.NttAlgorithm = core.Radix2
|
||||
|
||||
output := make(core.HostSlice[Projective], testSize)
|
||||
e := ECNtt(pointsCopy, core.KForward, &cfg, output)
|
||||
assert.Equal(t, core.IcicleErrorCode(0), e.IcicleErrorCode, "ECNtt failed")
|
||||
// run ntt
|
||||
output := make(core.HostSlice[fr.Element], testSize)
|
||||
ntt.Ntt(scalarsCopy, core.KForward, &cfg, output)
|
||||
|
||||
// Compare with gnark-crypto
|
||||
assert.True(t, testAgainstGnarkCryptoNttGnarkTypes(testSize, scalarsCopy, output, v, core.KForward))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNttDeviceAsync(t *testing.T) {
|
||||
cfg := GetDefaultNttConfig()
|
||||
scalars := GenerateScalars(1 << largestTestSize)
|
||||
cfg := ntt.GetDefaultNttConfig()
|
||||
scalars := bls12_377.GenerateScalars(1 << largestTestSize)
|
||||
|
||||
for _, size := range []int{1, 10, largestTestSize} {
|
||||
for _, direction := range []core.NTTDir{core.KForward, core.KInverse} {
|
||||
for _, v := range [4]core.Ordering{core.KNN, core.KNR, core.KRN, core.KRR} {
|
||||
testSize := 1 << size
|
||||
scalarsCopy := core.HostSliceFromElements[ScalarField](scalars[:testSize])
|
||||
scalarsCopy := core.HostSliceFromElements[bls12_377.ScalarField](scalars[:testSize])
|
||||
|
||||
stream, _ := cr.CreateStream()
|
||||
|
||||
@@ -147,12 +137,11 @@ func TestNttDeviceAsync(t *testing.T) {
|
||||
deviceOutput.MallocAsync(testSize*scalarsCopy.SizeOfElement(), scalarsCopy.SizeOfElement(), stream)
|
||||
|
||||
// run ntt
|
||||
Ntt(deviceInput, direction, &cfg, deviceOutput)
|
||||
output := make(core.HostSlice[ScalarField], testSize)
|
||||
ntt.Ntt(deviceInput, direction, &cfg, deviceOutput)
|
||||
output := make(core.HostSlice[bls12_377.ScalarField], testSize)
|
||||
output.CopyFromDeviceAsync(&deviceOutput, stream)
|
||||
|
||||
cr.SynchronizeStream(&stream)
|
||||
|
||||
// Compare with gnark-crypto
|
||||
assert.True(t, testAgainstGnarkCryptoNtt(testSize, scalarsCopy, output, v, direction))
|
||||
}
|
||||
@@ -161,22 +150,22 @@ func TestNttDeviceAsync(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNttBatch(t *testing.T) {
|
||||
cfg := GetDefaultNttConfig()
|
||||
cfg := ntt.GetDefaultNttConfig()
|
||||
largestBatchSize := 100
|
||||
scalars := GenerateScalars(1 << largestTestSize * largestBatchSize)
|
||||
scalars := bls12_377.GenerateScalars(1 << largestTestSize * largestBatchSize)
|
||||
|
||||
for _, size := range []int{4, largestTestSize} {
|
||||
for _, batchSize := range []int{1, 16, largestBatchSize} {
|
||||
testSize := 1 << size
|
||||
totalSize := testSize * batchSize
|
||||
|
||||
scalarsCopy := core.HostSliceFromElements[ScalarField](scalars[:totalSize])
|
||||
scalarsCopy := core.HostSliceFromElements[bls12_377.ScalarField](scalars[:totalSize])
|
||||
|
||||
cfg.Ordering = core.KNN
|
||||
cfg.BatchSize = int32(batchSize)
|
||||
// run ntt
|
||||
output := make(core.HostSlice[ScalarField], totalSize)
|
||||
Ntt(scalarsCopy, core.KForward, &cfg, output)
|
||||
output := make(core.HostSlice[bls12_377.ScalarField], totalSize)
|
||||
ntt.Ntt(scalarsCopy, core.KForward, &cfg, output)
|
||||
|
||||
// Compare with gnark-crypto
|
||||
domainWithPrecompute := fft.NewDomain(uint64(testSize))
|
||||
@@ -205,36 +194,18 @@ func TestNttBatch(t *testing.T) {
|
||||
|
||||
func TestReleaseDomain(t *testing.T) {
|
||||
t.Skip("Skipped because each test requires the domain to be initialized before running. We ensure this using the TestMain() function")
|
||||
cfg := GetDefaultNttConfig()
|
||||
e := ReleaseDomain(cfg.Ctx)
|
||||
cfg := ntt.GetDefaultNttConfig()
|
||||
e := ntt.ReleaseDomain(cfg.Ctx)
|
||||
assert.Equal(t, core.IcicleErrorCode(0), e.IcicleErrorCode, "ReleasDomain failed")
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
// setup domain
|
||||
cfg := GetDefaultNttConfig()
|
||||
e := initDomain(largestTestSize, cfg)
|
||||
if e.IcicleErrorCode != core.IcicleErrorCode(0) {
|
||||
panic("initDomain failed")
|
||||
}
|
||||
|
||||
// execute tests
|
||||
os.Exit(m.Run())
|
||||
|
||||
// release domain
|
||||
e = ReleaseDomain(cfg.Ctx)
|
||||
if e.IcicleErrorCode != core.IcicleErrorCode(0) {
|
||||
panic("ReleaseDomain failed")
|
||||
}
|
||||
}
|
||||
|
||||
// func TestNttArbitraryCoset(t *testing.T) {
|
||||
// for _, size := range []int{20} {
|
||||
// for _, v := range [4]core.Ordering{core.KNN, core.KNR, core.KRN, core.KRR} {
|
||||
// testSize := 1 << size
|
||||
// scalars := GenerateScalars(testSize)
|
||||
|
||||
// cfg := GetDefaultNttConfig()
|
||||
// cfg := ntt.GetDefaultNttConfig()
|
||||
|
||||
// var scalarsCopy core.HostSlice[ScalarField]
|
||||
// for _, v := range scalars {
|
||||
229
wrappers/golang/curves/bls12377/tests/polynomial_test.go
Normal file
229
wrappers/golang/curves/bls12377/tests/polynomial_test.go
Normal file
@@ -0,0 +1,229 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
bls12_377 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377"
|
||||
// "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377/ntt"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377/polynomial"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377/vecOps"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var one, two, three, four, five bls12_377.ScalarField
|
||||
|
||||
func init() {
|
||||
one.One()
|
||||
two.FromUint32(2)
|
||||
three.FromUint32(3)
|
||||
four.FromUint32(4)
|
||||
five.FromUint32(5)
|
||||
}
|
||||
|
||||
func rand() bls12_377.ScalarField {
|
||||
return bls12_377.GenerateScalars(1)[0]
|
||||
}
|
||||
|
||||
func randomPoly(size int) (f polynomial.DensePolynomial) {
|
||||
f.CreateFromCoeffecitients(core.HostSliceFromElements(bls12_377.GenerateScalars(size)))
|
||||
return f
|
||||
}
|
||||
|
||||
func vecOp(a, b bls12_377.ScalarField, op core.VecOps) bls12_377.ScalarField {
|
||||
ahost := core.HostSliceWithValue(a, 1)
|
||||
bhost := core.HostSliceWithValue(b, 1)
|
||||
out := make(core.HostSlice[bls12_377.ScalarField], 1)
|
||||
|
||||
cfg := core.DefaultVecOpsConfig()
|
||||
vecOps.VecOp(ahost, bhost, out, cfg, op)
|
||||
return out[0]
|
||||
}
|
||||
|
||||
func TestPolyCreateFromCoefficients(t *testing.T) {
|
||||
scalars := bls12_377.GenerateScalars(33)
|
||||
var uniPoly polynomial.DensePolynomial
|
||||
|
||||
poly := uniPoly.CreateFromCoeffecitients(scalars)
|
||||
poly.Print()
|
||||
}
|
||||
|
||||
func TestPolyEval(t *testing.T) {
|
||||
// testing correct evaluation of f(8) for f(x)=4x^2+2x+5
|
||||
coeffs := core.HostSliceFromElements([]bls12_377.ScalarField{five, two, four})
|
||||
var f polynomial.DensePolynomial
|
||||
f.CreateFromCoeffecitients(coeffs)
|
||||
|
||||
var x bls12_377.ScalarField
|
||||
x.FromUint32(8)
|
||||
domains := make(core.HostSlice[bls12_377.ScalarField], 1)
|
||||
domains[0] = x
|
||||
evals := make(core.HostSlice[bls12_377.ScalarField], 1)
|
||||
fEvaled := f.EvalOnDomain(domains, evals)
|
||||
var expected bls12_377.ScalarField
|
||||
assert.Equal(t, expected.FromUint32(277), fEvaled.(core.HostSlice[bls12_377.ScalarField])[0])
|
||||
}
|
||||
|
||||
func TestPolyClone(t *testing.T) {
|
||||
f := randomPoly(8)
|
||||
x := rand()
|
||||
fx := f.Eval(x)
|
||||
|
||||
g := f.Clone()
|
||||
fg := f.Add(&g)
|
||||
|
||||
gx := g.Eval(x)
|
||||
fgx := fg.Eval(x)
|
||||
|
||||
assert.Equal(t, fx, gx)
|
||||
assert.Equal(t, vecOp(fx, gx, core.Add), fgx)
|
||||
}
|
||||
|
||||
func TestPolyAddSubMul(t *testing.T) {
|
||||
testSize := 1 << 10
|
||||
f := randomPoly(testSize)
|
||||
g := randomPoly(testSize)
|
||||
x := rand()
|
||||
|
||||
fx := f.Eval(x)
|
||||
gx := g.Eval(x)
|
||||
|
||||
polyAdd := f.Add(&g)
|
||||
fxAddgx := vecOp(fx, gx, core.Add)
|
||||
assert.Equal(t, polyAdd.Eval(x), fxAddgx)
|
||||
|
||||
polySub := f.Subtract(&g)
|
||||
fxSubgx := vecOp(fx, gx, core.Sub)
|
||||
assert.Equal(t, polySub.Eval(x), fxSubgx)
|
||||
|
||||
polyMul := f.Multiply(&g)
|
||||
fxMulgx := vecOp(fx, gx, core.Mul)
|
||||
assert.Equal(t, polyMul.Eval(x), fxMulgx)
|
||||
|
||||
s1 := rand()
|
||||
polMulS1 := f.MultiplyByScalar(s1)
|
||||
assert.Equal(t, polMulS1.Eval(x), vecOp(fx, s1, core.Mul))
|
||||
|
||||
s2 := rand()
|
||||
polMulS2 := f.MultiplyByScalar(s2)
|
||||
assert.Equal(t, polMulS2.Eval(x), vecOp(fx, s2, core.Mul))
|
||||
}
|
||||
|
||||
func TestPolyMonomials(t *testing.T) {
|
||||
var zero bls12_377.ScalarField
|
||||
var f polynomial.DensePolynomial
|
||||
f.CreateFromCoeffecitients(core.HostSliceFromElements([]bls12_377.ScalarField{one, zero, two}))
|
||||
x := rand()
|
||||
|
||||
fx := f.Eval(x)
|
||||
f.AddMonomial(three, 1)
|
||||
fxAdded := f.Eval(x)
|
||||
assert.Equal(t, fxAdded, vecOp(fx, vecOp(three, x, core.Mul), core.Add))
|
||||
|
||||
f.SubMonomial(one, 0)
|
||||
fxSub := f.Eval(x)
|
||||
assert.Equal(t, fxSub, vecOp(fxAdded, one, core.Sub))
|
||||
}
|
||||
|
||||
func TestPolyReadCoeffs(t *testing.T) {
|
||||
var f polynomial.DensePolynomial
|
||||
coeffs := core.HostSliceFromElements([]bls12_377.ScalarField{one, two, three, four})
|
||||
f.CreateFromCoeffecitients(coeffs)
|
||||
coeffsCopied := make(core.HostSlice[bls12_377.ScalarField], coeffs.Len())
|
||||
_, _ = f.CopyCoeffsRange(0, coeffs.Len()-1, coeffsCopied)
|
||||
assert.ElementsMatch(t, coeffs, coeffsCopied)
|
||||
|
||||
var coeffsDevice core.DeviceSlice
|
||||
coeffsDevice.Malloc(coeffs.Len()*one.Size(), one.Size())
|
||||
_, _ = f.CopyCoeffsRange(0, coeffs.Len()-1, coeffsDevice)
|
||||
coeffsHost := make(core.HostSlice[bls12_377.ScalarField], coeffs.Len())
|
||||
coeffsHost.CopyFromDevice(&coeffsDevice)
|
||||
|
||||
assert.ElementsMatch(t, coeffs, coeffsHost)
|
||||
}
|
||||
|
||||
func TestPolyOddEvenSlicing(t *testing.T) {
|
||||
size := 1<<10 - 3
|
||||
f := randomPoly(size)
|
||||
|
||||
even := f.Even()
|
||||
odd := f.Odd()
|
||||
assert.Equal(t, f.Degree(), even.Degree()+odd.Degree()+1)
|
||||
|
||||
x := rand()
|
||||
var evenExpected, oddExpected bls12_377.ScalarField
|
||||
for i := size; i >= 0; i-- {
|
||||
if i%2 == 0 {
|
||||
mul := vecOp(evenExpected, x, core.Mul)
|
||||
evenExpected = vecOp(mul, f.GetCoeff(i), core.Add)
|
||||
} else {
|
||||
mul := vecOp(oddExpected, x, core.Mul)
|
||||
oddExpected = vecOp(mul, f.GetCoeff(i), core.Add)
|
||||
}
|
||||
}
|
||||
|
||||
evenEvaled := even.Eval(x)
|
||||
assert.Equal(t, evenExpected, evenEvaled)
|
||||
|
||||
oddEvaled := odd.Eval(x)
|
||||
assert.Equal(t, oddExpected, oddEvaled)
|
||||
}
|
||||
|
||||
func TestPolynomialDivision(t *testing.T) {
|
||||
// divide f(x)/g(x), compute q(x), r(x) and check f(x)=q(x)*g(x)+r(x)
|
||||
var f, g polynomial.DensePolynomial
|
||||
f.CreateFromCoeffecitients(core.HostSliceFromElements(bls12_377.GenerateScalars(1 << 4)))
|
||||
g.CreateFromCoeffecitients(core.HostSliceFromElements(bls12_377.GenerateScalars(1 << 2)))
|
||||
|
||||
q, r := f.Divide(&g)
|
||||
|
||||
qMulG := q.Multiply(&g)
|
||||
fRecon := qMulG.Add(&r)
|
||||
|
||||
x := bls12_377.GenerateScalars(1)[0]
|
||||
fEval := f.Eval(x)
|
||||
fReconEval := fRecon.Eval(x)
|
||||
assert.Equal(t, fEval, fReconEval)
|
||||
}
|
||||
|
||||
func TestDivideByVanishing(t *testing.T) {
|
||||
// poly of x^4-1 vanishes ad 4th rou
|
||||
var zero bls12_377.ScalarField
|
||||
minus_one := vecOp(zero, one, core.Sub)
|
||||
coeffs := core.HostSliceFromElements([]bls12_377.ScalarField{minus_one, zero, zero, zero, one}) // x^4-1
|
||||
var v polynomial.DensePolynomial
|
||||
v.CreateFromCoeffecitients(coeffs)
|
||||
|
||||
f := randomPoly(1 << 3)
|
||||
|
||||
fv := f.Multiply(&v)
|
||||
fDegree := f.Degree()
|
||||
fvDegree := fv.Degree()
|
||||
assert.Equal(t, fDegree+4, fvDegree)
|
||||
|
||||
fReconstructed := fv.DivideByVanishing(4)
|
||||
assert.Equal(t, fDegree, fReconstructed.Degree())
|
||||
|
||||
x := rand()
|
||||
assert.Equal(t, f.Eval(x), fReconstructed.Eval(x))
|
||||
}
|
||||
|
||||
// func TestPolySlice(t *testing.T) {
|
||||
// size := 4
|
||||
// coeffs := bls12_377.GenerateScalars(size)
|
||||
// var f DensePolynomial
|
||||
// f.CreateFromCoeffecitients(coeffs)
|
||||
// fSlice := f.AsSlice()
|
||||
// assert.True(t, fSlice.IsOnDevice())
|
||||
// assert.Equal(t, size, fSlice.Len())
|
||||
|
||||
// hostSlice := make(core.HostSlice[bls12_377.ScalarField], size)
|
||||
// hostSlice.CopyFromDevice(fSlice)
|
||||
// assert.Equal(t, coeffs, hostSlice)
|
||||
|
||||
// cfg := ntt.GetDefaultNttConfig()
|
||||
// res := make(core.HostSlice[bls12_377.ScalarField], size)
|
||||
// ntt.Ntt(fSlice, core.KForward, cfg, res)
|
||||
|
||||
// assert.Equal(t, f.Eval(one), res[0])
|
||||
// }
|
||||
120
wrappers/golang/curves/bls12377/tests/scalar_field_test.go
Normal file
120
wrappers/golang/curves/bls12377/tests/scalar_field_test.go
Normal file
@@ -0,0 +1,120 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
bls12_377 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
SCALAR_LIMBS = bls12_377.SCALAR_LIMBS
|
||||
)
|
||||
|
||||
func TestScalarFieldFromLimbs(t *testing.T) {
|
||||
emptyField := bls12_377.ScalarField{}
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(SCALAR_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
assert.ElementsMatch(t, randLimbs, emptyField.GetLimbs(), "Limbs do not match; there was an issue with setting the ScalarField's limbs")
|
||||
randLimbs[0] = 100
|
||||
assert.NotEqual(t, randLimbs, emptyField.GetLimbs())
|
||||
}
|
||||
|
||||
func TestScalarFieldGetLimbs(t *testing.T) {
|
||||
emptyField := bls12_377.ScalarField{}
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(SCALAR_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.ElementsMatch(t, randLimbs, emptyField.GetLimbs(), "Limbs do not match; there was an issue with setting the ScalarField's limbs")
|
||||
}
|
||||
|
||||
func TestScalarFieldOne(t *testing.T) {
|
||||
var emptyField bls12_377.ScalarField
|
||||
emptyField.One()
|
||||
limbOne := test_helpers.GenerateLimbOne(int(SCALAR_LIMBS))
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbOne, "Empty field to field one did not work")
|
||||
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(SCALAR_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
emptyField.One()
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbOne, "ScalarField with limbs to field one did not work")
|
||||
}
|
||||
|
||||
func TestScalarFieldZero(t *testing.T) {
|
||||
var emptyField bls12_377.ScalarField
|
||||
emptyField.Zero()
|
||||
limbsZero := make([]uint32, SCALAR_LIMBS)
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbsZero, "Empty field to field zero failed")
|
||||
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(SCALAR_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
emptyField.Zero()
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbsZero, "ScalarField with limbs to field zero failed")
|
||||
}
|
||||
|
||||
func TestScalarFieldSize(t *testing.T) {
|
||||
var emptyField bls12_377.ScalarField
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(SCALAR_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.Equal(t, len(randLimbs)*4, emptyField.Size(), "Size returned an incorrect value of bytes")
|
||||
}
|
||||
|
||||
func TestScalarFieldAsPointer(t *testing.T) {
|
||||
var emptyField bls12_377.ScalarField
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(SCALAR_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.Equal(t, randLimbs[0], *emptyField.AsPointer(), "AsPointer returned pointer to incorrect value")
|
||||
}
|
||||
|
||||
func TestScalarFieldFromBytes(t *testing.T) {
|
||||
var emptyField bls12_377.ScalarField
|
||||
bytes, expected := test_helpers.GenerateBytesArray(int(SCALAR_LIMBS))
|
||||
|
||||
emptyField.FromBytesLittleEndian(bytes)
|
||||
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), expected, "FromBytes returned incorrect values")
|
||||
}
|
||||
|
||||
func TestScalarFieldToBytes(t *testing.T) {
|
||||
var emptyField bls12_377.ScalarField
|
||||
expected, limbs := test_helpers.GenerateBytesArray(int(SCALAR_LIMBS))
|
||||
emptyField.FromLimbs(limbs)
|
||||
|
||||
assert.ElementsMatch(t, emptyField.ToBytesLittleEndian(), expected, "ToBytes returned incorrect values")
|
||||
}
|
||||
|
||||
func TestBls12_377GenerateScalars(t *testing.T) {
|
||||
const numScalars = 8
|
||||
scalars := bls12_377.GenerateScalars(numScalars)
|
||||
|
||||
assert.Implements(t, (*core.HostOrDeviceSlice)(nil), &scalars)
|
||||
|
||||
assert.Equal(t, numScalars, scalars.Len())
|
||||
zeroScalar := bls12_377.ScalarField{}
|
||||
assert.NotContains(t, scalars, zeroScalar)
|
||||
}
|
||||
|
||||
func TestBls12_377MongtomeryConversion(t *testing.T) {
|
||||
size := 1 << 15
|
||||
scalars := bls12_377.GenerateScalars(size)
|
||||
|
||||
var deviceScalars core.DeviceSlice
|
||||
scalars.CopyToDevice(&deviceScalars, true)
|
||||
|
||||
bls12_377.ToMontgomery(&deviceScalars)
|
||||
|
||||
scalarsMontHost := bls12_377.GenerateScalars(size)
|
||||
|
||||
scalarsMontHost.CopyFromDevice(&deviceScalars)
|
||||
assert.NotEqual(t, scalars, scalarsMontHost)
|
||||
|
||||
bls12_377.FromMontgomery(&deviceScalars)
|
||||
|
||||
scalarsMontHost.CopyFromDevice(&deviceScalars)
|
||||
assert.Equal(t, scalars, scalarsMontHost)
|
||||
}
|
||||
69
wrappers/golang/curves/bls12377/tests/vec_ops_test.go
Normal file
69
wrappers/golang/curves/bls12377/tests/vec_ops_test.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
bls12_377 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12377/vecOps"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestBls12_377VecOps(t *testing.T) {
|
||||
testSize := 1 << 14
|
||||
|
||||
a := bls12_377.GenerateScalars(testSize)
|
||||
b := bls12_377.GenerateScalars(testSize)
|
||||
var scalar bls12_377.ScalarField
|
||||
scalar.One()
|
||||
ones := core.HostSliceWithValue(scalar, testSize)
|
||||
|
||||
out := make(core.HostSlice[bls12_377.ScalarField], testSize)
|
||||
out2 := make(core.HostSlice[bls12_377.ScalarField], testSize)
|
||||
out3 := make(core.HostSlice[bls12_377.ScalarField], testSize)
|
||||
|
||||
cfg := core.DefaultVecOpsConfig()
|
||||
|
||||
vecOps.VecOp(a, b, out, cfg, core.Add)
|
||||
vecOps.VecOp(out, b, out2, cfg, core.Sub)
|
||||
|
||||
assert.Equal(t, a, out2)
|
||||
|
||||
vecOps.VecOp(a, ones, out3, cfg, core.Mul)
|
||||
|
||||
assert.Equal(t, a, out3)
|
||||
}
|
||||
|
||||
func TestBls12_377Transpose(t *testing.T) {
|
||||
rowSize := 1 << 6
|
||||
columnSize := 1 << 8
|
||||
onDevice := false
|
||||
isAsync := false
|
||||
|
||||
matrix := bls12_377.GenerateScalars(rowSize * columnSize)
|
||||
|
||||
out := make(core.HostSlice[bls12_377.ScalarField], rowSize*columnSize)
|
||||
out2 := make(core.HostSlice[bls12_377.ScalarField], rowSize*columnSize)
|
||||
|
||||
ctx, _ := cr.GetDefaultDeviceContext()
|
||||
|
||||
vecOps.TransposeMatrix(matrix, out, columnSize, rowSize, ctx, onDevice, isAsync)
|
||||
vecOps.TransposeMatrix(out, out2, rowSize, columnSize, ctx, onDevice, isAsync)
|
||||
|
||||
assert.Equal(t, matrix, out2)
|
||||
|
||||
var dMatrix, dOut, dOut2 core.DeviceSlice
|
||||
onDevice = true
|
||||
|
||||
matrix.CopyToDevice(&dMatrix, true)
|
||||
dOut.Malloc(columnSize*rowSize*matrix.SizeOfElement(), matrix.SizeOfElement())
|
||||
dOut2.Malloc(columnSize*rowSize*matrix.SizeOfElement(), matrix.SizeOfElement())
|
||||
|
||||
vecOps.TransposeMatrix(dMatrix, dOut, columnSize, rowSize, ctx, onDevice, isAsync)
|
||||
vecOps.TransposeMatrix(dOut, dOut2, rowSize, columnSize, ctx, onDevice, isAsync)
|
||||
output := make(core.HostSlice[bls12_377.ScalarField], rowSize*columnSize)
|
||||
output.CopyFromDevice(&dOut2)
|
||||
|
||||
assert.Equal(t, matrix, output)
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include "../../include/types.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_377_VEC_OPS_H
|
||||
#define _BLS12_377_VEC_OPS_H
|
||||
@@ -8,7 +8,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
cudaError_t bls12_377MulCuda(
|
||||
typedef struct scalar_t scalar_t;
|
||||
typedef struct VecOpsConfig VecOpsConfig;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
|
||||
cudaError_t bls12_377_mul_cuda(
|
||||
scalar_t* vec_a,
|
||||
scalar_t* vec_b,
|
||||
int n,
|
||||
@@ -16,7 +20,7 @@ cudaError_t bls12_377MulCuda(
|
||||
scalar_t* result
|
||||
);
|
||||
|
||||
cudaError_t bls12_377AddCuda(
|
||||
cudaError_t bls12_377_add_cuda(
|
||||
scalar_t* vec_a,
|
||||
scalar_t* vec_b,
|
||||
int n,
|
||||
@@ -24,7 +28,7 @@ cudaError_t bls12_377AddCuda(
|
||||
scalar_t* result
|
||||
);
|
||||
|
||||
cudaError_t bls12_377SubCuda(
|
||||
cudaError_t bls12_377_sub_cuda(
|
||||
scalar_t* vec_a,
|
||||
scalar_t* vec_b,
|
||||
int n,
|
||||
@@ -32,6 +36,16 @@ cudaError_t bls12_377SubCuda(
|
||||
scalar_t* result
|
||||
);
|
||||
|
||||
cudaError_t bls12_377_transpose_matrix_cuda(
|
||||
scalar_t* mat_in,
|
||||
int row_size,
|
||||
int column_size,
|
||||
scalar_t* mat_out,
|
||||
DeviceContext* ctx,
|
||||
bool on_device,
|
||||
bool is_async
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
48
wrappers/golang/curves/bls12377/vecOps/vec_ops.go
Normal file
48
wrappers/golang/curves/bls12377/vecOps/vec_ops.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package vecOps
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "vec_ops.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func VecOp(a, b, out core.HostOrDeviceSlice, config core.VecOpsConfig, op core.VecOps) (ret cr.CudaError) {
|
||||
aPointer, bPointer, outPointer, cfgPointer, size := core.VecOpCheck(a, b, out, &config)
|
||||
|
||||
cA := (*C.scalar_t)(aPointer)
|
||||
cB := (*C.scalar_t)(bPointer)
|
||||
cOut := (*C.scalar_t)(outPointer)
|
||||
cConfig := (*C.VecOpsConfig)(cfgPointer)
|
||||
cSize := (C.int)(size)
|
||||
|
||||
switch op {
|
||||
case core.Sub:
|
||||
ret = (cr.CudaError)(C.bls12_377_sub_cuda(cA, cB, cSize, cConfig, cOut))
|
||||
case core.Add:
|
||||
ret = (cr.CudaError)(C.bls12_377_add_cuda(cA, cB, cSize, cConfig, cOut))
|
||||
case core.Mul:
|
||||
ret = (cr.CudaError)(C.bls12_377_mul_cuda(cA, cB, cSize, cConfig, cOut))
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func TransposeMatrix(in, out core.HostOrDeviceSlice, columnSize, rowSize int, ctx cr.DeviceContext, onDevice, isAsync bool) (ret core.IcicleError) {
|
||||
core.TransposeCheck(in, out, onDevice)
|
||||
|
||||
cIn := (*C.scalar_t)(in.AsUnsafePointer())
|
||||
cOut := (*C.scalar_t)(out.AsUnsafePointer())
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
cRowSize := (C.int)(rowSize)
|
||||
cColumnSize := (C.int)(columnSize)
|
||||
cOnDevice := (C._Bool)(onDevice)
|
||||
cIsAsync := (C._Bool)(isAsync)
|
||||
|
||||
err := (cr.CudaError)(C.bls12_377_transpose_matrix_cuda(cIn, cRowSize, cColumnSize, cOut, cCtx, cOnDevice, cIsAsync))
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package bls12377
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "vec_ops.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
)
|
||||
|
||||
func VecOp(a, b, out core.HostOrDeviceSlice, config core.VecOpsConfig, op core.VecOps) (ret cr.CudaError) {
|
||||
core.VecOpCheck(a, b, out, &config)
|
||||
var cA, cB, cOut *C.scalar_t
|
||||
|
||||
if a.IsOnDevice() {
|
||||
aDevice := a.(core.DeviceSlice)
|
||||
aDevice.CheckDevice()
|
||||
cA = (*C.scalar_t)(aDevice.AsPointer())
|
||||
} else {
|
||||
cA = (*C.scalar_t)(unsafe.Pointer(&a.(core.HostSlice[ScalarField])[0]))
|
||||
}
|
||||
|
||||
if b.IsOnDevice() {
|
||||
bDevice := b.(core.DeviceSlice)
|
||||
bDevice.CheckDevice()
|
||||
cB = (*C.scalar_t)(bDevice.AsPointer())
|
||||
} else {
|
||||
cB = (*C.scalar_t)(unsafe.Pointer(&b.(core.HostSlice[ScalarField])[0]))
|
||||
}
|
||||
|
||||
if out.IsOnDevice() {
|
||||
outDevice := out.(core.DeviceSlice)
|
||||
outDevice.CheckDevice()
|
||||
cOut = (*C.scalar_t)(outDevice.AsPointer())
|
||||
} else {
|
||||
cOut = (*C.scalar_t)(unsafe.Pointer(&out.(core.HostSlice[ScalarField])[0]))
|
||||
}
|
||||
|
||||
cConfig := (*C.VecOpsConfig)(unsafe.Pointer(&config))
|
||||
cSize := (C.int)(a.Len())
|
||||
|
||||
switch op {
|
||||
case core.Sub:
|
||||
ret = (cr.CudaError)(C.bls12_377SubCuda(cA, cB, cSize, cConfig, cOut))
|
||||
case core.Add:
|
||||
ret = (cr.CudaError)(C.bls12_377AddCuda(cA, cB, cSize, cConfig, cOut))
|
||||
case core.Mul:
|
||||
ret = (cr.CudaError)(C.bls12_377MulCuda(cA, cB, cSize, cConfig, cOut))
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package bls12377
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestVecOps(t *testing.T) {
|
||||
testSize := 1 << 14
|
||||
|
||||
a := GenerateScalars(testSize)
|
||||
b := GenerateScalars(testSize)
|
||||
var scalar ScalarField
|
||||
scalar.One()
|
||||
ones := core.HostSliceWithValue(scalar, testSize)
|
||||
|
||||
out := make(core.HostSlice[ScalarField], testSize)
|
||||
out2 := make(core.HostSlice[ScalarField], testSize)
|
||||
out3 := make(core.HostSlice[ScalarField], testSize)
|
||||
|
||||
cfg := core.DefaultVecOpsConfig()
|
||||
|
||||
VecOp(a, b, out, cfg, core.Add)
|
||||
VecOp(out, b, out2, cfg, core.Sub)
|
||||
|
||||
assert.Equal(t, a, out2)
|
||||
|
||||
VecOp(a, ones, out3, cfg, core.Mul)
|
||||
|
||||
assert.Equal(t, a, out3)
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
BASE_LIMBS int8 = 12
|
||||
BASE_LIMBS int = 12
|
||||
)
|
||||
|
||||
type BaseField struct {
|
||||
@@ -29,6 +29,11 @@ func (f BaseField) AsPointer() *uint32 {
|
||||
return &f.limbs[0]
|
||||
}
|
||||
|
||||
func (f *BaseField) FromUint32(v uint32) BaseField {
|
||||
f.limbs[0] = v
|
||||
return *f
|
||||
}
|
||||
|
||||
func (f *BaseField) FromLimbs(limbs []uint32) BaseField {
|
||||
if len(limbs) != f.Len() {
|
||||
panic("Called FromLimbs with limbs of different length than field")
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
package bls12381
|
||||
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../../../icicle/build -lingo_bls12_381 -lstdc++ -lm
|
||||
import "C"
|
||||
@@ -53,7 +53,7 @@ func (p *Projective) FromAffine(a Affine) Projective {
|
||||
func (p Projective) ProjectiveEq(p2 *Projective) bool {
|
||||
cP := (*C.projective_t)(unsafe.Pointer(&p))
|
||||
cP2 := (*C.projective_t)(unsafe.Pointer(&p2))
|
||||
__ret := C.bls12_381Eq(cP, cP2)
|
||||
__ret := C.bls12_381_eq(cP, cP2)
|
||||
return __ret == (C._Bool)(true)
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ func (p *Projective) ProjectiveToAffine() Affine {
|
||||
|
||||
cA := (*C.affine_t)(unsafe.Pointer(&a))
|
||||
cP := (*C.projective_t)(unsafe.Pointer(&p))
|
||||
C.bls12_381ToAffine(cP, cA)
|
||||
C.bls12_381_to_affine(cP, cA)
|
||||
return a
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ func GenerateProjectivePoints(size int) core.HostSlice[Projective] {
|
||||
pointsSlice := core.HostSliceFromElements[Projective](points)
|
||||
pPoints := (*C.projective_t)(unsafe.Pointer(&pointsSlice[0]))
|
||||
cSize := (C.int)(size)
|
||||
C.bls12_381GenerateProjectivePoints(pPoints, cSize)
|
||||
C.bls12_381_generate_projective_points(pPoints, cSize)
|
||||
|
||||
return pointsSlice
|
||||
}
|
||||
@@ -129,18 +129,18 @@ func GenerateAffinePoints(size int) core.HostSlice[Affine] {
|
||||
pointsSlice := core.HostSliceFromElements[Affine](points)
|
||||
cPoints := (*C.affine_t)(unsafe.Pointer(&pointsSlice[0]))
|
||||
cSize := (C.int)(size)
|
||||
C.bls12_381GenerateAffinePoints(cPoints, cSize)
|
||||
C.bls12_381_generate_affine_points(cPoints, cSize)
|
||||
|
||||
return pointsSlice
|
||||
}
|
||||
|
||||
func convertAffinePointsMontgomery(points *core.DeviceSlice, isInto bool) cr.CudaError {
|
||||
cValues := (*C.affine_t)(points.AsPointer())
|
||||
cValues := (*C.affine_t)(points.AsUnsafePointer())
|
||||
cSize := (C.size_t)(points.Len())
|
||||
cIsInto := (C._Bool)(isInto)
|
||||
defaultCtx, _ := cr.GetDefaultDeviceContext()
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&defaultCtx))
|
||||
__ret := C.bls12_381AffineConvertMontgomery(cValues, cSize, cIsInto, cCtx)
|
||||
__ret := C.bls12_381_affine_convert_montgomery(cValues, cSize, cIsInto, cCtx)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
@@ -156,12 +156,12 @@ func AffineFromMontgomery(points *core.DeviceSlice) cr.CudaError {
|
||||
}
|
||||
|
||||
func convertProjectivePointsMontgomery(points *core.DeviceSlice, isInto bool) cr.CudaError {
|
||||
cValues := (*C.projective_t)(points.AsPointer())
|
||||
cValues := (*C.projective_t)(points.AsUnsafePointer())
|
||||
cSize := (C.size_t)(points.Len())
|
||||
cIsInto := (C._Bool)(isInto)
|
||||
defaultCtx, _ := cr.GetDefaultDeviceContext()
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&defaultCtx))
|
||||
__ret := C.bls12_381ProjectiveConvertMontgomery(cValues, cSize, cIsInto, cCtx)
|
||||
__ret := C.bls12_381_projective_convert_montgomery(cValues, cSize, cIsInto, cCtx)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
24
wrappers/golang/curves/bls12381/ecntt/ecntt.go
Normal file
24
wrappers/golang/curves/bls12381/ecntt/ecntt.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package ecntt
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "ecntt.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
)
|
||||
|
||||
func ECNtt[T any](points core.HostOrDeviceSlice, dir core.NTTDir, cfg *core.NTTConfig[T], results core.HostOrDeviceSlice) core.IcicleError {
|
||||
pointsPointer, resultsPointer, size, cfgPointer := core.NttCheck[T](points, cfg, results)
|
||||
|
||||
cPoints := (*C.projective_t)(pointsPointer)
|
||||
cSize := (C.int)(size)
|
||||
cDir := (C.int)(dir)
|
||||
cCfg := (*C.NTTConfig)(cfgPointer)
|
||||
cResults := (*C.projective_t)(resultsPointer)
|
||||
|
||||
__ret := C.bls12_381_ecntt_cuda(cPoints, cSize, cDir, cCfg, cResults)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
19
wrappers/golang/curves/bls12381/ecntt/include/ecntt.h
Normal file
19
wrappers/golang/curves/bls12381/ecntt/include/ecntt.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <cuda_runtime.h>
|
||||
|
||||
#ifndef _BLS12_381_ECNTT_H
|
||||
#define _BLS12_381_ECNTT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct NTTConfig NTTConfig;
|
||||
typedef struct projective_t projective_t;
|
||||
|
||||
cudaError_t bls12_381_ecntt_cuda(const projective_t* input, int size, int dir, NTTConfig* config, projective_t* output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,9 +1,7 @@
|
||||
//go:build g2
|
||||
|
||||
package bn254
|
||||
package g2
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "g2_curve.h"
|
||||
// #include "curve.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
@@ -55,7 +53,7 @@ func (p *G2Projective) FromAffine(a G2Affine) G2Projective {
|
||||
func (p G2Projective) ProjectiveEq(p2 *G2Projective) bool {
|
||||
cP := (*C.g2_projective_t)(unsafe.Pointer(&p))
|
||||
cP2 := (*C.g2_projective_t)(unsafe.Pointer(&p2))
|
||||
__ret := C.bn254G2Eq(cP, cP2)
|
||||
__ret := C.bls12_381_g2_eq(cP, cP2)
|
||||
return __ret == (C._Bool)(true)
|
||||
}
|
||||
|
||||
@@ -64,7 +62,7 @@ func (p *G2Projective) ProjectiveToAffine() G2Affine {
|
||||
|
||||
cA := (*C.g2_affine_t)(unsafe.Pointer(&a))
|
||||
cP := (*C.g2_projective_t)(unsafe.Pointer(&p))
|
||||
C.bn254G2ToAffine(cP, cA)
|
||||
C.bls12_381_g2_to_affine(cP, cA)
|
||||
return a
|
||||
}
|
||||
|
||||
@@ -77,7 +75,7 @@ func G2GenerateProjectivePoints(size int) core.HostSlice[G2Projective] {
|
||||
pointsSlice := core.HostSliceFromElements[G2Projective](points)
|
||||
pPoints := (*C.g2_projective_t)(unsafe.Pointer(&pointsSlice[0]))
|
||||
cSize := (C.int)(size)
|
||||
C.bn254G2GenerateProjectivePoints(pPoints, cSize)
|
||||
C.bls12_381_g2_generate_projective_points(pPoints, cSize)
|
||||
|
||||
return pointsSlice
|
||||
}
|
||||
@@ -131,18 +129,18 @@ func G2GenerateAffinePoints(size int) core.HostSlice[G2Affine] {
|
||||
pointsSlice := core.HostSliceFromElements[G2Affine](points)
|
||||
cPoints := (*C.g2_affine_t)(unsafe.Pointer(&pointsSlice[0]))
|
||||
cSize := (C.int)(size)
|
||||
C.bn254G2GenerateAffinePoints(cPoints, cSize)
|
||||
C.bls12_381_g2_generate_affine_points(cPoints, cSize)
|
||||
|
||||
return pointsSlice
|
||||
}
|
||||
|
||||
func convertG2AffinePointsMontgomery(points *core.DeviceSlice, isInto bool) cr.CudaError {
|
||||
cValues := (*C.g2_affine_t)(points.AsPointer())
|
||||
cValues := (*C.g2_affine_t)(points.AsUnsafePointer())
|
||||
cSize := (C.size_t)(points.Len())
|
||||
cIsInto := (C._Bool)(isInto)
|
||||
defaultCtx, _ := cr.GetDefaultDeviceContext()
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&defaultCtx))
|
||||
__ret := C.bn254G2AffineConvertMontgomery(cValues, cSize, cIsInto, cCtx)
|
||||
__ret := C.bls12_381_g2_affine_convert_montgomery(cValues, cSize, cIsInto, cCtx)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
@@ -158,12 +156,12 @@ func G2AffineFromMontgomery(points *core.DeviceSlice) cr.CudaError {
|
||||
}
|
||||
|
||||
func convertG2ProjectivePointsMontgomery(points *core.DeviceSlice, isInto bool) cr.CudaError {
|
||||
cValues := (*C.g2_projective_t)(points.AsPointer())
|
||||
cValues := (*C.g2_projective_t)(points.AsUnsafePointer())
|
||||
cSize := (C.size_t)(points.Len())
|
||||
cIsInto := (C._Bool)(isInto)
|
||||
defaultCtx, _ := cr.GetDefaultDeviceContext()
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&defaultCtx))
|
||||
__ret := C.bn254G2ProjectiveConvertMontgomery(cValues, cSize, cIsInto, cCtx)
|
||||
__ret := C.bls12_381_g2_projective_convert_montgomery(cValues, cSize, cIsInto, cCtx)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
//go:build g2
|
||||
|
||||
package bls12377
|
||||
package g2
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
@@ -8,19 +6,19 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
G2_BASE_LIMBS int8 = 24
|
||||
G2BASE_LIMBS int = 24
|
||||
)
|
||||
|
||||
type G2BaseField struct {
|
||||
limbs [G2_BASE_LIMBS]uint32
|
||||
limbs [G2BASE_LIMBS]uint32
|
||||
}
|
||||
|
||||
func (f G2BaseField) Len() int {
|
||||
return int(G2_BASE_LIMBS)
|
||||
return int(G2BASE_LIMBS)
|
||||
}
|
||||
|
||||
func (f G2BaseField) Size() int {
|
||||
return int(G2_BASE_LIMBS * 4)
|
||||
return int(G2BASE_LIMBS * 4)
|
||||
}
|
||||
|
||||
func (f G2BaseField) GetLimbs() []uint32 {
|
||||
@@ -31,6 +29,11 @@ func (f G2BaseField) AsPointer() *uint32 {
|
||||
return &f.limbs[0]
|
||||
}
|
||||
|
||||
func (f *G2BaseField) FromUint32(v uint32) G2BaseField {
|
||||
f.limbs[0] = v
|
||||
return *f
|
||||
}
|
||||
|
||||
func (f *G2BaseField) FromLimbs(limbs []uint32) G2BaseField {
|
||||
if len(limbs) != f.Len() {
|
||||
panic("Called FromLimbs with limbs of different length than field")
|
||||
26
wrappers/golang/curves/bls12381/g2/include/curve.h
Normal file
26
wrappers/golang/curves/bls12381/g2/include/curve.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_381_G2CURVE_H
|
||||
#define _BLS12_381_G2CURVE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct g2_projective_t g2_projective_t;
|
||||
typedef struct g2_affine_t g2_affine_t;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
|
||||
bool bls12_381_g2_eq(g2_projective_t* point1, g2_projective_t* point2);
|
||||
void bls12_381_g2_to_affine(g2_projective_t* point, g2_affine_t* point_out);
|
||||
void bls12_381_g2_generate_projective_points(g2_projective_t* points, int size);
|
||||
void bls12_381_g2_generate_affine_points(g2_affine_t* points, int size);
|
||||
cudaError_t bls12_381_g2_affine_convert_montgomery(g2_affine_t* points, size_t n, bool is_into, DeviceContext* ctx);
|
||||
cudaError_t bls12_381_g2_projective_convert_montgomery(g2_projective_t* points, size_t n, bool is_into, DeviceContext* ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
24
wrappers/golang/curves/bls12381/g2/include/msm.h
Normal file
24
wrappers/golang/curves/bls12381/g2/include/msm.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_381_G2MSM_H
|
||||
#define _BLS12_381_G2MSM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct scalar_t scalar_t;
|
||||
typedef struct g2_projective_t g2_projective_t;
|
||||
typedef struct g2_affine_t g2_affine_t;
|
||||
typedef struct MSMConfig MSMConfig;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
|
||||
cudaError_t bls12_381_g2_msm_cuda(const scalar_t* scalars,const g2_affine_t* points, int count, MSMConfig* config, g2_projective_t* out);
|
||||
cudaError_t bls12_381_g2_precompute_msm_bases_cuda(g2_affine_t* points, int count, int precompute_factor, int _c, bool bases_on_device, DeviceContext* ctx, g2_affine_t* out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
21
wrappers/golang/curves/bls12381/g2/include/scalar_field.h
Normal file
21
wrappers/golang/curves/bls12381/g2/include/scalar_field.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_381_FIELD_H
|
||||
#define _BLS12_381_FIELD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct scalar_t scalar_t;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
|
||||
void bls12_381_generate_scalars(scalar_t* scalars, int size);
|
||||
cudaError_t bls12_381_scalar_convert_montgomery(scalar_t* d_inout, size_t n, bool is_into, DeviceContext* ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
45
wrappers/golang/curves/bls12381/g2/msm.go
Normal file
45
wrappers/golang/curves/bls12381/g2/msm.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package g2
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "msm.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func G2GetDefaultMSMConfig() core.MSMConfig {
|
||||
return core.GetDefaultMSMConfig()
|
||||
}
|
||||
|
||||
func G2Msm(scalars core.HostOrDeviceSlice, points core.HostOrDeviceSlice, cfg *core.MSMConfig, results core.HostOrDeviceSlice) cr.CudaError {
|
||||
scalarsPointer, pointsPointer, resultsPointer, size, cfgPointer := core.MsmCheck(scalars, points, cfg, results)
|
||||
|
||||
cScalars := (*C.scalar_t)(scalarsPointer)
|
||||
cPoints := (*C.g2_affine_t)(pointsPointer)
|
||||
cResults := (*C.g2_projective_t)(resultsPointer)
|
||||
cSize := (C.int)(size)
|
||||
cCfg := (*C.MSMConfig)(cfgPointer)
|
||||
|
||||
__ret := C.bls12_381_g2_msm_cuda(cScalars, cPoints, cSize, cCfg, cResults)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
func G2PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c int32, ctx *cr.DeviceContext, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputeBasesCheck(points, precomputeFactor, outputBases)
|
||||
|
||||
cPoints := (*C.g2_affine_t)(pointsPointer)
|
||||
cPointsLen := (C.int)(points.Len())
|
||||
cPrecomputeFactor := (C.int)(precomputeFactor)
|
||||
cC := (C.int)(c)
|
||||
cPointsIsOnDevice := (C._Bool)(points.IsOnDevice())
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(ctx))
|
||||
cOutputBases := (*C.g2_affine_t)(outputBasesPointer)
|
||||
|
||||
__ret := C.bls12_381_g2_precompute_msm_bases_cuda(cPoints, cPointsLen, cPrecomputeFactor, cC, cPointsIsOnDevice, cCtx, cOutputBases)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
//go:build g2
|
||||
|
||||
package bls12381
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "g2_msm.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func G2GetDefaultMSMConfig() core.MSMConfig {
|
||||
return core.GetDefaultMSMConfig()
|
||||
}
|
||||
|
||||
func G2Msm(scalars core.HostOrDeviceSlice, points core.HostOrDeviceSlice, cfg *core.MSMConfig, results core.HostOrDeviceSlice) cr.CudaError {
|
||||
core.MsmCheck(scalars, points, cfg, results)
|
||||
var scalarsPointer unsafe.Pointer
|
||||
if scalars.IsOnDevice() {
|
||||
scalarsDevice := scalars.(core.DeviceSlice)
|
||||
scalarsDevice.CheckDevice()
|
||||
scalarsPointer = scalarsDevice.AsPointer()
|
||||
} else {
|
||||
scalarsPointer = unsafe.Pointer(&scalars.(core.HostSlice[ScalarField])[0])
|
||||
}
|
||||
cScalars := (*C.scalar_t)(scalarsPointer)
|
||||
|
||||
var pointsPointer unsafe.Pointer
|
||||
if points.IsOnDevice() {
|
||||
pointsDevice := points.(core.DeviceSlice)
|
||||
pointsDevice.CheckDevice()
|
||||
pointsPointer = pointsDevice.AsPointer()
|
||||
} else {
|
||||
pointsPointer = unsafe.Pointer(&points.(core.HostSlice[G2Affine])[0])
|
||||
}
|
||||
cPoints := (*C.g2_affine_t)(pointsPointer)
|
||||
|
||||
var resultsPointer unsafe.Pointer
|
||||
if results.IsOnDevice() {
|
||||
resultsDevice := results.(core.DeviceSlice)
|
||||
resultsDevice.CheckDevice()
|
||||
resultsPointer = resultsDevice.AsPointer()
|
||||
} else {
|
||||
resultsPointer = unsafe.Pointer(&results.(core.HostSlice[G2Projective])[0])
|
||||
}
|
||||
cResults := (*C.g2_projective_t)(resultsPointer)
|
||||
|
||||
cSize := (C.int)(scalars.Len() / results.Len())
|
||||
cCfg := (*C.MSMConfig)(unsafe.Pointer(cfg))
|
||||
|
||||
__ret := C.bls12_381G2MSMCuda(cScalars, cPoints, cSize, cCfg, cResults)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
func G2PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c int32, ctx *cr.DeviceContext, outputBases core.DeviceSlice) cr.CudaError {
|
||||
core.PrecomputeBasesCheck(points, precomputeFactor, outputBases)
|
||||
|
||||
var pointsPointer unsafe.Pointer
|
||||
if points.IsOnDevice() {
|
||||
pointsPointer = points.(core.DeviceSlice).AsPointer()
|
||||
} else {
|
||||
pointsPointer = unsafe.Pointer(&points.(core.HostSlice[G2Affine])[0])
|
||||
}
|
||||
cPoints := (*C.g2_affine_t)(pointsPointer)
|
||||
|
||||
cPointsLen := (C.int)(points.Len())
|
||||
cPrecomputeFactor := (C.int)(precomputeFactor)
|
||||
cC := (C.int)(c)
|
||||
cPointsIsOnDevice := (C._Bool)(points.IsOnDevice())
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(ctx))
|
||||
|
||||
outputBasesPointer := outputBases.AsPointer()
|
||||
cOutputBases := (*C.g2_affine_t)(outputBasesPointer)
|
||||
|
||||
__ret := C.bls12_381G2PrecomputeMSMBases(cPoints, cPointsLen, cPrecomputeFactor, cC, cPointsIsOnDevice, cCtx, cOutputBases)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include "../../include/types.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_381_CURVE_H
|
||||
@@ -9,12 +8,16 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool bls12_381Eq(projective_t* point1, projective_t* point2);
|
||||
void bls12_381ToAffine(projective_t* point, affine_t* point_out);
|
||||
void bls12_381GenerateProjectivePoints(projective_t* points, int size);
|
||||
void bls12_381GenerateAffinePoints(affine_t* points, int size);
|
||||
cudaError_t bls12_381AffineConvertMontgomery(affine_t* points, size_t n, bool is_into, DeviceContext* ctx);
|
||||
cudaError_t bls12_381ProjectiveConvertMontgomery(projective_t* points, size_t n, bool is_into, DeviceContext* ctx);
|
||||
typedef struct projective_t projective_t;
|
||||
typedef struct affine_t affine_t;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
|
||||
bool bls12_381_eq(projective_t* point1, projective_t* point2);
|
||||
void bls12_381_to_affine(projective_t* point, affine_t* point_out);
|
||||
void bls12_381_generate_projective_points(projective_t* points, int size);
|
||||
void bls12_381_generate_affine_points(affine_t* points, int size);
|
||||
cudaError_t bls12_381_affine_convert_montgomery(affine_t* points, size_t n, bool is_into, DeviceContext* ctx);
|
||||
cudaError_t bls12_381_projective_convert_montgomery(projective_t* points, size_t n, bool is_into, DeviceContext* ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include "../../include/types.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_381_G2CURVE_H
|
||||
#define _BLS12_381_G2CURVE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool bls12_381G2Eq(g2_projective_t* point1, g2_projective_t* point2);
|
||||
void bls12_381G2ToAffine(g2_projective_t* point, g2_affine_t* point_out);
|
||||
void bls12_381G2GenerateProjectivePoints(g2_projective_t* points, int size);
|
||||
void bls12_381G2GenerateAffinePoints(g2_affine_t* points, int size);
|
||||
cudaError_t bls12_381G2AffineConvertMontgomery(g2_affine_t* points, size_t n, bool is_into, DeviceContext* ctx);
|
||||
cudaError_t bls12_381G2ProjectiveConvertMontgomery(g2_projective_t* points, size_t n, bool is_into, DeviceContext* ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,19 +0,0 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include "../../include/types.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_381_G2MSM_H
|
||||
#define _BLS12_381_G2MSM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
cudaError_t bls12_381G2MSMCuda(const scalar_t* scalars,const g2_affine_t* points, int count, MSMConfig* config, g2_projective_t* out);
|
||||
cudaError_t bls12_381G2PrecomputeMSMBases(g2_affine_t* points, int count, int precompute_factor, int _c, bool bases_on_device, DeviceContext* ctx, g2_affine_t* out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,19 +0,0 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include "../../include/types.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_381_MSM_H
|
||||
#define _BLS12_381_MSM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
cudaError_t bls12_381MSMCuda(const scalar_t* scalars, const affine_t* points, int count, MSMConfig* config, projective_t* out);
|
||||
cudaError_t bls12_381PrecomputeMSMBases(affine_t* points, int bases_size, int precompute_factor, int _c, bool are_bases_on_device, DeviceContext* ctx, affine_t* output_bases);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,21 +0,0 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include "../../include/types.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_381_NTT_H
|
||||
#define _BLS12_381_NTT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
cudaError_t bls12_381NTTCuda(const scalar_t* input, int size, int dir, NTTConfig* config, scalar_t* output);
|
||||
cudaError_t bls12_381ECNTTCuda(const projective_t* input, int size, int dir, NTTConfig* config, projective_t* output);
|
||||
cudaError_t bls12_381InitializeDomain(scalar_t* primitive_root, DeviceContext* ctx, bool fast_twiddles);
|
||||
cudaError_t bls12_381ReleaseDomain(DeviceContext* ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,4 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include "../../include/types.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_381_FIELD_H
|
||||
@@ -9,8 +8,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void bls12_381GenerateScalars(scalar_t* scalars, int size);
|
||||
cudaError_t bls12_381ScalarConvertMontgomery(scalar_t* d_inout, size_t n, bool is_into, DeviceContext* ctx);
|
||||
typedef struct scalar_t scalar_t;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
|
||||
void bls12_381_generate_scalars(scalar_t* scalars, int size);
|
||||
cudaError_t bls12_381_scalar_convert_montgomery(scalar_t* d_inout, size_t n, bool is_into, DeviceContext* ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
4
wrappers/golang/curves/bls12381/main.go
Normal file
4
wrappers/golang/curves/bls12381/main.go
Normal file
@@ -0,0 +1,4 @@
|
||||
package bls12381
|
||||
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/../../../../icicle/build/lib -lingo_curve_bls12_381 -lingo_field_bls12_381 -lstdc++ -lm
|
||||
import "C"
|
||||
@@ -1,80 +0,0 @@
|
||||
package bls12381
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "msm.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func GetDefaultMSMConfig() core.MSMConfig {
|
||||
return core.GetDefaultMSMConfig()
|
||||
}
|
||||
|
||||
func Msm(scalars core.HostOrDeviceSlice, points core.HostOrDeviceSlice, cfg *core.MSMConfig, results core.HostOrDeviceSlice) cr.CudaError {
|
||||
core.MsmCheck(scalars, points, cfg, results)
|
||||
var scalarsPointer unsafe.Pointer
|
||||
if scalars.IsOnDevice() {
|
||||
scalarsDevice := scalars.(core.DeviceSlice)
|
||||
scalarsDevice.CheckDevice()
|
||||
scalarsPointer = scalarsDevice.AsPointer()
|
||||
} else {
|
||||
scalarsPointer = unsafe.Pointer(&scalars.(core.HostSlice[ScalarField])[0])
|
||||
}
|
||||
cScalars := (*C.scalar_t)(scalarsPointer)
|
||||
|
||||
var pointsPointer unsafe.Pointer
|
||||
if points.IsOnDevice() {
|
||||
pointsDevice := points.(core.DeviceSlice)
|
||||
pointsDevice.CheckDevice()
|
||||
pointsPointer = pointsDevice.AsPointer()
|
||||
} else {
|
||||
pointsPointer = unsafe.Pointer(&points.(core.HostSlice[Affine])[0])
|
||||
}
|
||||
cPoints := (*C.affine_t)(pointsPointer)
|
||||
|
||||
var resultsPointer unsafe.Pointer
|
||||
if results.IsOnDevice() {
|
||||
resultsDevice := results.(core.DeviceSlice)
|
||||
resultsDevice.CheckDevice()
|
||||
resultsPointer = resultsDevice.AsPointer()
|
||||
} else {
|
||||
resultsPointer = unsafe.Pointer(&results.(core.HostSlice[Projective])[0])
|
||||
}
|
||||
cResults := (*C.projective_t)(resultsPointer)
|
||||
|
||||
cSize := (C.int)(scalars.Len() / results.Len())
|
||||
cCfg := (*C.MSMConfig)(unsafe.Pointer(cfg))
|
||||
|
||||
__ret := C.bls12_381MSMCuda(cScalars, cPoints, cSize, cCfg, cResults)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
func PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c int32, ctx *cr.DeviceContext, outputBases core.DeviceSlice) cr.CudaError {
|
||||
core.PrecomputeBasesCheck(points, precomputeFactor, outputBases)
|
||||
|
||||
var pointsPointer unsafe.Pointer
|
||||
if points.IsOnDevice() {
|
||||
pointsPointer = points.(core.DeviceSlice).AsPointer()
|
||||
} else {
|
||||
pointsPointer = unsafe.Pointer(&points.(core.HostSlice[Affine])[0])
|
||||
}
|
||||
cPoints := (*C.affine_t)(pointsPointer)
|
||||
|
||||
cPointsLen := (C.int)(points.Len())
|
||||
cPrecomputeFactor := (C.int)(precomputeFactor)
|
||||
cC := (C.int)(c)
|
||||
cPointsIsOnDevice := (C._Bool)(points.IsOnDevice())
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(ctx))
|
||||
|
||||
outputBasesPointer := outputBases.AsPointer()
|
||||
cOutputBases := (*C.affine_t)(outputBasesPointer)
|
||||
|
||||
__ret := C.bls12_381PrecomputeMSMBases(cPoints, cPointsLen, cPrecomputeFactor, cC, cPointsIsOnDevice, cCtx, cOutputBases)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
24
wrappers/golang/curves/bls12381/msm/include/msm.h
Normal file
24
wrappers/golang/curves/bls12381/msm/include/msm.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_381_MSM_H
|
||||
#define _BLS12_381_MSM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct scalar_t scalar_t;
|
||||
typedef struct projective_t projective_t;
|
||||
typedef struct affine_t affine_t;
|
||||
typedef struct MSMConfig MSMConfig;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
|
||||
cudaError_t bls12_381_msm_cuda(const scalar_t* scalars,const affine_t* points, int count, MSMConfig* config, projective_t* out);
|
||||
cudaError_t bls12_381_precompute_msm_bases_cuda(affine_t* points, int count, int precompute_factor, int _c, bool bases_on_device, DeviceContext* ctx, affine_t* out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
45
wrappers/golang/curves/bls12381/msm/msm.go
Normal file
45
wrappers/golang/curves/bls12381/msm/msm.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package msm
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "msm.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func GetDefaultMSMConfig() core.MSMConfig {
|
||||
return core.GetDefaultMSMConfig()
|
||||
}
|
||||
|
||||
func Msm(scalars core.HostOrDeviceSlice, points core.HostOrDeviceSlice, cfg *core.MSMConfig, results core.HostOrDeviceSlice) cr.CudaError {
|
||||
scalarsPointer, pointsPointer, resultsPointer, size, cfgPointer := core.MsmCheck(scalars, points, cfg, results)
|
||||
|
||||
cScalars := (*C.scalar_t)(scalarsPointer)
|
||||
cPoints := (*C.affine_t)(pointsPointer)
|
||||
cResults := (*C.projective_t)(resultsPointer)
|
||||
cSize := (C.int)(size)
|
||||
cCfg := (*C.MSMConfig)(cfgPointer)
|
||||
|
||||
__ret := C.bls12_381_msm_cuda(cScalars, cPoints, cSize, cCfg, cResults)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
func PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c int32, ctx *cr.DeviceContext, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputeBasesCheck(points, precomputeFactor, outputBases)
|
||||
|
||||
cPoints := (*C.affine_t)(pointsPointer)
|
||||
cPointsLen := (C.int)(points.Len())
|
||||
cPrecomputeFactor := (C.int)(precomputeFactor)
|
||||
cC := (C.int)(c)
|
||||
cPointsIsOnDevice := (C._Bool)(points.IsOnDevice())
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(ctx))
|
||||
cOutputBases := (*C.affine_t)(outputBasesPointer)
|
||||
|
||||
__ret := C.bls12_381_precompute_msm_bases_cuda(cPoints, cPointsLen, cPrecomputeFactor, cC, cPointsIsOnDevice, cCtx, cOutputBases)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
package bls12381
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "ntt.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
)
|
||||
|
||||
func GetDefaultNttConfig() core.NTTConfig[[SCALAR_LIMBS]uint32] {
|
||||
cosetGenField := ScalarField{}
|
||||
cosetGenField.One()
|
||||
var cosetGen [SCALAR_LIMBS]uint32
|
||||
for i, v := range cosetGenField.GetLimbs() {
|
||||
cosetGen[i] = v
|
||||
}
|
||||
|
||||
return core.GetDefaultNTTConfig(cosetGen)
|
||||
}
|
||||
|
||||
func Ntt[T any](scalars core.HostOrDeviceSlice, dir core.NTTDir, cfg *core.NTTConfig[T], results core.HostOrDeviceSlice) core.IcicleError {
|
||||
core.NttCheck[T](scalars, cfg, results)
|
||||
|
||||
var scalarsPointer unsafe.Pointer
|
||||
if scalars.IsOnDevice() {
|
||||
scalarsDevice := scalars.(core.DeviceSlice)
|
||||
scalarsDevice.CheckDevice()
|
||||
scalarsPointer = scalarsDevice.AsPointer()
|
||||
} else {
|
||||
scalarsPointer = unsafe.Pointer(&scalars.(core.HostSlice[ScalarField])[0])
|
||||
}
|
||||
cScalars := (*C.scalar_t)(scalarsPointer)
|
||||
cSize := (C.int)(scalars.Len() / int(cfg.BatchSize))
|
||||
cDir := (C.int)(dir)
|
||||
cCfg := (*C.NTTConfig)(unsafe.Pointer(cfg))
|
||||
|
||||
var resultsPointer unsafe.Pointer
|
||||
if results.IsOnDevice() {
|
||||
resultsDevice := results.(core.DeviceSlice)
|
||||
resultsDevice.CheckDevice()
|
||||
resultsPointer = resultsDevice.AsPointer()
|
||||
} else {
|
||||
resultsPointer = unsafe.Pointer(&results.(core.HostSlice[ScalarField])[0])
|
||||
}
|
||||
cResults := (*C.scalar_t)(resultsPointer)
|
||||
|
||||
__ret := C.bls12_381NTTCuda(cScalars, cSize, cDir, cCfg, cResults)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func ECNtt[T any](points core.HostOrDeviceSlice, dir core.NTTDir, cfg *core.NTTConfig[T], results core.HostOrDeviceSlice) core.IcicleError {
|
||||
core.NttCheck[T](points, cfg, results)
|
||||
|
||||
var pointsPointer unsafe.Pointer
|
||||
if points.IsOnDevice() {
|
||||
pointsPointer = points.(core.DeviceSlice).AsPointer()
|
||||
} else {
|
||||
pointsPointer = unsafe.Pointer(&points.(core.HostSlice[Projective])[0])
|
||||
}
|
||||
cPoints := (*C.projective_t)(pointsPointer)
|
||||
cSize := (C.int)(points.Len() / int(cfg.BatchSize))
|
||||
cDir := (C.int)(dir)
|
||||
cCfg := (*C.NTTConfig)(unsafe.Pointer(cfg))
|
||||
|
||||
var resultsPointer unsafe.Pointer
|
||||
if results.IsOnDevice() {
|
||||
resultsPointer = results.(core.DeviceSlice).AsPointer()
|
||||
} else {
|
||||
resultsPointer = unsafe.Pointer(&results.(core.HostSlice[Projective])[0])
|
||||
}
|
||||
cResults := (*C.projective_t)(resultsPointer)
|
||||
|
||||
__ret := C.bls12_381ECNTTCuda(cPoints, cSize, cDir, cCfg, cResults)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func InitDomain(primitiveRoot ScalarField, ctx cr.DeviceContext, fastTwiddles bool) core.IcicleError {
|
||||
cPrimitiveRoot := (*C.scalar_t)(unsafe.Pointer(primitiveRoot.AsPointer()))
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
cFastTwiddles := (C._Bool)(fastTwiddles)
|
||||
__ret := C.bls12_381InitializeDomain(cPrimitiveRoot, cCtx, cFastTwiddles)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func ReleaseDomain(ctx cr.DeviceContext) core.IcicleError {
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
__ret := C.bls12_381ReleaseDomain(cCtx)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
23
wrappers/golang/curves/bls12381/ntt/include/ntt.h
Normal file
23
wrappers/golang/curves/bls12381/ntt/include/ntt.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_381_NTT_H
|
||||
#define _BLS12_381_NTT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct scalar_t scalar_t;
|
||||
typedef struct NTTConfig NTTConfig;
|
||||
typedef struct DeviceContext DeviceContext;
|
||||
|
||||
cudaError_t bls12_381_ntt_cuda(const scalar_t* input, int size, int dir, NTTConfig* config, scalar_t* output);
|
||||
cudaError_t bls12_381_initialize_domain(scalar_t* primitive_root, DeviceContext* ctx, bool fast_twiddles);
|
||||
cudaError_t bls12_381_release_domain(DeviceContext* ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
56
wrappers/golang/curves/bls12381/ntt/ntt.go
Normal file
56
wrappers/golang/curves/bls12381/ntt/ntt.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package ntt
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "ntt.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
bls12_381 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381"
|
||||
)
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func Ntt[T any](scalars core.HostOrDeviceSlice, dir core.NTTDir, cfg *core.NTTConfig[T], results core.HostOrDeviceSlice) core.IcicleError {
|
||||
scalarsPointer, resultsPointer, size, cfgPointer := core.NttCheck[T](scalars, cfg, results)
|
||||
|
||||
cScalars := (*C.scalar_t)(scalarsPointer)
|
||||
cSize := (C.int)(size)
|
||||
cDir := (C.int)(dir)
|
||||
cCfg := (*C.NTTConfig)(cfgPointer)
|
||||
cResults := (*C.scalar_t)(resultsPointer)
|
||||
|
||||
__ret := C.bls12_381_ntt_cuda(cScalars, cSize, cDir, cCfg, cResults)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func GetDefaultNttConfig() core.NTTConfig[[bls12_381.SCALAR_LIMBS]uint32] {
|
||||
cosetGenField := bls12_381.ScalarField{}
|
||||
cosetGenField.One()
|
||||
var cosetGen [bls12_381.SCALAR_LIMBS]uint32
|
||||
for i, v := range cosetGenField.GetLimbs() {
|
||||
cosetGen[i] = v
|
||||
}
|
||||
|
||||
return core.GetDefaultNTTConfig(cosetGen)
|
||||
}
|
||||
|
||||
func InitDomain(primitiveRoot bls12_381.ScalarField, ctx cr.DeviceContext, fastTwiddles bool) core.IcicleError {
|
||||
cPrimitiveRoot := (*C.scalar_t)(unsafe.Pointer(primitiveRoot.AsPointer()))
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
cFastTwiddles := (C._Bool)(fastTwiddles)
|
||||
__ret := C.bls12_381_initialize_domain(cPrimitiveRoot, cCtx, cFastTwiddles)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
|
||||
func ReleaseDomain(ctx cr.DeviceContext) core.IcicleError {
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&ctx))
|
||||
__ret := C.bls12_381_release_domain(cCtx)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return core.FromCudaError(err)
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _BLS12_381_POLY_H
|
||||
#define _BLS12_381_POLY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct scalar_t scalar_t;
|
||||
typedef struct PolynomialInst PolynomialInst;
|
||||
typedef struct IntegrityPointer IntegrityPointer;
|
||||
|
||||
bool bls12_381_polynomial_init_cuda_backend();
|
||||
PolynomialInst* bls12_381_polynomial_create_from_coefficients(scalar_t* coeffs, size_t size);
|
||||
PolynomialInst* bls12_381_polynomial_create_from_rou_evaluations(scalar_t* evals, size_t size);
|
||||
PolynomialInst* bls12_381_polynomial_clone(const PolynomialInst* p);
|
||||
void bls12_381_polynomial_print(PolynomialInst* p);
|
||||
void bls12_381_polynomial_delete(PolynomialInst* instance);
|
||||
PolynomialInst* bls12_381_polynomial_add(const PolynomialInst* a, const PolynomialInst* b);
|
||||
void bls12_381_polynomial_add_inplace(PolynomialInst* a, const PolynomialInst* b);
|
||||
PolynomialInst* bls12_381_polynomial_subtract(const PolynomialInst* a, const PolynomialInst* b);
|
||||
PolynomialInst* bls12_381_polynomial_multiply(const PolynomialInst* a, const PolynomialInst* b);
|
||||
PolynomialInst* bls12_381_polynomial_multiply_by_scalar(const PolynomialInst* a, const scalar_t* scalar);
|
||||
void bls12_381_polynomial_division(const PolynomialInst* a, const PolynomialInst* b, PolynomialInst** q /*OUT*/, PolynomialInst** r /*OUT*/);
|
||||
PolynomialInst* bls12_381_polynomial_quotient(const PolynomialInst* a, const PolynomialInst* b);
|
||||
PolynomialInst* bls12_381_polynomial_remainder(const PolynomialInst* a, const PolynomialInst* b);
|
||||
PolynomialInst* bls12_381_polynomial_divide_by_vanishing(const PolynomialInst* p, size_t vanishing_poly_degree);
|
||||
void bls12_381_polynomial_add_monomial_inplace(PolynomialInst* p, const scalar_t* monomial_coeff, size_t monomial);
|
||||
void bls12_381_polynomial_sub_monomial_inplace(PolynomialInst* p, const scalar_t* monomial_coeff, size_t monomial);
|
||||
void bls12_381_polynomial_evaluate_on_domain(const PolynomialInst* p, scalar_t* domain, size_t domain_size, scalar_t* evals /*OUT*/);
|
||||
size_t bls12_381_polynomial_degree(PolynomialInst* p);
|
||||
size_t bls12_381_polynomial_copy_coeffs_range(PolynomialInst* p, scalar_t* memory, size_t start_idx, size_t end_idx);
|
||||
PolynomialInst* bls12_381_polynomial_even(PolynomialInst* p);
|
||||
PolynomialInst* bls12_381_polynomial_odd(PolynomialInst* p);
|
||||
|
||||
// scalar_t* bls12_381_polynomial_get_coeffs_raw_ptr(PolynomialInst* p, size_t* size /*OUT*/, size_t* device_id /*OUT*/);
|
||||
// PolynomialInst* bls12_381_polynomial_slice(PolynomialInst* p, size_t offset, size_t stride, size_t size);
|
||||
// IntegrityPointer* bls12_381_polynomial_get_coeff_view(PolynomialInst* p, size_t* size /*OUT*/, size_t* device_id /*OUT*/);
|
||||
// IntegrityPointer* bls12_381_polynomial_get_rou_evaluations_view(PolynomialInst* p, size_t nof_evals, bool is_reversed, size_t* size /*OUT*/, size_t* device_id /*OUT*/);
|
||||
// const scalar_t* bls12_381_polynomial_intergrity_ptr_get(IntegrityPointer* p);
|
||||
// bool bls12_381_polynomial_intergrity_ptr_is_valid(IntegrityPointer* p);
|
||||
// void bls12_381_polynomial_intergrity_ptr_destroy(IntegrityPointer* p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
176
wrappers/golang/curves/bls12381/polynomial/polynomial.go
Normal file
176
wrappers/golang/curves/bls12381/polynomial/polynomial.go
Normal file
@@ -0,0 +1,176 @@
|
||||
package polynomial
|
||||
|
||||
// #cgo CFLAGS: -I./include/
|
||||
// #include "polynomial.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
bls12_381 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381"
|
||||
)
|
||||
|
||||
type PolynomialHandle = C.struct_PolynomialInst
|
||||
|
||||
type DensePolynomial struct {
|
||||
handle *PolynomialHandle
|
||||
}
|
||||
|
||||
func InitPolyBackend() bool {
|
||||
return (bool)(C.bls12_381_polynomial_init_cuda_backend())
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Print() {
|
||||
C.bls12_381_polynomial_print(up.handle)
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) CreateFromCoeffecitients(coeffs core.HostOrDeviceSlice) DensePolynomial {
|
||||
if coeffs.IsOnDevice() {
|
||||
coeffs.(core.DeviceSlice).CheckDevice()
|
||||
}
|
||||
coeffsPointer := (*C.scalar_t)(coeffs.AsUnsafePointer())
|
||||
cSize := (C.size_t)(coeffs.Len())
|
||||
up.handle = C.bls12_381_polynomial_create_from_coefficients(coeffsPointer, cSize)
|
||||
return *up
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) CreateFromROUEvaluations(evals core.HostOrDeviceSlice) DensePolynomial {
|
||||
evalsPointer := (*C.scalar_t)(evals.AsUnsafePointer())
|
||||
cSize := (C.size_t)(evals.Len())
|
||||
up.handle = C.bls12_381_polynomial_create_from_coefficients(evalsPointer, cSize)
|
||||
return *up
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Clone() DensePolynomial {
|
||||
return DensePolynomial{
|
||||
handle: C.bls12_381_polynomial_clone(up.handle),
|
||||
}
|
||||
}
|
||||
|
||||
// TODO @jeremyfelder: Maybe this should be in a SetFinalizer that is set on Create functions?
|
||||
func (up *DensePolynomial) Delete() {
|
||||
C.bls12_381_polynomial_delete(up.handle)
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Add(b *DensePolynomial) DensePolynomial {
|
||||
return DensePolynomial{
|
||||
handle: C.bls12_381_polynomial_add(up.handle, b.handle),
|
||||
}
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) AddInplace(b *DensePolynomial) {
|
||||
C.bls12_381_polynomial_add_inplace(up.handle, b.handle)
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Subtract(b *DensePolynomial) DensePolynomial {
|
||||
return DensePolynomial{
|
||||
handle: C.bls12_381_polynomial_subtract(up.handle, b.handle),
|
||||
}
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Multiply(b *DensePolynomial) DensePolynomial {
|
||||
return DensePolynomial{
|
||||
handle: C.bls12_381_polynomial_multiply(up.handle, b.handle),
|
||||
}
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) MultiplyByScalar(scalar bls12_381.ScalarField) DensePolynomial {
|
||||
cScalar := (*C.scalar_t)(unsafe.Pointer(scalar.AsPointer()))
|
||||
return DensePolynomial{
|
||||
handle: C.bls12_381_polynomial_multiply_by_scalar(up.handle, cScalar),
|
||||
}
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Divide(b *DensePolynomial) (DensePolynomial, DensePolynomial) {
|
||||
var q, r *PolynomialHandle
|
||||
C.bls12_381_polynomial_division(up.handle, b.handle, &q, &r)
|
||||
return DensePolynomial{
|
||||
handle: q,
|
||||
}, DensePolynomial{
|
||||
handle: r,
|
||||
}
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Quotient(b *DensePolynomial) DensePolynomial {
|
||||
return DensePolynomial{
|
||||
handle: C.bls12_381_polynomial_quotient(up.handle, b.handle),
|
||||
}
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Remainder(b *DensePolynomial) DensePolynomial {
|
||||
return DensePolynomial{
|
||||
handle: C.bls12_381_polynomial_remainder(up.handle, b.handle),
|
||||
}
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) DivideByVanishing(vanishing_degree uint64) DensePolynomial {
|
||||
cVanishingDegree := (C.ulong)(vanishing_degree)
|
||||
return DensePolynomial{
|
||||
handle: C.bls12_381_polynomial_divide_by_vanishing(up.handle, cVanishingDegree),
|
||||
}
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) AddMonomial(monomialCoeff bls12_381.ScalarField, monomial uint64) DensePolynomial {
|
||||
hs := core.HostSliceFromElements([]bls12_381.ScalarField{monomialCoeff})
|
||||
cMonomialCoeff := (*C.scalar_t)(hs.AsUnsafePointer())
|
||||
cMonomial := (C.ulong)(monomial)
|
||||
C.bls12_381_polynomial_add_monomial_inplace(up.handle, cMonomialCoeff, cMonomial)
|
||||
return *up
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) SubMonomial(monomialCoeff bls12_381.ScalarField, monomial uint64) DensePolynomial {
|
||||
hs := core.HostSliceFromElements([]bls12_381.ScalarField{monomialCoeff})
|
||||
cMonomialCoeff := (*C.scalar_t)(hs.AsUnsafePointer())
|
||||
cMonomial := (C.ulong)(monomial)
|
||||
C.bls12_381_polynomial_sub_monomial_inplace(up.handle, cMonomialCoeff, cMonomial)
|
||||
return *up
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Eval(x bls12_381.ScalarField) bls12_381.ScalarField {
|
||||
domains := make(core.HostSlice[bls12_381.ScalarField], 1)
|
||||
domains[0] = x
|
||||
evals := make(core.HostSlice[bls12_381.ScalarField], 1)
|
||||
up.EvalOnDomain(domains, evals)
|
||||
return evals[0]
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) EvalOnDomain(domain, evals core.HostOrDeviceSlice) core.HostOrDeviceSlice {
|
||||
cDomain := (*C.scalar_t)(domain.AsUnsafePointer())
|
||||
cDomainSize := (C.size_t)(domain.Len())
|
||||
cEvals := (*C.scalar_t)(evals.AsUnsafePointer())
|
||||
C.bls12_381_polynomial_evaluate_on_domain(up.handle, cDomain, cDomainSize, cEvals)
|
||||
return evals
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Degree() int {
|
||||
return int(C.bls12_381_polynomial_degree(up.handle))
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) CopyCoeffsRange(start, end int, out core.HostOrDeviceSlice) (int, core.HostOrDeviceSlice) {
|
||||
cStart := (C.size_t)(start)
|
||||
cEnd := (C.size_t)(end)
|
||||
cScalarOut := (*C.scalar_t)(out.AsUnsafePointer())
|
||||
__cNumCoeffsRead := C.bls12_381_polynomial_copy_coeffs_range(up.handle, cScalarOut, cStart, cEnd)
|
||||
return int(__cNumCoeffsRead), out
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) GetCoeff(idx int) bls12_381.ScalarField {
|
||||
out := make(core.HostSlice[bls12_381.ScalarField], 1)
|
||||
up.CopyCoeffsRange(idx, idx, out)
|
||||
return out[0]
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Even() DensePolynomial {
|
||||
evenPoly := C.bls12_381_polynomial_even(up.handle)
|
||||
return DensePolynomial{
|
||||
handle: evenPoly,
|
||||
}
|
||||
}
|
||||
|
||||
func (up *DensePolynomial) Odd() DensePolynomial {
|
||||
oddPoly := C.bls12_381_polynomial_odd(up.handle)
|
||||
return DensePolynomial{
|
||||
handle: oddPoly,
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
SCALAR_LIMBS int8 = 8
|
||||
SCALAR_LIMBS int = 8
|
||||
)
|
||||
|
||||
type ScalarField struct {
|
||||
@@ -35,6 +35,11 @@ func (f ScalarField) AsPointer() *uint32 {
|
||||
return &f.limbs[0]
|
||||
}
|
||||
|
||||
func (f *ScalarField) FromUint32(v uint32) ScalarField {
|
||||
f.limbs[0] = v
|
||||
return *f
|
||||
}
|
||||
|
||||
func (f *ScalarField) FromLimbs(limbs []uint32) ScalarField {
|
||||
if len(limbs) != f.Len() {
|
||||
panic("Called FromLimbs with limbs of different length than field")
|
||||
@@ -89,18 +94,18 @@ func GenerateScalars(size int) core.HostSlice[ScalarField] {
|
||||
|
||||
cScalars := (*C.scalar_t)(unsafe.Pointer(&scalarSlice[0]))
|
||||
cSize := (C.int)(size)
|
||||
C.bls12_381GenerateScalars(cScalars, cSize)
|
||||
C.bls12_381_generate_scalars(cScalars, cSize)
|
||||
|
||||
return scalarSlice
|
||||
}
|
||||
|
||||
func convertScalarsMontgomery(scalars *core.DeviceSlice, isInto bool) cr.CudaError {
|
||||
cValues := (*C.scalar_t)(scalars.AsPointer())
|
||||
cValues := (*C.scalar_t)(scalars.AsUnsafePointer())
|
||||
cSize := (C.size_t)(scalars.Len())
|
||||
cIsInto := (C._Bool)(isInto)
|
||||
defaultCtx, _ := cr.GetDefaultDeviceContext()
|
||||
cCtx := (*C.DeviceContext)(unsafe.Pointer(&defaultCtx))
|
||||
__ret := C.bls12_381ScalarConvertMontgomery(cValues, cSize, cIsInto, cCtx)
|
||||
__ret := C.bls12_381_scalar_convert_montgomery(cValues, cSize, cIsInto, cCtx)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
88
wrappers/golang/curves/bls12381/tests/base_field_test.go
Normal file
88
wrappers/golang/curves/bls12381/tests/base_field_test.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
bls12_381 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
BASE_LIMBS = bls12_381.BASE_LIMBS
|
||||
)
|
||||
|
||||
func TestBaseFieldFromLimbs(t *testing.T) {
|
||||
emptyField := bls12_381.BaseField{}
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
assert.ElementsMatch(t, randLimbs, emptyField.GetLimbs(), "Limbs do not match; there was an issue with setting the BaseField's limbs")
|
||||
randLimbs[0] = 100
|
||||
assert.NotEqual(t, randLimbs, emptyField.GetLimbs())
|
||||
}
|
||||
|
||||
func TestBaseFieldGetLimbs(t *testing.T) {
|
||||
emptyField := bls12_381.BaseField{}
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.ElementsMatch(t, randLimbs, emptyField.GetLimbs(), "Limbs do not match; there was an issue with setting the BaseField's limbs")
|
||||
}
|
||||
|
||||
func TestBaseFieldOne(t *testing.T) {
|
||||
var emptyField bls12_381.BaseField
|
||||
emptyField.One()
|
||||
limbOne := test_helpers.GenerateLimbOne(int(BASE_LIMBS))
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbOne, "Empty field to field one did not work")
|
||||
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
emptyField.One()
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbOne, "BaseField with limbs to field one did not work")
|
||||
}
|
||||
|
||||
func TestBaseFieldZero(t *testing.T) {
|
||||
var emptyField bls12_381.BaseField
|
||||
emptyField.Zero()
|
||||
limbsZero := make([]uint32, BASE_LIMBS)
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbsZero, "Empty field to field zero failed")
|
||||
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
emptyField.Zero()
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbsZero, "BaseField with limbs to field zero failed")
|
||||
}
|
||||
|
||||
func TestBaseFieldSize(t *testing.T) {
|
||||
var emptyField bls12_381.BaseField
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.Equal(t, len(randLimbs)*4, emptyField.Size(), "Size returned an incorrect value of bytes")
|
||||
}
|
||||
|
||||
func TestBaseFieldAsPointer(t *testing.T) {
|
||||
var emptyField bls12_381.BaseField
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.Equal(t, randLimbs[0], *emptyField.AsPointer(), "AsPointer returned pointer to incorrect value")
|
||||
}
|
||||
|
||||
func TestBaseFieldFromBytes(t *testing.T) {
|
||||
var emptyField bls12_381.BaseField
|
||||
bytes, expected := test_helpers.GenerateBytesArray(int(BASE_LIMBS))
|
||||
|
||||
emptyField.FromBytesLittleEndian(bytes)
|
||||
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), expected, "FromBytes returned incorrect values")
|
||||
}
|
||||
|
||||
func TestBaseFieldToBytes(t *testing.T) {
|
||||
var emptyField bls12_381.BaseField
|
||||
expected, limbs := test_helpers.GenerateBytesArray(int(BASE_LIMBS))
|
||||
emptyField.FromLimbs(limbs)
|
||||
|
||||
assert.ElementsMatch(t, emptyField.ToBytesLittleEndian(), expected, "ToBytes returned incorrect values")
|
||||
}
|
||||
103
wrappers/golang/curves/bls12381/tests/curve_test.go
Normal file
103
wrappers/golang/curves/bls12381/tests/curve_test.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
bls12_381 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAffineZero(t *testing.T) {
|
||||
var fieldZero = bls12_381.BaseField{}
|
||||
|
||||
var affineZero bls12_381.Affine
|
||||
assert.Equal(t, affineZero.X, fieldZero)
|
||||
assert.Equal(t, affineZero.Y, fieldZero)
|
||||
|
||||
x := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
y := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
var affine bls12_381.Affine
|
||||
affine.FromLimbs(x, y)
|
||||
|
||||
affine.Zero()
|
||||
assert.Equal(t, affine.X, fieldZero)
|
||||
assert.Equal(t, affine.Y, fieldZero)
|
||||
}
|
||||
|
||||
func TestAffineFromLimbs(t *testing.T) {
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs2 := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
|
||||
var affine bls12_381.Affine
|
||||
affine.FromLimbs(randLimbs, randLimbs2)
|
||||
|
||||
assert.ElementsMatch(t, randLimbs, affine.X.GetLimbs())
|
||||
assert.ElementsMatch(t, randLimbs2, affine.Y.GetLimbs())
|
||||
}
|
||||
|
||||
func TestAffineToProjective(t *testing.T) {
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs2 := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
var fieldOne bls12_381.BaseField
|
||||
fieldOne.One()
|
||||
|
||||
var expected bls12_381.Projective
|
||||
expected.FromLimbs(randLimbs, randLimbs2, fieldOne.GetLimbs()[:])
|
||||
|
||||
var affine bls12_381.Affine
|
||||
affine.FromLimbs(randLimbs, randLimbs2)
|
||||
|
||||
projectivePoint := affine.ToProjective()
|
||||
assert.Equal(t, expected, projectivePoint)
|
||||
}
|
||||
|
||||
func TestProjectiveZero(t *testing.T) {
|
||||
var projectiveZero bls12_381.Projective
|
||||
projectiveZero.Zero()
|
||||
var fieldZero = bls12_381.BaseField{}
|
||||
var fieldOne bls12_381.BaseField
|
||||
fieldOne.One()
|
||||
|
||||
assert.Equal(t, projectiveZero.X, fieldZero)
|
||||
assert.Equal(t, projectiveZero.Y, fieldOne)
|
||||
assert.Equal(t, projectiveZero.Z, fieldZero)
|
||||
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
var projective bls12_381.Projective
|
||||
projective.FromLimbs(randLimbs, randLimbs, randLimbs)
|
||||
|
||||
projective.Zero()
|
||||
assert.Equal(t, projective.X, fieldZero)
|
||||
assert.Equal(t, projective.Y, fieldOne)
|
||||
assert.Equal(t, projective.Z, fieldZero)
|
||||
}
|
||||
|
||||
func TestProjectiveFromLimbs(t *testing.T) {
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs2 := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs3 := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
|
||||
var projective bls12_381.Projective
|
||||
projective.FromLimbs(randLimbs, randLimbs2, randLimbs3)
|
||||
|
||||
assert.ElementsMatch(t, randLimbs, projective.X.GetLimbs())
|
||||
assert.ElementsMatch(t, randLimbs2, projective.Y.GetLimbs())
|
||||
assert.ElementsMatch(t, randLimbs3, projective.Z.GetLimbs())
|
||||
}
|
||||
|
||||
func TestProjectiveFromAffine(t *testing.T) {
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
randLimbs2 := test_helpers.GenerateRandomLimb(int(BASE_LIMBS))
|
||||
var fieldOne bls12_381.BaseField
|
||||
fieldOne.One()
|
||||
|
||||
var expected bls12_381.Projective
|
||||
expected.FromLimbs(randLimbs, randLimbs2, fieldOne.GetLimbs()[:])
|
||||
|
||||
var affine bls12_381.Affine
|
||||
affine.FromLimbs(randLimbs, randLimbs2)
|
||||
|
||||
var projectivePoint bls12_381.Projective
|
||||
projectivePoint.FromAffine(affine)
|
||||
assert.Equal(t, expected, projectivePoint)
|
||||
}
|
||||
30
wrappers/golang/curves/bls12381/tests/ecntt_test.go
Normal file
30
wrappers/golang/curves/bls12381/tests/ecntt_test.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
bls12_381 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381"
|
||||
ecntt "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381/ecntt"
|
||||
ntt "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381/ntt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestECNtt(t *testing.T) {
|
||||
cfg := ntt.GetDefaultNttConfig()
|
||||
points := bls12_381.GenerateProjectivePoints(1 << largestTestSize)
|
||||
|
||||
for _, size := range []int{4, 5, 6, 7, 8} {
|
||||
for _, v := range [4]core.Ordering{core.KNN, core.KNR, core.KRN, core.KRR} {
|
||||
testSize := 1 << size
|
||||
|
||||
pointsCopy := core.HostSliceFromElements[bls12_381.Projective](points[:testSize])
|
||||
cfg.Ordering = v
|
||||
cfg.NttAlgorithm = core.Radix2
|
||||
|
||||
output := make(core.HostSlice[bls12_381.Projective], testSize)
|
||||
e := ecntt.ECNtt(pointsCopy, core.KForward, &cfg, output)
|
||||
assert.Equal(t, core.IcicleErrorCode(0), e.IcicleErrorCode, "ECNtt failed")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,22 @@
|
||||
//go:build g2
|
||||
|
||||
package bls12377
|
||||
package tests
|
||||
|
||||
import (
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381/g2"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestG2AffineZero(t *testing.T) {
|
||||
var fieldZero = G2BaseField{}
|
||||
var fieldZero = g2.G2BaseField{}
|
||||
|
||||
var affineZero G2Affine
|
||||
var affineZero g2.G2Affine
|
||||
assert.Equal(t, affineZero.X, fieldZero)
|
||||
assert.Equal(t, affineZero.Y, fieldZero)
|
||||
|
||||
x := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
y := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
var affine G2Affine
|
||||
x := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
y := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
var affine g2.G2Affine
|
||||
affine.FromLimbs(x, y)
|
||||
|
||||
affine.Zero()
|
||||
@@ -25,10 +25,10 @@ func TestG2AffineZero(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestG2AffineFromLimbs(t *testing.T) {
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
randLimbs2 := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
randLimbs2 := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
|
||||
var affine G2Affine
|
||||
var affine g2.G2Affine
|
||||
affine.FromLimbs(randLimbs, randLimbs2)
|
||||
|
||||
assert.ElementsMatch(t, randLimbs, affine.X.GetLimbs())
|
||||
@@ -36,15 +36,15 @@ func TestG2AffineFromLimbs(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestG2AffineToProjective(t *testing.T) {
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
randLimbs2 := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
var fieldOne G2BaseField
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
randLimbs2 := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
var fieldOne g2.G2BaseField
|
||||
fieldOne.One()
|
||||
|
||||
var expected G2Projective
|
||||
expected.FromLimbs(randLimbs, randLimbs2, fieldOne.limbs[:])
|
||||
var expected g2.G2Projective
|
||||
expected.FromLimbs(randLimbs, randLimbs2, fieldOne.GetLimbs()[:])
|
||||
|
||||
var affine G2Affine
|
||||
var affine g2.G2Affine
|
||||
affine.FromLimbs(randLimbs, randLimbs2)
|
||||
|
||||
projectivePoint := affine.ToProjective()
|
||||
@@ -52,18 +52,18 @@ func TestG2AffineToProjective(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestG2ProjectiveZero(t *testing.T) {
|
||||
var projectiveZero G2Projective
|
||||
var projectiveZero g2.G2Projective
|
||||
projectiveZero.Zero()
|
||||
var fieldZero = G2BaseField{}
|
||||
var fieldOne G2BaseField
|
||||
var fieldZero = g2.G2BaseField{}
|
||||
var fieldOne g2.G2BaseField
|
||||
fieldOne.One()
|
||||
|
||||
assert.Equal(t, projectiveZero.X, fieldZero)
|
||||
assert.Equal(t, projectiveZero.Y, fieldOne)
|
||||
assert.Equal(t, projectiveZero.Z, fieldZero)
|
||||
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
var projective G2Projective
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
var projective g2.G2Projective
|
||||
projective.FromLimbs(randLimbs, randLimbs, randLimbs)
|
||||
|
||||
projective.Zero()
|
||||
@@ -73,11 +73,11 @@ func TestG2ProjectiveZero(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestG2ProjectiveFromLimbs(t *testing.T) {
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
randLimbs2 := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
randLimbs3 := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
randLimbs2 := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
randLimbs3 := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
|
||||
var projective G2Projective
|
||||
var projective g2.G2Projective
|
||||
projective.FromLimbs(randLimbs, randLimbs2, randLimbs3)
|
||||
|
||||
assert.ElementsMatch(t, randLimbs, projective.X.GetLimbs())
|
||||
@@ -86,18 +86,18 @@ func TestG2ProjectiveFromLimbs(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestG2ProjectiveFromAffine(t *testing.T) {
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
randLimbs2 := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
var fieldOne G2BaseField
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
randLimbs2 := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
var fieldOne g2.G2BaseField
|
||||
fieldOne.One()
|
||||
|
||||
var expected G2Projective
|
||||
expected.FromLimbs(randLimbs, randLimbs2, fieldOne.limbs[:])
|
||||
var expected g2.G2Projective
|
||||
expected.FromLimbs(randLimbs, randLimbs2, fieldOne.GetLimbs()[:])
|
||||
|
||||
var affine G2Affine
|
||||
var affine g2.G2Affine
|
||||
affine.FromLimbs(randLimbs, randLimbs2)
|
||||
|
||||
var projectivePoint G2Projective
|
||||
var projectivePoint g2.G2Projective
|
||||
projectivePoint.FromAffine(affine)
|
||||
assert.Equal(t, expected, projectivePoint)
|
||||
}
|
||||
@@ -1,36 +1,40 @@
|
||||
//go:build g2
|
||||
|
||||
package bw6761
|
||||
package tests
|
||||
|
||||
import (
|
||||
bls12_381 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381/g2"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
G2BASE_LIMBS = bls12_381.G2BASE_LIMBS
|
||||
)
|
||||
|
||||
func TestG2BaseFieldFromLimbs(t *testing.T) {
|
||||
emptyField := G2BaseField{}
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
emptyField := bls12_381.G2BaseField{}
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
assert.ElementsMatch(t, randLimbs, emptyField.limbs, "Limbs do not match; there was an issue with setting the G2BaseField's limbs")
|
||||
assert.ElementsMatch(t, randLimbs, emptyField.GetLimbs(), "Limbs do not match; there was an issue with setting the G2BaseField's limbs")
|
||||
randLimbs[0] = 100
|
||||
assert.NotEqual(t, randLimbs, emptyField.limbs)
|
||||
assert.NotEqual(t, randLimbs, emptyField.GetLimbs())
|
||||
}
|
||||
|
||||
func TestG2BaseFieldGetLimbs(t *testing.T) {
|
||||
emptyField := G2BaseField{}
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
emptyField := bls12_381.G2BaseField{}
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.ElementsMatch(t, randLimbs, emptyField.GetLimbs(), "Limbs do not match; there was an issue with setting the G2BaseField's limbs")
|
||||
}
|
||||
|
||||
func TestG2BaseFieldOne(t *testing.T) {
|
||||
var emptyField G2BaseField
|
||||
var emptyField bls12_381.G2BaseField
|
||||
emptyField.One()
|
||||
limbOne := generateLimbOne(int(G2_BASE_LIMBS))
|
||||
limbOne := test_helpers.GenerateLimbOne(int(G2BASE_LIMBS))
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbOne, "Empty field to field one did not work")
|
||||
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
emptyField.One()
|
||||
@@ -38,12 +42,12 @@ func TestG2BaseFieldOne(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestG2BaseFieldZero(t *testing.T) {
|
||||
var emptyField G2BaseField
|
||||
var emptyField bls12_381.G2BaseField
|
||||
emptyField.Zero()
|
||||
limbsZero := make([]uint32, G2_BASE_LIMBS)
|
||||
limbsZero := make([]uint32, G2BASE_LIMBS)
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbsZero, "Empty field to field zero failed")
|
||||
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
emptyField.Zero()
|
||||
@@ -51,24 +55,24 @@ func TestG2BaseFieldZero(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestG2BaseFieldSize(t *testing.T) {
|
||||
var emptyField G2BaseField
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
var emptyField bls12_381.G2BaseField
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.Equal(t, len(randLimbs)*4, emptyField.Size(), "Size returned an incorrect value of bytes")
|
||||
}
|
||||
|
||||
func TestG2BaseFieldAsPointer(t *testing.T) {
|
||||
var emptyField G2BaseField
|
||||
randLimbs := generateRandomLimb(int(G2_BASE_LIMBS))
|
||||
var emptyField bls12_381.G2BaseField
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(G2BASE_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.Equal(t, randLimbs[0], *emptyField.AsPointer(), "AsPointer returned pointer to incorrect value")
|
||||
}
|
||||
|
||||
func TestG2BaseFieldFromBytes(t *testing.T) {
|
||||
var emptyField G2BaseField
|
||||
bytes, expected := generateBytesArray(int(G2_BASE_LIMBS))
|
||||
var emptyField bls12_381.G2BaseField
|
||||
bytes, expected := test_helpers.GenerateBytesArray(int(G2BASE_LIMBS))
|
||||
|
||||
emptyField.FromBytesLittleEndian(bytes)
|
||||
|
||||
@@ -76,8 +80,8 @@ func TestG2BaseFieldFromBytes(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestG2BaseFieldToBytes(t *testing.T) {
|
||||
var emptyField G2BaseField
|
||||
expected, limbs := generateBytesArray(int(G2_BASE_LIMBS))
|
||||
var emptyField bls12_381.G2BaseField
|
||||
expected, limbs := test_helpers.GenerateBytesArray(int(G2BASE_LIMBS))
|
||||
emptyField.FromLimbs(limbs)
|
||||
|
||||
assert.ElementsMatch(t, emptyField.ToBytesLittleEndian(), expected, "ToBytes returned incorrect values")
|
||||
@@ -1,6 +1,4 @@
|
||||
//go:build g2
|
||||
|
||||
package bls12381
|
||||
package tests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -9,16 +7,18 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
|
||||
"github.com/consensys/gnark-crypto/ecc"
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-381"
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-381/fp"
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-381/fr"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
icicleBls12_381 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381/g2"
|
||||
)
|
||||
|
||||
func projectiveToGnarkAffineG2(p G2Projective) bls12381.G2Affine {
|
||||
func projectiveToGnarkAffineG2(p g2.G2Projective) bls12381.G2Affine {
|
||||
pxBytes := p.X.ToBytesLittleEndian()
|
||||
pxA0, _ := fp.LittleEndian.Element((*[fp.Bytes]byte)(pxBytes[:fp.Bytes]))
|
||||
pxA1, _ := fp.LittleEndian.Element((*[fp.Bytes]byte)(pxBytes[fp.Bytes:]))
|
||||
@@ -62,7 +62,7 @@ func projectiveToGnarkAffineG2(p G2Projective) bls12381.G2Affine {
|
||||
return *g2Affine.FromJacobian(&g2Jac)
|
||||
}
|
||||
|
||||
func testAgainstGnarkCryptoMsmG2(scalars core.HostSlice[ScalarField], points core.HostSlice[G2Affine], out G2Projective) bool {
|
||||
func testAgainstGnarkCryptoMsmG2(scalars core.HostSlice[icicleBls12_381.ScalarField], points core.HostSlice[g2.G2Affine], out g2.G2Projective) bool {
|
||||
scalarsFr := make([]fr.Element, len(scalars))
|
||||
for i, v := range scalars {
|
||||
slice64, _ := fr.LittleEndian.Element((*[fr.Bytes]byte)(v.ToBytesLittleEndian()))
|
||||
@@ -73,6 +73,11 @@ func testAgainstGnarkCryptoMsmG2(scalars core.HostSlice[ScalarField], points cor
|
||||
for i, v := range points {
|
||||
pointsFp[i] = projectiveToGnarkAffineG2(v.ToProjective())
|
||||
}
|
||||
|
||||
return testAgainstGnarkCryptoMsmG2GnarkCryptoTypes(scalarsFr, pointsFp, out)
|
||||
}
|
||||
|
||||
func testAgainstGnarkCryptoMsmG2GnarkCryptoTypes(scalarsFr core.HostSlice[fr.Element], pointsFp core.HostSlice[bls12381.G2Affine], out g2.G2Projective) bool {
|
||||
var msmRes bls12381.G2Jac
|
||||
msmRes.MultiExp(pointsFp, scalarsFr, ecc.MultiExpConfig{})
|
||||
|
||||
@@ -83,54 +88,117 @@ func testAgainstGnarkCryptoMsmG2(scalars core.HostSlice[ScalarField], points cor
|
||||
return msmRes.Equal(&icicleResAsJac)
|
||||
}
|
||||
|
||||
func convertIcicleG2AffineToG2Affine(iciclePoints []g2.G2Affine) []bls12381.G2Affine {
|
||||
points := make([]bls12381.G2Affine, len(iciclePoints))
|
||||
for index, iciclePoint := range iciclePoints {
|
||||
xBytes := ([fp.Bytes * 2]byte)(iciclePoint.X.ToBytesLittleEndian())
|
||||
xA0Bytes := ([fp.Bytes]byte)(xBytes[:fp.Bytes])
|
||||
xA1Bytes := ([fp.Bytes]byte)(xBytes[fp.Bytes:])
|
||||
xA0Elem, _ := fp.LittleEndian.Element(&xA0Bytes)
|
||||
xA1Elem, _ := fp.LittleEndian.Element(&xA1Bytes)
|
||||
|
||||
yBytes := ([fp.Bytes * 2]byte)(iciclePoint.Y.ToBytesLittleEndian())
|
||||
yA0Bytes := ([fp.Bytes]byte)(yBytes[:fp.Bytes])
|
||||
yA1Bytes := ([fp.Bytes]byte)(yBytes[fp.Bytes:])
|
||||
yA0Elem, _ := fp.LittleEndian.Element(&yA0Bytes)
|
||||
yA1Elem, _ := fp.LittleEndian.Element(&yA1Bytes)
|
||||
|
||||
points[index] = bls12381.G2Affine{
|
||||
X: bls12381.E2{
|
||||
A0: xA0Elem,
|
||||
A1: xA1Elem,
|
||||
},
|
||||
Y: bls12381.E2{
|
||||
A0: yA0Elem,
|
||||
A1: yA1Elem,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return points
|
||||
}
|
||||
|
||||
func TestMSMG2(t *testing.T) {
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := g2.G2GetDefaultMSMConfig()
|
||||
cfg.IsAsync = true
|
||||
for _, power := range []int{2, 3, 4, 5, 6, 7, 8, 10, 18} {
|
||||
size := 1 << power
|
||||
|
||||
scalars := GenerateScalars(size)
|
||||
points := G2GenerateAffinePoints(size)
|
||||
scalars := icicleBls12_381.GenerateScalars(size)
|
||||
points := g2.G2GenerateAffinePoints(size)
|
||||
|
||||
stream, _ := cr.CreateStream()
|
||||
var p G2Projective
|
||||
var p g2.G2Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.MallocAsync(p.Size(), p.Size(), stream)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
cfg.Ctx.Stream = &stream
|
||||
|
||||
e = G2Msm(scalars, points, &cfg, out)
|
||||
e = g2.G2Msm(scalars, points, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[G2Projective], 1)
|
||||
outHost := make(core.HostSlice[g2.G2Projective], 1)
|
||||
outHost.CopyFromDeviceAsync(&out, stream)
|
||||
out.FreeAsync(stream)
|
||||
|
||||
cr.SynchronizeStream(&stream)
|
||||
// Check with gnark-crypto
|
||||
assert.True(t, testAgainstGnarkCryptoMsmG2(scalars, points, outHost[0]))
|
||||
|
||||
}
|
||||
}
|
||||
func TestMSMG2GnarkCryptoTypes(t *testing.T) {
|
||||
cfg := g2.G2GetDefaultMSMConfig()
|
||||
for _, power := range []int{3} {
|
||||
size := 1 << power
|
||||
|
||||
scalars := make([]fr.Element, size)
|
||||
var x fr.Element
|
||||
for i := 0; i < size; i++ {
|
||||
x.SetRandom()
|
||||
scalars[i] = x
|
||||
}
|
||||
scalarsHost := (core.HostSlice[fr.Element])(scalars)
|
||||
points := g2.G2GenerateAffinePoints(size)
|
||||
pointsGnark := convertIcicleG2AffineToG2Affine(points)
|
||||
pointsHost := (core.HostSlice[bls12381.G2Affine])(pointsGnark)
|
||||
|
||||
var p g2.G2Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.Malloc(p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
cfg.ArePointsMontgomeryForm = true
|
||||
cfg.AreScalarsMontgomeryForm = true
|
||||
|
||||
e = g2.G2Msm(scalarsHost, pointsHost, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[g2.G2Projective], 1)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
// Check with gnark-crypto
|
||||
assert.True(t, testAgainstGnarkCryptoMsmG2GnarkCryptoTypes(scalarsHost, pointsHost, outHost[0]))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMSMG2Batch(t *testing.T) {
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := g2.G2GetDefaultMSMConfig()
|
||||
for _, power := range []int{10, 16} {
|
||||
for _, batchSize := range []int{1, 3, 16} {
|
||||
size := 1 << power
|
||||
totalSize := size * batchSize
|
||||
scalars := GenerateScalars(totalSize)
|
||||
points := G2GenerateAffinePoints(totalSize)
|
||||
scalars := icicleBls12_381.GenerateScalars(totalSize)
|
||||
points := g2.G2GenerateAffinePoints(totalSize)
|
||||
|
||||
var p G2Projective
|
||||
var p g2.G2Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.Malloc(batchSize*p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
e = G2Msm(scalars, points, &cfg, out)
|
||||
e = g2.G2Msm(scalars, points, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[G2Projective], batchSize)
|
||||
outHost := make(core.HostSlice[g2.G2Projective], batchSize)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
// Check with gnark-crypto
|
||||
for i := 0; i < batchSize; i++ {
|
||||
scalarsSlice := scalars[i*size : (i+1)*size]
|
||||
@@ -143,36 +211,35 @@ func TestMSMG2Batch(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPrecomputeBaseG2(t *testing.T) {
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := g2.G2GetDefaultMSMConfig()
|
||||
const precomputeFactor = 8
|
||||
for _, power := range []int{10, 16} {
|
||||
for _, batchSize := range []int{1, 3, 16} {
|
||||
size := 1 << power
|
||||
totalSize := size * batchSize
|
||||
scalars := GenerateScalars(totalSize)
|
||||
points := G2GenerateAffinePoints(totalSize)
|
||||
scalars := icicleBls12_381.GenerateScalars(totalSize)
|
||||
points := g2.G2GenerateAffinePoints(totalSize)
|
||||
|
||||
var precomputeOut core.DeviceSlice
|
||||
_, e := precomputeOut.Malloc(points[0].Size()*points.Len()*int(precomputeFactor), points[0].Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
|
||||
e = G2PrecomputeBases(points, precomputeFactor, 0, &cfg.Ctx, precomputeOut)
|
||||
e = g2.G2PrecomputeBases(points, precomputeFactor, 0, &cfg.Ctx, precomputeOut)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "PrecomputeBases failed")
|
||||
|
||||
var p G2Projective
|
||||
var p g2.G2Projective
|
||||
var out core.DeviceSlice
|
||||
_, e = out.Malloc(batchSize*p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
|
||||
e = G2Msm(scalars, precomputeOut, &cfg, out)
|
||||
e = g2.G2Msm(scalars, precomputeOut, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[G2Projective], batchSize)
|
||||
outHost := make(core.HostSlice[g2.G2Projective], batchSize)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
precomputeOut.Free()
|
||||
|
||||
// Check with gnark-crypto
|
||||
for i := 0; i < batchSize; i++ {
|
||||
scalarsSlice := scalars[i*size : (i+1)*size]
|
||||
@@ -185,30 +252,29 @@ func TestPrecomputeBaseG2(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMSMG2SkewedDistribution(t *testing.T) {
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := g2.G2GetDefaultMSMConfig()
|
||||
for _, power := range []int{2, 3, 4, 5, 6, 7, 8, 10, 18} {
|
||||
size := 1 << power
|
||||
|
||||
scalars := GenerateScalars(size)
|
||||
scalars := icicleBls12_381.GenerateScalars(size)
|
||||
for i := size / 4; i < size; i++ {
|
||||
scalars[i].One()
|
||||
}
|
||||
points := G2GenerateAffinePoints(size)
|
||||
points := g2.G2GenerateAffinePoints(size)
|
||||
for i := 0; i < size/4; i++ {
|
||||
points[i].Zero()
|
||||
}
|
||||
|
||||
var p G2Projective
|
||||
var p g2.G2Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.Malloc(p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
e = G2Msm(scalars, points, &cfg, out)
|
||||
e = g2.G2Msm(scalars, points, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[G2Projective], 1)
|
||||
outHost := make(core.HostSlice[g2.G2Projective], 1)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
// Check with gnark-crypto
|
||||
assert.True(t, testAgainstGnarkCryptoMsmG2(scalars, points, outHost[0]))
|
||||
}
|
||||
@@ -225,23 +291,23 @@ func TestMSMG2MultiDevice(t *testing.T) {
|
||||
wg.Add(1)
|
||||
cr.RunOnDevice(i, func(args ...any) {
|
||||
defer wg.Done()
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := g2.G2GetDefaultMSMConfig()
|
||||
cfg.IsAsync = true
|
||||
for _, power := range []int{2, 3, 4, 5, 6, 7, 8, 10, 18} {
|
||||
size := 1 << power
|
||||
scalars := GenerateScalars(size)
|
||||
points := G2GenerateAffinePoints(size)
|
||||
scalars := icicleBls12_381.GenerateScalars(size)
|
||||
points := g2.G2GenerateAffinePoints(size)
|
||||
|
||||
stream, _ := cr.CreateStream()
|
||||
var p G2Projective
|
||||
var p g2.G2Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.MallocAsync(p.Size(), p.Size(), stream)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
cfg.Ctx.Stream = &stream
|
||||
|
||||
e = G2Msm(scalars, points, &cfg, out)
|
||||
e = g2.G2Msm(scalars, points, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[G2Projective], 1)
|
||||
outHost := make(core.HostSlice[g2.G2Projective], 1)
|
||||
outHost.CopyFromDeviceAsync(&out, stream)
|
||||
out.FreeAsync(stream)
|
||||
|
||||
48
wrappers/golang/curves/bls12381/tests/main_test.go
Normal file
48
wrappers/golang/curves/bls12381/tests/main_test.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
bls12_381 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381"
|
||||
ntt "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381/ntt"
|
||||
poly "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381/polynomial"
|
||||
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-381/fr/fft"
|
||||
)
|
||||
|
||||
const (
|
||||
largestTestSize = 20
|
||||
)
|
||||
|
||||
func initDomain[T any](largestTestSize int, cfg core.NTTConfig[T]) core.IcicleError {
|
||||
rouMont, _ := fft.Generator(uint64(1 << largestTestSize))
|
||||
rou := rouMont.Bits()
|
||||
rouIcicle := bls12_381.ScalarField{}
|
||||
limbs := core.ConvertUint64ArrToUint32Arr(rou[:])
|
||||
|
||||
rouIcicle.FromLimbs(limbs)
|
||||
e := ntt.InitDomain(rouIcicle, cfg.Ctx, false)
|
||||
return e
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
poly.InitPolyBackend()
|
||||
|
||||
// setup domain
|
||||
cfg := ntt.GetDefaultNttConfig()
|
||||
e := initDomain(largestTestSize, cfg)
|
||||
if e.IcicleErrorCode != core.IcicleErrorCode(0) {
|
||||
panic("initDomain failed")
|
||||
}
|
||||
|
||||
// execute tests
|
||||
os.Exit(m.Run())
|
||||
|
||||
// release domain
|
||||
e = ntt.ReleaseDomain(cfg.Ctx)
|
||||
if e.IcicleErrorCode != core.IcicleErrorCode(0) {
|
||||
panic("ReleaseDomain failed")
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package bls12381
|
||||
package tests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -7,16 +7,18 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
|
||||
"github.com/consensys/gnark-crypto/ecc"
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-381"
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-381/fp"
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-381/fr"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
icicleBls12_381 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381/msm"
|
||||
)
|
||||
|
||||
func projectiveToGnarkAffine(p Projective) bls12381.G1Affine {
|
||||
func projectiveToGnarkAffine(p icicleBls12_381.Projective) bls12381.G1Affine {
|
||||
px, _ := fp.LittleEndian.Element((*[fp.Bytes]byte)((&p.X).ToBytesLittleEndian()))
|
||||
py, _ := fp.LittleEndian.Element((*[fp.Bytes]byte)((&p.Y).ToBytesLittleEndian()))
|
||||
pz, _ := fp.LittleEndian.Element((*[fp.Bytes]byte)((&p.Z).ToBytesLittleEndian()))
|
||||
@@ -33,7 +35,7 @@ func projectiveToGnarkAffine(p Projective) bls12381.G1Affine {
|
||||
return bls12381.G1Affine{X: *x, Y: *y}
|
||||
}
|
||||
|
||||
func testAgainstGnarkCryptoMsm(scalars core.HostSlice[ScalarField], points core.HostSlice[Affine], out Projective) bool {
|
||||
func testAgainstGnarkCryptoMsm(scalars core.HostSlice[icicleBls12_381.ScalarField], points core.HostSlice[icicleBls12_381.Affine], out icicleBls12_381.Projective) bool {
|
||||
scalarsFr := make([]fr.Element, len(scalars))
|
||||
for i, v := range scalars {
|
||||
slice64, _ := fr.LittleEndian.Element((*[fr.Bytes]byte)(v.ToBytesLittleEndian()))
|
||||
@@ -44,6 +46,11 @@ func testAgainstGnarkCryptoMsm(scalars core.HostSlice[ScalarField], points core.
|
||||
for i, v := range points {
|
||||
pointsFp[i] = projectiveToGnarkAffine(v.ToProjective())
|
||||
}
|
||||
|
||||
return testAgainstGnarkCryptoMsmGnarkCryptoTypes(scalarsFr, pointsFp, out)
|
||||
}
|
||||
|
||||
func testAgainstGnarkCryptoMsmGnarkCryptoTypes(scalarsFr core.HostSlice[fr.Element], pointsFp core.HostSlice[bls12381.G1Affine], out icicleBls12_381.Projective) bool {
|
||||
var msmRes bls12381.G1Jac
|
||||
msmRes.MultiExp(pointsFp, scalarsFr, ecc.MultiExpConfig{})
|
||||
|
||||
@@ -54,54 +61,104 @@ func testAgainstGnarkCryptoMsm(scalars core.HostSlice[ScalarField], points core.
|
||||
return msmRes.Equal(&icicleResAsJac)
|
||||
}
|
||||
|
||||
func convertIcicleAffineToG1Affine(iciclePoints []icicleBls12_381.Affine) []bls12381.G1Affine {
|
||||
points := make([]bls12381.G1Affine, len(iciclePoints))
|
||||
for index, iciclePoint := range iciclePoints {
|
||||
xBytes := ([fp.Bytes]byte)(iciclePoint.X.ToBytesLittleEndian())
|
||||
fpXElem, _ := fp.LittleEndian.Element(&xBytes)
|
||||
|
||||
yBytes := ([fp.Bytes]byte)(iciclePoint.Y.ToBytesLittleEndian())
|
||||
fpYElem, _ := fp.LittleEndian.Element(&yBytes)
|
||||
points[index] = bls12381.G1Affine{
|
||||
X: fpXElem,
|
||||
Y: fpYElem,
|
||||
}
|
||||
}
|
||||
|
||||
return points
|
||||
}
|
||||
|
||||
func TestMSM(t *testing.T) {
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := msm.GetDefaultMSMConfig()
|
||||
cfg.IsAsync = true
|
||||
for _, power := range []int{2, 3, 4, 5, 6, 7, 8, 10, 18} {
|
||||
size := 1 << power
|
||||
|
||||
scalars := GenerateScalars(size)
|
||||
points := GenerateAffinePoints(size)
|
||||
scalars := icicleBls12_381.GenerateScalars(size)
|
||||
points := icicleBls12_381.GenerateAffinePoints(size)
|
||||
|
||||
stream, _ := cr.CreateStream()
|
||||
var p Projective
|
||||
var p icicleBls12_381.Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.MallocAsync(p.Size(), p.Size(), stream)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
cfg.Ctx.Stream = &stream
|
||||
|
||||
e = Msm(scalars, points, &cfg, out)
|
||||
e = msm.Msm(scalars, points, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[Projective], 1)
|
||||
outHost := make(core.HostSlice[icicleBls12_381.Projective], 1)
|
||||
outHost.CopyFromDeviceAsync(&out, stream)
|
||||
out.FreeAsync(stream)
|
||||
|
||||
cr.SynchronizeStream(&stream)
|
||||
// Check with gnark-crypto
|
||||
assert.True(t, testAgainstGnarkCryptoMsm(scalars, points, outHost[0]))
|
||||
|
||||
}
|
||||
}
|
||||
func TestMSMGnarkCryptoTypes(t *testing.T) {
|
||||
cfg := msm.GetDefaultMSMConfig()
|
||||
for _, power := range []int{3} {
|
||||
size := 1 << power
|
||||
|
||||
scalars := make([]fr.Element, size)
|
||||
var x fr.Element
|
||||
for i := 0; i < size; i++ {
|
||||
x.SetRandom()
|
||||
scalars[i] = x
|
||||
}
|
||||
scalarsHost := (core.HostSlice[fr.Element])(scalars)
|
||||
points := icicleBls12_381.GenerateAffinePoints(size)
|
||||
pointsGnark := convertIcicleAffineToG1Affine(points)
|
||||
pointsHost := (core.HostSlice[bls12381.G1Affine])(pointsGnark)
|
||||
|
||||
var p icicleBls12_381.Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.Malloc(p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
cfg.ArePointsMontgomeryForm = true
|
||||
cfg.AreScalarsMontgomeryForm = true
|
||||
|
||||
e = msm.Msm(scalarsHost, pointsHost, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[icicleBls12_381.Projective], 1)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
// Check with gnark-crypto
|
||||
assert.True(t, testAgainstGnarkCryptoMsmGnarkCryptoTypes(scalarsHost, pointsHost, outHost[0]))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMSMBatch(t *testing.T) {
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := msm.GetDefaultMSMConfig()
|
||||
for _, power := range []int{10, 16} {
|
||||
for _, batchSize := range []int{1, 3, 16} {
|
||||
size := 1 << power
|
||||
totalSize := size * batchSize
|
||||
scalars := GenerateScalars(totalSize)
|
||||
points := GenerateAffinePoints(totalSize)
|
||||
scalars := icicleBls12_381.GenerateScalars(totalSize)
|
||||
points := icicleBls12_381.GenerateAffinePoints(totalSize)
|
||||
|
||||
var p Projective
|
||||
var p icicleBls12_381.Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.Malloc(batchSize*p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
e = Msm(scalars, points, &cfg, out)
|
||||
e = msm.Msm(scalars, points, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[Projective], batchSize)
|
||||
outHost := make(core.HostSlice[icicleBls12_381.Projective], batchSize)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
// Check with gnark-crypto
|
||||
for i := 0; i < batchSize; i++ {
|
||||
scalarsSlice := scalars[i*size : (i+1)*size]
|
||||
@@ -114,36 +171,35 @@ func TestMSMBatch(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPrecomputeBase(t *testing.T) {
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := msm.GetDefaultMSMConfig()
|
||||
const precomputeFactor = 8
|
||||
for _, power := range []int{10, 16} {
|
||||
for _, batchSize := range []int{1, 3, 16} {
|
||||
size := 1 << power
|
||||
totalSize := size * batchSize
|
||||
scalars := GenerateScalars(totalSize)
|
||||
points := GenerateAffinePoints(totalSize)
|
||||
scalars := icicleBls12_381.GenerateScalars(totalSize)
|
||||
points := icicleBls12_381.GenerateAffinePoints(totalSize)
|
||||
|
||||
var precomputeOut core.DeviceSlice
|
||||
_, e := precomputeOut.Malloc(points[0].Size()*points.Len()*int(precomputeFactor), points[0].Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
|
||||
e = PrecomputeBases(points, precomputeFactor, 0, &cfg.Ctx, precomputeOut)
|
||||
e = msm.PrecomputeBases(points, precomputeFactor, 0, &cfg.Ctx, precomputeOut)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "PrecomputeBases failed")
|
||||
|
||||
var p Projective
|
||||
var p icicleBls12_381.Projective
|
||||
var out core.DeviceSlice
|
||||
_, e = out.Malloc(batchSize*p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
|
||||
e = Msm(scalars, precomputeOut, &cfg, out)
|
||||
e = msm.Msm(scalars, precomputeOut, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[Projective], batchSize)
|
||||
outHost := make(core.HostSlice[icicleBls12_381.Projective], batchSize)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
precomputeOut.Free()
|
||||
|
||||
// Check with gnark-crypto
|
||||
for i := 0; i < batchSize; i++ {
|
||||
scalarsSlice := scalars[i*size : (i+1)*size]
|
||||
@@ -156,30 +212,29 @@ func TestPrecomputeBase(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMSMSkewedDistribution(t *testing.T) {
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := msm.GetDefaultMSMConfig()
|
||||
for _, power := range []int{2, 3, 4, 5, 6, 7, 8, 10, 18} {
|
||||
size := 1 << power
|
||||
|
||||
scalars := GenerateScalars(size)
|
||||
scalars := icicleBls12_381.GenerateScalars(size)
|
||||
for i := size / 4; i < size; i++ {
|
||||
scalars[i].One()
|
||||
}
|
||||
points := GenerateAffinePoints(size)
|
||||
points := icicleBls12_381.GenerateAffinePoints(size)
|
||||
for i := 0; i < size/4; i++ {
|
||||
points[i].Zero()
|
||||
}
|
||||
|
||||
var p Projective
|
||||
var p icicleBls12_381.Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.Malloc(p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
e = Msm(scalars, points, &cfg, out)
|
||||
e = msm.Msm(scalars, points, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[Projective], 1)
|
||||
outHost := make(core.HostSlice[icicleBls12_381.Projective], 1)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
// Check with gnark-crypto
|
||||
assert.True(t, testAgainstGnarkCryptoMsm(scalars, points, outHost[0]))
|
||||
}
|
||||
@@ -196,23 +251,23 @@ func TestMSMMultiDevice(t *testing.T) {
|
||||
wg.Add(1)
|
||||
cr.RunOnDevice(i, func(args ...any) {
|
||||
defer wg.Done()
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg := msm.GetDefaultMSMConfig()
|
||||
cfg.IsAsync = true
|
||||
for _, power := range []int{2, 3, 4, 5, 6, 7, 8, 10, 18} {
|
||||
size := 1 << power
|
||||
scalars := GenerateScalars(size)
|
||||
points := GenerateAffinePoints(size)
|
||||
scalars := icicleBls12_381.GenerateScalars(size)
|
||||
points := icicleBls12_381.GenerateAffinePoints(size)
|
||||
|
||||
stream, _ := cr.CreateStream()
|
||||
var p Projective
|
||||
var p icicleBls12_381.Projective
|
||||
var out core.DeviceSlice
|
||||
_, e := out.MallocAsync(p.Size(), p.Size(), stream)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
cfg.Ctx.Stream = &stream
|
||||
|
||||
e = Msm(scalars, points, &cfg, out)
|
||||
e = msm.Msm(scalars, points, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
outHost := make(core.HostSlice[Projective], 1)
|
||||
outHost := make(core.HostSlice[icicleBls12_381.Projective], 1)
|
||||
outHost.CopyFromDeviceAsync(&out, stream)
|
||||
out.FreeAsync(stream)
|
||||
|
||||
@@ -1,40 +1,20 @@
|
||||
package bls12381
|
||||
package tests
|
||||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-381/fr"
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-381/fr/fft"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
bls12_381 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381"
|
||||
ntt "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381/ntt"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
const (
|
||||
largestTestSize = 17
|
||||
)
|
||||
|
||||
func init() {
|
||||
cfg := GetDefaultNttConfig()
|
||||
initDomain(largestTestSize, cfg)
|
||||
}
|
||||
|
||||
func initDomain[T any](largestTestSize int, cfg core.NTTConfig[T]) core.IcicleError {
|
||||
rouMont, _ := fft.Generator(uint64(1 << largestTestSize))
|
||||
rou := rouMont.Bits()
|
||||
rouIcicle := ScalarField{}
|
||||
limbs := core.ConvertUint64ArrToUint32Arr(rou[:])
|
||||
|
||||
rouIcicle.FromLimbs(limbs)
|
||||
e := InitDomain(rouIcicle, cfg.Ctx, false)
|
||||
return e
|
||||
}
|
||||
|
||||
func testAgainstGnarkCryptoNtt(size int, scalars core.HostSlice[ScalarField], output core.HostSlice[ScalarField], order core.Ordering, direction core.NTTDir) bool {
|
||||
domainWithPrecompute := fft.NewDomain(uint64(size))
|
||||
func testAgainstGnarkCryptoNtt(size int, scalars core.HostSlice[bls12_381.ScalarField], output core.HostSlice[bls12_381.ScalarField], order core.Ordering, direction core.NTTDir) bool {
|
||||
scalarsFr := make([]fr.Element, size)
|
||||
for i, v := range scalars {
|
||||
slice64, _ := fr.LittleEndian.Element((*[fr.Bytes]byte)(v.ToBytesLittleEndian()))
|
||||
@@ -46,6 +26,11 @@ func testAgainstGnarkCryptoNtt(size int, scalars core.HostSlice[ScalarField], ou
|
||||
outputAsFr[i] = slice64
|
||||
}
|
||||
|
||||
return testAgainstGnarkCryptoNttGnarkTypes(size, scalarsFr, outputAsFr, order, direction)
|
||||
}
|
||||
|
||||
func testAgainstGnarkCryptoNttGnarkTypes(size int, scalarsFr core.HostSlice[fr.Element], outputAsFr core.HostSlice[fr.Element], order core.Ordering, direction core.NTTDir) bool {
|
||||
domainWithPrecompute := fft.NewDomain(uint64(size))
|
||||
// DIT + BitReverse == Ordering.kRR
|
||||
// DIT == Ordering.kRN
|
||||
// DIF + BitReverse == Ordering.kNN
|
||||
@@ -68,72 +53,77 @@ func testAgainstGnarkCryptoNtt(size int, scalars core.HostSlice[ScalarField], ou
|
||||
}
|
||||
return reflect.DeepEqual(scalarsFr, outputAsFr)
|
||||
}
|
||||
|
||||
func TestNTTGetDefaultConfig(t *testing.T) {
|
||||
actual := GetDefaultNttConfig()
|
||||
expected := generateLimbOne(int(SCALAR_LIMBS))
|
||||
actual := ntt.GetDefaultNttConfig()
|
||||
expected := test_helpers.GenerateLimbOne(int(bls12_381.SCALAR_LIMBS))
|
||||
assert.Equal(t, expected, actual.CosetGen[:])
|
||||
|
||||
cosetGenField := ScalarField{}
|
||||
cosetGenField := bls12_381.ScalarField{}
|
||||
cosetGenField.One()
|
||||
assert.ElementsMatch(t, cosetGenField.GetLimbs(), actual.CosetGen)
|
||||
}
|
||||
|
||||
func TestInitDomain(t *testing.T) {
|
||||
t.Skip("Skipped because each test requires the domain to be initialized before running. We ensure this using the TestMain() function")
|
||||
cfg := GetDefaultNttConfig()
|
||||
cfg := ntt.GetDefaultNttConfig()
|
||||
assert.NotPanics(t, func() { initDomain(largestTestSize, cfg) })
|
||||
}
|
||||
|
||||
func TestNtt(t *testing.T) {
|
||||
cfg := GetDefaultNttConfig()
|
||||
scalars := GenerateScalars(1 << largestTestSize)
|
||||
cfg := ntt.GetDefaultNttConfig()
|
||||
scalars := bls12_381.GenerateScalars(1 << largestTestSize)
|
||||
|
||||
for _, size := range []int{4, largestTestSize} {
|
||||
for _, v := range [4]core.Ordering{core.KNN, core.KNR, core.KRN, core.KRR} {
|
||||
testSize := 1 << size
|
||||
|
||||
scalarsCopy := core.HostSliceFromElements[ScalarField](scalars[:testSize])
|
||||
scalarsCopy := core.HostSliceFromElements[bls12_381.ScalarField](scalars[:testSize])
|
||||
cfg.Ordering = v
|
||||
|
||||
// run ntt
|
||||
output := make(core.HostSlice[ScalarField], testSize)
|
||||
Ntt(scalarsCopy, core.KForward, &cfg, output)
|
||||
output := make(core.HostSlice[bls12_381.ScalarField], testSize)
|
||||
ntt.Ntt(scalarsCopy, core.KForward, &cfg, output)
|
||||
|
||||
// Compare with gnark-crypto
|
||||
assert.True(t, testAgainstGnarkCryptoNtt(testSize, scalarsCopy, output, v, core.KForward))
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestNttFrElement(t *testing.T) {
|
||||
cfg := ntt.GetDefaultNttConfig()
|
||||
scalars := make([]fr.Element, 4)
|
||||
var x fr.Element
|
||||
for i := 0; i < 4; i++ {
|
||||
x.SetRandom()
|
||||
scalars[i] = x
|
||||
}
|
||||
|
||||
func TestECNtt(t *testing.T) {
|
||||
cfg := GetDefaultNttConfig()
|
||||
points := GenerateProjectivePoints(1 << largestTestSize)
|
||||
for _, size := range []int{4} {
|
||||
for _, v := range [1]core.Ordering{core.KNN} {
|
||||
testSize := size
|
||||
|
||||
for _, size := range []int{4, 5, 6, 7, 8} {
|
||||
for _, v := range [4]core.Ordering{core.KNN, core.KNR, core.KRN, core.KRR} {
|
||||
testSize := 1 << size
|
||||
|
||||
pointsCopy := core.HostSliceFromElements[Projective](points[:testSize])
|
||||
scalarsCopy := (core.HostSlice[fr.Element])(scalars[:testSize])
|
||||
cfg.Ordering = v
|
||||
cfg.NttAlgorithm = core.Radix2
|
||||
|
||||
output := make(core.HostSlice[Projective], testSize)
|
||||
e := ECNtt(pointsCopy, core.KForward, &cfg, output)
|
||||
assert.Equal(t, core.IcicleErrorCode(0), e.IcicleErrorCode, "ECNtt failed")
|
||||
// run ntt
|
||||
output := make(core.HostSlice[fr.Element], testSize)
|
||||
ntt.Ntt(scalarsCopy, core.KForward, &cfg, output)
|
||||
|
||||
// Compare with gnark-crypto
|
||||
assert.True(t, testAgainstGnarkCryptoNttGnarkTypes(testSize, scalarsCopy, output, v, core.KForward))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNttDeviceAsync(t *testing.T) {
|
||||
cfg := GetDefaultNttConfig()
|
||||
scalars := GenerateScalars(1 << largestTestSize)
|
||||
cfg := ntt.GetDefaultNttConfig()
|
||||
scalars := bls12_381.GenerateScalars(1 << largestTestSize)
|
||||
|
||||
for _, size := range []int{1, 10, largestTestSize} {
|
||||
for _, direction := range []core.NTTDir{core.KForward, core.KInverse} {
|
||||
for _, v := range [4]core.Ordering{core.KNN, core.KNR, core.KRN, core.KRR} {
|
||||
testSize := 1 << size
|
||||
scalarsCopy := core.HostSliceFromElements[ScalarField](scalars[:testSize])
|
||||
scalarsCopy := core.HostSliceFromElements[bls12_381.ScalarField](scalars[:testSize])
|
||||
|
||||
stream, _ := cr.CreateStream()
|
||||
|
||||
@@ -147,12 +137,11 @@ func TestNttDeviceAsync(t *testing.T) {
|
||||
deviceOutput.MallocAsync(testSize*scalarsCopy.SizeOfElement(), scalarsCopy.SizeOfElement(), stream)
|
||||
|
||||
// run ntt
|
||||
Ntt(deviceInput, direction, &cfg, deviceOutput)
|
||||
output := make(core.HostSlice[ScalarField], testSize)
|
||||
ntt.Ntt(deviceInput, direction, &cfg, deviceOutput)
|
||||
output := make(core.HostSlice[bls12_381.ScalarField], testSize)
|
||||
output.CopyFromDeviceAsync(&deviceOutput, stream)
|
||||
|
||||
cr.SynchronizeStream(&stream)
|
||||
|
||||
// Compare with gnark-crypto
|
||||
assert.True(t, testAgainstGnarkCryptoNtt(testSize, scalarsCopy, output, v, direction))
|
||||
}
|
||||
@@ -161,22 +150,22 @@ func TestNttDeviceAsync(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNttBatch(t *testing.T) {
|
||||
cfg := GetDefaultNttConfig()
|
||||
cfg := ntt.GetDefaultNttConfig()
|
||||
largestBatchSize := 100
|
||||
scalars := GenerateScalars(1 << largestTestSize * largestBatchSize)
|
||||
scalars := bls12_381.GenerateScalars(1 << largestTestSize * largestBatchSize)
|
||||
|
||||
for _, size := range []int{4, largestTestSize} {
|
||||
for _, batchSize := range []int{1, 16, largestBatchSize} {
|
||||
testSize := 1 << size
|
||||
totalSize := testSize * batchSize
|
||||
|
||||
scalarsCopy := core.HostSliceFromElements[ScalarField](scalars[:totalSize])
|
||||
scalarsCopy := core.HostSliceFromElements[bls12_381.ScalarField](scalars[:totalSize])
|
||||
|
||||
cfg.Ordering = core.KNN
|
||||
cfg.BatchSize = int32(batchSize)
|
||||
// run ntt
|
||||
output := make(core.HostSlice[ScalarField], totalSize)
|
||||
Ntt(scalarsCopy, core.KForward, &cfg, output)
|
||||
output := make(core.HostSlice[bls12_381.ScalarField], totalSize)
|
||||
ntt.Ntt(scalarsCopy, core.KForward, &cfg, output)
|
||||
|
||||
// Compare with gnark-crypto
|
||||
domainWithPrecompute := fft.NewDomain(uint64(testSize))
|
||||
@@ -205,36 +194,18 @@ func TestNttBatch(t *testing.T) {
|
||||
|
||||
func TestReleaseDomain(t *testing.T) {
|
||||
t.Skip("Skipped because each test requires the domain to be initialized before running. We ensure this using the TestMain() function")
|
||||
cfg := GetDefaultNttConfig()
|
||||
e := ReleaseDomain(cfg.Ctx)
|
||||
cfg := ntt.GetDefaultNttConfig()
|
||||
e := ntt.ReleaseDomain(cfg.Ctx)
|
||||
assert.Equal(t, core.IcicleErrorCode(0), e.IcicleErrorCode, "ReleasDomain failed")
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
// setup domain
|
||||
cfg := GetDefaultNttConfig()
|
||||
e := initDomain(largestTestSize, cfg)
|
||||
if e.IcicleErrorCode != core.IcicleErrorCode(0) {
|
||||
panic("initDomain failed")
|
||||
}
|
||||
|
||||
// execute tests
|
||||
os.Exit(m.Run())
|
||||
|
||||
// release domain
|
||||
e = ReleaseDomain(cfg.Ctx)
|
||||
if e.IcicleErrorCode != core.IcicleErrorCode(0) {
|
||||
panic("ReleaseDomain failed")
|
||||
}
|
||||
}
|
||||
|
||||
// func TestNttArbitraryCoset(t *testing.T) {
|
||||
// for _, size := range []int{20} {
|
||||
// for _, v := range [4]core.Ordering{core.KNN, core.KNR, core.KRN, core.KRR} {
|
||||
// testSize := 1 << size
|
||||
// scalars := GenerateScalars(testSize)
|
||||
|
||||
// cfg := GetDefaultNttConfig()
|
||||
// cfg := ntt.GetDefaultNttConfig()
|
||||
|
||||
// var scalarsCopy core.HostSlice[ScalarField]
|
||||
// for _, v := range scalars {
|
||||
229
wrappers/golang/curves/bls12381/tests/polynomial_test.go
Normal file
229
wrappers/golang/curves/bls12381/tests/polynomial_test.go
Normal file
@@ -0,0 +1,229 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
bls12_381 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381"
|
||||
// "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381/ntt"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381/polynomial"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381/vecOps"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var one, two, three, four, five bls12_381.ScalarField
|
||||
|
||||
func init() {
|
||||
one.One()
|
||||
two.FromUint32(2)
|
||||
three.FromUint32(3)
|
||||
four.FromUint32(4)
|
||||
five.FromUint32(5)
|
||||
}
|
||||
|
||||
func rand() bls12_381.ScalarField {
|
||||
return bls12_381.GenerateScalars(1)[0]
|
||||
}
|
||||
|
||||
func randomPoly(size int) (f polynomial.DensePolynomial) {
|
||||
f.CreateFromCoeffecitients(core.HostSliceFromElements(bls12_381.GenerateScalars(size)))
|
||||
return f
|
||||
}
|
||||
|
||||
func vecOp(a, b bls12_381.ScalarField, op core.VecOps) bls12_381.ScalarField {
|
||||
ahost := core.HostSliceWithValue(a, 1)
|
||||
bhost := core.HostSliceWithValue(b, 1)
|
||||
out := make(core.HostSlice[bls12_381.ScalarField], 1)
|
||||
|
||||
cfg := core.DefaultVecOpsConfig()
|
||||
vecOps.VecOp(ahost, bhost, out, cfg, op)
|
||||
return out[0]
|
||||
}
|
||||
|
||||
func TestPolyCreateFromCoefficients(t *testing.T) {
|
||||
scalars := bls12_381.GenerateScalars(33)
|
||||
var uniPoly polynomial.DensePolynomial
|
||||
|
||||
poly := uniPoly.CreateFromCoeffecitients(scalars)
|
||||
poly.Print()
|
||||
}
|
||||
|
||||
func TestPolyEval(t *testing.T) {
|
||||
// testing correct evaluation of f(8) for f(x)=4x^2+2x+5
|
||||
coeffs := core.HostSliceFromElements([]bls12_381.ScalarField{five, two, four})
|
||||
var f polynomial.DensePolynomial
|
||||
f.CreateFromCoeffecitients(coeffs)
|
||||
|
||||
var x bls12_381.ScalarField
|
||||
x.FromUint32(8)
|
||||
domains := make(core.HostSlice[bls12_381.ScalarField], 1)
|
||||
domains[0] = x
|
||||
evals := make(core.HostSlice[bls12_381.ScalarField], 1)
|
||||
fEvaled := f.EvalOnDomain(domains, evals)
|
||||
var expected bls12_381.ScalarField
|
||||
assert.Equal(t, expected.FromUint32(277), fEvaled.(core.HostSlice[bls12_381.ScalarField])[0])
|
||||
}
|
||||
|
||||
func TestPolyClone(t *testing.T) {
|
||||
f := randomPoly(8)
|
||||
x := rand()
|
||||
fx := f.Eval(x)
|
||||
|
||||
g := f.Clone()
|
||||
fg := f.Add(&g)
|
||||
|
||||
gx := g.Eval(x)
|
||||
fgx := fg.Eval(x)
|
||||
|
||||
assert.Equal(t, fx, gx)
|
||||
assert.Equal(t, vecOp(fx, gx, core.Add), fgx)
|
||||
}
|
||||
|
||||
func TestPolyAddSubMul(t *testing.T) {
|
||||
testSize := 1 << 10
|
||||
f := randomPoly(testSize)
|
||||
g := randomPoly(testSize)
|
||||
x := rand()
|
||||
|
||||
fx := f.Eval(x)
|
||||
gx := g.Eval(x)
|
||||
|
||||
polyAdd := f.Add(&g)
|
||||
fxAddgx := vecOp(fx, gx, core.Add)
|
||||
assert.Equal(t, polyAdd.Eval(x), fxAddgx)
|
||||
|
||||
polySub := f.Subtract(&g)
|
||||
fxSubgx := vecOp(fx, gx, core.Sub)
|
||||
assert.Equal(t, polySub.Eval(x), fxSubgx)
|
||||
|
||||
polyMul := f.Multiply(&g)
|
||||
fxMulgx := vecOp(fx, gx, core.Mul)
|
||||
assert.Equal(t, polyMul.Eval(x), fxMulgx)
|
||||
|
||||
s1 := rand()
|
||||
polMulS1 := f.MultiplyByScalar(s1)
|
||||
assert.Equal(t, polMulS1.Eval(x), vecOp(fx, s1, core.Mul))
|
||||
|
||||
s2 := rand()
|
||||
polMulS2 := f.MultiplyByScalar(s2)
|
||||
assert.Equal(t, polMulS2.Eval(x), vecOp(fx, s2, core.Mul))
|
||||
}
|
||||
|
||||
func TestPolyMonomials(t *testing.T) {
|
||||
var zero bls12_381.ScalarField
|
||||
var f polynomial.DensePolynomial
|
||||
f.CreateFromCoeffecitients(core.HostSliceFromElements([]bls12_381.ScalarField{one, zero, two}))
|
||||
x := rand()
|
||||
|
||||
fx := f.Eval(x)
|
||||
f.AddMonomial(three, 1)
|
||||
fxAdded := f.Eval(x)
|
||||
assert.Equal(t, fxAdded, vecOp(fx, vecOp(three, x, core.Mul), core.Add))
|
||||
|
||||
f.SubMonomial(one, 0)
|
||||
fxSub := f.Eval(x)
|
||||
assert.Equal(t, fxSub, vecOp(fxAdded, one, core.Sub))
|
||||
}
|
||||
|
||||
func TestPolyReadCoeffs(t *testing.T) {
|
||||
var f polynomial.DensePolynomial
|
||||
coeffs := core.HostSliceFromElements([]bls12_381.ScalarField{one, two, three, four})
|
||||
f.CreateFromCoeffecitients(coeffs)
|
||||
coeffsCopied := make(core.HostSlice[bls12_381.ScalarField], coeffs.Len())
|
||||
_, _ = f.CopyCoeffsRange(0, coeffs.Len()-1, coeffsCopied)
|
||||
assert.ElementsMatch(t, coeffs, coeffsCopied)
|
||||
|
||||
var coeffsDevice core.DeviceSlice
|
||||
coeffsDevice.Malloc(coeffs.Len()*one.Size(), one.Size())
|
||||
_, _ = f.CopyCoeffsRange(0, coeffs.Len()-1, coeffsDevice)
|
||||
coeffsHost := make(core.HostSlice[bls12_381.ScalarField], coeffs.Len())
|
||||
coeffsHost.CopyFromDevice(&coeffsDevice)
|
||||
|
||||
assert.ElementsMatch(t, coeffs, coeffsHost)
|
||||
}
|
||||
|
||||
func TestPolyOddEvenSlicing(t *testing.T) {
|
||||
size := 1<<10 - 3
|
||||
f := randomPoly(size)
|
||||
|
||||
even := f.Even()
|
||||
odd := f.Odd()
|
||||
assert.Equal(t, f.Degree(), even.Degree()+odd.Degree()+1)
|
||||
|
||||
x := rand()
|
||||
var evenExpected, oddExpected bls12_381.ScalarField
|
||||
for i := size; i >= 0; i-- {
|
||||
if i%2 == 0 {
|
||||
mul := vecOp(evenExpected, x, core.Mul)
|
||||
evenExpected = vecOp(mul, f.GetCoeff(i), core.Add)
|
||||
} else {
|
||||
mul := vecOp(oddExpected, x, core.Mul)
|
||||
oddExpected = vecOp(mul, f.GetCoeff(i), core.Add)
|
||||
}
|
||||
}
|
||||
|
||||
evenEvaled := even.Eval(x)
|
||||
assert.Equal(t, evenExpected, evenEvaled)
|
||||
|
||||
oddEvaled := odd.Eval(x)
|
||||
assert.Equal(t, oddExpected, oddEvaled)
|
||||
}
|
||||
|
||||
func TestPolynomialDivision(t *testing.T) {
|
||||
// divide f(x)/g(x), compute q(x), r(x) and check f(x)=q(x)*g(x)+r(x)
|
||||
var f, g polynomial.DensePolynomial
|
||||
f.CreateFromCoeffecitients(core.HostSliceFromElements(bls12_381.GenerateScalars(1 << 4)))
|
||||
g.CreateFromCoeffecitients(core.HostSliceFromElements(bls12_381.GenerateScalars(1 << 2)))
|
||||
|
||||
q, r := f.Divide(&g)
|
||||
|
||||
qMulG := q.Multiply(&g)
|
||||
fRecon := qMulG.Add(&r)
|
||||
|
||||
x := bls12_381.GenerateScalars(1)[0]
|
||||
fEval := f.Eval(x)
|
||||
fReconEval := fRecon.Eval(x)
|
||||
assert.Equal(t, fEval, fReconEval)
|
||||
}
|
||||
|
||||
func TestDivideByVanishing(t *testing.T) {
|
||||
// poly of x^4-1 vanishes ad 4th rou
|
||||
var zero bls12_381.ScalarField
|
||||
minus_one := vecOp(zero, one, core.Sub)
|
||||
coeffs := core.HostSliceFromElements([]bls12_381.ScalarField{minus_one, zero, zero, zero, one}) // x^4-1
|
||||
var v polynomial.DensePolynomial
|
||||
v.CreateFromCoeffecitients(coeffs)
|
||||
|
||||
f := randomPoly(1 << 3)
|
||||
|
||||
fv := f.Multiply(&v)
|
||||
fDegree := f.Degree()
|
||||
fvDegree := fv.Degree()
|
||||
assert.Equal(t, fDegree+4, fvDegree)
|
||||
|
||||
fReconstructed := fv.DivideByVanishing(4)
|
||||
assert.Equal(t, fDegree, fReconstructed.Degree())
|
||||
|
||||
x := rand()
|
||||
assert.Equal(t, f.Eval(x), fReconstructed.Eval(x))
|
||||
}
|
||||
|
||||
// func TestPolySlice(t *testing.T) {
|
||||
// size := 4
|
||||
// coeffs := bls12_381.GenerateScalars(size)
|
||||
// var f DensePolynomial
|
||||
// f.CreateFromCoeffecitients(coeffs)
|
||||
// fSlice := f.AsSlice()
|
||||
// assert.True(t, fSlice.IsOnDevice())
|
||||
// assert.Equal(t, size, fSlice.Len())
|
||||
|
||||
// hostSlice := make(core.HostSlice[bls12_381.ScalarField], size)
|
||||
// hostSlice.CopyFromDevice(fSlice)
|
||||
// assert.Equal(t, coeffs, hostSlice)
|
||||
|
||||
// cfg := ntt.GetDefaultNttConfig()
|
||||
// res := make(core.HostSlice[bls12_381.ScalarField], size)
|
||||
// ntt.Ntt(fSlice, core.KForward, cfg, res)
|
||||
|
||||
// assert.Equal(t, f.Eval(one), res[0])
|
||||
// }
|
||||
120
wrappers/golang/curves/bls12381/tests/scalar_field_test.go
Normal file
120
wrappers/golang/curves/bls12381/tests/scalar_field_test.go
Normal file
@@ -0,0 +1,120 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
bls12_381 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/test_helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
SCALAR_LIMBS = bls12_381.SCALAR_LIMBS
|
||||
)
|
||||
|
||||
func TestScalarFieldFromLimbs(t *testing.T) {
|
||||
emptyField := bls12_381.ScalarField{}
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(SCALAR_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
assert.ElementsMatch(t, randLimbs, emptyField.GetLimbs(), "Limbs do not match; there was an issue with setting the ScalarField's limbs")
|
||||
randLimbs[0] = 100
|
||||
assert.NotEqual(t, randLimbs, emptyField.GetLimbs())
|
||||
}
|
||||
|
||||
func TestScalarFieldGetLimbs(t *testing.T) {
|
||||
emptyField := bls12_381.ScalarField{}
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(SCALAR_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.ElementsMatch(t, randLimbs, emptyField.GetLimbs(), "Limbs do not match; there was an issue with setting the ScalarField's limbs")
|
||||
}
|
||||
|
||||
func TestScalarFieldOne(t *testing.T) {
|
||||
var emptyField bls12_381.ScalarField
|
||||
emptyField.One()
|
||||
limbOne := test_helpers.GenerateLimbOne(int(SCALAR_LIMBS))
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbOne, "Empty field to field one did not work")
|
||||
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(SCALAR_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
emptyField.One()
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbOne, "ScalarField with limbs to field one did not work")
|
||||
}
|
||||
|
||||
func TestScalarFieldZero(t *testing.T) {
|
||||
var emptyField bls12_381.ScalarField
|
||||
emptyField.Zero()
|
||||
limbsZero := make([]uint32, SCALAR_LIMBS)
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbsZero, "Empty field to field zero failed")
|
||||
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(SCALAR_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
emptyField.Zero()
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), limbsZero, "ScalarField with limbs to field zero failed")
|
||||
}
|
||||
|
||||
func TestScalarFieldSize(t *testing.T) {
|
||||
var emptyField bls12_381.ScalarField
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(SCALAR_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.Equal(t, len(randLimbs)*4, emptyField.Size(), "Size returned an incorrect value of bytes")
|
||||
}
|
||||
|
||||
func TestScalarFieldAsPointer(t *testing.T) {
|
||||
var emptyField bls12_381.ScalarField
|
||||
randLimbs := test_helpers.GenerateRandomLimb(int(SCALAR_LIMBS))
|
||||
emptyField.FromLimbs(randLimbs[:])
|
||||
|
||||
assert.Equal(t, randLimbs[0], *emptyField.AsPointer(), "AsPointer returned pointer to incorrect value")
|
||||
}
|
||||
|
||||
func TestScalarFieldFromBytes(t *testing.T) {
|
||||
var emptyField bls12_381.ScalarField
|
||||
bytes, expected := test_helpers.GenerateBytesArray(int(SCALAR_LIMBS))
|
||||
|
||||
emptyField.FromBytesLittleEndian(bytes)
|
||||
|
||||
assert.ElementsMatch(t, emptyField.GetLimbs(), expected, "FromBytes returned incorrect values")
|
||||
}
|
||||
|
||||
func TestScalarFieldToBytes(t *testing.T) {
|
||||
var emptyField bls12_381.ScalarField
|
||||
expected, limbs := test_helpers.GenerateBytesArray(int(SCALAR_LIMBS))
|
||||
emptyField.FromLimbs(limbs)
|
||||
|
||||
assert.ElementsMatch(t, emptyField.ToBytesLittleEndian(), expected, "ToBytes returned incorrect values")
|
||||
}
|
||||
|
||||
func TestBls12_381GenerateScalars(t *testing.T) {
|
||||
const numScalars = 8
|
||||
scalars := bls12_381.GenerateScalars(numScalars)
|
||||
|
||||
assert.Implements(t, (*core.HostOrDeviceSlice)(nil), &scalars)
|
||||
|
||||
assert.Equal(t, numScalars, scalars.Len())
|
||||
zeroScalar := bls12_381.ScalarField{}
|
||||
assert.NotContains(t, scalars, zeroScalar)
|
||||
}
|
||||
|
||||
func TestBls12_381MongtomeryConversion(t *testing.T) {
|
||||
size := 1 << 15
|
||||
scalars := bls12_381.GenerateScalars(size)
|
||||
|
||||
var deviceScalars core.DeviceSlice
|
||||
scalars.CopyToDevice(&deviceScalars, true)
|
||||
|
||||
bls12_381.ToMontgomery(&deviceScalars)
|
||||
|
||||
scalarsMontHost := bls12_381.GenerateScalars(size)
|
||||
|
||||
scalarsMontHost.CopyFromDevice(&deviceScalars)
|
||||
assert.NotEqual(t, scalars, scalarsMontHost)
|
||||
|
||||
bls12_381.FromMontgomery(&deviceScalars)
|
||||
|
||||
scalarsMontHost.CopyFromDevice(&deviceScalars)
|
||||
assert.Equal(t, scalars, scalarsMontHost)
|
||||
}
|
||||
69
wrappers/golang/curves/bls12381/tests/vec_ops_test.go
Normal file
69
wrappers/golang/curves/bls12381/tests/vec_ops_test.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
|
||||
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
|
||||
bls12_381 "github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381"
|
||||
"github.com/ingonyama-zk/icicle/wrappers/golang/curves/bls12381/vecOps"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestBls12_381VecOps(t *testing.T) {
|
||||
testSize := 1 << 14
|
||||
|
||||
a := bls12_381.GenerateScalars(testSize)
|
||||
b := bls12_381.GenerateScalars(testSize)
|
||||
var scalar bls12_381.ScalarField
|
||||
scalar.One()
|
||||
ones := core.HostSliceWithValue(scalar, testSize)
|
||||
|
||||
out := make(core.HostSlice[bls12_381.ScalarField], testSize)
|
||||
out2 := make(core.HostSlice[bls12_381.ScalarField], testSize)
|
||||
out3 := make(core.HostSlice[bls12_381.ScalarField], testSize)
|
||||
|
||||
cfg := core.DefaultVecOpsConfig()
|
||||
|
||||
vecOps.VecOp(a, b, out, cfg, core.Add)
|
||||
vecOps.VecOp(out, b, out2, cfg, core.Sub)
|
||||
|
||||
assert.Equal(t, a, out2)
|
||||
|
||||
vecOps.VecOp(a, ones, out3, cfg, core.Mul)
|
||||
|
||||
assert.Equal(t, a, out3)
|
||||
}
|
||||
|
||||
func TestBls12_381Transpose(t *testing.T) {
|
||||
rowSize := 1 << 6
|
||||
columnSize := 1 << 8
|
||||
onDevice := false
|
||||
isAsync := false
|
||||
|
||||
matrix := bls12_381.GenerateScalars(rowSize * columnSize)
|
||||
|
||||
out := make(core.HostSlice[bls12_381.ScalarField], rowSize*columnSize)
|
||||
out2 := make(core.HostSlice[bls12_381.ScalarField], rowSize*columnSize)
|
||||
|
||||
ctx, _ := cr.GetDefaultDeviceContext()
|
||||
|
||||
vecOps.TransposeMatrix(matrix, out, columnSize, rowSize, ctx, onDevice, isAsync)
|
||||
vecOps.TransposeMatrix(out, out2, rowSize, columnSize, ctx, onDevice, isAsync)
|
||||
|
||||
assert.Equal(t, matrix, out2)
|
||||
|
||||
var dMatrix, dOut, dOut2 core.DeviceSlice
|
||||
onDevice = true
|
||||
|
||||
matrix.CopyToDevice(&dMatrix, true)
|
||||
dOut.Malloc(columnSize*rowSize*matrix.SizeOfElement(), matrix.SizeOfElement())
|
||||
dOut2.Malloc(columnSize*rowSize*matrix.SizeOfElement(), matrix.SizeOfElement())
|
||||
|
||||
vecOps.TransposeMatrix(dMatrix, dOut, columnSize, rowSize, ctx, onDevice, isAsync)
|
||||
vecOps.TransposeMatrix(dOut, dOut2, rowSize, columnSize, ctx, onDevice, isAsync)
|
||||
output := make(core.HostSlice[bls12_381.ScalarField], rowSize*columnSize)
|
||||
output.CopyFromDevice(&dOut2)
|
||||
|
||||
assert.Equal(t, matrix, output)
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user