Documentation ¶
Overview ¶
Package bgls implements bls signatures, as described by Short Signatures from the Weil Pairing. In this library, an aggregate signature refers to an aggregation of signatures on different messages into a single signature. A multi signature refers to an aggregation of signatures on the same message into the same signature. The difference is that a multi signature can be verified quite quickly, using 2 pairing operations regardless of the number of signers, whereas an aggregate signature requires n+1 pairing operations.
There are three different methods to protect against the rogue public key attack. The three methods are proving knowledge of secret key (kosk), enforcing that all messages are distinct (Distinct Message), and using a hash of the public keys to create exponents that are used in aggregation (Hashed Aggregation Exponents - HAE). These are all described in https://crypto.stanford.edu/~dabo/pubs/papers/BLSmultisig.html, where HAE is Dan Boneh's new method introduced in that article.
Proof of knowledge of the secret key is done in this library through doing a BLS signature on the public key itself as a message. See blsKosk.go for more details. Note that this Kosk method is not interoperable with 'plain' bls due to design choices explained in blsKosk.go
BLS with distinct messages is done in this library by prepending the public key to each message, before signing, to ensure that it each message is unique. (thereby circumventing rogue public key attacks). See blsDistinctMessage.go for more details. Note that BLS with distinct messages does not offer multi sigs in their efficiently computable form where only 2 pairings are required.
The third method for preventing the rogue public key attack is explained in in blsHAE.go, and in Boneh's paper. The method for hashing public keys to the exponents is to write them to blake2x, and then to squeeze the corresponding amount of output from the XOF.
blsKosk.go implements Knowledge of secret key (Kosk) BLS. You do a proof to show that you know the secret key. This protects against the rogue public key attack.
Proof of knowledge of the secret key is done in this library through doing a BLS signature on the public key itself as a message. There is a situation where this doesn't prove knowledge of the secret key. Suppose there is a BLS signing oracle for (pk1, sk1). Let pkA = -pk1 + x*g_2. Note that sig_pkA(pkA) = -sig_pk1(pkA) + xH(-pk1 + x*g_2) Consequently, if pk1 signs on pkA, this doesn't prove that person A knows skA and the rogue public key attack is possible as pkA is an authenticated key. One solution to fix this is to ensure that it is impossible for pk1 to sign the same pkA that is used in authentication. The way this is implemented here is to make the sign/verify methods prepend a 0x01 byte to any message that is being signed, and to make authentication prepend a null to public key before its signed. Since one would only ever authenticate their own public key, noone could get a signature from you that would work for their own authentication. (As all signatures you give out, other than your own authentication, have a 0x01 byte prepended instead of a null byte)
Prepending bytes to ensure signing / authentication domain seperation sacrifices interoperability between KoskBls and normal BLS, however the advantage is that the authentications are aggregatable. They're aggregatable, since they are BLS signatures but all on distinct messages since they are distinct public keys.
If you are using Kosk to secure against the rogue public key attack, you are intended to use: AggregateSignatures, KeyGen, KoskSign, KoskVerifySingleSignature, KoskVerifyMultiSignature KoskVerifyMultiSignatureWithMultiplicity, KoskVerifyAggregateSignature
blsDistinctMessage.go implements the method of using Distinct Messages for aggregate signatures. This ensures that no two messages are used from separate pubkeys by prepending the public key before the message, thereby preventing the rogue public key attack.
If you are using DistinctMsg to secure against the rogue public key attack, you are intended to use: AggregateSignatures, KeyGen, DistinctMsgSign, DistinctMsgVerifySingleSignature, DistinctMsgVerifyAggregateSignature
The third method in Boneh's paper is dubbed "BLS with hashed aggregation exponents(HAE)" here, and is implemented in blsHAE.go. This is normal bls, but when aggregating you hash the `n` public keys to get `n` numbers in the range [0,2^(128)). Call these numbers t_0, t_1, ... t_{n-1}. Then you scale the ith signature to the by t_i, before multiplying them together.
For Verification, you hash to obtain the same t_0, t_1, ... t_{n-1}, and scale the public keys accordingly. Then BLS proceeds as normal with these scaled public keys. Note that this method cannot aggregate pre-aggregated signatures. (I.e. you can only aggregate once), and it also requires inputing the keys into the hash function in the same order.
The hash function from G^n \to \R^n is blake2x. The uncompressed marshal of every key is written to then blake2x instance. Then n 16 byte numbers are read from the XOF, each corresponding to a value of t.
Note. I am calling this Hashed Aggregation Exponents in lieu of a better name for this defense against the rogue public key attack.
If you are using HAE to secure against the rogue public key attack, you are intended to use: KeyGen, Sign, VerifySingleSignature, AggregateSignaturesWithHAE, VerifyMultiSignatureWithHAE, VerifyAggregateSignatureWithHAE
Index ¶
- func AggregateKeys(keys []Point) Point
- func AggregateSignatures(sigs []Point) Point
- func AggregateSignaturesWithHAE(sigs []Point, pubkeys []Point) Point
- func AmsAggregateMembershipKeyShares(curve CurveSystem, shares []Point) Point
- func AmsCombineSignatureShares(pubkeys []Point, sigs []Point) (aggKey Point, aggSig Point)
- func AmsCreateMembershipKeyShares(curve CurveSystem, sk *big.Int, curIndex int, pubkeys []Point) []Point
- func AmsCreateMembershipKeySharesKnownExp(curve CurveSystem, sk *big.Int, apk Point, exp *big.Int, numSigners int) []Point
- func AmsCreateSignatureShare(curve CurveSystem, sk *big.Int, membershipKey Point, msg []byte) Point
- func AmsVerifySignature(curve CurveSystem, apk Point, signers []int, aggKey Point, aggSig Point, ...) bool
- func AmsVerifySignatureWithSetCheck(curve CurveSystem, check func([]int) bool, apk Point, signers []int, ...) bool
- func AmspGetMessage(curve CurveSystem, pubkeys []Point, msg []byte) []byte
- func Authenticate(curve CurveSystem, sk *big.Int) Point
- func AuthenticateCustHash(curve CurveSystem, sk *big.Int, hash func([]byte) Point) Point
- func CheckAuthentication(curve CurveSystem, pubkey Point, authentication Point) bool
- func CheckAuthenticationCustHash(curve CurveSystem, pubkey Point, authentication Point, hash func([]byte) Point) bool
- func DistinctMsgSign(curve CurveSystem, sk *big.Int, m []byte) Point
- func DistinctMsgSignCustHash(curve CurveSystem, sk *big.Int, msg []byte, hash func([]byte) Point) Point
- func DistinctMsgVerifyAggregateSignature(curve CurveSystem, aggsig Point, keys []Point, msgs [][]byte) bool
- func DistinctMsgVerifySingleSignature(curve CurveSystem, sig Point, pubkey Point, m []byte) bool
- func KeyGen(curve CurveSystem) (*big.Int, Point, error)
- func KoskSign(curve CurveSystem, sk *big.Int, msg []byte) Point
- func KoskSignCustHash(curve CurveSystem, sk *big.Int, msg []byte, hash func([]byte) Point) Point
- func KoskVerifyAggregateSignature(curve CurveSystem, aggsig Point, keys []Point, msgs [][]byte) bool
- func KoskVerifyBatchMultiSignature(curve CurveSystem, aggsigs []Point, pubkeys [][]Point, msgs [][]byte) bool
- func KoskVerifyMultiSignature(curve CurveSystem, aggsig Point, keys []Point, msg []byte) bool
- func KoskVerifyMultiSignatureWithMultiplicity(curve CurveSystem, aggsig Point, keys []Point, multiplicity []int64, ...) bool
- func KoskVerifySingleSignature(curve CurveSystem, sig Point, pubKey Point, msg []byte) bool
- func KoskVerifySingleSignatureCustHash(curve CurveSystem, pubKey Point, msg []byte, sig Point, ...) bool
- func LoadPublicKey(curve CurveSystem, sk *big.Int) Point
- func Sign(curve CurveSystem, sk *big.Int, msg []byte) Point
- func SignCustHash(sk *big.Int, msg []byte, hash func([]byte) Point) Point
- func VerifyAggregateSignature(curve CurveSystem, aggsig Point, keys []Point, msgs [][]byte) bool
- func VerifyAggregateSignatureWithHAE(curve CurveSystem, aggsig Point, pubkeys []Point, msgs [][]byte) bool
- func VerifyBatchMultiSignatureWithHAE(curve CurveSystem, aggsigs []Point, aggpubkeys []Point, msgs [][]byte, ...) bool
- func VerifyMultiSignatureWithHAE(curve CurveSystem, aggsig Point, pubkeys []Point, msg []byte) bool
- func VerifySingleSignature(curve CurveSystem, sig Point, pubKey Point, msg []byte) bool
- func VerifySingleSignatureCustHash(curve CurveSystem, sig Point, pubkey Point, msg []byte, ...) bool
- type AggSig
- type MultiSig
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AggregateKeys ¶
func AggregateKeys(keys []Point) Point
AggregateKeys sums an array of public keys into one key. This wrapper only exists so end-users don't have to use the method from curve
func AggregateSignatures ¶
func AggregateSignatures(sigs []Point) Point
AggregateSignatures aggregates an array of signatures into one aggsig. This wrapper only exists so end-users don't have to use the method from curves
func AggregateSignaturesWithHAE ¶
func AggregateSignaturesWithHAE(sigs []Point, pubkeys []Point) Point
AggregateSignaturesWithHAE aggregates the signatures, using the hashed exponents derived from the pubkeys to protect against the rogue public key attack.
func AmsAggregateMembershipKeyShares ¶ added in v0.5.2
func AmsAggregateMembershipKeyShares(curve CurveSystem, shares []Point) Point
func AmsCombineSignatureShares ¶ added in v0.5.2
func AmsCombineSignatureShares(pubkeys []Point, sigs []Point) (aggKey Point, aggSig Point)
func AmsCreateMembershipKeyShares ¶ added in v0.5.2
func AmsCreateMembershipKeySharesKnownExp ¶ added in v0.5.2
func AmsCreateSignatureShare ¶ added in v0.5.2
func AmsVerifySignature ¶ added in v0.5.2
func AmsVerifySignatureWithSetCheck ¶ added in v0.5.2
func AmspGetMessage ¶ added in v0.5.2
func Authenticate ¶
Authenticate generates an Aggregatable Authentication for a given secret key. It signs the public key generated from sk, with a 0x01 byte prepended to it.
func AuthenticateCustHash ¶
AuthenticateCustHash generates an Aggregatable Authentication for a given secret key. It signs the public key generated from sk, with a null byte prepended to it. This runs with the specified hash function.
func CheckAuthentication ¶
func CheckAuthentication(curve CurveSystem, pubkey Point, authentication Point) bool
CheckAuthentication verifies that the provided signature is in fact authentication for this public key.
func CheckAuthenticationCustHash ¶
func CheckAuthenticationCustHash(curve CurveSystem, pubkey Point, authentication Point, hash func([]byte) Point) bool
CheckAuthenticationCustHash verifies that the provided signature is in fact authentication for this public key.
func DistinctMsgSign ¶
DistinctMsgSign creates a signature on a message with a private key, with prepending the public key to the message.
func DistinctMsgSignCustHash ¶
func DistinctMsgSignCustHash(curve CurveSystem, sk *big.Int, msg []byte, hash func([]byte) Point) Point
DistinctMsgSignCustHash creates a signature on a message with a private key, using a supplied function to hash to g1.
func DistinctMsgVerifyAggregateSignature ¶
func DistinctMsgVerifyAggregateSignature(curve CurveSystem, aggsig Point, keys []Point, msgs [][]byte) bool
DistinctMsgVerifyAggregateSignature checks that an aggsig was generated from the the provided set of public key / msg pairs, when the messages are signed using the 'Distinct Message' method.
func DistinctMsgVerifySingleSignature ¶
DistinctMsgVerifySingleSignature checks that a single 'Distinct Message' signature is valid
func KeyGen ¶
KeyGen generates a private / public key pair. The private key is a big int, and the the public key is on G2.
func KoskSign ¶
KoskSign creates a kosk signature on a message with a private key. A kosk signature prepends a 0x01 byte to the message before signing.
func KoskSignCustHash ¶
KoskSignCustHash creates a kosk signature on a message with a private key, using a supplied function to hash to point. A kosk signature prepends a 0x01 byte to the message before signing.
func KoskVerifyAggregateSignature ¶
func KoskVerifyAggregateSignature(curve CurveSystem, aggsig Point, keys []Point, msgs [][]byte) bool
KoskVerifyAggregateSignature verifies that the aggregated signature proves that all messages were signed by the associated keys.
func KoskVerifyBatchMultiSignature ¶ added in v0.5.2
func KoskVerifyBatchMultiSignature(curve CurveSystem, aggsigs []Point, pubkeys [][]Point, msgs [][]byte) bool
KoskVerifyBatchMultiSignature checks that the set of aggregate signatures correctly proves that a set of messages has the correct associated pubkey. vulnerable against chosen key attack, if keys have not been authenticated This is faster than verifying each multisignature individually.
func KoskVerifyMultiSignature ¶
KoskVerifyMultiSignature 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
func KoskVerifyMultiSignatureWithMultiplicity ¶
func KoskVerifyMultiSignatureWithMultiplicity(curve CurveSystem, aggsig Point, keys []Point, multiplicity []int64, msg []byte) bool
KoskVerifyMultiSignatureWithMultiplicity verifies a BLS multi signature where multiple copies of each signature may have been included in the aggregation
func KoskVerifySingleSignature ¶
KoskVerifySingleSignature checks that a single kosk signature is valid.
func KoskVerifySingleSignatureCustHash ¶
func KoskVerifySingleSignatureCustHash(curve CurveSystem, pubKey Point, msg []byte, sig Point, hash func([]byte) Point) bool
KoskVerifySingleSignatureCustHash checks that a single kosk signature is valid, with the supplied hash function.
func LoadPublicKey ¶
LoadPublicKey turns secret key into a public key of type Point2
func SignCustHash ¶
SignCustHash creates a standard BLS signature on a message with a private key, using a supplied function to hash onto the curve where signatures lie.
func VerifyAggregateSignature ¶
VerifyAggregateSignature verifies that the aggregated signature proves that all messages were signed by the associated keys. This will fail if there are duplicate messages, due to the possibility of the rogue public-key attack. If duplicate messages should be allowed, one of the protections against the rogue public-key attack should be used. See doc.go for more details.
func VerifyAggregateSignatureWithHAE ¶
func VerifyAggregateSignatureWithHAE(curve CurveSystem, aggsig Point, pubkeys []Point, msgs [][]byte) bool
VerifyAggregateSignatureWithHAE verifies signatures of different messages aggregated with HAE.
func VerifyBatchMultiSignatureWithHAE ¶ added in v0.5.2
func VerifyBatchMultiSignatureWithHAE(curve CurveSystem, aggsigs []Point, aggpubkeys []Point, msgs [][]byte, allowDups bool) bool
VerifyBatchMultiSignatureWithHAE verifies multiple MultiSignatures are valid, in time faster than verifying each multisignature individually.
func VerifyMultiSignatureWithHAE ¶
VerifyMultiSignatureWithHAE verifies signatures of the same message aggregated with HAE.
func VerifySingleSignature ¶
VerifySingleSignature checks that a single standard BLS signature is valid
func VerifySingleSignatureCustHash ¶
func VerifySingleSignatureCustHash(curve CurveSystem, sig Point, pubkey Point, msg []byte, hash func([]byte) Point) bool
VerifySingleSignatureCustHash checks that a single standard BLS signature is valid, using the supplied hash function to hash onto the curve where signatures lie.
Types ¶
type AggSig ¶
type AggSig struct {
// contains filtered or unexported fields
}
AggSig holds paired sequences of keys and messages, and one signature