bgls

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Feb 28, 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   TestEthereumHash
--- PASS: TestEthereumHash (0.00s)
=== RUN   TestSingleSigner
--- PASS: TestSingleSigner (0.10s)
=== RUN   TestAggregation
--- PASS: TestAggregation (0.48s)
=== RUN   TestMultiSig
--- PASS: TestMultiSig (0.81s)
=== RUN   TestKnownCases
--- PASS: TestKnownCases (0.08s)
BenchmarkKeygen-8                  	     300	   4610235 ns/op
BenchmarkAltBnHashToCurve-8        	   20000	     91348 ns/op
BenchmarkSigning-8                 	    1000	   2201775 ns/op
BenchmarkVerification-8            	      50	  30001975 ns/op
BenchmarkMultiVerification64-8     	      50	  32210135 ns/op
BenchmarkMultiVerification128-8    	      50	  33022116 ns/op
BenchmarkMultiVerification256-8    	      50	  37648131 ns/op
BenchmarkMultiVerification512-8    	      30	  45162677 ns/op
BenchmarkMultiVerification1024-8   	      20	  59932214 ns/op
BenchmarkMultiVerification2048-8   	      20	  90268680 ns/op
BenchmarkAggregateVerification-8   	     100	  15534821 ns/op
PASS
ok  	github.com/jlandrews/bgls	42.092s

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. This was removed because it can't be implemented in the EVM due to gas costs, and because it 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.
  • Integrations with bgls-on-evm.
  • Add tests to show that none of the functions mutate data.
  • 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 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 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 CheckAuthentication

func CheckAuthentication(curve CurveSystem, v *VerifyKey, authentication *Signature) bool

CheckAuthentication verifies that this VerifyKey is valid

func CheckAuthenticationCustHash added in v0.2.0

func CheckAuthenticationCustHash(curve CurveSystem, v *VerifyKey, authentication *Signature, hash func([]byte) Point1) bool

CheckAuthenticationCustHash verifies that this VerifyKey is valid, with the specified hash function

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(curve CurveSystem) (*SigningKey, *VerifyKey, error)

KeyGen generates a SigningKey and VerifyKey

func LoadKey

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

LoadKey turns secret key into SigninKey and VerifyKey

func Verify

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

Verify checks that a signature is valid

func VerifyAggregateSignature

func VerifyAggregateSignature(curve CurveSystem, 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 VerifyCustHash added in v0.2.0

func VerifyCustHash(curve CurveSystem, vk *VerifyKey, m []byte, sig *Signature, hash func([]byte) Point1) bool

Verify checks that a signature is valid

func VerifyMultiSignature

func VerifyMultiSignature(curve CurveSystem, 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(curve CurveSystem) 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

type CurveSystem added in v0.2.0

type CurveSystem interface {
	Pair(Point1, Point2) (PointT, bool)
	MakeG1Point(*big.Int, *big.Int) (Point1, bool)

	CopyG1(Point1) Point1
	CopyG2(Point2) Point2
	CopyGT(PointT) PointT

	MarshalG1(Point1) []byte
	MarshalG2(Point2) []byte
	MarshalGT(PointT) []byte

	G1Add(Point1, Point1) (Point1, bool)
	G1Mul(*big.Int, Point1) (Point1, bool)
	G1Equals(Point1, Point1) bool
	GetG1() Point1
	HashToG1(message []byte) Point1

	G2Add(Point2, Point2) (Point2, bool)
	G2Mul(*big.Int, Point2) (Point2, bool)
	G2Equals(Point2, Point2) bool
	GetG2() Point2

	GTAdd(PointT, PointT) (PointT, bool)
	GTMul(*big.Int, PointT) (PointT, bool)
	GTEquals(PointT, PointT) bool
	// contains filtered or unexported methods
}

CurveSystem is a set of parameters and functions for a pairing based cryptosystem It has everything necessary to support all bgls functionality which we use.

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(curve CurveSystem) 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 Point1 added in v0.2.0

type Point1 interface {
	// contains filtered or unexported methods
}

Point1 is a way to represent a point on G1, in the first elliptic curve.

type Point2 added in v0.2.0

type Point2 interface {
}

Point2 is a way to represent a point on G2, in the first elliptic curve.

type PointT added in v0.2.0

type PointT interface {
}

PointT is a way to represent a point on GT, in the first elliptic curve.

type Signature

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

Signature Wraps G1 curve point as signature

func Aggregate

func Aggregate(curve CurveSystem, sigs []*Signature) *Signature

Aggregate turns a set of signatures into a single signature

func Authenticate

func Authenticate(curve CurveSystem, x *SigningKey, v *VerifyKey) *Signature

Authenticate generates an Authentication for a valid SigningKey/VerifyKey combo It signs a verification key with x.

func AuthenticateCustHash added in v0.2.0

func AuthenticateCustHash(curve CurveSystem, x *SigningKey, v *VerifyKey, hash func([]byte) Point1) *Signature

AuthenticateCustHash generates an Authentication for a valid SigningKey/VerifyKey combo It signs a verification key with x. This runs with the specified hash function.

type SigningKey

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

SigningKey wraps secret exponent

func (*SigningKey) Sign

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

Sign creates a signature on a message with a private key

func (*SigningKey) SignCustHash added in v0.2.0

func (sk *SigningKey) SignCustHash(curve CurveSystem, m []byte, hash func([]byte) Point1) *Signature

SignCustHash creates a signature on a message with a private key, using a supplied function to hash to g1.

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