- The public key and the signatures are encoded as single group elements.
- Verification requires 2 pairing operations.
- A collection of signatures (signature_1, ..., signature_n) can be aggregated into a single signature. Moreover, the aggregate signature can be verified using only n+1 pairings (as opposed to 2n pairings, when verifying n signatures separately).

Authentication and integrity for Public Key Infrastructure (PKI) and blockchains. - The usage is similar to classical digital signatures, such as ECDSA.

Aggregating signature chains for PKI and Secure Border Gateway Protocol (SBGP). - Concretely, in a PKI signature chain of depth n, we have n signatures by n certificate authorities on n distinct certificates. Similarly, in SBGP, each router receives a list of n signatures attesting to a path of length n in the network. In both settings, using the BLS signature scheme would allow us to aggregate the n signatures into a single signature.

consensus protocols for blockchains. - There, BLS signatures are used for authenticating transactions as well as votes during the consensus protocol, and the use of aggregation significantly reduces the bandwidth and storage requirements.

The remainder of this section defines terminology and the high-level API. defines primitive operations used in the BLS signature scheme. These operations MUST NOT be used alone. defines three BLS Signature schemes giving slightly different security and performance properties. defines the format for a ciphersuites and gives recommended ciphersuites. The appendices give test vectors, etc.

SK: The secret key for the signature scheme. PK: The public key for the signature scheme. message: The input to be signed by the signature scheme. signature: The digital signature output. aggregation: Given a list of signatures for a list of messages and public keys, an aggregation algorithm generates one signature that authenticates the same list of messages and public keys. rogue key attack: An attack in which a specially crafted public key (the "rogue" key) is used to forge an aggregated signature. specifies methods for securing against rogue key attacks.

a || b denotes the concatenation of octet strings a and b. A pairing-friendly elliptic curve defines the following primitives (see for detailed discussion): E1, E2: elliptic curve groups defined over finite fields. This document assumes that E1 has a more compact representation than E2, i.e., because E1 is defined over a smaller field than E2. G1, G2: subgroups of E1 and E2 (respectively) having prime order r. P1, P2: distinguished points that generate G1 and G2, respectively. GT: a subgroup, of prime order r, of the multiplicative group of a field extension. e : G1 x G2 -> GT: a non-degenerate bilinear map.

For the above pairing-friendly curve, this document writes operations in E1 and E2 in additive notation, i.e., P + Q denotes point addition and x * P denotes scalar multiplication. Operations in GT are written in multiplicative notation, i.e., a * b is field multiplication.

For each of E1 and E2 defined by the above pairing-friendly curve, we assume that the pairing-friendly elliptic curve definition provides several primitives, described below. Note that these primitives are named generically. When referring to one of these primitives for a specific group, this document appends the name of the group, e.g., point_to_octets_E1, subgroup_check_E2, etc. point_to_octets(P) -> ostr: returns the canonical representation of the point P as an octet string. This operation is also known as serialization. octets_to_point(ostr) -> P: returns the point P corresponding to the canonical representation ostr, or INVALID if ostr is not a valid output of point_to_octets. This operation is also known as deserialization. subgroup_check(P) -> VALID or INVALID: returns VALID when the point P is an element of the subgroup of order r, and INVALID otherwise. This function can always be implemented by checking that r * P is equal to the identity element. In some cases, faster checks may also exist, e.g., .

I2OSP and OS2IP are the functions defined in , Section 4. hash_to_point(ostr) -> P: a cryptographic hash function that takes as input an arbitrary octet string and returns a point on an elliptic curve. Functions of this kind are defined in . Each of the ciphersuites in specifies the hash_to_point algorithm to be used.

KeyGen(IKM) -> SK: a key generation algorithm that takes as input an octet string comprising secret keying material, and outputs a secret key SK. SkToPk(SK) -> PK: an algorithm that takes as input a secret key and outputs the corresponding public key. Sign(SK, message) -> signature: a signing algorithm that generates a deterministic signature given a secret key SK and a message. Verify(PK, message, signature) -> VALID or INVALID: a verification algorithm that outputs VALID if signature is a valid signature of message under public key PK, and INVALID otherwise. Aggregate((signature_1, ..., signature_n)) -> signature: an aggregation algorithm that aggregates a collection of signatures into a single signature. AggregateVerify((PK_1, ..., PK_n), (message_1, ..., message_n), signature) -> VALID or INVALID: an aggregate verification algorithm that outputs VALID if signature is a valid aggregated signature for a collection of public keys and messages, and outputs INVALID otherwise.

Minimal-signature-size: signatures are points in G1, public keys are points in G2. (Recall from that E1 has a more compact representation than E2.) Minimal-pubkey-size: public keys are points in G1, signatures are points in G2. Implementations using signature aggregation SHOULD use this approach, since the size of (PK_1, ..., PK_n, signature) is dominated by the public keys even for small n.

A signature variant, either minimal-signature-size or minimal-pubkey-size. These are defined in . A pairing-friendly elliptic curve, plus associated functionality given in . H, a hash function that MUST be a secure cryptographic hash function, e.g., SHA-256 . For security, H MUST output at least ceil(log2(r)) bits, where r is the order of the subgroups G1 and G2 defined by the pairing-friendly elliptic curve. hash_to_point, a function whose interface is described in . When the signature variant is minimal-signature-size, this function MUST output a point in G1. When the signature variant is minimal-pubkey size, this function MUST output a point in G2. For security, this function MUST be either a random oracle encoding or a nonuniform encoding, as defined in .

P, an elliptic curve point. When the signature variant is minimal-signature-size, P is the distinguished point P2 that generates the group G2 (see ). When the signature variant is minimal-pubkey-size, P is the distinguished point P1 that generates the group G1. r, the order of the subgroups G1 and G2 defined by the pairing-friendly curve. pairing, a function that invokes the function e of , with argument order depending on signature variant: For minimal-signature-size: pairing(U, V) := e(U, V) For minimal-pubkey-size: pairing(U, V) := e(V, U)

point_to_pubkey and point_to_signature, functions that invoke the appropriate serialization routine ( ) depending on signature variant: For minimal-signature-size: point_to_pubkey(P) := point_to_octets_E2(P) point_to_signature(P) := point_to_octets_E1(P) For minimal-pubkey-size: point_to_pubkey(P) := point_to_octets_E1(P) point_to_signature(P) := point_to_octets_E2(P)

pubkey_to_point and signature_to_point, functions that invoke the appropriate deserialization routine ( ) depending on signature variant: For minimal-signature-size: pubkey_to_point(ostr) := octets_to_point_E2(ostr) signature_to_point(ostr) := octets_to_point_E1(ostr) For minimal-pubkey-size: pubkey_to_point(ostr) := octets_to_point_E1(ostr) signature_to_point(ostr) := octets_to_point_E2(ostr)

pubkey_subgroup_check and signature_subgroup_check, functions that invoke the appropriate subgroup check routine ( ) depending on signature variant: For minimal-signature-size: pubkey_subgroup_check(P) := subgroup_check_E2(P) signature_subgroup_check(P) := subgroup_check_E1(P) For minimal-pubkey-size: pubkey_subgroup_check(P) := subgroup_check_E1(P) signature_subgroup_check(P) := subgroup_check_E2(P)

PopProve(SK) -> proof: an algorithm that generates a proof of possession for the public key corresponding to secret key SK. PopVerify(PK, proof) -> VALID or INVALID: an algorithm that outputs VALID if proof is valid for PK, and INVALID otherwise. FastAggregateVerify((PK_1, ..., PK_n), message, signature) -> VALID or INVALID: a verification algorithm for the aggregate of multiple signatures on the same message. This function is faster than AggregateVerify.

hash_pubkey_to_point(PK) -> P: a cryptographic hash function that takes as input a public key and outputs a point in the same subgroup as the hash_to_point algorithm used to instantiate the core operations. For security, this function MUST be domain separated from the hash_to_point function. In addition, this function MUST be either a random oracle encoding or a nonuniform encoding, as defined in . The RECOMMENDED way of instantiating hash_pubkey_to_point is to use the same hash-to-curve function as hash_to_point, with a different domain separation tag (see , Section 3.1). discusses the RECOMMENDED way to construct the domain separation tag.

ID: the ciphersuite ID, an ASCII string. The REQUIRED format for this string is "BLS_SIG_" || H2C_SUITE_ID || SC_TAG || "_" Strings in double quotes are ASCII-encoded literals. H2C_SUITE_ID is the suite ID of the hash-to-curve suite used to define the hash_to_point and hash_pubkey_to_point functions. SC_TAG is a string indicating the scheme and, optionally, additional information. The first three characters of this string MUST chosen as follows: - "NUL" if SC is basic,
- "AUG" if SC is message-augmentation, or
- "POP" if SC is proof-of-possession.
- Other values MUST NOT be used.

SC_TAG MAY be used to encode other information about the ciphersuite, for example, a version number. When used in this way, SC_TAG MUST contain only ASCII characters between 0x21 and 0x7e (inclusive), except that it MUST NOT contain underscore (0x5f). The RECOMMENDED way to add user-defined information to SC_TAG is to append a colon (':', ASCII 0x3a) and then the informational string. For example, "NUL:version=2" is an appropriate SC_TAG value.

Note that hash-to-curve suite IDs always include a trailing underscore, so no field separator is needed between H2C_SUITE_ID and SC_TAG. SC: the scheme, one of basic, message-augmentation, or proof-of-possession. SV: the signature variant, either minimal-signature-size or minimal-pubkey-size. EC: a pairing-friendly elliptic curve, plus all associated functionality ( ). H: a cryptographic hash function. hash_to_point: a hash from arbitrary strings to elliptic curve points. hash_to_point MUST be defined in terms of a hash-to-curve suite . The RECOMMENDED hash-to-curve domain separation tag is the ciphersuite ID string defined above. hash_pubkey_to_point (only specified when SC is proof-of-possession): a hash from serialized public keys to elliptic curve points. hash_pubkey_to_point MUST be defined in terms of a hash-to-curve suite . The hash-to-curve domain separation tag MUST be distinct from the domain separation tag used for hash_to_point. It is RECOMMENDED that the domain separation tag be constructed similarly to the ciphersuite ID string, namely: "BLS_POP_" || H2C_SUITE_ID || SC_TAG || "_"

SC: basic SV: minimal-signature-size EC: BLS12-381, as defined in . H: SHA-256 hash_to_point: BLS12381G1_XMD:SHA-256_SSWU_RO_ with the ASCII-encoded domain separation tag BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_

SV: minimal-pubkey-size hash_to_point: BLS12381G2_XMD:SHA-256_SSWU_RO_ with the ASCII-encoded domain separation tag BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_

SC: message-augmentation SV: minimal-signature-size EC: BLS12-381, as defined in . H: SHA-256 hash_to_point: BLS12381G1_XMD:SHA-256_SSWU_RO_ with the ASCII-encoded domain separation tag BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_AUG_

SV: minimal-pubkey-size hash_to_point: BLS12381G2_XMD:SHA-256_SSWU_RO_ with the ASCII-encoded domain separation tag BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_AUG_

SC: proof-of-possession SV: minimal-signature-size EC: BLS12-381, as defined in . H: SHA-256 hash_to_point: BLS12381G1_XMD:SHA-256_SSWU_RO_ with the ASCII-encoded domain separation tag BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_ hash_pubkey_to_point: BLS12381G1_XMD:SHA-256_SSWU_RO_ with the ASCII-encoded domain separation tag BLS_POP_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_

SV: minimal-pubkey-size hash_to_point: BLS12381G2_XMD:SHA-256_SSWU_RO_ with the ASCII-encoded domain separation tag BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ hash_pubkey_to_point: BLS12381G2_XMD:SHA-256_SSWU_RO_ with the ASCII-encoded domain separation tag BLS_POP_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_

For most pairing-friendly elliptic curves used in practice, the pairing operation e ( ) is undefined when its input points are not in the prime-order subgroups of E1 and E2. The resulting behavior is unpredictable, and may enable forgeries. Even if the pairing operation behaves properly on inputs that are outside the correct subgroups, skipping the subgroup check breaks the strong unforgeability property .

Algorand: bls_sigs_ref .Chia: spec python/C++ . Here, they are swapping G1 and G2 so that the public keys are small, and the benefits of avoiding a membership check during signature verification would even be more substantial. The current implementation does not seem to implement the membership check. Chia uses the Fouque-Tibouchi hashing to the curve, which can be done in constant time.Dfinity: go BLS . The current implementations do not seem to implement the membership check.Ethereum 2.0: spec .

Pairing-friendly curves, Pairing-based Identity-Based Encryption IEEE 1363.3 .Identity-Based Cryptography Standard rfc5901 .Hashing to Elliptic Curves , in order to implement the hash function hash_to_point. EdDSA rfc8032 .

E1, G1: the curve E and its order-r subgroup. E2, G2: the curve E' and its order-r subgroup. GT: the subgroup G_T. P1: the point BP. P2: the point BP'. e: the optimal Ate pairing defined in Appendix A of . point_to_octets and octets_to_point use the compressed serialization formats for E1 and E2 defined by . subgroup_check MAY use either the naive check described in or the optimized checks given by or .