├── obj └── .emptydir ├── .gitignore ├── ETH.cfg ├── go.mod ├── .gitmodules ├── bls ├── tests │ ├── README.md │ ├── g1_compressed_valid_test_vectors.dat │ ├── g2_compressed_valid_test_vectors.dat │ ├── g1_uncompressed_valid_test_vectors.dat │ ├── g2_uncompressed_valid_test_vectors.dat │ ├── aggregate_verify.txt │ ├── aggregate.txt │ ├── sign.txt │ ├── fast_aggregate_verify.txt │ └── verify.txt ├── link_ios.go ├── link_iossimulator.go ├── callback.go ├── include │ ├── bls │ │ ├── bls384_256.h │ │ └── bls.h │ └── mcl │ │ ├── bn_c384_256.h │ │ ├── curve_type.h │ │ └── bn.h ├── rand_test.go ├── cast.go ├── link.go ├── harmony_test.go ├── eth.go ├── bls_test.go ├── bls.go └── mcl.go ├── examples ├── alpine.Dockerfile ├── readme.md └── sample.go ├── patch ├── mcl.patch └── bls.patch ├── setup_vendor.sh ├── .github └── workflows │ ├── main.yml │ └── release.yml ├── Makefile └── readme.md /obj/.emptydir: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | obj/*.o 2 | CVS 3 | -------------------------------------------------------------------------------- /ETH.cfg: -------------------------------------------------------------------------------- 1 | ETH_CFLAGS=-DBLS_ETH 2 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/herumi/bls-eth-go-binary 2 | 3 | go 1.21 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/bls"] 2 | path = src/bls 3 | url = https://github.com/herumi/bls 4 | -------------------------------------------------------------------------------- /bls/tests/README.md: -------------------------------------------------------------------------------- 1 | Test vectors are copied from [zkcrypto/bls12_381](https://github.com/zkcrypto/bls12_381) @ _afe30519f862abfba3ab26ae1ed406dd779db22e_ -------------------------------------------------------------------------------- /bls/tests/g1_compressed_valid_test_vectors.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/herumi/bls-eth-go-binary/HEAD/bls/tests/g1_compressed_valid_test_vectors.dat -------------------------------------------------------------------------------- /bls/tests/g2_compressed_valid_test_vectors.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/herumi/bls-eth-go-binary/HEAD/bls/tests/g2_compressed_valid_test_vectors.dat -------------------------------------------------------------------------------- /bls/tests/g1_uncompressed_valid_test_vectors.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/herumi/bls-eth-go-binary/HEAD/bls/tests/g1_uncompressed_valid_test_vectors.dat -------------------------------------------------------------------------------- /bls/tests/g2_uncompressed_valid_test_vectors.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/herumi/bls-eth-go-binary/HEAD/bls/tests/g2_uncompressed_valid_test_vectors.dat -------------------------------------------------------------------------------- /bls/link_ios.go: -------------------------------------------------------------------------------- 1 | //go:build ios && !iossimulator 2 | // +build ios,!iossimulator 3 | 4 | package bls 5 | 6 | /* 7 | #cgo LDFLAGS:-lbls384_256 -lstdc++ -lm 8 | #cgo ios LDFLAGS:-L${SRCDIR}/lib/ios 9 | */ 10 | import "C" 11 | -------------------------------------------------------------------------------- /bls/link_iossimulator.go: -------------------------------------------------------------------------------- 1 | //go:build iossimulator 2 | // +build iossimulator 3 | 4 | package bls 5 | 6 | /* 7 | #cgo LDFLAGS:-lbls384_256 -lstdc++ -lm 8 | #cgo ios LDFLAGS:-L${SRCDIR}/lib/iossimulator 9 | */ 10 | import "C" 11 | -------------------------------------------------------------------------------- /examples/alpine.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.14-alpine 2 | 3 | # For CGO build 4 | RUN apk add gcc g++ 5 | 6 | RUN mkdir /app 7 | ADD . /app 8 | WORKDIR /app 9 | 10 | RUN go build -o sample ./examples/sample.go 11 | 12 | ENTRYPOINT /app/sample 13 | 14 | -------------------------------------------------------------------------------- /bls/callback.go: -------------------------------------------------------------------------------- 1 | package bls 2 | 3 | /* 4 | // exported from bls.go 5 | unsigned int wrapReadRandGo(void *buf, unsigned int n); 6 | int wrapReadRandCgo(void *self, void *buf, unsigned int n) 7 | { 8 | (void)self; 9 | return wrapReadRandGo(buf, n); 10 | } 11 | */ 12 | import "C" 13 | -------------------------------------------------------------------------------- /bls/include/bls/bls384_256.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /** 3 | @file 4 | @brief C API of 384/256-bit 5 | @author MITSUNARI Shigeo(@herumi) 6 | @license modified new BSD license 7 | http://opensource.org/licenses/BSD-3-Clause 8 | */ 9 | #define MCLBN_FP_UNIT_SIZE 6 10 | #define MCLBN_FR_UNIT_SIZE 4 11 | #include 12 | 13 | -------------------------------------------------------------------------------- /bls/include/mcl/bn_c384_256.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /** 3 | @file 4 | @brief C API of 384/256-bit optimal ate pairing over BN curves 5 | @author MITSUNARI Shigeo(@herumi) 6 | @license modified new BSD license 7 | http://opensource.org/licenses/BSD-3-Clause 8 | */ 9 | #define MCLBN_FP_UNIT_SIZE 6 10 | #define MCLBN_FR_UNIT_SIZE 4 11 | #include 12 | 13 | -------------------------------------------------------------------------------- /examples/readme.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | See `sample.go` for basic usage. 4 | 5 | To run the example: 6 | 7 | ```shell 8 | go run examples/sample.go 9 | ``` 10 | 11 | Alternatively, run the example in a minimal `golang-alpine` Docker image: 12 | 13 | ```shell 14 | docker image build -f examples/alpine.Dockerfile -t herumi-bls-sample ./ 15 | docker container run herumi-bls-sample 16 | ``` 17 | 18 | -------------------------------------------------------------------------------- /patch/mcl.patch: -------------------------------------------------------------------------------- 1 | --- src/bls/ffi/go/bls/mcl.go 2021-04-28 14:25:51.929725397 +0900 2 | +++ bls/mcl.go 2021-04-28 18:13:51.972947460 +0900 3 | @@ -1,10 +1,8 @@ 4 | package bls 5 | 6 | /* 7 | -#cgo bn256 CFLAGS:-DMCLBN_FP_UNIT_SIZE=4 8 | -#cgo bn384 CFLAGS:-DMCLBN_FP_UNIT_SIZE=6 9 | -#cgo bn384_256 CFLAGS:-DMCLBN_FP_UNIT_SIZE=6 -DMCLBN_FR_UNIT_SIZE=4 10 | -#include 11 | +#cgo CFLAGS:-I./include 12 | +#include 13 | */ 14 | import "C" 15 | import "fmt" 16 | -------------------------------------------------------------------------------- /bls/rand_test.go: -------------------------------------------------------------------------------- 1 | package bls 2 | 3 | import ( 4 | "crypto/rand" 5 | "fmt" 6 | "testing" 7 | ) 8 | 9 | func genSec(t *testing.T) { 10 | var sec SecretKey 11 | for i := 0; i < 10; i++ { 12 | sec.SetByCSPRNG() 13 | fmt.Printf("i=%v sec=%v\n", i, sec) 14 | if sec.IsZero() { 15 | t.Fatal("err") 16 | } 17 | } 18 | } 19 | 20 | func TestRand(t *testing.T) { 21 | Init(BLS12_381) 22 | SetETHmode(EthModeDraft07) 23 | fmt.Printf("default\n") 24 | genSec(t) 25 | fmt.Printf("rand.Reader\n") 26 | SetRandFunc(rand.Reader) 27 | genSec(t) 28 | SetRandFunc(nil) 29 | } 30 | -------------------------------------------------------------------------------- /bls/cast.go: -------------------------------------------------------------------------------- 1 | package bls 2 | 3 | import ( 4 | "unsafe" 5 | ) 6 | 7 | // SecretKey 8 | 9 | func CastFromSecretKey(in *SecretKey) *Fr { 10 | return (*Fr)(unsafe.Pointer(in)) 11 | } 12 | 13 | func CastToSecretKey(in *Fr) *SecretKey { 14 | return (*SecretKey)(unsafe.Pointer(in)) 15 | } 16 | 17 | // PublicKey 18 | 19 | func CastFromPublicKey(in *PublicKey) *G1 { 20 | return (*G1)(unsafe.Pointer(in)) 21 | } 22 | 23 | func CastToPublicKey(in *G1) *PublicKey { 24 | return (*PublicKey)(unsafe.Pointer(in)) 25 | } 26 | 27 | // Sign 28 | 29 | func CastFromSign(in *Sign) *G2 { 30 | return (*G2)(unsafe.Pointer(in)) 31 | } 32 | 33 | func CastToSign(in *G2) *Sign { 34 | return (*Sign)(unsafe.Pointer(in)) 35 | } 36 | -------------------------------------------------------------------------------- /patch/bls.patch: -------------------------------------------------------------------------------- 1 | --- src//bls/ffi/go/bls/bls.go 2023-01-23 17:14:02.857374208 +0900 2 | +++ bls/bls.go 2023-01-23 17:15:35.064970601 +0900 3 | @@ -1,16 +1,10 @@ 4 | package bls 5 | 6 | /* 7 | -#cgo bn256 CFLAGS:-DMCLBN_FP_UNIT_SIZE=4 8 | -#cgo bn256 LDFLAGS:-lbls256 9 | -#cgo bn384 CFLAGS:-DMCLBN_FP_UNIT_SIZE=6 10 | -#cgo bn384 LDFLAGS:-lbls384 11 | -#cgo bn384_256 CFLAGS:-DMCLBN_FP_UNIT_SIZE=6 -DMCLBN_FR_UNIT_SIZE=4 12 | -#cgo bn384_256 LDFLAGS:-lbls384_256 13 | - 14 | -#cgo LDFLAGS:-lstdc++ 15 | +#cgo CFLAGS:-I${SRCDIR}./include -DBLS_ETH 16 | typedef unsigned int (*ReadRandFunc)(void *, void *, unsigned int); 17 | int wrapReadRandCgo(void *self, void *buf, unsigned int n); 18 | +#include 19 | #include 20 | */ 21 | import "C" 22 | @@ -22,7 +16,7 @@ import ( 23 | "unsafe" 24 | ) 25 | 26 | -const ethMode = false 27 | +const ethMode = true 28 | 29 | const EthModeOld = C.BLS_ETH_MODE_OLD 30 | const EthModeDraft05 = C.BLS_ETH_MODE_DRAFT_05 31 | -------------------------------------------------------------------------------- /bls/link.go: -------------------------------------------------------------------------------- 1 | //go:build !ios 2 | // +build !ios 3 | 4 | package bls 5 | 6 | /* 7 | #cgo LDFLAGS:-lbls384_256 -lm 8 | #cgo android,arm64 LDFLAGS:-L${SRCDIR}/lib/android/arm64-v8a 9 | #cgo android,arm LDFLAGS:-L${SRCDIR}/lib/android/armeabi-v7a 10 | #cgo android,amd64 LDFLAGS:-L${SRCDIR}/lib/android/x86_64 -lstdc++ 11 | #cgo linux,amd64 LDFLAGS:-L${SRCDIR}/lib/linux/amd64 12 | #cgo linux,arm64 LDFLAGS:-L${SRCDIR}/lib/linux/arm64 13 | #cgo linux,mipsle LDFLAGS:-L${SRCDIR}/lib/linux/mipsel 14 | #cgo linux,arm LDFLAGS:-L${SRCDIR}/lib/linux/arm 15 | #cgo linux,s390x LDFLAGS:-L${SRCDIR}/lib/linux/s390x 16 | #cgo linux,riscv64 LDFLAGS:-L${SRCDIR}/lib/linux/riscv64 17 | #cgo darwin,amd64 LDFLAGS:-L${SRCDIR}/lib/darwin/amd64 18 | #cgo darwin,arm64 LDFLAGS:-L${SRCDIR}/lib/darwin/arm64 19 | #cgo windows,amd64 LDFLAGS:-L${SRCDIR}/lib/windows/amd64 -lstdc++ 20 | #cgo openbsd,amd64 LDFLAGS:-L${SRCDIR}/lib/openbsd/amd64 21 | #cgo freebsd,amd64 LDFLAGS:-L${SRCDIR}/lib/freebsd/amd64 22 | */ 23 | import "C" 24 | -------------------------------------------------------------------------------- /setup_vendor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # setup vendor script 3 | 4 | set -e 5 | 6 | if [ -f "$(dirname "$0")/ETH.cfg" ]; then 7 | MODULE_NAME="bls-eth-go-binary" 8 | echo "github.com/herumi/${MODULE_NAME}" 9 | else 10 | MODULE_NAME="bls-go-binary" 11 | echo "ETH.cfg not found, using module: github.com/herumi/${MODULE_NAME}" 12 | fi 13 | 14 | MODULE="github.com/herumi/${MODULE_NAME}" 15 | echo "module : ${MODULE_NAME}" 16 | 17 | if [ $# -ge 1 ]; then 18 | VERSION="$1" 19 | echo "Using specified version: ${VERSION}" 20 | else 21 | VERSION=$(go list -m -f '{{.Version}}' ${MODULE}) 22 | fi 23 | 24 | if [ -z "$VERSION" ]; then 25 | echo "Error: Could not determine module version. Please add the module to go.mod or specify version as argument." 26 | echo "Usage: $0 [version]" 27 | echo "Example: $0 v1.36.4" 28 | exit 1 29 | fi 30 | 31 | GOPATH=$(go env GOPATH) 32 | MODULE_PATH="${GOPATH}/pkg/mod/${MODULE}@${VERSION}" 33 | 34 | go mod vendor 35 | 36 | mkdir -p vendor/${MODULE}/bls/include 37 | mkdir -p vendor/${MODULE}/bls/lib/ 38 | 39 | cp -r "${MODULE_PATH}/bls/include/" "vendor/${MODULE}/bls/" 40 | cp -r "${MODULE_PATH}/bls/lib/" "vendor/${MODULE}/bls/" 41 | 42 | -------------------------------------------------------------------------------- /bls/tests/aggregate_verify.txt: -------------------------------------------------------------------------------- 1 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 2 | pub b301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81 3 | pub b53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f 4 | msg 0000000000000000000000000000000000000000000000000000000000000000 5 | msg 5656565656565656565656565656565656565656565656565656565656565656 6 | msg abababababababababababababababababababababababababababababababab 7 | sig 9104e74bffffffff 8 | out false 9 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 10 | pub b301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81 11 | pub b53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f 12 | msg 0000000000000000000000000000000000000000000000000000000000000000 13 | msg 5656565656565656565656565656565656565656565656565656565656565656 14 | msg abababababababababababababababababababababababababababababababab 15 | sig 9104e74b9dfd3ad502f25d6a5ef57db0ed7d9a0e00f3500586d8ce44231212542fcfaf87840539b398bf07626705cf1105d246ca1062c6c2e1a53029a0f790ed5e3cb1f52f8234dc5144c45fc847c0cd37a92d68e7c5ba7c648a8a339f171244 16 | out true 17 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | on: [push] 3 | 4 | jobs: 5 | Run-on-ubuntu: 6 | name: Run on ubuntu 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 10 | - uses: actions/setup-go@v5 11 | with: 12 | go-version: '1.22.x' 13 | - run: | 14 | git submodule update --init --recursive 15 | sudo apt update 16 | sudo apt install -y nasm 17 | make clean 18 | make CXX=clang++ 19 | go test -v ./bls 20 | 21 | Run-on-Intel-macos: 22 | name: Run on Intel macos 23 | runs-on: macos-15 24 | steps: 25 | - uses: actions/checkout@v4 26 | - uses: actions/setup-go@v5 27 | with: 28 | go-version: '1.22.x' 29 | - run: | 30 | git submodule update --init --recursive 31 | brew install nasm 32 | make clean 33 | make 34 | go test -v ./bls 35 | 36 | Run-on-ARM-macos: 37 | name: Run on macos 38 | # Intel Mac 39 | runs-on: macos-latest 40 | steps: 41 | - uses: actions/checkout@v4 42 | - uses: actions/setup-go@v5 43 | with: 44 | go-version: '1.22.x' 45 | - run: | 46 | git submodule update --init --recursive 47 | make clean 48 | make 49 | go test -v ./bls 50 | 51 | # For some reason, the ar command fails, so disable this action 52 | # Run-on-windows: 53 | # name: Run on windows 54 | # runs-on: windows-latest 55 | # steps: 56 | # - uses: actions/checkout@v4 57 | # - uses: msys2/setup-msys2@v2 58 | # with: 59 | # msystem: MINGW64 60 | # update: true 61 | # platform-check-severity: warn 62 | # install: >- 63 | # make 64 | # python3 65 | # mingw-w64-x86_64-gcc 66 | # mingw-w64-x86_64-go 67 | # - run: | 68 | # git submodule update --init --recursive 69 | # make clean 70 | # make 71 | # go test -v ./bls 72 | -------------------------------------------------------------------------------- /examples/sample.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/hex" 5 | "fmt" 6 | "github.com/herumi/bls-eth-go-binary/bls" 7 | ) 8 | 9 | func sample1() { 10 | fmt.Printf("sample1\n") 11 | var sec bls.SecretKey 12 | sec.SetByCSPRNG() 13 | msg := []byte("abc") 14 | pub := sec.GetPublicKey() 15 | sig := sec.SignByte(msg) 16 | fmt.Printf("verify=%v\n", sig.VerifyByte(pub, msg)) 17 | } 18 | 19 | func sample2() { 20 | fmt.Printf("sample2\n") 21 | var sec bls.SecretKey 22 | sec.SetByCSPRNG() 23 | fmt.Printf("sec:%s\n", sec.SerializeToHexStr()) 24 | pub := sec.GetPublicKey() 25 | fmt.Printf("1.pub:%s\n", pub.SerializeToHexStr()) 26 | fmt.Printf("1.pub x=%x\n", pub) 27 | var P *bls.G1 = bls.CastFromPublicKey(pub) 28 | bls.G1Normalize(P, P) 29 | fmt.Printf("2.pub:%s\n", pub.SerializeToHexStr()) 30 | fmt.Printf("2.pub x=%x\n", pub) 31 | fmt.Printf("P.X=%x\n", P.X.Serialize()) 32 | fmt.Printf("P.Y=%x\n", P.Y.Serialize()) 33 | fmt.Printf("P.Z=%x\n", P.Z.Serialize()) 34 | } 35 | 36 | func sample3() { 37 | fmt.Printf("sample3\n") 38 | var sec bls.SecretKey 39 | b := make([]byte, 64) 40 | for i := 0; i < len(b); i++ { 41 | b[i] = 0xff 42 | } 43 | err := sec.SetLittleEndianMod(b) 44 | if err != nil { 45 | fmt.Printf("err") 46 | return 47 | } 48 | fmt.Printf("sec=%x\n", sec.Serialize()) 49 | } 50 | 51 | func sample4() { 52 | fmt.Printf("sample4\n") 53 | var sec bls.SecretKey 54 | secByte, _ := hex.DecodeString("4aac41b5cb665b93e031faa751944b1f14d77cb17322403cba8df1d6e4541a4d") 55 | sec.Deserialize(secByte) 56 | msg := []byte("message to be signed.") 57 | fmt.Printf("sec:%x\n", sec.Serialize()) 58 | pub := sec.GetPublicKey() 59 | fmt.Printf("pub:%x\n", pub.Serialize()) 60 | sig := sec.SignByte(msg) 61 | fmt.Printf("sig:%x\n", sig.Serialize()) 62 | } 63 | 64 | func main() { 65 | bls.Init(bls.BLS12_381) 66 | bls.SetETHmode(bls.EthModeDraft07) 67 | sample1() 68 | sample2() 69 | sample3() 70 | sample4() 71 | } 72 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | -include ETH.cfg 2 | ARCH?=$(shell uname -m) 3 | SRC_DIR?=src/ 4 | BLS_DIR?=$(SRC_DIR)/bls 5 | MCL_DIR?=$(BLS_DIR)/mcl 6 | all: 7 | $(MAKE) -f $(BLS_DIR)/Makefile.onelib BLS_DIR=$(BLS_DIR) MCL_DIR=$(MCL_DIR) OUT_DIR=$(shell pwd) ARCH=$(ARCH) ETH_CFLAGS=$(ETH_CFLAGS) all 8 | ios: 9 | $(MAKE) -f $(BLS_DIR)/Makefile.onelib BLS_DIR=$(BLS_DIR) MCL_DIR=$(MCL_DIR) OUT_DIR=$(shell pwd) ETH_CFLAGS=$(ETH_CFLAGS) ios 10 | ios_simulator: 11 | $(MAKE) -f $(BLS_DIR)/Makefile.onelib BLS_DIR=$(BLS_DIR) MCL_DIR=$(MCL_DIR) OUT_DIR=$(shell pwd) ETH_CFLAGS=$(ETH_CFLAGS) ios_simulator 12 | 13 | aarch64: # for cross compile on x64-linux 14 | $(MAKE) -f $(BLS_DIR)/Makefile.onelib BLS_DIR=$(BLS_DIR) MCL_DIR=$(MCL_DIR) OUT_DIR=$(shell pwd) ETH_CFLAGS=$(ETH_CFLAGS) build_aarch64 CXX=clang++ 15 | riscv64: # for cross compile on x64-linux 16 | $(MAKE) -f $(BLS_DIR)/Makefile.onelib BLS_DIR=$(BLS_DIR) MCL_DIR=$(MCL_DIR) OUT_DIR=$(shell pwd) ETH_CFLAGS=$(ETH_CFLAGS) build_riscv64 CXX=clang++ 17 | 18 | NDK_BUILD?=ndk-build 19 | android: 20 | $(MAKE) -f $(BLS_DIR)/Makefile.onelib BLS_DIR=$(BLS_DIR) MCL_DIR=$(MCL_DIR) OUT_DIR=$(shell pwd) ETH_CFLAGS=$(ETH_CFLAGS) NDK_BUILD=$(NDK_BUILD) BLS_LIB_SHARED=$(BLS_LIB_SHARED) android 21 | 22 | update: 23 | cp $(BLS_DIR)/include/bls/bls.h bls/include/bls/. 24 | cp $(BLS_DIR)/include/bls/bls384_256.h bls/include/bls/. 25 | cp $(MCL_DIR)/include/mcl/bn.h bls/include/mcl/. 26 | cp $(MCL_DIR)/include/mcl/bn_c384_256.h bls/include/mcl/. 27 | cp $(MCL_DIR)/include/mcl/curve_type.h bls/include/mcl/. 28 | patch -o - -p0 ../bls/ffi/go/bls/mcl.go bls/mcl.go 29 | patch -o - -p0 ../bls/ffi/go/bls/bls.go bls/bls.go 30 | 31 | update_patch: 32 | -diff -up $(BLS_DIR)/ffi/go/bls/mcl.go bls/mcl.go > patch/mcl.patch 33 | -diff -up $(BLS_DIR)/ffi/go/bls/bls.go bls/bls.go > patch/bls.patch 34 | 35 | clean: 36 | $(MAKE) -C $(MCL_DIR) clean 37 | $(MAKE) -C $(BLS_DIR) clean 38 | $(RM) -rf obj/*.o android/obj/* bls/lib/android/* 39 | 40 | .PHONY: android ios each_ios clean 41 | -------------------------------------------------------------------------------- /bls/harmony_test.go: -------------------------------------------------------------------------------- 1 | package bls 2 | 3 | import "testing" 4 | import "fmt" 5 | import "encoding/hex" 6 | 7 | func TestHarmony(t *testing.T) { 8 | if Init(BLS12_381) != nil { 9 | t.Fatalf("Init") 10 | } 11 | if SetETHmode(0) != nil { 12 | t.Fatalf("SetMapToMode") 13 | } 14 | SetETHserialization(false) 15 | SetMapToMode(0) 16 | var gen PublicKey 17 | gen.SetHexString("1 4f58f3d9ee829f9a853f80b0e32c2981be883a537f0c21ad4af17be22e6e9959915ec21b7f9d8cc4c7315f31f3600e5 1212110eb10dbc575bccc44dcd77400f38282c4728b5efac69c0b4c9011bd27b8ed608acd81f027039216a291ac636a8") 18 | SetGeneratorOfPublicKey(&gen) 19 | 20 | var sec SecretKey 21 | bytes := []byte{185, 10, 0, 237, 196, 231, 235, 253, 95, 221, 36, 224, 109, 252, 10, 222, 14, 197, 82, 107, 220, 29, 208, 123, 169, 190, 98, 181, 240, 198, 35, 98} 22 | sec.Deserialize(bytes) 23 | sig := sec.SignHash(bytes) 24 | fmt.Printf("sig=%v\n", sig.SerializeToHexStr()) 25 | // assertBool("check sig", byteToHexStr(sig.serialize()).equals("2f4ff940216b2f13d75a231b988cd16ef22b45a4709df3461d9baeebfeaafeb54fad86ea7465212f35ceb0af6fe86b1828cf6de9099cefe233d97e0523ba6c0f5eecf4db71f7b1ae08cd098547946abbd0329fdac14d27102f2a1891e9188a19"));A 26 | 27 | sec.DeserializeHexStr("d243f3f029c188a5b1c4c098f5719cbc967184ef962b5c5d6c72693c92c1f725") 28 | pub := sec.GetPublicKey() 29 | fmt.Printf("pub=%v\n", pub.SerializeToHexStr()) 30 | if pub.SerializeToHexStr() != "15ad529698be1f6164fd50416d1991a04b977d9014b43ae9d014ca50ae634829182632d54c7188b3a53e0b77ae4c9e87" { 31 | t.Errorf("bad pub") 32 | } 33 | msg, _ := hex.DecodeString("1100000000000000000000000000000000000000000000000000000000000031") 34 | sig = sec.SignByte(msg) 35 | if sig.SerializeToHexStr() != "2f2071370054ded61081a069dc657d7111ae909fc08a38ae1f3a967c4e4c1b97b7d2ee8adc512ded7213dc0ab2c9db158451eca54a4db26ec013e108d561d8e0eede883b73074d49143ea8e9291903aabce2a2b4f153f99822e4512dac86ae18" { 36 | t.Errorf("bad sig") 37 | } 38 | sig = sec.SignHash(msg) 39 | if sig.SerializeToHexStr() != "807f6fb074cfdd0318501ef894b127a3f71754745dcff2163dd128091efd065c4ac419e3d7d5428a0b94ada19de657176fb4ccfdb3105f869d6351e503ba20e9d6ef55f179510941db4d131c3678e9d9316090c99bd7d62107d83f6fe5f6f115" { 40 | t.Errorf("bad sig2") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /bls/tests/aggregate.txt: -------------------------------------------------------------------------------- 1 | sig 882730e5d03f6b42c3abc26d3372625034e1d871b65a8a6b900a56dae22da98abbe1b68f85e49fe7652a55ec3d0591c20767677e33e5cbb1207315c41a9ac03be39c2e7668edc043d6cb1d9fd93033caa8a1c5b0e84bedaeb6c64972503a43eb 2 | sig af1390c3c47acdb37131a51216da683c509fce0e954328a59f93aebda7e4ff974ba208d9a4a2a2389f892a9d418d618418dd7f7a6bc7aa0da999a9d3a5b815bc085e14fd001f6a1948768a3f4afefc8b8240dda329f984cb345c6363272ba4fe 3 | sig a4efa926610b8bd1c8330c918b7a5e9bf374e53435ef8b7ec186abf62e1b1f65aeaaeb365677ac1d1172a1f5b44b4e6d022c252c58486c0a759fbdc7de15a756acc4d343064035667a594b4c2a6f0b0b421975977f297dba63ee2f63ffe47bb6 4 | out ad38fc73846583b08d110d16ab1d026c6ea77ac2071e8ae832f56ac0cbcdeb9f5678ba5ce42bd8dce334cc47b5abcba40a58f7f1f80ab304193eb98836cc14d8183ec14cc77de0f80c4ffd49e168927a968b5cdaa4cf46b9805be84ad7efa77b 5 | sig b6ed936746e01f8ecf281f020953fbf1f01debd5657c4a383940b020b26507f6076334f91e2366c96e9ab279fb5158090352ea1c5b0c9274504f4f0e7053af24802e51e4568d164fe986834f41e55c8e850ce1f98458c0cfc9ab380b55285a55 6 | sig b23c46be3a001c63ca711f87a005c200cc550b9429d5f4eb38d74322144f1b63926da3388979e5321012fb1a0526bcd100b5ef5fe72628ce4cd5e904aeaa3279527843fae5ca9ca675f4f51ed8f83bbf7155da9ecc9663100a885d5dc6df96d9 7 | sig 948a7cb99f76d616c2c564ce9bf4a519f1bea6b0a624a02276443c245854219fabb8d4ce061d255af5330b078d5380681751aa7053da2c98bae898edc218c75f07e24d8802a17cd1f6833b71e58f5eb5b94208b4d0bb3848cecb075ea21be115 8 | out 9683b3e6701f9a4b706709577963110043af78a5b41991b998475a3d3fd62abf35ce03b33908418efc95a058494a8ae504354b9f626231f6b3f3c849dfdeaf5017c4780e2aee1850ceaf4b4d9ce70971a3d2cfcd97b7e5ecf6759f8da5f76d31 9 | sig 91347bccf740d859038fcdcaf233eeceb2a436bcaaee9b2aa3bfb70efe29dfb2677562ccbea1c8e061fb9971b0753c240622fab78489ce96768259fc01360346da5b9f579e5da0d941e4c6ba18a0e64906082375394f337fa1af2b7127b0d121 10 | sig 9674e2228034527f4c083206032b020310face156d4a4685e2fcaec2f6f3665aa635d90347b6ce124eb879266b1e801d185de36a0a289b85e9039662634f2eea1e02e670bc7ab849d006a70b2f93b84597558a05b879c8d445f387a5d5b653df 11 | sig ae82747ddeefe4fd64cf9cedb9b04ae3e8a43420cd255e3c7cd06a8d88b7c7f8638543719981c5d16fa3527c468c25f0026704a6951bde891360c7e8d12ddee0559004ccdbe6046b55bae1b257ee97f7cdb955773d7cf29adf3ccbb9975e4eb9 12 | out 9712c3edd73a209c742b8250759db12549b3eaf43b5ca61376d9f30e2747dbcf842d8b2ac0901d2a093713e20284a7670fcf6954e9ab93de991bb9b313e664785a075fc285806fa5224c82bde146561b446ccfc706a64b8579513cfc4ff1d930 13 | -------------------------------------------------------------------------------- /bls/tests/sign.txt: -------------------------------------------------------------------------------- 1 | sec 328388aff0d4a5b7dc9205abd374e7e98f3cd9f3418edb4eafda5fb16473d216 2 | msg abababababababababababababababababababababababababababababababab 3 | out ae82747ddeefe4fd64cf9cedb9b04ae3e8a43420cd255e3c7cd06a8d88b7c7f8638543719981c5d16fa3527c468c25f0026704a6951bde891360c7e8d12ddee0559004ccdbe6046b55bae1b257ee97f7cdb955773d7cf29adf3ccbb9975e4eb9 4 | sec 47b8192d77bf871b62e87859d653922725724a5c031afeabc60bcef5ff665138 5 | msg abababababababababababababababababababababababababababababababab 6 | out 9674e2228034527f4c083206032b020310face156d4a4685e2fcaec2f6f3665aa635d90347b6ce124eb879266b1e801d185de36a0a289b85e9039662634f2eea1e02e670bc7ab849d006a70b2f93b84597558a05b879c8d445f387a5d5b653df 7 | sec 328388aff0d4a5b7dc9205abd374e7e98f3cd9f3418edb4eafda5fb16473d216 8 | msg 5656565656565656565656565656565656565656565656565656565656565656 9 | out a4efa926610b8bd1c8330c918b7a5e9bf374e53435ef8b7ec186abf62e1b1f65aeaaeb365677ac1d1172a1f5b44b4e6d022c252c58486c0a759fbdc7de15a756acc4d343064035667a594b4c2a6f0b0b421975977f297dba63ee2f63ffe47bb6 10 | sec 47b8192d77bf871b62e87859d653922725724a5c031afeabc60bcef5ff665138 11 | msg 5656565656565656565656565656565656565656565656565656565656565656 12 | out af1390c3c47acdb37131a51216da683c509fce0e954328a59f93aebda7e4ff974ba208d9a4a2a2389f892a9d418d618418dd7f7a6bc7aa0da999a9d3a5b815bc085e14fd001f6a1948768a3f4afefc8b8240dda329f984cb345c6363272ba4fe 13 | sec 263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e3 14 | msg 0000000000000000000000000000000000000000000000000000000000000000 15 | out b6ed936746e01f8ecf281f020953fbf1f01debd5657c4a383940b020b26507f6076334f91e2366c96e9ab279fb5158090352ea1c5b0c9274504f4f0e7053af24802e51e4568d164fe986834f41e55c8e850ce1f98458c0cfc9ab380b55285a55 16 | sec 47b8192d77bf871b62e87859d653922725724a5c031afeabc60bcef5ff665138 17 | msg 0000000000000000000000000000000000000000000000000000000000000000 18 | out b23c46be3a001c63ca711f87a005c200cc550b9429d5f4eb38d74322144f1b63926da3388979e5321012fb1a0526bcd100b5ef5fe72628ce4cd5e904aeaa3279527843fae5ca9ca675f4f51ed8f83bbf7155da9ecc9663100a885d5dc6df96d9 19 | sec 328388aff0d4a5b7dc9205abd374e7e98f3cd9f3418edb4eafda5fb16473d216 20 | msg 0000000000000000000000000000000000000000000000000000000000000000 21 | out 948a7cb99f76d616c2c564ce9bf4a519f1bea6b0a624a02276443c245854219fabb8d4ce061d255af5330b078d5380681751aa7053da2c98bae898edc218c75f07e24d8802a17cd1f6833b71e58f5eb5b94208b4d0bb3848cecb075ea21be115 22 | sec 263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e3 23 | msg abababababababababababababababababababababababababababababababab 24 | out 91347bccf740d859038fcdcaf233eeceb2a436bcaaee9b2aa3bfb70efe29dfb2677562ccbea1c8e061fb9971b0753c240622fab78489ce96768259fc01360346da5b9f579e5da0d941e4c6ba18a0e64906082375394f337fa1af2b7127b0d121 25 | sec 263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e3 26 | msg 5656565656565656565656565656565656565656565656565656565656565656 27 | out 882730e5d03f6b42c3abc26d3372625034e1d871b65a8a6b900a56dae22da98abbe1b68f85e49fe7652a55ec3d0591c20767677e33e5cbb1207315c41a9ac03be39c2e7668edc043d6cb1d9fd93033caa8a1c5b0e84bedaeb6c64972503a43eb 28 | -------------------------------------------------------------------------------- /bls/include/mcl/curve_type.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /** 3 | @file 4 | @brief curve type 5 | @author MITSUNARI Shigeo(@herumi) 6 | @license modified new BSD license 7 | http://opensource.org/licenses/BSD-3-Clause 8 | */ 9 | 10 | enum { 11 | MCL_BN254 = 0, 12 | MCL_BN381_1 = 1, 13 | MCL_BN381_2 = 2, 14 | MCL_BN462 = 3, 15 | MCL_BN_SNARK1 = 4, 16 | MCL_BLS12_381 = 5, 17 | MCL_BN160 = 6, 18 | MCL_BLS12_461 = 7, 19 | MCL_BLS12_377 = 8, 20 | MCL_BN_P256 = 9, 21 | 22 | /* 23 | for only G1 24 | the size of curve must be <= MCLBN_FP_UNIT_SIZE 25 | */ 26 | MCL_EC_BEGIN = 100, 27 | MCL_SECP192K1 = MCL_EC_BEGIN, 28 | MCL_SECP224K1 = 101, 29 | MCL_SECP256K1 = 102, 30 | MCL_SECP384R1 = 103, 31 | MCL_SECP521R1 = 104, 32 | MCL_NIST_P192 = 105, 33 | MCL_NIST_P224 = 106, 34 | MCL_NIST_P256 = 107, 35 | MCL_SECP160K1 = 108, 36 | MCL_P160_1 = 109, 37 | MCL_EC_END = MCL_P160_1 + 1, 38 | MCL_NIST_P384 = MCL_SECP384R1, 39 | MCL_NIST_P521 = MCL_SECP521R1 40 | }; 41 | 42 | /* 43 | remark : if irtf-cfrg-hash-to-curve is compeletely fixed, then 44 | MCL_MAP_TO_MODE_WB19, MCL_MAP_TO_MODE_HASH_TO_CURVE_0? will be removed and 45 | only MCL_MAP_TO_MODE_HASH_TO_CURVE will be available. 46 | */ 47 | enum { 48 | MCL_MAP_TO_MODE_ORIGINAL, // see MapTo::calcBN 49 | MCL_MAP_TO_MODE_TRY_AND_INC, // try-and-incremental-x 50 | MCL_MAP_TO_MODE_ETH2, // (deprecated) old eth2.0 spec 51 | MCL_MAP_TO_MODE_WB19, // (deprecated) used in new eth2.0 spec 52 | MCL_MAP_TO_MODE_HASH_TO_CURVE_05 = MCL_MAP_TO_MODE_WB19, // (deprecated) draft-irtf-cfrg-hash-to-curve-05 53 | MCL_MAP_TO_MODE_HASH_TO_CURVE_06, // (deprecated) draft-irtf-cfrg-hash-to-curve-06 54 | MCL_MAP_TO_MODE_HASH_TO_CURVE_07 = 5, /* don't change this value! */ // draft-irtf-cfrg-hash-to-curve-07 55 | MCL_MAP_TO_MODE_HASH_TO_CURVE = MCL_MAP_TO_MODE_HASH_TO_CURVE_07, // the latset version 56 | MCL_MAP_TO_MODE_ETH2_LEGACY // backwards compatible version of MCL_MAP_TO_MODE_ETH2 with commit 730c50d4eaff1e0d685a92ac8c896e873749471b 57 | }; 58 | 59 | #ifdef __cplusplus 60 | 61 | #include 62 | #include 63 | 64 | namespace mcl { 65 | 66 | struct CurveParam { 67 | /* 68 | y^2 = x^3 + b 69 | i^2 = -1 70 | xi = xi_a + i 71 | v^3 = xi 72 | w^2 = v 73 | */ 74 | const char *z; 75 | int b; // y^2 = x^3 + b 76 | int xi_a; // xi = xi_a + i 77 | /* 78 | BN254, BN381, BLS12_377 : Dtype 79 | BLS12-381, BN_P256 : Mtype 80 | */ 81 | bool isMtype; 82 | int curveType; // same in curve_type.h 83 | bool operator==(const CurveParam& rhs) const 84 | { 85 | return strcmp(z, rhs.z) == 0 && b == rhs.b && xi_a == rhs.xi_a && isMtype == rhs.isMtype; 86 | } 87 | bool operator!=(const CurveParam& rhs) const { return !operator==(rhs); } 88 | }; 89 | 90 | const CurveParam BN254 = { "-0x4080000000000001", 2, 1, false, MCL_BN254 }; // -(2^62 + 2^55 + 1) 91 | const CurveParam BN_P256 = { "-0x6882f5c030b0a801", 3, 1, true, MCL_BN_P256 }; // BN P256 defined in TCG Algorithm Registry Family "2.0", Revision 1.32 92 | // provisional(experimental) param with maxBitSize = 384 93 | const CurveParam BN381_1 = { "-0x400011000000000000000001", 2, 1, false, MCL_BN381_1 }; // -(2^94 + 2^76 + 2^72 + 1) // A Family of Implementation-Friendly BN Elliptic Curves 94 | const CurveParam BN381_2 = { "-0x400040090001000000000001", 2, 1, false, MCL_BN381_2 }; // -(2^94 + 2^78 + 2^67 + 2^64 + 2^48 + 1) // used in relic-toolkit 95 | const CurveParam BN462 = { "0x4001fffffffffffffffffffffbfff", 5, 2, false, MCL_BN462 }; // 2^114 + 2^101 - 2^14 - 1 // https://eprint.iacr.org/2017/334 96 | const CurveParam BN_SNARK1 = { "4965661367192848881", 3, 9, false, MCL_BN_SNARK1 }; 97 | const CurveParam BLS12_381 = { "-0xd201000000010000", 4, 1, true, MCL_BLS12_381 }; 98 | const CurveParam BN160 = { "0x4000000031", 3, 4, false, MCL_BN160 }; 99 | const CurveParam BLS12_461 = { "-0x1ffffffbfffe00000000", 4, 1, true, MCL_BLS12_461 }; 100 | // QQQ BLS12_377 is under construction 101 | const CurveParam BLS12_377 = { "0x8508c00000000001", 1, 0, false, MCL_BLS12_377 }; // not supported yet 102 | 103 | #ifdef __clang__ 104 | #pragma GCC diagnostic push 105 | #pragma GCC diagnostic ignored "-Wreturn-type-c-linkage" 106 | #endif 107 | inline const CurveParam* getCurveParam(int type) 108 | { 109 | switch (type) { 110 | case MCL_BN254: return &mcl::BN254; 111 | case MCL_BN_P256: return &mcl::BN_P256; 112 | case MCL_BN381_1: return &mcl::BN381_1; 113 | case MCL_BN381_2: return &mcl::BN381_2; 114 | case MCL_BN462: return &mcl::BN462; 115 | case MCL_BN_SNARK1: return &mcl::BN_SNARK1; 116 | case MCL_BLS12_381: return &mcl::BLS12_381; 117 | case MCL_BN160: return &mcl::BN160; 118 | default: 119 | return 0; 120 | } 121 | } 122 | #ifdef __clang__ 123 | #pragma GCC diagnostic pop 124 | #endif 125 | 126 | } // mcl 127 | #endif 128 | -------------------------------------------------------------------------------- /bls/tests/fast_aggregate_verify.txt: -------------------------------------------------------------------------------- 1 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 2 | pub b301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81 3 | pub b53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f 4 | msg abababababababababababababababababababababababababababababababab 5 | sig 9712c3edd73a209c742b8250759db12549b3eaf43b5ca61376d9f30e2747dbcf842d8b2ac0901d2a093713e20284a7670fcf6954e9ab93de991bb9b313e664785a075fc285806fa5224c82bde146561b446ccfc706a64b8579513cfcffffffff 6 | out false 7 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 8 | pub b301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81 9 | msg 5656565656565656565656565656565656565656565656565656565656565656 10 | sig 912c3615f69575407db9392eb21fee18fff797eeb2fbe1816366ca2a08ae574d8824dbfafb4c9eaa1cf61b63c6f9b69911f269b664c42947dd1b53ef1081926c1e82bb2a465f927124b08391a5249036146d6f3f1e17ff5f162f7797ffffffff 11 | out false 12 | msg abababababababababababababababababababababababababababababababab 13 | sig c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 14 | out false 15 | msg abababababababababababababababababababababababababababababababab 16 | sig 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 17 | out false 18 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 19 | msg 0000000000000000000000000000000000000000000000000000000000000000 20 | sig b6ed936746e01f8ecf281f020953fbf1f01debd5657c4a383940b020b26507f6076334f91e2366c96e9ab279fb5158090352ea1c5b0c9274504f4f0e7053af24802e51e4568d164fe986834f41e55c8e850ce1f98458c0cfc9ab380b55285a55 21 | out true 22 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 23 | pub b301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81 24 | msg 5656565656565656565656565656565656565656565656565656565656565656 25 | sig 912c3615f69575407db9392eb21fee18fff797eeb2fbe1816366ca2a08ae574d8824dbfafb4c9eaa1cf61b63c6f9b69911f269b664c42947dd1b53ef1081926c1e82bb2a465f927124b08391a5249036146d6f3f1e17ff5f162f779746d830d1 26 | out true 27 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 28 | pub b301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81 29 | pub b53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f 30 | pub b53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f 31 | msg abababababababababababababababababababababababababababababababab 32 | sig 9712c3edd73a209c742b8250759db12549b3eaf43b5ca61376d9f30e2747dbcf842d8b2ac0901d2a093713e20284a7670fcf6954e9ab93de991bb9b313e664785a075fc285806fa5224c82bde146561b446ccfc706a64b8579513cfc4ff1d930 33 | out false 34 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 35 | pub b301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81 36 | pub b53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f 37 | msg abababababababababababababababababababababababababababababababab 38 | sig 9712c3edd73a209c742b8250759db12549b3eaf43b5ca61376d9f30e2747dbcf842d8b2ac0901d2a093713e20284a7670fcf6954e9ab93de991bb9b313e664785a075fc285806fa5224c82bde146561b446ccfc706a64b8579513cfc4ff1d930 39 | out true 40 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 41 | msg 0000000000000000000000000000000000000000000000000000000000000000 42 | sig b6ed936746e01f8ecf281f020953fbf1f01debd5657c4a383940b020b26507f6076334f91e2366c96e9ab279fb5158090352ea1c5b0c9274504f4f0e7053af24802e51e4568d164fe986834f41e55c8e850ce1f98458c0cfc9ab380bffffffff 43 | out false 44 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 45 | pub b301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81 46 | pub b53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f 47 | msg 5656565656565656565656565656565656565656565656565656565656565656 48 | sig 912c3615f69575407db9392eb21fee18fff797eeb2fbe1816366ca2a08ae574d8824dbfafb4c9eaa1cf61b63c6f9b69911f269b664c42947dd1b53ef1081926c1e82bb2a465f927124b08391a5249036146d6f3f1e17ff5f162f779746d830d1 49 | out false 50 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 51 | pub b53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f 52 | msg 0000000000000000000000000000000000000000000000000000000000000000 53 | sig b6ed936746e01f8ecf281f020953fbf1f01debd5657c4a383940b020b26507f6076334f91e2366c96e9ab279fb5158090352ea1c5b0c9274504f4f0e7053af24802e51e4568d164fe986834f41e55c8e850ce1f98458c0cfc9ab380b55285a55 54 | out false 55 | -------------------------------------------------------------------------------- /bls/eth.go: -------------------------------------------------------------------------------- 1 | package bls 2 | 3 | /* 4 | #cgo CFLAGS:-I${SRCDIR}./include -DBLS_ETH 5 | #include 6 | #include 7 | */ 8 | import "C" 9 | import ( 10 | "crypto/rand" 11 | "fmt" 12 | "runtime" 13 | "unsafe" 14 | ) 15 | 16 | // MultiVerify -- 17 | // true if all (sigs[i], pubs[i], concatenatedMsg[msgSize*i:msgSize*(i+1)]) are valid 18 | // concatenatedMsg has the size of len(sigs) * 32 19 | func MultiVerify(sigs []Sign, pubs []PublicKey, concatenatedMsg []byte) bool { 20 | msgSize := 32 21 | randSize := 8 22 | threadN := runtime.NumCPU() 23 | n := len(sigs) 24 | if n == 0 || len(pubs) != n || len(concatenatedMsg) != n*msgSize { 25 | return false 26 | } 27 | randVec := make([]byte, n*randSize) 28 | rand.Read(randVec) 29 | 30 | var e C.mclBnGT 31 | var aggSig Sign 32 | msg := uintptr(unsafe.Pointer(&concatenatedMsg[0])) 33 | rp := uintptr(unsafe.Pointer(&randVec[0])) 34 | 35 | maxThreadN := 32 36 | if threadN > maxThreadN { 37 | threadN = maxThreadN 38 | } 39 | minN := 16 40 | if threadN > 1 && n >= minN { 41 | et := make([]C.mclBnGT, threadN) 42 | aggSigt := make([]Sign, threadN) 43 | blockN := n / minN 44 | q := blockN / threadN 45 | r := blockN % threadN 46 | cs := make(chan int, threadN) 47 | sub := func(i int, sigs []Sign, pubs []PublicKey, msg uintptr, rp uintptr, m int) { 48 | C.blsMultiVerifySub(&et[i], &aggSigt[i].v, &sigs[0].v, &pubs[0].v, (*C.char)(unsafe.Pointer(msg)), C.mclSize(msgSize), (*C.char)(unsafe.Pointer(rp)), C.mclSize(randSize), C.mclSize(m)) 49 | cs <- 1 50 | } 51 | for i := 0; i < threadN; i++ { 52 | m := q 53 | if r > 0 { 54 | m++ 55 | r-- 56 | } 57 | if m == 0 { 58 | threadN = i // n is too small for threadN 59 | break 60 | } 61 | m *= minN 62 | if i == threadN-1 { 63 | m = n // remain all 64 | } 65 | // C.blsMultiVerifySub(&et[i], &aggSigt[i].v, &sigs[0].v, &pubs[0].v, (*C.char)(unsafe.Pointer(msg)), C.mclSize(msgSize), (*C.char)(unsafe.Pointer(rp)), C.mclSize(randSize), C.mclSize(m)) 66 | go sub(i, sigs, pubs, msg, rp, m) 67 | sigs = sigs[m:] 68 | pubs = pubs[m:] 69 | msg += uintptr(msgSize * m) 70 | rp += uintptr(randSize * m) 71 | n -= m 72 | } 73 | for i := 0; i < threadN; i++ { 74 | <-cs 75 | } 76 | e = et[0] 77 | aggSig = aggSigt[0] 78 | for i := 1; i < threadN; i++ { 79 | C.mclBnGT_mul(&e, &e, &et[i]) 80 | aggSig.Add(&aggSigt[i]) 81 | } 82 | } else { 83 | C.blsMultiVerifySub(&e, &aggSig.v, &sigs[0].v, &pubs[0].v, (*C.char)(unsafe.Pointer(msg)), C.mclSize(msgSize), (*C.char)(unsafe.Pointer(rp)), C.mclSize(randSize), C.mclSize(n)) 84 | } 85 | return C.blsMultiVerifyFinal(&e, &aggSig.v) == 1 86 | } 87 | 88 | // SerializeUncompressed -- 89 | func (pub *PublicKey) SerializeUncompressed() []byte { 90 | buf := make([]byte, 96) 91 | // #nosec 92 | n := C.blsPublicKeySerializeUncompressed(unsafe.Pointer(&buf[0]), C.mclSize(len(buf)), &pub.v) 93 | if n == 0 { 94 | panic("err blsPublicKeySerializeUncompressed") 95 | } 96 | return buf[:n] 97 | } 98 | 99 | // SerializeUncompressed -- 100 | func (sig *Sign) SerializeUncompressed() []byte { 101 | buf := make([]byte, 192) 102 | // #nosec 103 | n := C.blsSignatureSerializeUncompressed(unsafe.Pointer(&buf[0]), C.mclSize(len(buf)), &sig.v) 104 | if n == 0 { 105 | panic("err blsSignatureSerializeUncompressed") 106 | } 107 | return buf[:n] 108 | } 109 | 110 | // DeserializeUncompressed -- 111 | func (pub *PublicKey) DeserializeUncompressed(buf []byte) error { 112 | // #nosec 113 | err := C.blsPublicKeyDeserializeUncompressed(&pub.v, unsafe.Pointer(&buf[0]), C.mclSize(len(buf))) 114 | if err == 0 { 115 | return fmt.Errorf("err blsPublicKeyDeserializeUncompressed %x", buf) 116 | } 117 | return nil 118 | } 119 | 120 | // DeserializeUncompressed -- 121 | func (sig *Sign) DeserializeUncompressed(buf []byte) error { 122 | // #nosec 123 | err := C.blsSignatureDeserializeUncompressed(&sig.v, unsafe.Pointer(&buf[0]), C.mclSize(len(buf))) 124 | if err == 0 { 125 | return fmt.Errorf("err blsSignatureDeserializeUncompressed %x", buf) 126 | } 127 | return nil 128 | } 129 | 130 | // AreAllMsgDifferent checks the given message slice to ensure that each 32 byte segment is unique. 131 | func AreAllMsgDifferent(msgVec []byte) bool { 132 | const MSG_SIZE = 32 133 | n := len(msgVec) / MSG_SIZE 134 | if n*MSG_SIZE != len(msgVec) { 135 | return false 136 | } 137 | set := make(map[[MSG_SIZE]byte]struct{}, n) 138 | msg := [MSG_SIZE]byte{} 139 | for i := 0; i < n; i++ { 140 | // one copy can be reduced by unsafe.Pointer 141 | // msg := *(*[MSG_SIZE]byte)(unsafe.Pointer(&msgVec[i*MSG_SIZE : (i+1)*MSG_SIZE][0])) 142 | copy(msg[:], msgVec[i*MSG_SIZE:(i+1)*MSG_SIZE]) 143 | _, ok := set[msg] 144 | if ok { 145 | return false 146 | } 147 | set[msg] = struct{}{} 148 | } 149 | return true 150 | } 151 | 152 | func (sig *Sign) innerAggregateVerify(pubVec []PublicKey, msgVec []byte, checkMessage bool) bool { 153 | const MSG_SIZE = 32 154 | n := len(pubVec) 155 | if n == 0 || len(msgVec) != MSG_SIZE*n { 156 | return false 157 | } 158 | if checkMessage && !AreAllMsgDifferent(msgVec) { 159 | return false 160 | } 161 | return C.blsAggregateVerifyNoCheck(&sig.v, &pubVec[0].v, unsafe.Pointer(&msgVec[0]), MSG_SIZE, C.mclSize(n)) == 1 162 | } 163 | 164 | // AggregateVerify -- 165 | // len(msgVec) == 32 * len(pubVec) 166 | func (sig *Sign) AggregateVerifyNoCheck(pubVec []PublicKey, msgVec []byte) bool { 167 | return sig.innerAggregateVerify(pubVec, msgVec, false) 168 | } 169 | 170 | // AggregateVerify -- 171 | // len(msgVec) == 32 * len(pubVec) 172 | // check all msgs are different each other 173 | func (sig *Sign) AggregateVerify(pubVec []PublicKey, msgVec []byte) bool { 174 | return sig.innerAggregateVerify(pubVec, msgVec, true) 175 | } 176 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://github.com/herumi/bls-eth-go-binary/actions/workflows/main.yml/badge.svg)](https://github.com/herumi/bls-eth-go-binary/actions/workflows/main.yml) 2 | 3 | # bls for eth with compiled static library 4 | 5 | This repository contains compiled static library of https://github.com/herumi/bls with `BLS_ETH=1`. 6 | 7 | * SecretKey; Fr 8 | * PublicKey; G1 9 | * Sign; G2 10 | 11 | # News 12 | - 2023/Aug/17 The performance of Sign is a little improved. 13 | - 2023/Jun/12 move static libraries to release branch 14 | - 2021/Jan/28 (change specification) enable VerifySignatureOrder and VerifyPublicKeyOrder by default 15 | - 2021/Jan/28 (change specification) verify returns false for zero public key 16 | - 2021/Jan/02 support arm64 golang on M1 mac 17 | - 2020/Oct/15 `add SecretKey::GetSafePublicKey()`, which returns an error if sec is zero 18 | - 2020/Oct/08 `MultiVerify` returns true only if all signatures are valid. 19 | - 2020/Sep/18 static binary for x64 is JIT-less mode, which uses code pre-generated by Xbyak. 20 | - 2020/Jul/03 remove old tests and use the latest hash function defined at [draft-07](https://www.ietf.org/id/draft-irtf-cfrg-hash-to-curve-07.txt) is set by default. 21 | - 2020/May/22 `SignHashWithDomain`, `VerifyHashWithDomain`, `VerifyAggregateHashWithDomain` are removed. 22 | - 2020/May/15 `EthModeDraft07` is added for [draft-07](https://www.ietf.org/id/draft-irtf-cfrg-hash-to-curve-07.txt). 23 | - 2020/Apr/20 `EthModeDraft06` is default. Call `SetETHmode(EthModeDraft05)` to use older evrsion. 24 | - 2020/Mar/26 The signature value in `SetETHmode(2)` has changed because of changing DST in hash-to-curve function. 25 | - 2020/Mar/17 This library supports [eth2.0 functions](https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/beacon-chain.md#bls-signatures). But the spec of hash-to-curve function may be changed. 26 | 27 | Init as the followings: 28 | 29 | ``` 30 | Init(BLS12_381) 31 | ``` 32 | 33 | then, you can use the following functions. 34 | 35 | bls-eth-go-binary | eth2.0 spec name| 36 | ------|-----------------| 37 | SecretKey::SignByte|Sign| 38 | PublicKey::VerifyByte|Verify| 39 | Sign::Aggregate|Aggregate| 40 | Sign::FastAggregateVerify|FastAggregateVerify| 41 | Sign::AggregateVerifyNoCheck|AggregateVerify| 42 | 43 | The size of message must be 32 byte. 44 | 45 | Check functions: 46 | - VerifySignatureOrder ; make `deserialize` check the correctness of the order 47 | - Sign::IsValidOrder ; check the correctness of the order 48 | - VerifyPublicKeyOrder ; make `deserialize` check the correctness of the order 49 | - PublicKey::IsValidOrder ; check the correctness of the order 50 | - AreAllMsgDifferent ; check that all messages are different each other 51 | 52 | # How to run `examples/sample.go` 53 | 54 | ``` 55 | git clone -b release https://github.com/herumi/bls-eth-go-binary 56 | cd bls-eth-go-binary 57 | go run examples/sample.go 58 | ``` 59 | 60 | # How to use `setup_vendor.sh` 61 | Since this package includes C headers and libraries, 62 | when using `go build -mod=vendor`, please run: 63 | 64 | ```bash 65 | $GOMODCACHE/github.com/herumi/bls-eth-go-binary@/setup_vendor.sh 66 | ``` 67 | 68 | This command will copy all necessary files to your vendor directory. 69 | 70 | # How to build the static binary 71 | The following steps are not necessary if you use release branch. 72 | 73 | ``` 74 | git clone https://github.com/herumi/bls-eth-go-binary 75 | cd bls-eth-go-binary 76 | git submodule update --init --recursive 77 | go test ./bls 78 | ``` 79 | 80 | ## Linux, Mac, Windows(mingw64) 81 | On x64 Linux, 82 | ``` 83 | make 84 | ``` 85 | 86 | Otherwise, clang is necessary to build ll files. 87 | ``` 88 | make CXX=clang++ 89 | ``` 90 | 91 | ### Cross compile on macOS 92 | 93 | ``` 94 | make ARCH=x86_64 # for Intel mac 95 | make ARCH=arm64 # for M1 mac 96 | ``` 97 | 98 | ### Cross compile of aarch64 on x64 Linux 99 | 100 | ``` 101 | sudo apt-get install gcc-multilib 102 | make -C src/bls -f Makefile.onelib build_aarch64 CXX=clang++ -j OUT_DIR=../.. 103 | ``` 104 | 105 | ### Cross compile of RISC-V 106 | Install a cross compiler. 107 | ``` 108 | sudo apt install gcc-riscv64-linux-gnu 109 | ``` 110 | 111 | Build a library and run the sample. 112 | ``` 113 | make riscv64 114 | env CGO_ENABLED=1 GOARCH=riscv64 CC=riscv64-linux-gnu-gcc-14 go build examples/sample.go 115 | env QEMU_LD_PREFIX=/usr/riscv64-linux-gnu ./sample 116 | ``` 117 | 118 | # Android 119 | Install [ndk-build](https://developer.android.com/ndk/guides). 120 | ``` 121 | make android 122 | ``` 123 | 124 | If you need a shared library, then after `make clean`, 125 | 126 | ``` 127 | make android BLS_LIB_SHARED=1 128 | ``` 129 | 130 | # iOS 131 | ``` 132 | make ios 133 | ``` 134 | 135 | ## How to cross-compile for armeabi-v7a 136 | Check `llc --version` shows to support the target armv7a. 137 | 138 | ``` 139 | make ../mcl/src/base32.ll 140 | env CXX=clang++ BIT=32 ARCH=arm _OS=android _ARCH=armeabi-v7a make MCL_USE_GMP=0 UNIT=4 CFLAGS_USER="-target armv7a-linux-eabi -fPIC" 141 | ``` 142 | 143 | * Remark : clang++ must support `armv7a-linux-eabi`. 144 | ### How to build sample.go for armeabi-v7a 145 | 146 | ``` 147 | env CC=arm-linux-gnueabi-gcc CGO_ENABLED=1 GOOS=linux GOARM=7 GOARCH=arm go build examples/sample.go 148 | env QEMU_LD_PREFIX=/usr/arm-linux-gnueabi qemu-arm ./sample 149 | ``` 150 | 151 | ## How to cross-compile for mipsel 152 | Check `llc --version` shows to support the target mips. 153 | 154 | ``` 155 | make ../mcl/src/base32.ll 156 | env CXX=clang++ BIT=32 ARCH=mipsel _OS=linux _ARCH=mipsle make MCL_USE_GMP=0 UNIT=4 CFLAGS_USER="-target mipsel-linux -fPIC" 157 | ``` 158 | 159 | * Remark : clang++ must support `mipsel-linux`. 160 | ### How to build sample.go for mipsel 161 | 162 | ``` 163 | env CC=mipsel-linux-gnu-gcc CGO_ENABLED=1 GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build examples/sample.go 164 | env QEMU_LD_PREFIX=/usr/mipsel-linux-gnu qemu-mipsel ./sample 165 | ``` 166 | 167 | # How to use the static library from C 168 | ``` 169 | #define BLS_ETH 170 | #include 171 | #include 172 | ``` 173 | 174 | # Author 175 | MITSUNARI Shigeo(herumi@nifty.com) 176 | 177 | # Sponsors welcome 178 | [GitHub Sponsor](https://github.com/sponsors/herumi) 179 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | 4 | permissions: 5 | contents: write 6 | repository-projects: write 7 | 8 | concurrency: 9 | group: "release-${{ github.ref }}" 10 | cancel-in-progress: true 11 | 12 | on: 13 | workflow_dispatch: 14 | inputs: 15 | version: 16 | description: 'release/tag: vX.Y.Z' 17 | required: true 18 | 19 | 20 | jobs: 21 | create-branch: 22 | runs-on: ubuntu-latest 23 | 24 | steps: 25 | - name: Checkout code 26 | uses: actions/checkout@v4 27 | 28 | - name: Create branch 29 | env: 30 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token 31 | run: | 32 | git pull 33 | git checkout release 2>/dev/null || git checkout -b release 34 | rm -rf ./src/bls && mkdir -p ./src/bls 35 | git merge origin/master -q -m "chore(git): merged latest master" 36 | git submodule update --init --recursive 37 | 38 | git config user.name github-actions 39 | git config user.email github-actions@github.com 40 | git push --set-upstream origin release 41 | build-linux: 42 | # For Linux build we use an Ubuntu version that's as old as possible so that 43 | # the generated artifacts are compatible with not-so-recent systems 44 | runs-on: ubuntu-24.04 45 | needs: create-branch 46 | steps: 47 | - name: Checkout code 48 | uses: actions/checkout@v4 49 | 50 | - name: Setup Go 51 | uses: actions/setup-go@v5 52 | with: 53 | go-version: ^1.22 54 | 55 | - name: Install Java 56 | uses: actions/setup-java@v4 57 | with: 58 | distribution: 'temurin' 59 | java-version: '17' 60 | 61 | - uses: android-actions/setup-android@v3 62 | 63 | - name: Install Android Platform 64 | run: | 65 | sdkmanager "platform-tools" 66 | sdkmanager "platforms;android-29" 67 | sdkmanager "build-tools;29.0.2" 68 | 69 | - uses: nttld/setup-ndk@v1 70 | id: setup-ndk 71 | with: 72 | ndk-version: r21d 73 | 74 | - name: Build linux 75 | env: 76 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token 77 | run: | 78 | git pull && git checkout release 79 | git submodule update --init --recursive 80 | 81 | sudo apt update 82 | sudo apt install nasm 83 | 84 | [ -d ./bls/lib/linux/ ] && rm -rf ./bls/lib/linux/ 85 | make clean 86 | 87 | mkdir -p ./bls/lib/linux/ 88 | 89 | #make CXX=clang++ # avoid crashes on non-AVX CPUs 90 | make 91 | make clean 92 | # build linux/arm64 93 | sudo apt-get install gcc-multilib 94 | make aarch64 95 | 96 | git config user.name github-actions 97 | git config user.email github-actions@github.com 98 | 99 | git add ./bls/lib/linux -f 100 | 101 | changes=$(git diff --staged --numstat | wc -l) 102 | if [[ $changes -gt 0 ]] 103 | then 104 | git commit -m "fix(release): added libs for linux(amd64/arm64)" 105 | git push 106 | fi 107 | 108 | - name: Build android 109 | env: 110 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token 111 | run: | 112 | git pull && git checkout release 113 | 114 | [ -d ./bls/lib/android/ ] && rm -rf ./bls/lib/android/ 115 | make clean 116 | 117 | mkdir -p ./bls/lib/android/ 118 | 119 | make android 120 | 121 | git config user.name github-actions 122 | git config user.email github-actions@github.com 123 | 124 | git add ./bls/lib/android/ -f 125 | 126 | changes=$(git diff --staged --numstat | wc -l) 127 | if [[ $changes -gt 0 ]] 128 | then 129 | git commit -m "fix(release): added libs for android" 130 | git push 131 | fi 132 | build-macos: 133 | runs-on: macos-13 # macos-14 causes link error 134 | needs: build-linux 135 | steps: 136 | - name: Checkout code 137 | uses: actions/checkout@v4 138 | 139 | - name: Setup Go 140 | uses: actions/setup-go@v5 141 | with: 142 | go-version: ^1.22 143 | 144 | - name: Build darwin 145 | env: 146 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token 147 | run: | 148 | git pull && git checkout release 149 | git submodule update --init --recursive 150 | 151 | brew install nasm 152 | 153 | [ -d ./bls/lib/darwin/ ] && rm -rf ./bls/lib/darwin/ 154 | make clean 155 | 156 | mkdir -p ./bls/lib/darwin/ 157 | 158 | make ARCH=x86_64 159 | make clean 160 | make ARCH=arm64 161 | 162 | git config user.name github-actions 163 | git config user.email github-actions@github.com 164 | 165 | git add ./bls/lib/darwin/ -f 166 | 167 | changes=$(git diff --staged --numstat | wc -l) 168 | if [[ $changes -gt 0 ]] 169 | then 170 | git commit -m "fix(release): added libs for darwin" 171 | git push 172 | fi 173 | 174 | - name: Build ios 175 | env: 176 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token 177 | run: | 178 | git pull && git checkout release 179 | git submodule update --init --recursive 180 | 181 | [ -d ./bls/lib/ios ] && rm -rf ./bls/lib/ios 182 | [ -d ./bls/lib/iossimulator ] && rm -rf ./bls/lib/iossimulator 183 | make clean 184 | 185 | mkdir -p ./bls/lib/ios 186 | mkdir -p ./bls/lib/iossimulator 187 | 188 | git config user.name github-actions 189 | git config user.email github-actions@github.com 190 | 191 | make ios 192 | make ios_simulator 193 | 194 | git add ./bls/lib/ios -f 195 | git add ./bls/lib/iossimulator -f 196 | 197 | changes=$(git diff --staged --numstat | wc -l) 198 | if [[ $changes -gt 0 ]] 199 | then 200 | git commit -m "fix(release): added libs for ios/ios simulator" 201 | git push 202 | fi 203 | 204 | build-windows: 205 | runs-on: windows-latest 206 | needs: build-macos 207 | steps: 208 | - name: Checkout code 209 | uses: actions/checkout@v4 210 | 211 | - name: Setup Go 212 | uses: actions/setup-go@v5 213 | with: 214 | go-version: ^1.22 215 | 216 | - name: Install MSYS2 217 | uses: msys2/setup-msys2@v2 218 | with: 219 | update: true 220 | msystem: MINGW64 221 | install: base-devel git gcc make python3 nasm # mingw-w64-x86_64-clang 222 | 223 | - name: Build windows 224 | # shell: msys2 {0} 225 | env: 226 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token 227 | run: | 228 | git pull && git checkout release 229 | git submodule update --init --recursive 230 | 231 | gcc --version 232 | python3 --version 233 | 234 | git checkout . 235 | if (Test-Path "./bls/lib/windows/amd64") { 236 | Remove-Item "./bls/lib/windows/amd64" -Recurse -Force 237 | } 238 | make clean 239 | # make -j # ar gives an error for some reason, so use the followings: 240 | 241 | md "./bls/lib/windows/amd64" 242 | 243 | make -C ./src/bls -f Makefile.onelib LIB_DIR=./ ETH_CFLAGS=-DBLS_ETH 244 | cp ./src/bls/libbls384_256.a ./bls/lib/windows/amd64/libbls384_256.a 245 | 246 | git config user.name github-actions 247 | git config user.email github-actions@github.com 248 | git add ./bls/lib/windows -f && git commit -m "fix(release): added libs for windows" && git push 249 | 250 | 251 | create-release: 252 | runs-on: ubuntu-latest 253 | needs: build-windows 254 | steps: 255 | - name: Checkout code 256 | uses: actions/checkout@v4 257 | - name: Set hash 258 | id: set-hash 259 | env: 260 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token 261 | run: | 262 | git pull && git checkout release 263 | git submodule update --init --recursive 264 | git branch -av 265 | git rev-parse HEAD 266 | echo "hash=$(git rev-parse HEAD)" >> "$GITHUB_ENV" 267 | 268 | - name: show 269 | run: | 270 | echo "hash" "${{ env.hash }}" 271 | 272 | - name: Create Release 273 | id: create_release 274 | run: gh release create "${{ github.event.inputs.version }}" -t "${{ github.event.inputs.version }}" --target "release" --latest 275 | env: 276 | GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 277 | -------------------------------------------------------------------------------- /bls/tests/verify.txt: -------------------------------------------------------------------------------- 1 | pub b301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81 2 | msg abababababababababababababababababababababababababababababababab 3 | sig 9674e2228034527f4c083206032b020310face156d4a4685e2fcaec2f6f3665aa635d90347b6ce124eb879266b1e801d185de36a0a289b85e9039662634f2eea1e02e670bc7ab849d006a70b2f93b84597558a05b879c8d445f387a5d5b653df 4 | out true 5 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 6 | msg abababababababababababababababababababababababababababababababab 7 | sig 91347bccf740d859038fcdcaf233eeceb2a436bcaaee9b2aa3bfb70efe29dfb2677562ccbea1c8e061fb9971b0753c240622fab78489ce96768259fc01360346da5b9f579e5da0d941e4c6ba18a0e64906082375394f337fa1af2b71ffffffff 8 | out false 9 | pub b301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81 10 | msg 0000000000000000000000000000000000000000000000000000000000000000 11 | sig b6ed936746e01f8ecf281f020953fbf1f01debd5657c4a383940b020b26507f6076334f91e2366c96e9ab279fb5158090352ea1c5b0c9274504f4f0e7053af24802e51e4568d164fe986834f41e55c8e850ce1f98458c0cfc9ab380b55285a55 12 | out false 13 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 14 | msg 5656565656565656565656565656565656565656565656565656565656565656 15 | sig a4efa926610b8bd1c8330c918b7a5e9bf374e53435ef8b7ec186abf62e1b1f65aeaaeb365677ac1d1172a1f5b44b4e6d022c252c58486c0a759fbdc7de15a756acc4d343064035667a594b4c2a6f0b0b421975977f297dba63ee2f63ffe47bb6 16 | out false 17 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 18 | msg abababababababababababababababababababababababababababababababab 19 | sig 91347bccf740d859038fcdcaf233eeceb2a436bcaaee9b2aa3bfb70efe29dfb2677562ccbea1c8e061fb9971b0753c240622fab78489ce96768259fc01360346da5b9f579e5da0d941e4c6ba18a0e64906082375394f337fa1af2b7127b0d121 20 | out true 21 | pub b301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81 22 | msg 5656565656565656565656565656565656565656565656565656565656565656 23 | sig af1390c3c47acdb37131a51216da683c509fce0e954328a59f93aebda7e4ff974ba208d9a4a2a2389f892a9d418d618418dd7f7a6bc7aa0da999a9d3a5b815bc085e14fd001f6a1948768a3f4afefc8b8240dda329f984cb345c6363ffffffff 24 | out false 25 | pub c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 26 | msg abababababababababababababababababababababababababababababababab 27 | sig c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 28 | out false 29 | pub b53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f 30 | msg 5656565656565656565656565656565656565656565656565656565656565656 31 | sig af1390c3c47acdb37131a51216da683c509fce0e954328a59f93aebda7e4ff974ba208d9a4a2a2389f892a9d418d618418dd7f7a6bc7aa0da999a9d3a5b815bc085e14fd001f6a1948768a3f4afefc8b8240dda329f984cb345c6363272ba4fe 32 | out false 33 | pub b53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f 34 | msg abababababababababababababababababababababababababababababababab 35 | sig ae82747ddeefe4fd64cf9cedb9b04ae3e8a43420cd255e3c7cd06a8d88b7c7f8638543719981c5d16fa3527c468c25f0026704a6951bde891360c7e8d12ddee0559004ccdbe6046b55bae1b257ee97f7cdb955773d7cf29adf3ccbb9975e4eb9 36 | out true 37 | pub b53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f 38 | msg 5656565656565656565656565656565656565656565656565656565656565656 39 | sig a4efa926610b8bd1c8330c918b7a5e9bf374e53435ef8b7ec186abf62e1b1f65aeaaeb365677ac1d1172a1f5b44b4e6d022c252c58486c0a759fbdc7de15a756acc4d343064035667a594b4c2a6f0b0b421975977f297dba63ee2f63ffffffff 40 | out false 41 | pub b301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81 42 | msg abababababababababababababababababababababababababababababababab 43 | sig 91347bccf740d859038fcdcaf233eeceb2a436bcaaee9b2aa3bfb70efe29dfb2677562ccbea1c8e061fb9971b0753c240622fab78489ce96768259fc01360346da5b9f579e5da0d941e4c6ba18a0e64906082375394f337fa1af2b7127b0d121 44 | out false 45 | pub b53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f 46 | msg abababababababababababababababababababababababababababababababab 47 | sig ae82747ddeefe4fd64cf9cedb9b04ae3e8a43420cd255e3c7cd06a8d88b7c7f8638543719981c5d16fa3527c468c25f0026704a6951bde891360c7e8d12ddee0559004ccdbe6046b55bae1b257ee97f7cdb955773d7cf29adf3ccbb9ffffffff 48 | out false 49 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 50 | msg 0000000000000000000000000000000000000000000000000000000000000000 51 | sig 948a7cb99f76d616c2c564ce9bf4a519f1bea6b0a624a02276443c245854219fabb8d4ce061d255af5330b078d5380681751aa7053da2c98bae898edc218c75f07e24d8802a17cd1f6833b71e58f5eb5b94208b4d0bb3848cecb075ea21be115 52 | out false 53 | pub b53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f 54 | msg 0000000000000000000000000000000000000000000000000000000000000000 55 | sig b23c46be3a001c63ca711f87a005c200cc550b9429d5f4eb38d74322144f1b63926da3388979e5321012fb1a0526bcd100b5ef5fe72628ce4cd5e904aeaa3279527843fae5ca9ca675f4f51ed8f83bbf7155da9ecc9663100a885d5dc6df96d9 56 | out false 57 | pub b301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81 58 | msg 0000000000000000000000000000000000000000000000000000000000000000 59 | sig b23c46be3a001c63ca711f87a005c200cc550b9429d5f4eb38d74322144f1b63926da3388979e5321012fb1a0526bcd100b5ef5fe72628ce4cd5e904aeaa3279527843fae5ca9ca675f4f51ed8f83bbf7155da9ecc9663100a885d5dffffffff 60 | out false 61 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 62 | msg 0000000000000000000000000000000000000000000000000000000000000000 63 | sig b6ed936746e01f8ecf281f020953fbf1f01debd5657c4a383940b020b26507f6076334f91e2366c96e9ab279fb5158090352ea1c5b0c9274504f4f0e7053af24802e51e4568d164fe986834f41e55c8e850ce1f98458c0cfc9ab380bffffffff 64 | out false 65 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 66 | msg 5656565656565656565656565656565656565656565656565656565656565656 67 | sig 882730e5d03f6b42c3abc26d3372625034e1d871b65a8a6b900a56dae22da98abbe1b68f85e49fe7652a55ec3d0591c20767677e33e5cbb1207315c41a9ac03be39c2e7668edc043d6cb1d9fd93033caa8a1c5b0e84bedaeb6c64972ffffffff 68 | out false 69 | pub b301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81 70 | msg abababababababababababababababababababababababababababababababab 71 | sig 9674e2228034527f4c083206032b020310face156d4a4685e2fcaec2f6f3665aa635d90347b6ce124eb879266b1e801d185de36a0a289b85e9039662634f2eea1e02e670bc7ab849d006a70b2f93b84597558a05b879c8d445f387a5ffffffff 72 | out false 73 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 74 | msg abababababababababababababababababababababababababababababababab 75 | sig ae82747ddeefe4fd64cf9cedb9b04ae3e8a43420cd255e3c7cd06a8d88b7c7f8638543719981c5d16fa3527c468c25f0026704a6951bde891360c7e8d12ddee0559004ccdbe6046b55bae1b257ee97f7cdb955773d7cf29adf3ccbb9975e4eb9 76 | out false 77 | pub b53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f 78 | msg 0000000000000000000000000000000000000000000000000000000000000000 79 | sig 948a7cb99f76d616c2c564ce9bf4a519f1bea6b0a624a02276443c245854219fabb8d4ce061d255af5330b078d5380681751aa7053da2c98bae898edc218c75f07e24d8802a17cd1f6833b71e58f5eb5b94208b4d0bb3848cecb075effffffff 80 | out false 81 | pub b53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f 82 | msg abababababababababababababababababababababababababababababababab 83 | sig 9674e2228034527f4c083206032b020310face156d4a4685e2fcaec2f6f3665aa635d90347b6ce124eb879266b1e801d185de36a0a289b85e9039662634f2eea1e02e670bc7ab849d006a70b2f93b84597558a05b879c8d445f387a5d5b653df 84 | out false 85 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 86 | msg 5656565656565656565656565656565656565656565656565656565656565656 87 | sig 882730e5d03f6b42c3abc26d3372625034e1d871b65a8a6b900a56dae22da98abbe1b68f85e49fe7652a55ec3d0591c20767677e33e5cbb1207315c41a9ac03be39c2e7668edc043d6cb1d9fd93033caa8a1c5b0e84bedaeb6c64972503a43eb 88 | out true 89 | pub b53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f 90 | msg 0000000000000000000000000000000000000000000000000000000000000000 91 | sig 948a7cb99f76d616c2c564ce9bf4a519f1bea6b0a624a02276443c245854219fabb8d4ce061d255af5330b078d5380681751aa7053da2c98bae898edc218c75f07e24d8802a17cd1f6833b71e58f5eb5b94208b4d0bb3848cecb075ea21be115 92 | out true 93 | pub b301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81 94 | msg 5656565656565656565656565656565656565656565656565656565656565656 95 | sig 882730e5d03f6b42c3abc26d3372625034e1d871b65a8a6b900a56dae22da98abbe1b68f85e49fe7652a55ec3d0591c20767677e33e5cbb1207315c41a9ac03be39c2e7668edc043d6cb1d9fd93033caa8a1c5b0e84bedaeb6c64972503a43eb 96 | out false 97 | pub b301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81 98 | msg 0000000000000000000000000000000000000000000000000000000000000000 99 | sig b23c46be3a001c63ca711f87a005c200cc550b9429d5f4eb38d74322144f1b63926da3388979e5321012fb1a0526bcd100b5ef5fe72628ce4cd5e904aeaa3279527843fae5ca9ca675f4f51ed8f83bbf7155da9ecc9663100a885d5dc6df96d9 100 | out true 101 | pub b301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81 102 | msg 5656565656565656565656565656565656565656565656565656565656565656 103 | sig af1390c3c47acdb37131a51216da683c509fce0e954328a59f93aebda7e4ff974ba208d9a4a2a2389f892a9d418d618418dd7f7a6bc7aa0da999a9d3a5b815bc085e14fd001f6a1948768a3f4afefc8b8240dda329f984cb345c6363272ba4fe 104 | out true 105 | pub a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a 106 | msg 0000000000000000000000000000000000000000000000000000000000000000 107 | sig b6ed936746e01f8ecf281f020953fbf1f01debd5657c4a383940b020b26507f6076334f91e2366c96e9ab279fb5158090352ea1c5b0c9274504f4f0e7053af24802e51e4568d164fe986834f41e55c8e850ce1f98458c0cfc9ab380b55285a55 108 | out true 109 | pub b53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f 110 | msg 5656565656565656565656565656565656565656565656565656565656565656 111 | sig a4efa926610b8bd1c8330c918b7a5e9bf374e53435ef8b7ec186abf62e1b1f65aeaaeb365677ac1d1172a1f5b44b4e6d022c252c58486c0a759fbdc7de15a756acc4d343064035667a594b4c2a6f0b0b421975977f297dba63ee2f63ffe47bb6 112 | out true 113 | -------------------------------------------------------------------------------- /bls/include/bls/bls.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /** 3 | @file 4 | @brief C interface of bls.hpp 5 | @author MITSUNARI Shigeo(@herumi) 6 | @license modified new BSD license 7 | http://opensource.org/licenses/BSD-3-Clause 8 | */ 9 | #define MCLBN_NO_AUTOLINK 10 | #include 11 | 12 | #ifdef BLS_ETH 13 | #define BLS_COMPILER_TIME_VAR_ADJ 200 14 | /* 15 | error if BLS_ETH is inconsistently defined between library and exe 16 | */ 17 | #undef MCLBN_COMPILED_TIME_VAR 18 | #define MCLBN_COMPILED_TIME_VAR ((MCLBN_FR_UNIT_SIZE) * 10 + (MCLBN_FP_UNIT_SIZE) + BLS_COMPILER_TIME_VAR_ADJ) 19 | #endif 20 | 21 | #ifdef _WIN32 22 | #ifdef BLS_DONT_EXPORT 23 | #define BLS_DLL_API 24 | #else 25 | #ifdef BLS_DLL_EXPORT 26 | #define BLS_DLL_API __declspec(dllexport) 27 | #else 28 | #define BLS_DLL_API //__declspec(dllimport) 29 | #endif 30 | #endif 31 | #if defined(_MSC_VER) && !defined(BLS_NO_AUTOLINK) 32 | #if MCLBN_FP_UNIT_SIZE == 4 33 | #pragma comment(lib, "bls256.lib") 34 | #elif (MCLBN_FP_UNIT_SIZE == 6) && (MCLBN_FR_UNIT_SIZE == 4) 35 | #pragma comment(lib, "bls384_256.lib") 36 | #elif (MCLBN_FP_UNIT_SIZE == 6) && (MCLBN_FR_UNIT_SIZE == 6) 37 | #pragma comment(lib, "bls384.lib") 38 | #endif 39 | #endif 40 | #elif defined(__EMSCRIPTEN__) && !defined(BLS_DONT_EXPORT) 41 | #define BLS_DLL_API __attribute__((used)) 42 | #elif defined(__wasm__) && !defined(BLS_DONT_EXPORT) 43 | #define BLS_DLL_API __attribute__((visibility("default"))) 44 | #else 45 | #define BLS_DLL_API 46 | #endif 47 | 48 | #ifdef __cplusplus 49 | extern "C" { 50 | #endif 51 | 52 | typedef struct { 53 | mclBnFr v; 54 | } blsId; 55 | 56 | typedef struct { 57 | mclBnFr v; 58 | } blsSecretKey; 59 | 60 | typedef struct { 61 | #ifdef BLS_ETH 62 | mclBnG1 v; 63 | #else 64 | mclBnG2 v; 65 | #endif 66 | } blsPublicKey; 67 | 68 | typedef struct { 69 | #ifdef BLS_ETH 70 | mclBnG2 v; 71 | #else 72 | mclBnG1 v; 73 | #endif 74 | } blsSignature; 75 | 76 | /* 77 | initialize this library 78 | call this once before using the other functions 79 | @param curve [in] enum value defined in mcl/bn.h 80 | @param compiledTimeVar [in] specify MCLBN_COMPILED_TIME_VAR, 81 | which macro is used to make sure that the values 82 | are the same when the library is built and used 83 | @return 0 if success 84 | @note blsInit() is not thread safe 85 | */ 86 | BLS_DLL_API int blsInit(int curve, int compiledTimeVar); 87 | 88 | /* 89 | use new eth 2.0 spec 90 | @return 0 if success 91 | @remark 92 | this functions and the spec may change until it is fixed 93 | the size of message <= 32 94 | */ 95 | #define BLS_ETH_MODE_OLD 0 96 | #define BLS_ETH_MODE_DRAFT_05 1 // 2020/Jan/30 97 | #define BLS_ETH_MODE_DRAFT_06 2 // 2020/Mar/15 98 | #define BLS_ETH_MODE_DRAFT_07 3 // 2020/May/13 99 | #define BLS_ETH_MODE_LATEST 3 100 | BLS_DLL_API int blsSetETHmode(int mode); 101 | 102 | /* 103 | set ETH serialization mode for BLS12-381 104 | @param ETHserialization [in] 1:enable, 0:disable 105 | @note ignore the flag if curve is not BLS12-381 106 | @note set in blsInit if BLS_ETH is defined 107 | */ 108 | BLS_DLL_API void blsSetETHserialization(int ETHserialization); 109 | 110 | /* 111 | set map-to-function to mode 112 | MCL_MAP_TO_MODE_ORIGINAL ; for backward compatibility 113 | MCL_MAP_TO_MODE_HASH_TO_CURVE ; irtf-cfrg-hash-to-curve 114 | return 0 if success else -1 115 | */ 116 | BLS_DLL_API int blsSetMapToMode(int mode); 117 | 118 | BLS_DLL_API void blsIdSetInt(blsId *id, int x); 119 | 120 | // sec = buf & (1 << bitLen(r)) - 1 121 | // if (sec >= r) sec &= (1 << (bitLen(r) - 1)) - 1 122 | // always return 0 123 | BLS_DLL_API int blsSecretKeySetLittleEndian(blsSecretKey *sec, const void *buf, mclSize bufSize); 124 | // return 0 if success (bufSize <= 64) else -1 125 | // set (buf mod r) to sec 126 | BLS_DLL_API int blsSecretKeySetLittleEndianMod(blsSecretKey *sec, const void *buf, mclSize bufSize); 127 | 128 | BLS_DLL_API void blsGetPublicKey(blsPublicKey *pub, const blsSecretKey *sec); 129 | 130 | // calculate the has of m and sign the hash 131 | BLS_DLL_API void blsSign(blsSignature *sig, const blsSecretKey *sec, const void *m, mclSize size); 132 | 133 | // return 1 if valid else 0 134 | // @remark return 0 if pub is zero for BLS_ETH 135 | BLS_DLL_API int blsVerify(const blsSignature *sig, const blsPublicKey *pub, const void *m, mclSize size); 136 | /* 137 | return 1 if blsVerify(&sigVec[i], &pubVec[i], &msgVec[i * msgSize]) returns 1 for all i = 0, ..., n-1 138 | @param randVec [in] non-zero randSize * n byte array 139 | @note for only BLS_ETH 140 | sig = sum_i sigVec[i] * randVec[i] 141 | pubVec[i] *= randVec[i] 142 | return blsAggregateVerifyNoCheck(sig, pubVec, msgVec, msgSize, n); 143 | @remark return 0 if some pubVec[i] is zero 144 | sigVec may be normalized 145 | */ 146 | BLS_DLL_API int blsMultiVerify(blsSignature *sigVec, const blsPublicKey *pubVec, const void *msgVec, mclSize msgSize, const void *randVec, mclSize randSize, mclSize n, int threadN); 147 | 148 | /* 149 | subroutine of blsMultiVerify 150 | e = prod_i millerLoop(pubVec[i] * randVec[i], Hash(msgVec[i])) 151 | aggSig = sum_i sigVec[i] * randVec[i] 152 | @remark set *e = 0 if some pubVec[i] is zero 153 | sigVec may be normalized 154 | */ 155 | BLS_DLL_API void blsMultiVerifySub(mclBnGT *e, blsSignature *aggSig, blsSignature *sigVec, const blsPublicKey *pubVec, const char *msg, mclSize msgSize, const char *randVec, mclSize randSize, mclSize n); 156 | 157 | /* 158 | subroutine of blsMultiVerify 159 | return FE(e * ML(P, -aggSig)) == 1 ? 1 : 0 160 | */ 161 | BLS_DLL_API int blsMultiVerifyFinal(const mclBnGT *e, const blsSignature *aggSig); 162 | 163 | // aggSig = sum of sigVec[0..n] 164 | BLS_DLL_API void blsAggregateSignature(blsSignature *aggSig, const blsSignature *sigVec, mclSize n); 165 | 166 | // verify(sig, sum of pubVec[0..n], msg) 167 | BLS_DLL_API int blsFastAggregateVerify(const blsSignature *sig, const blsPublicKey *pubVec, mclSize n, const void *msg, mclSize msgSize); 168 | 169 | /* 170 | all msg[i] has the same msgSize byte, so msgVec must have (msgSize * n) byte area 171 | verify prod e(H(pubVec[i], msgToG2[i]) == e(P, sig) 172 | @note CHECK that sig has the valid order, all msg are different each other before calling this 173 | */ 174 | BLS_DLL_API int blsAggregateVerifyNoCheck(const blsSignature *sig, const blsPublicKey *pubVec, const void *msgVec, mclSize msgSize, mclSize n); 175 | 176 | // return written byte size if success else 0 177 | BLS_DLL_API mclSize blsIdSerialize(void *buf, mclSize maxBufSize, const blsId *id); 178 | BLS_DLL_API mclSize blsSecretKeySerialize(void *buf, mclSize maxBufSize, const blsSecretKey *sec); 179 | BLS_DLL_API mclSize blsPublicKeySerialize(void *buf, mclSize maxBufSize, const blsPublicKey *pub); 180 | BLS_DLL_API mclSize blsSignatureSerialize(void *buf, mclSize maxBufSize, const blsSignature *sig); 181 | 182 | // return read byte size if success else 0 183 | BLS_DLL_API mclSize blsIdDeserialize(blsId *id, const void *buf, mclSize bufSize); 184 | BLS_DLL_API mclSize blsSecretKeyDeserialize(blsSecretKey *sec, const void *buf, mclSize bufSize); 185 | BLS_DLL_API mclSize blsPublicKeyDeserialize(blsPublicKey *pub, const void *buf, mclSize bufSize); 186 | BLS_DLL_API mclSize blsSignatureDeserialize(blsSignature *sig, const void *buf, mclSize bufSize); 187 | 188 | // return 1 if same else 0 189 | BLS_DLL_API int blsIdIsEqual(const blsId *lhs, const blsId *rhs); 190 | BLS_DLL_API int blsSecretKeyIsEqual(const blsSecretKey *lhs, const blsSecretKey *rhs); 191 | BLS_DLL_API int blsPublicKeyIsEqual(const blsPublicKey *lhs, const blsPublicKey *rhs); 192 | BLS_DLL_API int blsSignatureIsEqual(const blsSignature *lhs, const blsSignature *rhs); 193 | 194 | // return 1 if zero else 0 195 | BLS_DLL_API int blsIdIsZero(const blsId *x); 196 | BLS_DLL_API int blsSecretKeyIsZero(const blsSecretKey *x); 197 | BLS_DLL_API int blsPublicKeyIsZero(const blsPublicKey *x); 198 | BLS_DLL_API int blsSignatureIsZero(const blsSignature *x); 199 | 200 | // return 0 if success 201 | // make sec corresponding to id from {msk[0], ..., msk[k-1]} 202 | BLS_DLL_API int blsSecretKeyShare(blsSecretKey *sec, const blsSecretKey *msk, mclSize k, const blsId *id); 203 | // make pub corresponding to id from {mpk[0], ..., mpk[k-1]} 204 | BLS_DLL_API int blsPublicKeyShare(blsPublicKey *pub, const blsPublicKey *mpk, mclSize k, const blsId *id); 205 | 206 | // return 0 if success 207 | // recover sec from {(secVec[i], idVec[i]) for i = 0, ..., n-1} 208 | BLS_DLL_API int blsSecretKeyRecover(blsSecretKey *sec, const blsSecretKey *secVec, const blsId *idVec, mclSize n); 209 | // recover pub from {(pubVec[i], idVec[i]) for i = 0, ..., n-1} 210 | BLS_DLL_API int blsPublicKeyRecover(blsPublicKey *pub, const blsPublicKey *pubVec, const blsId *idVec, mclSize n); 211 | // recover sig from {(sigVec[i], idVec[i]) for i = 0, ..., n-1} 212 | BLS_DLL_API int blsSignatureRecover(blsSignature *sig, const blsSignature *sigVec, const blsId *idVec, mclSize n); 213 | 214 | // sec += rhs 215 | BLS_DLL_API void blsSecretKeyAdd(blsSecretKey *sec, const blsSecretKey *rhs); 216 | // pub += rhs 217 | BLS_DLL_API void blsPublicKeyAdd(blsPublicKey *pub, const blsPublicKey *rhs); 218 | // sig += rhs 219 | BLS_DLL_API void blsSignatureAdd(blsSignature *sig, const blsSignature *rhs); 220 | 221 | /* 222 | verify whether a point of an elliptic curve has order r 223 | This api affetcs setStr(), deserialize() for G2 on BN or G1/G2 on BLS12 224 | @param doVerify [in] does not verify if zero(default 1) 225 | Signature = G1, PublicKey = G2 226 | */ 227 | BLS_DLL_API void blsSignatureVerifyOrder(int doVerify); 228 | BLS_DLL_API void blsPublicKeyVerifyOrder(int doVerify); 229 | // deserialize under VerifyOrder(true) = deserialize under VerifyOrder(false) + IsValidOrder 230 | BLS_DLL_API int blsSignatureIsValidOrder(const blsSignature *sig); 231 | BLS_DLL_API int blsPublicKeyIsValidOrder(const blsPublicKey *pub); 232 | 233 | #ifndef BLS_MINIMUM_API 234 | 235 | /* 236 | verify X == sY by checking e(X, sQ) = e(Y, Q) 237 | @param X [in] 238 | @param Y [in] 239 | @param pub [in] pub = sQ 240 | @return 1 if e(X, pub) = e(Y, Q) else 0 241 | */ 242 | BLS_DLL_API int blsVerifyPairing(const blsSignature *X, const blsSignature *Y, const blsPublicKey *pub); 243 | 244 | /* 245 | sign the hash 246 | use the low (bitSize of r) - 1 bit of h 247 | return 0 if success else -1 248 | NOTE : return false if h is zero or c1 or -c1 value for BN254. see hashTest() in test/bls_test.hpp 249 | */ 250 | BLS_DLL_API int blsSignHash(blsSignature *sig, const blsSecretKey *sec, const void *h, mclSize size); 251 | // return 1 if valid 252 | BLS_DLL_API int blsVerifyHash(const blsSignature *sig, const blsPublicKey *pub, const void *h, mclSize size); 253 | 254 | /* 255 | verify aggSig with pubVec[0, n) and hVec[0, n) 256 | e(aggSig, Q) = prod_i e(hVec[i], pubVec[i]) 257 | return 1 if valid 258 | @note do not check duplication of hVec 259 | */ 260 | BLS_DLL_API int blsVerifyAggregatedHashes(const blsSignature *aggSig, const blsPublicKey *pubVec, const void *hVec, size_t sizeofHash, mclSize n); 261 | 262 | /* 263 | Uncompressed version of Serialize/Deserialize 264 | the buffer size is twice of Serialize/Deserialize 265 | */ 266 | BLS_DLL_API mclSize blsPublicKeySerializeUncompressed(void *buf, mclSize maxBufSize, const blsPublicKey *pub); 267 | BLS_DLL_API mclSize blsSignatureSerializeUncompressed(void *buf, mclSize maxBufSize, const blsSignature *sig); 268 | BLS_DLL_API mclSize blsPublicKeyDeserializeUncompressed(blsPublicKey *pub, const void *buf, mclSize bufSize); 269 | BLS_DLL_API mclSize blsSignatureDeserializeUncompressed(blsSignature *sig, const void *buf, mclSize bufSize); 270 | 271 | ///// to here only for BLS12-381 with BLS_ETH 272 | 273 | // sub 274 | BLS_DLL_API void blsSecretKeySub(blsSecretKey *sec, const blsSecretKey *rhs); 275 | BLS_DLL_API void blsPublicKeySub(blsPublicKey *pub, const blsPublicKey *rhs); 276 | BLS_DLL_API void blsSignatureSub(blsSignature *sig, const blsSignature *rhs); 277 | 278 | // neg 279 | BLS_DLL_API void blsSecretKeyNeg(blsSecretKey *x); 280 | BLS_DLL_API void blsPublicKeyNeg(blsPublicKey *x); 281 | BLS_DLL_API void blsSignatureNeg(blsSignature *x); 282 | 283 | // mul y *= x 284 | BLS_DLL_API void blsSecretKeyMul(blsSecretKey *y, const blsSecretKey *x); 285 | BLS_DLL_API void blsPublicKeyMul(blsPublicKey *y, const blsSecretKey *x); 286 | BLS_DLL_API void blsSignatureMul(blsSignature *y, const blsSecretKey *x); 287 | 288 | // x may be normalized, so it is not a const pointer 289 | BLS_DLL_API void blsPublicKeyMulVec(blsPublicKey *z, blsPublicKey *x, const blsSecretKey *y, mclSize n); 290 | BLS_DLL_API void blsSignatureMulVec(blsSignature *z, blsSignature *x, const blsSecretKey *y, mclSize n); 291 | 292 | // not thread safe version (old blsInit) 293 | BLS_DLL_API int blsInitNotThreadSafe(int curve, int compiledTimeVar); 294 | 295 | BLS_DLL_API mclSize blsGetOpUnitSize(void); 296 | // return strlen(buf) if success else 0 297 | BLS_DLL_API int blsGetCurveOrder(char *buf, mclSize maxBufSize); 298 | BLS_DLL_API int blsGetFieldOrder(char *buf, mclSize maxBufSize); 299 | 300 | // return serialized secretKey size 301 | BLS_DLL_API int blsGetSerializedSecretKeyByteSize(void); 302 | // return serialized publicKey size 303 | BLS_DLL_API int blsGetSerializedPublicKeyByteSize(void); 304 | // return serialized signature size 305 | BLS_DLL_API int blsGetSerializedSignatureByteSize(void); 306 | 307 | // return bytes for serialized G1(=Fp) 308 | BLS_DLL_API int blsGetG1ByteSize(void); 309 | 310 | // return bytes for serialized Fr 311 | BLS_DLL_API int blsGetFrByteSize(void); 312 | 313 | // get a generator of PublicKey 314 | BLS_DLL_API void blsGetGeneratorOfPublicKey(blsPublicKey *pub); 315 | // set a generator of PublicKey 316 | BLS_DLL_API int blsSetGeneratorOfPublicKey(const blsPublicKey *pub); 317 | 318 | // return 0 if success 319 | BLS_DLL_API int blsIdSetDecStr(blsId *id, const char *buf, mclSize bufSize); 320 | BLS_DLL_API int blsIdSetHexStr(blsId *id, const char *buf, mclSize bufSize); 321 | 322 | /* 323 | return strlen(buf) if success else 0 324 | buf is '\0' terminated 325 | */ 326 | BLS_DLL_API mclSize blsIdGetDecStr(char *buf, mclSize maxBufSize, const blsId *id); 327 | BLS_DLL_API mclSize blsIdGetHexStr(char *buf, mclSize maxBufSize, const blsId *id); 328 | 329 | // hash buf and set SecretKey 330 | BLS_DLL_API int blsHashToSecretKey(blsSecretKey *sec, const void *buf, mclSize bufSize); 331 | // hash buf and set Signature 332 | BLS_DLL_API int blsHashToSignature(blsSignature *sig, const void *buf, mclSize bufSize); 333 | #ifndef MCL_DONT_USE_CSPRNG 334 | /* 335 | set secretKey if system has /dev/urandom or CryptGenRandom 336 | return 0 if success else -1 337 | */ 338 | BLS_DLL_API int blsSecretKeySetByCSPRNG(blsSecretKey *sec); 339 | /* 340 | set user-defined random function for setByCSPRNG 341 | @param self [in] user-defined pointer 342 | @param readFunc [in] user-defined function, 343 | which writes random bufSize bytes to buf and returns bufSize if success else returns 0 344 | @note if self == 0 and readFunc == 0 then set default random function 345 | @note not threadsafe 346 | */ 347 | BLS_DLL_API void blsSetRandFunc(void *self, unsigned int (*readFunc)(void *self, void *buf, unsigned int bufSize)); 348 | #endif 349 | 350 | BLS_DLL_API void blsGetPop(blsSignature *sig, const blsSecretKey *sec); 351 | 352 | BLS_DLL_API int blsVerifyPop(const blsSignature *sig, const blsPublicKey *pub); 353 | ////////////////////////////////////////////////////////////////////////// 354 | // the following apis will be removed 355 | 356 | // mask buf with (1 << (bitLen(r) - 1)) - 1 if buf >= r 357 | BLS_DLL_API int blsIdSetLittleEndian(blsId *id, const void *buf, mclSize bufSize); 358 | /* 359 | return written byte size if success else 0 360 | */ 361 | BLS_DLL_API mclSize blsIdGetLittleEndian(void *buf, mclSize maxBufSize, const blsId *id); 362 | 363 | // return 0 if success 364 | BLS_DLL_API int blsSecretKeySetDecStr(blsSecretKey *sec, const char *buf, mclSize bufSize); 365 | BLS_DLL_API int blsSecretKeySetHexStr(blsSecretKey *sec, const char *buf, mclSize bufSize); 366 | BLS_DLL_API int blsPublicKeySetHexStr(blsPublicKey *pub, const char *buf, mclSize bufSize); 367 | BLS_DLL_API int blsSignatureSetHexStr(blsSignature *sig, const char *buf, mclSize bufSize); 368 | /* 369 | return written byte size if success else 0 370 | */ 371 | BLS_DLL_API mclSize blsSecretKeyGetLittleEndian(void *buf, mclSize maxBufSize, const blsSecretKey *sec); 372 | /* 373 | return strlen(buf) if success else 0 374 | buf is '\0' terminated 375 | */ 376 | BLS_DLL_API mclSize blsSecretKeyGetDecStr(char *buf, mclSize maxBufSize, const blsSecretKey *sec); 377 | BLS_DLL_API mclSize blsSecretKeyGetHexStr(char *buf, mclSize maxBufSize, const blsSecretKey *sec); 378 | BLS_DLL_API mclSize blsPublicKeyGetHexStr(char *buf, mclSize maxBufSize, const blsPublicKey *pub); 379 | BLS_DLL_API mclSize blsSignatureGetHexStr(char *buf, mclSize maxBufSize, const blsSignature *sig); 380 | 381 | /* 382 | Diffie Hellman key exchange 383 | out = sec * pub 384 | */ 385 | BLS_DLL_API void blsDHKeyExchange(blsPublicKey *out, const blsSecretKey *sec, const blsPublicKey *pub); 386 | 387 | /* 388 | BLS Multi-Signatures With Public-Key Aggregation 389 | https://crypto.stanford.edu/~dabo/pubs/papers/BLSmultisig.html 390 | H(pubVec)_i := SHA-256(pubVec[0], ..., pubVec[n-1], 4-byte little endian(i)) 391 | @note 392 | 1. this hash function will be modifed in the future 393 | 2. sigVec and pubVec are not const because they may be normalized (the value are not changed) 394 | */ 395 | // aggSig = sum sigVec[i] t_i where (t_1, ..., t_n) = H({pubVec}) 396 | BLS_DLL_API void blsMultiAggregateSignature(blsSignature *aggSig, blsSignature *sigVec, blsPublicKey *pubVec, mclSize n); 397 | // aggPub = sum pubVec[i] t_i where (t_1, ..., t_n) = H({pubVec}) 398 | BLS_DLL_API void blsMultiAggregatePublicKey(blsPublicKey *aggPub, blsPublicKey *pubVec, mclSize n); 399 | #endif // BLS_MINIMUM_API 400 | 401 | #ifdef __cplusplus 402 | } 403 | #endif 404 | -------------------------------------------------------------------------------- /bls/bls_test.go: -------------------------------------------------------------------------------- 1 | package bls 2 | 3 | import ( 4 | "crypto/rand" 5 | "encoding/csv" 6 | "encoding/hex" 7 | "io" 8 | "io/ioutil" 9 | "os" 10 | "testing" 11 | ) 12 | 13 | func testUncompressedG1(t *testing.T, gen1 *G1) { 14 | buf, err := ioutil.ReadFile("tests/g1_uncompressed_valid_test_vectors.dat") 15 | if err != nil { 16 | t.Fatalf("ReadFile") 17 | } 18 | one := CastToPublicKey(gen1) 19 | var p1, p2 PublicKey 20 | for i := 0; i < 1000; i++ { 21 | if p1.DeserializeUncompressed(buf[i*96:(i+1)*96]) != nil { 22 | t.Fatalf("i=%d X.Deserialize", i) 23 | } 24 | if !p1.IsEqual(&p2) { 25 | t.Fatalf("i=%d p1=%x\np2=%x\n", i, p1.Serialize(), p2.Serialize()) 26 | } 27 | p2.Add(one) 28 | } 29 | } 30 | 31 | func testCompressedG1(t *testing.T, gen1 *G1) { 32 | buf, err := ioutil.ReadFile("tests/g1_compressed_valid_test_vectors.dat") 33 | if err != nil { 34 | t.Fatalf("ReadFile") 35 | } 36 | one := CastToPublicKey(gen1) 37 | var p1, p2 PublicKey 38 | for i := 0; i < 1000; i++ { 39 | if p1.Deserialize(buf[i*48:(i+1)*48]) != nil { 40 | t.Fatalf("err i=%d\n", i) 41 | } 42 | if !p1.IsEqual(&p2) { 43 | t.Fatalf("p1=%x\np2=%x\n", p1.Serialize(), p2.Serialize()) 44 | } 45 | p2.Add(one) 46 | } 47 | } 48 | 49 | func testUncompressedG2(t *testing.T, gen2 *G2) { 50 | buf, err := ioutil.ReadFile("tests/g2_uncompressed_valid_test_vectors.dat") 51 | if err != nil { 52 | t.Fatalf("ReadFile") 53 | } 54 | one := CastToSign(gen2) 55 | var p1, p2 Sign 56 | for i := 0; i < 1000; i++ { 57 | if p1.DeserializeUncompressed(buf[i*192:(i+1)*192]) != nil { 58 | t.Fatalf("i=%d X.Deserialize", i) 59 | } 60 | if !p1.IsEqual(&p2) { 61 | t.Fatalf("i=%d p1=%x\np2=%x\n", i, p1.Serialize(), p2.Serialize()) 62 | } 63 | p2.Add(one) 64 | } 65 | } 66 | 67 | func testCompressedG2(t *testing.T, gen2 *G2) { 68 | buf, err := ioutil.ReadFile("tests/g2_compressed_valid_test_vectors.dat") 69 | if err != nil { 70 | t.Fatalf("ReadFile") 71 | } 72 | one := CastToSign(gen2) 73 | var p1, p2 Sign 74 | for i := 0; i < 1000; i++ { 75 | if p1.Deserialize(buf[i*96:(i+1)*96]) != nil { 76 | t.Fatalf("err i=%d\n", i) 77 | } 78 | if !p1.IsEqual(&p2) { 79 | t.Fatalf("p1=%x\np2=%x\n", p1.Serialize(), p2.Serialize()) 80 | } 81 | p2.Add(one) 82 | } 83 | } 84 | 85 | func getSecPubHash() (*SecretKey, *PublicKey, []byte) { 86 | var sec SecretKey 87 | sec.SetByCSPRNG() 88 | pub := sec.GetPublicKey() 89 | var x Fp2 90 | x.D[0].SetByCSPRNG() 91 | x.D[1].SetByCSPRNG() 92 | hash := x.Serialize() 93 | return &sec, pub, hash 94 | } 95 | 96 | func testSignAndVerifyHash(t *testing.T) { 97 | sec, pub, hash := getSecPubHash() 98 | sig := sec.SignHash(hash) 99 | if sig == nil { 100 | t.Fatal("SignHash") 101 | } 102 | if !sig.VerifyHash(pub, hash) { 103 | t.Fatal("VerifyHash 1") 104 | } 105 | hash[0] = hash[0] + 1 106 | if sig.VerifyHash(pub, hash) { 107 | t.Fatal("VerifyHash 2") 108 | } 109 | } 110 | 111 | func getSecPubHashVec(n int) ([]PublicKey, [][]byte, []Sign) { 112 | pubVec := make([]PublicKey, n) 113 | hashVec := make([][]byte, n) 114 | sigVec := make([]Sign, n) 115 | var x Fp2 116 | var sec SecretKey 117 | for i := 0; i < n; i++ { 118 | sec.SetByCSPRNG() 119 | pubVec[i] = *sec.GetPublicKey() 120 | x.D[0].SetByCSPRNG() 121 | x.D[1].SetByCSPRNG() 122 | hashVec[i] = x.Serialize() 123 | sigVec[i] = *sec.SignHash(hashVec[i]) 124 | } 125 | return pubVec, hashVec, sigVec 126 | } 127 | 128 | func testVerifyAggreageteHash(t *testing.T) { 129 | const N = 100 130 | pubVec, hashVec, sigVec := getSecPubHashVec(N) 131 | agg := sigVec[0] 132 | for i := 1; i < N; i++ { 133 | agg.Add(&sigVec[i]) 134 | } 135 | if !agg.VerifyAggregateHashes(pubVec, hashVec) { 136 | t.Fatal("VerifyAggregateHashes 1") 137 | } 138 | hashVec[0][0] = hashVec[0][0] + 1 139 | if agg.VerifyAggregateHashes(pubVec, hashVec) { 140 | t.Fatal("VerifyAggregateHashes 2") 141 | } 142 | } 143 | 144 | func TestAreAllMsgDifferent(t *testing.T) { 145 | padTo32Bytes := func(b []byte) []byte { 146 | dst := [32]byte{} 147 | copy(dst[:], b) 148 | return dst[:] 149 | } 150 | makeMsg := func(b ...[]byte) []byte { 151 | var dst []byte 152 | for _, bb := range b { 153 | dst = append(dst, padTo32Bytes(bb)...) 154 | } 155 | return dst 156 | } 157 | type args struct { 158 | msgVec []byte 159 | } 160 | tests := []struct { 161 | name string 162 | args args 163 | want bool 164 | }{ 165 | { 166 | name: "all unique", 167 | args: args{ 168 | msgVec: makeMsg( 169 | []byte("a"), 170 | []byte("b"), 171 | []byte("c"), 172 | []byte("d"), 173 | []byte("e"), 174 | ), 175 | }, 176 | want: true, 177 | }, { 178 | name: "some duplicates", 179 | args: args{ 180 | msgVec: makeMsg( 181 | []byte("a"), 182 | []byte("b"), 183 | []byte("c"), 184 | []byte("a"), 185 | []byte("a"), 186 | ), 187 | }, 188 | want: false, 189 | }, { 190 | name: "long string1", 191 | args: args{ 192 | msgVec: makeMsg( 193 | []byte("abcdefg"), 194 | []byte("csadfasdfasereaaesfaefa"), 195 | []byte("01234567890123456789012345678901"), 196 | []byte("xxxxxxxxxxxxxxx"), 197 | []byte("xxxxxxxxxxxxxxxx"), 198 | []byte("xxxxxxxxxxxxxxxxx"), 199 | []byte("xxxxxxxxxxxxxxxxxx"), 200 | []byte("xxxxxxxxxxxxxxxxxxx"), 201 | []byte("xxxxxxxxxxxxxxxxxxxx"), 202 | []byte("xxxxxxxxxxxxxxxxxxxxx"), 203 | []byte("xxxxxxxxxxxxxxxxxxxxxx"), 204 | ), 205 | }, 206 | want: true, 207 | }, { 208 | name: "long string2", 209 | args: args{ 210 | msgVec: makeMsg( 211 | []byte("abcdefg"), 212 | []byte("csadfasdfasereaaesfaefa"), 213 | []byte("01234567890123456789012345678901"), 214 | []byte("xxxxxxxxxxxxxxx"), 215 | []byte("xxxxxxxxxxxxxxxx"), 216 | []byte("xxxxxxxxxxxxxxxxx"), 217 | []byte("xxxxxxxxxxxxxxxxxx"), 218 | []byte("xxxxxxxxxxxxxxxxxxx"), 219 | []byte("xxxxxxxxxxxxxxxxxxxx"), 220 | []byte("xxxxxxxxxxxxxxxxxxxxx"), 221 | []byte("xxxxxxxxxxxxxxxxxxxxxx"), 222 | []byte("01234567890123456789012345678901"), 223 | ), 224 | }, 225 | want: false, 226 | }, { 227 | name: "empty input", 228 | args: args{ 229 | msgVec: []byte{}, 230 | }, 231 | want: true, 232 | }, 233 | } 234 | for _, tt := range tests { 235 | t.Run(tt.name, func(t *testing.T) { 236 | if got := AreAllMsgDifferent(tt.args.msgVec); got != tt.want { 237 | t.Errorf("AreAllMsgDifferent() = %v, want %v", got, tt.want) 238 | } 239 | }) 240 | } 241 | } 242 | 243 | func ethSignOneTest(t *testing.T, secHex string, msgHex string, sigHex string) { 244 | var sec SecretKey 245 | if sec.DeserializeHexStr(secHex) != nil { 246 | t.Fatalf("bad sec") 247 | } 248 | var sig Sign 249 | if sig.DeserializeHexStr(sigHex) != nil { 250 | t.Logf("bad sig %v\n", sigHex) 251 | return 252 | } 253 | pub := sec.GetPublicKey() 254 | msg, _ := hex.DecodeString(msgHex) 255 | sig = *sec.SignByte(msg) 256 | if !sig.VerifyByte(pub, msg) { 257 | t.Fatalf("bad verify %v %v", secHex, msgHex) 258 | } 259 | s := sig.SerializeToHexStr() 260 | if s != sigHex { 261 | t.Fatalf("bad sign\nL=%v\nR=%v\nsec=%v\nmsg=%v", s, sigHex, secHex, msgHex) 262 | } 263 | } 264 | 265 | func ethVerifyOneTest(t *testing.T, pubHex string, msgHex string, sigHex string, outStr string) { 266 | var pub PublicKey 267 | if pub.DeserializeHexStr(pubHex) != nil { 268 | t.Fatalf("bad pub %v", pubHex) 269 | } 270 | var sig Sign 271 | if sig.DeserializeHexStr(sigHex) != nil { 272 | t.Logf("bad sig %v\n", sigHex) 273 | return 274 | } 275 | msg, _ := hex.DecodeString(msgHex) 276 | b := sig.VerifyByte(&pub, msg) 277 | expect := outStr == "true" 278 | if b != expect { 279 | t.Fatalf("bad verify\nL=%v\nR=%v\npub=%v\nmsg=%v\nsig=%v\n", b, expect, pubHex, msgHex, sigHex) 280 | } 281 | } 282 | 283 | func ethSignTest(t *testing.T) { 284 | fileName := "tests/sign.txt" 285 | fp, err := os.Open(fileName) 286 | if err != nil { 287 | t.Fatalf("can't open %v %v", fileName, err) 288 | } 289 | defer fp.Close() 290 | reader := csv.NewReader(fp) 291 | reader.Comma = ' ' 292 | for { 293 | secHex, err := reader.Read() 294 | if err == io.EOF { 295 | break 296 | } 297 | msgHex, _ := reader.Read() 298 | sigHex, _ := reader.Read() 299 | ethSignOneTest(t, secHex[1], msgHex[1], sigHex[1]) 300 | } 301 | } 302 | 303 | func ethVerifyTest(t *testing.T) { 304 | fileName := "tests/verify.txt" 305 | fp, err := os.Open(fileName) 306 | if err != nil { 307 | t.Fatalf("can't open %v %v", fileName, err) 308 | } 309 | defer fp.Close() 310 | reader := csv.NewReader(fp) 311 | reader.Comma = ' ' 312 | for { 313 | pubHex, err := reader.Read() 314 | if err == io.EOF { 315 | break 316 | } 317 | msgHex, _ := reader.Read() 318 | sigHex, _ := reader.Read() 319 | outStr, _ := reader.Read() 320 | ethVerifyOneTest(t, pubHex[1], msgHex[1], sigHex[1], outStr[1]) 321 | } 322 | } 323 | 324 | func ethFastAggregateVerifyTest(t *testing.T) { 325 | fileName := "tests/fast_aggregate_verify.txt" 326 | fp, err := os.Open(fileName) 327 | if err != nil { 328 | t.Fatalf("can't open %v %v", fileName, err) 329 | } 330 | defer fp.Close() 331 | 332 | reader := csv.NewReader(fp) 333 | reader.Comma = ' ' 334 | i := 0 335 | for { 336 | var pubVec []PublicKey 337 | var s []string 338 | var err error 339 | for { 340 | s, err = reader.Read() 341 | if err == io.EOF { 342 | return 343 | } 344 | if s[0] == "msg" { 345 | break 346 | } 347 | var pub PublicKey 348 | if pub.DeserializeHexStr(s[1]) != nil { 349 | t.Fatalf("bad signature") 350 | } 351 | pubVec = append(pubVec, pub) 352 | } 353 | t.Logf("i=%v\n", i) 354 | i++ 355 | msg, _ := hex.DecodeString(s[1]) 356 | sigHex, _ := reader.Read() 357 | outHex, _ := reader.Read() 358 | var sig Sign 359 | if sig.DeserializeHexStr(sigHex[1]) != nil { 360 | t.Logf("bad signature %v", sigHex[1]) 361 | continue 362 | } 363 | if !sig.IsValidOrder() { 364 | t.Logf("bad order %v", sigHex[1]) 365 | continue 366 | } 367 | out := outHex[1] == "true" 368 | if sig.FastAggregateVerify(pubVec, msg) != out { 369 | t.Fatalf("bad FastAggregateVerify") 370 | } 371 | } 372 | } 373 | 374 | func makeMultiSig(n int) (pubs []PublicKey, sigs []Sign, msgs []byte) { 375 | msgSize := 32 376 | pubs = make([]PublicKey, n) 377 | sigs = make([]Sign, n) 378 | msgs = make([]byte, n*msgSize) 379 | for i := 0; i < n; i++ { 380 | var sec SecretKey 381 | sec.SetByCSPRNG() 382 | pubs[i] = *sec.GetPublicKey() 383 | msgs[msgSize*i] = byte(i) 384 | sigs[i] = *sec.SignByte(msgs[msgSize*i : msgSize*(i+1)]) 385 | } 386 | return pubs, sigs, msgs 387 | } 388 | 389 | func blsAggregateVerifyNoCheckTestOne(t *testing.T, n int) { 390 | t.Logf("blsAggregateVerifyNoCheckTestOne %v\n", n) 391 | pubs, sigs, msgs := makeMultiSig(n) 392 | if !AreAllMsgDifferent(msgs) { 393 | t.Fatalf("bad msgs") 394 | } 395 | var aggSig Sign 396 | aggSig.Aggregate(sigs) 397 | if !aggSig.AggregateVerifyNoCheck(pubs, msgs) { 398 | t.Fatalf("bad AggregateVerifyNoCheck 1") 399 | } 400 | msgs[1] = 1 401 | if aggSig.AggregateVerifyNoCheck(pubs, msgs) { 402 | t.Fatalf("bad AggregateVerifyNoCheck 2") 403 | } 404 | } 405 | 406 | func blsAggregateVerifyNoCheckTest(t *testing.T) { 407 | nTbl := []int{1, 2, 15, 16, 17, 50} 408 | for i := 0; i < len(nTbl); i++ { 409 | blsAggregateVerifyNoCheckTestOne(t, nTbl[i]) 410 | } 411 | } 412 | 413 | func ethAggregateTest(t *testing.T) { 414 | fileName := "tests/aggregate.txt" 415 | fp, err := os.Open(fileName) 416 | if err != nil { 417 | t.Fatalf("can't open %v %v", fileName, err) 418 | } 419 | defer fp.Close() 420 | 421 | reader := csv.NewReader(fp) 422 | reader.Comma = ' ' 423 | i := 0 424 | for { 425 | t.Logf("ethAggregateTest i=%v\n", i) 426 | i++ 427 | var sigVec []Sign 428 | var s []string 429 | var err error 430 | for { 431 | s, err = reader.Read() 432 | if err == io.EOF { 433 | return 434 | } 435 | if s[0] == "out" { 436 | break 437 | } 438 | var sig Sign 439 | if sig.DeserializeHexStr(s[1]) != nil { 440 | t.Fatalf("bad signature") 441 | } 442 | sigVec = append(sigVec, sig) 443 | } 444 | var sig Sign 445 | if sig.DeserializeHexStr(s[1]) != nil { 446 | t.Logf("bad signature %v", s[1]) 447 | continue 448 | } 449 | var agg Sign 450 | agg.Aggregate(sigVec) 451 | if !agg.IsEqual(&sig) { 452 | t.Fatalf("bad aggregate") 453 | } 454 | } 455 | } 456 | 457 | func ethAggregateVerifyTest(t *testing.T) { 458 | fileName := "tests/aggregate_verify.txt" 459 | fp, err := os.Open(fileName) 460 | if err != nil { 461 | t.Fatalf("can't open %v %v", fileName, err) 462 | } 463 | defer fp.Close() 464 | 465 | reader := csv.NewReader(fp) 466 | reader.Comma = ' ' 467 | i := 0 468 | for { 469 | t.Logf("i=%v\n", i) 470 | i++ 471 | var pubVec []PublicKey 472 | var s []string 473 | var err error 474 | for { 475 | s, err = reader.Read() 476 | if err == io.EOF { 477 | return 478 | } 479 | if s[0] == "msg" { 480 | break 481 | } 482 | var pub PublicKey 483 | if pub.DeserializeHexStr(s[1]) != nil { 484 | t.Fatalf("bad signature") 485 | } 486 | pubVec = append(pubVec, pub) 487 | } 488 | msg, _ := hex.DecodeString(s[1]) 489 | for j := 1; j < len(pubVec); j++ { 490 | s, _ := reader.Read() 491 | b, _ := hex.DecodeString(s[1]) 492 | msg = append(msg, b...) 493 | } 494 | sigHex, _ := reader.Read() 495 | outHex, _ := reader.Read() 496 | var sig Sign 497 | if sig.DeserializeHexStr(sigHex[1]) != nil { 498 | t.Logf("bad signature %v", sigHex[1]) 499 | continue 500 | } 501 | out := outHex[1] == "true" 502 | b := sig.AggregateVerifyNoCheck(pubVec, msg) 503 | if b != out { 504 | t.Fatalf("bad AggregateVerify") 505 | } 506 | } 507 | } 508 | 509 | func testEthDraft07(t *testing.T) { 510 | secHex := "0000000000000000000000000000000000000000000000000000000000000001" 511 | msgHex := "61736466" 512 | sigHex := "b45a264e0d6f8614c4640ea97bae13effd3c74c4e200e3b1596d6830debc952602a7d210eca122dc4f596fa01d7f6299106933abd29477606f64588595e18349afe22ecf2aeeeb63753e88a42ef85b24140847e05620a28422f8c30f1d33b9aa" 513 | ethSignOneTest(t, secHex, msgHex, sigHex) 514 | ethSignTest(t) 515 | ethFastAggregateVerifyTest(t) 516 | ethVerifyTest(t) 517 | ethAggregateTest(t) 518 | ethAggregateVerifyTest(t) 519 | blsAggregateVerifyNoCheckTest(t) 520 | } 521 | 522 | func testMultiVerifyOne(n int) bool { 523 | pubs, sigs, msgs := makeMultiSig(n) 524 | return MultiVerify(sigs, pubs, msgs) 525 | } 526 | 527 | func testMultiVerify(t *testing.T) { 528 | tbl := []int{1, 2, 15, 16, 17, 50, 50, 100, 200, 400} 529 | for i := 0; i < len(tbl); i++ { 530 | n := tbl[i] 531 | ret := testMultiVerifyOne(n) 532 | if !ret { 533 | t.Fatalf("testMultiVerifyOne n=%v ret=%v\n", n, ret) 534 | } 535 | } 536 | } 537 | 538 | func testGetSafePublicKey(t *testing.T) { 539 | var sec SecretKey 540 | pub, err := sec.GetSafePublicKey() 541 | if pub != nil || err == nil { 542 | t.Fatalf("sec must be zero") 543 | } 544 | sec.SetByCSPRNG() 545 | pub, err = sec.GetSafePublicKey() 546 | if pub == nil || err != nil { 547 | t.Fatalf("sec must be non-zero") 548 | } 549 | } 550 | 551 | func Test(t *testing.T) { 552 | if Init(BLS12_381) != nil { 553 | t.Fatalf("Init") 554 | } 555 | var gen1 G1 556 | if gen1.SetString("1 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb 0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", 16) != nil { 557 | t.Fatalf("gen1.SetString") 558 | } 559 | var gen2 G2 560 | if gen2.SetString("1 0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e 0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801 0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", 16) != nil { 561 | t.Fatalf("gen2.SetString") 562 | } 563 | 564 | testUncompressedG1(t, &gen1) 565 | testCompressedG1(t, &gen1) 566 | testUncompressedG2(t, &gen2) 567 | testCompressedG2(t, &gen2) 568 | testSignAndVerifyHash(t) 569 | testVerifyAggreageteHash(t) 570 | testEthDraft07(t) 571 | testMultiVerify(t) 572 | testGetSafePublicKey(t) 573 | } 574 | 575 | func BenchmarkPairing(b *testing.B) { 576 | b.StopTimer() 577 | err := Init(BLS12_381) 578 | if err != nil { 579 | b.Fatal(err) 580 | } 581 | var P G1 582 | var Q G2 583 | var e GT 584 | P.HashAndMapTo([]byte("abc")) 585 | Q.HashAndMapTo([]byte("abc")) 586 | b.StartTimer() 587 | for n := 0; n < b.N; n++ { 588 | Pairing(&e, &P, &Q) 589 | } 590 | b.StopTimer() 591 | } 592 | 593 | func BenchmarkSignHash(b *testing.B) { 594 | b.StopTimer() 595 | err := Init(BLS12_381) 596 | if err != nil { 597 | b.Fatal(err) 598 | } 599 | sec, _, hash := getSecPubHash() 600 | b.StartTimer() 601 | for n := 0; n < b.N; n++ { 602 | sec.SignHash(hash) 603 | } 604 | b.StopTimer() 605 | } 606 | 607 | func BenchmarkVerifyHash(b *testing.B) { 608 | b.StopTimer() 609 | err := Init(BLS12_381) 610 | if err != nil { 611 | b.Fatal(err) 612 | } 613 | sec, pub, hash := getSecPubHash() 614 | sig := sec.SignHash(hash) 615 | b.StartTimer() 616 | for n := 0; n < b.N; n++ { 617 | sig.VerifyHash(pub, hash) 618 | } 619 | b.StopTimer() 620 | } 621 | 622 | func BenchmarkVerifyAggreageteHash(b *testing.B) { 623 | b.StopTimer() 624 | err := Init(BLS12_381) 625 | if err != nil { 626 | b.Fatal(err) 627 | } 628 | const N = 50 629 | pubVec, hashVec, sigVec := getSecPubHashVec(N) 630 | agg := sigVec[0] 631 | for i := 1; i < N; i++ { 632 | agg.Add(&sigVec[i]) 633 | } 634 | b.StartTimer() 635 | for n := 0; n < b.N; n++ { 636 | agg.VerifyAggregateHashes(pubVec, hashVec) 637 | } 638 | } 639 | 640 | func BenchmarkDeserialization1(b *testing.B) { 641 | b.StopTimer() 642 | err := Init(BLS12_381) 643 | if err != nil { 644 | b.Fatal(err) 645 | } 646 | VerifyOrderG1(false) 647 | VerifyOrderG2(false) 648 | const N = 50 649 | sec, _, hash := getSecPubHash() 650 | sig := sec.SignHash(hash) 651 | buf := sig.Serialize() 652 | b.StartTimer() 653 | for n := 0; n < b.N; n++ { 654 | sig.Deserialize(buf) 655 | } 656 | } 657 | 658 | func BenchmarkDeserialization2(b *testing.B) { 659 | b.StopTimer() 660 | err := Init(BLS12_381) 661 | if err != nil { 662 | b.Fatal(err) 663 | } 664 | VerifyOrderG1(true) 665 | VerifyOrderG2(true) 666 | const N = 50 667 | sec, _, hash := getSecPubHash() 668 | sig := sec.SignHash(hash) 669 | buf := sig.Serialize() 670 | b.StartTimer() 671 | for n := 0; n < b.N; n++ { 672 | sig.Deserialize(buf) 673 | } 674 | } 675 | 676 | func BenchmarkAreAllMsgDifferent(b *testing.B) { 677 | b.StopTimer() 678 | const N = 32 * 3000 679 | msgVec := make([]byte, N) 680 | rand.Read(msgVec) 681 | b.StartTimer() 682 | for i := 0; i < b.N; i++ { 683 | AreAllMsgDifferent(msgVec) 684 | } 685 | } 686 | 687 | func NaieveMultiVerify(sigs []Sign, pubs []PublicKey, concatenatedMsg []byte) bool { 688 | msgSize := 32 689 | n := len(sigs) 690 | if n == 0 || len(pubs) != n || len(concatenatedMsg) != n*msgSize { 691 | return false 692 | } 693 | for i := 0; i < n; i++ { 694 | if !sigs[i].VerifyByte(&pubs[i], concatenatedMsg[msgSize*i:msgSize*(i+1)]) { 695 | return false 696 | } 697 | } 698 | return true 699 | } 700 | 701 | func BenchmarkNaieveMultiVerify(b *testing.B) { 702 | b.StopTimer() 703 | pubs, sigs, msgs := makeMultiSig(400) 704 | b.StartTimer() 705 | for i := 0; i < b.N; i++ { 706 | NaieveMultiVerify(sigs, pubs, msgs) 707 | } 708 | } 709 | 710 | func BenchmarkMultiVerify(b *testing.B) { 711 | b.StopTimer() 712 | pubs, sigs, msgs := makeMultiSig(400) 713 | b.StartTimer() 714 | for i := 0; i < b.N; i++ { 715 | MultiVerify(sigs, pubs, msgs) 716 | } 717 | } 718 | -------------------------------------------------------------------------------- /bls/bls.go: -------------------------------------------------------------------------------- 1 | package bls 2 | 3 | /* 4 | #cgo CFLAGS:-I${SRCDIR}./include -DBLS_ETH 5 | typedef unsigned int (*ReadRandFunc)(void *, void *, unsigned int); 6 | int wrapReadRandCgo(void *self, void *buf, unsigned int n); 7 | #include 8 | #include 9 | */ 10 | import "C" 11 | import ( 12 | "encoding/hex" 13 | "encoding/json" 14 | "fmt" 15 | "io" 16 | "unsafe" 17 | ) 18 | 19 | const ethMode = true 20 | 21 | const EthModeOld = C.BLS_ETH_MODE_OLD 22 | const EthModeDraft05 = C.BLS_ETH_MODE_DRAFT_05 23 | const EthModeDraft06 = C.BLS_ETH_MODE_DRAFT_06 24 | const EthModeDraft07 = C.BLS_ETH_MODE_DRAFT_07 25 | const EthModeLatest = C.BLS_ETH_MODE_LATEST 26 | 27 | func hex2byte(s string) ([]byte, error) { 28 | if (len(s) & 1) == 1 { 29 | return nil, fmt.Errorf("odd length") 30 | } 31 | return hex.DecodeString(s) 32 | } 33 | 34 | // SetETHmode -- 35 | // Set hash function 36 | // mode = EthModeOld or EthModeLatest(=EthModeDraft07) 37 | // error if curve != MCL_BLS12_381 38 | func SetETHmode(mode int) error { 39 | if C.blsSetETHmode(C.int(mode)) != 0 { 40 | return fmt.Errorf("ERR SetETHmode") 41 | } 42 | return nil 43 | } 44 | 45 | // Init -- 46 | // call this function before calling all the other operations 47 | // this function is not thread safe 48 | func Init(curve int) error { 49 | err := C.blsInit(C.int(curve), C.MCLBN_COMPILED_TIME_VAR) 50 | if err != 0 { 51 | return fmt.Errorf("ERR Init curve=%d", curve) 52 | } 53 | if !ethMode { 54 | return nil 55 | } 56 | return SetETHmode(C.BLS_ETH_MODE_LATEST) 57 | } 58 | 59 | // ID -- 60 | type ID struct { 61 | v C.blsId 62 | } 63 | 64 | // Serialize -- 65 | func (id *ID) Serialize() []byte { 66 | buf := make([]byte, 2048) 67 | // #nosec 68 | n := C.blsIdSerialize(unsafe.Pointer(&buf[0]), C.mclSize(len(buf)), &id.v) 69 | if n == 0 { 70 | panic("err blsIdSerialize") 71 | } 72 | return buf[:n] 73 | } 74 | 75 | // Deserialize -- 76 | func (id *ID) Deserialize(buf []byte) error { 77 | // #nosec 78 | n := C.blsIdDeserialize(&id.v, getPointer(buf), C.mclSize(len(buf))) 79 | if n == 0 || int(n) != len(buf) { 80 | return fmt.Errorf("err blsIdDeserialize %x", buf) 81 | } 82 | return nil 83 | } 84 | 85 | // GetLittleEndian -- alias of Serialize 86 | func (id *ID) GetLittleEndian() []byte { 87 | return id.Serialize() 88 | } 89 | 90 | // SetLittleEndian -- 91 | func (id *ID) SetLittleEndian(buf []byte) error { 92 | // #nosec 93 | err := C.blsIdSetLittleEndian(&id.v, getPointer(buf), C.mclSize(len(buf))) 94 | if err != 0 { 95 | return fmt.Errorf("err blsIdSetLittleEndian %x", err) 96 | } 97 | return nil 98 | } 99 | 100 | // SerializeToHexStr -- 101 | func (id *ID) SerializeToHexStr() string { 102 | return hex.EncodeToString(id.Serialize()) 103 | } 104 | 105 | // DeserializeHexStr -- 106 | func (id *ID) DeserializeHexStr(s string) error { 107 | a, err := hex2byte(s) 108 | if err != nil { 109 | return err 110 | } 111 | return id.Deserialize(a) 112 | } 113 | 114 | // GetHexString -- 115 | func (id *ID) GetHexString() string { 116 | buf := make([]byte, 2048) 117 | // #nosec 118 | n := C.blsIdGetHexStr((*C.char)(unsafe.Pointer(&buf[0])), C.mclSize(len(buf)), &id.v) 119 | if n == 0 { 120 | panic("err blsIdGetHexStr") 121 | } 122 | return string(buf[:n]) 123 | } 124 | 125 | // GetDecString -- 126 | func (id *ID) GetDecString() string { 127 | buf := make([]byte, 2048) 128 | // #nosec 129 | n := C.blsIdGetDecStr((*C.char)(unsafe.Pointer(&buf[0])), C.mclSize(len(buf)), &id.v) 130 | if n == 0 { 131 | panic("err blsIdGetDecStr") 132 | } 133 | return string(buf[:n]) 134 | } 135 | 136 | // SetHexString -- 137 | func (id *ID) SetHexString(s string) error { 138 | buf := []byte(s) 139 | // #nosec 140 | err := C.blsIdSetHexStr(&id.v, (*C.char)(getPointer(buf)), C.mclSize(len(buf))) 141 | if err != 0 { 142 | return fmt.Errorf("err blsIdSetHexStr %s", s) 143 | } 144 | return nil 145 | } 146 | 147 | // SetDecString -- 148 | func (id *ID) SetDecString(s string) error { 149 | buf := []byte(s) 150 | // #nosec 151 | err := C.blsIdSetDecStr(&id.v, (*C.char)(getPointer(buf)), C.mclSize(len(buf))) 152 | if err != 0 { 153 | return fmt.Errorf("err blsIdSetDecStr %s", s) 154 | } 155 | return nil 156 | } 157 | 158 | // IsEqual -- 159 | func (id *ID) IsEqual(rhs *ID) bool { 160 | if id == nil || rhs == nil { 161 | return false 162 | } 163 | return C.blsIdIsEqual(&id.v, &rhs.v) == 1 164 | } 165 | 166 | // SecretKey -- 167 | type SecretKey struct { 168 | v C.blsSecretKey 169 | } 170 | 171 | // Serialize -- 172 | func (sec *SecretKey) Serialize() []byte { 173 | buf := make([]byte, C.mclBn_getFpByteSize()) 174 | // #nosec 175 | n := C.blsSecretKeySerialize(unsafe.Pointer(&buf[0]), C.mclSize(len(buf)), &sec.v) 176 | if n == 0 { 177 | panic("err blsSecretKeySerialize") 178 | } 179 | return buf[:n] 180 | } 181 | 182 | // Deserialize -- 183 | func (sec *SecretKey) Deserialize(buf []byte) error { 184 | // #nosec 185 | n := C.blsSecretKeyDeserialize(&sec.v, getPointer(buf), C.mclSize(len(buf))) 186 | if n == 0 || int(n) != len(buf) { 187 | return fmt.Errorf("err blsSecretKeyDeserialize %x", buf) 188 | } 189 | return nil 190 | } 191 | 192 | // GetLittleEndian -- alias of Serialize 193 | func (sec *SecretKey) GetLittleEndian() []byte { 194 | return sec.Serialize() 195 | } 196 | 197 | // SetLittleEndian -- 198 | func (sec *SecretKey) SetLittleEndian(buf []byte) error { 199 | // #nosec 200 | err := C.blsSecretKeySetLittleEndian(&sec.v, getPointer(buf), C.mclSize(len(buf))) 201 | if err != 0 { 202 | return fmt.Errorf("err blsSecretKeySetLittleEndian %x", err) 203 | } 204 | return nil 205 | } 206 | 207 | // SetLittleEndianMod -- 208 | func (sec *SecretKey) SetLittleEndianMod(buf []byte) error { 209 | // #nosec 210 | err := C.blsSecretKeySetLittleEndianMod(&sec.v, getPointer(buf), C.mclSize(len(buf))) 211 | if err != 0 { 212 | return fmt.Errorf("err blsSecretKeySetLittleEndianMod %x", err) 213 | } 214 | return nil 215 | } 216 | 217 | // SerializeToHexStr -- 218 | func (sec *SecretKey) SerializeToHexStr() string { 219 | return hex.EncodeToString(sec.Serialize()) 220 | } 221 | 222 | // DeserializeHexStr -- 223 | func (sec *SecretKey) DeserializeHexStr(s string) error { 224 | a, err := hex2byte(s) 225 | if err != nil { 226 | return err 227 | } 228 | return sec.Deserialize(a) 229 | } 230 | 231 | // GetHexString -- 232 | func (sec *SecretKey) GetHexString() string { 233 | buf := make([]byte, 2048) 234 | // #nosec 235 | n := C.blsSecretKeyGetHexStr((*C.char)(unsafe.Pointer(&buf[0])), C.mclSize(len(buf)), &sec.v) 236 | if n == 0 { 237 | panic("err blsSecretKeyGetHexStr") 238 | } 239 | return string(buf[:n]) 240 | } 241 | 242 | // GetDecString -- 243 | func (sec *SecretKey) GetDecString() string { 244 | buf := make([]byte, 2048) 245 | // #nosec 246 | n := C.blsSecretKeyGetDecStr((*C.char)(unsafe.Pointer(&buf[0])), C.mclSize(len(buf)), &sec.v) 247 | if n == 0 { 248 | panic("err blsSecretKeyGetDecStr") 249 | } 250 | return string(buf[:n]) 251 | } 252 | 253 | // SetHexString -- 254 | func (sec *SecretKey) SetHexString(s string) error { 255 | buf := []byte(s) 256 | // #nosec 257 | err := C.blsSecretKeySetHexStr(&sec.v, (*C.char)(getPointer(buf)), C.mclSize(len(buf))) 258 | if err != 0 { 259 | return fmt.Errorf("err blsSecretKeySetHexStr %s", s) 260 | } 261 | return nil 262 | } 263 | 264 | // SetDecString -- 265 | func (sec *SecretKey) SetDecString(s string) error { 266 | buf := []byte(s) 267 | // #nosec 268 | err := C.blsSecretKeySetDecStr(&sec.v, (*C.char)(getPointer(buf)), C.mclSize(len(buf))) 269 | if err != 0 { 270 | return fmt.Errorf("err blsSecretKeySetDecStr %s", s) 271 | } 272 | return nil 273 | } 274 | 275 | // IsEqual -- 276 | func (sec *SecretKey) IsEqual(rhs *SecretKey) bool { 277 | if sec == nil || rhs == nil { 278 | return false 279 | } 280 | return C.blsSecretKeyIsEqual(&sec.v, &rhs.v) == 1 281 | } 282 | 283 | // IsZero -- 284 | func (sec *SecretKey) IsZero() bool { 285 | return C.blsSecretKeyIsZero(&sec.v) == 1 286 | } 287 | 288 | // SetByCSPRNG -- 289 | func (sec *SecretKey) SetByCSPRNG() { 290 | err := C.blsSecretKeySetByCSPRNG(&sec.v) 291 | if err != 0 { 292 | panic("err blsSecretKeySetByCSPRNG") 293 | } 294 | if sec.IsZero() { 295 | panic("err blsSecretKeySetByCSPRNG zero") 296 | } 297 | } 298 | 299 | // Add -- 300 | func (sec *SecretKey) Add(rhs *SecretKey) { 301 | C.blsSecretKeyAdd(&sec.v, &rhs.v) 302 | } 303 | 304 | // GetMasterSecretKey -- 305 | func (sec *SecretKey) GetMasterSecretKey(k int) (msk []SecretKey) { 306 | msk = make([]SecretKey, k) 307 | msk[0] = *sec 308 | for i := 1; i < k; i++ { 309 | msk[i].SetByCSPRNG() 310 | } 311 | return msk 312 | } 313 | 314 | // GetMasterPublicKey -- 315 | func GetMasterPublicKey(msk []SecretKey) (mpk []PublicKey) { 316 | n := len(msk) 317 | mpk = make([]PublicKey, n) 318 | for i := 0; i < n; i++ { 319 | mpk[i] = *msk[i].GetPublicKey() 320 | } 321 | return mpk 322 | } 323 | 324 | // Set -- 325 | func (sec *SecretKey) Set(msk []SecretKey, id *ID) error { 326 | if len(msk) == 0 { 327 | return fmt.Errorf("Set zero mask") 328 | } 329 | // #nosec 330 | ret := C.blsSecretKeyShare(&sec.v, &msk[0].v, (C.mclSize)(len(msk)), &id.v) 331 | if ret != 0 { 332 | return fmt.Errorf("err blsSecretKeyShare") 333 | } 334 | return nil 335 | } 336 | 337 | // Recover -- 338 | func (sec *SecretKey) Recover(secVec []SecretKey, idVec []ID) error { 339 | n := len(secVec) 340 | if n == 0 { 341 | return fmt.Errorf("Recover zero secVec") 342 | } 343 | if n != len(idVec) { 344 | return fmt.Errorf("err SecretKey.Recover bad size") 345 | } 346 | // #nosec 347 | ret := C.blsSecretKeyRecover(&sec.v, &secVec[0].v, (*C.blsId)(&idVec[0].v), (C.mclSize)(n)) 348 | if ret != 0 { 349 | return fmt.Errorf("err blsSecretKeyRecover") 350 | } 351 | return nil 352 | } 353 | 354 | // GetPop -- 355 | func (sec *SecretKey) GetPop() (sig *Sign) { 356 | sig = new(Sign) 357 | C.blsGetPop(&sig.v, &sec.v) 358 | return sig 359 | } 360 | 361 | // PublicKey -- 362 | type PublicKey struct { 363 | v C.blsPublicKey 364 | } 365 | 366 | // PublicKeys .. 367 | type PublicKeys []PublicKey 368 | 369 | // JSON provides a JSON string dump of slice of PublicKeys in Hexformat 370 | func (keys PublicKeys) JSON() string { 371 | type T struct { 372 | Count int `json:"count"` 373 | PublicKeys []string `json:"public-keys"` 374 | } 375 | t := T{len(keys), make([]string, len(keys))} 376 | for i := range keys { 377 | t.PublicKeys[i] = keys[i].SerializeToHexStr() 378 | } 379 | b, _ := json.Marshal(t) 380 | return string(b) 381 | } 382 | 383 | // Serialize -- 384 | func (pub *PublicKey) Serialize() []byte { 385 | buf := make([]byte, C.blsGetSerializedPublicKeyByteSize()) 386 | // #nosec 387 | n := C.blsPublicKeySerialize(unsafe.Pointer(&buf[0]), C.mclSize(len(buf)), &pub.v) 388 | if n == 0 { 389 | panic("err blsPublicKeySerialize") 390 | } 391 | return buf[:n] 392 | } 393 | 394 | // Deserialize -- 395 | func (pub *PublicKey) Deserialize(buf []byte) error { 396 | // #nosec 397 | n := C.blsPublicKeyDeserialize(&pub.v, getPointer(buf), C.mclSize(len(buf))) 398 | if n == 0 || int(n) != len(buf) { 399 | return fmt.Errorf("err blsPublicKeyDeserialize %x", buf) 400 | } 401 | return nil 402 | } 403 | 404 | // SerializeToHexStr -- 405 | func (pub *PublicKey) SerializeToHexStr() string { 406 | return hex.EncodeToString(pub.Serialize()) 407 | } 408 | 409 | // DeserializeHexStr -- 410 | func (pub *PublicKey) DeserializeHexStr(s string) error { 411 | a, err := hex2byte(s) 412 | if err != nil { 413 | return err 414 | } 415 | return pub.Deserialize(a) 416 | } 417 | 418 | // GetHexString -- 419 | func (pub *PublicKey) GetHexString() string { 420 | buf := make([]byte, 2048) 421 | // #nosec 422 | n := C.blsPublicKeyGetHexStr((*C.char)(unsafe.Pointer(&buf[0])), C.mclSize(len(buf)), &pub.v) 423 | if n == 0 { 424 | panic("err blsPublicKeyGetHexStr") 425 | } 426 | return string(buf[:n]) 427 | } 428 | 429 | // SetHexString -- 430 | func (pub *PublicKey) SetHexString(s string) error { 431 | buf := []byte(s) 432 | // #nosec 433 | err := C.blsPublicKeySetHexStr(&pub.v, (*C.char)(getPointer(buf)), C.mclSize(len(buf))) 434 | if err != 0 { 435 | return fmt.Errorf("err blsPublicKeySetHexStr %s", s) 436 | } 437 | return nil 438 | } 439 | 440 | // IsEqual -- 441 | func (pub *PublicKey) IsEqual(rhs *PublicKey) bool { 442 | if pub == nil || rhs == nil { 443 | return false 444 | } 445 | return C.blsPublicKeyIsEqual(&pub.v, &rhs.v) == 1 446 | } 447 | 448 | // IsZero -- 449 | func (pub *PublicKey) IsZero() bool { 450 | return C.blsPublicKeyIsZero(&pub.v) == 1 451 | } 452 | 453 | // Add -- 454 | func (pub *PublicKey) Add(rhs *PublicKey) { 455 | C.blsPublicKeyAdd(&pub.v, &rhs.v) 456 | } 457 | 458 | // Set -- 459 | func (pub *PublicKey) Set(mpk []PublicKey, id *ID) error { 460 | if len(mpk) == 0 { 461 | return fmt.Errorf("Set zero mpk") 462 | } 463 | // #nosec 464 | ret := C.blsPublicKeyShare(&pub.v, &mpk[0].v, (C.mclSize)(len(mpk)), &id.v) 465 | if ret != 0 { 466 | return fmt.Errorf("err blsPublicKeyShare") 467 | } 468 | return nil 469 | } 470 | 471 | // Recover -- 472 | func (pub *PublicKey) Recover(pubVec []PublicKey, idVec []ID) error { 473 | n := len(pubVec) 474 | if n == 0 { 475 | return fmt.Errorf("Recover zero pubVec") 476 | } 477 | if n != len(idVec) { 478 | return fmt.Errorf("err PublicKey.Recover bad size") 479 | } 480 | // #nosec 481 | ret := C.blsPublicKeyRecover(&pub.v, &pubVec[0].v, (*C.blsId)(&idVec[0].v), (C.mclSize)(n)) 482 | if ret != 0 { 483 | return fmt.Errorf("err blsPublicKeyRecover") 484 | } 485 | return nil 486 | } 487 | 488 | // Sign -- 489 | type Sign struct { 490 | v C.blsSignature 491 | } 492 | 493 | // Serialize -- 494 | func (sig *Sign) Serialize() []byte { 495 | buf := make([]byte, C.blsGetSerializedSignatureByteSize()) 496 | // #nosec 497 | n := C.blsSignatureSerialize(unsafe.Pointer(&buf[0]), C.mclSize(len(buf)), &sig.v) 498 | if n == 0 { 499 | panic("err blsSignatureSerialize") 500 | } 501 | return buf[:n] 502 | } 503 | 504 | // Deserialize -- 505 | func (sig *Sign) Deserialize(buf []byte) error { 506 | // #nosec 507 | n := C.blsSignatureDeserialize(&sig.v, getPointer(buf), C.mclSize(len(buf))) 508 | if n == 0 || int(n) != len(buf) { 509 | return fmt.Errorf("err blsSignatureDeserialize %x", buf) 510 | } 511 | return nil 512 | } 513 | 514 | // SerializeToHexStr -- 515 | func (sig *Sign) SerializeToHexStr() string { 516 | return hex.EncodeToString(sig.Serialize()) 517 | } 518 | 519 | // DeserializeHexStr -- 520 | func (sig *Sign) DeserializeHexStr(s string) error { 521 | a, err := hex2byte(s) 522 | if err != nil { 523 | return err 524 | } 525 | return sig.Deserialize(a) 526 | } 527 | 528 | // GetHexString -- 529 | func (sig *Sign) GetHexString() string { 530 | buf := make([]byte, 2048) 531 | // #nosec 532 | n := C.blsSignatureGetHexStr((*C.char)(unsafe.Pointer(&buf[0])), C.mclSize(len(buf)), &sig.v) 533 | if n == 0 { 534 | panic("err blsSignatureGetHexStr") 535 | } 536 | return string(buf[:n]) 537 | } 538 | 539 | // SetHexString -- 540 | func (sig *Sign) SetHexString(s string) error { 541 | buf := []byte(s) 542 | // #nosec 543 | err := C.blsSignatureSetHexStr(&sig.v, (*C.char)(getPointer(buf)), C.mclSize(len(buf))) 544 | if err != 0 { 545 | return fmt.Errorf("err blsSignatureSetHexStr %s", s) 546 | } 547 | return nil 548 | } 549 | 550 | // IsEqual -- 551 | func (sig *Sign) IsEqual(rhs *Sign) bool { 552 | if sig == nil || rhs == nil { 553 | return false 554 | } 555 | return C.blsSignatureIsEqual(&sig.v, &rhs.v) == 1 556 | } 557 | 558 | // IsZero -- 559 | func (sig *Sign) IsZero() bool { 560 | return C.blsSignatureIsZero(&sig.v) == 1 561 | } 562 | 563 | // GetPublicKey -- 564 | func (sec *SecretKey) GetPublicKey() (pub *PublicKey) { 565 | pub = new(PublicKey) 566 | C.blsGetPublicKey(&pub.v, &sec.v) 567 | return pub 568 | } 569 | 570 | // GetSafePublicKey -- error if sec is zero 571 | func (sec *SecretKey) GetSafePublicKey() (pub *PublicKey, err error) { 572 | if sec.IsZero() { 573 | return nil, fmt.Errorf("sec is zero") 574 | } 575 | pub = new(PublicKey) 576 | C.blsGetPublicKey(&pub.v, &sec.v) 577 | return pub, nil 578 | } 579 | 580 | // Sign -- Constant Time version 581 | func (sec *SecretKey) Sign(m string) (sig *Sign) { 582 | sig = new(Sign) 583 | buf := []byte(m) 584 | // #nosec 585 | C.blsSign(&sig.v, &sec.v, getPointer(buf), C.mclSize(len(buf))) 586 | return sig 587 | } 588 | 589 | // Add -- 590 | func (sig *Sign) Add(rhs *Sign) { 591 | C.blsSignatureAdd(&sig.v, &rhs.v) 592 | } 593 | 594 | // Recover -- 595 | func (sig *Sign) Recover(sigVec []Sign, idVec []ID) error { 596 | if len(sigVec) == 0 { 597 | return fmt.Errorf("Recover zero sigVec") 598 | } 599 | if len(sigVec) != len(idVec) { 600 | return fmt.Errorf("err Sign.Recover bad size") 601 | } 602 | // #nosec 603 | ret := C.blsSignatureRecover(&sig.v, &sigVec[0].v, (*C.blsId)(&idVec[0].v), (C.mclSize)(len(idVec))) 604 | if ret != 0 { 605 | return fmt.Errorf("err blsSignatureRecover") 606 | } 607 | return nil 608 | } 609 | 610 | // Verify -- 611 | func (sig *Sign) Verify(pub *PublicKey, m string) bool { 612 | if sig == nil || pub == nil { 613 | return false 614 | } 615 | buf := []byte(m) 616 | // #nosec 617 | return C.blsVerify(&sig.v, &pub.v, getPointer(buf), C.mclSize(len(buf))) == 1 618 | } 619 | 620 | func bool2int(b bool) C.int { 621 | if b { 622 | return 1 623 | } 624 | return 0 625 | } 626 | 627 | // VerifySignatureOrder -- 628 | func VerifySignatureOrder(doVerify bool) { 629 | C.blsSignatureVerifyOrder(bool2int(doVerify)) 630 | } 631 | 632 | // VerifyPublicKeyOrder -- 633 | func VerifyPublicKeyOrder(doVerify bool) { 634 | C.blsPublicKeyVerifyOrder(bool2int(doVerify)) 635 | } 636 | 637 | // IsValidOrder -- 638 | func (pub *PublicKey) IsValidOrder() bool { 639 | return C.blsPublicKeyIsValidOrder(&pub.v) == 1 640 | } 641 | 642 | // IsValidOrder -- 643 | func (sig *Sign) IsValidOrder() bool { 644 | return C.blsSignatureIsValidOrder(&sig.v) == 1 645 | } 646 | 647 | // VerifyPop -- 648 | func (sig *Sign) VerifyPop(pub *PublicKey) bool { 649 | if sig == nil || pub == nil { 650 | return false 651 | } 652 | return C.blsVerifyPop(&sig.v, &pub.v) == 1 653 | } 654 | 655 | // DHKeyExchange -- 656 | func DHKeyExchange(sec *SecretKey, pub *PublicKey) (out PublicKey) { 657 | C.blsDHKeyExchange(&out.v, &sec.v, &pub.v) 658 | return out 659 | } 660 | 661 | // HashAndMapToSignature -- 662 | func HashAndMapToSignature(buf []byte) *Sign { 663 | sig := new(Sign) 664 | // #nosec 665 | err := C.blsHashToSignature(&sig.v, getPointer(buf), C.mclSize(len(buf))) 666 | if err != 0 { 667 | return nil 668 | } 669 | return sig 670 | } 671 | 672 | // VerifyPairing -- 673 | func VerifyPairing(X *Sign, Y *Sign, pub *PublicKey) bool { 674 | if X == nil || Y == nil || pub == nil { 675 | return false 676 | } 677 | return C.blsVerifyPairing(&X.v, &Y.v, &pub.v) == 1 678 | } 679 | 680 | // SignHash -- 681 | func (sec *SecretKey) SignHash(hash []byte) (sig *Sign) { 682 | sig = new(Sign) 683 | // #nosec 684 | err := C.blsSignHash(&sig.v, &sec.v, getPointer(hash), C.mclSize(len(hash))) 685 | if err == 0 { 686 | return sig 687 | } 688 | return nil 689 | } 690 | 691 | // VerifyHash -- 692 | func (sig *Sign) VerifyHash(pub *PublicKey, hash []byte) bool { 693 | if pub == nil { 694 | return false 695 | } 696 | // #nosec 697 | return C.blsVerifyHash(&sig.v, &pub.v, getPointer(hash), C.mclSize(len(hash))) == 1 698 | } 699 | 700 | // VerifyAggregateHashes -- 701 | func (sig *Sign) VerifyAggregateHashes(pubVec []PublicKey, hash [][]byte) bool { 702 | if pubVec == nil { 703 | return false 704 | } 705 | n := len(hash) 706 | if n == 0 || len(pubVec) != n { 707 | return false 708 | } 709 | hashByte := len(hash[0]) 710 | if hashByte == 0 { 711 | return false 712 | } 713 | h := make([]byte, n*hashByte) 714 | for i := 0; i < n; i++ { 715 | hn := len(hash[i]) 716 | copy(h[i*hashByte:(i+1)*hashByte], hash[i][0:min(hn, hashByte)]) 717 | } 718 | return C.blsVerifyAggregatedHashes(&sig.v, &pubVec[0].v, unsafe.Pointer(&h[0]), C.mclSize(hashByte), C.mclSize(n)) == 1 719 | } 720 | 721 | // SignatureVerifyOrder -- 722 | // check the correctness of the order of signature in deserialize if true 723 | func SignatureVerifyOrder(doVerify bool) { 724 | var b = 0 725 | if doVerify { 726 | b = 1 727 | } 728 | C.blsSignatureVerifyOrder(C.int(b)) 729 | } 730 | 731 | // SignByte -- 732 | func (sec *SecretKey) SignByte(msg []byte) (sig *Sign) { 733 | sig = new(Sign) 734 | // #nosec 735 | C.blsSign(&sig.v, &sec.v, getPointer(msg), C.mclSize(len(msg))) 736 | return sig 737 | } 738 | 739 | // VerifyByte -- 740 | func (sig *Sign) VerifyByte(pub *PublicKey, msg []byte) bool { 741 | if sig == nil || pub == nil { 742 | return false 743 | } 744 | // #nosec 745 | return C.blsVerify(&sig.v, &pub.v, getPointer(msg), C.mclSize(len(msg))) == 1 746 | } 747 | 748 | // Aggregate -- 749 | func (sig *Sign) Aggregate(sigVec []Sign) { 750 | var p *C.blsSignature 751 | if len(sigVec) == 0 { 752 | p = nil 753 | } else { 754 | p = &sigVec[0].v 755 | } 756 | C.blsAggregateSignature(&sig.v, p, C.mclSize(len(sigVec))) 757 | } 758 | 759 | // FastAggregateVerify -- 760 | func (sig *Sign) FastAggregateVerify(pubVec []PublicKey, msg []byte) bool { 761 | if pubVec == nil || len(pubVec) == 0 { 762 | return false 763 | } 764 | n := len(pubVec) 765 | return C.blsFastAggregateVerify(&sig.v, &pubVec[0].v, C.mclSize(n), getPointer(msg), C.mclSize(len(msg))) == 1 766 | } 767 | 768 | /// 769 | 770 | var sRandReader io.Reader 771 | 772 | func createSlice(buf *C.char, n C.uint) []byte { 773 | size := int(n) 774 | return (*[1 << 30]byte)(unsafe.Pointer(buf))[:size:size] 775 | } 776 | 777 | // this function can't be put in callback.go 778 | //export wrapReadRandGo 779 | func wrapReadRandGo(buf *C.char, n C.uint) C.uint { 780 | slice := createSlice(buf, n) 781 | ret, err := sRandReader.Read(slice) 782 | if ret == int(n) && err == nil { 783 | return n 784 | } 785 | return 0 786 | } 787 | 788 | // SetRandFunc -- 789 | func SetRandFunc(randReader io.Reader) { 790 | sRandReader = randReader 791 | if randReader != nil { 792 | C.blsSetRandFunc(nil, C.ReadRandFunc(unsafe.Pointer(C.wrapReadRandCgo))) 793 | } else { 794 | // use default random generator 795 | C.blsSetRandFunc(nil, C.ReadRandFunc(unsafe.Pointer(nil))) 796 | } 797 | } 798 | 799 | // GetGeneratorOfPublicKey - 800 | func GetGeneratorOfPublicKey(pub *PublicKey) { 801 | C.blsGetGeneratorOfPublicKey(&pub.v) 802 | } 803 | 804 | // SetGeneratorOfPublicKey - 805 | func SetGeneratorOfPublicKey(pub *PublicKey) error { 806 | if C.blsSetGeneratorOfPublicKey(&pub.v) != 0 { 807 | return fmt.Errorf("bad public key") 808 | } 809 | return nil 810 | } 811 | 812 | // keep for backward compatibility 813 | func BlsGetGeneratorOfPublicKey(pub *PublicKey) { 814 | GetGeneratorOfPublicKey(pub) 815 | } 816 | -------------------------------------------------------------------------------- /bls/include/mcl/bn.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /** 3 | @file 4 | @brief C interface of 256/384-bit optimal ate pairing over BN curves 5 | @author MITSUNARI Shigeo(@herumi) 6 | @license modified new BSD license 7 | http://opensource.org/licenses/BSD-3-Clause 8 | */ 9 | /* 10 | the order of an elliptic curve over Fp is Fr 11 | */ 12 | #ifndef MCLBN_FP_UNIT_SIZE 13 | #error "define MCLBN_FP_UNIT_SIZE 4(, 6 or 8)" 14 | #endif 15 | #ifndef MCLBN_FR_UNIT_SIZE 16 | #define MCLBN_FR_UNIT_SIZE MCLBN_FP_UNIT_SIZE 17 | #endif 18 | #define MCLBN_COMPILED_TIME_VAR ((MCLBN_FR_UNIT_SIZE) * 10 + (MCLBN_FP_UNIT_SIZE)) 19 | 20 | #include // for uint64_t, uint8_t 21 | #include // for size_t 22 | 23 | 24 | #if defined(_WIN32) 25 | #ifdef MCLBN_DONT_EXPORT 26 | #define MCLBN_DLL_API 27 | #else 28 | #ifdef MCLBN_DLL_EXPORT 29 | #define MCLBN_DLL_API __declspec(dllexport) 30 | #else 31 | #define MCLBN_DLL_API //__declspec(dllimport) 32 | #endif 33 | #endif 34 | #if defined(_MSC_VER) && !defined(MCLBN_NO_AUTOLINK) 35 | #if MCLBN_FP_UNIT_SIZE == 4 36 | #pragma comment(lib, "mclbn256.lib") 37 | #elif (MCLBN_FP_UNIT_SIZE == 6) && (MCLBN_FR_UNIT_SIZE == 4) 38 | #pragma comment(lib, "mclbn384_256.lib") 39 | #elif (MCLBN_FP_UNIT_SIZE == 6) && (MCLBN_FR_UNIT_SIZE == 6) 40 | #pragma comment(lib, "mclbn384.lib") 41 | #elif MCLBN_FP_UNIT_SIZE == 8 42 | #pragma comment(lib, "mclbn512.lib") 43 | #endif 44 | #endif 45 | #elif defined(__EMSCRIPTEN__) && !defined(MCLBN_DONT_EXPORT) 46 | #define MCLBN_DLL_API __attribute__((used)) 47 | #elif defined(__wasm__) && !defined(MCLBN_DONT_EXPORT) 48 | #define MCLBN_DLL_API __attribute__((visibility("default"))) 49 | #else 50 | #define MCLBN_DLL_API 51 | #endif 52 | 53 | #ifdef __EMSCRIPTEN__ 54 | // avoid 64-bit integer 55 | #define mclSize unsigned int 56 | #define mclInt int 57 | #else 58 | // use #define for cgo 59 | #define mclSize size_t 60 | #define mclInt int64_t 61 | #endif 62 | 63 | #ifdef __cplusplus 64 | extern "C" { 65 | #endif 66 | 67 | #ifdef MCLBN_NOT_DEFINE_STRUCT 68 | 69 | typedef struct mclBnFr mclBnFr; 70 | typedef struct mclBnG1 mclBnG1; 71 | typedef struct mclBnG2 mclBnG2; 72 | typedef struct mclBnGT mclBnGT; 73 | typedef struct mclBnFp mclBnFp; 74 | typedef struct mclBnFp2 mclBnFp2; 75 | 76 | #else 77 | 78 | typedef struct { 79 | uint64_t d[MCLBN_FP_UNIT_SIZE]; 80 | } mclBnFp; 81 | 82 | /* 83 | x = d[0] + d[1] i where i^2 = -1 84 | */ 85 | typedef struct { 86 | mclBnFp d[2]; 87 | } mclBnFp2; 88 | 89 | /* 90 | G1 and G2 are isomorphism to Fr 91 | */ 92 | typedef struct { 93 | uint64_t d[MCLBN_FR_UNIT_SIZE]; 94 | } mclBnFr; 95 | 96 | /* 97 | G1 is defined over Fp 98 | */ 99 | typedef struct { 100 | mclBnFp x, y, z; 101 | } mclBnG1; 102 | 103 | typedef struct { 104 | mclBnFp2 x, y, z; 105 | } mclBnG2; 106 | 107 | typedef struct { 108 | mclBnFp d[12]; 109 | } mclBnGT; 110 | 111 | #endif 112 | 113 | #include 114 | 115 | #define MCLBN_IO_EC_AFFINE 0 116 | #define MCLBN_IO_EC_PROJ 1024 117 | #define MCLBN_IO_SERIALIZE_HEX_STR 2048 118 | 119 | // for backword compatibility 120 | enum { 121 | mclBn_CurveFp254BNb = 0, 122 | mclBn_CurveFp382_1 = 1, 123 | mclBn_CurveFp382_2 = 2, 124 | mclBn_CurveFp462 = 3, 125 | mclBn_CurveSNARK1 = 4, 126 | mclBls12_CurveFp381 = 5 127 | }; 128 | 129 | // return 0xABC which means A.BC 130 | MCLBN_DLL_API int mclBn_getVersion(void); 131 | /* 132 | init library 133 | @param curve [in] type of bn curve 134 | @param compiledTimeVar [in] specify MCLBN_COMPILED_TIME_VAR, 135 | which macro is used to make sure that the values 136 | are the same when the library is built and used 137 | @return 0 if success 138 | curve = BN254/BN_SNARK1 is allowed if maxUnitSize = 4 139 | curve = BN381_1/BN381_2/BLS12_381 are allowed if maxUnitSize = 6 140 | This parameter is used to detect a library compiled with different MCLBN_FP_UNIT_SIZE for safety. 141 | @note not threadsafe 142 | @note BN_init is used in libeay32 143 | */ 144 | MCLBN_DLL_API int mclBn_init(int curve, int compiledTimeVar); 145 | 146 | MCLBN_DLL_API int mclBn_getCurveType(void); 147 | 148 | /* 149 | pairing : G1 x G2 -> GT 150 | #G1 = #G2 = r 151 | G1 is a curve defined on Fp 152 | 153 | serialized size of elements 154 | |Fr| |Fp| 155 | BN254 32 32 156 | BN381 48 48 157 | BLS12_381 32 48 158 | BN462 58 58 159 | |G1| = |Fp| 160 | |G2| = |G1| * 2 161 | |GT| = |G1| * 12 162 | */ 163 | /* 164 | return the num of Unit(=uint64_t) to store Fr 165 | */ 166 | MCLBN_DLL_API int mclBn_getOpUnitSize(void); 167 | 168 | /* 169 | return bytes for serialized G1(=size of Fp) + adj 170 | adj = 1 if p is full bit else 0 171 | */ 172 | MCLBN_DLL_API int mclBn_getG1ByteSize(void); 173 | /* 174 | return bytes for serialized G2(=size of Fp2) + adj 175 | adj = 1 if p is full bit else 0 176 | */ 177 | MCLBN_DLL_API int mclBn_getG2ByteSize(void); 178 | /* 179 | return bytes for serialized Fr 180 | */ 181 | MCLBN_DLL_API int mclBn_getFrByteSize(void); 182 | /* 183 | return bytes for serialized Fp 184 | */ 185 | MCLBN_DLL_API int mclBn_getFpByteSize(void); 186 | 187 | /* 188 | return decimal string of the order of the curve(=the characteristic of Fr) 189 | return str(buf) if success 190 | */ 191 | MCLBN_DLL_API mclSize mclBn_getCurveOrder(char *buf, mclSize maxBufSize); 192 | 193 | /* 194 | return decimal string of the characteristic of Fp 195 | return str(buf) if success 196 | */ 197 | MCLBN_DLL_API mclSize mclBn_getFieldOrder(char *buf, mclSize maxBufSize); 198 | 199 | /* 200 | set ETH serialization mode for BLS12-381 201 | @param enable [in] 1:enable, 0:disable 202 | @note ignore the flag if curve is not BLS12-381 203 | */ 204 | MCLBN_DLL_API void mclBn_setETHserialization(int enable); 205 | 206 | // return 1 if ETH serialization mode else 0 207 | MCLBN_DLL_API int mclBn_getETHserialization(void); 208 | 209 | /* 210 | set map-to-function to mode (only support MCL_MAP_TO_MODE_HASH_TO_CURVE_07) 211 | return 0 if success else -1 212 | */ 213 | MCLBN_DLL_API int mclBn_setMapToMode(int mode); 214 | 215 | //////////////////////////////////////////////// 216 | /* 217 | deserialize 218 | return read size if success else 0 219 | */ 220 | MCLBN_DLL_API mclSize mclBnFr_deserialize(mclBnFr *x, const void *buf, mclSize bufSize); 221 | MCLBN_DLL_API mclSize mclBnG1_deserialize(mclBnG1 *x, const void *buf, mclSize bufSize); 222 | MCLBN_DLL_API mclSize mclBnG2_deserialize(mclBnG2 *x, const void *buf, mclSize bufSize); 223 | MCLBN_DLL_API mclSize mclBnGT_deserialize(mclBnGT *x, const void *buf, mclSize bufSize); 224 | MCLBN_DLL_API mclSize mclBnFp_deserialize(mclBnFp *x, const void *buf, mclSize bufSize); 225 | MCLBN_DLL_API mclSize mclBnFp2_deserialize(mclBnFp2 *x, const void *buf, mclSize bufSize); 226 | 227 | /* 228 | serialize 229 | return written byte if sucess else 0 230 | */ 231 | MCLBN_DLL_API mclSize mclBnFr_serialize(void *buf, mclSize maxBufSize, const mclBnFr *x); 232 | MCLBN_DLL_API mclSize mclBnG1_serialize(void *buf, mclSize maxBufSize, const mclBnG1 *x); 233 | MCLBN_DLL_API mclSize mclBnG2_serialize(void *buf, mclSize maxBufSize, const mclBnG2 *x); 234 | MCLBN_DLL_API mclSize mclBnGT_serialize(void *buf, mclSize maxBufSize, const mclBnGT *x); 235 | MCLBN_DLL_API mclSize mclBnFp_serialize(void *buf, mclSize maxBufSize, const mclBnFp *x); 236 | MCLBN_DLL_API mclSize mclBnFp2_serialize(void *buf, mclSize maxBufSize, const mclBnFp2 *x); 237 | 238 | /* 239 | set string 240 | ioMode 241 | 10 : decimal number 242 | 16 : hexadecimal number 243 | MCLBN_IO_SERIALIZE_HEX_STR : hex string of serialized data 244 | return 0 if success else -1 245 | */ 246 | MCLBN_DLL_API int mclBnFr_setStr(mclBnFr *x, const char *buf, mclSize bufSize, int ioMode); 247 | MCLBN_DLL_API int mclBnG1_setStr(mclBnG1 *x, const char *buf, mclSize bufSize, int ioMode); 248 | MCLBN_DLL_API int mclBnG2_setStr(mclBnG2 *x, const char *buf, mclSize bufSize, int ioMode); 249 | MCLBN_DLL_API int mclBnGT_setStr(mclBnGT *x, const char *buf, mclSize bufSize, int ioMode); 250 | MCLBN_DLL_API int mclBnFp_setStr(mclBnFp *x, const char *buf, mclSize bufSize, int ioMode); 251 | 252 | /* 253 | buf is terminated by '\0' 254 | return strlen(buf) if sucess else 0 255 | */ 256 | MCLBN_DLL_API mclSize mclBnFr_getStr(char *buf, mclSize maxBufSize, const mclBnFr *x, int ioMode); 257 | MCLBN_DLL_API mclSize mclBnG1_getStr(char *buf, mclSize maxBufSize, const mclBnG1 *x, int ioMode); 258 | MCLBN_DLL_API mclSize mclBnG2_getStr(char *buf, mclSize maxBufSize, const mclBnG2 *x, int ioMode); 259 | MCLBN_DLL_API mclSize mclBnGT_getStr(char *buf, mclSize maxBufSize, const mclBnGT *x, int ioMode); 260 | MCLBN_DLL_API mclSize mclBnFp_getStr(char *buf, mclSize maxBufSize, const mclBnFp *x, int ioMode); 261 | 262 | // set zero 263 | MCLBN_DLL_API void mclBnFr_clear(mclBnFr *x); 264 | MCLBN_DLL_API void mclBnFp_clear(mclBnFp *x); 265 | MCLBN_DLL_API void mclBnFp2_clear(mclBnFp2 *x); 266 | 267 | // set x to y 268 | MCLBN_DLL_API void mclBnFr_setInt(mclBnFr *y, mclInt x); 269 | MCLBN_DLL_API void mclBnFr_setInt32(mclBnFr *y, int x); 270 | MCLBN_DLL_API void mclBnFp_setInt(mclBnFp *y, mclInt x); 271 | MCLBN_DLL_API void mclBnFp_setInt32(mclBnFp *y, int x); 272 | 273 | // x = buf & (1 << bitLen(r)) - 1 274 | // if (x >= r) x &= (1 << (bitLen(r) - 1)) - 1 275 | // always return 0 276 | MCLBN_DLL_API int mclBnFr_setLittleEndian(mclBnFr *x, const void *buf, mclSize bufSize); 277 | MCLBN_DLL_API int mclBnFp_setLittleEndian(mclBnFp *x, const void *buf, mclSize bufSize); 278 | 279 | /* 280 | write a value as little endian 281 | return written size if success else 0 282 | @note buf[0] = 0 and return 1 if the value is zero 283 | */ 284 | MCLBN_DLL_API mclSize mclBnFr_getLittleEndian(void *buf, mclSize maxBufSize, const mclBnFr *x); 285 | MCLBN_DLL_API mclSize mclBnFp_getLittleEndian(void *buf, mclSize maxBufSize, const mclBnFp *x); 286 | 287 | // set (buf mod r) to x 288 | // return 0 if bufSize <= (byte size of Fr * 2) else -1 289 | MCLBN_DLL_API int mclBnFr_setLittleEndianMod(mclBnFr *x, const void *buf, mclSize bufSize); 290 | MCLBN_DLL_API int mclBnFr_setBigEndianMod(mclBnFr *x, const void *buf, mclSize bufSize); 291 | // set (buf mod p) to x 292 | // return 0 if bufSize <= (byte size of Fp * 2) else -1 293 | MCLBN_DLL_API int mclBnFp_setLittleEndianMod(mclBnFp *x, const void *buf, mclSize bufSize); 294 | MCLBN_DLL_API int mclBnFp_setBigEndianMod(mclBnFp *x, const void *buf, mclSize bufSize); 295 | 296 | // return 1 if true and 0 otherwise 297 | MCLBN_DLL_API int mclBnFr_isValid(const mclBnFr *x); 298 | MCLBN_DLL_API int mclBnFr_isEqual(const mclBnFr *x, const mclBnFr *y); 299 | MCLBN_DLL_API int mclBnFr_isZero(const mclBnFr *x); 300 | MCLBN_DLL_API int mclBnFr_isOne(const mclBnFr *x); 301 | MCLBN_DLL_API int mclBnFr_isOdd(const mclBnFr *x); 302 | // return 1 if half <= x < r, where half = (r + 1) / 2 else 0 303 | MCLBN_DLL_API int mclBnFr_isNegative(const mclBnFr *x); 304 | // compare x and y as unsigned 305 | // return x < y ? -1 : x == y ? 0 : 1; 306 | // @note two Montgomery conversions may be required 307 | MCLBN_DLL_API int mclBnFr_cmp(const mclBnFr *x, const mclBnFr *y); 308 | 309 | MCLBN_DLL_API int mclBnFp_isValid(const mclBnFp *x); 310 | MCLBN_DLL_API int mclBnFp_isEqual(const mclBnFp *x, const mclBnFp *y); 311 | MCLBN_DLL_API int mclBnFp_isZero(const mclBnFp *x); 312 | MCLBN_DLL_API int mclBnFp_isOne(const mclBnFp *x); 313 | MCLBN_DLL_API int mclBnFp_isOdd(const mclBnFp *x); 314 | // return 1 if half <= x < p, where half = (p + 1) / 2 else 0 315 | MCLBN_DLL_API int mclBnFp_isNegative(const mclBnFp *x); 316 | // compare x and y as unsigned 317 | // return x < y ? -1 : x == y ? 0 : 1; 318 | // @note two Montgomery conversions may be required 319 | MCLBN_DLL_API int mclBnFp_cmp(const mclBnFp *x, const mclBnFp *y); 320 | 321 | MCLBN_DLL_API int mclBnFp2_isEqual(const mclBnFp2 *x, const mclBnFp2 *y); 322 | MCLBN_DLL_API int mclBnFp2_isZero(const mclBnFp2 *x); 323 | MCLBN_DLL_API int mclBnFp2_isOne(const mclBnFp2 *x); 324 | 325 | 326 | #ifndef MCL_DONT_USE_CSRPNG 327 | // return 0 if success 328 | MCLBN_DLL_API int mclBnFr_setByCSPRNG(mclBnFr *x); 329 | MCLBN_DLL_API int mclBnFp_setByCSPRNG(mclBnFp *x); 330 | 331 | /* 332 | set user-defined random function for setByCSPRNG 333 | @param self [in] user-defined pointer 334 | @param readFunc [in] user-defined function, 335 | which writes random bufSize bytes to buf and returns bufSize if success else returns 0 336 | @note if self == 0 and readFunc == 0 then set default random function 337 | @note not threadsafe 338 | */ 339 | MCLBN_DLL_API void mclBn_setRandFunc(void *self, unsigned int (*readFunc)(void *self, void *buf, unsigned int bufSize)); 340 | #endif 341 | 342 | // hash(s) and set x 343 | // return 0 if success 344 | MCLBN_DLL_API int mclBnFr_setHashOf(mclBnFr *x, const void *buf, mclSize bufSize); 345 | MCLBN_DLL_API int mclBnFp_setHashOf(mclBnFp *x, const void *buf, mclSize bufSize); 346 | 347 | // map x to y 348 | // return 0 if success else -1 349 | MCLBN_DLL_API int mclBnFp_mapToG1(mclBnG1 *y, const mclBnFp *x); 350 | MCLBN_DLL_API int mclBnFp2_mapToG2(mclBnG2 *y, const mclBnFp2 *x); 351 | 352 | MCLBN_DLL_API void mclBnFr_neg(mclBnFr *y, const mclBnFr *x); 353 | MCLBN_DLL_API void mclBnFr_inv(mclBnFr *y, const mclBnFr *x); 354 | MCLBN_DLL_API void mclBnFr_sqr(mclBnFr *y, const mclBnFr *x); 355 | MCLBN_DLL_API void mclBnFr_add(mclBnFr *z, const mclBnFr *x, const mclBnFr *y); 356 | MCLBN_DLL_API void mclBnFr_sub(mclBnFr *z, const mclBnFr *x, const mclBnFr *y); 357 | MCLBN_DLL_API void mclBnFr_mul(mclBnFr *z, const mclBnFr *x, const mclBnFr *y); 358 | MCLBN_DLL_API void mclBnFr_div(mclBnFr *z, const mclBnFr *x, const mclBnFr *y); 359 | 360 | MCLBN_DLL_API void mclBnFp_neg(mclBnFp *y, const mclBnFp *x); 361 | MCLBN_DLL_API void mclBnFp_inv(mclBnFp *y, const mclBnFp *x); 362 | MCLBN_DLL_API void mclBnFp_sqr(mclBnFp *y, const mclBnFp *x); 363 | MCLBN_DLL_API void mclBnFp_add(mclBnFp *z, const mclBnFp *x, const mclBnFp *y); 364 | MCLBN_DLL_API void mclBnFp_sub(mclBnFp *z, const mclBnFp *x, const mclBnFp *y); 365 | MCLBN_DLL_API void mclBnFp_mul(mclBnFp *z, const mclBnFp *x, const mclBnFp *y); 366 | MCLBN_DLL_API void mclBnFp_div(mclBnFp *z, const mclBnFp *x, const mclBnFp *y); 367 | 368 | MCLBN_DLL_API void mclBnFp2_neg(mclBnFp2 *y, const mclBnFp2 *x); 369 | MCLBN_DLL_API void mclBnFp2_inv(mclBnFp2 *y, const mclBnFp2 *x); 370 | MCLBN_DLL_API void mclBnFp2_sqr(mclBnFp2 *y, const mclBnFp2 *x); 371 | MCLBN_DLL_API void mclBnFp2_add(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y); 372 | MCLBN_DLL_API void mclBnFp2_sub(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y); 373 | MCLBN_DLL_API void mclBnFp2_mul(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y); 374 | MCLBN_DLL_API void mclBnFp2_div(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y); 375 | 376 | // y is one of square root of x 377 | // return 0 if success else -1 378 | MCLBN_DLL_API int mclBnFr_squareRoot(mclBnFr *y, const mclBnFr *x); 379 | MCLBN_DLL_API int mclBnFp_squareRoot(mclBnFp *y, const mclBnFp *x); 380 | MCLBN_DLL_API int mclBnFp2_squareRoot(mclBnFp2 *y, const mclBnFp2 *x); 381 | 382 | //////////////////////////////////////////////// 383 | // set zero 384 | MCLBN_DLL_API void mclBnG1_clear(mclBnG1 *x); 385 | 386 | 387 | // return 1 if true and 0 otherwise 388 | MCLBN_DLL_API int mclBnG1_isValid(const mclBnG1 *x); 389 | MCLBN_DLL_API int mclBnG1_isEqual(const mclBnG1 *x, const mclBnG1 *y); 390 | MCLBN_DLL_API int mclBnG1_isZero(const mclBnG1 *x); 391 | /* 392 | return 1 if x has a correct order 393 | x is valid point of G1 if and only if 394 | mclBnG1_isValid() is true, which contains mclBnG1_isValidOrder() if mclBn_verifyOrderG1(true) 395 | mclBnG1_isValid() && mclBnG1_isValidOrder() is true if mclBn_verifyOrderG1(false) 396 | */ 397 | MCLBN_DLL_API int mclBnG1_isValidOrder(const mclBnG1 *x); 398 | 399 | MCLBN_DLL_API int mclBnG1_hashAndMapTo(mclBnG1 *x, const void *buf, mclSize bufSize); 400 | // user-defined dst 401 | MCLBN_DLL_API int mclBnG1_hashAndMapToWithDst(mclBnG1 *x, const void *buf, mclSize bufSize, const char *dst, mclSize dstSize); 402 | // set default dst 403 | MCLBN_DLL_API int mclBnG1_setDst(const char *dst, mclSize dstSize); 404 | 405 | 406 | MCLBN_DLL_API void mclBnG1_neg(mclBnG1 *y, const mclBnG1 *x); 407 | MCLBN_DLL_API void mclBnG1_dbl(mclBnG1 *y, const mclBnG1 *x); 408 | MCLBN_DLL_API void mclBnG1_normalize(mclBnG1 *y, const mclBnG1 *x); 409 | MCLBN_DLL_API void mclBnG1_add(mclBnG1 *z, const mclBnG1 *x, const mclBnG1 *y); 410 | MCLBN_DLL_API void mclBnG1_sub(mclBnG1 *z, const mclBnG1 *x, const mclBnG1 *y); 411 | MCLBN_DLL_API void mclBnG1_mul(mclBnG1 *z, const mclBnG1 *x, const mclBnFr *y); 412 | 413 | /* 414 | constant time mul 415 | */ 416 | MCLBN_DLL_API void mclBnG1_mulCT(mclBnG1 *z, const mclBnG1 *x, const mclBnFr *y); 417 | 418 | //////////////////////////////////////////////// 419 | // set zero 420 | MCLBN_DLL_API void mclBnG2_clear(mclBnG2 *x); 421 | 422 | // return 1 if true and 0 otherwise 423 | MCLBN_DLL_API int mclBnG2_isValid(const mclBnG2 *x); 424 | MCLBN_DLL_API int mclBnG2_isEqual(const mclBnG2 *x, const mclBnG2 *y); 425 | MCLBN_DLL_API int mclBnG2_isZero(const mclBnG2 *x); 426 | // return 1 if x has a correct order 427 | MCLBN_DLL_API int mclBnG2_isValidOrder(const mclBnG2 *x); 428 | 429 | MCLBN_DLL_API int mclBnG2_hashAndMapTo(mclBnG2 *x, const void *buf, mclSize bufSize); 430 | // user-defined dst 431 | MCLBN_DLL_API int mclBnG2_hashAndMapToWithDst(mclBnG2 *x, const void *buf, mclSize bufSize, const char *dst, mclSize dstSize); 432 | // set default dst 433 | MCLBN_DLL_API int mclBnG2_setDst(const char *dst, mclSize dstSize); 434 | 435 | // return written size if sucess else 0 436 | 437 | MCLBN_DLL_API void mclBnG2_neg(mclBnG2 *y, const mclBnG2 *x); 438 | MCLBN_DLL_API void mclBnG2_dbl(mclBnG2 *y, const mclBnG2 *x); 439 | MCLBN_DLL_API void mclBnG2_normalize(mclBnG2 *y, const mclBnG2 *x); 440 | MCLBN_DLL_API void mclBnG2_add(mclBnG2 *z, const mclBnG2 *x, const mclBnG2 *y); 441 | MCLBN_DLL_API void mclBnG2_sub(mclBnG2 *z, const mclBnG2 *x, const mclBnG2 *y); 442 | MCLBN_DLL_API void mclBnG2_mul(mclBnG2 *z, const mclBnG2 *x, const mclBnFr *y); 443 | /* 444 | constant time mul 445 | */ 446 | MCLBN_DLL_API void mclBnG2_mulCT(mclBnG2 *z, const mclBnG2 *x, const mclBnFr *y); 447 | 448 | //////////////////////////////////////////////// 449 | // set zero 450 | MCLBN_DLL_API void mclBnGT_clear(mclBnGT *x); 451 | // set x to y 452 | MCLBN_DLL_API void mclBnGT_setInt(mclBnGT *y, mclInt x); 453 | MCLBN_DLL_API void mclBnGT_setInt32(mclBnGT *y, int x); 454 | 455 | // return 1 if true and 0 otherwise 456 | MCLBN_DLL_API int mclBnGT_isEqual(const mclBnGT *x, const mclBnGT *y); 457 | MCLBN_DLL_API int mclBnGT_isZero(const mclBnGT *x); 458 | MCLBN_DLL_API int mclBnGT_isOne(const mclBnGT *x); 459 | 460 | MCLBN_DLL_API void mclBnGT_neg(mclBnGT *y, const mclBnGT *x); 461 | MCLBN_DLL_API void mclBnGT_sqr(mclBnGT *y, const mclBnGT *x); 462 | MCLBN_DLL_API void mclBnGT_add(mclBnGT *z, const mclBnGT *x, const mclBnGT *y); 463 | MCLBN_DLL_API void mclBnGT_sub(mclBnGT *z, const mclBnGT *x, const mclBnGT *y); 464 | MCLBN_DLL_API void mclBnGT_mul(mclBnGT *z, const mclBnGT *x, const mclBnGT *y); 465 | MCLBN_DLL_API void mclBnGT_div(mclBnGT *z, const mclBnGT *x, const mclBnGT *y); 466 | 467 | // y = conjugate of x in Fp12, which is equal to the inverse of x if |x|^r = 1 468 | MCLBN_DLL_API void mclBnGT_inv(mclBnGT *y, const mclBnGT *x); 469 | // use invGeneric when x in Fp12 is not in GT 470 | MCLBN_DLL_API void mclBnGT_invGeneric(mclBnGT *y, const mclBnGT *x); 471 | 472 | /* 473 | pow for all elements of Fp12 474 | */ 475 | MCLBN_DLL_API void mclBnGT_powGeneric(mclBnGT *z, const mclBnGT *x, const mclBnFr *y); 476 | /* 477 | pow for only {x|x^r = 1} in GT by GLV method 478 | the value generated by pairing satisfies the condition 479 | */ 480 | MCLBN_DLL_API void mclBnGT_pow(mclBnGT *z, const mclBnGT *x, const mclBnFr *y); 481 | 482 | // z = sum_{i=0}^{n-1} x[i] y[i] 483 | // x[] may be normalized (the values are not changed) when computing z 484 | MCLBN_DLL_API void mclBnG1_mulVec(mclBnG1 *z, mclBnG1 *x, const mclBnFr *y, mclSize n); 485 | MCLBN_DLL_API void mclBnG2_mulVec(mclBnG2 *z, mclBnG2 *x, const mclBnFr *y, mclSize n); 486 | MCLBN_DLL_API void mclBnGT_powVec(mclBnGT *z, const mclBnGT *x, const mclBnFr *y, mclSize n); 487 | 488 | MCLBN_DLL_API void mclBn_pairing(mclBnGT *z, const mclBnG1 *x, const mclBnG2 *y); 489 | MCLBN_DLL_API void mclBn_finalExp(mclBnGT *y, const mclBnGT *x); 490 | MCLBN_DLL_API void mclBn_millerLoop(mclBnGT *z, const mclBnG1 *x, const mclBnG2 *y); 491 | // z = prod_{i=0}^{n-1} millerLoop(x[i], y[i]) 492 | MCLBN_DLL_API void mclBn_millerLoopVec(mclBnGT *z, const mclBnG1 *x, const mclBnG2 *y, mclSize n); 493 | // multi thread version of millerLoopVec/mclBnG1_mulVec/mclBnG2_mulVec (enabled if the library built with MCL_USE_OMP=1) 494 | // the num of thread is automatically detected if cpuN = 0 495 | // x[] may be normalized (the values are not changed) when computing z 496 | MCLBN_DLL_API void mclBn_millerLoopVecMT(mclBnGT *z, const mclBnG1 *x, const mclBnG2 *y, mclSize n, mclSize cpuN); 497 | MCLBN_DLL_API void mclBnG1_mulVecMT(mclBnG1 *z, mclBnG1 *x, const mclBnFr *y, mclSize n, mclSize cpuN); 498 | MCLBN_DLL_API void mclBnG2_mulVecMT(mclBnG2 *z, mclBnG2 *x, const mclBnFr *y, mclSize n, mclSize cpuN); 499 | 500 | // return precomputedQcoeffSize * sizeof(Fp6) / sizeof(uint64_t) 501 | MCLBN_DLL_API int mclBn_getUint64NumToPrecompute(void); 502 | 503 | // allocate Qbuf[MCLBN_getUint64NumToPrecompute()] before calling this 504 | MCLBN_DLL_API void mclBn_precomputeG2(uint64_t *Qbuf, const mclBnG2 *Q); 505 | 506 | MCLBN_DLL_API void mclBn_precomputedMillerLoop(mclBnGT *f, const mclBnG1 *P, const uint64_t *Qbuf); 507 | MCLBN_DLL_API void mclBn_precomputedMillerLoop2(mclBnGT *f, const mclBnG1 *P1, const uint64_t *Q1buf, const mclBnG1 *P2, const uint64_t *Q2buf); 508 | MCLBN_DLL_API void mclBn_precomputedMillerLoop2mixed(mclBnGT *f, const mclBnG1 *P1, const mclBnG2 *Q1, const mclBnG1 *P2, const uint64_t *Q2buf); 509 | 510 | /* 511 | Lagrange interpolation 512 | recover out = y(0) by { (xVec[i], yVec[i]) } 513 | return 0 if success else -1 514 | @note *out = yVec[0] if k = 1 515 | @note k >= 2, xVec[i] != 0, xVec[i] != xVec[j] for i != j 516 | */ 517 | MCLBN_DLL_API int mclBn_FrLagrangeInterpolation(mclBnFr *out, const mclBnFr *xVec, const mclBnFr *yVec, mclSize k); 518 | MCLBN_DLL_API int mclBn_G1LagrangeInterpolation(mclBnG1 *out, const mclBnFr *xVec, const mclBnG1 *yVec, mclSize k); 519 | MCLBN_DLL_API int mclBn_G2LagrangeInterpolation(mclBnG2 *out, const mclBnFr *xVec, const mclBnG2 *yVec, mclSize k); 520 | 521 | /* 522 | evaluate polynomial 523 | out = f(x) = c[0] + c[1] * x + c[2] * x^2 + ... + c[cSize - 1] * x^(cSize - 1) 524 | return 0 if success else -1 525 | @note cSize >= 1 526 | */ 527 | MCLBN_DLL_API int mclBn_FrEvaluatePolynomial(mclBnFr *out, const mclBnFr *cVec, mclSize cSize, const mclBnFr *x); 528 | MCLBN_DLL_API int mclBn_G1EvaluatePolynomial(mclBnG1 *out, const mclBnG1 *cVec, mclSize cSize, const mclBnFr *x); 529 | MCLBN_DLL_API int mclBn_G2EvaluatePolynomial(mclBnG2 *out, const mclBnG2 *cVec, mclSize cSize, const mclBnFr *x); 530 | 531 | /* 532 | verify whether a point of an elliptic curve has order r 533 | This api affetcs setStr(), deserialize() for G2 on BN or G1/G2 on BLS12 534 | @param doVerify [in] does not verify if zero(default 1) 535 | */ 536 | MCLBN_DLL_API void mclBn_verifyOrderG1(int doVerify); 537 | MCLBN_DLL_API void mclBn_verifyOrderG2(int doVerify); 538 | 539 | /* 540 | EXPERIMENTAL 541 | only for curve = MCL_SECP* or MCL_NIST* 542 | return standard base point of the current elliptic curve 543 | */ 544 | MCLBN_DLL_API int mclBnG1_getBasePoint(mclBnG1 *x); 545 | 546 | #ifdef __cplusplus 547 | } 548 | #endif 549 | -------------------------------------------------------------------------------- /bls/mcl.go: -------------------------------------------------------------------------------- 1 | package bls 2 | 3 | /* 4 | #cgo CFLAGS:-I./include 5 | #include 6 | */ 7 | import "C" 8 | import "fmt" 9 | import "unsafe" 10 | 11 | // CurveFp254BNb -- 254 bit curve 12 | const CurveFp254BNb = C.mclBn_CurveFp254BNb 13 | 14 | // CurveFp382_1 -- 382 bit curve 1 15 | const CurveFp382_1 = C.mclBn_CurveFp382_1 16 | 17 | // CurveFp382_2 -- 382 bit curve 2 18 | const CurveFp382_2 = C.mclBn_CurveFp382_2 19 | 20 | // BLS12_381 -- 21 | const BLS12_381 = C.MCL_BLS12_381 22 | 23 | // IoSerializeHexStr -- 24 | const IoSerializeHexStr = C.MCLBN_IO_SERIALIZE_HEX_STR 25 | 26 | // IO_EC_AFFINE -- 27 | const IO_EC_AFFINE = C.MCLBN_IO_EC_AFFINE 28 | 29 | // IO_EC_PROJ -- 30 | const IO_EC_PROJ = C.MCLBN_IO_EC_PROJ 31 | 32 | // IRTF -- for SetMapToMode 33 | const IRTF = 5 /* MCL_MAP_TO_MODE_HASH_TO_CURVE_07 */ 34 | 35 | // GetFrUnitSize -- 36 | func GetFrUnitSize() int { 37 | return int(C.MCLBN_FR_UNIT_SIZE) 38 | } 39 | 40 | // GetFpUnitSize -- 41 | // same as GetMaxOpUnitSize() 42 | func GetFpUnitSize() int { 43 | return int(C.MCLBN_FP_UNIT_SIZE) 44 | } 45 | 46 | // GetMaxOpUnitSize -- 47 | func GetMaxOpUnitSize() int { 48 | return int(C.MCLBN_FP_UNIT_SIZE) 49 | } 50 | 51 | // GetOpUnitSize -- 52 | // the length of Fr is GetOpUnitSize() * 8 bytes 53 | func GetOpUnitSize() int { 54 | return int(C.mclBn_getOpUnitSize()) 55 | } 56 | 57 | // GetFrByteSize -- the serialized size of Fr 58 | func GetFrByteSize() int { 59 | return int(C.mclBn_getFrByteSize()) 60 | } 61 | 62 | // GetFpByteSize -- the serialized size of Fp 63 | func GetFpByteSize() int { 64 | return int(C.mclBn_getFpByteSize()) 65 | } 66 | 67 | // GetG1ByteSize -- the serialized size of G1 68 | func GetG1ByteSize() int { 69 | return int(C.mclBn_getG1ByteSize()) 70 | } 71 | 72 | // GetG2ByteSize -- the serialized size of G2 73 | func GetG2ByteSize() int { 74 | return int(C.mclBn_getG2ByteSize()) 75 | } 76 | 77 | // allow zero length byte 78 | func getPointer(msg []byte) unsafe.Pointer { 79 | if len(msg) == 0 { 80 | return nil 81 | } 82 | return unsafe.Pointer(&msg[0]) 83 | } 84 | 85 | // GetCurveOrder -- 86 | // return the order of G1 87 | func GetCurveOrder() string { 88 | buf := make([]byte, 1024) 89 | // #nosec 90 | n := C.mclBn_getCurveOrder((*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf))) 91 | if n == 0 { 92 | panic("implementation err. size of buf is small") 93 | } 94 | return string(buf[:n]) 95 | } 96 | 97 | // GetFieldOrder -- 98 | // return the characteristic of the field where a curve is defined 99 | func GetFieldOrder() string { 100 | buf := make([]byte, 1024) 101 | // #nosec 102 | n := C.mclBn_getFieldOrder((*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf))) 103 | if n == 0 { 104 | panic("implementation err. size of buf is small") 105 | } 106 | return string(buf[:n]) 107 | } 108 | 109 | func bool2Cint(b bool) C.int { 110 | if b { 111 | return 1 112 | } else { 113 | return 0 114 | } 115 | } 116 | 117 | // VerifyOrderG1 -- verify order if SetString/Deserialize are called 118 | func VerifyOrderG1(doVerify bool) { 119 | // #nosec 120 | C.mclBn_verifyOrderG1(bool2Cint(doVerify)) 121 | } 122 | 123 | // VerifyOrderG2 -- verify order if SetString/Deserialize are called 124 | func VerifyOrderG2(doVerify bool) { 125 | // #nosec 126 | C.mclBn_verifyOrderG2(bool2Cint(doVerify)) 127 | } 128 | 129 | // SetETHserialization -- 130 | func SetETHserialization(enable bool) { 131 | // #nosec 132 | C.mclBn_setETHserialization(bool2Cint(enable)) 133 | } 134 | 135 | // SetMapToMode -- 136 | func SetMapToMode(mode int) error { 137 | // #nosec 138 | err := C.mclBn_setMapToMode((C.int)(mode)) 139 | if err != 0 { 140 | return fmt.Errorf("SetMapToMode mode=%d\n", mode) 141 | } 142 | return nil 143 | } 144 | 145 | // SetDstG1 -- 146 | func SetDstG1(s string) error { 147 | // #nosec 148 | err := C.mclBnG1_setDst((*C.char)(getPointer([]byte(s))), C.size_t(len(s))) 149 | if err != 0 { 150 | return fmt.Errorf("err mclBnG1_setDst") 151 | } 152 | return nil 153 | } 154 | 155 | // SetDstG2 -- 156 | func SetDstG2(s string) error { 157 | // #nosec 158 | err := C.mclBnG2_setDst((*C.char)(getPointer([]byte(s))), C.size_t(len(s))) 159 | if err != 0 { 160 | return fmt.Errorf("err mclBnG2_setDst") 161 | } 162 | return nil 163 | } 164 | 165 | // Fr -- 166 | type Fr struct { 167 | v C.mclBnFr 168 | } 169 | 170 | // getPointer -- 171 | func (x *Fr) getPointer() (p *C.mclBnFr) { 172 | // #nosec 173 | return (*C.mclBnFr)(unsafe.Pointer(x)) 174 | } 175 | 176 | // Clear -- 177 | func (x *Fr) Clear() { 178 | // #nosec 179 | C.mclBnFr_clear(x.getPointer()) 180 | } 181 | 182 | // SetInt64 -- 183 | func (x *Fr) SetInt64(v int64) { 184 | // #nosec 185 | C.mclBnFr_setInt(x.getPointer(), C.int64_t(v)) 186 | } 187 | 188 | // SetString -- 189 | func (x *Fr) SetString(s string, base int) error { 190 | buf := []byte(s) 191 | // #nosec 192 | err := C.mclBnFr_setStr(x.getPointer(), (*C.char)(getPointer(buf)), C.size_t(len(buf)), C.int(base)) 193 | if err != 0 { 194 | return fmt.Errorf("err mclBnFr_setStr %x", err) 195 | } 196 | return nil 197 | } 198 | 199 | // Deserialize -- 200 | func (x *Fr) Deserialize(buf []byte) error { 201 | // #nosec 202 | n := C.mclBnFr_deserialize(x.getPointer(), getPointer(buf), C.size_t(len(buf))) 203 | if n == 0 || int(n) != len(buf) { 204 | return fmt.Errorf("err mclBnFr_deserialize %x", buf) 205 | } 206 | return nil 207 | } 208 | 209 | // SetLittleEndian -- 210 | func (x *Fr) SetLittleEndian(buf []byte) error { 211 | // #nosec 212 | err := C.mclBnFr_setLittleEndian(x.getPointer(), getPointer(buf), C.size_t(len(buf))) 213 | if err != 0 { 214 | return fmt.Errorf("err mclBnFr_setLittleEndian %x", err) 215 | } 216 | return nil 217 | } 218 | 219 | // SetLittleEndianMod -- 220 | func (x *Fr) SetLittleEndianMod(buf []byte) error { 221 | // #nosec 222 | err := C.mclBnFr_setLittleEndianMod(x.getPointer(), getPointer(buf), C.size_t(len(buf))) 223 | if err != 0 { 224 | return fmt.Errorf("err mclBnFr_setLittleEndianMod %x", err) 225 | } 226 | return nil 227 | } 228 | 229 | // SetBigEndianMod -- 230 | func (x *Fr) SetBigEndianMod(buf []byte) error { 231 | // #nosec 232 | err := C.mclBnFr_setBigEndianMod(x.getPointer(), getPointer(buf), C.size_t(len(buf))) 233 | if err != 0 { 234 | return fmt.Errorf("err mclBnFr_setBigEndianMod %x", err) 235 | } 236 | return nil 237 | } 238 | 239 | // IsEqual -- 240 | func (x *Fr) IsEqual(rhs *Fr) bool { 241 | return C.mclBnFr_isEqual(x.getPointer(), rhs.getPointer()) == 1 242 | } 243 | 244 | // IsZero -- 245 | func (x *Fr) IsZero() bool { 246 | return C.mclBnFr_isZero(x.getPointer()) == 1 247 | } 248 | 249 | // IsValid -- 250 | func (x *Fr) IsValid() bool { 251 | return C.mclBnFr_isValid(x.getPointer()) == 1 252 | } 253 | 254 | // IsOne -- 255 | func (x *Fr) IsOne() bool { 256 | return C.mclBnFr_isOne(x.getPointer()) == 1 257 | } 258 | 259 | // IsOdd -- 260 | func (x *Fr) IsOdd() bool { 261 | return C.mclBnFr_isOdd(x.getPointer()) == 1 262 | } 263 | 264 | // IsNegative -- true if x >= (r + 1) / 2 265 | func (x *Fr) IsNegative() bool { 266 | return C.mclBnFr_isNegative(x.getPointer()) == 1 267 | } 268 | 269 | // SetByCSPRNG -- 270 | func (x *Fr) SetByCSPRNG() { 271 | err := C.mclBnFr_setByCSPRNG(x.getPointer()) 272 | if err != 0 { 273 | panic("err mclBnFr_setByCSPRNG") 274 | } 275 | } 276 | 277 | // SetHashOf -- 278 | func (x *Fr) SetHashOf(buf []byte) bool { 279 | // #nosec 280 | return C.mclBnFr_setHashOf(x.getPointer(), getPointer(buf), C.size_t(len(buf))) == 0 281 | } 282 | 283 | // GetString -- 284 | func (x *Fr) GetString(base int) string { 285 | buf := make([]byte, 2048) 286 | // #nosec 287 | n := C.mclBnFr_getStr((*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), x.getPointer(), C.int(base)) 288 | if n == 0 { 289 | panic("err mclBnFr_getStr") 290 | } 291 | return string(buf[:n]) 292 | } 293 | 294 | // Serialize -- 295 | func (x *Fr) Serialize() []byte { 296 | buf := make([]byte, 2048) 297 | // #nosec 298 | n := C.mclBnFr_serialize(unsafe.Pointer(&buf[0]), C.size_t(len(buf)), x.getPointer()) 299 | if n == 0 { 300 | panic("err mclBnFr_serialize") 301 | } 302 | return buf[:n] 303 | } 304 | 305 | // FrNeg -- 306 | func FrNeg(out *Fr, x *Fr) { 307 | C.mclBnFr_neg(out.getPointer(), x.getPointer()) 308 | } 309 | 310 | // FrInv -- 311 | func FrInv(out *Fr, x *Fr) { 312 | C.mclBnFr_inv(out.getPointer(), x.getPointer()) 313 | } 314 | 315 | // FrSqr -- 316 | func FrSqr(out *Fr, x *Fr) { 317 | C.mclBnFr_sqr(out.getPointer(), x.getPointer()) 318 | } 319 | 320 | // FrAdd -- 321 | func FrAdd(out *Fr, x *Fr, y *Fr) { 322 | C.mclBnFr_add(out.getPointer(), x.getPointer(), y.getPointer()) 323 | } 324 | 325 | // FrSub -- 326 | func FrSub(out *Fr, x *Fr, y *Fr) { 327 | C.mclBnFr_sub(out.getPointer(), x.getPointer(), y.getPointer()) 328 | } 329 | 330 | // FrMul -- 331 | func FrMul(out *Fr, x *Fr, y *Fr) { 332 | C.mclBnFr_mul(out.getPointer(), x.getPointer(), y.getPointer()) 333 | } 334 | 335 | // FrDiv -- 336 | func FrDiv(out *Fr, x *Fr, y *Fr) { 337 | C.mclBnFr_div(out.getPointer(), x.getPointer(), y.getPointer()) 338 | } 339 | 340 | // FrSquareRoot -- 341 | func FrSquareRoot(out *Fr, x *Fr) bool { 342 | return C.mclBnFr_squareRoot(out.getPointer(), x.getPointer()) == 0 343 | } 344 | 345 | // Fp -- 346 | type Fp struct { 347 | v C.mclBnFp 348 | } 349 | 350 | // getPointer -- 351 | func (x *Fp) getPointer() (p *C.mclBnFp) { 352 | // #nosec 353 | return (*C.mclBnFp)(unsafe.Pointer(x)) 354 | } 355 | 356 | // Clear -- 357 | func (x *Fp) Clear() { 358 | // #nosec 359 | C.mclBnFp_clear(x.getPointer()) 360 | } 361 | 362 | // SetInt64 -- 363 | func (x *Fp) SetInt64(v int64) { 364 | // #nosec 365 | C.mclBnFp_setInt(x.getPointer(), C.int64_t(v)) 366 | } 367 | 368 | // SetString -- 369 | func (x *Fp) SetString(s string, base int) error { 370 | buf := []byte(s) 371 | // #nosec 372 | err := C.mclBnFp_setStr(x.getPointer(), (*C.char)(getPointer(buf)), C.size_t(len(buf)), C.int(base)) 373 | if err != 0 { 374 | return fmt.Errorf("err mclBnFp_setStr %x", err) 375 | } 376 | return nil 377 | } 378 | 379 | // Deserialize -- 380 | func (x *Fp) Deserialize(buf []byte) error { 381 | // #nosec 382 | n := C.mclBnFp_deserialize(x.getPointer(), getPointer(buf), C.size_t(len(buf))) 383 | if n == 0 || int(n) != len(buf) { 384 | return fmt.Errorf("err mclBnFp_deserialize %x", buf) 385 | } 386 | return nil 387 | } 388 | 389 | // SetLittleEndian -- 390 | func (x *Fp) SetLittleEndian(buf []byte) error { 391 | // #nosec 392 | err := C.mclBnFp_setLittleEndian(x.getPointer(), getPointer(buf), C.size_t(len(buf))) 393 | if err != 0 { 394 | return fmt.Errorf("err mclBnFp_setLittleEndian %x", err) 395 | } 396 | return nil 397 | } 398 | 399 | // SetLittleEndianMod -- 400 | func (x *Fp) SetLittleEndianMod(buf []byte) error { 401 | // #nosec 402 | err := C.mclBnFp_setLittleEndianMod(x.getPointer(), getPointer(buf), C.size_t(len(buf))) 403 | if err != 0 { 404 | return fmt.Errorf("err mclBnFp_setLittleEndianMod %x", err) 405 | } 406 | return nil 407 | } 408 | 409 | // SetBigEndianMod -- 410 | func (x *Fp) SetBigEndianMod(buf []byte) error { 411 | // #nosec 412 | err := C.mclBnFp_setBigEndianMod(x.getPointer(), getPointer(buf), C.size_t(len(buf))) 413 | if err != 0 { 414 | return fmt.Errorf("err mclBnFp_setBigEndianMod %x", err) 415 | } 416 | return nil 417 | } 418 | 419 | // IsEqual -- 420 | func (x *Fp) IsEqual(rhs *Fp) bool { 421 | return C.mclBnFp_isEqual(x.getPointer(), rhs.getPointer()) == 1 422 | } 423 | 424 | // IsZero -- 425 | func (x *Fp) IsZero() bool { 426 | return C.mclBnFp_isZero(x.getPointer()) == 1 427 | } 428 | 429 | // IsValid -- 430 | func (x *Fp) IsValid() bool { 431 | return C.mclBnFp_isValid(x.getPointer()) == 1 432 | } 433 | 434 | // IsOne -- 435 | func (x *Fp) IsOne() bool { 436 | return C.mclBnFp_isOne(x.getPointer()) == 1 437 | } 438 | 439 | // IsOdd -- 440 | func (x *Fp) IsOdd() bool { 441 | return C.mclBnFp_isOdd(x.getPointer()) == 1 442 | } 443 | 444 | // IsNegative -- true if x >= (p + 1) / 2 445 | func (x *Fp) IsNegative() bool { 446 | return C.mclBnFp_isNegative(x.getPointer()) == 1 447 | } 448 | 449 | // SetByCSPRNG -- 450 | func (x *Fp) SetByCSPRNG() { 451 | err := C.mclBnFp_setByCSPRNG(x.getPointer()) 452 | if err != 0 { 453 | panic("err mclBnFp_setByCSPRNG") 454 | } 455 | } 456 | 457 | // SetHashOf -- 458 | func (x *Fp) SetHashOf(buf []byte) bool { 459 | // #nosec 460 | return C.mclBnFp_setHashOf(x.getPointer(), getPointer(buf), C.size_t(len(buf))) == 0 461 | } 462 | 463 | // GetString -- 464 | func (x *Fp) GetString(base int) string { 465 | buf := make([]byte, 2048) 466 | // #nosec 467 | n := C.mclBnFp_getStr((*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), x.getPointer(), C.int(base)) 468 | if n == 0 { 469 | panic("err mclBnFp_getStr") 470 | } 471 | return string(buf[:n]) 472 | } 473 | 474 | // Serialize -- 475 | func (x *Fp) Serialize() []byte { 476 | buf := make([]byte, 2048) 477 | // #nosec 478 | n := C.mclBnFp_serialize(unsafe.Pointer(&buf[0]), C.size_t(len(buf)), x.getPointer()) 479 | if n == 0 { 480 | panic("err mclBnFp_serialize") 481 | } 482 | return buf[:n] 483 | } 484 | 485 | // FpNeg -- 486 | func FpNeg(out *Fp, x *Fp) { 487 | C.mclBnFp_neg(out.getPointer(), x.getPointer()) 488 | } 489 | 490 | // FpInv -- 491 | func FpInv(out *Fp, x *Fp) { 492 | C.mclBnFp_inv(out.getPointer(), x.getPointer()) 493 | } 494 | 495 | // FpSqr -- 496 | func FpSqr(out *Fp, x *Fp) { 497 | C.mclBnFp_sqr(out.getPointer(), x.getPointer()) 498 | } 499 | 500 | // FpAdd -- 501 | func FpAdd(out *Fp, x *Fp, y *Fp) { 502 | C.mclBnFp_add(out.getPointer(), x.getPointer(), y.getPointer()) 503 | } 504 | 505 | // FpSub -- 506 | func FpSub(out *Fp, x *Fp, y *Fp) { 507 | C.mclBnFp_sub(out.getPointer(), x.getPointer(), y.getPointer()) 508 | } 509 | 510 | // FpMul -- 511 | func FpMul(out *Fp, x *Fp, y *Fp) { 512 | C.mclBnFp_mul(out.getPointer(), x.getPointer(), y.getPointer()) 513 | } 514 | 515 | // FpDiv -- 516 | func FpDiv(out *Fp, x *Fp, y *Fp) { 517 | C.mclBnFp_div(out.getPointer(), x.getPointer(), y.getPointer()) 518 | } 519 | 520 | // FpSquareRoot -- 521 | func FpSquareRoot(out *Fp, x *Fp) bool { 522 | return C.mclBnFp_squareRoot(out.getPointer(), x.getPointer()) == 0 523 | } 524 | 525 | // Fp2 -- x = D[0] + D[1] i where i^2 = -1 526 | type Fp2 struct { 527 | D [2]Fp 528 | } 529 | 530 | // getPointer -- 531 | func (x *Fp2) getPointer() (p *C.mclBnFp2) { 532 | // #nosec 533 | return (*C.mclBnFp2)(unsafe.Pointer(x)) 534 | } 535 | 536 | // Clear -- 537 | func (x *Fp2) Clear() { 538 | // #nosec 539 | C.mclBnFp2_clear(x.getPointer()) 540 | } 541 | 542 | // Deserialize -- 543 | func (x *Fp2) Deserialize(buf []byte) error { 544 | // #nosec 545 | n := C.mclBnFp2_deserialize(x.getPointer(), getPointer(buf), C.size_t(len(buf))) 546 | if n == 0 || int(n) != len(buf) { 547 | return fmt.Errorf("err mclBnFp2_deserialize %x", buf) 548 | } 549 | return nil 550 | } 551 | 552 | // IsEqual -- 553 | func (x *Fp2) IsEqual(rhs *Fp2) bool { 554 | return C.mclBnFp2_isEqual(x.getPointer(), rhs.getPointer()) == 1 555 | } 556 | 557 | // IsZero -- 558 | func (x *Fp2) IsZero() bool { 559 | return C.mclBnFp2_isZero(x.getPointer()) == 1 560 | } 561 | 562 | // IsOne -- 563 | func (x *Fp2) IsOne() bool { 564 | return C.mclBnFp2_isOne(x.getPointer()) == 1 565 | } 566 | 567 | // Serialize -- 568 | func (x *Fp2) Serialize() []byte { 569 | buf := make([]byte, 2048) 570 | // #nosec 571 | n := C.mclBnFp2_serialize(unsafe.Pointer(&buf[0]), C.size_t(len(buf)), x.getPointer()) 572 | if n == 0 { 573 | panic("err mclBnFp2_serialize") 574 | } 575 | return buf[:n] 576 | } 577 | 578 | // Fp2Neg -- 579 | func Fp2Neg(out *Fp2, x *Fp2) { 580 | C.mclBnFp2_neg(out.getPointer(), x.getPointer()) 581 | } 582 | 583 | // Fp2Inv -- 584 | func Fp2Inv(out *Fp2, x *Fp2) { 585 | C.mclBnFp2_inv(out.getPointer(), x.getPointer()) 586 | } 587 | 588 | // Fp2Sqr -- 589 | func Fp2Sqr(out *Fp2, x *Fp2) { 590 | C.mclBnFp2_sqr(out.getPointer(), x.getPointer()) 591 | } 592 | 593 | // Fp2Add -- 594 | func Fp2Add(out *Fp2, x *Fp2, y *Fp2) { 595 | C.mclBnFp2_add(out.getPointer(), x.getPointer(), y.getPointer()) 596 | } 597 | 598 | // Fp2Sub -- 599 | func Fp2Sub(out *Fp2, x *Fp2, y *Fp2) { 600 | C.mclBnFp2_sub(out.getPointer(), x.getPointer(), y.getPointer()) 601 | } 602 | 603 | // Fp2Mul -- 604 | func Fp2Mul(out *Fp2, x *Fp2, y *Fp2) { 605 | C.mclBnFp2_mul(out.getPointer(), x.getPointer(), y.getPointer()) 606 | } 607 | 608 | // Fp2Div -- 609 | func Fp2Div(out *Fp2, x *Fp2, y *Fp2) { 610 | C.mclBnFp2_div(out.getPointer(), x.getPointer(), y.getPointer()) 611 | } 612 | 613 | // Fp2SquareRoot -- 614 | func Fp2SquareRoot(out *Fp2, x *Fp2) bool { 615 | return C.mclBnFp2_squareRoot(out.getPointer(), x.getPointer()) == 0 616 | } 617 | 618 | // G1 -- 619 | type G1 struct { 620 | X Fp 621 | Y Fp 622 | Z Fp 623 | } 624 | 625 | // getPointer -- 626 | func (x *G1) getPointer() (p *C.mclBnG1) { 627 | // #nosec 628 | return (*C.mclBnG1)(unsafe.Pointer(x)) 629 | } 630 | 631 | // Clear -- 632 | func (x *G1) Clear() { 633 | // #nosec 634 | C.mclBnG1_clear(x.getPointer()) 635 | } 636 | 637 | // SetString -- 638 | func (x *G1) SetString(s string, base int) error { 639 | buf := []byte(s) 640 | // #nosec 641 | err := C.mclBnG1_setStr(x.getPointer(), (*C.char)(getPointer(buf)), C.size_t(len(buf)), C.int(base)) 642 | if err != 0 { 643 | return fmt.Errorf("err mclBnG1_setStr %x", err) 644 | } 645 | return nil 646 | } 647 | 648 | // Deserialize -- 649 | func (x *G1) Deserialize(buf []byte) error { 650 | // #nosec 651 | n := C.mclBnG1_deserialize(x.getPointer(), getPointer(buf), C.size_t(len(buf))) 652 | if n == 0 || int(n) != len(buf) { 653 | return fmt.Errorf("err mclBnG1_deserialize %x", buf) 654 | } 655 | return nil 656 | } 657 | 658 | const ZERO_HEADER = 1 << 6 659 | 660 | func isZeroFormat(buf []byte, n int) bool { 661 | if len(buf) < n { 662 | return false 663 | } 664 | if buf[0] != ZERO_HEADER { 665 | return false 666 | } 667 | for i := 1; i < n; i++ { 668 | if buf[i] != 0 { 669 | return false 670 | } 671 | } 672 | return true 673 | } 674 | 675 | // DeserializeUncompressed -- x.Deserialize() + y.Deserialize() 676 | func (x *G1) DeserializeUncompressed(buf []byte) error { 677 | if isZeroFormat(buf, GetG1ByteSize()*2) { 678 | x.Clear() 679 | return nil 680 | } 681 | // #nosec 682 | var n = C.mclBnFp_deserialize(x.X.getPointer(), getPointer(buf), C.size_t(len(buf))) 683 | if n == 0 { 684 | return fmt.Errorf("err UncompressedDeserialize X %x", buf) 685 | } 686 | buf = buf[n:] 687 | // #nosec 688 | n = C.mclBnFp_deserialize(x.Y.getPointer(), getPointer(buf), C.size_t(len(buf))) 689 | if n == 0 { 690 | return fmt.Errorf("err UncompressedDeserialize Y %x", buf) 691 | } 692 | x.Z.SetInt64(1) 693 | if !x.IsValid() { 694 | return fmt.Errorf("err invalid point") 695 | } 696 | return nil 697 | } 698 | 699 | // IsEqual -- 700 | func (x *G1) IsEqual(rhs *G1) bool { 701 | return C.mclBnG1_isEqual(x.getPointer(), rhs.getPointer()) == 1 702 | } 703 | 704 | // IsZero -- 705 | func (x *G1) IsZero() bool { 706 | return C.mclBnG1_isZero(x.getPointer()) == 1 707 | } 708 | 709 | // IsValid -- 710 | func (x *G1) IsValid() bool { 711 | return C.mclBnG1_isValid(x.getPointer()) == 1 712 | } 713 | 714 | // IsValidOrder -- 715 | func (x *G1) IsValidOrder() bool { 716 | return C.mclBnG1_isValidOrder(x.getPointer()) == 1 717 | } 718 | 719 | // HashAndMapTo -- 720 | func (x *G1) HashAndMapTo(buf []byte) error { 721 | // #nosec 722 | err := C.mclBnG1_hashAndMapTo(x.getPointer(), getPointer(buf), C.size_t(len(buf))) 723 | if err != 0 { 724 | return fmt.Errorf("err mclBnG1_hashAndMapTo %x", err) 725 | } 726 | return nil 727 | } 728 | 729 | // GetString -- 730 | func (x *G1) GetString(base int) string { 731 | buf := make([]byte, 2048) 732 | // #nosec 733 | n := C.mclBnG1_getStr((*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), x.getPointer(), C.int(base)) 734 | if n == 0 { 735 | panic("err mclBnG1_getStr") 736 | } 737 | return string(buf[:n]) 738 | } 739 | 740 | // Serialize -- 741 | func (x *G1) Serialize() []byte { 742 | buf := make([]byte, GetG1ByteSize()) 743 | // #nosec 744 | n := C.mclBnG1_serialize(unsafe.Pointer(&buf[0]), C.size_t(len(buf)), x.getPointer()) 745 | if n == 0 { 746 | panic("err mclBnG1_serialize") 747 | } 748 | return buf 749 | } 750 | 751 | // SerializeUncompressed -- all zero array if x.IsZero() 752 | func (x *G1) SerializeUncompressed() []byte { 753 | buf := make([]byte, GetG1ByteSize()*2) 754 | if x.IsZero() { 755 | buf[0] = ZERO_HEADER 756 | return buf 757 | } 758 | var nx G1 759 | G1Normalize(&nx, x) 760 | // #nosec 761 | var n = C.mclBnFp_serialize(unsafe.Pointer(&buf[0]), C.size_t(len(buf)), nx.X.getPointer()) 762 | if n == 0 { 763 | panic("err mclBnFp_serialize X") 764 | } 765 | n = C.mclBnFp_serialize(unsafe.Pointer(&buf[n]), C.size_t(len(buf))-n, nx.Y.getPointer()) 766 | if n == 0 { 767 | panic("err mclBnFp_serialize Y") 768 | } 769 | return buf 770 | } 771 | 772 | // G1Normalize -- 773 | func G1Normalize(out *G1, x *G1) { 774 | C.mclBnG1_normalize(out.getPointer(), x.getPointer()) 775 | } 776 | 777 | // G1Neg -- 778 | func G1Neg(out *G1, x *G1) { 779 | C.mclBnG1_neg(out.getPointer(), x.getPointer()) 780 | } 781 | 782 | // G1Dbl -- 783 | func G1Dbl(out *G1, x *G1) { 784 | C.mclBnG1_dbl(out.getPointer(), x.getPointer()) 785 | } 786 | 787 | // G1Add -- 788 | func G1Add(out *G1, x *G1, y *G1) { 789 | C.mclBnG1_add(out.getPointer(), x.getPointer(), y.getPointer()) 790 | } 791 | 792 | // G1Sub -- 793 | func G1Sub(out *G1, x *G1, y *G1) { 794 | C.mclBnG1_sub(out.getPointer(), x.getPointer(), y.getPointer()) 795 | } 796 | 797 | // G1Mul -- 798 | func G1Mul(out *G1, x *G1, y *Fr) { 799 | C.mclBnG1_mul(out.getPointer(), x.getPointer(), y.getPointer()) 800 | } 801 | 802 | // G1MulVec -- multi scalar multiplication out = sum mul(xVec[i], yVec[i]) 803 | func G1MulVec(out *G1, xVec []G1, yVec []Fr) { 804 | n := len(xVec) 805 | if n != len(yVec) { 806 | panic("xVec and yVec have the same size") 807 | } 808 | if n == 0 { 809 | out.Clear() 810 | return 811 | } 812 | C.mclBnG1_mulVec(out.getPointer(), (*C.mclBnG1)(unsafe.Pointer(&xVec[0])), (*C.mclBnFr)(unsafe.Pointer(&yVec[0])), (C.size_t)(n)) 813 | } 814 | 815 | // G1MulCT -- constant time (depending on bit lengh of y) 816 | func G1MulCT(out *G1, x *G1, y *Fr) { 817 | C.mclBnG1_mulCT(out.getPointer(), x.getPointer(), y.getPointer()) 818 | } 819 | 820 | // G2 -- 821 | type G2 struct { 822 | X Fp2 823 | Y Fp2 824 | Z Fp2 825 | } 826 | 827 | // getPointer -- 828 | func (x *G2) getPointer() (p *C.mclBnG2) { 829 | // #nosec 830 | return (*C.mclBnG2)(unsafe.Pointer(x)) 831 | } 832 | 833 | // Clear -- 834 | func (x *G2) Clear() { 835 | // #nosec 836 | C.mclBnG2_clear(x.getPointer()) 837 | } 838 | 839 | // SetString -- 840 | func (x *G2) SetString(s string, base int) error { 841 | buf := []byte(s) 842 | // #nosec 843 | err := C.mclBnG2_setStr(x.getPointer(), (*C.char)(getPointer(buf)), C.size_t(len(buf)), C.int(base)) 844 | if err != 0 { 845 | return fmt.Errorf("err mclBnG2_setStr %x", err) 846 | } 847 | return nil 848 | } 849 | 850 | // Deserialize -- 851 | func (x *G2) Deserialize(buf []byte) error { 852 | // #nosec 853 | n := C.mclBnG2_deserialize(x.getPointer(), getPointer(buf), C.size_t(len(buf))) 854 | if n == 0 || int(n) != len(buf) { 855 | return fmt.Errorf("err mclBnG2_deserialize %x", buf) 856 | } 857 | return nil 858 | } 859 | 860 | // DeserializeUncompressed -- x.Deserialize() + y.Deserialize() 861 | func (x *G2) DeserializeUncompressed(buf []byte) error { 862 | if isZeroFormat(buf, GetG2ByteSize()*2) { 863 | x.Clear() 864 | return nil 865 | } 866 | // #nosec 867 | var n = C.mclBnFp2_deserialize(x.X.getPointer(), getPointer(buf), C.size_t(len(buf))) 868 | if n == 0 { 869 | return fmt.Errorf("err UncompressedDeserialize X %x", buf) 870 | } 871 | buf = buf[n:] 872 | // #nosec 873 | n = C.mclBnFp2_deserialize(x.Y.getPointer(), getPointer(buf), C.size_t(len(buf))) 874 | if n == 0 { 875 | return fmt.Errorf("err UncompressedDeserialize Y %x", buf) 876 | } 877 | x.Z.D[0].SetInt64(1) 878 | x.Z.D[1].Clear() 879 | if !x.IsValid() { 880 | return fmt.Errorf("err invalid point") 881 | } 882 | return nil 883 | } 884 | 885 | // IsEqual -- 886 | func (x *G2) IsEqual(rhs *G2) bool { 887 | return C.mclBnG2_isEqual(x.getPointer(), rhs.getPointer()) == 1 888 | } 889 | 890 | // IsZero -- 891 | func (x *G2) IsZero() bool { 892 | return C.mclBnG2_isZero(x.getPointer()) == 1 893 | } 894 | 895 | // IsValid -- 896 | func (x *G2) IsValid() bool { 897 | return C.mclBnG2_isValid(x.getPointer()) == 1 898 | } 899 | 900 | // IsValidOrder -- 901 | func (x *G2) IsValidOrder() bool { 902 | return C.mclBnG2_isValidOrder(x.getPointer()) == 1 903 | } 904 | 905 | // HashAndMapTo -- 906 | func (x *G2) HashAndMapTo(buf []byte) error { 907 | // #nosec 908 | err := C.mclBnG2_hashAndMapTo(x.getPointer(), getPointer(buf), C.size_t(len(buf))) 909 | if err != 0 { 910 | return fmt.Errorf("err mclBnG2_hashAndMapTo %x", err) 911 | } 912 | return nil 913 | } 914 | 915 | // GetString -- 916 | func (x *G2) GetString(base int) string { 917 | buf := make([]byte, 2048) 918 | // #nosec 919 | n := C.mclBnG2_getStr((*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), x.getPointer(), C.int(base)) 920 | if n == 0 { 921 | panic("err mclBnG2_getStr") 922 | } 923 | return string(buf[:n]) 924 | } 925 | 926 | // Serialize -- 927 | func (x *G2) Serialize() []byte { 928 | buf := make([]byte, 2048) 929 | // #nosec 930 | n := C.mclBnG2_serialize(unsafe.Pointer(&buf[0]), C.size_t(len(buf)), x.getPointer()) 931 | if n == 0 { 932 | panic("err mclBnG2_serialize") 933 | } 934 | return buf[:n] 935 | } 936 | 937 | // SerializeUncompressed -- all zero array if x.IsZero() 938 | func (x *G2) SerializeUncompressed() []byte { 939 | buf := make([]byte, GetG2ByteSize()*2) 940 | if x.IsZero() { 941 | buf[0] = ZERO_HEADER 942 | return buf 943 | } 944 | var nx G2 945 | G2Normalize(&nx, x) 946 | // #nosec 947 | var n = C.mclBnFp2_serialize(unsafe.Pointer(&buf[0]), C.size_t(len(buf)), nx.X.getPointer()) 948 | if n == 0 { 949 | panic("err mclBnFp2_serialize X") 950 | } 951 | n = C.mclBnFp2_serialize(unsafe.Pointer(&buf[n]), C.size_t(len(buf))-n, nx.Y.getPointer()) 952 | if n == 0 { 953 | panic("err mclBnFp2_serialize Y") 954 | } 955 | return buf 956 | } 957 | 958 | // G2Normalize -- 959 | func G2Normalize(out *G2, x *G2) { 960 | C.mclBnG2_normalize(out.getPointer(), x.getPointer()) 961 | } 962 | 963 | // G2Neg -- 964 | func G2Neg(out *G2, x *G2) { 965 | C.mclBnG2_neg(out.getPointer(), x.getPointer()) 966 | } 967 | 968 | // G2Dbl -- 969 | func G2Dbl(out *G2, x *G2) { 970 | C.mclBnG2_dbl(out.getPointer(), x.getPointer()) 971 | } 972 | 973 | // G2Add -- 974 | func G2Add(out *G2, x *G2, y *G2) { 975 | C.mclBnG2_add(out.getPointer(), x.getPointer(), y.getPointer()) 976 | } 977 | 978 | // G2Sub -- 979 | func G2Sub(out *G2, x *G2, y *G2) { 980 | C.mclBnG2_sub(out.getPointer(), x.getPointer(), y.getPointer()) 981 | } 982 | 983 | // G2Mul -- 984 | func G2Mul(out *G2, x *G2, y *Fr) { 985 | C.mclBnG2_mul(out.getPointer(), x.getPointer(), y.getPointer()) 986 | } 987 | 988 | // G2MulVec -- multi scalar multiplication out = sum mul(xVec[i], yVec[i]) 989 | func G2MulVec(out *G2, xVec []G2, yVec []Fr) { 990 | n := len(xVec) 991 | if n != len(yVec) { 992 | panic("xVec and yVec have the same size") 993 | } 994 | if n == 0 { 995 | out.Clear() 996 | return 997 | } 998 | C.mclBnG2_mulVec(out.getPointer(), (*C.mclBnG2)(unsafe.Pointer(&xVec[0])), (*C.mclBnFr)(unsafe.Pointer(&yVec[0])), (C.size_t)(n)) 999 | } 1000 | 1001 | // GT -- 1002 | type GT struct { 1003 | v C.mclBnGT 1004 | } 1005 | 1006 | // getPointer -- 1007 | func (x *GT) getPointer() (p *C.mclBnGT) { 1008 | // #nosec 1009 | return (*C.mclBnGT)(unsafe.Pointer(x)) 1010 | } 1011 | 1012 | // Clear -- 1013 | func (x *GT) Clear() { 1014 | // #nosec 1015 | C.mclBnGT_clear(x.getPointer()) 1016 | } 1017 | 1018 | // SetInt64 -- 1019 | func (x *GT) SetInt64(v int64) { 1020 | // #nosec 1021 | C.mclBnGT_setInt(x.getPointer(), C.int64_t(v)) 1022 | } 1023 | 1024 | // SetString -- 1025 | func (x *GT) SetString(s string, base int) error { 1026 | buf := []byte(s) 1027 | // #nosec 1028 | err := C.mclBnGT_setStr(x.getPointer(), (*C.char)(getPointer(buf)), C.size_t(len(buf)), C.int(base)) 1029 | if err != 0 { 1030 | return fmt.Errorf("err mclBnGT_setStr %x", err) 1031 | } 1032 | return nil 1033 | } 1034 | 1035 | // Deserialize -- 1036 | func (x *GT) Deserialize(buf []byte) error { 1037 | // #nosec 1038 | n := C.mclBnGT_deserialize(x.getPointer(), getPointer(buf), C.size_t(len(buf))) 1039 | if n == 0 || int(n) != len(buf) { 1040 | return fmt.Errorf("err mclBnGT_deserialize %x", buf) 1041 | } 1042 | return nil 1043 | } 1044 | 1045 | // IsEqual -- 1046 | func (x *GT) IsEqual(rhs *GT) bool { 1047 | return C.mclBnGT_isEqual(x.getPointer(), rhs.getPointer()) == 1 1048 | } 1049 | 1050 | // IsZero -- 1051 | func (x *GT) IsZero() bool { 1052 | return C.mclBnGT_isZero(x.getPointer()) == 1 1053 | } 1054 | 1055 | // IsOne -- 1056 | func (x *GT) IsOne() bool { 1057 | return C.mclBnGT_isOne(x.getPointer()) == 1 1058 | } 1059 | 1060 | // GetString -- 1061 | func (x *GT) GetString(base int) string { 1062 | buf := make([]byte, 2048) 1063 | // #nosec 1064 | n := C.mclBnGT_getStr((*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), x.getPointer(), C.int(base)) 1065 | if n == 0 { 1066 | panic("err mclBnGT_getStr") 1067 | } 1068 | return string(buf[:n]) 1069 | } 1070 | 1071 | // Serialize -- 1072 | func (x *GT) Serialize() []byte { 1073 | buf := make([]byte, 2048) 1074 | // #nosec 1075 | n := C.mclBnGT_serialize(unsafe.Pointer(&buf[0]), C.size_t(len(buf)), x.getPointer()) 1076 | if n == 0 { 1077 | panic("err mclBnGT_serialize") 1078 | } 1079 | return buf[:n] 1080 | } 1081 | 1082 | // GTNeg -- 1083 | func GTNeg(out *GT, x *GT) { 1084 | C.mclBnGT_neg(out.getPointer(), x.getPointer()) 1085 | } 1086 | 1087 | // GTInv -- 1088 | func GTInv(out *GT, x *GT) { 1089 | C.mclBnGT_inv(out.getPointer(), x.getPointer()) 1090 | } 1091 | 1092 | // GTAdd -- 1093 | func GTAdd(out *GT, x *GT, y *GT) { 1094 | C.mclBnGT_add(out.getPointer(), x.getPointer(), y.getPointer()) 1095 | } 1096 | 1097 | // GTSub -- 1098 | func GTSub(out *GT, x *GT, y *GT) { 1099 | C.mclBnGT_sub(out.getPointer(), x.getPointer(), y.getPointer()) 1100 | } 1101 | 1102 | // GTMul -- 1103 | func GTMul(out *GT, x *GT, y *GT) { 1104 | C.mclBnGT_mul(out.getPointer(), x.getPointer(), y.getPointer()) 1105 | } 1106 | 1107 | // GTDiv -- 1108 | func GTDiv(out *GT, x *GT, y *GT) { 1109 | C.mclBnGT_div(out.getPointer(), x.getPointer(), y.getPointer()) 1110 | } 1111 | 1112 | // GTPow -- 1113 | func GTPow(out *GT, x *GT, y *Fr) { 1114 | C.mclBnGT_pow(out.getPointer(), x.getPointer(), y.getPointer()) 1115 | } 1116 | 1117 | // MapToG1 -- 1118 | func MapToG1(out *G1, x *Fp) error { 1119 | if C.mclBnFp_mapToG1(out.getPointer(), x.getPointer()) != 0 { 1120 | return fmt.Errorf("err mclBnFp_mapToG1") 1121 | } 1122 | return nil 1123 | } 1124 | 1125 | // MapToG2 -- 1126 | func MapToG2(out *G2, x *Fp2) error { 1127 | if C.mclBnFp2_mapToG2(out.getPointer(), x.getPointer()) != 0 { 1128 | return fmt.Errorf("err mclBnFp2_mapToG2") 1129 | } 1130 | return nil 1131 | } 1132 | 1133 | // Pairing -- 1134 | func Pairing(out *GT, x *G1, y *G2) { 1135 | C.mclBn_pairing(out.getPointer(), x.getPointer(), y.getPointer()) 1136 | } 1137 | 1138 | // FinalExp -- 1139 | func FinalExp(out *GT, x *GT) { 1140 | C.mclBn_finalExp(out.getPointer(), x.getPointer()) 1141 | } 1142 | 1143 | // MillerLoop -- 1144 | func MillerLoop(out *GT, x *G1, y *G2) { 1145 | C.mclBn_millerLoop(out.getPointer(), x.getPointer(), y.getPointer()) 1146 | } 1147 | 1148 | // MillerLoopVec -- multi pairings ; out = prod_i e(xVec[i], yVec[i]) 1149 | func MillerLoopVec(out *GT, xVec []G1, yVec []G2) { 1150 | n := len(xVec) 1151 | if n != len(yVec) { 1152 | panic("xVec and yVec have the same size") 1153 | } 1154 | if n == 0 { 1155 | out.SetInt64(1) 1156 | return 1157 | } 1158 | C.mclBn_millerLoopVec(out.getPointer(), (*C.mclBnG1)(unsafe.Pointer(&xVec[0])), (*C.mclBnG2)(unsafe.Pointer(&yVec[0])), (C.size_t)(n)) 1159 | } 1160 | 1161 | // GetUint64NumToPrecompute -- 1162 | func GetUint64NumToPrecompute() int { 1163 | return int(C.mclBn_getUint64NumToPrecompute()) 1164 | } 1165 | 1166 | // PrecomputeG2 -- 1167 | func PrecomputeG2(Qbuf []uint64, Q *G2) { 1168 | // #nosec 1169 | C.mclBn_precomputeG2((*C.uint64_t)(unsafe.Pointer(&Qbuf[0])), Q.getPointer()) 1170 | } 1171 | 1172 | // PrecomputedMillerLoop -- 1173 | func PrecomputedMillerLoop(out *GT, P *G1, Qbuf []uint64) { 1174 | // #nosec 1175 | C.mclBn_precomputedMillerLoop(out.getPointer(), P.getPointer(), (*C.uint64_t)(unsafe.Pointer(&Qbuf[0]))) 1176 | } 1177 | 1178 | // PrecomputedMillerLoop2 -- 1179 | func PrecomputedMillerLoop2(out *GT, P1 *G1, Q1buf []uint64, P2 *G1, Q2buf []uint64) { 1180 | // #nosec 1181 | C.mclBn_precomputedMillerLoop2(out.getPointer(), P1.getPointer(), (*C.uint64_t)(unsafe.Pointer(&Q1buf[0])), P1.getPointer(), (*C.uint64_t)(unsafe.Pointer(&Q1buf[0]))) 1182 | } 1183 | 1184 | // FrEvaluatePolynomial -- y = c[0] + c[1] * x + c[2] * x^2 + ... 1185 | func FrEvaluatePolynomial(y *Fr, c []Fr, x *Fr) error { 1186 | n := len(c) 1187 | if n == 0 { 1188 | y.Clear() 1189 | return nil 1190 | } 1191 | // #nosec 1192 | err := C.mclBn_FrEvaluatePolynomial(y.getPointer(), (*C.mclBnFr)(unsafe.Pointer(&c[0])), (C.size_t)(n), x.getPointer()) 1193 | if err != 0 { 1194 | return fmt.Errorf("err mclBn_FrEvaluatePolynomial") 1195 | } 1196 | return nil 1197 | } 1198 | 1199 | // G1EvaluatePolynomial -- y = c[0] + c[1] * x + c[2] * x^2 + ... 1200 | func G1EvaluatePolynomial(y *G1, c []G1, x *Fr) error { 1201 | n := len(c) 1202 | if n == 0 { 1203 | y.Clear() 1204 | return nil 1205 | } 1206 | // #nosec 1207 | err := C.mclBn_G1EvaluatePolynomial(y.getPointer(), (*C.mclBnG1)(unsafe.Pointer(&c[0])), (C.size_t)(n), x.getPointer()) 1208 | if err != 0 { 1209 | return fmt.Errorf("err mclBn_G1EvaluatePolynomial") 1210 | } 1211 | return nil 1212 | } 1213 | 1214 | // G2EvaluatePolynomial -- y = c[0] + c[1] * x + c[2] * x^2 + ... 1215 | func G2EvaluatePolynomial(y *G2, c []G2, x *Fr) error { 1216 | n := len(c) 1217 | if n == 0 { 1218 | y.Clear() 1219 | return nil 1220 | } 1221 | // #nosec 1222 | err := C.mclBn_G2EvaluatePolynomial(y.getPointer(), (*C.mclBnG2)(unsafe.Pointer(&c[0])), (C.size_t)(n), x.getPointer()) 1223 | if err != 0 { 1224 | return fmt.Errorf("err mclBn_G2EvaluatePolynomial") 1225 | } 1226 | return nil 1227 | } 1228 | 1229 | // FrLagrangeInterpolation -- 1230 | func FrLagrangeInterpolation(out *Fr, xVec []Fr, yVec []Fr) error { 1231 | n := len(xVec) 1232 | if n == 0 { 1233 | return fmt.Errorf("err FrLagrangeInterpolation:n=0") 1234 | } 1235 | if n != len(yVec) { 1236 | return fmt.Errorf("err FrLagrangeInterpolation:bad size") 1237 | } 1238 | // #nosec 1239 | err := C.mclBn_FrLagrangeInterpolation(out.getPointer(), (*C.mclBnFr)(unsafe.Pointer(&xVec[0])), (*C.mclBnFr)(unsafe.Pointer(&yVec[0])), (C.size_t)(n)) 1240 | if err != 0 { 1241 | return fmt.Errorf("err FrLagrangeInterpolation") 1242 | } 1243 | return nil 1244 | } 1245 | 1246 | // G1LagrangeInterpolation -- 1247 | func G1LagrangeInterpolation(out *G1, xVec []Fr, yVec []G1) error { 1248 | n := len(xVec) 1249 | if n == 0 { 1250 | return fmt.Errorf("err G1LagrangeInterpolation:n=0") 1251 | } 1252 | if n != len(yVec) { 1253 | return fmt.Errorf("err G1LagrangeInterpolation:bad size") 1254 | } 1255 | // #nosec 1256 | err := C.mclBn_G1LagrangeInterpolation(out.getPointer(), (*C.mclBnFr)(unsafe.Pointer(&xVec[0])), (*C.mclBnG1)(unsafe.Pointer(&yVec[0])), (C.size_t)(n)) 1257 | if err != 0 { 1258 | return fmt.Errorf("err G1LagrangeInterpolation") 1259 | } 1260 | return nil 1261 | } 1262 | 1263 | // G2LagrangeInterpolation -- 1264 | func G2LagrangeInterpolation(out *G2, xVec []Fr, yVec []G2) error { 1265 | n := len(xVec) 1266 | if n == 0 { 1267 | return fmt.Errorf("err G2LagrangeInterpolation:n=0") 1268 | } 1269 | if n != len(yVec) { 1270 | return fmt.Errorf("err G2LagrangeInterpolation:bad size") 1271 | } 1272 | // #nosec 1273 | err := C.mclBn_G2LagrangeInterpolation(out.getPointer(), (*C.mclBnFr)(unsafe.Pointer(&xVec[0])), (*C.mclBnG2)(unsafe.Pointer(&yVec[0])), (C.size_t)(n)) 1274 | if err != 0 { 1275 | return fmt.Errorf("err G2LagrangeInterpolation") 1276 | } 1277 | return nil 1278 | } 1279 | --------------------------------------------------------------------------------