Feature/key compression (#1990)

## What has changed?

I've introduced to the public binding functionality that will compress and decompress public keys of a variety of encoding and key types. This functionality supports all major byte encoding formats and the following EC public key types:

- `secp256k1` pks
- `bls12-381 g1` pks
- `bls12-381 g2` pks

## Why make the change?

We want shorter public (chat) keys and we want to be future proof and encoding agnostic. See the issue here https://github.com/status-im/status-go/issues/1937

---

* Added basic signature for compresspk and uncompresspk

* Added basic encoding information

* make vendor

* formatted imports for the linter

* Reformatted imports hoping linter likes it

* This linter is capricious

* Added check that the secp256k1 key is valid

* Added test for valid key

* Added multiformat/go-varint dep

* Added public key type handling

* Added key decompression with key type handling

* Added handling for '0x' type indentifying

* Added more robust testing

* Less lint for the linting gods

* make vendor for bls12_381

* Added bls12-381 compression tests

* Added decompress key expected results

* Refactor of typed and untyped keys in tests

* Lint god appeasment

* Refactor of sample public keys

* Implemented bls12-381 decompression

* gofmt

* Renamed decode/encode funcs to be more descriptive

* Added binary bindings for key de/compression

* Refactor of func parameters

gomobile is a bit tempermental using raw bytes as a parameter, so I've decided to use string only inputs and outputs

* gofmt

* Added function documentation

* Moved multiformat de/compression into api/multiformat ns

* Moved multiformat de/compression into api/multiformat ns

* Changed compress to serialize on API
This commit is contained in:
Samuel Hawksby-Robinson 2020-06-23 11:47:17 +01:00 committed by GitHub
parent 4720224ba2
commit c8f9dad554
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 7361 additions and 2 deletions

221
api/multiformat/utils.go Normal file
View file

@ -0,0 +1,221 @@
package multiformat
import (
"crypto/elliptic"
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
bls12381 "github.com/kilic/bls12-381"
"github.com/multiformats/go-multibase"
"github.com/multiformats/go-varint"
)
const (
secp256k1KeyType = 0xe7
bls12p381g1KeyType = 0xea
bls12p381g2KeyType = 0xeb
)
// SerializePublicKey serialises a non-serialised multibase encoded multicodec identified EC public key
// For details on usage see specs //TODO add the link to the specs
func SerializePublicKey(key, outputBase string) (string, error) {
dKey, err := multibaseDecode(key)
if err != nil {
return "", err
}
kt, i, err := getPublicKeyType(dKey)
if err != nil {
return "", err
}
cpk, err := compressPublicKey(dKey[i:], kt)
if err != nil {
return "", err
}
cpk = prependKeyIdentifier(cpk, kt, i)
return multibaseEncode(outputBase, cpk)
}
// DeserializePublicKey deserialise a serialised multibase encoded multicodec identified EC public key
// For details on usage see specs //TODO add the link to the specs
func DeserializePublicKey(key, outputBase string) (string, error) {
cpk, err := multibaseDecode(key)
if err != nil {
return "", err
}
kt, i, err := getPublicKeyType(cpk)
if err != nil {
return "", err
}
pk, err := decompressPublicKey(cpk[i:], kt)
if err != nil {
return "", err
}
pk = prependKeyIdentifier(pk, kt, i)
return multibaseEncode(outputBase, pk)
}
// getPublicKeyType wrapper for the `varint.FromUvarint()` func
func getPublicKeyType(key []byte) (uint64, int, error) {
return varint.FromUvarint(key)
}
// prependKeyIdentifier prepends an Unsigned Variable Integer (uvarint) to a given []byte
func prependKeyIdentifier(key []byte, kt uint64, ktl int) []byte {
buf := make([]byte, ktl)
varint.PutUvarint(buf, kt)
key = append(buf, key...)
return key
}
// compressPublicKey serves as logic switch function to parse key data for compression based on the given keyType
func compressPublicKey(key []byte, keyType uint64) ([]byte, error) {
switch keyType {
case secp256k1KeyType:
return compressSecp256k1PublicKey(key)
case bls12p381g1KeyType:
return compressBls12p381g1PublicKey(key)
case bls12p381g2KeyType:
return compressBls12p381g2PublicKey(key)
default:
return nil, fmt.Errorf("unsupported public key type '%X'", keyType)
}
}
// compressSecp256k1PublicKey is a dedicated key compression function for secp256k1 pks
func compressSecp256k1PublicKey(key []byte) ([]byte, error) {
x, y := elliptic.Unmarshal(secp256k1.S256(), key)
if err := isSecp256k1XYValid(key, x, y); err != nil {
return nil, err
}
cpk := secp256k1.CompressPubkey(x, y)
return cpk, nil
}
// compressBls12p381g1PublicKey is a dedicated key compression function for bls12 381 g1 pks
func compressBls12p381g1PublicKey(key []byte) ([]byte, error) {
g1 := bls12381.NewG1()
// Generate the G1 point
pg1, err := g1.FromBytes(key)
if err != nil {
return nil, err
}
cpk := g1.ToCompressed(pg1)
return cpk, nil
}
// compressBls12p381g1PublicKey is a dedicated key compression function for bls12 381 g2 pks
func compressBls12p381g2PublicKey(key []byte) ([]byte, error) {
g2 := bls12381.NewG2()
// Generate the G2 point
pg2, err := g2.FromBytes(key)
if err != nil {
return nil, err
}
cpk := g2.ToCompressed(pg2)
return cpk, nil
}
// decompressPublicKey serves as logic switch function to parse key data for decompression based on the given keyType
func decompressPublicKey(key []byte, keyType uint64) ([]byte, error) {
switch keyType {
case secp256k1KeyType:
return decompressSecp256k1PublicKey(key)
case bls12p381g1KeyType:
return decompressBls12p381g1PublicKey(key)
case bls12p381g2KeyType:
return decompressBls12p381g2PublicKey(key)
default:
return nil, fmt.Errorf("unsupported public key type '%X'", keyType)
}
}
// decompressSecp256k1PublicKey is a dedicated key decompression function for secp256k1 pks
func decompressSecp256k1PublicKey(key []byte) ([]byte, error) {
x, y := secp256k1.DecompressPubkey(key)
if err := isSecp256k1XYValid(key, x, y); err != nil {
return nil, err
}
k := elliptic.Marshal(secp256k1.S256(), x, y)
return k, nil
}
// isSecp256k1XYValid checks if a given x and y coordinate is nil, returns an error if either x or y is nil
// secp256k1.DecompressPubkey will not return an error if a compressed pk fails decompression and instead returns
// nil x, y coordinates
func isSecp256k1XYValid(key []byte, x, y *big.Int) error {
if x == nil || y == nil {
return fmt.Errorf("invalid public key format, '%b'", key)
}
return nil
}
// decompressBls12p381g1PublicKey is a dedicated key decompression function for bls12 381 g1 pks
func decompressBls12p381g1PublicKey(key []byte) ([]byte, error) {
g1 := bls12381.NewG1()
pg1, err := g1.FromCompressed(key)
if err != nil {
return nil, err
}
pk := g1.ToUncompressed(pg1)
return pk, nil
}
// decompressBls12p381g2PublicKey is a dedicated key decompression function for bls12 381 g2 pks
func decompressBls12p381g2PublicKey(key []byte) ([]byte, error) {
g2 := bls12381.NewG2()
pg2, err := g2.FromCompressed(key)
if err != nil {
return nil, err
}
pk := g2.ToUncompressed(pg2)
return pk, nil
}
// multibaseEncode wraps `multibase.Encode()` extending the base functionality to support `0x` prefixed strings
func multibaseEncode(base string, data []byte) (string, error) {
if base == "0x" {
base = "f"
}
return multibase.Encode(multibase.Encoding(base[0]), data)
}
// multibaseDecode wraps `multibase.Decode()` extending the base functionality to support `0x` prefixed strings
func multibaseDecode(data string) ([]byte, error) {
if data[0:2] == "0x" {
data = "f" + data[2:]
}
_, dd, err := multibase.Decode(data)
return dd, err
}

View file

@ -0,0 +1,293 @@
package multiformat
import (
"encoding/hex"
"fmt"
"testing"
"github.com/stretchr/testify/require"
)
var (
// secp256k1 sample public key
secPkB = []byte{
0x04,
0x26, 0x1c, 0x55, 0x67, 0x5e, 0x55, 0xff, 0x25,
0xed, 0xb5, 0x0b, 0x34, 0x5c, 0xfb, 0x3a, 0x3f,
0x35, 0xf6, 0x07, 0x12, 0xd2, 0x51, 0xcb, 0xaa,
0xab, 0x97, 0xbd, 0x50, 0x05, 0x4c, 0x6e, 0xbc,
0x3c, 0xd4, 0xe2, 0x22, 0x00, 0xc6, 0x8d, 0xaf,
0x74, 0x93, 0xe1, 0xf8, 0xda, 0x6a, 0x19, 0x0a,
0x68, 0xa6, 0x71, 0xe2, 0xd3, 0x97, 0x78, 0x09,
0x61, 0x24, 0x24, 0xc7, 0xc3, 0x88, 0x8b, 0xc6,
}
secPk = "f" + hex.EncodeToString(secPkB)
secPkBt = append([]byte{0xe7, 0x01}, secPkB...)
secPkt = "f" + hex.EncodeToString(secPkBt)
// bls12-381 G1 sample public key
bls12G1PkB = []byte{
0x17, 0xf1, 0xd3, 0xa7, 0x31, 0x97, 0xd7, 0x94,
0x26, 0x95, 0x63, 0x8c, 0x4f, 0xa9, 0xac, 0x0f,
0xc3, 0x68, 0x8c, 0x4f, 0x97, 0x74, 0xb9, 0x05,
0xa1, 0x4e, 0x3a, 0x3f, 0x17, 0x1b, 0xac, 0x58,
0x6c, 0x55, 0xe8, 0x3f, 0xf9, 0x7a, 0x1a, 0xef,
0xfb, 0x3a, 0xf0, 0x0a, 0xdb, 0x22, 0xc6, 0xbb,
0x08, 0xb3, 0xf4, 0x81, 0xe3, 0xaa, 0xa0, 0xf1,
0xa0, 0x9e, 0x30, 0xed, 0x74, 0x1d, 0x8a, 0xe4,
0xfc, 0xf5, 0xe0, 0x95, 0xd5, 0xd0, 0x0a, 0xf6,
0x00, 0xdb, 0x18, 0xcb, 0x2c, 0x04, 0xb3, 0xed,
0xd0, 0x3c, 0xc7, 0x44, 0xa2, 0x88, 0x8a, 0xe4,
0x0c, 0xaa, 0x23, 0x29, 0x46, 0xc5, 0xe7, 0xe1,
}
bls12G1Pk = "f" + hex.EncodeToString(bls12G1PkB)
bls12G1PkBt = append([]byte{0xea, 0x01}, bls12G1PkB...)
bls12G1Pkt = "f" + hex.EncodeToString(bls12G1PkBt)
// bls12 381 G2 sample public key
bls12G2PkB = []byte{
0x13, 0xe0, 0x2b, 0x60, 0x52, 0x71, 0x9f, 0x60,
0x7d, 0xac, 0xd3, 0xa0, 0x88, 0x27, 0x4f, 0x65,
0x59, 0x6b, 0xd0, 0xd0, 0x99, 0x20, 0xb6, 0x1a,
0xb5, 0xda, 0x61, 0xbb, 0xdc, 0x7f, 0x50, 0x49,
0x33, 0x4c, 0xf1, 0x12, 0x13, 0x94, 0x5d, 0x57,
0xe5, 0xac, 0x7d, 0x05, 0x5d, 0x04, 0x2b, 0x7e,
0x02, 0x4a, 0xa2, 0xb2, 0xf0, 0x8f, 0x0a, 0x91,
0x26, 0x08, 0x05, 0x27, 0x2d, 0xc5, 0x10, 0x51,
0xc6, 0xe4, 0x7a, 0xd4, 0xfa, 0x40, 0x3b, 0x02,
0xb4, 0x51, 0x0b, 0x64, 0x7a, 0xe3, 0xd1, 0x77,
0x0b, 0xac, 0x03, 0x26, 0xa8, 0x05, 0xbb, 0xef,
0xd4, 0x80, 0x56, 0xc8, 0xc1, 0x21, 0xbd, 0xb8,
0x06, 0x06, 0xc4, 0xa0, 0x2e, 0xa7, 0x34, 0xcc,
0x32, 0xac, 0xd2, 0xb0, 0x2b, 0xc2, 0x8b, 0x99,
0xcb, 0x3e, 0x28, 0x7e, 0x85, 0xa7, 0x63, 0xaf,
0x26, 0x74, 0x92, 0xab, 0x57, 0x2e, 0x99, 0xab,
0x3f, 0x37, 0x0d, 0x27, 0x5c, 0xec, 0x1d, 0xa1,
0xaa, 0xa9, 0x07, 0x5f, 0xf0, 0x5f, 0x79, 0xbe,
0x0c, 0xe5, 0xd5, 0x27, 0x72, 0x7d, 0x6e, 0x11,
0x8c, 0xc9, 0xcd, 0xc6, 0xda, 0x2e, 0x35, 0x1a,
0xad, 0xfd, 0x9b, 0xaa, 0x8c, 0xbd, 0xd3, 0xa7,
0x6d, 0x42, 0x9a, 0x69, 0x51, 0x60, 0xd1, 0x2c,
0x92, 0x3a, 0xc9, 0xcc, 0x3b, 0xac, 0xa2, 0x89,
0xe1, 0x93, 0x54, 0x86, 0x08, 0xb8, 0x28, 0x01,
}
bls12G2Pk = "f" + hex.EncodeToString(bls12G2PkB)
bls12G2PkBt = append([]byte{0xeb, 0x01}, bls12G2PkB...)
bls12G2Pkt = "f" + hex.EncodeToString(bls12G2PkBt)
)
func TestSerialisePublicKey(t *testing.T) {
cs := []struct {
Description string
OutBase string
Key string
Expected string
Error error
}{
{
"invalid key, with valid key type",
"z",
"0xe701ff42ea",
"",
fmt.Errorf("invalid public key format, '[11111111 1000010 11101010]'"),
},
{
"invalid key type, with invalid key",
"z",
"0xeeff42ea",
"",
fmt.Errorf("unsupported public key type '10BFEE'"),
},
{
"invalid encoding type, with valid key",
"p",
secPkt,
"",
fmt.Errorf("selected encoding not supported"),
},
{
"valid key, no key type defined",
"z",
secPk,
"",
fmt.Errorf("unsupported public key type '4'"),
},
{
"valid key, with base58 bitcoin encoding",
"z",
secPkt,
"zQ3shPyZJnxZK4Bwyx9QsaksNKDYTPmpwPvGSjMYVHoXHeEgB",
nil,
},
{
"valid key, with traditional hex encoding",
"0x",
secPkt,
"fe70102261c55675e55ff25edb50b345cfb3a3f35f60712d251cbaaab97bd50054c6ebc",
nil,
},
{
"valid secp256k1 key, with multiencoding hex encoding",
"f",
secPkt,
"fe70102261c55675e55ff25edb50b345cfb3a3f35f60712d251cbaaab97bd50054c6ebc",
nil,
},
{
"valid bls12-381 g1 key, with multiencoding hex encoding",
"f",
bls12G1Pkt,
"fea0197f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb",
nil,
},
{
"valid bls12-381 g1 key, with base58 bitcoin encoding",
"z",
bls12G1Pkt,
"z3tEFUdV4D3tCMG6Fr1deVvt32DCS1Y4SxDGoELedXaMUdTdr5FfZvBnbK9bWMhAGj3RHk",
nil,
},
{
"valid bls12-381 g1 key, with no key type",
"f",
bls12G1Pk,
"",
fmt.Errorf("unsupported public key type '17'"),
},
{
"valid bls12-381 g2 key, with multiencoding hex encoding",
"f",
bls12G2Pkt,
"feb0193e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8",
nil,
},
{
"valid bls12-381 g2 key, with base58 bitcoin encoding",
"z",
bls12G2Pkt,
"zUC77n3BqSWuoGMY7ut91NDoWzpithCd4GwPLAnv9fc7drWY4wBTvMX1y9eGSAuiBpktqGAocND2KXdu1HqNgrd6i3vCZKCLqZ3nQFaEA2FpTs7ZEChRpWReLvYyXNYUHvQjyKd",
nil,
},
{
"valid bls12-381 g2 key, with no key type",
"f",
bls12G2Pk,
"",
fmt.Errorf("unsupported public key type '13'"),
},
}
for _, c := range cs {
cpk, err := SerializePublicKey(c.Key, c.OutBase)
require.Equal(t, c.Expected, cpk, c.Description)
if c.Error != nil {
require.EqualError(t, err, c.Error.Error(), c.Description)
continue
}
require.NoError(t, err, c.Description)
}
}
func TestDeserialisePublicKey(t *testing.T) {
cs := []struct {
Description string
Key string
OutBase string
Expected string
Error error
}{
{
"valid key with valid encoding type '0x'",
"0xe70102261c55675e55ff25edb50b345cfb3a3f35f60712d251cbaaab97bd50054c6ebc",
"f",
secPkt,
nil,
},
{
"valid key with valid encoding type 'f'",
"fe70102261c55675e55ff25edb50b345cfb3a3f35f60712d251cbaaab97bd50054c6ebc",
"f",
secPkt,
nil,
},
{
"valid key with valid encoding type 'z'",
"zQ3shPyZJnxZK4Bwyx9QsaksNKDYTPmpwPvGSjMYVHoXHeEgB",
"f",
secPkt,
nil,
},
{
"valid key with mismatched encoding type 'f' instead of 'z'",
"fQ3shPyZJnxZK4Bwyx9QsaksNKDYTPmpwPvGSjMYVHoXHeEgB",
"f",
"",
fmt.Errorf("encoding/hex: invalid byte: U+0051 'Q'"),
},
{
"valid key with no encoding type, in base58 encoding",
"Q3shPyZJnxZK4Bwyx9QsaksNKDYTPmpwPvGSjMYVHoXHeEgB",
"f",
"",
fmt.Errorf("selected encoding not supported"),
},
{
"valid bls12-381 g1 key encoding type 'z'",
"z3tEFUdV4D3tCMG6Fr1deVvt32DCS1Y4SxDGoELedXaMUdTdr5FfZvBnbK9bWMhAGj3RHk",
"f",
bls12G1Pkt,
nil,
},
{
"valid bls12-381 g1 key encoding type 'f'",
"fea0197f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb",
"f",
bls12G1Pkt,
nil,
},
{
"valid bls12-381 g1 key encoding type '0x'",
"0xea0197f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb",
"f",
bls12G1Pkt,
nil,
},
{
"valid bls12-381 g2 key encoding type 'z'",
"zUC77n3BqSWuoGMY7ut91NDoWzpithCd4GwPLAnv9fc7drWY4wBTvMX1y9eGSAuiBpktqGAocND2KXdu1HqNgrd6i3vCZKCLqZ3nQFaEA2FpTs7ZEChRpWReLvYyXNYUHvQjyKd",
"f",
bls12G2Pkt,
nil,
},
{
"valid bls12-381 g2 key encoding type 'f'",
"feb0193e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8",
"f",
bls12G2Pkt,
nil,
},
{
"valid bls12-381 g2 key encoding type '0x'",
"0xeb0193e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8",
"f",
bls12G2Pkt,
nil,
},
}
for _, c := range cs {
key, err := DeserializePublicKey(c.Key, c.OutBase)
require.Exactly(t, c.Expected, key, c.Description)
if c.Error != nil {
require.EqualError(t, err, c.Error.Error(), c.Description)
continue
}
require.NoError(t, err, c.Description)
}
}

3
go.mod
View file

@ -22,6 +22,7 @@ require (
github.com/google/uuid v1.1.1
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 // indirect
github.com/kilic/bls12-381 v0.0.0-20200607163746-32e1441c8a9f
github.com/leodido/go-urn v1.2.0 // indirect
github.com/lib/pq v1.3.0
github.com/libp2p/go-libp2p v0.4.2 // indirect
@ -29,6 +30,8 @@ require (
github.com/lucasb-eyer/go-colorful v1.0.3
github.com/mattn/go-pointer v0.0.0-20190911064623-a0a44394634f
github.com/multiformats/go-multiaddr v0.1.1
github.com/multiformats/go-multibase v0.0.1
github.com/multiformats/go-varint v0.0.5
github.com/mutecomm/go-sqlcipher v0.0.0-20190227152316-55dbde17881f
github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd
github.com/pborman/uuid v1.2.0

7
go.sum
View file

@ -138,7 +138,6 @@ github.com/elastic/gosigar v0.10.4/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTy
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
github.com/ethereum/go-ethereum v1.8.20/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
github.com/ethereum/go-ethereum v1.9.2/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
github.com/ethereum/go-ethereum v1.9.13 h1:rOPqjSngvs1VSYH2H+PMPiWt4VEulvNRbFgqiGqJM3E=
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc h1:jtW8jbpkO4YirRSyepBOH8E+2HEw6/hKkBvFPwhUN8c=
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
@ -303,6 +302,8 @@ github.com/karalabe/usb v0.0.0-20190819132248-550797b1cad8/go.mod h1:Od972xHfMJo
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 h1:ZHuwnjpP8LsVsUYqTqeVAI+GfDfJ6UNPrExZF+vX/DQ=
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
github.com/kilic/bls12-381 v0.0.0-20200607163746-32e1441c8a9f h1:qET3Wx0v8tMtoTOQnsJXVvqvCopSf48qobR6tcJuDHo=
github.com/kilic/bls12-381 v0.0.0-20200607163746-32e1441c8a9f/go.mod h1:XXfR6YFCRSrkEXbNlIyDsgXVNJWVUV30m/ebkVy9n6s=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
@ -498,6 +499,8 @@ github.com/multiformats/go-multihash v0.0.8 h1:wrYcW5yxSi3dU07n5jnuS5PrNwyHy0zRH
github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ=
github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg=
github.com/multiformats/go-varint v0.0.5 h1:XVZwSo04Cs3j/jS0uAEPpT3JY6DzMcVLLoWOSnCxOjg=
github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
github.com/mutecomm/go-sqlcipher v0.0.0-20190227152316-55dbde17881f h1:hd3r+uv9DNLScbOrnlj82rBldHQf3XWmCeXAWbw8euQ=
github.com/mutecomm/go-sqlcipher v0.0.0-20190227152316-55dbde17881f/go.mod h1:MyUWrZlB1aI5bs7j9/pJ8ckLLZ4QcCYcNiSbsAW32D4=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
@ -636,7 +639,6 @@ github.com/status-im/rendezvous v1.3.0/go.mod h1:+hzjuP+j/XzLPeF6E50b88pWOTLdTcw
github.com/status-im/status-go/extkeys v1.0.0/go.mod h1:GdqJbrcpkNm5ZsSCpp+PdMxnXx+OcRBdm3PI0rs1FpU=
github.com/status-im/status-go/extkeys v1.1.2 h1:FSjARgDathJ3rIapJt851LsIXP9Oyuu2M2jPJKuzloU=
github.com/status-im/status-go/extkeys v1.1.2/go.mod h1:hCmFzb2jiiVF2voZKYbzuhOQiHHCmyLJsZJXrFFg7BY=
github.com/status-im/status-go/waku v1.3.1 h1:hXvWsS/5ZKJ5iUXJvIZRE4Z78OH5u4d7OwBEPLNY9Gs=
github.com/status-im/status-go/whisper/v6 v6.2.6 h1:xELIv/8QB9CQlJjChnCPt4COWOFmgsc2kl03Y3Dspmo=
github.com/status-im/status-go/whisper/v6 v6.2.6/go.mod h1:csqMoPMkCPW1NJO56HJzNTWAl9UMdetnQzkPbPjsAC4=
github.com/status-im/tcp-shaker v0.0.0-20191114194237-215893130501 h1:oa0KU5jJRNtXaM/P465MhvSFo/HM2O8qi2DDuPcd7ro=
@ -789,6 +791,7 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 h1:dHtDnRWQtSx0Hjq9kvKFpBh9uPPKfQN70NZZmvssGwk=
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU=

View file

@ -13,6 +13,7 @@ import (
"github.com/ethereum/go-ethereum/log"
"github.com/status-im/status-go/api"
"github.com/status-im/status-go/api/multiformat"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/exportlogs"
"github.com/status-im/status-go/extkeys"
@ -668,3 +669,25 @@ func ValidateMnemonic(mnemonic string) string {
err := m.ValidateMnemonic(mnemonic, extkeys.Language(0))
return makeJSONResponse(err)
}
// SerializePublicKey compresses an uncompressed multibase encoded multicodec identified EC public key
// For details on usage see specs //TODO add the link to the specs
func MultiformatSerializePublicKey(key, outBase string) string {
cpk, err := multiformat.SerializePublicKey(key, outBase)
if err != nil {
return makeJSONResponse(err)
}
return cpk
}
// DeserializePublicKey decompresses a compressed multibase encoded multicodec identified EC public key
// For details on usage see specs //TODO add the link to the specs
func MultiformatDeserializePublicKey(key, outBase string) string {
pk, err := multiformat.DeserializePublicKey(key, outBase)
if err != nil {
return makeJSONResponse(err)
}
return pk
}

2
vendor/github.com/kilic/bls12-381/.gitignore generated vendored Normal file
View file

@ -0,0 +1,2 @@
*.out
eip2537

202
vendor/github.com/kilic/bls12-381/LICENSE generated vendored Normal file
View file

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

30
vendor/github.com/kilic/bls12-381/README.md generated vendored Normal file
View file

@ -0,0 +1,30 @@
### High Speed BLS12-381 Implementation in Go
#### Pairing Instance
A Group instance or a pairing engine instance _is not_ suitable for concurrent processing since an instance has its own preallocated memory for temporary variables. A new instance must be created for each thread.
#### Base Field
x86 optimized base field is generated with [kilic/fp](https://github.com/kilic/fp) and for native go is generated with [goff](https://github.com/ConsenSys/goff). Generated codes are slightly edited in both for further requirements.
#### Scalar Field
Standart big.Int module is currently used for scalar field implementation. x86 optimized faster field implementation is planned to be added.
#### Serialization
Point serialization is in line with [zkcrypto library](https://github.com/zkcrypto/pairing/tree/master/src/bls12_381#serialization).
#### Hashing to Curve
Hashing to curve implementations for both G1 and G2 follows `_XMD:SHA-256_SSWU_RO_` and `_XMD:SHA-256_SSWU_NU_` suites as defined in `v7` of [irtf hash to curve draft](https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/).
#### Benchmarks
on _3.1 GHz i5_
```
BenchmarkPairing 1034837 ns/op
```

66
vendor/github.com/kilic/bls12-381/arithmetic_decl.go generated vendored Normal file
View file

@ -0,0 +1,66 @@
// +build amd64,!generic
package bls12381
import (
"golang.org/x/sys/cpu"
)
func init() {
if !cpu.X86.HasADX || !cpu.X86.HasBMI2 {
mul = mulNoADX
}
}
var mul func(c, a, b *fe) = mulADX
func square(c, a *fe) {
mul(c, a, a)
}
func neg(c, a *fe) {
if a.isZero() {
c.set(a)
} else {
_neg(c, a)
}
}
//go:noescape
func add(c, a, b *fe)
//go:noescape
func addAssign(a, b *fe)
//go:noescape
func ladd(c, a, b *fe)
//go:noescape
func laddAssign(a, b *fe)
//go:noescape
func double(c, a *fe)
//go:noescape
func doubleAssign(a *fe)
//go:noescape
func ldouble(c, a *fe)
//go:noescape
func sub(c, a, b *fe)
//go:noescape
func subAssign(a, b *fe)
//go:noescape
func lsubAssign(a, b *fe)
//go:noescape
func _neg(c, a *fe)
//go:noescape
func mulNoADX(c, a, b *fe)
//go:noescape
func mulADX(c, a, b *fe)

View file

@ -0,0 +1,566 @@
// +build !amd64 generic
// Native go field arithmetic code is generated with 'goff'
// https://github.com/ConsenSys/goff
// Many function signature of field operations are renamed.
// Copyright 2020 ConsenSys AG
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// field modulus q =
//
// 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
// Code generated by goff DO NOT EDIT
// goff version: v0.1.0 - build: 790f1f56eac432441e043abff8819eacddd1d668
// fe are assumed to be in Montgomery form in all methods
// /!\ WARNING /!\
// this code has not been audited and is provided as-is. In particular,
// there is no security guarantees such as constant time implementation
// or side-channel attack resistance
// /!\ WARNING /!\
// Package bls (generated by goff) contains field arithmetics operations
package bls12381
import (
"math/bits"
)
func add(z, x, y *fe) {
var carry uint64
z[0], carry = bits.Add64(x[0], y[0], 0)
z[1], carry = bits.Add64(x[1], y[1], carry)
z[2], carry = bits.Add64(x[2], y[2], carry)
z[3], carry = bits.Add64(x[3], y[3], carry)
z[4], carry = bits.Add64(x[4], y[4], carry)
z[5], _ = bits.Add64(x[5], y[5], carry)
// if z > q --> z -= q
// note: this is NOT constant time
if !(z[5] < 1873798617647539866 || (z[5] == 1873798617647539866 && (z[4] < 5412103778470702295 || (z[4] == 5412103778470702295 && (z[3] < 7239337960414712511 || (z[3] == 7239337960414712511 && (z[2] < 7435674573564081700 || (z[2] == 7435674573564081700 && (z[1] < 2210141511517208575 || (z[1] == 2210141511517208575 && (z[0] < 13402431016077863595))))))))))) {
var b uint64
z[0], b = bits.Sub64(z[0], 13402431016077863595, 0)
z[1], b = bits.Sub64(z[1], 2210141511517208575, b)
z[2], b = bits.Sub64(z[2], 7435674573564081700, b)
z[3], b = bits.Sub64(z[3], 7239337960414712511, b)
z[4], b = bits.Sub64(z[4], 5412103778470702295, b)
z[5], _ = bits.Sub64(z[5], 1873798617647539866, b)
}
}
func addAssign(x, y *fe) {
var carry uint64
x[0], carry = bits.Add64(x[0], y[0], 0)
x[1], carry = bits.Add64(x[1], y[1], carry)
x[2], carry = bits.Add64(x[2], y[2], carry)
x[3], carry = bits.Add64(x[3], y[3], carry)
x[4], carry = bits.Add64(x[4], y[4], carry)
x[5], _ = bits.Add64(x[5], y[5], carry)
// if z > q --> z -= q
// note: this is NOT constant time
if !(x[5] < 1873798617647539866 || (x[5] == 1873798617647539866 && (x[4] < 5412103778470702295 || (x[4] == 5412103778470702295 && (x[3] < 7239337960414712511 || (x[3] == 7239337960414712511 && (x[2] < 7435674573564081700 || (x[2] == 7435674573564081700 && (x[1] < 2210141511517208575 || (x[1] == 2210141511517208575 && (x[0] < 13402431016077863595))))))))))) {
var b uint64
x[0], b = bits.Sub64(x[0], 13402431016077863595, 0)
x[1], b = bits.Sub64(x[1], 2210141511517208575, b)
x[2], b = bits.Sub64(x[2], 7435674573564081700, b)
x[3], b = bits.Sub64(x[3], 7239337960414712511, b)
x[4], b = bits.Sub64(x[4], 5412103778470702295, b)
x[5], _ = bits.Sub64(x[5], 1873798617647539866, b)
}
}
func ladd(z, x, y *fe) {
var carry uint64
z[0], carry = bits.Add64(x[0], y[0], 0)
z[1], carry = bits.Add64(x[1], y[1], carry)
z[2], carry = bits.Add64(x[2], y[2], carry)
z[3], carry = bits.Add64(x[3], y[3], carry)
z[4], carry = bits.Add64(x[4], y[4], carry)
z[5], _ = bits.Add64(x[5], y[5], carry)
}
func laddAssign(x, y *fe) {
var carry uint64
x[0], carry = bits.Add64(x[0], y[0], 0)
x[1], carry = bits.Add64(x[1], y[1], carry)
x[2], carry = bits.Add64(x[2], y[2], carry)
x[3], carry = bits.Add64(x[3], y[3], carry)
x[4], carry = bits.Add64(x[4], y[4], carry)
x[5], _ = bits.Add64(x[5], y[5], carry)
}
func double(z, x *fe) {
var carry uint64
z[0], carry = bits.Add64(x[0], x[0], 0)
z[1], carry = bits.Add64(x[1], x[1], carry)
z[2], carry = bits.Add64(x[2], x[2], carry)
z[3], carry = bits.Add64(x[3], x[3], carry)
z[4], carry = bits.Add64(x[4], x[4], carry)
z[5], _ = bits.Add64(x[5], x[5], carry)
// if z > q --> z -= q
// note: this is NOT constant time
if !(z[5] < 1873798617647539866 || (z[5] == 1873798617647539866 && (z[4] < 5412103778470702295 || (z[4] == 5412103778470702295 && (z[3] < 7239337960414712511 || (z[3] == 7239337960414712511 && (z[2] < 7435674573564081700 || (z[2] == 7435674573564081700 && (z[1] < 2210141511517208575 || (z[1] == 2210141511517208575 && (z[0] < 13402431016077863595))))))))))) {
var b uint64
z[0], b = bits.Sub64(z[0], 13402431016077863595, 0)
z[1], b = bits.Sub64(z[1], 2210141511517208575, b)
z[2], b = bits.Sub64(z[2], 7435674573564081700, b)
z[3], b = bits.Sub64(z[3], 7239337960414712511, b)
z[4], b = bits.Sub64(z[4], 5412103778470702295, b)
z[5], _ = bits.Sub64(z[5], 1873798617647539866, b)
}
}
func doubleAssign(z *fe) {
var carry uint64
z[0], carry = bits.Add64(z[0], z[0], 0)
z[1], carry = bits.Add64(z[1], z[1], carry)
z[2], carry = bits.Add64(z[2], z[2], carry)
z[3], carry = bits.Add64(z[3], z[3], carry)
z[4], carry = bits.Add64(z[4], z[4], carry)
z[5], _ = bits.Add64(z[5], z[5], carry)
// if z > q --> z -= q
// note: this is NOT constant time
if !(z[5] < 1873798617647539866 || (z[5] == 1873798617647539866 && (z[4] < 5412103778470702295 || (z[4] == 5412103778470702295 && (z[3] < 7239337960414712511 || (z[3] == 7239337960414712511 && (z[2] < 7435674573564081700 || (z[2] == 7435674573564081700 && (z[1] < 2210141511517208575 || (z[1] == 2210141511517208575 && (z[0] < 13402431016077863595))))))))))) {
var b uint64
z[0], b = bits.Sub64(z[0], 13402431016077863595, 0)
z[1], b = bits.Sub64(z[1], 2210141511517208575, b)
z[2], b = bits.Sub64(z[2], 7435674573564081700, b)
z[3], b = bits.Sub64(z[3], 7239337960414712511, b)
z[4], b = bits.Sub64(z[4], 5412103778470702295, b)
z[5], _ = bits.Sub64(z[5], 1873798617647539866, b)
}
}
func ldouble(z, x *fe) {
var carry uint64
z[0], carry = bits.Add64(x[0], x[0], 0)
z[1], carry = bits.Add64(x[1], x[1], carry)
z[2], carry = bits.Add64(x[2], x[2], carry)
z[3], carry = bits.Add64(x[3], x[3], carry)
z[4], carry = bits.Add64(x[4], x[4], carry)
z[5], _ = bits.Add64(x[5], x[5], carry)
}
func sub(z, x, y *fe) {
var b uint64
z[0], b = bits.Sub64(x[0], y[0], 0)
z[1], b = bits.Sub64(x[1], y[1], b)
z[2], b = bits.Sub64(x[2], y[2], b)
z[3], b = bits.Sub64(x[3], y[3], b)
z[4], b = bits.Sub64(x[4], y[4], b)
z[5], b = bits.Sub64(x[5], y[5], b)
if b != 0 {
var c uint64
z[0], c = bits.Add64(z[0], 13402431016077863595, 0)
z[1], c = bits.Add64(z[1], 2210141511517208575, c)
z[2], c = bits.Add64(z[2], 7435674573564081700, c)
z[3], c = bits.Add64(z[3], 7239337960414712511, c)
z[4], c = bits.Add64(z[4], 5412103778470702295, c)
z[5], _ = bits.Add64(z[5], 1873798617647539866, c)
}
}
func subAssign(z, x *fe) {
var b uint64
z[0], b = bits.Sub64(z[0], x[0], 0)
z[1], b = bits.Sub64(z[1], x[1], b)
z[2], b = bits.Sub64(z[2], x[2], b)
z[3], b = bits.Sub64(z[3], x[3], b)
z[4], b = bits.Sub64(z[4], x[4], b)
z[5], b = bits.Sub64(z[5], x[5], b)
if b != 0 {
var c uint64
z[0], c = bits.Add64(z[0], 13402431016077863595, 0)
z[1], c = bits.Add64(z[1], 2210141511517208575, c)
z[2], c = bits.Add64(z[2], 7435674573564081700, c)
z[3], c = bits.Add64(z[3], 7239337960414712511, c)
z[4], c = bits.Add64(z[4], 5412103778470702295, c)
z[5], _ = bits.Add64(z[5], 1873798617647539866, c)
}
}
func lsubAssign(z, x *fe) {
var b uint64
z[0], b = bits.Sub64(z[0], x[0], 0)
z[1], b = bits.Sub64(z[1], x[1], b)
z[2], b = bits.Sub64(z[2], x[2], b)
z[3], b = bits.Sub64(z[3], x[3], b)
z[4], b = bits.Sub64(z[4], x[4], b)
z[5], _ = bits.Sub64(z[5], x[5], b)
}
func neg(z *fe, x *fe) {
if x.isZero() {
z.zero()
return
}
var borrow uint64
z[0], borrow = bits.Sub64(13402431016077863595, x[0], 0)
z[1], borrow = bits.Sub64(2210141511517208575, x[1], borrow)
z[2], borrow = bits.Sub64(7435674573564081700, x[2], borrow)
z[3], borrow = bits.Sub64(7239337960414712511, x[3], borrow)
z[4], borrow = bits.Sub64(5412103778470702295, x[4], borrow)
z[5], _ = bits.Sub64(1873798617647539866, x[5], borrow)
}
func mul(z, x, y *fe) {
var t [6]uint64
var c [3]uint64
{
// round 0
v := x[0]
c[1], c[0] = bits.Mul64(v, y[0])
m := c[0] * 9940570264628428797
c[2] = madd0(m, 13402431016077863595, c[0])
c[1], c[0] = madd1(v, y[1], c[1])
c[2], t[0] = madd2(m, 2210141511517208575, c[2], c[0])
c[1], c[0] = madd1(v, y[2], c[1])
c[2], t[1] = madd2(m, 7435674573564081700, c[2], c[0])
c[1], c[0] = madd1(v, y[3], c[1])
c[2], t[2] = madd2(m, 7239337960414712511, c[2], c[0])
c[1], c[0] = madd1(v, y[4], c[1])
c[2], t[3] = madd2(m, 5412103778470702295, c[2], c[0])
c[1], c[0] = madd1(v, y[5], c[1])
t[5], t[4] = madd3(m, 1873798617647539866, c[0], c[2], c[1])
}
{
// round 1
v := x[1]
c[1], c[0] = madd1(v, y[0], t[0])
m := c[0] * 9940570264628428797
c[2] = madd0(m, 13402431016077863595, c[0])
c[1], c[0] = madd2(v, y[1], c[1], t[1])
c[2], t[0] = madd2(m, 2210141511517208575, c[2], c[0])
c[1], c[0] = madd2(v, y[2], c[1], t[2])
c[2], t[1] = madd2(m, 7435674573564081700, c[2], c[0])
c[1], c[0] = madd2(v, y[3], c[1], t[3])
c[2], t[2] = madd2(m, 7239337960414712511, c[2], c[0])
c[1], c[0] = madd2(v, y[4], c[1], t[4])
c[2], t[3] = madd2(m, 5412103778470702295, c[2], c[0])
c[1], c[0] = madd2(v, y[5], c[1], t[5])
t[5], t[4] = madd3(m, 1873798617647539866, c[0], c[2], c[1])
}
{
// round 2
v := x[2]
c[1], c[0] = madd1(v, y[0], t[0])
m := c[0] * 9940570264628428797
c[2] = madd0(m, 13402431016077863595, c[0])
c[1], c[0] = madd2(v, y[1], c[1], t[1])
c[2], t[0] = madd2(m, 2210141511517208575, c[2], c[0])
c[1], c[0] = madd2(v, y[2], c[1], t[2])
c[2], t[1] = madd2(m, 7435674573564081700, c[2], c[0])
c[1], c[0] = madd2(v, y[3], c[1], t[3])
c[2], t[2] = madd2(m, 7239337960414712511, c[2], c[0])
c[1], c[0] = madd2(v, y[4], c[1], t[4])
c[2], t[3] = madd2(m, 5412103778470702295, c[2], c[0])
c[1], c[0] = madd2(v, y[5], c[1], t[5])
t[5], t[4] = madd3(m, 1873798617647539866, c[0], c[2], c[1])
}
{
// round 3
v := x[3]
c[1], c[0] = madd1(v, y[0], t[0])
m := c[0] * 9940570264628428797
c[2] = madd0(m, 13402431016077863595, c[0])
c[1], c[0] = madd2(v, y[1], c[1], t[1])
c[2], t[0] = madd2(m, 2210141511517208575, c[2], c[0])
c[1], c[0] = madd2(v, y[2], c[1], t[2])
c[2], t[1] = madd2(m, 7435674573564081700, c[2], c[0])
c[1], c[0] = madd2(v, y[3], c[1], t[3])
c[2], t[2] = madd2(m, 7239337960414712511, c[2], c[0])
c[1], c[0] = madd2(v, y[4], c[1], t[4])
c[2], t[3] = madd2(m, 5412103778470702295, c[2], c[0])
c[1], c[0] = madd2(v, y[5], c[1], t[5])
t[5], t[4] = madd3(m, 1873798617647539866, c[0], c[2], c[1])
}
{
// round 4
v := x[4]
c[1], c[0] = madd1(v, y[0], t[0])
m := c[0] * 9940570264628428797
c[2] = madd0(m, 13402431016077863595, c[0])
c[1], c[0] = madd2(v, y[1], c[1], t[1])
c[2], t[0] = madd2(m, 2210141511517208575, c[2], c[0])
c[1], c[0] = madd2(v, y[2], c[1], t[2])
c[2], t[1] = madd2(m, 7435674573564081700, c[2], c[0])
c[1], c[0] = madd2(v, y[3], c[1], t[3])
c[2], t[2] = madd2(m, 7239337960414712511, c[2], c[0])
c[1], c[0] = madd2(v, y[4], c[1], t[4])
c[2], t[3] = madd2(m, 5412103778470702295, c[2], c[0])
c[1], c[0] = madd2(v, y[5], c[1], t[5])
t[5], t[4] = madd3(m, 1873798617647539866, c[0], c[2], c[1])
}
{
// round 5
v := x[5]
c[1], c[0] = madd1(v, y[0], t[0])
m := c[0] * 9940570264628428797
c[2] = madd0(m, 13402431016077863595, c[0])
c[1], c[0] = madd2(v, y[1], c[1], t[1])
c[2], z[0] = madd2(m, 2210141511517208575, c[2], c[0])
c[1], c[0] = madd2(v, y[2], c[1], t[2])
c[2], z[1] = madd2(m, 7435674573564081700, c[2], c[0])
c[1], c[0] = madd2(v, y[3], c[1], t[3])
c[2], z[2] = madd2(m, 7239337960414712511, c[2], c[0])
c[1], c[0] = madd2(v, y[4], c[1], t[4])
c[2], z[3] = madd2(m, 5412103778470702295, c[2], c[0])
c[1], c[0] = madd2(v, y[5], c[1], t[5])
z[5], z[4] = madd3(m, 1873798617647539866, c[0], c[2], c[1])
}
// if z > q --> z -= q
// note: this is NOT constant time
if !(z[5] < 1873798617647539866 || (z[5] == 1873798617647539866 && (z[4] < 5412103778470702295 || (z[4] == 5412103778470702295 && (z[3] < 7239337960414712511 || (z[3] == 7239337960414712511 && (z[2] < 7435674573564081700 || (z[2] == 7435674573564081700 && (z[1] < 2210141511517208575 || (z[1] == 2210141511517208575 && (z[0] < 13402431016077863595))))))))))) {
var b uint64
z[0], b = bits.Sub64(z[0], 13402431016077863595, 0)
z[1], b = bits.Sub64(z[1], 2210141511517208575, b)
z[2], b = bits.Sub64(z[2], 7435674573564081700, b)
z[3], b = bits.Sub64(z[3], 7239337960414712511, b)
z[4], b = bits.Sub64(z[4], 5412103778470702295, b)
z[5], _ = bits.Sub64(z[5], 1873798617647539866, b)
}
}
func square(z, x *fe) {
var p [6]uint64
var u, v uint64
{
// round 0
u, p[0] = bits.Mul64(x[0], x[0])
m := p[0] * 9940570264628428797
C := madd0(m, 13402431016077863595, p[0])
var t uint64
t, u, v = madd1sb(x[0], x[1], u)
C, p[0] = madd2(m, 2210141511517208575, v, C)
t, u, v = madd1s(x[0], x[2], t, u)
C, p[1] = madd2(m, 7435674573564081700, v, C)
t, u, v = madd1s(x[0], x[3], t, u)
C, p[2] = madd2(m, 7239337960414712511, v, C)
t, u, v = madd1s(x[0], x[4], t, u)
C, p[3] = madd2(m, 5412103778470702295, v, C)
_, u, v = madd1s(x[0], x[5], t, u)
p[5], p[4] = madd3(m, 1873798617647539866, v, C, u)
}
{
// round 1
m := p[0] * 9940570264628428797
C := madd0(m, 13402431016077863595, p[0])
u, v = madd1(x[1], x[1], p[1])
C, p[0] = madd2(m, 2210141511517208575, v, C)
var t uint64
t, u, v = madd2sb(x[1], x[2], p[2], u)
C, p[1] = madd2(m, 7435674573564081700, v, C)
t, u, v = madd2s(x[1], x[3], p[3], t, u)
C, p[2] = madd2(m, 7239337960414712511, v, C)
t, u, v = madd2s(x[1], x[4], p[4], t, u)
C, p[3] = madd2(m, 5412103778470702295, v, C)
_, u, v = madd2s(x[1], x[5], p[5], t, u)
p[5], p[4] = madd3(m, 1873798617647539866, v, C, u)
}
{
// round 2
m := p[0] * 9940570264628428797
C := madd0(m, 13402431016077863595, p[0])
C, p[0] = madd2(m, 2210141511517208575, p[1], C)
u, v = madd1(x[2], x[2], p[2])
C, p[1] = madd2(m, 7435674573564081700, v, C)
var t uint64
t, u, v = madd2sb(x[2], x[3], p[3], u)
C, p[2] = madd2(m, 7239337960414712511, v, C)
t, u, v = madd2s(x[2], x[4], p[4], t, u)
C, p[3] = madd2(m, 5412103778470702295, v, C)
_, u, v = madd2s(x[2], x[5], p[5], t, u)
p[5], p[4] = madd3(m, 1873798617647539866, v, C, u)
}
{
// round 3
m := p[0] * 9940570264628428797
C := madd0(m, 13402431016077863595, p[0])
C, p[0] = madd2(m, 2210141511517208575, p[1], C)
C, p[1] = madd2(m, 7435674573564081700, p[2], C)
u, v = madd1(x[3], x[3], p[3])
C, p[2] = madd2(m, 7239337960414712511, v, C)
var t uint64
t, u, v = madd2sb(x[3], x[4], p[4], u)
C, p[3] = madd2(m, 5412103778470702295, v, C)
_, u, v = madd2s(x[3], x[5], p[5], t, u)
p[5], p[4] = madd3(m, 1873798617647539866, v, C, u)
}
{
// round 4
m := p[0] * 9940570264628428797
C := madd0(m, 13402431016077863595, p[0])
C, p[0] = madd2(m, 2210141511517208575, p[1], C)
C, p[1] = madd2(m, 7435674573564081700, p[2], C)
C, p[2] = madd2(m, 7239337960414712511, p[3], C)
u, v = madd1(x[4], x[4], p[4])
C, p[3] = madd2(m, 5412103778470702295, v, C)
_, u, v = madd2sb(x[4], x[5], p[5], u)
p[5], p[4] = madd3(m, 1873798617647539866, v, C, u)
}
{
// round 5
m := p[0] * 9940570264628428797
C := madd0(m, 13402431016077863595, p[0])
C, z[0] = madd2(m, 2210141511517208575, p[1], C)
C, z[1] = madd2(m, 7435674573564081700, p[2], C)
C, z[2] = madd2(m, 7239337960414712511, p[3], C)
C, z[3] = madd2(m, 5412103778470702295, p[4], C)
u, v = madd1(x[5], x[5], p[5])
z[5], z[4] = madd3(m, 1873798617647539866, v, C, u)
}
// if z > q --> z -= q
// note: this is NOT constant time
if !(z[5] < 1873798617647539866 || (z[5] == 1873798617647539866 && (z[4] < 5412103778470702295 || (z[4] == 5412103778470702295 && (z[3] < 7239337960414712511 || (z[3] == 7239337960414712511 && (z[2] < 7435674573564081700 || (z[2] == 7435674573564081700 && (z[1] < 2210141511517208575 || (z[1] == 2210141511517208575 && (z[0] < 13402431016077863595))))))))))) {
var b uint64
z[0], b = bits.Sub64(z[0], 13402431016077863595, 0)
z[1], b = bits.Sub64(z[1], 2210141511517208575, b)
z[2], b = bits.Sub64(z[2], 7435674573564081700, b)
z[3], b = bits.Sub64(z[3], 7239337960414712511, b)
z[4], b = bits.Sub64(z[4], 5412103778470702295, b)
z[5], _ = bits.Sub64(z[5], 1873798617647539866, b)
}
}
// arith.go
// Copyright 2020 ConsenSys AG
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by goff DO NOT EDIT
func madd(a, b, t, u, v uint64) (uint64, uint64, uint64) {
var carry uint64
hi, lo := bits.Mul64(a, b)
v, carry = bits.Add64(lo, v, 0)
u, carry = bits.Add64(hi, u, carry)
t, _ = bits.Add64(t, 0, carry)
return t, u, v
}
// madd0 hi = a*b + c (discards lo bits)
func madd0(a, b, c uint64) (hi uint64) {
var carry, lo uint64
hi, lo = bits.Mul64(a, b)
_, carry = bits.Add64(lo, c, 0)
hi, _ = bits.Add64(hi, 0, carry)
return
}
// madd1 hi, lo = a*b + c
func madd1(a, b, c uint64) (hi uint64, lo uint64) {
var carry uint64
hi, lo = bits.Mul64(a, b)
lo, carry = bits.Add64(lo, c, 0)
hi, _ = bits.Add64(hi, 0, carry)
return
}
// madd2 hi, lo = a*b + c + d
func madd2(a, b, c, d uint64) (hi uint64, lo uint64) {
var carry uint64
hi, lo = bits.Mul64(a, b)
c, carry = bits.Add64(c, d, 0)
hi, _ = bits.Add64(hi, 0, carry)
lo, carry = bits.Add64(lo, c, 0)
hi, _ = bits.Add64(hi, 0, carry)
return
}
// madd2s superhi, hi, lo = 2*a*b + c + d + e
func madd2s(a, b, c, d, e uint64) (superhi, hi, lo uint64) {
var carry, sum uint64
hi, lo = bits.Mul64(a, b)
lo, carry = bits.Add64(lo, lo, 0)
hi, superhi = bits.Add64(hi, hi, carry)
sum, carry = bits.Add64(c, e, 0)
hi, _ = bits.Add64(hi, 0, carry)
lo, carry = bits.Add64(lo, sum, 0)
hi, _ = bits.Add64(hi, 0, carry)
hi, _ = bits.Add64(hi, 0, d)
return
}
func madd1s(a, b, d, e uint64) (superhi, hi, lo uint64) {
var carry uint64
hi, lo = bits.Mul64(a, b)
lo, carry = bits.Add64(lo, lo, 0)
hi, superhi = bits.Add64(hi, hi, carry)
lo, carry = bits.Add64(lo, e, 0)
hi, _ = bits.Add64(hi, 0, carry)
hi, _ = bits.Add64(hi, 0, d)
return
}
func madd2sb(a, b, c, e uint64) (superhi, hi, lo uint64) {
var carry, sum uint64
hi, lo = bits.Mul64(a, b)
lo, carry = bits.Add64(lo, lo, 0)
hi, superhi = bits.Add64(hi, hi, carry)
sum, carry = bits.Add64(c, e, 0)
hi, _ = bits.Add64(hi, 0, carry)
lo, carry = bits.Add64(lo, sum, 0)
hi, _ = bits.Add64(hi, 0, carry)
return
}
func madd1sb(a, b, e uint64) (superhi, hi, lo uint64) {
var carry uint64
hi, lo = bits.Mul64(a, b)
lo, carry = bits.Add64(lo, lo, 0)
hi, superhi = bits.Add64(hi, hi, carry)
lo, carry = bits.Add64(lo, e, 0)
hi, _ = bits.Add64(hi, 0, carry)
return
}
func madd3(a, b, c, d, e uint64) (hi uint64, lo uint64) {
var carry uint64
hi, lo = bits.Mul64(a, b)
c, carry = bits.Add64(c, d, 0)
hi, _ = bits.Add64(hi, 0, carry)
lo, carry = bits.Add64(lo, c, 0)
hi, _ = bits.Add64(hi, e, carry)
return
}

2151
vendor/github.com/kilic/bls12-381/arithmetic_x86.s generated vendored Normal file

File diff suppressed because it is too large Load diff

234
vendor/github.com/kilic/bls12-381/bls12_381.go generated vendored Normal file
View file

@ -0,0 +1,234 @@
package bls12381
/*
Field Constants
*/
// Base field modulus
// p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab
// Size of six words
// r = 2 ^ 384
// modulus = p
var modulus = fe{0xb9feffffffffaaab, 0x1eabfffeb153ffff, 0x6730d2a0f6b0f624, 0x64774b84f38512bf, 0x4b1ba7b6434bacd7, 0x1a0111ea397fe69a}
// -p^(-1) mod 2^64
var inp uint64 = 0x89f3fffcfffcfffd
// r mod p
var r1 = &fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493}
// r^2 mod p
var r2 = &fe{
0xf4df1f341c341746, 0x0a76e6a609d104f1, 0x8de5476c4c95b6d5, 0x67eb88a9939d83c0, 0x9a793e85b519952d, 0x11988fe592cae3aa,
}
// -1 + 0 * u
var negativeOne2 = &fe2{
fe{0x43f5fffffffcaaae, 0x32b7fff2ed47fffd, 0x07e83a49a2e99d69, 0xeca8f3318332bb7a, 0xef148d1ea0f4c069, 0x040ab3263eff0206},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
}
// 2 ^ (-1)
var twoInv = &fe{0x1804000000015554, 0x855000053ab00001, 0x633cb57c253c276f, 0x6e22d1ec31ebb502, 0xd3916126f2d14ca2, 0x17fbb8571a006596}
// (p - 3) / 4
var pMinus3Over4 = bigFromHex("0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce144afd9cc34a83dac3d8907aaffffac54ffffee7fbfffffffeaaa")
// (p + 1) / 4
var pPlus1Over4 = bigFromHex("0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce144afd9cc34a83dac3d8907aaffffac54ffffee7fbfffffffeaab")
// (p - 1) / 2
var pMinus1Over2 = bigFromHex("0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ffffdcff7fffffffd555")
// -1
var nonResidue1 = &fe{0x43f5fffffffcaaae, 0x32b7fff2ed47fffd, 0x07e83a49a2e99d69, 0xeca8f3318332bb7a, 0xef148d1ea0f4c069, 0x040ab3263eff0206}
// (1 + 1 * u)
var nonResidue2 = &fe2{
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
}
/*
Curve Constants
*/
// b coefficient for G1
var b = &fe{0xaa270000000cfff3, 0x53cc0032fc34000a, 0x478fe97a6b0a807f, 0xb1d37ebee6ba24d7, 0x8ec9733bbf78ab2f, 0x09d645513d83de7e}
// b coefficient for G2
var b2 = &fe2{
fe{0xaa270000000cfff3, 0x53cc0032fc34000a, 0x478fe97a6b0a807f, 0xb1d37ebee6ba24d7, 0x8ec9733bbf78ab2f, 0x09d645513d83de7e},
fe{0xaa270000000cfff3, 0x53cc0032fc34000a, 0x478fe97a6b0a807f, 0xb1d37ebee6ba24d7, 0x8ec9733bbf78ab2f, 0x09d645513d83de7e},
}
// Group order
var q = bigFromHex("0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001")
// G1 cofactor
var cofactorG1 = bigFromHex("0x396c8c005555e1568c00aaab0000aaab")
// G2 cofactor
var cofactorG2 = bigFromHex("5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5")
// Efficient G1 cofactor
var cofactorEFFG1 = bigFromHex("0xd201000000010001")
// Efficient G2 cofactor
var cofactorEFFG2 = bigFromHex("0x0bc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551")
// G1 generator
var g1One = PointG1{
fe{0x5cb38790fd530c16, 0x7817fc679976fff5, 0x154f95c7143ba1c1, 0xf0ae6acdf3d0e747, 0xedce6ecc21dbf440, 0x120177419e0bfb75},
fe{0xbaac93d50ce72271, 0x8c22631a7918fd8e, 0xdd595f13570725ce, 0x51ac582950405194, 0x0e1c8c3fad0059c0, 0x0bbc3efc5008a26a},
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
}
var G1One = g1One
// Negated G1 generator
var g1NegativeOne = PointG1{
fe{0x5cb38790fd530c16, 0x7817fc679976fff5, 0x154f95c7143ba1c1, 0xf0ae6acdf3d0e747, 0xedce6ecc21dbf440, 0x120177419e0bfb75},
fe{0xff526c2af318883a, 0x92899ce4383b0270, 0x89d7738d9fa9d055, 0x12caf35ba344c12a, 0x3cff1b76964b5317, 0x0e44d2ede9774430},
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
}
// G2 generator
var g2One = PointG2{
fe2{
fe{0xf5f28fa202940a10, 0xb3f5fb2687b4961a, 0xa1a893b53e2ae580, 0x9894999d1a3caee9, 0x6f67b7631863366b, 0x058191924350bcd7},
fe{0xa5a9c0759e23f606, 0xaaa0c59dbccd60c3, 0x3bb17e18e2867806, 0x1b1ab6cc8541b367, 0xc2b6ed0ef2158547, 0x11922a097360edf3},
},
fe2{
fe{0x4c730af860494c4a, 0x597cfa1f5e369c5a, 0xe7e6856caa0a635a, 0xbbefb5e96e0d495f, 0x07d3a975f0ef25a2, 0x083fd8e7e80dae5},
fe{0xadc0fc92df64b05d, 0x18aa270a2b1461dc, 0x86adac6a3be4eba0, 0x79495c4ec93da33a, 0xe7175850a43ccaed, 0xb2bc2a163de1bf2},
},
fe2{
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
}
var G2One = g2One
/*
Frobenious Coeffs
*/
var frobeniusCoeffs2 = [2]fe{
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
fe{0x43f5fffffffcaaae, 0x32b7fff2ed47fffd, 0x07e83a49a2e99d69, 0xeca8f3318332bb7a, 0xef148d1ea0f4c069, 0x040ab3263eff0206},
}
var frobeniusCoeffs61 = [6]fe2{
fe2{
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
fe{0xcd03c9e48671f071, 0x5dab22461fcda5d2, 0x587042afd3851b95, 0x8eb60ebe01bacb9e, 0x03f97d6e83d050d2, 0x18f0206554638741},
},
fe2{
fe{0x30f1361b798a64e8, 0xf3b8ddab7ece5a2a, 0x16a8ca3ac61577f7, 0xc26a2ff874fd029b, 0x3636b76660701c6e, 0x051ba4ab241b6160},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
},
fe2{
fe{0xcd03c9e48671f071, 0x5dab22461fcda5d2, 0x587042afd3851b95, 0x8eb60ebe01bacb9e, 0x03f97d6e83d050d2, 0x18f0206554638741},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
fe{0x30f1361b798a64e8, 0xf3b8ddab7ece5a2a, 0x16a8ca3ac61577f7, 0xc26a2ff874fd029b, 0x3636b76660701c6e, 0x051ba4ab241b6160},
},
}
var frobeniusCoeffs62 = [6]fe2{
fe2{
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x890dc9e4867545c3, 0x2af322533285a5d5, 0x50880866309b7e2c, 0xa20d1b8c7e881024, 0x14e4f04fe2db9068, 0x14e56d3f1564853a},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0xcd03c9e48671f071, 0x5dab22461fcda5d2, 0x587042afd3851b95, 0x8eb60ebe01bacb9e, 0x03f97d6e83d050d2, 0x18f0206554638741},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x43f5fffffffcaaae, 0x32b7fff2ed47fffd, 0x07e83a49a2e99d69, 0xeca8f3318332bb7a, 0xef148d1ea0f4c069, 0x040ab3263eff0206},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x30f1361b798a64e8, 0xf3b8ddab7ece5a2a, 0x16a8ca3ac61577f7, 0xc26a2ff874fd029b, 0x3636b76660701c6e, 0x051ba4ab241b6160},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0xecfb361b798dba3a, 0xc100ddb891865a2c, 0x0ec08ff1232bda8e, 0xd5c13cc6f1ca4721, 0x47222a47bf7b5c04, 0x0110f184e51c5f59},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
}
var frobeniusCoeffs12 = [12]fe2{
fe2{
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x07089552b319d465, 0xc6695f92b50a8313, 0x97e83cccd117228f, 0xa35baecab2dc29ee, 0x1ce393ea5daace4d, 0x08f2220fb0fb66eb},
fe{0xb2f66aad4ce5d646, 0x5842a06bfc497cec, 0xcf4895d42599d394, 0xc11b9cba40a8e8d0, 0x2e3813cbe5a0de89, 0x110eefda88847faf},
},
fe2{
fe{0xecfb361b798dba3a, 0xc100ddb891865a2c, 0x0ec08ff1232bda8e, 0xd5c13cc6f1ca4721, 0x47222a47bf7b5c04, 0x0110f184e51c5f59},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x3e2f585da55c9ad1, 0x4294213d86c18183, 0x382844c88b623732, 0x92ad2afd19103e18, 0x1d794e4fac7cf0b9, 0x0bd592fc7d825ec8},
fe{0x7bcfa7a25aa30fda, 0xdc17dec12a927e7c, 0x2f088dd86b4ebef1, 0xd1ca2087da74d4a7, 0x2da2596696cebc1d, 0x0e2b7eedbbfd87d2},
},
fe2{
fe{0x30f1361b798a64e8, 0xf3b8ddab7ece5a2a, 0x16a8ca3ac61577f7, 0xc26a2ff874fd029b, 0x3636b76660701c6e, 0x051ba4ab241b6160},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x3726c30af242c66c, 0x7c2ac1aad1b6fe70, 0xa04007fbba4b14a2, 0xef517c3266341429, 0x0095ba654ed2226b, 0x02e370eccc86f7dd},
fe{0x82d83cf50dbce43f, 0xa2813e53df9d018f, 0xc6f0caa53c65e181, 0x7525cf528d50fe95, 0x4a85ed50f4798a6b, 0x171da0fd6cf8eebd},
},
fe2{
fe{0x43f5fffffffcaaae, 0x32b7fff2ed47fffd, 0x07e83a49a2e99d69, 0xeca8f3318332bb7a, 0xef148d1ea0f4c069, 0x040ab3263eff0206},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0xb2f66aad4ce5d646, 0x5842a06bfc497cec, 0xcf4895d42599d394, 0xc11b9cba40a8e8d0, 0x2e3813cbe5a0de89, 0x110eefda88847faf},
fe{0x07089552b319d465, 0xc6695f92b50a8313, 0x97e83cccd117228f, 0xa35baecab2dc29ee, 0x1ce393ea5daace4d, 0x08f2220fb0fb66eb},
},
fe2{
fe{0xcd03c9e48671f071, 0x5dab22461fcda5d2, 0x587042afd3851b95, 0x8eb60ebe01bacb9e, 0x03f97d6e83d050d2, 0x18f0206554638741},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x7bcfa7a25aa30fda, 0xdc17dec12a927e7c, 0x2f088dd86b4ebef1, 0xd1ca2087da74d4a7, 0x2da2596696cebc1d, 0x0e2b7eedbbfd87d2},
fe{0x3e2f585da55c9ad1, 0x4294213d86c18183, 0x382844c88b623732, 0x92ad2afd19103e18, 0x1d794e4fac7cf0b9, 0x0bd592fc7d825ec8},
},
fe2{
fe{0x890dc9e4867545c3, 0x2af322533285a5d5, 0x50880866309b7e2c, 0xa20d1b8c7e881024, 0x14e4f04fe2db9068, 0x14e56d3f1564853a},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x82d83cf50dbce43f, 0xa2813e53df9d018f, 0xc6f0caa53c65e181, 0x7525cf528d50fe95, 0x4a85ed50f4798a6b, 0x171da0fd6cf8eebd},
fe{0x3726c30af242c66c, 0x7c2ac1aad1b6fe70, 0xa04007fbba4b14a2, 0xef517c3266341429, 0x0095ba654ed2226b, 0x02e370eccc86f7dd},
},
}
/*
x
*/
var x = bigFromHex("0xd201000000010000")

338
vendor/github.com/kilic/bls12-381/field_element.go generated vendored Normal file
View file

@ -0,0 +1,338 @@
package bls12381
import (
"crypto/rand"
"encoding/hex"
"fmt"
"io"
"math/big"
)
// fe is base field element representation
type fe /*** ***/ [6]uint64
// fe2 is element representation of 'fp2' which is quadratic extention of base field 'fp'
// Representation follows c[0] + c[1] * u encoding order.
type fe2 /** ***/ [2]fe
// fe6 is element representation of 'fp6' field which is cubic extention of 'fp2'
// Representation follows c[0] + c[1] * v + c[2] * v^2 encoding order.
type fe6 /** ***/ [3]fe2
// fe12 is element representation of 'fp12' field which is quadratic extention of 'fp6'
// Representation follows c[0] + c[1] * w encoding order.
type fe12 /** ***/ [2]fe6
func (fe *fe) setBytes(in []byte) *fe {
size := 48
l := len(in)
if l >= size {
l = size
}
padded := make([]byte, size)
copy(padded[size-l:], in[:])
var a int
for i := 0; i < 6; i++ {
a = size - i*8
fe[i] = uint64(padded[a-1]) | uint64(padded[a-2])<<8 |
uint64(padded[a-3])<<16 | uint64(padded[a-4])<<24 |
uint64(padded[a-5])<<32 | uint64(padded[a-6])<<40 |
uint64(padded[a-7])<<48 | uint64(padded[a-8])<<56
}
return fe
}
func (fe *fe) setBig(a *big.Int) *fe {
return fe.setBytes(a.Bytes())
}
func (fe *fe) setString(s string) (*fe, error) {
if s[:2] == "0x" {
s = s[2:]
}
bytes, err := hex.DecodeString(s)
if err != nil {
return nil, err
}
return fe.setBytes(bytes), nil
}
func (fe *fe) set(fe2 *fe) *fe {
fe[0] = fe2[0]
fe[1] = fe2[1]
fe[2] = fe2[2]
fe[3] = fe2[3]
fe[4] = fe2[4]
fe[5] = fe2[5]
return fe
}
func (fe *fe) bytes() []byte {
out := make([]byte, 48)
var a int
for i := 0; i < 6; i++ {
a = 48 - i*8
out[a-1] = byte(fe[i])
out[a-2] = byte(fe[i] >> 8)
out[a-3] = byte(fe[i] >> 16)
out[a-4] = byte(fe[i] >> 24)
out[a-5] = byte(fe[i] >> 32)
out[a-6] = byte(fe[i] >> 40)
out[a-7] = byte(fe[i] >> 48)
out[a-8] = byte(fe[i] >> 56)
}
return out
}
func (fe *fe) big() *big.Int {
return new(big.Int).SetBytes(fe.bytes())
}
func (fe *fe) string() (s string) {
for i := 5; i >= 0; i-- {
s = fmt.Sprintf("%s%16.16x", s, fe[i])
}
return "0x" + s
}
func (fe *fe) zero() *fe {
fe[0] = 0
fe[1] = 0
fe[2] = 0
fe[3] = 0
fe[4] = 0
fe[5] = 0
return fe
}
func (fe *fe) one() *fe {
return fe.set(r1)
}
func (fe *fe) rand(r io.Reader) (*fe, error) {
bi, err := rand.Int(r, modulus.big())
if err != nil {
return nil, err
}
return fe.setBig(bi), nil
}
func (fe *fe) isValid() bool {
return fe.cmp(&modulus) == -1
}
func (fe *fe) isOdd() bool {
var mask uint64 = 1
return fe[0]&mask != 0
}
func (fe *fe) isEven() bool {
var mask uint64 = 1
return fe[0]&mask == 0
}
func (fe *fe) isZero() bool {
return (fe[5] | fe[4] | fe[3] | fe[2] | fe[1] | fe[0]) == 0
}
func (fe *fe) isOne() bool {
return fe.equal(r1)
}
func (fe *fe) cmp(fe2 *fe) int {
for i := 5; i > -1; i-- {
if fe[i] > fe2[i] {
return 1
} else if fe[i] < fe2[i] {
return -1
}
}
return 0
}
func (fe *fe) equal(fe2 *fe) bool {
return fe2[0] == fe[0] && fe2[1] == fe[1] && fe2[2] == fe[2] && fe2[3] == fe[3] && fe2[4] == fe[4] && fe2[5] == fe[5]
}
func (e *fe) signBE() bool {
negZ, z := new(fe), new(fe)
fromMont(z, e)
neg(negZ, z)
return negZ.cmp(z) > -1
}
func (e *fe) sign() bool {
r := new(fe)
fromMont(r, e)
return r[0]&1 == 0
}
func (fe *fe) div2(e uint64) {
fe[0] = fe[0]>>1 | fe[1]<<63
fe[1] = fe[1]>>1 | fe[2]<<63
fe[2] = fe[2]>>1 | fe[3]<<63
fe[3] = fe[3]>>1 | fe[4]<<63
fe[4] = fe[4]>>1 | fe[5]<<63
fe[5] = fe[5]>>1 | e<<63
}
func (fe *fe) mul2() uint64 {
e := fe[5] >> 63
fe[5] = fe[5]<<1 | fe[4]>>63
fe[4] = fe[4]<<1 | fe[3]>>63
fe[3] = fe[3]<<1 | fe[2]>>63
fe[2] = fe[2]<<1 | fe[1]>>63
fe[1] = fe[1]<<1 | fe[0]>>63
fe[0] = fe[0] << 1
return e
}
func (e *fe2) zero() *fe2 {
e[0].zero()
e[1].zero()
return e
}
func (e *fe2) one() *fe2 {
e[0].one()
e[1].zero()
return e
}
func (e *fe2) set(e2 *fe2) *fe2 {
e[0].set(&e2[0])
e[1].set(&e2[1])
return e
}
func (e *fe2) rand(r io.Reader) (*fe2, error) {
a0, err := new(fe).rand(r)
if err != nil {
return nil, err
}
a1, err := new(fe).rand(r)
if err != nil {
return nil, err
}
return &fe2{*a0, *a1}, nil
}
func (e *fe2) isOne() bool {
return e[0].isOne() && e[1].isZero()
}
func (e *fe2) isZero() bool {
return e[0].isZero() && e[1].isZero()
}
func (e *fe2) equal(e2 *fe2) bool {
return e[0].equal(&e2[0]) && e[1].equal(&e2[1])
}
func (e *fe2) signBE() bool {
if !e[1].isZero() {
return e[1].signBE()
}
return e[0].signBE()
}
func (e *fe2) sign() bool {
r := new(fe)
if !e[0].isZero() {
fromMont(r, &e[0])
return r[0]&1 == 0
}
fromMont(r, &e[1])
return r[0]&1 == 0
}
func (e *fe6) zero() *fe6 {
e[0].zero()
e[1].zero()
e[2].zero()
return e
}
func (e *fe6) one() *fe6 {
e[0].one()
e[1].zero()
e[2].zero()
return e
}
func (e *fe6) set(e2 *fe6) *fe6 {
e[0].set(&e2[0])
e[1].set(&e2[1])
e[2].set(&e2[2])
return e
}
func (e *fe6) rand(r io.Reader) (*fe6, error) {
a0, err := new(fe2).rand(r)
if err != nil {
return nil, err
}
a1, err := new(fe2).rand(r)
if err != nil {
return nil, err
}
a2, err := new(fe2).rand(r)
if err != nil {
return nil, err
}
return &fe6{*a0, *a1, *a2}, nil
}
func (e *fe6) isOne() bool {
return e[0].isOne() && e[1].isZero() && e[2].isZero()
}
func (e *fe6) isZero() bool {
return e[0].isZero() && e[1].isZero() && e[2].isZero()
}
func (e *fe6) equal(e2 *fe6) bool {
return e[0].equal(&e2[0]) && e[1].equal(&e2[1]) && e[2].equal(&e2[2])
}
func (e *fe12) zero() *fe12 {
e[0].zero()
e[1].zero()
return e
}
func (e *fe12) one() *fe12 {
e[0].one()
e[1].zero()
return e
}
func (e *fe12) set(e2 *fe12) *fe12 {
e[0].set(&e2[0])
e[1].set(&e2[1])
return e
}
func (e *fe12) rand(r io.Reader) (*fe12, error) {
a0, err := new(fe6).rand(r)
if err != nil {
return nil, err
}
a1, err := new(fe6).rand(r)
if err != nil {
return nil, err
}
return &fe12{*a0, *a1}, nil
}
func (e *fe12) isOne() bool {
return e[0].isOne() && e[1].isZero()
}
func (e *fe12) isZero() bool {
return e[0].isZero() && e[1].isZero()
}
func (e *fe12) equal(e2 *fe12) bool {
return e[0].equal(&e2[0]) && e[1].equal(&e2[1])
}

183
vendor/github.com/kilic/bls12-381/fp.go generated vendored Normal file
View file

@ -0,0 +1,183 @@
package bls12381
import (
"errors"
"math/big"
)
func fromBytes(in []byte) (*fe, error) {
fe := &fe{}
if len(in) != 48 {
return nil, errors.New("input string should be equal 48 bytes")
}
fe.setBytes(in)
if !fe.isValid() {
return nil, errors.New("must be less than modulus")
}
toMont(fe, fe)
return fe, nil
}
func from64Bytes(in []byte) (*fe, error) {
if len(in) != 64 {
return nil, errors.New("input string should be equal 64 bytes")
}
a0 := make([]byte, 48)
copy(a0[16:48], in[:32])
a1 := make([]byte, 48)
copy(a1[16:48], in[32:])
e0, err := fromBytes(a0)
if err != nil {
return nil, err
}
e1, err := fromBytes(a1)
if err != nil {
return nil, err
}
// F = 2 ^ 256 * R
F := fe{
0x75b3cd7c5ce820f,
0x3ec6ba621c3edb0b,
0x168a13d82bff6bce,
0x87663c4bf8c449d2,
0x15f34c83ddc8d830,
0xf9628b49caa2e85,
}
mul(e0, e0, &F)
add(e1, e1, e0)
return e1, nil
}
func fromBig(in *big.Int) (*fe, error) {
fe := new(fe).setBig(in)
if !fe.isValid() {
return nil, errors.New("invalid input string")
}
toMont(fe, fe)
return fe, nil
}
func fromString(in string) (*fe, error) {
fe, err := new(fe).setString(in)
if err != nil {
return nil, err
}
if !fe.isValid() {
return nil, errors.New("invalid input string")
}
toMont(fe, fe)
return fe, nil
}
func toBytes(e *fe) []byte {
e2 := new(fe)
fromMont(e2, e)
return e2.bytes()
}
func toBig(e *fe) *big.Int {
e2 := new(fe)
fromMont(e2, e)
return e2.big()
}
func toString(e *fe) (s string) {
e2 := new(fe)
fromMont(e2, e)
return e2.string()
}
func toMont(c, a *fe) {
mul(c, a, r2)
}
func fromMont(c, a *fe) {
mul(c, a, &fe{1})
}
func exp(c, a *fe, e *big.Int) {
z := new(fe).set(r1)
for i := e.BitLen(); i >= 0; i-- {
mul(z, z, z)
if e.Bit(i) == 1 {
mul(z, z, a)
}
}
c.set(z)
}
func inverse(inv, e *fe) {
if e.isZero() {
inv.zero()
return
}
u := new(fe).set(&modulus)
v := new(fe).set(e)
s := &fe{1}
r := &fe{0}
var k int
var z uint64
var found = false
// Phase 1
for i := 0; i < 768; i++ {
if v.isZero() {
found = true
break
}
if u.isEven() {
u.div2(0)
s.mul2()
} else if v.isEven() {
v.div2(0)
z += r.mul2()
} else if u.cmp(v) == 1 {
lsubAssign(u, v)
u.div2(0)
laddAssign(r, s)
s.mul2()
} else {
lsubAssign(v, u)
v.div2(0)
laddAssign(s, r)
z += r.mul2()
}
k += 1
}
if !found {
inv.zero()
return
}
if k < 381 || k > 381+384 {
inv.zero()
return
}
if r.cmp(&modulus) != -1 || z > 0 {
lsubAssign(r, &modulus)
}
u.set(&modulus)
lsubAssign(u, r)
// Phase 2
for i := k; i < 384*2; i++ {
double(u, u)
}
inv.set(u)
return
}
func sqrt(c, a *fe) bool {
u, v := new(fe).set(a), new(fe)
exp(c, a, pPlus1Over4)
square(v, c)
return u.equal(v)
}
func isQuadraticNonResidue(elem *fe) bool {
result := new(fe)
exp(result, elem, pMinus1Over2)
return !result.isOne()
}

263
vendor/github.com/kilic/bls12-381/fp12.go generated vendored Normal file
View file

@ -0,0 +1,263 @@
package bls12381
import (
"errors"
"math/big"
)
type fp12 struct {
fp12temp
fp6 *fp6
}
type fp12temp struct {
t2 [9]*fe2
t6 [5]*fe6
t12 *fe12
}
func newFp12Temp() fp12temp {
t2 := [9]*fe2{}
t6 := [5]*fe6{}
for i := 0; i < len(t2); i++ {
t2[i] = &fe2{}
}
for i := 0; i < len(t6); i++ {
t6[i] = &fe6{}
}
return fp12temp{t2, t6, &fe12{}}
}
func newFp12(fp6 *fp6) *fp12 {
t := newFp12Temp()
if fp6 == nil {
return &fp12{t, newFp6(nil)}
}
return &fp12{t, fp6}
}
func (e *fp12) fp2() *fp2 {
return e.fp6.fp2
}
func (e *fp12) fromBytes(in []byte) (*fe12, error) {
if len(in) != 576 {
return nil, errors.New("input string should be larger than 96 bytes")
}
fp6 := e.fp6
c1, err := fp6.fromBytes(in[:288])
if err != nil {
return nil, err
}
c0, err := fp6.fromBytes(in[288:])
if err != nil {
return nil, err
}
return &fe12{*c0, *c1}, nil
}
func (e *fp12) toBytes(a *fe12) []byte {
fp6 := e.fp6
out := make([]byte, 576)
copy(out[:288], fp6.toBytes(&a[1]))
copy(out[288:], fp6.toBytes(&a[0]))
return out
}
func (e *fp12) new() *fe12 {
return new(fe12)
}
func (e *fp12) zero() *fe12 {
return new(fe12)
}
func (e *fp12) one() *fe12 {
return new(fe12).one()
}
func (e *fp12) add(c, a, b *fe12) {
fp6 := e.fp6
fp6.add(&c[0], &a[0], &b[0])
fp6.add(&c[1], &a[1], &b[1])
}
func (e *fp12) double(c, a *fe12) {
fp6 := e.fp6
fp6.double(&c[0], &a[0])
fp6.double(&c[1], &a[1])
}
func (e *fp12) sub(c, a, b *fe12) {
fp6 := e.fp6
fp6.sub(&c[0], &a[0], &b[0])
fp6.sub(&c[1], &a[1], &b[1])
}
func (e *fp12) neg(c, a *fe12) {
fp6 := e.fp6
fp6.neg(&c[0], &a[0])
fp6.neg(&c[1], &a[1])
}
func (e *fp12) conjugate(c, a *fe12) {
fp6 := e.fp6
c[0].set(&a[0])
fp6.neg(&c[1], &a[1])
}
func (e *fp12) square(c, a *fe12) {
fp6, t := e.fp6, e.t6
fp6.add(t[0], &a[0], &a[1])
fp6.mul(t[2], &a[0], &a[1])
fp6.mulByNonResidue(t[1], &a[1])
fp6.addAssign(t[1], &a[0])
fp6.mulByNonResidue(t[3], t[2])
fp6.mulAssign(t[0], t[1])
fp6.subAssign(t[0], t[2])
fp6.sub(&c[0], t[0], t[3])
fp6.double(&c[1], t[2])
}
func (e *fp12) cyclotomicSquare(c, a *fe12) {
t, fp2 := e.t2, e.fp2()
e.fp4Square(t[3], t[4], &a[0][0], &a[1][1])
fp2.sub(t[2], t[3], &a[0][0])
fp2.doubleAssign(t[2])
fp2.add(&c[0][0], t[2], t[3])
fp2.add(t[2], t[4], &a[1][1])
fp2.doubleAssign(t[2])
fp2.add(&c[1][1], t[2], t[4])
e.fp4Square(t[3], t[4], &a[1][0], &a[0][2])
e.fp4Square(t[5], t[6], &a[0][1], &a[1][2])
fp2.sub(t[2], t[3], &a[0][1])
fp2.doubleAssign(t[2])
fp2.add(&c[0][1], t[2], t[3])
fp2.add(t[2], t[4], &a[1][2])
fp2.doubleAssign(t[2])
fp2.add(&c[1][2], t[2], t[4])
fp2.mulByNonResidue(t[3], t[6])
fp2.add(t[2], t[3], &a[1][0])
fp2.doubleAssign(t[2])
fp2.add(&c[1][0], t[2], t[3])
fp2.sub(t[2], t[5], &a[0][2])
fp2.doubleAssign(t[2])
fp2.add(&c[0][2], t[2], t[5])
}
func (e *fp12) mul(c, a, b *fe12) {
t, fp6 := e.t6, e.fp6
fp6.mul(t[1], &a[0], &b[0])
fp6.mul(t[2], &a[1], &b[1])
fp6.add(t[0], t[1], t[2])
fp6.mulByNonResidue(t[2], t[2])
fp6.add(t[3], t[1], t[2])
fp6.add(t[1], &a[0], &a[1])
fp6.add(t[2], &b[0], &b[1])
fp6.mulAssign(t[1], t[2])
c[0].set(t[3])
fp6.sub(&c[1], t[1], t[0])
}
func (e *fp12) mulAssign(a, b *fe12) {
t, fp6 := e.t6, e.fp6
fp6.mul(t[1], &a[0], &b[0])
fp6.mul(t[2], &a[1], &b[1])
fp6.add(t[0], t[1], t[2])
fp6.mulByNonResidue(t[2], t[2])
fp6.add(t[3], t[1], t[2])
fp6.add(t[1], &a[0], &a[1])
fp6.add(t[2], &b[0], &b[1])
fp6.mulAssign(t[1], t[2])
a[0].set(t[3])
fp6.sub(&a[1], t[1], t[0])
}
func (e *fp12) fp4Square(c0, c1, a0, a1 *fe2) {
t, fp2 := e.t2, e.fp2()
fp2.square(t[0], a0)
fp2.square(t[1], a1)
fp2.mulByNonResidue(t[2], t[1])
fp2.add(c0, t[2], t[0])
fp2.add(t[2], a0, a1)
fp2.squareAssign(t[2])
fp2.subAssign(t[2], t[0])
fp2.sub(c1, t[2], t[1])
}
func (e *fp12) inverse(c, a *fe12) {
fp6, t := e.fp6, e.t6
fp6.square(t[0], &a[0])
fp6.square(t[1], &a[1])
fp6.mulByNonResidue(t[1], t[1])
fp6.sub(t[1], t[0], t[1])
fp6.inverse(t[0], t[1])
fp6.mul(&c[0], &a[0], t[0])
fp6.mulAssign(t[0], &a[1])
fp6.neg(&c[1], t[0])
}
func (e *fp12) mulBy014Assign(a *fe12, c0, c1, c4 *fe2) {
fp2, fp6, t, t2 := e.fp2(), e.fp6, e.t6, e.t2[0]
fp6.mulBy01(t[0], &a[0], c0, c1)
fp6.mulBy1(t[1], &a[1], c4)
fp2.add(t2, c1, c4)
fp6.add(t[2], &a[1], &a[0])
fp6.mulBy01Assign(t[2], c0, t2)
fp6.subAssign(t[2], t[0])
fp6.sub(&a[1], t[2], t[1])
fp6.mulByNonResidue(t[1], t[1])
fp6.add(&a[0], t[1], t[0])
}
func (e *fp12) exp(c, a *fe12, s *big.Int) {
z := e.one()
for i := s.BitLen() - 1; i >= 0; i-- {
e.square(z, z)
if s.Bit(i) == 1 {
e.mul(z, z, a)
}
}
c.set(z)
}
func (e *fp12) cyclotomicExp(c, a *fe12, s *big.Int) {
z := e.one()
for i := s.BitLen() - 1; i >= 0; i-- {
e.cyclotomicSquare(z, z)
if s.Bit(i) == 1 {
e.mul(z, z, a)
}
}
c.set(z)
}
func (e *fp12) frobeniusMap(c, a *fe12, power uint) {
fp6 := e.fp6
fp6.frobeniusMap(&c[0], &a[0], power)
fp6.frobeniusMap(&c[1], &a[1], power)
switch power {
case 0:
return
case 6:
fp6.neg(&c[1], &c[1])
default:
fp6.mulByBaseField(&c[1], &c[1], &frobeniusCoeffs12[power])
}
}
func (e *fp12) frobeniusMapAssign(a *fe12, power uint) {
fp6 := e.fp6
fp6.frobeniusMapAssign(&a[0], power)
fp6.frobeniusMapAssign(&a[1], power)
switch power {
case 0:
return
case 6:
fp6.neg(&a[1], &a[1])
default:
fp6.mulByBaseField(&a[1], &a[1], &frobeniusCoeffs12[power])
}
}

245
vendor/github.com/kilic/bls12-381/fp2.go generated vendored Normal file
View file

@ -0,0 +1,245 @@
package bls12381
import (
"errors"
"math/big"
)
type fp2Temp struct {
t [4]*fe
}
type fp2 struct {
fp2Temp
}
func newFp2Temp() fp2Temp {
t := [4]*fe{}
for i := 0; i < len(t); i++ {
t[i] = &fe{}
}
return fp2Temp{t}
}
func newFp2() *fp2 {
t := newFp2Temp()
return &fp2{t}
}
func (e *fp2) fromBytes(in []byte) (*fe2, error) {
if len(in) != 96 {
return nil, errors.New("input string should be larger than 96 bytes")
}
c1, err := fromBytes(in[:48])
if err != nil {
return nil, err
}
c0, err := fromBytes(in[48:])
if err != nil {
return nil, err
}
return &fe2{*c0, *c1}, nil
}
func (e *fp2) toBytes(a *fe2) []byte {
out := make([]byte, 96)
copy(out[:48], toBytes(&a[1]))
copy(out[48:], toBytes(&a[0]))
return out
}
func (e *fp2) new() *fe2 {
return new(fe2).zero()
}
func (e *fp2) zero() *fe2 {
return new(fe2).zero()
}
func (e *fp2) one() *fe2 {
return new(fe2).one()
}
func (e *fp2) fromMont(c, a *fe2) {
fromMont(&c[0], &a[0])
fromMont(&c[1], &a[1])
}
func (e *fp2) add(c, a, b *fe2) {
add(&c[0], &a[0], &b[0])
add(&c[1], &a[1], &b[1])
}
func (e *fp2) addAssign(a, b *fe2) {
addAssign(&a[0], &b[0])
addAssign(&a[1], &b[1])
}
func (e *fp2) ladd(c, a, b *fe2) {
ladd(&c[0], &a[0], &b[0])
ladd(&c[1], &a[1], &b[1])
}
func (e *fp2) double(c, a *fe2) {
double(&c[0], &a[0])
double(&c[1], &a[1])
}
func (e *fp2) doubleAssign(a *fe2) {
doubleAssign(&a[0])
doubleAssign(&a[1])
}
func (e *fp2) ldouble(c, a *fe2) {
ldouble(&c[0], &a[0])
ldouble(&c[1], &a[1])
}
func (e *fp2) sub(c, a, b *fe2) {
sub(&c[0], &a[0], &b[0])
sub(&c[1], &a[1], &b[1])
}
func (e *fp2) subAssign(c, a *fe2) {
subAssign(&c[0], &a[0])
subAssign(&c[1], &a[1])
}
func (e *fp2) neg(c, a *fe2) {
neg(&c[0], &a[0])
neg(&c[1], &a[1])
}
func (e *fp2) conjugate(c, a *fe2) {
c[0].set(&a[0])
neg(&c[1], &a[1])
}
func (e *fp2) mul(c, a, b *fe2) {
t := e.t
mul(t[1], &a[0], &b[0])
mul(t[2], &a[1], &b[1])
add(t[0], &a[0], &a[1])
add(t[3], &b[0], &b[1])
sub(&c[0], t[1], t[2])
addAssign(t[1], t[2])
mul(t[0], t[0], t[3])
sub(&c[1], t[0], t[1])
}
func (e *fp2) mulAssign(a, b *fe2) {
t := e.t
mul(t[1], &a[0], &b[0])
mul(t[2], &a[1], &b[1])
add(t[0], &a[0], &a[1])
add(t[3], &b[0], &b[1])
sub(&a[0], t[1], t[2])
addAssign(t[1], t[2])
mul(t[0], t[0], t[3])
sub(&a[1], t[0], t[1])
}
func (e *fp2) square(c, a *fe2) {
t := e.t
ladd(t[0], &a[0], &a[1])
sub(t[1], &a[0], &a[1])
ldouble(t[2], &a[0])
mul(&c[0], t[0], t[1])
mul(&c[1], t[2], &a[1])
}
func (e *fp2) squareAssign(a *fe2) {
t := e.t
ladd(t[0], &a[0], &a[1])
sub(t[1], &a[0], &a[1])
ldouble(t[2], &a[0])
mul(&a[0], t[0], t[1])
mul(&a[1], t[2], &a[1])
}
func (e *fp2) mulByNonResidue(c, a *fe2) {
t := e.t
sub(t[0], &a[0], &a[1])
add(&c[1], &a[0], &a[1])
c[0].set(t[0])
}
func (e *fp2) mulByB(c, a *fe2) {
t := e.t
double(t[0], &a[0])
double(t[1], &a[1])
doubleAssign(t[0])
doubleAssign(t[1])
sub(&c[0], t[0], t[1])
add(&c[1], t[0], t[1])
}
func (e *fp2) inverse(c, a *fe2) {
t := e.t
square(t[0], &a[0])
square(t[1], &a[1])
addAssign(t[0], t[1])
inverse(t[0], t[0])
mul(&c[0], &a[0], t[0])
mul(t[0], t[0], &a[1])
neg(&c[1], t[0])
}
func (e *fp2) mulByFq(c, a *fe2, b *fe) {
mul(&c[0], &a[0], b)
mul(&c[1], &a[1], b)
}
func (e *fp2) exp(c, a *fe2, s *big.Int) {
z := e.one()
for i := s.BitLen() - 1; i >= 0; i-- {
e.square(z, z)
if s.Bit(i) == 1 {
e.mul(z, z, a)
}
}
c.set(z)
}
func (e *fp2) frobeniousMap(c, a *fe2, power uint) {
c[0].set(&a[0])
if power%2 == 1 {
neg(&c[1], &a[1])
return
}
c[1].set(&a[1])
}
func (e *fp2) frobeniousMapAssign(a *fe2, power uint) {
if power%2 == 1 {
neg(&a[1], &a[1])
return
}
}
func (e *fp2) sqrt(c, a *fe2) bool {
u, x0, a1, alpha := &fe2{}, &fe2{}, &fe2{}, &fe2{}
u.set(a)
e.exp(a1, a, pMinus3Over4)
e.square(alpha, a1)
e.mul(alpha, alpha, a)
e.mul(x0, a1, a)
if alpha.equal(negativeOne2) {
neg(&c[0], &x0[1])
c[1].set(&x0[0])
return true
}
e.add(alpha, alpha, e.one())
e.exp(alpha, alpha, pMinus1Over2)
e.mul(c, alpha, x0)
e.square(alpha, c)
return alpha.equal(u)
}
func (e *fp2) isQuadraticNonResidue(a *fe2) bool {
c0, c1 := new(fe), new(fe)
square(c0, &a[0])
square(c1, &a[1])
add(c1, c1, c0)
return isQuadraticNonResidue(c1)
}

342
vendor/github.com/kilic/bls12-381/fp6.go generated vendored Normal file
View file

@ -0,0 +1,342 @@
package bls12381
import (
"errors"
"math/big"
)
type fp6Temp struct {
t [6]*fe2
}
type fp6 struct {
fp2 *fp2
fp6Temp
}
func newFp6Temp() fp6Temp {
t := [6]*fe2{}
for i := 0; i < len(t); i++ {
t[i] = &fe2{}
}
return fp6Temp{t}
}
func newFp6(f *fp2) *fp6 {
t := newFp6Temp()
if f == nil {
return &fp6{newFp2(), t}
}
return &fp6{f, t}
}
func (e *fp6) fromBytes(b []byte) (*fe6, error) {
if len(b) < 288 {
return nil, errors.New("input string should be larger than 288 bytes")
}
fp2 := e.fp2
u2, err := fp2.fromBytes(b[:96])
if err != nil {
return nil, err
}
u1, err := fp2.fromBytes(b[96:192])
if err != nil {
return nil, err
}
u0, err := fp2.fromBytes(b[192:])
if err != nil {
return nil, err
}
return &fe6{*u0, *u1, *u2}, nil
}
func (e *fp6) toBytes(a *fe6) []byte {
fp2 := e.fp2
out := make([]byte, 288)
copy(out[:96], fp2.toBytes(&a[2]))
copy(out[96:192], fp2.toBytes(&a[1]))
copy(out[192:], fp2.toBytes(&a[0]))
return out
}
func (e *fp6) new() *fe6 {
return new(fe6)
}
func (e *fp6) zero() *fe6 {
return new(fe6)
}
func (e *fp6) one() *fe6 {
return new(fe6).one()
}
func (e *fp6) add(c, a, b *fe6) {
fp2 := e.fp2
fp2.add(&c[0], &a[0], &b[0])
fp2.add(&c[1], &a[1], &b[1])
fp2.add(&c[2], &a[2], &b[2])
}
func (e *fp6) addAssign(a, b *fe6) {
fp2 := e.fp2
fp2.addAssign(&a[0], &b[0])
fp2.addAssign(&a[1], &b[1])
fp2.addAssign(&a[2], &b[2])
}
func (e *fp6) double(c, a *fe6) {
fp2 := e.fp2
fp2.double(&c[0], &a[0])
fp2.double(&c[1], &a[1])
fp2.double(&c[2], &a[2])
}
func (e *fp6) doubleAssign(a *fe6) {
fp2 := e.fp2
fp2.doubleAssign(&a[0])
fp2.doubleAssign(&a[1])
fp2.doubleAssign(&a[2])
}
func (e *fp6) sub(c, a, b *fe6) {
fp2 := e.fp2
fp2.sub(&c[0], &a[0], &b[0])
fp2.sub(&c[1], &a[1], &b[1])
fp2.sub(&c[2], &a[2], &b[2])
}
func (e *fp6) subAssign(a, b *fe6) {
fp2 := e.fp2
fp2.subAssign(&a[0], &b[0])
fp2.subAssign(&a[1], &b[1])
fp2.subAssign(&a[2], &b[2])
}
func (e *fp6) neg(c, a *fe6) {
fp2 := e.fp2
fp2.neg(&c[0], &a[0])
fp2.neg(&c[1], &a[1])
fp2.neg(&c[2], &a[2])
}
func (e *fp6) conjugate(c, a *fe6) {
fp2 := e.fp2
c[0].set(&a[0])
fp2.neg(&c[1], &a[1])
c[0].set(&a[2])
}
func (e *fp6) mul(c, a, b *fe6) {
fp2, t := e.fp2, e.t
fp2.mul(t[0], &a[0], &b[0])
fp2.mul(t[1], &a[1], &b[1])
fp2.mul(t[2], &a[2], &b[2])
fp2.add(t[3], &a[1], &a[2])
fp2.add(t[4], &b[1], &b[2])
fp2.mulAssign(t[3], t[4])
fp2.add(t[4], t[1], t[2])
fp2.subAssign(t[3], t[4])
fp2.mulByNonResidue(t[3], t[3])
fp2.add(t[5], t[0], t[3])
fp2.add(t[3], &a[0], &a[1])
fp2.add(t[4], &b[0], &b[1])
fp2.mulAssign(t[3], t[4])
fp2.add(t[4], t[0], t[1])
fp2.subAssign(t[3], t[4])
fp2.mulByNonResidue(t[4], t[2])
fp2.add(&c[1], t[3], t[4])
fp2.add(t[3], &a[0], &a[2])
fp2.add(t[4], &b[0], &b[2])
fp2.mulAssign(t[3], t[4])
fp2.add(t[4], t[0], t[2])
fp2.subAssign(t[3], t[4])
fp2.add(&c[2], t[1], t[3])
c[0].set(t[5])
}
func (e *fp6) mulAssign(a, b *fe6) {
fp2, t := e.fp2, e.t
fp2.mul(t[0], &a[0], &b[0])
fp2.mul(t[1], &a[1], &b[1])
fp2.mul(t[2], &a[2], &b[2])
fp2.add(t[3], &a[1], &a[2])
fp2.add(t[4], &b[1], &b[2])
fp2.mulAssign(t[3], t[4])
fp2.add(t[4], t[1], t[2])
fp2.subAssign(t[3], t[4])
fp2.mulByNonResidue(t[3], t[3])
fp2.add(t[5], t[0], t[3])
fp2.add(t[3], &a[0], &a[1])
fp2.add(t[4], &b[0], &b[1])
fp2.mulAssign(t[3], t[4])
fp2.add(t[4], t[0], t[1])
fp2.subAssign(t[3], t[4])
fp2.mulByNonResidue(t[4], t[2])
fp2.add(&a[1], t[3], t[4])
fp2.add(t[3], &a[0], &a[2])
fp2.add(t[4], &b[0], &b[2])
fp2.mulAssign(t[3], t[4])
fp2.add(t[4], t[0], t[2])
fp2.subAssign(t[3], t[4])
fp2.add(&a[2], t[1], t[3])
a[0].set(t[5])
}
func (e *fp6) square(c, a *fe6) {
fp2, t := e.fp2, e.t
fp2.square(t[0], &a[0])
fp2.mul(t[1], &a[0], &a[1])
fp2.doubleAssign(t[1])
fp2.sub(t[2], &a[0], &a[1])
fp2.addAssign(t[2], &a[2])
fp2.squareAssign(t[2])
fp2.mul(t[3], &a[1], &a[2])
fp2.doubleAssign(t[3])
fp2.square(t[4], &a[2])
fp2.mulByNonResidue(t[5], t[3])
fp2.add(&c[0], t[0], t[5])
fp2.mulByNonResidue(t[5], t[4])
fp2.add(&c[1], t[1], t[5])
fp2.addAssign(t[1], t[2])
fp2.addAssign(t[1], t[3])
fp2.addAssign(t[0], t[4])
fp2.sub(&c[2], t[1], t[0])
}
func (e *fp6) mulBy01Assign(a *fe6, b0, b1 *fe2) {
fp2, t := e.fp2, e.t
fp2.mul(t[0], &a[0], b0)
fp2.mul(t[1], &a[1], b1)
fp2.add(t[5], &a[1], &a[2])
fp2.mul(t[2], b1, t[5])
fp2.subAssign(t[2], t[1])
fp2.mulByNonResidue(t[2], t[2])
fp2.add(t[5], &a[0], &a[2])
fp2.mul(t[3], b0, t[5])
fp2.subAssign(t[3], t[0])
fp2.add(&a[2], t[3], t[1])
fp2.add(t[4], b0, b1)
fp2.add(t[5], &a[0], &a[1])
fp2.mulAssign(t[4], t[5])
fp2.subAssign(t[4], t[0])
fp2.sub(&a[1], t[4], t[1])
fp2.add(&a[0], t[2], t[0])
}
func (e *fp6) mulBy01(c, a *fe6, b0, b1 *fe2) {
fp2, t := e.fp2, e.t
fp2.mul(t[0], &a[0], b0)
fp2.mul(t[1], &a[1], b1)
fp2.add(t[2], &a[1], &a[2])
fp2.mulAssign(t[2], b1)
fp2.subAssign(t[2], t[1])
fp2.mulByNonResidue(t[2], t[2])
fp2.add(t[3], &a[0], &a[2])
fp2.mulAssign(t[3], b0)
fp2.subAssign(t[3], t[0])
fp2.add(&c[2], t[3], t[1])
fp2.add(t[4], b0, b1)
fp2.add(t[3], &a[0], &a[1])
fp2.mulAssign(t[4], t[3])
fp2.subAssign(t[4], t[0])
fp2.sub(&c[1], t[4], t[1])
fp2.add(&c[0], t[2], t[0])
}
func (e *fp6) mulBy1(c, a *fe6, b1 *fe2) {
fp2, t := e.fp2, e.t
fp2.mul(t[0], &a[2], b1)
fp2.mul(&c[2], &a[1], b1)
fp2.mul(&c[1], &a[0], b1)
fp2.mulByNonResidue(&c[0], t[0])
}
func (e *fp6) mulByNonResidue(c, a *fe6) {
fp2, t := e.fp2, e.t
t[0].set(&a[0])
fp2.mulByNonResidue(&c[0], &a[2])
c[2].set(&a[1])
c[1].set(t[0])
}
func (e *fp6) mulByBaseField(c, a *fe6, b *fe2) {
fp2 := e.fp2
fp2.mul(&c[0], &a[0], b)
fp2.mul(&c[1], &a[1], b)
fp2.mul(&c[2], &a[2], b)
}
func (e *fp6) exp(c, a *fe6, s *big.Int) {
z := e.one()
for i := s.BitLen() - 1; i >= 0; i-- {
e.square(z, z)
if s.Bit(i) == 1 {
e.mul(z, z, a)
}
}
c.set(z)
}
func (e *fp6) inverse(c, a *fe6) {
fp2, t := e.fp2, e.t
fp2.square(t[0], &a[0])
fp2.mul(t[1], &a[1], &a[2])
fp2.mulByNonResidue(t[1], t[1])
fp2.subAssign(t[0], t[1])
fp2.square(t[1], &a[1])
fp2.mul(t[2], &a[0], &a[2])
fp2.subAssign(t[1], t[2])
fp2.square(t[2], &a[2])
fp2.mulByNonResidue(t[2], t[2])
fp2.mul(t[3], &a[0], &a[1])
fp2.subAssign(t[2], t[3])
fp2.mul(t[3], &a[2], t[2])
fp2.mul(t[4], &a[1], t[1])
fp2.addAssign(t[3], t[4])
fp2.mulByNonResidue(t[3], t[3])
fp2.mul(t[4], &a[0], t[0])
fp2.addAssign(t[3], t[4])
fp2.inverse(t[3], t[3])
fp2.mul(&c[0], t[0], t[3])
fp2.mul(&c[1], t[2], t[3])
fp2.mul(&c[2], t[1], t[3])
}
func (e *fp6) frobeniusMap(c, a *fe6, power uint) {
fp2 := e.fp2
fp2.frobeniousMap(&c[0], &a[0], power)
fp2.frobeniousMap(&c[1], &a[1], power)
fp2.frobeniousMap(&c[2], &a[2], power)
switch power % 6 {
case 0:
return
case 3:
neg(&c[0][0], &a[1][1])
c[1][1].set(&a[1][0])
fp2.neg(&a[2], &a[2])
default:
fp2.mul(&c[1], &c[1], &frobeniusCoeffs61[power%6])
fp2.mul(&c[2], &c[2], &frobeniusCoeffs62[power%6])
}
}
func (e *fp6) frobeniusMapAssign(a *fe6, power uint) {
fp2 := e.fp2
fp2.frobeniousMapAssign(&a[0], power)
fp2.frobeniousMapAssign(&a[1], power)
fp2.frobeniousMapAssign(&a[2], power)
t := e.t
switch power % 6 {
case 0:
return
case 3:
neg(&t[0][0], &a[1][1])
a[1][1].set(&a[1][0])
a[1][0].set(&t[0][0])
fp2.neg(&a[2], &a[2])
default:
fp2.mulAssign(&a[1], &frobeniusCoeffs61[power%6])
fp2.mulAssign(&a[2], &frobeniusCoeffs62[power%6])
}
}

551
vendor/github.com/kilic/bls12-381/g1.go generated vendored Normal file
View file

@ -0,0 +1,551 @@
package bls12381
import (
"errors"
"math"
"math/big"
)
// PointG1 is type for point in G1.
// PointG1 is both used for Affine and Jacobian point representation.
// If z is equal to one the point is accounted as in affine form.
type PointG1 [3]fe
func (p *PointG1) Set(p2 *PointG1) *PointG1 {
p[0].set(&p2[0])
p[1].set(&p2[1])
p[2].set(&p2[2])
return p
}
func (p *PointG1) Zero() *PointG1 {
p[0].zero()
p[1].one()
p[2].zero()
return p
}
type tempG1 struct {
t [9]*fe
}
// G1 is struct for G1 group.
type G1 struct {
tempG1
}
// NewG1 constructs a new G1 instance.
func NewG1() *G1 {
t := newTempG1()
return &G1{t}
}
func newTempG1() tempG1 {
t := [9]*fe{}
for i := 0; i < 9; i++ {
t[i] = &fe{}
}
return tempG1{t}
}
// Q returns group order in big.Int.
func (g *G1) Q() *big.Int {
return new(big.Int).Set(q)
}
// FromUncompressed expects byte slice larger than 96 bytes and given bytes returns a new point in G1.
// Serialization rules are in line with zcash library. See below for details.
// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization
// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html
func (g *G1) FromUncompressed(uncompressed []byte) (*PointG1, error) {
if len(uncompressed) < 96 {
return nil, errors.New("input string should be equal or larger than 96")
}
var in [96]byte
copy(in[:], uncompressed[:96])
if in[0]&(1<<7) != 0 {
return nil, errors.New("input string should be equal or larger than 96")
}
if in[0]&(1<<5) != 0 {
return nil, errors.New("input string should be equal or larger than 96")
}
if in[0]&(1<<6) != 0 {
for i, v := range in {
if (i == 0 && v != 0x40) || (i != 0 && v != 0x00) {
return nil, errors.New("input string should be equal or larger than 96")
}
}
return g.Zero(), nil
}
in[0] &= 0x1f
x, err := fromBytes(in[:48])
if err != nil {
return nil, err
}
y, err := fromBytes(in[48:])
if err != nil {
return nil, err
}
z := new(fe).one()
p := &PointG1{*x, *y, *z}
if !g.IsOnCurve(p) {
return nil, errors.New("input string should be equal or larger than 96")
}
if !g.InCorrectSubgroup(p) {
return nil, errors.New("input string should be equal or larger than 96")
}
return p, nil
}
// ToUncompressed given a G1 point returns bytes in uncompressed (x, y) form of the point.
// Serialization rules are in line with zcash library. See below for details.
// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization
// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html
func (g *G1) ToUncompressed(p *PointG1) []byte {
out := make([]byte, 96)
if g.IsZero(p) {
out[0] |= 1 << 6
return out
}
g.Affine(p)
copy(out[:48], toBytes(&p[0]))
copy(out[48:], toBytes(&p[1]))
return out
}
// FromCompressed expects byte slice larger than 96 bytes and given bytes returns a new point in G1.
// Serialization rules are in line with zcash library. See below for details.
// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization
// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html
func (g *G1) FromCompressed(compressed []byte) (*PointG1, error) {
if len(compressed) < 48 {
return nil, errors.New("input string should be equal or larger than 48")
}
var in [48]byte
copy(in[:], compressed[:])
if in[0]&(1<<7) == 0 {
return nil, errors.New("compression flag should be set")
}
if in[0]&(1<<6) != 0 {
// in[0] == (1 << 6) + (1 << 7)
for i, v := range in {
if (i == 0 && v != 0xc0) || (i != 0 && v != 0x00) {
return nil, errors.New("input string should be zero when infinity flag is set")
}
}
return g.Zero(), nil
}
a := in[0]&(1<<5) != 0
in[0] &= 0x1f
x, err := fromBytes(in[:])
if err != nil {
return nil, err
}
// solve curve equation
y := &fe{}
square(y, x)
mul(y, y, x)
add(y, y, b)
if ok := sqrt(y, y); !ok {
return nil, errors.New("point is not on curve")
}
if y.signBE() == a {
neg(y, y)
}
z := new(fe).one()
p := &PointG1{*x, *y, *z}
if !g.InCorrectSubgroup(p) {
return nil, errors.New("point is not on correct subgroup")
}
return p, nil
}
// ToCompressed given a G1 point returns bytes in compressed form of the point.
// Serialization rules are in line with zcash library. See below for details.
// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization
// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html
func (g *G1) ToCompressed(p *PointG1) []byte {
out := make([]byte, 48)
g.Affine(p)
if g.IsZero(p) {
out[0] |= 1 << 6
} else {
copy(out[:], toBytes(&p[0]))
if !p[1].signBE() {
out[0] |= 1 << 5
}
}
out[0] |= 1 << 7
return out
}
func (g *G1) fromBytesUnchecked(in []byte) (*PointG1, error) {
p0, err := fromBytes(in[:48])
if err != nil {
return nil, err
}
p1, err := fromBytes(in[48:])
if err != nil {
return nil, err
}
p2 := new(fe).one()
return &PointG1{*p0, *p1, *p2}, nil
}
// FromBytes constructs a new point given uncompressed byte input.
// FromBytes does not take zcash flags into account.
// Byte input expected to be larger than 96 bytes.
// First 96 bytes should be concatenation of x and y values.
// Point (0, 0) is considered as infinity.
func (g *G1) FromBytes(in []byte) (*PointG1, error) {
if len(in) < 96 {
return nil, errors.New("input string should be equal or larger than 96")
}
p0, err := fromBytes(in[:48])
if err != nil {
return nil, err
}
p1, err := fromBytes(in[48:])
if err != nil {
return nil, err
}
// check if given input points to infinity
if p0.isZero() && p1.isZero() {
return g.Zero(), nil
}
p2 := new(fe).one()
p := &PointG1{*p0, *p1, *p2}
if !g.IsOnCurve(p) {
return nil, errors.New("point is not on curve")
}
return p, nil
}
// ToBytes serializes a point into bytes in uncompressed form.
// ToBytes does not take zcash flags into account.
// ToBytes returns (0, 0) if point is infinity.
func (g *G1) ToBytes(p *PointG1) []byte {
out := make([]byte, 96)
if g.IsZero(p) {
return out
}
g.Affine(p)
copy(out[:48], toBytes(&p[0]))
copy(out[48:], toBytes(&p[1]))
return out
}
// New creates a new G1 Point which is equal to zero in other words point at infinity.
func (g *G1) New() *PointG1 {
return g.Zero()
}
// Zero returns a new G1 Point which is equal to point at infinity.
func (g *G1) Zero() *PointG1 {
return new(PointG1).Zero()
}
// One returns a new G1 Point which is equal to generator point.
func (g *G1) One() *PointG1 {
p := &PointG1{}
return p.Set(&g1One)
}
// IsZero returns true if given point is equal to zero.
func (g *G1) IsZero(p *PointG1) bool {
return p[2].isZero()
}
// Equal checks if given two G1 point is equal in their affine form.
func (g *G1) Equal(p1, p2 *PointG1) bool {
if g.IsZero(p1) {
return g.IsZero(p2)
}
if g.IsZero(p2) {
return g.IsZero(p1)
}
t := g.t
square(t[0], &p1[2])
square(t[1], &p2[2])
mul(t[2], t[0], &p2[0])
mul(t[3], t[1], &p1[0])
mul(t[0], t[0], &p1[2])
mul(t[1], t[1], &p2[2])
mul(t[1], t[1], &p1[1])
mul(t[0], t[0], &p2[1])
return t[0].equal(t[1]) && t[2].equal(t[3])
}
// InCorrectSubgroup checks whether given point is in correct subgroup.
func (g *G1) InCorrectSubgroup(p *PointG1) bool {
tmp := &PointG1{}
g.MulScalar(tmp, p, q)
return g.IsZero(tmp)
}
// IsOnCurve checks a G1 point is on curve.
func (g *G1) IsOnCurve(p *PointG1) bool {
if g.IsZero(p) {
return true
}
t := g.t
square(t[0], &p[1])
square(t[1], &p[0])
mul(t[1], t[1], &p[0])
square(t[2], &p[2])
square(t[3], t[2])
mul(t[2], t[2], t[3])
mul(t[2], b, t[2])
add(t[1], t[1], t[2])
return t[0].equal(t[1])
}
// IsAffine checks a G1 point whether it is in affine form.
func (g *G1) IsAffine(p *PointG1) bool {
return p[2].isOne()
}
// Add adds two G1 points p1, p2 and assigns the result to point at first argument.
func (g *G1) Affine(p *PointG1) *PointG1 {
if g.IsZero(p) {
return p
}
if !g.IsAffine(p) {
t := g.t
inverse(t[0], &p[2])
square(t[1], t[0])
mul(&p[0], &p[0], t[1])
mul(t[0], t[0], t[1])
mul(&p[1], &p[1], t[0])
p[2].one()
}
return p
}
// Add adds two G1 points p1, p2 and assigns the result to point at first argument.
func (g *G1) Add(r, p1, p2 *PointG1) *PointG1 {
// http://www.hyperelliptic.org/EFD/gp/auto-shortw-jacobian-0.html#addition-add-2007-bl
if g.IsZero(p1) {
return r.Set(p2)
}
if g.IsZero(p2) {
return r.Set(p1)
}
t := g.t
square(t[7], &p1[2])
mul(t[1], &p2[0], t[7])
mul(t[2], &p1[2], t[7])
mul(t[0], &p2[1], t[2])
square(t[8], &p2[2])
mul(t[3], &p1[0], t[8])
mul(t[4], &p2[2], t[8])
mul(t[2], &p1[1], t[4])
if t[1].equal(t[3]) {
if t[0].equal(t[2]) {
return g.Double(r, p1)
} else {
return r.Zero()
}
}
sub(t[1], t[1], t[3])
double(t[4], t[1])
square(t[4], t[4])
mul(t[5], t[1], t[4])
sub(t[0], t[0], t[2])
double(t[0], t[0])
square(t[6], t[0])
sub(t[6], t[6], t[5])
mul(t[3], t[3], t[4])
double(t[4], t[3])
sub(&r[0], t[6], t[4])
sub(t[4], t[3], &r[0])
mul(t[6], t[2], t[5])
double(t[6], t[6])
mul(t[0], t[0], t[4])
sub(&r[1], t[0], t[6])
add(t[0], &p1[2], &p2[2])
square(t[0], t[0])
sub(t[0], t[0], t[7])
sub(t[0], t[0], t[8])
mul(&r[2], t[0], t[1])
return r
}
// Double doubles a G1 point p and assigns the result to the point at first argument.
func (g *G1) Double(r, p *PointG1) *PointG1 {
// http://www.hyperelliptic.org/EFD/gp/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
if g.IsZero(p) {
return r.Set(p)
}
t := g.t
square(t[0], &p[0])
square(t[1], &p[1])
square(t[2], t[1])
add(t[1], &p[0], t[1])
square(t[1], t[1])
sub(t[1], t[1], t[0])
sub(t[1], t[1], t[2])
double(t[1], t[1])
double(t[3], t[0])
add(t[0], t[3], t[0])
square(t[4], t[0])
double(t[3], t[1])
sub(&r[0], t[4], t[3])
sub(t[1], t[1], &r[0])
double(t[2], t[2])
double(t[2], t[2])
double(t[2], t[2])
mul(t[0], t[0], t[1])
sub(t[1], t[0], t[2])
mul(t[0], &p[1], &p[2])
r[1].set(t[1])
double(&r[2], t[0])
return r
}
// Neg negates a G1 point p and assigns the result to the point at first argument.
func (g *G1) Neg(r, p *PointG1) *PointG1 {
r[0].set(&p[0])
r[2].set(&p[2])
neg(&r[1], &p[1])
return r
}
// Sub subtracts two G1 points p1, p2 and assigns the result to point at first argument.
func (g *G1) Sub(c, a, b *PointG1) *PointG1 {
d := &PointG1{}
g.Neg(d, b)
g.Add(c, a, d)
return c
}
// MulScalar multiplies a point by given scalar value in big.Int and assigns the result to point at first argument.
func (g *G1) MulScalar(c, p *PointG1, e *big.Int) *PointG1 {
q, n := &PointG1{}, &PointG1{}
n.Set(p)
l := e.BitLen()
for i := 0; i < l; i++ {
if e.Bit(i) == 1 {
g.Add(q, q, n)
}
g.Double(n, n)
}
return c.Set(q)
}
// ClearCofactor maps given a G1 point to correct subgroup
func (g *G1) ClearCofactor(p *PointG1) {
g.MulScalar(p, p, cofactorEFFG1)
}
// MultiExp calculates multi exponentiation. Given pairs of G1 point and scalar values
// (P_0, e_0), (P_1, e_1), ... (P_n, e_n) calculates r = e_0 * P_0 + e_1 * P_1 + ... + e_n * P_n
// Length of points and scalars are expected to be equal, otherwise an error is returned.
// Result is assigned to point at first argument.
func (g *G1) MultiExp(r *PointG1, points []*PointG1, powers []*big.Int) (*PointG1, error) {
if len(points) != len(powers) {
return nil, errors.New("point and scalar vectors should be in same length")
}
var c uint32 = 3
if len(powers) >= 32 {
c = uint32(math.Ceil(math.Log10(float64(len(powers)))))
}
bucketSize, numBits := (1<<c)-1, uint32(g.Q().BitLen())
windows := make([]*PointG1, numBits/c+1)
bucket := make([]*PointG1, bucketSize)
acc, sum := g.New(), g.New()
for i := 0; i < bucketSize; i++ {
bucket[i] = g.New()
}
mask := (uint64(1) << c) - 1
j := 0
var cur uint32
for cur <= numBits {
acc.Zero()
bucket = make([]*PointG1, (1<<c)-1)
for i := 0; i < len(bucket); i++ {
bucket[i] = g.New()
}
for i := 0; i < len(powers); i++ {
s0 := powers[i].Uint64()
index := uint(s0 & mask)
if index != 0 {
g.Add(bucket[index-1], bucket[index-1], points[i])
}
powers[i] = new(big.Int).Rsh(powers[i], uint(c))
}
sum.Zero()
for i := len(bucket) - 1; i >= 0; i-- {
g.Add(sum, sum, bucket[i])
g.Add(acc, acc, sum)
}
windows[j] = g.New()
windows[j].Set(acc)
j++
cur += c
}
acc.Zero()
for i := len(windows) - 1; i >= 0; i-- {
for j := uint32(0); j < c; j++ {
g.Double(acc, acc)
}
g.Add(acc, acc, windows[i])
}
return r.Set(acc), nil
}
// MapToCurve given a byte slice returns a valid G1 point.
// This mapping function implements the Simplified Shallue-van de Woestijne-Ulas method.
// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06
// Input byte slice should be a valid field element, otherwise an error is returned.
func (g *G1) MapToCurve(in []byte) (*PointG1, error) {
u, err := fromBytes(in)
if err != nil {
return nil, err
}
x, y := swuMapG1(u)
isogenyMapG1(x, y)
one := new(fe).one()
p := &PointG1{*x, *y, *one}
g.ClearCofactor(p)
return g.Affine(p), nil
}
// EncodeToCurve given a message and domain seperator tag returns the hash result
// which is a valid curve point.
// Implementation follows BLS12381G1_XMD:SHA-256_SSWU_NU_ suite at
// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06
func (g *G1) EncodeToCurve(msg, domain []byte) (*PointG1, error) {
hashRes, err := hashToFpXMDSHA256(msg, domain, 1)
if err != nil {
return nil, err
}
u := hashRes[0]
x, y := swuMapG1(u)
isogenyMapG1(x, y)
one := new(fe).one()
p := &PointG1{*x, *y, *one}
g.ClearCofactor(p)
return g.Affine(p), nil
}
// HashToCurve given a message and domain seperator tag returns the hash result
// which is a valid curve point.
// Implementation follows BLS12381G1_XMD:SHA-256_SSWU_RO_ suite at
// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06
func (g *G1) HashToCurve(msg, domain []byte) (*PointG1, error) {
hashRes, err := hashToFpXMDSHA256(msg, domain, 2)
if err != nil {
return nil, err
}
u0, u1 := hashRes[0], hashRes[1]
x0, y0 := swuMapG1(u0)
x1, y1 := swuMapG1(u1)
one := new(fe).one()
p0, p1 := &PointG1{*x0, *y0, *one}, &PointG1{*x1, *y1, *one}
g.Add(p0, p0, p1)
g.Affine(p0)
isogenyMapG1(&p0[0], &p0[1])
g.ClearCofactor(p0)
return g.Affine(p0), nil
}

604
vendor/github.com/kilic/bls12-381/g2.go generated vendored Normal file
View file

@ -0,0 +1,604 @@
package bls12381
import (
"errors"
"math"
"math/big"
)
// PointG2 is type for point in G2.
// PointG2 is both used for Affine and Jacobian point representation.
// If z is equal to one the point is accounted as in affine form.
type PointG2 [3]fe2
// Set copies valeus of one point to another.
func (p *PointG2) Set(p2 *PointG2) *PointG2 {
p[0].set(&p2[0])
p[1].set(&p2[1])
p[2].set(&p2[2])
return p
}
func (p *PointG2) Zero() *PointG2 {
p[0].zero()
p[1].one()
p[2].zero()
return p
}
type tempG2 struct {
t [9]*fe2
}
// G2 is struct for G2 group.
type G2 struct {
f *fp2
tempG2
}
// NewG2 constructs a new G2 instance.
func NewG2() *G2 {
return newG2(nil)
}
func newG2(f *fp2) *G2 {
if f == nil {
f = newFp2()
}
t := newTempG2()
return &G2{f, t}
}
func newTempG2() tempG2 {
t := [9]*fe2{}
for i := 0; i < 9; i++ {
t[i] = &fe2{}
}
return tempG2{t}
}
// Q returns group order in big.Int.
func (g *G2) Q() *big.Int {
return new(big.Int).Set(q)
}
// FromUncompressed expects byte slice larger than 192 bytes and given bytes returns a new point in G2.
// Serialization rules are in line with zcash library. See below for details.
// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization
// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html
func (g *G2) FromUncompressed(uncompressed []byte) (*PointG2, error) {
if len(uncompressed) < 192 {
return nil, errors.New("input string should be equal or larger than 192")
}
var in [192]byte
copy(in[:], uncompressed[:192])
if in[0]&(1<<7) != 0 {
return nil, errors.New("compression flag should be zero")
}
if in[0]&(1<<5) != 0 {
return nil, errors.New("sort flag should be zero")
}
if in[0]&(1<<6) != 0 {
for i, v := range in {
if (i == 0 && v != 0x40) || (i != 0 && v != 0x00) {
return nil, errors.New("input string should be zero when infinity flag is set")
}
}
return g.Zero(), nil
}
in[0] &= 0x1f
x, err := g.f.fromBytes(in[:96])
if err != nil {
return nil, err
}
y, err := g.f.fromBytes(in[96:])
if err != nil {
return nil, err
}
z := new(fe2).one()
p := &PointG2{*x, *y, *z}
if !g.IsOnCurve(p) {
return nil, errors.New("point is not on curve")
}
if !g.InCorrectSubgroup(p) {
return nil, errors.New("point is not on correct subgroup")
}
return p, nil
}
// ToUncompressed given a G2 point returns bytes in uncompressed (x, y) form of the point.
// Serialization rules are in line with zcash library. See below for details.
// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization
// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html
func (g *G2) ToUncompressed(p *PointG2) []byte {
out := make([]byte, 192)
g.Affine(p)
if g.IsZero(p) {
out[0] |= 1 << 6
return out
}
copy(out[:96], g.f.toBytes(&p[0]))
copy(out[96:], g.f.toBytes(&p[1]))
return out
}
// FromCompressed expects byte slice larger than 96 bytes and given bytes returns a new point in G2.
// Serialization rules are in line with zcash library. See below for details.
// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization
// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html
func (g *G2) FromCompressed(compressed []byte) (*PointG2, error) {
if len(compressed) < 96 {
return nil, errors.New("input string should be equal or larger than 96")
}
var in [96]byte
copy(in[:], compressed[:])
if in[0]&(1<<7) == 0 {
return nil, errors.New("bad compression")
}
if in[0]&(1<<6) != 0 {
// in[0] == (1 << 6) + (1 << 7)
for i, v := range in {
if (i == 0 && v != 0xc0) || (i != 0 && v != 0x00) {
return nil, errors.New("input string should be zero when infinity flag is set")
}
}
return g.Zero(), nil
}
a := in[0]&(1<<5) != 0
in[0] &= 0x1f
x, err := g.f.fromBytes(in[:])
if err != nil {
return nil, err
}
// solve curve equation
y := &fe2{}
g.f.square(y, x)
g.f.mul(y, y, x)
g.f.add(y, y, b2)
if ok := g.f.sqrt(y, y); !ok {
return nil, errors.New("point is not on curve")
}
if y.signBE() == a {
g.f.neg(y, y)
}
z := new(fe2).one()
p := &PointG2{*x, *y, *z}
if !g.InCorrectSubgroup(p) {
return nil, errors.New("point is not on correct subgroup")
}
return p, nil
}
// ToCompressed given a G2 point returns bytes in compressed form of the point.
// Serialization rules are in line with zcash library. See below for details.
// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization
// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html
func (g *G2) ToCompressed(p *PointG2) []byte {
out := make([]byte, 96)
g.Affine(p)
if g.IsZero(p) {
out[0] |= 1 << 6
} else {
copy(out[:], g.f.toBytes(&p[0]))
if !p[1].signBE() {
out[0] |= 1 << 5
}
}
out[0] |= 1 << 7
return out
}
func (g *G2) fromBytesUnchecked(in []byte) (*PointG2, error) {
p0, err := g.f.fromBytes(in[:96])
if err != nil {
return nil, err
}
p1, err := g.f.fromBytes(in[96:])
if err != nil {
return nil, err
}
p2 := new(fe2).one()
return &PointG2{*p0, *p1, *p2}, nil
}
// FromBytes constructs a new point given uncompressed byte input.
// FromBytes does not take zcash flags into account.
// Byte input expected to be larger than 96 bytes.
// First 192 bytes should be concatenation of x and y values
// Point (0, 0) is considered as infinity.
func (g *G2) FromBytes(in []byte) (*PointG2, error) {
if len(in) < 192 {
return nil, errors.New("input string should be equal or larger than 192")
}
p0, err := g.f.fromBytes(in[:96])
if err != nil {
return nil, err
}
p1, err := g.f.fromBytes(in[96:])
if err != nil {
return nil, err
}
// check if given input points to infinity
if p0.isZero() && p1.isZero() {
return g.Zero(), nil
}
p2 := new(fe2).one()
p := &PointG2{*p0, *p1, *p2}
if !g.IsOnCurve(p) {
return nil, errors.New("point is not on curve")
}
return p, nil
}
// ToBytes serializes a point into bytes in uncompressed form,
// does not take zcash flags into account,
// returns (0, 0) if point is infinity.
func (g *G2) ToBytes(p *PointG2) []byte {
out := make([]byte, 192)
if g.IsZero(p) {
return out
}
g.Affine(p)
copy(out[:96], g.f.toBytes(&p[0]))
copy(out[96:], g.f.toBytes(&p[1]))
return out
}
// New creates a new G2 Point which is equal to zero in other words point at infinity.
func (g *G2) New() *PointG2 {
return new(PointG2).Zero()
}
// Zero returns a new G2 Point which is equal to point at infinity.
func (g *G2) Zero() *PointG2 {
return new(PointG2).Zero()
}
// One returns a new G2 Point which is equal to generator point.
func (g *G2) One() *PointG2 {
p := &PointG2{}
return p.Set(&g2One)
}
// IsZero returns true if given point is equal to zero.
func (g *G2) IsZero(p *PointG2) bool {
return p[2].isZero()
}
// Equal checks if given two G2 point is equal in their affine form.
func (g *G2) Equal(p1, p2 *PointG2) bool {
if g.IsZero(p1) {
return g.IsZero(p2)
}
if g.IsZero(p2) {
return g.IsZero(p1)
}
t := g.t
g.f.square(t[0], &p1[2])
g.f.square(t[1], &p2[2])
g.f.mul(t[2], t[0], &p2[0])
g.f.mul(t[3], t[1], &p1[0])
g.f.mul(t[0], t[0], &p1[2])
g.f.mul(t[1], t[1], &p2[2])
g.f.mul(t[1], t[1], &p1[1])
g.f.mul(t[0], t[0], &p2[1])
return t[0].equal(t[1]) && t[2].equal(t[3])
}
// InCorrectSubgroup checks whether given point is in correct subgroup.
func (g *G2) InCorrectSubgroup(p *PointG2) bool {
tmp := &PointG2{}
g.MulScalar(tmp, p, q)
return g.IsZero(tmp)
}
// IsOnCurve checks a G2 point is on curve.
func (g *G2) IsOnCurve(p *PointG2) bool {
if g.IsZero(p) {
return true
}
t := g.t
g.f.square(t[0], &p[1])
g.f.square(t[1], &p[0])
g.f.mul(t[1], t[1], &p[0])
g.f.square(t[2], &p[2])
g.f.square(t[3], t[2])
g.f.mul(t[2], t[2], t[3])
g.f.mul(t[2], b2, t[2])
g.f.add(t[1], t[1], t[2])
return t[0].equal(t[1])
}
// IsAffine checks a G2 point whether it is in affine form.
func (g *G2) IsAffine(p *PointG2) bool {
return p[2].isOne()
}
// Affine calculates affine form of given G2 point.
func (g *G2) Affine(p *PointG2) *PointG2 {
if g.IsZero(p) {
return p
}
if !g.IsAffine(p) {
t := g.t
g.f.inverse(t[0], &p[2])
g.f.square(t[1], t[0])
g.f.mul(&p[0], &p[0], t[1])
g.f.mul(t[0], t[0], t[1])
g.f.mul(&p[1], &p[1], t[0])
p[2].one()
}
return p
}
// Add adds two G2 points p1, p2 and assigns the result to point at first argument.
func (g *G2) Add(r, p1, p2 *PointG2) *PointG2 {
// http://www.hyperelliptic.org/EFD/gp/auto-shortw-jacobian-0.html#addition-add-2007-bl
if g.IsZero(p1) {
return r.Set(p2)
}
if g.IsZero(p2) {
return r.Set(p1)
}
t := g.t
g.f.square(t[7], &p1[2])
g.f.mul(t[1], &p2[0], t[7])
g.f.mul(t[2], &p1[2], t[7])
g.f.mul(t[0], &p2[1], t[2])
g.f.square(t[8], &p2[2])
g.f.mul(t[3], &p1[0], t[8])
g.f.mul(t[4], &p2[2], t[8])
g.f.mul(t[2], &p1[1], t[4])
if t[1].equal(t[3]) {
if t[0].equal(t[2]) {
return g.Double(r, p1)
} else {
return r.Zero()
}
}
g.f.sub(t[1], t[1], t[3])
g.f.double(t[4], t[1])
g.f.square(t[4], t[4])
g.f.mul(t[5], t[1], t[4])
g.f.sub(t[0], t[0], t[2])
g.f.double(t[0], t[0])
g.f.square(t[6], t[0])
g.f.sub(t[6], t[6], t[5])
g.f.mul(t[3], t[3], t[4])
g.f.double(t[4], t[3])
g.f.sub(&r[0], t[6], t[4])
g.f.sub(t[4], t[3], &r[0])
g.f.mul(t[6], t[2], t[5])
g.f.double(t[6], t[6])
g.f.mul(t[0], t[0], t[4])
g.f.sub(&r[1], t[0], t[6])
g.f.add(t[0], &p1[2], &p2[2])
g.f.square(t[0], t[0])
g.f.sub(t[0], t[0], t[7])
g.f.sub(t[0], t[0], t[8])
g.f.mul(&r[2], t[0], t[1])
return r
}
// Double doubles a G2 point p and assigns the result to the point at first argument.
func (g *G2) Double(r, p *PointG2) *PointG2 {
// http://www.hyperelliptic.org/EFD/gp/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
if g.IsZero(p) {
return r.Set(p)
}
t := g.t
g.f.square(t[0], &p[0])
g.f.square(t[1], &p[1])
g.f.square(t[2], t[1])
g.f.add(t[1], &p[0], t[1])
g.f.square(t[1], t[1])
g.f.sub(t[1], t[1], t[0])
g.f.sub(t[1], t[1], t[2])
g.f.double(t[1], t[1])
g.f.double(t[3], t[0])
g.f.add(t[0], t[3], t[0])
g.f.square(t[4], t[0])
g.f.double(t[3], t[1])
g.f.sub(&r[0], t[4], t[3])
g.f.sub(t[1], t[1], &r[0])
g.f.double(t[2], t[2])
g.f.double(t[2], t[2])
g.f.double(t[2], t[2])
g.f.mul(t[0], t[0], t[1])
g.f.sub(t[1], t[0], t[2])
g.f.mul(t[0], &p[1], &p[2])
r[1].set(t[1])
g.f.double(&r[2], t[0])
return r
}
// Neg negates a G2 point p and assigns the result to the point at first argument.
func (g *G2) Neg(r, p *PointG2) *PointG2 {
r[0].set(&p[0])
g.f.neg(&r[1], &p[1])
r[2].set(&p[2])
return r
}
// Sub subtracts two G2 points p1, p2 and assigns the result to point at first argument.
func (g *G2) Sub(c, a, b *PointG2) *PointG2 {
d := &PointG2{}
g.Neg(d, b)
g.Add(c, a, d)
return c
}
// MulScalar multiplies a point by given scalar value in big.Int and assigns the result to point at first argument.
func (g *G2) MulScalar(c, p *PointG2, e *big.Int) *PointG2 {
q, n := &PointG2{}, &PointG2{}
n.Set(p)
l := e.BitLen()
for i := 0; i < l; i++ {
if e.Bit(i) == 1 {
g.Add(q, q, n)
}
g.Double(n, n)
}
return c.Set(q)
}
// ClearCofactor maps given a G2 point to correct subgroup
func (g *G2) ClearCofactor(p *PointG2) *PointG2 {
return g.wnafMul(p, p, cofactorEFFG2)
}
// MultiExp calculates multi exponentiation. Given pairs of G2 point and scalar values
// (P_0, e_0), (P_1, e_1), ... (P_n, e_n) calculates r = e_0 * P_0 + e_1 * P_1 + ... + e_n * P_n
// Length of points and scalars are expected to be equal, otherwise an error is returned.
// Result is assigned to point at first argument.
func (g *G2) MultiExp(r *PointG2, points []*PointG2, powers []*big.Int) (*PointG2, error) {
if len(points) != len(powers) {
return nil, errors.New("point and scalar vectors should be in same length")
}
var c uint32 = 3
if len(powers) >= 32 {
c = uint32(math.Ceil(math.Log10(float64(len(powers)))))
}
bucketSize, numBits := (1<<c)-1, uint32(g.Q().BitLen())
windows := make([]*PointG2, numBits/c+1)
bucket := make([]*PointG2, bucketSize)
acc, sum := g.New(), g.New()
for i := 0; i < bucketSize; i++ {
bucket[i] = g.New()
}
mask := (uint64(1) << c) - 1
j := 0
var cur uint32
for cur <= numBits {
acc.Zero()
bucket = make([]*PointG2, (1<<c)-1)
for i := 0; i < len(bucket); i++ {
bucket[i] = g.New()
}
for i := 0; i < len(powers); i++ {
s0 := powers[i].Uint64()
index := uint(s0 & mask)
if index != 0 {
g.Add(bucket[index-1], bucket[index-1], points[i])
}
powers[i] = new(big.Int).Rsh(powers[i], uint(c))
}
sum.Zero()
for i := len(bucket) - 1; i >= 0; i-- {
g.Add(sum, sum, bucket[i])
g.Add(acc, acc, sum)
}
windows[j] = g.New()
windows[j].Set(acc)
j++
cur += c
}
acc.Zero()
for i := len(windows) - 1; i >= 0; i-- {
for j := uint32(0); j < c; j++ {
g.Double(acc, acc)
}
g.Add(acc, acc, windows[i])
}
return r.Set(acc), nil
}
func (g *G2) wnafMul(c, p *PointG2, e *big.Int) *PointG2 {
windowSize := uint(6)
precompTable := make([]*PointG2, (1 << (windowSize - 1)))
for i := 0; i < len(precompTable); i++ {
precompTable[i] = g.New()
}
var indexForPositive uint64 = (1 << (windowSize - 2))
precompTable[indexForPositive].Set(p)
g.Neg(precompTable[indexForPositive-1], p)
doubled, precomp := g.New(), g.New()
g.Double(doubled, p)
precomp.Set(p)
for i := uint64(1); i < indexForPositive; i++ {
g.Add(precomp, precomp, doubled)
precompTable[indexForPositive+i].Set(precomp)
g.Neg(precompTable[indexForPositive-1-i], precomp)
}
wnaf := wnaf(e, windowSize)
q := g.Zero()
found := false
var idx uint64
for i := len(wnaf) - 1; i >= 0; i-- {
if found {
g.Double(q, q)
}
if wnaf[i] != 0 {
found = true
if wnaf[i] > 0 {
idx = uint64(wnaf[i] >> 1)
g.Add(q, q, precompTable[indexForPositive+idx])
} else {
idx = uint64(((0 - wnaf[i]) >> 1))
g.Add(q, q, precompTable[indexForPositive-1-idx])
}
}
}
return c.Set(q)
}
// MapToCurve given a byte slice returns a valid G2 point.
// This mapping function implements the Simplified Shallue-van de Woestijne-Ulas method.
// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-05#section-6.6.2
// Input byte slice should be a valid field element, otherwise an error is returned.
func (g *G2) MapToCurve(in []byte) (*PointG2, error) {
fp2 := g.f
u, err := fp2.fromBytes(in)
if err != nil {
return nil, err
}
x, y := swuMapG2(fp2, u)
isogenyMapG2(fp2, x, y)
z := new(fe2).one()
q := &PointG2{*x, *y, *z}
g.ClearCofactor(q)
return g.Affine(q), nil
}
// EncodeToCurve given a message and domain seperator tag returns the hash result
// which is a valid curve point.
// Implementation follows BLS12381G1_XMD:SHA-256_SSWU_NU_ suite at
// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06
func (g *G2) EncodeToCurve(msg, domain []byte) (*PointG2, error) {
hashRes, err := hashToFpXMDSHA256(msg, domain, 2)
if err != nil {
return nil, err
}
fp2 := g.f
u := &fe2{*hashRes[0], *hashRes[1]}
x, y := swuMapG2(fp2, u)
isogenyMapG2(fp2, x, y)
z := new(fe2).one()
q := &PointG2{*x, *y, *z}
g.ClearCofactor(q)
return g.Affine(q), nil
}
// HashToCurve given a message and domain seperator tag returns the hash result
// which is a valid curve point.
// Implementation follows BLS12381G1_XMD:SHA-256_SSWU_RO_ suite at
// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06
func (g *G2) HashToCurve(msg, domain []byte) (*PointG2, error) {
hashRes, err := hashToFpXMDSHA256(msg, domain, 4)
if err != nil {
return nil, err
}
fp2 := g.f
u0, u1 := &fe2{*hashRes[0], *hashRes[1]}, &fe2{*hashRes[2], *hashRes[3]}
x0, y0 := swuMapG2(fp2, u0)
x1, y1 := swuMapG2(fp2, u1)
z0 := new(fe2).one()
z1 := new(fe2).one()
p0, p1 := &PointG2{*x0, *y0, *z0}, &PointG2{*x1, *y1, *z1}
g.Add(p0, p0, p1)
g.Affine(p0)
isogenyMapG2(fp2, &p0[0], &p0[1])
g.ClearCofactor(p0)
return g.Affine(p0), nil
}

5
vendor/github.com/kilic/bls12-381/go.mod generated vendored Normal file
View file

@ -0,0 +1,5 @@
module github.com/kilic/bls12-381
go 1.12
require golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339

2
vendor/github.com/kilic/bls12-381/go.sum generated vendored Normal file
View file

@ -0,0 +1,2 @@
golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339 h1:zSqWKgm/o7HAnlAzBQ+aetp9fpuyytsXnKA8eiLHYQM=
golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

106
vendor/github.com/kilic/bls12-381/gt.go generated vendored Normal file
View file

@ -0,0 +1,106 @@
package bls12381
import (
"errors"
"math/big"
)
// E is type for target group element
type E = fe12
// GT is type for target multiplicative group GT.
type GT struct {
fp12 *fp12
}
// Set copies given value into the destination
func (e *E) Set(e2 *E) *E {
return e.set(e2)
}
// One sets a new target group element to one
func (e *E) One() *E {
e = new(fe12).one()
return e
}
// IsOne returns true if given element equals to one
func (e *E) IsOne() bool {
return e.isOne()
}
// Equal returns true if given two element is equal, otherwise returns false
func (g *E) Equal(g2 *E) bool {
return g.equal(g2)
}
// NewGT constructs new target group instance.
func NewGT() *GT {
fp12 := newFp12(nil)
return &GT{fp12}
}
// Q returns group order in big.Int.
func (g *GT) Q() *big.Int {
return new(big.Int).Set(q)
}
// FromBytes expects 576 byte input and returns target group element
// FromBytes returns error if given element is not on correct subgroup.
func (g *GT) FromBytes(in []byte) (*E, error) {
e, err := g.fp12.fromBytes(in)
if err != nil {
return nil, err
}
if !g.IsValid(e) {
return e, errors.New("invalid element")
}
return e, nil
}
// ToBytes serializes target group element.
func (g *GT) ToBytes(e *E) []byte {
return g.fp12.toBytes(e)
}
// IsValid checks whether given target group element is in correct subgroup.
func (g *GT) IsValid(e *E) bool {
r := g.New()
g.fp12.exp(r, e, q)
return r.isOne()
}
// New initializes a new target group element which is equal to one
func (g *GT) New() *E {
return new(E).One()
}
// Add adds two field element `a` and `b` and assigns the result to the element in first argument.
func (g *GT) Add(c, a, b *E) {
g.fp12.add(c, a, b)
}
// Sub subtracts two field element `a` and `b`, and assigns the result to the element in first argument.
func (g *GT) Sub(c, a, b *E) {
g.fp12.sub(c, a, b)
}
// Mul multiplies two field element `a` and `b` and assigns the result to the element in first argument.
func (g *GT) Mul(c, a, b *E) {
g.fp12.mul(c, a, b)
}
// Square squares an element `a` and assigns the result to the element in first argument.
func (g *GT) Square(c, a *E) {
g.fp12.cyclotomicSquare(c, a)
}
// Exp exponents an element `a` by a scalar `s` and assigns the result to the element in first argument.
func (g *GT) Exp(c, a *E, s *big.Int) {
g.fp12.cyclotomicExp(c, a, s)
}
// Inverse inverses an element `a` and assigns the result to the element in first argument.
func (g *GT) Inverse(c, a *E) {
g.fp12.inverse(c, a)
}

70
vendor/github.com/kilic/bls12-381/hash_to_field.go generated vendored Normal file
View file

@ -0,0 +1,70 @@
package bls12381
import (
"crypto/sha256"
"errors"
)
func hashToFpXMDSHA256(msg []byte, domain []byte, count int) ([]*fe, error) {
randBytes, err := expandMsgSHA256XMD(msg, domain, count*64)
if err != nil {
return nil, err
}
els := make([]*fe, count)
for i := 0; i < count; i++ {
els[i], err = from64Bytes(randBytes[i*64 : (i+1)*64])
if err != nil {
return nil, err
}
}
return els, nil
}
func expandMsgSHA256XMD(msg []byte, domain []byte, outLen int) ([]byte, error) {
h := sha256.New()
domainLen := uint8(len(domain))
if domainLen > 255 {
return nil, errors.New("invalid domain length")
}
// DST_prime = DST || I2OSP(len(DST), 1)
// b_0 = H(Z_pad || msg || l_i_b_str || I2OSP(0, 1) || DST_prime)
_, _ = h.Write(make([]byte, h.BlockSize()))
_, _ = h.Write(msg)
_, _ = h.Write([]byte{uint8(outLen >> 8), uint8(outLen)})
_, _ = h.Write([]byte{0})
_, _ = h.Write(domain)
_, _ = h.Write([]byte{domainLen})
b0 := h.Sum(nil)
// b_1 = H(b_0 || I2OSP(1, 1) || DST_prime)
h.Reset()
_, _ = h.Write(b0)
_, _ = h.Write([]byte{1})
_, _ = h.Write(domain)
_, _ = h.Write([]byte{domainLen})
b1 := h.Sum(nil)
// b_i = H(strxor(b_0, b_(i - 1)) || I2OSP(i, 1) || DST_prime)
ell := (outLen + h.Size() - 1) / h.Size()
bi := b1
out := make([]byte, outLen)
for i := 1; i < ell; i++ {
h.Reset()
// b_i = H(strxor(b_0, b_(i - 1)) || I2OSP(i, 1) || DST_prime)
tmp := make([]byte, h.Size())
for j := 0; j < h.Size(); j++ {
tmp[j] = b0[j] ^ bi[j]
}
_, _ = h.Write(tmp)
_, _ = h.Write([]byte{1 + uint8(i)})
_, _ = h.Write(domain)
_, _ = h.Write([]byte{domainLen})
// b_1 || ... || b_(ell - 1)
copy(out[(i-1)*h.Size():i*h.Size()], bi[:])
bi = h.Sum(nil)
}
// b_ell
copy(out[(ell-1)*h.Size():], bi[:])
return out[:outLen], nil
}

211
vendor/github.com/kilic/bls12-381/isogeny.go generated vendored Normal file
View file

@ -0,0 +1,211 @@
package bls12381
// isogenyMapG1 applies 11-isogeny map for BLS12-381 G1 defined at draft-irtf-cfrg-hash-to-curve-06.
func isogenyMapG1(x, y *fe) {
// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#appendix-C.2
params := isogenyConstansG1
degree := 15
xNum, xDen, yNum, yDen := new(fe), new(fe), new(fe), new(fe)
xNum.set(params[0][degree])
xDen.set(params[1][degree])
yNum.set(params[2][degree])
yDen.set(params[3][degree])
for i := degree - 1; i >= 0; i-- {
mul(xNum, xNum, x)
mul(xDen, xDen, x)
mul(yNum, yNum, x)
mul(yDen, yDen, x)
add(xNum, xNum, params[0][i])
add(xDen, xDen, params[1][i])
add(yNum, yNum, params[2][i])
add(yDen, yDen, params[3][i])
}
inverse(xDen, xDen)
inverse(yDen, yDen)
mul(xNum, xNum, xDen)
mul(yNum, yNum, yDen)
mul(yNum, yNum, y)
x.set(xNum)
y.set(yNum)
}
// isogenyMapG2 applies 11-isogeny map for BLS12-381 G1 defined at draft-irtf-cfrg-hash-to-curve-06.
func isogenyMapG2(e *fp2, x, y *fe2) {
if e == nil {
e = newFp2()
}
// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#appendix-C.2
params := isogenyConstantsG2
degree := 3
xNum := new(fe2).set(params[0][degree])
xDen := new(fe2).set(params[1][degree])
yNum := new(fe2).set(params[2][degree])
yDen := new(fe2).set(params[3][degree])
for i := degree - 1; i >= 0; i-- {
e.mul(xNum, xNum, x)
e.mul(xDen, xDen, x)
e.mul(yNum, yNum, x)
e.mul(yDen, yDen, x)
e.add(xNum, xNum, params[0][i])
e.add(xDen, xDen, params[1][i])
e.add(yNum, yNum, params[2][i])
e.add(yDen, yDen, params[3][i])
}
e.inverse(xDen, xDen)
e.inverse(yDen, yDen)
e.mul(xNum, xNum, xDen)
e.mul(yNum, yNum, yDen)
e.mul(yNum, yNum, y)
x.set(xNum)
y.set(yNum)
}
var isogenyConstansG1 = [4][16]*fe{
[16]*fe{
&fe{0x4d18b6f3af00131c, 0x19fa219793fee28c, 0x3f2885f1467f19ae, 0x23dcea34f2ffb304, 0xd15b58d2ffc00054, 0x0913be200a20bef4},
&fe{0x898985385cdbbd8b, 0x3c79e43cc7d966aa, 0x1597e193f4cd233a, 0x8637ef1e4d6623ad, 0x11b22deed20d827b, 0x07097bc5998784ad},
&fe{0xa542583a480b664b, 0xfc7169c026e568c6, 0x5ba2ef314ed8b5a6, 0x5b5491c05102f0e7, 0xdf6e99707d2a0079, 0x0784151ed7605524},
&fe{0x494e212870f72741, 0xab9be52fbda43021, 0x26f5577994e34c3d, 0x049dfee82aefbd60, 0x65dadd7828505289, 0x0e93d431ea011aeb},
&fe{0x90ee774bd6a74d45, 0x7ada1c8a41bfb185, 0x0f1a8953b325f464, 0x104c24211be4805c, 0x169139d319ea7a8f, 0x09f20ead8e532bf6},
&fe{0x6ddd93e2f43626b7, 0xa5482c9aa1ccd7bd, 0x143245631883f4bd, 0x2e0a94ccf77ec0db, 0xb0282d480e56489f, 0x18f4bfcbb4368929},
&fe{0x23c5f0c953402dfd, 0x7a43ff6958ce4fe9, 0x2c390d3d2da5df63, 0xd0df5c98e1f9d70f, 0xffd89869a572b297, 0x1277ffc72f25e8fe},
&fe{0x79f4f0490f06a8a6, 0x85f894a88030fd81, 0x12da3054b18b6410, 0xe2a57f6505880d65, 0xbba074f260e400f1, 0x08b76279f621d028},
&fe{0xe67245ba78d5b00b, 0x8456ba9a1f186475, 0x7888bff6e6b33bb4, 0xe21585b9a30f86cb, 0x05a69cdcef55feee, 0x09e699dd9adfa5ac},
&fe{0x0de5c357bff57107, 0x0a0db4ae6b1a10b2, 0xe256bb67b3b3cd8d, 0x8ad456574e9db24f, 0x0443915f50fd4179, 0x098c4bf7de8b6375},
&fe{0xe6b0617e7dd929c7, 0xfe6e37d442537375, 0x1dafdeda137a489e, 0xe4efd1ad3f767ceb, 0x4a51d8667f0fe1cf, 0x054fdf4bbf1d821c},
&fe{0x72db2a50658d767b, 0x8abf91faa257b3d5, 0xe969d6833764ab47, 0x464170142a1009eb, 0xb14f01aadb30be2f, 0x18ae6a856f40715d},
&fe{0, 0, 0, 0, 0, 0},
&fe{0, 0, 0, 0, 0, 0},
&fe{0, 0, 0, 0, 0, 0},
&fe{0, 0, 0, 0, 0, 0},
},
[16]*fe{
&fe{0xb962a077fdb0f945, 0xa6a9740fefda13a0, 0xc14d568c3ed6c544, 0xb43fc37b908b133e, 0x9c0b3ac929599016, 0x0165aa6c93ad115f},
&fe{0x23279a3ba506c1d9, 0x92cfca0a9465176a, 0x3b294ab13755f0ff, 0x116dda1c5070ae93, 0xed4530924cec2045, 0x083383d6ed81f1ce},
&fe{0x9885c2a6449fecfc, 0x4a2b54ccd37733f0, 0x17da9ffd8738c142, 0xa0fba72732b3fafd, 0xff364f36e54b6812, 0x0f29c13c660523e2},
&fe{0xe349cc118278f041, 0xd487228f2f3204fb, 0xc9d325849ade5150, 0x43a92bd69c15c2df, 0x1c2c7844bc417be4, 0x12025184f407440c},
&fe{0x587f65ae6acb057b, 0x1444ef325140201f, 0xfbf995e71270da49, 0xccda066072436a42, 0x7408904f0f186bb2, 0x13b93c63edf6c015},
&fe{0xfb918622cd141920, 0x4a4c64423ecaddb4, 0x0beb232927f7fb26, 0x30f94df6f83a3dc2, 0xaeedd424d780f388, 0x06cc402dd594bbeb},
&fe{0xd41f761151b23f8f, 0x32a92465435719b3, 0x64f436e888c62cb9, 0xdf70a9a1f757c6e4, 0x6933a38d5b594c81, 0x0c6f7f7237b46606},
&fe{0x693c08747876c8f7, 0x22c9850bf9cf80f0, 0x8e9071dab950c124, 0x89bc62d61c7baf23, 0xbc6be2d8dad57c23, 0x17916987aa14a122},
&fe{0x1be3ff439c1316fd, 0x9965243a7571dfa7, 0xc7f7f62962f5cd81, 0x32c6aa9af394361c, 0xbbc2ee18e1c227f4, 0x0c102cbac531bb34},
&fe{0x997614c97bacbf07, 0x61f86372b99192c0, 0x5b8c95fc14353fc3, 0xca2b066c2a87492f, 0x16178f5bbf698711, 0x12a6dcd7f0f4e0e8},
&fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
&fe{0, 0, 0, 0, 0, 0},
&fe{0, 0, 0, 0, 0, 0},
&fe{0, 0, 0, 0, 0, 0},
&fe{0, 0, 0, 0, 0, 0},
&fe{0, 0, 0, 0, 0, 0},
},
[16]*fe{
&fe{0x2b567ff3e2837267, 0x1d4d9e57b958a767, 0xce028fea04bd7373, 0xcc31a30a0b6cd3df, 0x7d7b18a682692693, 0x0d300744d42a0310},
&fe{0x99c2555fa542493f, 0xfe7f53cc4874f878, 0x5df0608b8f97608a, 0x14e03832052b49c8, 0x706326a6957dd5a4, 0x0a8dadd9c2414555},
&fe{0x13d942922a5cf63a, 0x357e33e36e261e7d, 0xcf05a27c8456088d, 0x0000bd1de7ba50f0, 0x83d0c7532f8c1fde, 0x13f70bf38bbf2905},
&fe{0x5c57fd95bfafbdbb, 0x28a359a65e541707, 0x3983ceb4f6360b6d, 0xafe19ff6f97e6d53, 0xb3468f4550192bf7, 0x0bb6cde49d8ba257},
&fe{0x590b62c7ff8a513f, 0x314b4ce372cacefd, 0x6bef32ce94b8a800, 0x6ddf84a095713d5f, 0x64eace4cb0982191, 0x0386213c651b888d},
&fe{0xa5310a31111bbcdd, 0xa14ac0f5da148982, 0xf9ad9cc95423d2e9, 0xaa6ec095283ee4a7, 0xcf5b1f022e1c9107, 0x01fddf5aed881793},
&fe{0x65a572b0d7a7d950, 0xe25c2d8183473a19, 0xc2fcebe7cb877dbd, 0x05b2d36c769a89b0, 0xba12961be86e9efb, 0x07eb1b29c1dfde1f},
&fe{0x93e09572f7c4cd24, 0x364e929076795091, 0x8569467e68af51b5, 0xa47da89439f5340f, 0xf4fa918082e44d64, 0x0ad52ba3e6695a79},
&fe{0x911429844e0d5f54, 0xd03f51a3516bb233, 0x3d587e5640536e66, 0xfa86d2a3a9a73482, 0xa90ed5adf1ed5537, 0x149c9c326a5e7393},
&fe{0x462bbeb03c12921a, 0xdc9af5fa0a274a17, 0x9a558ebde836ebed, 0x649ef8f11a4fae46, 0x8100e1652b3cdc62, 0x1862bd62c291dacb},
&fe{0x05c9b8ca89f12c26, 0x0194160fa9b9ac4f, 0x6a643d5a6879fa2c, 0x14665bdd8846e19d, 0xbb1d0d53af3ff6bf, 0x12c7e1c3b28962e5},
&fe{0xb55ebf900b8a3e17, 0xfedc77ec1a9201c4, 0x1f07db10ea1a4df4, 0x0dfbd15dc41a594d, 0x389547f2334a5391, 0x02419f98165871a4},
&fe{0xb416af000745fc20, 0x8e563e9d1ea6d0f5, 0x7c763e17763a0652, 0x01458ef0159ebbef, 0x8346fe421f96bb13, 0x0d2d7b829ce324d2},
&fe{0x93096bb538d64615, 0x6f2a2619951d823a, 0x8f66b3ea59514fa4, 0xf563e63704f7092f, 0x724b136c4cf2d9fa, 0x046959cfcfd0bf49},
&fe{0xea748d4b6e405346, 0x91e9079c2c02d58f, 0x41064965946d9b59, 0xa06731f1d2bbe1ee, 0x07f897e267a33f1b, 0x1017290919210e5f},
&fe{0x872aa6c17d985097, 0xeecc53161264562a, 0x07afe37afff55002, 0x54759078e5be6838, 0xc4b92d15db8acca8, 0x106d87d1b51d13b9},
},
[16]*fe{
&fe{0xeb6c359d47e52b1c, 0x18ef5f8a10634d60, 0xddfa71a0889d5b7e, 0x723e71dcc5fc1323, 0x52f45700b70d5c69, 0x0a8b981ee47691f1},
&fe{0x616a3c4f5535b9fb, 0x6f5f037395dbd911, 0xf25f4cc5e35c65da, 0x3e50dffea3c62658, 0x6a33dca523560776, 0x0fadeff77b6bfe3e},
&fe{0x2be9b66df470059c, 0x24a2c159a3d36742, 0x115dbe7ad10c2a37, 0xb6634a652ee5884d, 0x04fe8bb2b8d81af4, 0x01c2a7a256fe9c41},
&fe{0xf27bf8ef3b75a386, 0x898b367476c9073f, 0x24482e6b8c2f4e5f, 0xc8e0bbd6fe110806, 0x59b0c17f7631448a, 0x11037cd58b3dbfbd},
&fe{0x31c7912ea267eec6, 0x1dbf6f1c5fcdb700, 0xd30d4fe3ba86fdb1, 0x3cae528fbee9a2a4, 0xb1cce69b6aa9ad9a, 0x044393bb632d94fb},
&fe{0xc66ef6efeeb5c7e8, 0x9824c289dd72bb55, 0x71b1a4d2f119981d, 0x104fc1aafb0919cc, 0x0e49df01d942a628, 0x096c3a09773272d4},
&fe{0x9abc11eb5fadeff4, 0x32dca50a885728f0, 0xfb1fa3721569734c, 0xc4b76271ea6506b3, 0xd466a75599ce728e, 0x0c81d4645f4cb6ed},
&fe{0x4199f10e5b8be45b, 0xda64e495b1e87930, 0xcb353efe9b33e4ff, 0x9e9efb24aa6424c6, 0xf08d33680a237465, 0x0d3378023e4c7406},
&fe{0x7eb4ae92ec74d3a5, 0xc341b4aa9fac3497, 0x5be603899e907687, 0x03bfd9cca75cbdeb, 0x564c2935a96bfa93, 0x0ef3c33371e2fdb5},
&fe{0x7ee91fd449f6ac2e, 0xe5d5bd5cb9357a30, 0x773a8ca5196b1380, 0xd0fda172174ed023, 0x6cb95e0fa776aead, 0x0d22d5a40cec7cff},
&fe{0xf727e09285fd8519, 0xdc9d55a83017897b, 0x7549d8bd057894ae, 0x178419613d90d8f8, 0xfce95ebdeb5b490a, 0x0467ffaef23fc49e},
&fe{0xc1769e6a7c385f1b, 0x79bc930deac01c03, 0x5461c75a23ede3b5, 0x6e20829e5c230c45, 0x828e0f1e772a53cd, 0x116aefa749127bff},
&fe{0x101c10bf2744c10a, 0xbbf18d053a6a3154, 0xa0ecf39ef026f602, 0xfc009d4996dc5153, 0xb9000209d5bd08d3, 0x189e5fe4470cd73c},
&fe{0x7ebd546ca1575ed2, 0xe47d5a981d081b55, 0x57b2b625b6d4ca21, 0xb0a1ba04228520cc, 0x98738983c2107ff3, 0x13dddbc4799d81d6},
&fe{0x09319f2e39834935, 0x039e952cbdb05c21, 0x55ba77a9a2f76493, 0xfd04e3dfc6086467, 0xfb95832e7d78742e, 0x0ef9c24eccaf5e0e},
&fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
},
}
var isogenyConstantsG2 = [4][4]*fe2{
[4]*fe2{
&fe2{
fe{0x47f671c71ce05e62, 0x06dd57071206393e, 0x7c80cd2af3fd71a2, 0x048103ea9e6cd062, 0xc54516acc8d037f6, 0x13808f550920ea41},
fe{0x47f671c71ce05e62, 0x06dd57071206393e, 0x7c80cd2af3fd71a2, 0x048103ea9e6cd062, 0xc54516acc8d037f6, 0x13808f550920ea41},
},
&fe2{
fe{0, 0, 0, 0, 0, 0},
fe{0x5fe55555554c71d0, 0x873fffdd236aaaa3, 0x6a6b4619b26ef918, 0x21c2888408874945, 0x2836cda7028cabc5, 0x0ac73310a7fd5abd},
},
&fe2{
fe{0x0a0c5555555971c3, 0xdb0c00101f9eaaae, 0xb1fb2f941d797997, 0xd3960742ef416e1c, 0xb70040e2c20556f4, 0x149d7861e581393b},
fe{0xaff2aaaaaaa638e8, 0x439fffee91b55551, 0xb535a30cd9377c8c, 0x90e144420443a4a2, 0x941b66d3814655e2, 0x0563998853fead5e},
},
&fe2{
fe{0x40aac71c71c725ed, 0x190955557a84e38e, 0xd817050a8f41abc3, 0xd86485d4c87f6fb1, 0x696eb479f885d059, 0x198e1a74328002d2},
fe{0, 0, 0, 0, 0, 0},
},
},
[4]*fe2{
&fe2{
fe{0, 0, 0, 0, 0, 0},
fe{0x1f3affffff13ab97, 0xf25bfc611da3ff3e, 0xca3757cb3819b208, 0x3e6427366f8cec18, 0x03977bc86095b089, 0x04f69db13f39a952},
},
&fe2{
fe{0x447600000027552e, 0xdcb8009a43480020, 0x6f7ee9ce4a6e8b59, 0xb10330b7c0a95bc6, 0x6140b1fcfb1e54b7, 0x0381be097f0bb4e1},
fe{0x7588ffffffd8557d, 0x41f3ff646e0bffdf, 0xf7b1e8d2ac426aca, 0xb3741acd32dbb6f8, 0xe9daf5b9482d581f, 0x167f53e0ba7431b8},
},
&fe2{
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
fe{0, 0, 0, 0, 0, 0},
},
&fe2{
fe{0, 0, 0, 0, 0, 0},
fe{0, 0, 0, 0, 0, 0},
},
},
[4]*fe2{
&fe2{
fe{0x96d8f684bdfc77be, 0xb530e4f43b66d0e2, 0x184a88ff379652fd, 0x57cb23ecfae804e1, 0x0fd2e39eada3eba9, 0x08c8055e31c5d5c3},
fe{0x96d8f684bdfc77be, 0xb530e4f43b66d0e2, 0x184a88ff379652fd, 0x57cb23ecfae804e1, 0x0fd2e39eada3eba9, 0x08c8055e31c5d5c3},
},
&fe2{
fe{0, 0, 0, 0, 0, 0},
fe{0xbf0a71c71c91b406, 0x4d6d55d28b7638fd, 0x9d82f98e5f205aee, 0xa27aa27b1d1a18d5, 0x02c3b2b2d2938e86, 0x0c7d13420b09807f},
},
&fe2{
fe{0xd7f9555555531c74, 0x21cffff748daaaa8, 0x5a9ad1866c9bbe46, 0x4870a2210221d251, 0x4a0db369c0a32af1, 0x02b1ccc429ff56af},
fe{0xe205aaaaaaac8e37, 0xfcdc000768795556, 0x0c96011a8a1537dd, 0x1c06a963f163406e, 0x010df44c82a881e6, 0x174f45260f808feb},
},
&fe2{
fe{0xa470bda12f67f35c, 0xc0fe38e23327b425, 0xc9d3d0f2c6f0678d, 0x1c55c9935b5a982e, 0x27f6c0e2f0746764, 0x117c5e6e28aa9054},
fe{0, 0, 0, 0, 0, 0},
},
},
[4]*fe2{
&fe2{
fe{0x0162fffffa765adf, 0x8f7bea480083fb75, 0x561b3c2259e93611, 0x11e19fc1a9c875d5, 0xca713efc00367660, 0x03c6a03d41da1151},
fe{0x0162fffffa765adf, 0x8f7bea480083fb75, 0x561b3c2259e93611, 0x11e19fc1a9c875d5, 0xca713efc00367660, 0x03c6a03d41da1151},
},
&fe2{
fe{0, 0, 0, 0, 0, 0},
fe{0x5db0fffffd3b02c5, 0xd713f52358ebfdba, 0x5ea60761a84d161a, 0xbb2c75a34ea6c44a, 0x0ac6735921c1119b, 0x0ee3d913bdacfbf6},
},
&fe2{
fe{0x66b10000003affc5, 0xcb1400e764ec0030, 0xa73e5eb56fa5d106, 0x8984c913a0fe09a9, 0x11e10afb78ad7f13, 0x05429d0e3e918f52},
fe{0x534dffffffc4aae6, 0x5397ff174c67ffcf, 0xbff273eb870b251d, 0xdaf2827152870915, 0x393a9cbaca9e2dc3, 0x14be74dbfaee5748},
},
&fe2{
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
fe{0, 0, 0, 0, 0, 0},
},
},
}

266
vendor/github.com/kilic/bls12-381/pairing.go generated vendored Normal file
View file

@ -0,0 +1,266 @@
package bls12381
type pair struct {
g1 *PointG1
g2 *PointG2
}
func newPair(g1 *PointG1, g2 *PointG2) pair {
return pair{g1, g2}
}
// Engine is BLS12-381 elliptic curve pairing engine
type Engine struct {
G1 *G1
G2 *G2
fp12 *fp12
fp2 *fp2
pairingEngineTemp
pairs []pair
}
// NewEngine creates new pairing engine insteace.
func NewEngine() *Engine {
fp2 := newFp2()
fp6 := newFp6(fp2)
fp12 := newFp12(fp6)
g1 := NewG1()
g2 := newG2(fp2)
return &Engine{
fp2: fp2,
fp12: fp12,
G1: g1,
G2: g2,
pairingEngineTemp: newEngineTemp(),
}
}
type pairingEngineTemp struct {
t2 [10]*fe2
t12 [9]fe12
}
func newEngineTemp() pairingEngineTemp {
t2 := [10]*fe2{}
for i := 0; i < 10; i++ {
t2[i] = &fe2{}
}
t12 := [9]fe12{}
return pairingEngineTemp{t2, t12}
}
// AddPair adds a g1, g2 point pair to pairing engine
func (e *Engine) AddPair(g1 *PointG1, g2 *PointG2) *Engine {
p := newPair(g1, g2)
if !e.isZero(p) {
e.affine(p)
e.pairs = append(e.pairs, p)
}
return e
}
// AddPairInv adds a G1, G2 point pair to pairing engine. G1 point is negated.
func (e *Engine) AddPairInv(g1 *PointG1, g2 *PointG2) *Engine {
e.G1.Neg(g1, g1)
e.AddPair(g1, g2)
return e
}
// Reset deletes added pairs.
func (e *Engine) Reset() *Engine {
e.pairs = []pair{}
return e
}
func (e *Engine) isZero(p pair) bool {
return e.G1.IsZero(p.g1) || e.G2.IsZero(p.g2)
}
func (e *Engine) affine(p pair) {
e.G1.Affine(p.g1)
e.G2.Affine(p.g2)
}
func (e *Engine) doublingStep(coeff *[3]fe2, r *PointG2) {
// Adaptation of Formula 3 in https://eprint.iacr.org/2010/526.pdf
fp2 := e.fp2
t := e.t2
fp2.mul(t[0], &r[0], &r[1])
fp2.mulByFq(t[0], t[0], twoInv)
fp2.square(t[1], &r[1])
fp2.square(t[2], &r[2])
fp2.double(t[7], t[2])
fp2.add(t[7], t[7], t[2])
fp2.mulByB(t[3], t[7])
fp2.double(t[4], t[3])
fp2.add(t[4], t[4], t[3])
fp2.add(t[5], t[1], t[4])
fp2.mulByFq(t[5], t[5], twoInv)
fp2.add(t[6], &r[1], &r[2])
fp2.square(t[6], t[6])
fp2.add(t[7], t[2], t[1])
fp2.sub(t[6], t[6], t[7])
fp2.sub(&coeff[0], t[3], t[1])
fp2.square(t[7], &r[0])
fp2.sub(t[4], t[1], t[4])
fp2.mul(&r[0], t[4], t[0])
fp2.square(t[2], t[3])
fp2.double(t[3], t[2])
fp2.add(t[3], t[3], t[2])
fp2.square(t[5], t[5])
fp2.sub(&r[1], t[5], t[3])
fp2.mul(&r[2], t[1], t[6])
fp2.double(t[0], t[7])
fp2.add(&coeff[1], t[0], t[7])
fp2.neg(&coeff[2], t[6])
}
func (e *Engine) additionStep(coeff *[3]fe2, r, q *PointG2) {
// Algorithm 12 in https://eprint.iacr.org/2010/526.pdf
fp2 := e.fp2
t := e.t2
fp2.mul(t[0], &q[1], &r[2])
fp2.neg(t[0], t[0])
fp2.add(t[0], t[0], &r[1])
fp2.mul(t[1], &q[0], &r[2])
fp2.neg(t[1], t[1])
fp2.add(t[1], t[1], &r[0])
fp2.square(t[2], t[0])
fp2.square(t[3], t[1])
fp2.mul(t[4], t[1], t[3])
fp2.mul(t[2], &r[2], t[2])
fp2.mul(t[3], &r[0], t[3])
fp2.double(t[5], t[3])
fp2.sub(t[5], t[4], t[5])
fp2.add(t[5], t[5], t[2])
fp2.mul(&r[0], t[1], t[5])
fp2.sub(t[2], t[3], t[5])
fp2.mul(t[2], t[2], t[0])
fp2.mul(t[3], &r[1], t[4])
fp2.sub(&r[1], t[2], t[3])
fp2.mul(&r[2], &r[2], t[4])
fp2.mul(t[2], t[1], &q[1])
fp2.mul(t[3], t[0], &q[0])
fp2.sub(&coeff[0], t[3], t[2])
fp2.neg(&coeff[1], t[0])
coeff[2].set(t[1])
}
func (e *Engine) preCompute(ellCoeffs *[68][3]fe2, twistPoint *PointG2) {
// Algorithm 5 in https://eprint.iacr.org/2019/077.pdf
if e.G2.IsZero(twistPoint) {
return
}
r := new(PointG2).Set(twistPoint)
j := 0
for i := int(x.BitLen() - 2); i >= 0; i-- {
e.doublingStep(&ellCoeffs[j], r)
if x.Bit(i) != 0 {
j++
ellCoeffs[j] = fe6{}
e.additionStep(&ellCoeffs[j], r, twistPoint)
}
j++
}
}
func (e *Engine) millerLoop(f *fe12) {
pairs := e.pairs
ellCoeffs := make([][68][3]fe2, len(pairs))
for i := 0; i < len(pairs); i++ {
e.preCompute(&ellCoeffs[i], pairs[i].g2)
}
fp12, fp2 := e.fp12, e.fp2
t := e.t2
f.one()
j := 0
for i := 62; /* x.BitLen() - 2 */ i >= 0; i-- {
if i != 62 {
fp12.square(f, f)
}
for i := 0; i <= len(pairs)-1; i++ {
fp2.mulByFq(t[0], &ellCoeffs[i][j][2], &pairs[i].g1[1])
fp2.mulByFq(t[1], &ellCoeffs[i][j][1], &pairs[i].g1[0])
fp12.mulBy014Assign(f, &ellCoeffs[i][j][0], t[1], t[0])
}
if x.Bit(i) != 0 {
j++
for i := 0; i <= len(pairs)-1; i++ {
fp2.mulByFq(t[0], &ellCoeffs[i][j][2], &pairs[i].g1[1])
fp2.mulByFq(t[1], &ellCoeffs[i][j][1], &pairs[i].g1[0])
fp12.mulBy014Assign(f, &ellCoeffs[i][j][0], t[1], t[0])
}
}
j++
}
fp12.conjugate(f, f)
}
func (e *Engine) exp(c, a *fe12) {
fp12 := e.fp12
fp12.cyclotomicExp(c, a, x)
fp12.conjugate(c, c)
}
func (e *Engine) finalExp(f *fe12) {
fp12 := e.fp12
t := e.t12
// easy part
fp12.frobeniusMap(&t[0], f, 6)
fp12.inverse(&t[1], f)
fp12.mul(&t[2], &t[0], &t[1])
t[1].set(&t[2])
fp12.frobeniusMapAssign(&t[2], 2)
fp12.mulAssign(&t[2], &t[1])
fp12.cyclotomicSquare(&t[1], &t[2])
fp12.conjugate(&t[1], &t[1])
// hard part
e.exp(&t[3], &t[2])
fp12.cyclotomicSquare(&t[4], &t[3])
fp12.mul(&t[5], &t[1], &t[3])
e.exp(&t[1], &t[5])
e.exp(&t[0], &t[1])
e.exp(&t[6], &t[0])
fp12.mulAssign(&t[6], &t[4])
e.exp(&t[4], &t[6])
fp12.conjugate(&t[5], &t[5])
fp12.mulAssign(&t[4], &t[5])
fp12.mulAssign(&t[4], &t[2])
fp12.conjugate(&t[5], &t[2])
fp12.mulAssign(&t[1], &t[2])
fp12.frobeniusMapAssign(&t[1], 3)
fp12.mulAssign(&t[6], &t[5])
fp12.frobeniusMapAssign(&t[6], 1)
fp12.mulAssign(&t[3], &t[0])
fp12.frobeniusMapAssign(&t[3], 2)
fp12.mulAssign(&t[3], &t[1])
fp12.mulAssign(&t[3], &t[6])
fp12.mul(f, &t[3], &t[4])
}
func (e *Engine) calculate() *fe12 {
f := e.fp12.one()
if len(e.pairs) == 0 {
return f
}
e.millerLoop(f)
e.finalExp(f)
return f
}
// Check computes pairing and checks if result is equal to one
func (e *Engine) Check() bool {
return e.calculate().isOne()
}
// Result computes pairing and returns target group element as result.
func (e *Engine) Result() *E {
r := e.calculate()
e.Reset()
return r
}
// GT returns target group instance.
func (e *Engine) GT() *GT {
return NewGT()
}

142
vendor/github.com/kilic/bls12-381/swu.go generated vendored Normal file
View file

@ -0,0 +1,142 @@
package bls12381
// swuMapG1 is implementation of Simplified Shallue-van de Woestijne-Ulas Method
// follows the implmentation at draft-irtf-cfrg-hash-to-curve-06.
func swuMapG1(u *fe) (*fe, *fe) {
var params = swuParamsForG1
var tv [4]*fe
for i := 0; i < 4; i++ {
tv[i] = new(fe)
}
square(tv[0], u)
mul(tv[0], tv[0], params.z)
square(tv[1], tv[0])
x1 := new(fe)
add(x1, tv[0], tv[1])
inverse(x1, x1)
e1 := x1.isZero()
one := new(fe).one()
add(x1, x1, one)
if e1 {
x1.set(params.zInv)
}
mul(x1, x1, params.minusBOverA)
gx1 := new(fe)
square(gx1, x1)
add(gx1, gx1, params.a)
mul(gx1, gx1, x1)
add(gx1, gx1, params.b)
x2 := new(fe)
mul(x2, tv[0], x1)
mul(tv[1], tv[0], tv[1])
gx2 := new(fe)
mul(gx2, gx1, tv[1])
e2 := !isQuadraticNonResidue(gx1)
x, y2 := new(fe), new(fe)
if e2 {
x.set(x1)
y2.set(gx1)
} else {
x.set(x2)
y2.set(gx2)
}
y := new(fe)
sqrt(y, y2)
if y.sign() != u.sign() {
neg(y, y)
}
return x, y
}
// swuMapG2 is implementation of Simplified Shallue-van de Woestijne-Ulas Method
// defined at draft-irtf-cfrg-hash-to-curve-06.
func swuMapG2(e *fp2, u *fe2) (*fe2, *fe2) {
if e == nil {
e = newFp2()
}
params := swuParamsForG2
var tv [4]*fe2
for i := 0; i < 4; i++ {
tv[i] = e.new()
}
e.square(tv[0], u)
e.mul(tv[0], tv[0], params.z)
e.square(tv[1], tv[0])
x1 := e.new()
e.add(x1, tv[0], tv[1])
e.inverse(x1, x1)
e1 := x1.isZero()
e.add(x1, x1, e.one())
if e1 {
x1.set(params.zInv)
}
e.mul(x1, x1, params.minusBOverA)
gx1 := e.new()
e.square(gx1, x1)
e.add(gx1, gx1, params.a)
e.mul(gx1, gx1, x1)
e.add(gx1, gx1, params.b)
x2 := e.new()
e.mul(x2, tv[0], x1)
e.mul(tv[1], tv[0], tv[1])
gx2 := e.new()
e.mul(gx2, gx1, tv[1])
e2 := !e.isQuadraticNonResidue(gx1)
x, y2 := e.new(), e.new()
if e2 {
x.set(x1)
y2.set(gx1)
} else {
x.set(x2)
y2.set(gx2)
}
y := e.new()
e.sqrt(y, y2)
if y.sign() != u.sign() {
e.neg(y, y)
}
return x, y
}
var swuParamsForG1 = struct {
z *fe
zInv *fe
a *fe
b *fe
minusBOverA *fe
}{
a: &fe{0x2f65aa0e9af5aa51, 0x86464c2d1e8416c3, 0xb85ce591b7bd31e2, 0x27e11c91b5f24e7c, 0x28376eda6bfc1835, 0x155455c3e5071d85},
b: &fe{0xfb996971fe22a1e0, 0x9aa93eb35b742d6f, 0x8c476013de99c5c4, 0x873e27c3a221e571, 0xca72b5e45a52d888, 0x06824061418a386b},
z: &fe{0x886c00000023ffdc, 0x0f70008d3090001d, 0x77672417ed5828c3, 0x9dac23e943dc1740, 0x50553f1b9c131521, 0x078c712fbe0ab6e8},
zInv: &fe{0x0e8a2e8ba2e83e10, 0x5b28ba2ca4d745d1, 0x678cd5473847377a, 0x4c506dd8a8076116, 0x9bcb227d79284139, 0x0e8d3154b0ba099a},
minusBOverA: &fe{0x052583c93555a7fe, 0x3b40d72430f93c82, 0x1b75faa0105ec983, 0x2527e7dc63851767, 0x99fffd1f34fc181d, 0x097cab54770ca0d3},
}
var swuParamsForG2 = struct {
z *fe2
zInv *fe2
a *fe2
b *fe2
minusBOverA *fe2
}{
a: &fe2{
fe{0, 0, 0, 0, 0, 0},
fe{0xe53a000003135242, 0x01080c0fdef80285, 0xe7889edbe340f6bd, 0x0b51375126310601, 0x02d6985717c744ab, 0x1220b4e979ea5467},
},
b: &fe2{
fe{0x22ea00000cf89db2, 0x6ec832df71380aa4, 0x6e1b94403db5a66e, 0x75bf3c53a79473ba, 0x3dd3a569412c0a34, 0x125cdb5e74dc4fd1},
fe{0x22ea00000cf89db2, 0x6ec832df71380aa4, 0x6e1b94403db5a66e, 0x75bf3c53a79473ba, 0x3dd3a569412c0a34, 0x125cdb5e74dc4fd1},
},
z: &fe2{
fe{0x87ebfffffff9555c, 0x656fffe5da8ffffa, 0x0fd0749345d33ad2, 0xd951e663066576f4, 0xde291a3d41e980d3, 0x0815664c7dfe040d},
fe{0x43f5fffffffcaaae, 0x32b7fff2ed47fffd, 0x07e83a49a2e99d69, 0xeca8f3318332bb7a, 0xef148d1ea0f4c069, 0x040ab3263eff0206},
},
zInv: &fe2{
fe{0xacd0000000011110, 0x9dd9999dc88ccccd, 0xb5ca2ac9b76352bf, 0xf1b574bcf4bc90ce, 0x42dab41f28a77081, 0x132fc6ac14cd1e12},
fe{0xe396ffffffff2223, 0x4fbf332fcd0d9998, 0x0c4bbd3c1aff4cc4, 0x6b9c91267926ca58, 0x29ae4da6aef7f496, 0x10692e942f195791},
},
minusBOverA: &fe2{
fe{0x903c555555474fb3, 0x5f98cc95ce451105, 0x9f8e582eefe0fade, 0xc68946b6aebbd062, 0x467a4ad10ee6de53, 0x0e7146f483e23a05},
fe{0x29c2aaaaaab85af8, 0xbf133368e30eeefa, 0xc7a27a7206cffb45, 0x9dee04ce44c9425c, 0x04a15ce53464ce83, 0x0b8fcaf5b59dac95},
},
}

13
vendor/github.com/kilic/bls12-381/utils.go generated vendored Normal file
View file

@ -0,0 +1,13 @@
package bls12381
import (
"math/big"
)
func bigFromHex(hex string) *big.Int {
if len(hex) > 1 && hex[:2] == "0x" {
hex = hex[2:]
}
n, _ := new(big.Int).SetString(hex, 16)
return n
}

35
vendor/github.com/kilic/bls12-381/wnaf.go generated vendored Normal file
View file

@ -0,0 +1,35 @@
package bls12381
import (
"math/big"
)
func wnaf(e0 *big.Int, window uint) []int64 {
e := new(big.Int).Set(e0)
zero := big.NewInt(0)
if e.Cmp(zero) == 0 {
return []int64{}
}
max := int64(1 << window)
midpoint := int64(1 << (window - 1))
modulusMask := uint64(1<<window) - 1
var out []int64
for e.Cmp(zero) != 0 {
var z int64
if e.Bit(0)&1 == 1 {
maskedBits := int64(e.Uint64() & modulusMask)
if maskedBits > midpoint {
z = maskedBits - max
e.Add(e, new(big.Int).SetInt64(0-z))
} else {
z = maskedBits
e.Sub(e, new(big.Int).SetInt64(z))
}
} else {
z = 0
}
out = append(out, z)
e.Rsh(e, 1)
}
return out
}

30
vendor/github.com/multiformats/go-varint/.travis.yml generated vendored Normal file
View file

@ -0,0 +1,30 @@
os:
- linux
language: go
go:
- 1.11.x
env:
global:
- GOTFLAGS="-race"
- GO111MODULE=on
matrix:
- BUILD_DEPTYPE=gomod
# disable travis install
install:
- true
script:
- bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh)
cache:
directories:
- $GOPATH/pkg/mod
- /home/travis/.cache/go-build
notifications:
email: false

21
vendor/github.com/multiformats/go-varint/LICENSE generated vendored Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2019 Protocol Labs
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

35
vendor/github.com/multiformats/go-varint/README.md generated vendored Normal file
View file

@ -0,0 +1,35 @@
# go-varint
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai)
[![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)](https://github.com/multiformats/multiformats)
[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](https://webchat.freenode.net/?channels=%23ipfs)
[![](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)
[![GoDoc](https://godoc.org/github.com/multiformats/go-varint?status.svg)](https://godoc.org/github.com/multiformats/go-varint)
[![Travis CI](https://img.shields.io/travis/multiformats/go-varint.svg?style=flat-square&branch=master)](https://travis-ci.org/multiformats/go-varint)
[![codecov.io](https://img.shields.io/codecov/c/github/multiformats/go-varint.svg?style=flat-square&branch=master)](https://codecov.io/github/multiformats/go-varint?branch=master)
> Varint helpers that enforce minimal encoding.
## Table of Contents
- [Install](#install)
- [Contribute](#contribute)
- [License](#license)
## Install
```sh
go get github.com/multiformats/go-varint
```
## Contribute
Contributions welcome. Please check out [the issues](https://github.com/multiformats/go-multiaddr/issues).
Check out our [contributing document](https://github.com/multiformats/multiformats/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to multiformats are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).
Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.
## License
[MIT](LICENSE) © 2019 Protocol Labs

2
vendor/github.com/multiformats/go-varint/codecov.yml generated vendored Normal file
View file

@ -0,0 +1,2 @@
ignore:
- "multiaddr"

3
vendor/github.com/multiformats/go-varint/go.mod generated vendored Normal file
View file

@ -0,0 +1,3 @@
module github.com/multiformats/go-varint
go 1.12

94
vendor/github.com/multiformats/go-varint/varint.go generated vendored Normal file
View file

@ -0,0 +1,94 @@
package varint
import (
"encoding/binary"
"errors"
"io"
"math/bits"
)
var (
ErrOverflow = errors.New("varints larger than uint64 not yet supported")
ErrUnderflow = errors.New("varints malformed, could not reach the end")
ErrNotMinimal = errors.New("varint not minimally encoded")
)
// UvarintSize returns the size (in bytes) of `num` encoded as a unsigned varint.
func UvarintSize(num uint64) int {
bits := bits.Len64(num)
q, r := bits/7, bits%7
size := q
if r > 0 || size == 0 {
size++
}
return size
}
// ToUvarint converts an unsigned integer to a varint-encoded []byte
func ToUvarint(num uint64) []byte {
buf := make([]byte, UvarintSize(num))
n := binary.PutUvarint(buf, uint64(num))
return buf[:n]
}
// FromUvarint reads an unsigned varint from the beginning of buf, returns the
// varint, and the number of bytes read.
func FromUvarint(buf []byte) (uint64, int, error) {
// Modified from the go standard library. Copyright the Go Authors and
// released under the BSD License.
var x uint64
var s uint
for i, b := range buf {
if b < 0x80 {
if i > 9 || i == 9 && b > 1 {
return 0, 0, ErrOverflow
} else if b == 0 && s > 0 {
return 0, 0, ErrNotMinimal
}
return x | uint64(b)<<s, i + 1, nil
}
x |= uint64(b&0x7f) << s
s += 7
}
return 0, 0, ErrUnderflow
}
// ReadUvarint reads a unsigned varint from the given reader.
func ReadUvarint(r io.ByteReader) (uint64, error) {
// Modified from the go standard library. Copyright the Go Authors and
// released under the BSD License.
var x uint64
var s uint
for i := 0; ; i++ {
b, err := r.ReadByte()
if err != nil {
if err == io.EOF && i != 0 {
// "eof" will look like a success.
// If we've read part of a value, this is not a
// success.
err = io.ErrUnexpectedEOF
}
return 0, err
}
if b < 0x80 {
if i > 9 || i == 9 && b > 1 {
return 0, ErrOverflow
} else if b == 0 && s > 0 {
// we should never _finish_ on a 0 byte if we
// have more than one byte.
return 0, ErrNotMinimal
}
return x | uint64(b)<<s, nil
}
x |= uint64(b&0x7f) << s
s += 7
}
}
// PutUvarint is an alias for binary.PutUvarint.
//
// This is provided for convenience so users of this library can avoid built-in
// varint functions and easily audit code for uses of those functions.
func PutUvarint(buf []byte, x uint64) int {
return binary.PutUvarint(buf, x)
}

4
vendor/modules.txt vendored
View file

@ -181,6 +181,8 @@ github.com/jbenet/goprocess/periodic
github.com/jinzhu/copier
# github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9
github.com/karalabe/usb
# github.com/kilic/bls12-381 v0.0.0-20200607163746-32e1441c8a9f
github.com/kilic/bls12-381
# github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d
github.com/koron/go-ssdp
# github.com/leodido/go-urn v1.2.0
@ -312,6 +314,8 @@ github.com/multiformats/go-multibase
github.com/multiformats/go-multihash
# github.com/multiformats/go-multistream v0.1.0
github.com/multiformats/go-multistream
# github.com/multiformats/go-varint v0.0.5
github.com/multiformats/go-varint
# github.com/mutecomm/go-sqlcipher v0.0.0-20190227152316-55dbde17881f
github.com/mutecomm/go-sqlcipher
# github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd