bgls

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 24, 2018 License: Apache-2.0 Imports: 9 Imported by: 0

README

BGLS

Aggregate and Multi Signatures based on BGLS over Alt bn128

This library provides no security against side channel attacks. We provide no security guarantees of this implementation.

Design

The goal of this library is to create an efficient and secure ad hoc aggregate and multi signature scheme. It relies on alt bn128 for curve and pairing operations. It implements hashing of arbitrary byte data to curve points, the standard BGLS scheme for aggregate signatures, and a custom multi signature scheme.

Multi Signature

The multi signature scheme is a modification of the BGLS scheme, where all signatures are on the same message. This allows verification with a constant number of pairing operations, at the cost of being insecure to chosen key attacks. To fix the chosen key attack, users are required to prove knowledge of their secret key, through the use of the Schnorr scheme applied to their public key.

Curves

Alt bn128

The group G_1 is a cyclic group of prime order on the curve Y^2 = X^3 + 3 defined over the field F_p with p = 21888242871839275222246405745257275088696311157297823662689037894645226208583.

The generator g_1 is (1,2)

Since this curve is of prime order, every non-identity point is a generator, therefore the cofactor is 1.

The group G_2 is a cyclic subgroup of the non-prime order elliptic curve Y^2 = X^3 + 3*((i + 9)^(-1)) over the field F_p^2 = F_p[X] / (X^2 + 1) (where p is the same as above). We can write our irreducible element as i. The cofactor of this group is 21888242871839275222246405745257275088844257914179612981679871602714643921549.

The generator g_2 is defined as: (11559732032986387107991004021392285783925812861821192530917403151452391805634*i + 10857046999023057135944570762232829481370756359578518086990519993285655852781, 4082367875863433681332203403145435568316851327593401208105741076214120093531*i + 8495653923123431417604973247489272438418190587263600148770280649306958101930)

Benchmarks

The following benchmarks are from a 3.80GHz i7-7700HQ CPU with 16GB ram.

For reference, the pairing operation (the slowest operation involved) takes ~14 milliseconds.

$ go test github.com/ethereum/go-ethereum/crypto/bn256 -bench .
BenchmarkPairing-8   	     100	  13845045 ns/op
PASS
ok  	github.com/ethereum/go-ethereum/crypto/bn256	1.842s
  • Signing ~2 milliseconds
  • Signature verification ~30 milliseconds, using two pairings.
  • Multi Signature verification ~30 milliseconds + ~60 microseconds per signer, two pairings + n point additions
  • Aggregate Signature verification ~15 milliseconds per signer/message pair, with n+1 pairings.
$ go test github.com/jlandrews/bgls -v -bench .
=== RUN   TestAltbnHashToCurve
--- PASS: TestAltbnHashToCurve (0.01s)
=== RUN   TestBls12Hashing
--- PASS: TestBls12Hashing (0.02s)
=== RUN   TestEthereumHash
--- PASS: TestEthereumHash (0.00s)
=== RUN   TestSingleSigner
--- PASS: TestSingleSigner (0.08s)
=== RUN   TestAggregation
--- PASS: TestAggregation (0.47s)
=== RUN   TestMultiSig
--- PASS: TestMultiSig (0.82s)
BenchmarkKeygen-8                  	     300	   4786044 ns/op
BenchmarkAltBnHashToCurve-8        	   20000	     91582 ns/op
BenchmarkSigning-8                 	    1000	   2157084 ns/op
BenchmarkVerification-8            	      50	  29335089 ns/op
BenchmarkMultiVerification64-8     	      50	  31163219 ns/op
BenchmarkMultiVerification128-8    	      50	  33080672 ns/op
BenchmarkMultiVerification256-8    	      50	  36682071 ns/op
BenchmarkMultiVerification512-8    	      30	  43788199 ns/op
BenchmarkMultiVerification1024-8   	      20	  57576500 ns/op
BenchmarkMultiVerification2048-8   	      20	  89297507 ns/op
BenchmarkAggregateVerification-8   	     100	  15325182 ns/op
PASS
ok  	github.com/jlandrews/bgls	41.946s

For comparison, the ed25519 implementation in go yields much faster key generation signing and single signature verification. At ~145 microseconds per verification, the multi signature verification is actually faster beyond ~350 signatures.

$ go test golang.org/x/crypto/ed25519 -bench .
BenchmarkKeyGeneration-8   	   30000	     51878 ns/op
BenchmarkSigning-8         	   30000	     54050 ns/op
BenchmarkVerification-8    	   10000	    145063 ns/op
PASS
ok  	golang.org/x/crypto/ed25519	5.750s
Hashing

The hashing algorithm is currently try-and-increment, and we support SHA3, Kangaroo twelve, Keccak256, and Blake2b.

We previously used a direct implementation of Indifferentiable Hashing to Barreto–Naehrig Curves using blake2b, however this was removed because this can't be implemented in the EVM due to gas costs, and will not work for BLS12-381.

Future work

  • Optimize bigint allocations.
  • Add utility operations for serialization of keys/signatures.
  • Implement a better Hashing algorithm, such as Elligator Squared
  • Integrate BLS12-381 with go bindings.
  • Abstract choice of curve in bgls.go
  • Integrations with bgls-on-evm
  • More complete usage documentation

References

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AltbnBlake2b

func AltbnBlake2b(message []byte) (p1, p2 *big.Int)

AltbnBlake2b Hashes a message to a point on Altbn128 using Blake2b and try and increment The return value is the x,y affine coordinate pair.

func AltbnG1ToCoord

func AltbnG1ToCoord(pt *bn256.G1) (x, y *big.Int)

AltbnG1ToCoord takes a point in G1 of Altbn_128, and returns its affine coordinates

func AltbnG2ToCoord

func AltbnG2ToCoord(pt *bn256.G2) (xx, xy, yx, yy *big.Int)

AltbnG2ToCoord takes a point in G2 of Altbn_128, and returns its affine coordinates

func AltbnHashToCurve

func AltbnHashToCurve(message []byte) *bn256.G1

AltbnHashToCurve Hashes a message to a point on Altbn128 using Keccak3 and try and increment This is for compatability with Ethereum hashing. The return value is the altbn_128 library's internel representation for points.

func AltbnKang12

func AltbnKang12(message []byte) (p1, p2 *big.Int)

AltbnKang12 Hashes a message to a point on Altbn128 using Blake2b and try and increment The return value is the x,y affine coordinate pair.

func AltbnKeccak3

func AltbnKeccak3(message []byte) (p1, p2 *big.Int)

AltbnKeccak3 Hashes a message to a point on Altbn128 using Keccak3 and try and increment Keccak3 is only for compatability with Ethereum hashing. The return value is the x,y affine coordinate pair.

func AltbnMkG1Point

func AltbnMkG1Point(x, y *big.Int) (*bn256.G1, bool)

AltbnMkG1Point copies points into []byte and unmarshals to get around curvePoint not being exported This is copied from bn256.G1.Marshal (modified)

func AltbnSha3

func AltbnSha3(message []byte) (p1, p2 *big.Int)

AltbnSha3 Hashes a message to a point on Altbn128 using SHA3 and try and increment The return value is the x,y affine coordinate pair.

func Bls12Blake2b

func Bls12Blake2b(message []byte) (p1, p2 *big.Int)

Bls12Blake2b Hashes a message to a point on BLS12-381 using Blake2b and try and increment The return value is the x,y affine coordinate pair.

func Bls12Kang12

func Bls12Kang12(message []byte) (p1, p2 *big.Int)

Bls12Kang12 Hashes a message to a point on BLS12-381 using Kangaroo Twelve and try and increment The return value is the x,y affine coordinate pair.

func Bls12Sha3

func Bls12Sha3(message []byte) (p1, p2 *big.Int)

Bls12Sha3 Hashes a message to a point on BLS12-381 using SHA3 and try and increment The return value is the x,y affine coordinate pair.

func CheckAuthentication

func CheckAuthentication(v *VerifyKey, a *Authentication) bool

CheckAuthentication verifies that this VerifyKey is valid

func EthereumSum256

func EthereumSum256(data []byte) (digest [32]byte)

EthereumSum256 returns the Keccak3-256 digest of the data. This is because Ethereum uses a non-standard hashing algo.

func KeyGen

func KeyGen() (*SigningKey, *VerifyKey, error)

KeyGen generates a SigningKey and VerifyKey

func LoadKey

func LoadKey(x *big.Int) (*SigningKey, *VerifyKey)

LoadKey turns secret key into SigninKey and VerifyKey

func Verify

func Verify(vk *VerifyKey, m []byte, sig *Signature) bool

Verify checks that a signature is valid

func VerifyAggregateSignature

func VerifyAggregateSignature(aggsig *Signature, keys []*VerifyKey, msgs [][]byte, allowDuplicates bool) bool

VerifyAggregateSignature verifies that the aggregated signature proves that all messages were signed by associated keys Will fail under duplicate messages, unless allow duplicates is True.

func VerifyMultiSignature

func VerifyMultiSignature(aggsig *Signature, keys []*VerifyKey, msg []byte) bool

VerifyMultiSignature checks that the aggregate signature correctly proves that a single message has been signed by a set of keys, vulnerable against chosen key attack, if keys have not been authenticated

Types

type AggSig

type AggSig struct {
	// contains filtered or unexported fields
}

AggSig holds paired sequences of keys and messages, and one signature

func (AggSig) Verify

func (a AggSig) Verify() bool

Verify checks that all messages were signed by associated keys Will fail under duplicate messages

type Authentication

type Authentication struct {
	// contains filtered or unexported fields
}

Authentication is a proof of a valid VerifyKey

func Authenticate

func Authenticate(x *SigningKey, v *VerifyKey) *Authentication

Authenticate generates an Authentication for a valid SigningKey/VerifyKey combo

type MultiSig

type MultiSig struct {
	// contains filtered or unexported fields
}

MultiSig holds set of keys and one message plus signature

func (MultiSig) Verify

func (m MultiSig) Verify() bool

Verify checks that a single message has been signed by a set of keys vulnerable against chosen key attack, if keys have not been authenticated

type Signature

type Signature struct {
	// contains filtered or unexported fields
}

Signature Wraps G1 curve point as signature

func Aggregate

func Aggregate(sigs []*Signature) *Signature

Aggregate turns a set of signatures into a single signature

type SigningKey

type SigningKey struct {
	// contains filtered or unexported fields
}

SigningKey wraps secret exponent

func (*SigningKey) Sign

func (sk *SigningKey) Sign(m []byte) *Signature

Sign creates a signature on a message with a private key

type VerifyKey

type VerifyKey struct {
	// contains filtered or unexported fields
}

VerifyKey wraps public G2 curve point

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL