Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
268 changes: 259 additions & 9 deletions gnark/gnark-jni/gnark-eip-2537.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import "C"
import (
"bytes"
"errors"
"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"
"math/big"
"reflect"
"unsafe"

"github.com/consensys/gnark-crypto/ecc"
bls12381 "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"
)

const (
Expand All @@ -23,13 +24,14 @@ const (
EIP2537PreallocateForG2 = EIP2537PreallocateForG1 * 2 // G2 comprise 2 G1 points, left padded with zero for 16 bytes
EIP2537PreallocateForResultBytes = EIP2537PreallocateForG2 // maximum for G2 point
EIP2537PreallocateForErrorBytes = 256 // max error length

)

var ErrSubgroupCheckFailed = errors.New("invalid point: subgroup check failed")
var ErrPointOnCurveCheckFailed = errors.New("invalid point: point is not on curve")
var ErrMalformedPointPadding = errors.New("invalid point: point is not left padded with zero")
var ErrMalformedOutputBytes = errors.New("malformed output buffer parameter")
var (
ErrSubgroupCheckFailed = errors.New("invalid point: subgroup check failed")
ErrPointOnCurveCheckFailed = errors.New("invalid point: point is not on curve")
ErrMalformedPointPadding = errors.New("invalid point: point is not left padded with zero")
ErrMalformedOutputBytes = errors.New("malformed output buffer parameter")
)

// Predefine a zero slice of length 16
var zeroSlice = make([]byte, 16)
Expand All @@ -41,6 +43,29 @@ func init() {
q = new(fp.Element).SetBigInt(fp.Modulus())
}

/*

eip2537blsG1Add adds two G1 points together and returns a G1 Point.

- Input:
- javaInputBuf: Pointer to a buffer containing two G1 points
- javaOutputBuf: Pointer to a buffer where the resulting G1 point will be written
- javaErrorBuf: Pointer to a buffer where error messages will be written if an error occurs
- cInputLen: Length of the input buffer in bytes
- cOutputLen: Length of the output buffer in bytes
- cErrorLen: Length of the error buffer in bytes
- Returns:
- zero is returned if successful, result is written to javaOutputBuf
- one is returned if there is an error, error message is written to javaErrorBuf
- Cryptography:
- The field elements that comprise the G1 input points must be checked to be canonical.
- Check that both G1 input points are on the curve
- Do not check that input points are in the correct subgroup (See EIP-2537)
- JNI:
- javaInputBuf must be at least 2*EIP2537PreallocateForG1 bytes (two G1 points)
- javaOutputBuf must be at least EIP2537PreallocateForG1 bytes to safely store the result

*/
//export eip2537blsG1Add
func eip2537blsG1Add(javaInputBuf, javaOutputBuf, javaErrorBuf *C.char, cInputLen, cOutputLen, cErrorLen C.int) C.int {
inputLen := int(cInputLen)
Expand Down Expand Up @@ -80,6 +105,28 @@ func eip2537blsG1Add(javaInputBuf, javaOutputBuf, javaErrorBuf *C.char, cInputLe
return nonMontgomeryMarshalG1(result, javaOutputBuf, errorBuf)
}

/*
eip2537blsG1Mul performs a scalar multiplication on a G1 point.

- Input:
- javaInputBuf: Pointer to a buffer containing one G1 point and one scalar
- javaOutputBuf: Pointer to a buffer where the resulting G1 point will be written
- javaErrorBuf: Pointer to a buffer where error messages will be written if an error occurs
- cInputLen: Length of the input buffer in bytes
- cOutputLen: Length of the output buffer in bytes
- cErrorLen: Length of the error buffer in bytes
- Returns:
- zero is returned if successful, result is written to javaOutputBuf
- one is returned if there is an error, error message is written to javaErrorBuf
- Cryptography:
- The field elements that comprise the G1 input point must be checked to be canonical.
- The input point must be checked to be on the curve and in the correct subgroup.
- JNI:
- javaInputBuf must be at least (EIP2537PreallocateForG1 + EIP2537PreallocateForScalar) bytes
- javaOutputBuf must be at least EIP2537PreallocateForG1 bytes to safely store the result

*/

//export eip2537blsG1Mul
func eip2537blsG1Mul(javaInputBuf, javaOutputBuf, javaErrorBuf *C.char, cInputLen, cOutputLen, cErrorLen C.int) C.int {
inputLen := int(cInputLen)
Expand Down Expand Up @@ -115,6 +162,29 @@ func eip2537blsG1Mul(javaInputBuf, javaOutputBuf, javaErrorBuf *C.char, cInputLe
return nonMontgomeryMarshalG1(result, javaOutputBuf, errorBuf)
}

/*

eip2537blsG1MultiExp performs a multi-scalar multiplication on multiple G1 points.

- Input:
- javaInputBuf: Pointer to a buffer containing a series of G1 point and scalar pairs
- javaOutputBuf: Pointer to a buffer where the resulting G1 point will be written
- javaErrorBuf: Pointer to a buffer where error messages will be written if an error occurs
- cInputLen: Length of the input buffer in bytes
- cOutputLen: Length of the output buffer in bytes
- cErrorLen: Length of the error buffer in bytes
- Returns:
- zero is returned if successful, result is written to javaOutputBuf
- one is returned if there is an error, error message is written to javaErrorBuf
- Cryptography:
- The field elements that comprise the G1 input points must be checked to be canonical.
- The scalars are not required to be canonical.
- All G1 input points must be checked to be on the curve and in the correct subgroup.
- JNI:
- javaInputBuf must be at least n*(EIP2537PreallocateForG1 + EIP2537PreallocateForScalar) bytes, where n is the number of point-scalar pairs
- javaOutputBuf must be at least EIP2537PreallocateForG1 bytes to safely store the result

*/
//export eip2537blsG1MultiExp
func eip2537blsG1MultiExp(javaInputBuf, javaOutputBuf, javaErrorBuf *C.char, cInputLen, cOutputLen, cErrorLen C.int) C.int {
inputLen := int(cInputLen)
Expand Down Expand Up @@ -169,6 +239,30 @@ func eip2537blsG1MultiExp(javaInputBuf, javaOutputBuf, javaErrorBuf *C.char, cIn
return nonMontgomeryMarshalG1(result, javaOutputBuf, errorBuf)
}

/*

eip2537blsG1MultiExpParallel performs multi-scalar multiplication on multiple G1 points in parallel.

- Input:
- javaInputBuf: Pointer to a buffer containing a series of G1 point and scalar pairs
- javaOutputBuf: Pointer to a buffer where the resulting G1 point will be written
- javaErrorBuf: Pointer to a buffer where error messages will be written if an error occurs
- cInputLen: Length of the input buffer in bytes
- cOutputLen: Length of the output buffer in bytes
- cErrorLen: Length of the error buffer in bytes
- nbTasks: Number of parallel tasks to use for computation
- Returns:
- zero is returned if successful, result is written to javaOutputBuf
- one is returned if there is an error, error message is written to javaErrorBuf
- Cryptography:
- The field elements that comprise the G1 input points must be checked to be canonical.
- The scalars are not required to be canonical.
- Check that all input points are on the curve and in the correct subgroup.
- JNI:
- javaInputBuf must be at least n*(EIP2537PreallocateForG1 + EIP2537PreallocateForScalar) bytes, where n is the number of point-scalar pairs
- javaOutputBuf must be at least EIP2537PreallocateForG1 bytes to safely store the result

*/
//export eip2537blsG1MultiExpParallel
func eip2537blsG1MultiExpParallel(javaInputBuf, javaOutputBuf, javaErrorBuf *C.char, cInputLen, cOutputLen, cErrorLen C.int, nbTasks C.int) C.int {
inputLen := int(cInputLen)
Expand Down Expand Up @@ -217,6 +311,29 @@ func eip2537blsG1MultiExpParallel(javaInputBuf, javaOutputBuf, javaErrorBuf *C.c
return nonMontgomeryMarshalG1(&affineResult, javaOutputBuf, errorBuf)
}

/*

eip2537blsG2Add adds two G2 points together and returns a G2 Point.

- Input:
- javaInputBuf: Pointer to a buffer containing two G2 points
- javaOutputBuf: Pointer to a buffer where the resulting G2 point will be written
- javaErrorBuf: Pointer to a buffer where error messages will be written if an error occurs
- cInputLen: Length of the input buffer in bytes
- cOutputLen: Length of the output buffer in bytes
- cErrorLen: Length of the error buffer in bytes
- Returns:
- zero is returned if successful, result is written to javaOutputBuf
- one is returned if there is an error, error message is written to javaErrorBuf
- Cryptography:
- The field elements that comprise the G2 input points must be checked to be canonical.
- Check that both input points are on the curve
- Do not check that input points are in the correct subgroup (See EIP-2537)
- JNI:
- javaInputBuf must be at least 2*EIP2537PreallocateForG2 bytes (two G2 points)
- javaOutputBuf must be at least EIP2537PreallocateForG2 bytes to safely store the result

*/
//export eip2537blsG2Add
func eip2537blsG2Add(javaInputBuf, javaOutputBuf, javaErrorBuf *C.char, cInputLen, cOutputLen, cErrorLen C.int) C.int {
inputLen := int(cInputLen)
Expand Down Expand Up @@ -252,6 +369,28 @@ func eip2537blsG2Add(javaInputBuf, javaOutputBuf, javaErrorBuf *C.char, cInputLe
return nonMontgomeryMarshalG2(result, javaOutputBuf, errorBuf)
}

/*

eip2537blsG2Mul performs scalar multiplication on a G2 point.

- Input:
- javaInputBuf: Pointer to a buffer containing one G2 point and one scalar
- javaOutputBuf: Pointer to a buffer where the resulting G2 point will be written
- javaErrorBuf: Pointer to a buffer where error messages will be written if an error occurs
- cInputLen: Length of the input buffer in bytes
- cOutputLen: Length of the output buffer in bytes
- cErrorLen: Length of the error buffer in bytes
- Returns:
- zero is returned if successful, result is written to javaOutputBuf
- one is returned if there is an error, error message is written to javaErrorBuf
- Cryptography:
- The field elements that comprise the G2 input point must be checked to be canonical.
- The input point must be checked to be on the curve and in the correct subgroup.
- JNI:
- javaInputBuf must be at least (EIP2537PreallocateForG2 + EIP2537PreallocateForScalar) bytes
- javaOutputBuf must be at least EIP2537PreallocateForG2 bytes to safely store the result

*/
//export eip2537blsG2Mul
func eip2537blsG2Mul(javaInputBuf, javaOutputBuf, javaErrorBuf *C.char, cInputLen, cOutputLen, cErrorLen C.int) C.int {
inputLen := int(cInputLen)
Expand Down Expand Up @@ -284,6 +423,28 @@ func eip2537blsG2Mul(javaInputBuf, javaOutputBuf, javaErrorBuf *C.char, cInputLe
return nonMontgomeryMarshalG2(result, javaOutputBuf, errorBuf)
}

/*

eip2537blsG2MultiExp performs multi-scalar multiplication on multiple G2 points.

- Input:
- javaInputBuf: Pointer to a buffer containing a series of G2 point and scalar pairs
- javaOutputBuf: Pointer to a buffer where the resulting G2 point will be written
- javaErrorBuf: Pointer to a buffer where error messages will be written if an error occurs
- cInputLen: Length of the input buffer in bytes
- cOutputLen: Length of the output buffer in bytes
- cErrorLen: Length of the error buffer in bytes
- Returns:
- zero is returned if successful, result is written to javaOutputBuf
- one is returned if there is an error, error message is written to javaErrorBuf
- Cryptography:
- The field elements that comprise the G2 input points must be checked to be canonical.
- Check that all input points are on the curve and in the correct subgroup.
- JNI:
- javaInputBuf must be at least n*(EIP2537PreallocateForG2 + EIP2537PreallocateForScalar) bytes, where n is the number of point-scalar pairs
- javaOutputBuf must be at least EIP2537PreallocateForG2 bytes to safely store the result

*/
//export eip2537blsG2MultiExp
func eip2537blsG2MultiExp(javaInputBuf, javaOutputBuf, javaErrorBuf *C.char, cInputLen, cOutputLen, cErrorLen C.int) C.int {
inputLen := int(cInputLen)
Expand Down Expand Up @@ -337,6 +498,29 @@ func eip2537blsG2MultiExp(javaInputBuf, javaOutputBuf, javaErrorBuf *C.char, cIn
return nonMontgomeryMarshalG2(result, javaOutputBuf, errorBuf)
}

/*

eip2537blsG2MultiExpParallel performs multi-scalar multiplication on multiple G2 points in parallel.

- Input:
- javaInputBuf: Pointer to a buffer containing a series of G2 point and scalar pairs
- javaOutputBuf: Pointer to a buffer where the resulting G2 point will be written
- javaErrorBuf: Pointer to a buffer where error messages will be written if an error occurs
- cInputLen: Length of the input buffer in bytes
- cOutputLen: Length of the output buffer in bytes
- cErrorLen: Length of the error buffer in bytes
- nbTasks: Number of parallel tasks to use for computation.
- Returns:
- zero is returned if successful, result is written to javaOutputBuf
- one is returned if there is an error, error message is written to javaErrorBuf
- Cryptography:
- The field elements that comprise the G2 input points must be checked to be canonical.
- Check that all input points are on the curve and in the correct subgroup.
- JNI:
- javaInputBuf must be at least n*(EIP2537PreallocateForG2 + EIP2537PreallocateForScalar) bytes, where n is the number of point-scalar pairs
- javaOutputBuf must be at least EIP2537PreallocateForG2 bytes to safely store the result

*/
//export eip2537blsG2MultiExpParallel
func eip2537blsG2MultiExpParallel(javaInputBuf, javaOutputBuf, javaErrorBuf *C.char, cInputLen, cOutputLen, cErrorLen C.int, nbTasks C.int) C.int {
inputLen := int(cInputLen)
Expand Down Expand Up @@ -385,6 +569,28 @@ func eip2537blsG2MultiExpParallel(javaInputBuf, javaOutputBuf, javaErrorBuf *C.c
return nonMontgomeryMarshalG2(&affineResult, javaOutputBuf, errorBuf)
}

/*

eip2537blsPairing performs a pairing check on a collection of G1 and G2 point pairs.

- Input:
- javaInputBuf: Pointer to a buffer containing a series of G1 and G2 point pairs
- javaOutputBuf: Pointer to a buffer where the result (32-byte value) will be written
- javaErrorBuf: Pointer to a buffer where error messages will be written if an error occurs
- cInputLen: Length of the input buffer in bytes
- cOutputLen: Length of the output buffer in bytes
- cErrorLen: Length of the error buffer in bytes
- Returns:
- zero is returned if successful, javaOutputBuf contains a 32-byte value: 0x01 if pairing check succeeded, 0x00 otherwise
- one is returned if there is an error, error message is written to javaErrorBuf
- Cryptography:
- The field elements that comprise the input points must be checked to be canonical.
- Check that all input points are on the curve and in the correct subgroup.
- JNI:
- javaInputBuf must be at least n*(EIP2537PreallocateForG1 + EIP2537PreallocateForG2) bytes, where n is the number of G1-G2 point pairs
- javaOutputBuf must be at least 32 bytes to safely store the result (0x01 for success, 0x00 otherwise)

*/
//export eip2537blsPairing
func eip2537blsPairing(javaInputBuf, javaOutputBuf, javaErrorBuf *C.char, cInputLen, cOutputLen, cErrorLen C.int) C.int {
inputLen := int(cInputLen)
Expand Down Expand Up @@ -448,6 +654,28 @@ func eip2537blsPairing(javaInputBuf, javaOutputBuf, javaErrorBuf *C.char, cInput

}

/*

eip2537blsMapFpToG1 maps a field element to a point on the G1 curve.

- Input:
- javaInputBuf: Pointer to a buffer containing one Fp field element
- javaOutputBuf: Pointer to a buffer where the resulting G1 point will be written
- javaErrorBuf: Pointer to a buffer where error messages will be written if an error occurs
- cInputLen: Length of the input buffer in bytes
- cOutputLen: Length of the output buffer in bytes
- cErrorLen: Length of the error buffer in bytes
- Returns:
- zero is returned if successful, result is written to javaOutputBuf
- one is returned if there is an error, error message is written to javaErrorBuf
- Cryptography:
- The input field element must be checked to be canonical.
- The resulting point is guaranteed to be on the curve and in the correct subgroup.
- JNI:
- javaInputBuf must be at least EIP2537PreallocateForFp bytes to store the input field element
- javaOutputBuf must be at least EIP2537PreallocateForG1 bytes to safely store the result

*/
//export eip2537blsMapFpToG1
func eip2537blsMapFpToG1(javaInputBuf, javaOutputBuf, javaErrorBuf *C.char, cInputLen, cOutputLen, cErrorLen C.int) C.int {
inputLen := int(cInputLen)
Expand Down Expand Up @@ -482,6 +710,28 @@ func eip2537blsMapFpToG1(javaInputBuf, javaOutputBuf, javaErrorBuf *C.char, cInp
return nonMontgomeryMarshalG1(&result, javaOutputBuf, errorBuf)
}

/*

eip2537blsMapFp2ToG2 maps a field element in the quadratic extension field Fp^2 to a point on the G2 curve.

- Input:
- javaInputBuf: Pointer to a buffer containing one Fp^2 field element (two Fp elements)
- javaOutputBuf: Pointer to a buffer where the resulting G2 point will be written
- javaErrorBuf: Pointer to a buffer where error messages will be written if an error occurs
- cInputLen: Length of the input buffer in bytes
- cOutputLen: Length of the output buffer in bytes
- cErrorLen: Length of the error buffer in bytes
- Returns:
- zero is returned if successful, result is written to javaOutputBuf
- one is returned if there is an error, error message is written to javaErrorBuf
- Cryptography:
- The input field elements must be checked to be canonical.
- The resulting point is guaranteed to be on the curve and in the correct subgroup.
- JNI:
- javaInputBuf must be at least 2*EIP2537PreallocateForFp bytes to store the input Fp^2 field element (two Fp elements)
- javaOutputBuf must be at least EIP2537PreallocateForG2 bytes to safely store the result

*/
//export eip2537blsMapFp2ToG2
func eip2537blsMapFp2ToG2(javaInputBuf, javaOutputBuf, javaErrorBuf *C.char, cInputLen, cOutputLen, cErrorLen C.int) C.int {
inputLen := int(cInputLen)
Expand Down
Loading