├── .gitignore ├── Makefile ├── poc ├── Makefile ├── pairing.sage ├── hash_to_base.sage ├── hash_to_base.py ├── fouquetibouchi.sage ├── utils.py ├── map2curve_ft.sage ├── map2curve_ft.py └── map2curve_ft.sage.py ├── resources.md ├── minutes ├── minutes-aug12-19.md ├── minutes-jun24-19.md ├── minutes-july15-19.md ├── minutes-apr11-19.md └── spec-v1.md ├── plans.md ├── README.md └── old_versions ├── draft-boneh-bls-signature-01.md ├── draft-boneh-bls-signature.md └── draft-irtf-cfrg-bls-signature-00.xml /.gitignore: -------------------------------------------------------------------------------- 1 | draft.txt 2 | draft.xml 3 | draft.html 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: draft.txt draft.html 2 | 3 | draft.xml: draft-irtf-cfrg-bls-signature.md 4 | mmark draft-irtf-cfrg-bls-signature.md > draft.xml 5 | 6 | draft.txt: draft.xml 7 | xml2rfc --text draft.xml 8 | 9 | draft.html: draft.xml 10 | xml2rfc --html --no-external-js draft.xml -o draft.html 11 | 12 | clean: 13 | rm -f draft.txt draft.html draft.xml 14 | -------------------------------------------------------------------------------- /poc/Makefile: -------------------------------------------------------------------------------- 1 | %.py: %.sage 2 | sage -preparse $< 3 | mv $<.py $@ 4 | 5 | all: hash_to_base.py\ 6 | map2curve_ft.py 7 | 8 | 9 | test_fouquetibouchi: 10 | sage fouquetibouchi.sage 11 | test_ft_bls12_381: 12 | sage map2curve_ft.sage 13 | test_hash_to_base: 14 | sage hash_to_base.sage 15 | 16 | test: all 17 | test_fouquetibouchi \ 18 | test_ft_bls12_381 \ 19 | 20 | clean: 21 | rm -f *.sage.py 22 | -------------------------------------------------------------------------------- /poc/pairing.sage: -------------------------------------------------------------------------------- 1 | p = 7549; A = 0; B = 1; n = 157; k = 6; t = 14 2 | F = GF(p); E = EllipticCurve(F, [A, B]) 3 | R. = F[]; K. = GF(p^k, modulus=x^k+2) 4 | EK = E.base_extend(K) 5 | P = EK(3050, 5371); Q = EK(6908*a^4, 3231*a^3) 6 | P.ate_pairing(Q, n, k, t) 7 | 8 | s = Integer(randrange(1, n)) 9 | (s*P).ate_pairing(Q, n, k, t) == P.ate_pairing(s*Q, n, k, t) 10 | P.ate_pairing(s*Q, n, k, t) == P.ate_pairing(Q, n, k, t)^s 11 | -------------------------------------------------------------------------------- /resources.md: -------------------------------------------------------------------------------- 1 | 2 | # Resources 3 | 4 | ## Implementations 5 | 6 | * [Unofficial Reference Implementation](https://github.com/kwantam/bls_sigs_ref) (Riad S. Wahby) 7 | * [Sigma Prime](https://github.com/sigp/milagro_bls/tree/experimental/src/test_vectors) (Kirk) 8 | 9 | ## Related Drafts 10 | 11 | * [Hashing to Curves](https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve) 12 | * [Pairing-Friendly Curves](https://github.com/pairingwg/pfc_standard) 13 | 14 | ## Additional Proposals 15 | 16 | * [serialization](https://github.com/pairingwg/bls_standard/issues/16) format for BLS12-381 17 | * [fast verification](https://ethresear.ch/t/fast-verification-of-multiple-bls-signatures/5407) of multiple signatures 18 | -------------------------------------------------------------------------------- /minutes/minutes-aug12-19.md: -------------------------------------------------------------------------------- 1 | # Meeting notes August 12, 2019 2 | 3 | * Attendees: 4 | Bram Cohen, 5 | Carl Beekhuizen, 6 | Dan Middleton, 7 | Hoeteck Wee, 8 | Justin Drake, 9 | Mike Lodder, 10 | Sergey Gorbunov, 11 | Victor Servant, 12 | Zaki Manian, 13 | zhenfei Zhang, 14 | 15 | ------ 16 | 17 | Hoeteck: update of the new cfrg draft 18 | * link: https://github.com/cfrg/draft-irtf-cfrg-bls-signature/blob/master/draft-irtf-cfrg-bls-signature-00.txt 19 | * changes since last version: 20 | * rely on hash to curve draft on hash into groups 21 | * used as a black box 22 | * arbitrary length messages 23 | * hash to curve function will rehash the message 24 | * uses HKDF for hash into groups and secret key derivation during key generation 25 | * serialization - follows pairing-friendly draft; uses zkcrypto's encoding 26 | 27 | Justin: hashing pk during proof of possession uses a different domain separator; need to be specific about this separator 28 | 29 | Hoeteck: will checks this issue 30 | 31 | 32 | ------ 33 | Bram: shall we standardize hierarchical key derivation for BLS secret keys (with a different approach than Bitcoin's)? 34 | 35 | Carl: is working on this; make sense to also use hkdf following this standard 36 | 37 | discussion to be continued on Telegram channel 38 | 39 | ------ 40 | Justin: quantum safe back up - a master seed to derive both a seed for bls sk and a seed for Hash-based signatures 41 | 42 | Bram: hash a seed to the sk; reveal the sk, and generate a zk proof between the seed and the sk 43 | 44 | Justin & Bram: discussion on mitigations against quantum apocalypse. Discussion to be continued on Telegram channel 45 | 46 | 47 | Sergey: Is there a good implementation of Lamport signature? 48 | 49 | Bram: No good source 50 | 51 | Sergey: Will Ethereum deploy BLS with quantum safe backups? 52 | 53 | Justin: there are two pks in Ethereum, a hot secret key and a cold secret key; target deploying quantum safety for cold 54 | secret key along with bls signature this October 55 | 56 | --- 57 | 58 | 59 | Zhenfei: updates on Riad's code 60 | * Use zkcrypto's serialization method 61 | * Use hkdf during hash to group and key generation 62 | * todos: 63 | * Signature aggregation and verification 64 | * Proof of possession 65 | 66 | Justin: which POP identifier will be used? 67 | 68 | Sergey: it will be taken care of with the ciphersuite identifier 69 | -------------------------------------------------------------------------------- /poc/hash_to_base.sage: -------------------------------------------------------------------------------- 1 | import hashlib 2 | from utils import * 3 | 4 | # Format the input as `"h2b" || label || len(x) || x` (where || is concatenation) 5 | # Since label is a fixed string, and len(x) is fixed to 4 bytes, 6 | # this encoding is unambiguous 7 | def format_input(label, x): 8 | return "h2b%s%s%s" % (label, i2osp(len(x), 4), x) 9 | 10 | # Hash bytestring input to a field element. 11 | def hash_to_base(x, H, hbits, p, label): 12 | assert type(x) is bytes 13 | F = GF(p) 14 | min_bits = floor(log(p, 2).n()) + 1 15 | assert hbits >= min_bits, "Need at least %d bits to hash p. H only outputs %d" % (min_bits, hbits) 16 | xin = format_input(label, x) # concatenate inputs 17 | print "xin" 18 | for i in xin: 19 | print ord(i), 20 | print "" 21 | h = H() 22 | h.update(xin) 23 | t1 = h.digest() 24 | for i in range(64): 25 | print ord(t1[i]), 26 | t1 = os2ip(t1) # recover integer from hash output 27 | print "t1", t1 28 | # s = t1 >> (hbits - 1) 29 | t2 = t1 & ((1 << hbits) - 1) 30 | print "t2", t2 31 | t3 = ZZ(t2) 32 | print "t3", t3 33 | y = t3 % p 34 | return F(y) 35 | 36 | # Helper function to extract parameters from a ciphersuite label 37 | def h2b_from_label(label, x): 38 | cs = Ciphersuite(label) 39 | H = cs.hash.H 40 | hbits = cs.hash.hbits() 41 | p = cs.curve.p 42 | 43 | value = hash_to_base(x, H, hbits, p, label) 44 | if len(x) == 0 and DEBUG: 45 | print("hash2base('" + label + "', nil ) = \n\t" + str(value)) 46 | elif DEBUG: 47 | print("hash2base('" + label + "', " + pprint_hex(x) + ") = \n\t" + str(value)) 48 | return value 49 | 50 | if __name__ == "__main__": 51 | print "## Sample hash2base" 52 | print "" 53 | 54 | DEBUG = False 55 | print "~~~" 56 | print("hash2base(\"%s\", %s) \n\t= %s\n" % ("H2C-Curve25519-SHA256-Elligator-Clear", pprint_hex("\x12\x34"), Hex(h2b_from_label("H2C-Curve25519-SHA256-Elligator-Clear", "\x12\x34")))) 57 | print("hash2base(\"%s\", %s) \n\t= %s\n" % ("H2C-P256-SHA512-SWU-", pprint_hex("\x12\x34"), Hex(h2b_from_label("H2C-P256-SHA512-SWU-", "\x12\x34")))) 58 | print("hash2base(\"%s\", %s) \n\t= %s\n" % ("H2C-P256-SHA512-SSWU-", pprint_hex("\x12\x34"), Hex(h2b_from_label("H2C-P256-SHA512-SSWU-", "\x12\x34")))) 59 | print "~~~" 60 | -------------------------------------------------------------------------------- /plans.md: -------------------------------------------------------------------------------- 1 | # BLS Standard Draft -- Plans (Jul 31/Aug 5, 2019) 2 | 3 | We outline our plans for the next iteration of the draft. 4 | 5 | ## Major 6 | 7 | * Refer to hash-to-curve spec. 8 | 9 | * Ciphersuite for BLS signatures will include (i) ciphersuite for 10 | hash-to-curve which specifies the curve and which groups the 11 | public keys and signatures live in, as well as the underlying 12 | "data hash" (i.e. SHA256, etc), (ii) rogue-key protection 13 | mechanism (POP vs AUG). E.g. BLS12381G2-SHA256-SSWU-RO-AUG, 14 | encoded in ASCII as an octet string. 15 | 16 | * For proof-of-possession mechanism against rogue 17 | key attacks, the ciphersuite will provide domain 18 | separation for the proofs of possession and the actual signing. 19 | 20 | * Ciphersuite will be specified via the parameter DST for hash-to-curve. 21 | 22 | * For message augmentation, we will use "pk || message" as the input 23 | to hash-to-curve. 24 | 25 | * Signing will take variable-length messages as in hash-to-curve. For 26 | "pre-hashed messages", the signing algorithm takes as input the 27 | hash. As long as the pre-hash algorithm is collision-resistant, a 28 | standard cryptographic argument guarantees that the signature 29 | authenticates the message. 30 | 31 | * We will assume access to serialize and unserialize algorithms from 32 | the underlying groups. For public keys, we assume the same 33 | serialization format is used throughout (we expect that this will be 34 | the compressed point format in most applications). Whenever we need to 35 | serialize a public key in the context of messag augmentation and PoP, 36 | we will use the same serialization. 37 | 38 | * We will use HKDF for key generation. 39 | 40 | * Unlike the [EdDSA](https://tools.ietf.org/html/rfc8032) spec, there will 41 | not be a separate pre-hash or contextualized mode. 42 | 43 | * There will be three "modes" for aggregation: NULL, POP and AUG corresponding 44 | to the three mechanisms for security against rogue-key attacks. NULL also captures 45 | applications that do not require aggregation. 46 | 47 | * Aggregation algorithm for all modes simply multiply the signatures 48 | together (there are no special checks and there is no need to have access 49 | to the underlying messges or public keys). 50 | 51 | * AggregateVerify for NULL mode additionally checks that the messages are distinct. 52 | AggregateVerify for POP and AUG modes do not have any additional check. (Verifying 53 | proofs of possessions are carried out separately. For message augmentation, the 54 | analysis in [BNN06] says that we do not need to check that the public keys 55 | are distinct. 56 | -------------------------------------------------------------------------------- /poc/hash_to_base.py: -------------------------------------------------------------------------------- 1 | 2 | # This file was *autogenerated* from the file hash_to_base.sage 3 | from sage.all_cmdline import * # import sage library 4 | 5 | _sage_const_2 = Integer(2); _sage_const_1 = Integer(1); _sage_const_0 = Integer(0); _sage_const_64 = Integer(64); _sage_const_4 = Integer(4) 6 | import hashlib 7 | from utils import * 8 | 9 | # Format the input as `"h2b" || label || len(x) || x` (where || is concatenation) 10 | # Since label is a fixed string, and len(x) is fixed to 4 bytes, 11 | # this encoding is unambiguous 12 | def format_input(label, x): 13 | return "h2b%s%s%s" % (label, i2osp(len(x), _sage_const_4 ), x) 14 | 15 | # Hash bytestring input to a field element. 16 | def hash_to_base(x, H, hbits, p, label): 17 | assert type(x) is bytes 18 | F = GF(p) 19 | min_bits = floor(log(p, _sage_const_2 ).n()) + _sage_const_1 20 | assert hbits >= min_bits, "Need at least %d bits to hash p. H only outputs %d" % (min_bits, hbits) 21 | xin = format_input(label, x) # concatenate inputs 22 | print "xin" 23 | for i in xin: 24 | print ord(i), 25 | print "" 26 | h = H() 27 | h.update(xin) 28 | t1 = h.digest() 29 | for i in range(_sage_const_64 ): 30 | print ord(t1[i]), 31 | t1 = os2ip(t1) # recover integer from hash output 32 | print "t1", t1 33 | # s = t1 >> (hbits - 1) 34 | t2 = t1 & ((_sage_const_1 << hbits) - _sage_const_1 ) 35 | print "t2", t2 36 | t3 = ZZ(t2) 37 | print "t3", t3 38 | y = t3 % p 39 | return F(y) 40 | 41 | # Helper function to extract parameters from a ciphersuite label 42 | def h2b_from_label(label, x): 43 | cs = Ciphersuite(label) 44 | H = cs.hash.H 45 | hbits = cs.hash.hbits() 46 | p = cs.curve.p 47 | 48 | value = hash_to_base(x, H, hbits, p, label) 49 | if len(x) == _sage_const_0 and DEBUG: 50 | print("hash2base('" + label + "', nil ) = \n\t" + str(value)) 51 | elif DEBUG: 52 | print("hash2base('" + label + "', " + pprint_hex(x) + ") = \n\t" + str(value)) 53 | return value 54 | 55 | if __name__ == "__main__": 56 | print "## Sample hash2base" 57 | print "" 58 | 59 | DEBUG = False 60 | print "~~~" 61 | print("hash2base(\"%s\", %s) \n\t= %s\n" % ("H2C-Curve25519-SHA256-Elligator-Clear", pprint_hex("\x12\x34"), Hex(h2b_from_label("H2C-Curve25519-SHA256-Elligator-Clear", "\x12\x34")))) 62 | print("hash2base(\"%s\", %s) \n\t= %s\n" % ("H2C-P256-SHA512-SWU-", pprint_hex("\x12\x34"), Hex(h2b_from_label("H2C-P256-SHA512-SWU-", "\x12\x34")))) 63 | print("hash2base(\"%s\", %s) \n\t= %s\n" % ("H2C-P256-SHA512-SSWU-", pprint_hex("\x12\x34"), Hex(h2b_from_label("H2C-P256-SHA512-SSWU-", "\x12\x34")))) 64 | print "~~~" 65 | 66 | -------------------------------------------------------------------------------- /minutes/minutes-jun24-19.md: -------------------------------------------------------------------------------- 1 | 2 | # Meeting notes Jun 24, 2019 3 | 4 | * Attendees: 5 | 6 | Kirk Baird 7 | Justin Drake 8 | Sergey Gorbunov 9 | Armando Faz 10 | Riad Wahby 11 | Bram Cohen 12 | Brian Vohaska 13 | Carl Beekhuizen 14 | Kobi Gurkan 15 | Mariano Sorgente 16 | Victor Servant 17 | Zhenfei Zhang 18 | 19 | * Sergey: start with overview of implementations 20 | 21 | * Kirk: implementation matches Riad's, provided additional test vectors 22 | 23 | * Kobbi: gave suggestions on how to improve performance on sage. 24 | suggested adding test vectors for basic curve operations (ED: some test vectors already in pairing-friendly draft) 25 | 26 | * Riad: current implementation specifies message, secret key, and test checks that the verification is successful. 27 | 28 | * Armando: implementation in Go, some assembly implementations 29 | 30 | * Riad: Berkeley folks, [JEDI](https://people.eecs.berkeley.edu/~raluca/JEDIFinal.pdf), some low-level 31 | [implementations](https://github.com/ucbrise/jedi-pairing) 32 | 33 | * Hoeteck: which curves to use and which functions to use will be specified in the pairing specific draft. 34 | 35 | * Riad: will check pairing-friendly draft to confirm consistency of the pairing function. 36 | 37 | * Justin: target date for production-ready code -- Oct 8, 2019 (ED: no one else provided target dates) 38 | 39 | * Kobi: motivated BLS12-377 (SNARKs) [ZEXE](https://eprint.iacr.org/2018/962.pdf) [implementation](https://github.com/scipr-lab/zexe) 40 | [BLS12-377 code](https://github.com/scipr-lab/zexe/tree/master/algebra/src/curves/bls12_377) 41 | 42 | * Bram: how do sizes and performances compare? doing things inside snarks is a use case that’s far from now. 43 | 44 | * Kobbi: sizes are comparable 45 | 46 | * Riad: there might be slight speed improvements for 381 vs 377, but should be small. Hashing to g1 for 377 is no problem. Hashing to g2 for 377 should be about 2x worse, for non-constant should be 25-35% worse than for 381. 47 | 48 | * Sergey: may be useful to have a self-contained description for the blockchain community independent of the IETF standards 49 | 50 | * Justin: status of hash-to-curve? 51 | 52 | * Riad: see github [page](https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve) for a substantially updated draft. 53 | hash to curve should be updated by the next ietf meeting. 54 | discussion on [domain separation](https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/issues/124) 55 | 56 | * Justin / Kirk / Carl: will check that the Etherum production-ready code remains consistent with the current reference implementation / test vectors 57 | 58 | * Sergey / Riad: short-term -- focus on and continue with BLS 12-381 59 | 60 | * Carl: will people abandon BLS 12-381 if BLS-377 turns out to be the better one in 6 months' time? 61 | 62 | -------------------------------------------------------------------------------- /poc/fouquetibouchi.sage: -------------------------------------------------------------------------------- 1 | from hash_to_base import * 2 | from utils import * 3 | 4 | # BN curve 5 | t = -(2**62 + 2**55 + 1) 6 | pp = lambda x: 36*x**4 + 36*x**3 + 24*x**2 + 6*x + 1 7 | p = pp(t) 8 | print p 9 | assert is_prime(p) 10 | assert p%3 == 1 11 | F = GF(p) 12 | A = F(0) 13 | B = F(1) 14 | E = EllipticCurve([A,B]) 15 | S = sqrt(F(-3)) 16 | assert is_square(1+B) == false 17 | 18 | h2c_suite = "H2C-BN256-SHA512-FT-" 19 | 20 | def f(x): 21 | return F(x**3 + A*x + B) 22 | 23 | def fouquetibouchi(alpha): 24 | u = h2b_from_label(h2c_suite, alpha) 25 | u = F(u) 26 | 27 | w = (S*u)/(1+B+u**2) 28 | x1 = (-1+S)/2-u*w 29 | x2 = -1-x1 30 | x3 = 1+1/w**2 31 | e = legendre_symbol(u,p) 32 | if is_square( f(x1) ) : 33 | return E( [ x1, e * sqrt(f(x1)) ]) 34 | elif is_square( f(x2) ) : 35 | return E( [ x2, e * sqrt(f(x2)) ]) 36 | else: 37 | return E( [ x3, e * sqrt(f(x3)) ]) 38 | 39 | 40 | SQRT_MINUS3 = sqrt(F(-3)) # Field arithmetic 41 | ONE_SQRT3_DIV2 = F((-1+SQRT_MINUS3)/2) # Field arithmetic 42 | ORDER_OVER_2 = ZZ((p - 1)/2) # Integer arithmetic 43 | 44 | def fouquetibouchi_slp(alpha): 45 | u = h2b_from_label(h2c_suite, alpha) 46 | tv("u ", u, 32) 47 | 48 | u = F(u) 49 | t0 = u**2 # u^2 50 | t0 = t0+B+1 # u^2+B+1 51 | t0 = 1/t0 # 1/(u^2+B+1) 52 | t0 = t0*u # u/(u^2+B+1) 53 | t0 = t0*SQRT_MINUS3 # sqrt(-3)u/(u^2+B+1) 54 | assert t0 == F(sqrt(F(-3))*u/(u**2+B+1)) 55 | tv("t0", t0, 32) 56 | 57 | x1 = ONE_SQRT3_DIV2-u*t0 # (-1+sqrt(-3))/2-sqrt(-3)u^2/(u^2+B+1) 58 | assert x1 == F((-1+sqrt(F(-3)))/2-sqrt(F(-3))*u**2/(u**2+B+1)) 59 | tv("x1", x1, 32) 60 | 61 | x2 = -1-x1 62 | assert x2 == F(-1-((-1+sqrt(F(-3)))/2-sqrt(F(-3))*u**2/(u**2+B+1))) 63 | tv("x2", x2, 32) 64 | 65 | t1 = t0**2 66 | t1 = 1/t1 67 | x3 = t1+1 68 | assert x3 == F(1+1/t0**2) 69 | tv("x3", x3, 32) 70 | 71 | e = u^ORDER_OVER_2 72 | assert e == legendre_symbol(u,p) 73 | tv("e", e, 32) 74 | 75 | fx1 = x1^3+B 76 | assert fx1 == F(x1**3+B) 77 | tv("fx1", fx1, 32) 78 | 79 | s1 = fx1^ORDER_OVER_2 80 | if s1 == 1: 81 | y1 = e*sqrt(fx1) 82 | tv("y1", y1, 32) 83 | return E(x1, y1) 84 | 85 | fx2 = x2^3+B 86 | assert fx2 == F(x2**3+B) 87 | tv("fx2", fx2, 32) 88 | 89 | s2 = fx2^ORDER_OVER_2 90 | if s2 == 1: 91 | y2 = e*sqrt(fx2) 92 | tv("y2", y2, 32) 93 | return E(x2, y2) 94 | 95 | fx3 = x3^3+B 96 | assert fx3 == F(x3**3+B) 97 | tv("fx3", fx3, 32) 98 | 99 | y3 = e*sqrt(fx3) 100 | tv("y3", y3, 32) 101 | return E(x3, y3) 102 | 103 | 104 | if __name__ == "__main__": 105 | enable_debug() 106 | print "## Fouque-Tibouchi to BN256" 107 | for alpha in map2curve_alphas: 108 | print "\n~~~" 109 | print("Input:") 110 | print("") 111 | tv_text("alpha", pprint_hex(alpha)) 112 | print("") 113 | print("Intermediate values:") 114 | print("") 115 | pA, pB = fouquetibouchi(alpha), fouquetibouchi_slp(alpha) 116 | assert pA == pB 117 | print("") 118 | print("Output:") 119 | print("") 120 | tv("x", pB[0], 32) 121 | tv("y", pB[1], 32) 122 | print "~~~" 123 | -------------------------------------------------------------------------------- /poc/utils.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import struct 3 | import textwrap 4 | 5 | DEBUG = False 6 | 7 | map2curve_alphas = [ 8 | "", 9 | "\x00", 10 | "\xFF", 11 | "\xFF\x00" 12 | "\x11\x22\x33\x44\x11\x22\x33\x44\x11\x22\x33\x44\x11\x22\x33\x44\x55\x66\x77\x88\x55\x66\x77\x88\x55\x66\x77\x88\x55\x66\x77\x88", 13 | ] 14 | 15 | # Convert an non-negative integer into n bytes 16 | def i2osp(i, n): 17 | i = int(i) 18 | res = [0]*n 19 | for idx in range(n-1, -1, -1): 20 | res[idx] = i & 0xff 21 | i = i >> 8 22 | if i > 0: 23 | raise ValueError("Integer %s cannot fit into %s bytes" % (i, n)) 24 | return struct.pack("<" + "B" * n, *res) 25 | 26 | # Convert octal string into to integer 27 | def os2ip(os): 28 | res = 0 29 | for (idx, b) in enumerate(struct.unpack("<" + "B" * len(os), os)): 30 | res = res << 8 31 | res += b 32 | return res 33 | 34 | def Hex(n): 35 | return format(int(n),'x') 36 | 37 | def pprint_hex(os): 38 | return "".join("{:02x}".format(ord(c)) for c in os) 39 | 40 | def from_hex_string(str): 41 | os = "".join(chr(int(b, 16)) for b in str.split(" ")) 42 | return os2ip(os) 43 | 44 | def enable_debug(): 45 | global DEBUG 46 | DEBUG = True 47 | 48 | def tv_wrap(text): 49 | return textwrap.fill(text, 54).split("\n") 50 | 51 | def tv_text(label, value): 52 | if DEBUG: 53 | chunks = tv_wrap(value) 54 | print("%7s = %s" % (label, chunks[0])) 55 | for i, v in enumerate(chunks[1:]): 56 | print((" " * 10) + v) 57 | 58 | def tv(label, v, len): 59 | if DEBUG: 60 | chunks = tv_wrap(pprint_hex(i2osp(v, len))) 61 | print("%7s = %s" % (label, chunks[0])) 62 | for i, v in enumerate(chunks[1:]): 63 | print((" " * 10) + v) 64 | 65 | class Ciphersuite: 66 | def __init__(self, label): 67 | (h2c_prefix, curve, hash_name, map_name, variant_name) = label.split("-") 68 | self.curve = Curve(curve) 69 | self.hash = Hash(hash_name) 70 | 71 | class Hash: 72 | def __init__(self, label): 73 | if label == "SHA256": 74 | self.H = hashlib.sha256 75 | elif label == "SHA384": 76 | self.H = hashlib.sha384 77 | elif label == "SHA512": 78 | self.H = hashlib.sha512 79 | else: 80 | raise ValueError("Hash %s is not recognized" % curve) 81 | 82 | def hbits(self): 83 | return self.H().digest_size * 8 84 | 85 | class Curve: 86 | def __init__(self, label): 87 | if label == "Curve25519": 88 | self.p = 2**255 - 19 89 | elif label == "P256": 90 | self.p = 2**256 - 2**224 + 2**192 + 2**96 - 1 91 | elif label == "P384": 92 | self.p = 2**384 - 2**128 - 2**96 + 2**32 - 1 93 | elif label == "P503": 94 | self.p = 2**250*3**159-1 95 | elif label == "BN256": 96 | mu = -(2**62 + 2**55 + 1) 97 | pp = lambda x: 36*x**4 + 36*x**3 + 24*x**2 + 6*x + 1 98 | self.p = pp(mu) 99 | elif label == "BLS12_381_1": 100 | # t = -0xd201000000010000 101 | # pp = lambda x: ((x-1)**2) * ((x**4 - x**2 + 1)/3) + x 102 | # print pp(t) 103 | # self.p = pp(t) 104 | self.p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab 105 | 106 | else: 107 | raise ValueError("Curve %s is not recognized" % curve) 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BLS Standard Draft 2 | 3 | The repo is maintained by a working group aiming to standardize BLS signature scheme. 4 | This repo was moved from [here](https://github.com/pairingwg/bls_standard). 5 | 6 | ## News: 7 | 8 | * Updated from -02 to -03 and from -03 to -04. 9 | * -03 is a compatibility release for existing implementations. 10 | * -04 is an update that addresses a potential security concern. 11 | 12 | * Updated from -00 to -02. See changelog. 13 | 14 | * This draft has been adopted by the CFRG as an active [work group draft](https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-02) 15 | 16 | ## Changelog: 17 | * Changes from draft-irtf-cfrg-bls-signature-03 to draft-irtf-cfrg-bls-signtuare-04: 18 | * KeyGen and KeyValidate updated. KeyValidate now rejects PK if it represents the 19 | identity element. KeyGen likewise will not generate SK = 0, which would result 20 | in an identity public key. 21 | * Security Considerations updated with a discussion of why identity PK is disallowed. 22 | 23 | * Changes from draft-irtf-cfrg-bls-signature-02 to draft-irtf-cfrg-bls-signtuare-03: 24 | * Updated author affiliations 25 | * Updated hash-to-curve reference to version -09 26 | * minor pagination changes 27 | 28 | * Changes from draft-irtf-cfrg-bls-signature-01 to draft-irtf-cfrg-bls-signature-02: 29 | * No change, maintenance release only: fix broken bibliography entry for hash-to-curve. 30 | 31 | * Changes from draft-irtf-cfrg-bls-signature-00 to draft-irtf-cfrg-bls-signature-01: 32 | * Improve APIs: 33 | * make API functions take array/tuple of keys/messages instead of being variadic 34 | * clarify that functions taking multiple inputs are only valid when n >= 1 35 | * Remove SK-to-PK functionality from KeyGen; moved it to SkToPk function. 36 | * Tweaks to KeyGen: 37 | * append a null byte to IKM (lets us prove indifferentiability) 38 | * add optional key_info parameter (lets one generate different keys from same IKM) 39 | * append I2OSP(L, 2) to the info argument to HKDF-Expand. Ensures that changing L gives orthogonal output. 40 | * Update ciphersuites to use new hash-to-curve suite naming convention 41 | 42 | * Changes from draft-boneh-bls-signature to draft-irtf-cfrg-bls-signature-00: 43 | * Changed serialization methods 44 | * Use HKDF to derive keys 45 | * Use hash to curve/group methods from [Hash to curve draft](https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-04) 46 | 47 | ## Useful links: 48 | * Pairing draft: [stable](https://datatracker.ietf.org/doc/draft-irtf-cfrg-pairing-friendly-curves/), [dev](https://github.com/pairingwg/pfc_standard) 49 | * Hash to curve draft: [stable](https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve/), [dev](https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve) 50 | * Current reference implementations: 51 | * https://github.com/kwantam/bls_sigs_ref 52 | * https://github.com/sigp/milagro_bls/ 53 | * https://github.com/hyperledger/ursa/blob/master/libursa/src/bls/mod.rs 54 | * https://github.com/mikelodder7/bls12-381-comparison 55 | * https://github.com/apache/incubator-milagro-crypto-rust 56 | 57 | 58 | ## Version control 59 | 60 | Major milestone updates (version [0](https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-00), [1](https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-01), [2](https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-02), ...) 61 | will be uploaded to [IETF webpage](https://datatracker.ietf.org/doc/draft-irtf-cfrg-bls-signature). 62 | Minor advancement are released through subversions. 63 | 64 | ## Comments and feedbacks 65 | Feel free to submit any feedback by 66 | * creating issues (preferred method), or 67 | * pull request (please use it for editorial only) 68 | 69 | ## Formatting 70 | To generate txt/pdf: 71 | 1. use mmark to convert md to xml 72 | 2. use xml2rfc to convert xml to txt/pdf 73 | -------------------------------------------------------------------------------- /poc/map2curve_ft.sage: -------------------------------------------------------------------------------- 1 | # H2C-xxx-SHA512-FT- outputs curve points that do not necessarily lie in the subgroup. 2 | # H2C-xxx-SHA512-FT-Clear would include cofactor clearing. 3 | # https://www.ietf.org/id/draft-irtf-cfrg-hash-to-curve-03.txt 4 | 5 | from hash_to_base import * 6 | from utils import * 7 | 8 | # BLS12-381 G1 curve 9 | t = -0xd201000000010000 10 | pp = lambda x: ((x-1)**2) * ((x**4 - x**2 + 1)/3) + x 11 | p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab 12 | assert is_prime(p) 13 | assert p%3 == 1 14 | assert p == pp(t) 15 | 16 | F = GF(p) 17 | A = F(0) 18 | B = F(4) 19 | E = EllipticCurve([A,B]) # y^2 = x^3 + 4 20 | S = sqrt(F(-3)) 21 | assert is_square(1+B) == false 22 | h = 0x396c8c005555e1568c00aaab0000aaab # co-factor for G1 23 | 24 | # BLS12-381 G2 curve 25 | K2. = F [] 26 | F2. = F.extension(U^2+1) 27 | A2 = F2(0) 28 | B2 = F2(4*root+1) 29 | E2 = EllipticCurve([A2,B2]) 30 | ## define S2? 31 | h2 = 0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5 # co-factor for G2 32 | 33 | h2c_suite = "H2C-BLS12_381_1-SHA512-FT-" 34 | 35 | def f(x): 36 | return F(x**3 + A*x + B) 37 | 38 | def map2curve_ft(alpha): 39 | u = h2b_from_label(h2c_suite, alpha) 40 | u = F(u) 41 | 42 | w = (S*u)/(1+B+u**2) 43 | x1 = (-1+S)/2-u*w 44 | x2 = -1-x1 45 | x3 = 1+1/w**2 46 | e = legendre_symbol(u,p) 47 | if is_square( f(x1) ) : 48 | return E( [ x1, e * sqrt(f(x1)) ]) 49 | elif is_square( f(x2) ) : 50 | return E( [ x2, e * sqrt(f(x2)) ]) 51 | else: 52 | return E( [ x3, e * sqrt(f(x3)) ]) 53 | 54 | def map2curve_ft_clear(alpha): 55 | return h * map2curve_ft(alpha) 56 | 57 | SQRT_MINUS3 = sqrt(F(-3)) # Field arithmetic 58 | ONE_SQRT3_DIV2 = F((-1+SQRT_MINUS3)/2) # Field arithmetic 59 | ORDER_OVER_2 = ZZ((p - 1)/2) # Integer arithmetic 60 | 61 | def map2curve_ft_slp(alpha): 62 | u = h2b_from_label(h2c_suite, alpha) 63 | tv("u ", u, 48) 64 | 65 | u = F(u) 66 | t0 = u**2 # u^2 67 | t0 = t0+B+1 # u^2+B+1 68 | t0 = 1/t0 # 1/(u^2+B+1) 69 | t0 = t0*u # u/(u^2+B+1) 70 | t0 = t0*SQRT_MINUS3 # sqrt(-3)u/(u^2+B+1) 71 | assert t0 == F(sqrt(F(-3))*u/(u**2+B+1)) 72 | tv("t0", t0, 48) 73 | 74 | x1 = ONE_SQRT3_DIV2-u*t0 # (-1+sqrt(-3))/2-sqrt(-3)u^2/(u^2+B+1) 75 | assert x1 == F((-1+sqrt(F(-3)))/2-sqrt(F(-3))*u**2/(u**2+B+1)) 76 | tv("x1", x1, 48) 77 | 78 | x2 = -1-x1 79 | assert x2 == F(-1-((-1+sqrt(F(-3)))/2-sqrt(F(-3))*u**2/(u**2+B+1))) 80 | tv("x2", x2, 48) 81 | 82 | t1 = t0**2 83 | t1 = 1/t1 84 | x3 = t1+1 85 | assert x3 == F(1+1/t0**2) 86 | tv("x3", x3, 48) 87 | 88 | e = u^ORDER_OVER_2 89 | assert e == legendre_symbol(u,p) 90 | tv("e", e, 48) 91 | 92 | fx1 = x1^3+B 93 | assert fx1 == F(x1**3+B) 94 | tv("fx1", fx1, 48) 95 | 96 | s1 = fx1^ORDER_OVER_2 97 | if s1 == 1: 98 | y1 = e*sqrt(fx1) 99 | tv("y1", y1, 48) 100 | return E(x1, y1) 101 | 102 | fx2 = x2^3+B 103 | assert fx2 == F(x2**3+B) 104 | tv("fx2", fx2, 48) 105 | 106 | s2 = fx2^ORDER_OVER_2 107 | if s2 == 1: 108 | y2 = e*sqrt(fx2) 109 | tv("y2", y2, 48) 110 | return E(x2, y2) 111 | 112 | fx3 = x3^3+B 113 | assert fx3 == F(x3**3+B) 114 | tv("fx3", fx3, 48) 115 | 116 | y3 = e*sqrt(fx3) 117 | tv("y3", y3, 48) 118 | return E(x3, y3) 119 | 120 | 121 | if __name__ == "__main__": 122 | enable_debug() 123 | print "## Fouque-Tibouchi to BLS12-381 G1" 124 | for alpha in map2curve_alphas: 125 | tv_text("alpha", pprint_hex(alpha)) 126 | for alpha in map2curve_alphas: 127 | print "\n~~~" 128 | print("Input:") 129 | print("") 130 | tv_text("alpha", pprint_hex(alpha)) 131 | print("") 132 | print("Intermediate values:") 133 | print("") 134 | pA, pB = map2curve_ft(alpha), map2curve_ft_slp(alpha) 135 | assert pA == pB 136 | print("") 137 | print("Output:") 138 | print("") 139 | tv("x", pB[0], 48) 140 | tv("y", pB[1], 48) 141 | print "~~~" 142 | -------------------------------------------------------------------------------- /minutes/minutes-july15-19.md: -------------------------------------------------------------------------------- 1 | # Meeting notes July 15, 2019 2 | 3 | * Attendees: 4 | Armando Faz, 5 | Bram cohen, 6 | Carl Beekhuizen, 7 | Dan Middleton, 8 | Chih Cheng Liang, 9 | Hoeteck Wee, 10 | Justin Drake, 11 | Mariano Sorgente, 12 | Mike Lodder, 13 | Raid Wahby, 14 | Sean Bowe, 15 | Sergey Gorbunov, 16 | Victor Servant, 17 | Zaki Manian, 18 | zhenfei Zhang 19 | 20 | ---------------- 21 | 22 | Useful links: 23 | * [Pairing draft](https://github.com/pairingwg/pfc_standard) 24 | * [Hash to curve draft](https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-04) 25 | * Current references: 26 | * https://github.com/kwantam/bls_sigs_ref 27 | * https://github.com/sigp/milagro_bls/ 28 | * https://github.com/hyperledger/ursa/blob/master/libursa/src/bls/mod.rs 29 | * https://github.com/mikelodder7/bls12-381-comparison 30 | 31 | 32 | ---------------- 33 | 34 | 35 | Sergey: opening 36 | 37 | * a summery of the current state of the draft 38 | * dependencies: pairing draft, hash to curve; both to be presented at next IETF meeting 39 | * summery from last meeting: 40 | * agreed to decouple BLS standard for blockchain from BLS draft for IETF 41 | * Etherum is looking for deployment this fall 42 | * we expect to have BLS standard for blockchain by end of this summer 43 | 44 | * decide the right format for the spec: python sudo codes 45 | * Justin: will use BLS to deposit contract. No performance requirement there; pseudo code is sufficient 46 | * Mike: Signature is not the bottleneck for them either. 47 | * Bram: do not require constant time code for reference implementation 48 | * Justin: Harmony also launched BLS signature 49 | * Justin: the standard needs to handle edge cases; pseudo code may not be sufficient 50 | * Discussions on proof of possession, etc 51 | * consensus: for bls standard for blockchain, a high level spec, with pseudo codes to cover edge cases; 52 | IETF draft may need a more detailed spec. 53 | 54 | ---------------- 55 | 56 | Status of hash to curve draft 57 | * Riad: the draft is updated for the coming IETF meeting, two major changes: 58 | * first one is how to hash strings to the field. Previously uses sha256, described [here](https://github.com/pairingwg/bls_standard/blob/master/minutes/spec-v1.md#hash-to-curve). 59 | The revised draft will use hkdf as specified by [RFC-5869](https://tools.ietf.org/html/rfc5869). 60 | This change is __NOT__ backward compatible with current BLS implementations. 61 | * the other change is on domain separation, ciphersuite, etc. It is not expected to impact BLS standard. 62 | * time line for hash to curve draft: closer to feature complete. It still needs pseudo code, test vectors, clean ups, etc. 63 | They do not have an exact deadline, but expect that the delta between current version and the final one will be minor. 64 | 65 | * Sergey: our plan is to freeze some version of hash to curve draft, and use that version for BLS standard for blockchain. 66 | * Bram: fine with the change for now 67 | * Raid: concerned about backward compatibility; a possible solution: use csid to separate implementation versions. 68 | * Justin: spec looks good, happy with hkdf. Clarifications may need: shall we pass msg or msg digest to hkdf to extract? 69 | * Justin: restrict msg to 32 bytes digest 70 | * Bram: api should take 32 bytes, not necessarily digest 71 | * Hoeteck: we shall follow ECDSA draft 72 | * 2 modes for signing: pre-hash mode and normal mode. 73 | * need to check the length of pre-hashed message 74 | 75 | ---------------- 76 | 77 | Updates on implementations 78 | 79 | * Mike: confusion on non-constant time hash to group based on hkdf 80 | * Riad: hkdf is used for hash to field, not to group. So hash to curve still remains constant time. 81 | 82 | * Riad: reference implementation, 83 | * no major changes 84 | * added/adding more more test cases: must fail tests for non group elements 85 | * should also put those test cases in the spec 86 | 87 | * Armando: no update. 88 | * Kirk: on holiday 89 | 90 | * Sergey: update proof of possession and aggregation for spec; update code after that 91 | 92 | ---------------- 93 | 94 | Misc 95 | 96 | * Mike: working on bbs+ signature with selective opening; is looking for faster pairing curve implementation. 97 | * Sergey: pairing friendly curves is done by another draft 98 | * Armando: Mike can take a look at [relic](https://github.com/relic-toolkit/relic) 99 | 100 | * Justin: serialization issue 101 | * Riad: zcash use size/length to imply the which group the element lies in; 102 | * [issue](https://github.com/pairingwg/bls_standard/issues/16) on bls standard github 103 | * backward compatibility - zcash is not able to decode 104 | * next step: everyone takes a look at the [issue](https://github.com/pairingwg/bls_standard/issues/16) and discuss it during the next call? 105 | 106 | ---------------- 107 | 108 | Next step: 109 | 110 | * Justin: what more work need to be done? proof of possession, aggregation, and ciphersuite ids. 111 | * Riad: serialization format for signature and proof of possession, domain separation. 112 | * Hoeteck: serialization for curve point will imply serialization for signatures 113 | -------------------------------------------------------------------------------- /minutes/minutes-apr11-19.md: -------------------------------------------------------------------------------- 1 | 2 | # Meeting notes Apr 11, 2019, 6.30 pm EST 3 | 4 | * Attendees: 5 | 6 | Kirk Baird 7 | Vitalik Buterin 8 | Justin Drake 9 | Dankrad Feist 10 | Sergey Gorbunov 11 | Paul Hauner 12 | Danny Ryan 13 | Hsiao-Wei Wang 14 | Hoeteck Wee 15 | 16 | * Justin: The Ethereum 2.0 team is keen to boost the BLS standardisation effort. 17 | Indeed, many projects are intending to launch in 2019 and standardisation takes time. 18 | 19 | * Sergey: The BLS signatures draft is intended for the wide community and not just the 20 | blockchain community. We choose IETF/CFRG for several reasons: 21 | 22 | - generally regarded as the industry standard. E.g. TLS 1.3, EdDSA, etc 23 | - BLS signatures builds upon two IETF/CFRG drafts: one for pairing-friendly 24 | curves, and another for hashing to curves 25 | - can get valuable feedback from a broad community of academic cryptographers and 26 | industry experts. 27 | 28 | * Which hashing algorithm? General support for Fouque-Tibouchi for BLS12-381. 29 | 30 | - 15% overhead over hash-and-test (see numbers below) 31 | - constant-time implementations for forward-compatibility (even though we do 32 | not know any use cases with such a requirement off-hand) 33 | - slower signing does not seem to be a big deal, and signing unlikely to be a bottleneck 34 | - most players are not too opinitiated about which algorithm to use. 35 | 36 | * Suggestion: limit the scope of options in the BLS signatures draft, e.g. 37 | fix BLS12-381 curves, etc. 38 | 39 | * General support for (i) standardizing two variants of the scheme, 40 | one where signatures are in G1, another where signatures are in G2, 41 | and (ii) standardizing aggregation algorithms 42 | 43 | * Etherum 2.0 consensus. Enshrine key registration; don’t enshrine 44 | user-level transaction. Data layer / agnostic. Contract can specify 45 | whatever signature scheme they want. Don’t even have a notion of 46 | transaction. Centralized spec, outsourcing implementation. All the implementations 47 | are open-source. 48 | 49 | * Etherum uses proof of possession for protect against rogue key attacks 50 | in consensus. Domain separation could maybe be left to the application level. 51 | 52 | * Serialization: need to point all the way to bits. The rest should be at the 53 | application or networking level, etc. 54 | 55 | - as a starting point, we could follow the zcash [serialization]( 56 | https://github.com/zkcrypto/pairing/blob/183a64b08e9dc7067f78624ec161371f1829623e/src/bls12_381/ec.rs#L837) 57 | - this should be handled in the draft for pairing-friendly curves. 58 | 59 | * Will not limit the length of the messages. 60 | 61 | - consistent with Ed25519: "The inputs to the signing procedure is the private key, 62 | 32-octet string, and a message M of arbitrary size." 63 | - arbitrary-length messages already handled by hash-to-curve anyway 64 | 65 | * Should create a Telegram channel -- update: [link](https://t.me/blsstandardwg) 66 | 67 | 68 | ## Appendix 69 | 70 | 71 | ### Benchmarks for hashing onto BLS-381 G1 72 | 73 | These numbers are on an i7 processor. 74 | 75 | * hash-and-test x cofactor: hashing takes 140 μs and signing 370 μs 76 | * map2curve_ft x cofactor: hashing takes 200 μs and signing 430 μs 77 | 78 | Here is a breakdown of the costs: 79 | 80 | * map2curve_ft computes 3 square roots (90 μs) plus extra operations 81 | * hash-and-test computes 2 = 1+0.5+0.25+0.125 +... square roots (60 μs) 82 | * 1 cofactor multiplication (80 μs), 83 | * signing is hash plus 1 G1-exp (130 μs) 84 | 85 | Note that Chia implements indifferentiable hashing and makes two calls to map2curve_ft. 86 | This incurs an additional cost of 120 μs. 87 | 88 | ### Proposed agenda (Sergey) 89 | 90 | For BLS, we're looking for immediate feedback on the following questions: 91 | 92 | 1) Hashing algorithms. There are three variants we consider: 93 | * hash-and-test (not constant time) 94 | * Fouque-Tibouchi Method (map2curve_ft) : hits 5/8 points 95 | * repeat map2curve_ft twice and add the outputs points to hit all points on the curve. 96 | 97 | Our implementation for map2curve_ft adds 15% vs hash-and-test method. 98 | 99 | 2) Protection against rogue key attacks. 100 | * Message augmentation: pk = g^sk, sig = H(pk, m)^sk 101 | * Proof of possession: pk = ( u=g^sk, H'(u)^sk ), sig = H(m)^sk 102 | * Linear combination: agg = sig_1^t_1 ... sig_n^t_n 103 | 104 | 3) We're planning on standardizing 2 variants of the scheme, one where signatures are in G1, another where signatures are in G2. 105 | 106 | 4) Serialization. Agree on methods for conversions between strings and curve points. 107 | 108 | For instance, for transactions in blockchains one could consider instantiating the scheme in the following ciphersuite: 109 | 110 | * Use hash-and-test (since constant time is not required for signatures) 111 | * Use message augmentation to protect against rogue key attacks (since all messages signed in transactions are already distinct). 112 | * Put signatures in G2 (since public keys have to live on the chain in clear; but signatures can be compressed). 113 | 114 | 115 | ### Pointers 116 | 117 | * Implementations 118 | 119 | https://github.com/ethereum/eth2.0-specs/blob/master/specs/bls_signature.md 120 | https://github.com/sigp/signature-schemes 121 | https://github.com/ethereum/eth2.0-pm/issues/13/ 122 | 123 | * Jubjub -- https://z.cash/technology/jubjub/ 124 | 125 | * Hashing to G2 126 | 127 | https://github.com/Chia-Network/bls-signatures/blob/master/SPEC.md 128 | https://eprint.iacr.org/2017/419.pdf 129 | -------------------------------------------------------------------------------- /minutes/spec-v1.md: -------------------------------------------------------------------------------- 1 | 2 | # Specification for BLS Signatures over BLS12-381 v1 3 | 4 | **Initial draft: Apr 29, 2019. Current verison: May 1, 2019.** 5 | 6 | This is an initial specification for BLS signatures. The objective is 7 | to provide a specification which enable consistent implementations 8 | with respect to low-level encoding and algorithmic choices. 9 | Note that it does not cover aggregation or protection against rogue key attacks. 10 | 11 | ## Preliminaries 12 | 13 | * [P1], [P2] are generators for the BLS12-381 curve; subgroups are of order r. We use generators specified in the pairing-friendly curves standard: https://tools.ietf.org/html/draft-yonezawa-pairing-friendly-curves-01#section-4.2 14 | 15 | * ciphersuite is a fixed-length 8-bit string. 16 | 17 | * a || b denotes (naive) string concatenation. In all our applications below, 18 | a or b has a fixed length, so decoding is unique. 19 | 20 | * we use OS2IP from [RFC8017](https://tools.ietf.org/html/rfc8017) 21 | 22 | ### Hash to curve 23 | 24 | We follow WB19 [paper](https://eprint.iacr.org/2019/403), [implementation](https://github.com/kwantam/bls12-381_hash). We will rely on the following subroutines: 25 | 26 | * hash_to_field is a generic construction that uses a cryptographic hash function to output field elements: 27 | 28 | ~~~ 29 | hash_to_field(msg, ctr, p, m, hash_fn, hash_reps) 30 | 31 | Parameters: 32 | - msg is an octet string to be hashed. 33 | - ctr is an integer < 2^8 used to orthogonalize hash functions 34 | - p and m specify the field as GF(p^m) 35 | - hash_fn is a hash function, e.g., SHA256 36 | - hash_reps is the number of concatenated hash outputs 37 | used to produce an element of F_p 38 | 39 | hash_to_field(msg, ctr, p, m, hash_fn, hash_reps) := 40 | msg' = hash_fn(msg) || I2OSP(ctr, 1) 41 | for i in (1, ..., m): 42 | t = "" // initialize to the empty string 43 | for j in (1, ..., hash_reps): 44 | t = t || hash_fn( msg' || I2OSP(i, 1) || I2OSP(j, 1) ) 45 | e_i = OS2IP(t) mod p 46 | return (e_1, ..., e_m) 47 | ~~~ 48 | 49 | In the above, an element of the extension field GF(p^m) is represented by a vector V of elements of GF(p). 50 | GF(p^m) defines a primitive element α, and the vector V represents the element determined by the inner 51 | product of V with the vector (α^0, ..., α^{m-1}). For BLS12-381 G2, α = sqrt(-1). 52 | 53 | * Using the above, define Hp and Hp2 as: 54 | 55 | Hp(msg, ctr) := hash_to_field(msg, ctr, p, 1, SHA256, 2) 56 | 57 | Hp2(msg, ctr) := hash_to_field(msg, ctr, p, 2, SHA256, 2) 58 | 59 | * Map1 and Map2 are the maps given in Section 4 of [WB19](https://eprint.iacr.org/2019/403). 60 | 61 | * hashtoG1(msg in {0,1}\*) is construction #2 in WB19, instantiated with `Hp (msg, 0)` and `Hp (msg, 1)`. In particular, 62 | 63 | hashtoG1(msg) := (Map1(Hp(msg, 0)) * Map1(Hp(msg, 1)))^{1-z} 64 | 65 | * hashtoG2(msg in {0,1}\*) is construction #5 in WB19, instantiated with `Hp2 (msg, 0)` and `Hp2 (msg, 1)`. 66 | 67 | 68 | ## Basic signature in G1 69 | 70 | * key generation: 71 | 72 | - sk = x is 32 octets (256 bits) 73 | - compute x' = `hash_to_field(x, 0, r, 1, SHA256, 2)` 74 | - pk := x' * [P2] 75 | 76 | * sign(sk, msg in {0,1}\*, ciphersuite in {0,1}^8) 77 | 78 | - derive x' from sk as in key generation 79 | - H = `hashtoG1(ciphersuite || msg)` 80 | - output x' * H 81 | 82 | ## Basic signature in G2 83 | 84 | As before, replace P2, hashtoG1 with P1, hashtoG2 85 | 86 | ## TODOs 87 | 88 | * Specify how to represent curve points as octet strings. 89 | 90 | * Specify a variant where we sign the concatenation of the public key and the message. Here, 91 | the public key has a fixed length (which is determined by the ciphersuite), and we need to 92 | fix a representation of the public key as an octet string. 93 | 94 | * Generate test vectors for ciphersuite being all-zeroes. 95 | 96 | * To add a ciphersuite "look up" table. The ciphersuite string will tell us 97 | - which curve to use 98 | - whether signatures sit in G1 or in G2 99 | - which encoding algorithm to use, e.g. WB19 vs FT12 100 | - which data hashing algorithm to use, namely SHA256 vs SHA 101 | - whether and how we clear the co-factor 102 | - possibly which mechanism is used to prevent rogue-key attacks (message augmentation vs 103 | proof of posession) 104 | 105 | As a place-holder, we will use 0x01 for signatures in G1, 0x02 for signatures in G2. 106 | 107 | * To decide if we want separate ciphersuite strings for the signature scheme and hash-to-curve. 108 | Given that hash-to-curve is only used as an intermediate building, our motivating principle 109 | here is that only the final application (e.g. signatures or VRFs) should provide the ciphersuite string. 110 | 111 | ## Design Rationale 112 | 113 | * We hash the randomness during key generation to mitigate any attacks arising from 114 | weak sources of randomness. This was also done in [EdDSA spec](https://tools.ietf.org/html/rfc8032). 115 | 116 | * The specification uses SHA256 as used in many existing implementations. 117 | If we decide to support SHA512 later, the change should be straight-forward. 118 | 119 | * For hashing to curves, we use indifferentiable hashing in order to be "future-proof", 120 | even though a weaker security notion (with a slightly more efficient instantiation) suffices for security for BLS signatures. 121 | 122 | * There will be no explicit pre-hash mode. If the signature algorithm 123 | gets as input the hash H(M) of a huge message, then we should think of 124 | this as signing H(M), and not signing M, pre-hashed. This has the 125 | advantage of allowing the application to use a different data hash 126 | algorithm. 127 | -------------------------------------------------------------------------------- /poc/map2curve_ft.py: -------------------------------------------------------------------------------- 1 | 2 | # This file was *autogenerated* from the file map2curve_ft.sage 3 | from sage.all_cmdline import * # import sage library 4 | 5 | _sage_const_3 = Integer(3); _sage_const_2 = Integer(2); _sage_const_1 = Integer(1); _sage_const_0 = Integer(0); _sage_const_4 = Integer(4); _sage_const_48 = Integer(48); _sage_const_0x396c8c005555e1568c00aaab0000aaab = Integer(0x396c8c005555e1568c00aaab0000aaab); _sage_const_0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab = Integer(0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab); _sage_const_0xd201000000010000 = Integer(0xd201000000010000); _sage_const_0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5 = Integer(0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5)# H2C-xxx-SHA512-FT- outputs curve points that do not necessarily lie in the subgroup. 6 | # H2C-xxx-SHA512-FT-Clear would include cofactor clearing. 7 | # https://www.ietf.org/id/draft-irtf-cfrg-hash-to-curve-03.txt 8 | 9 | from hash_to_base import * 10 | from utils import * 11 | 12 | # BLS12-381 G1 curve 13 | t = -_sage_const_0xd201000000010000 14 | pp = lambda x: ((x-_sage_const_1 )**_sage_const_2 ) * ((x**_sage_const_4 - x**_sage_const_2 + _sage_const_1 )/_sage_const_3 ) + x 15 | p = _sage_const_0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab 16 | assert is_prime(p) 17 | assert p%_sage_const_3 == _sage_const_1 18 | assert p == pp(t) 19 | 20 | F = GF(p) 21 | A = F(_sage_const_0 ) 22 | B = F(_sage_const_4 ) 23 | E = EllipticCurve([A,B]) # y^2 = x^3 + 4 24 | S = sqrt(F(-_sage_const_3 )) 25 | assert is_square(_sage_const_1 +B) == false 26 | h = _sage_const_0x396c8c005555e1568c00aaab0000aaab # co-factor for G1 27 | 28 | # BLS12-381 G2 curve 29 | K2 = F ['U']; (U,) = K2._first_ngens(1) 30 | F2 = F.extension(U**_sage_const_2 +_sage_const_1 , names=('root',)); (root,) = F2._first_ngens(1) 31 | A2 = F2(_sage_const_0 ) 32 | B2 = F2(_sage_const_4 *root+_sage_const_1 ) 33 | E2 = EllipticCurve([A2,B2]) 34 | ## define S2? 35 | h2 = _sage_const_0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5 # co-factor for G2 36 | 37 | h2c_suite = "H2C-BLS12_381_1-SHA512-FT-" 38 | 39 | def f(x): 40 | return F(x**_sage_const_3 + A*x + B) 41 | 42 | def map2curve_ft(alpha): 43 | u = h2b_from_label(h2c_suite, alpha) 44 | u = F(u) 45 | 46 | w = (S*u)/(_sage_const_1 +B+u**_sage_const_2 ) 47 | x1 = (-_sage_const_1 +S)/_sage_const_2 -u*w 48 | x2 = -_sage_const_1 -x1 49 | x3 = _sage_const_1 +_sage_const_1 /w**_sage_const_2 50 | e = legendre_symbol(u,p) 51 | if is_square( f(x1) ) : 52 | return E( [ x1, e * sqrt(f(x1)) ]) 53 | elif is_square( f(x2) ) : 54 | return E( [ x2, e * sqrt(f(x2)) ]) 55 | else: 56 | return E( [ x3, e * sqrt(f(x3)) ]) 57 | 58 | def map2curve_ft_clear(alpha): 59 | return h * map2curve_ft(alpha) 60 | 61 | SQRT_MINUS3 = sqrt(F(-_sage_const_3 )) # Field arithmetic 62 | ONE_SQRT3_DIV2 = F((-_sage_const_1 +SQRT_MINUS3)/_sage_const_2 ) # Field arithmetic 63 | ORDER_OVER_2 = ZZ((p - _sage_const_1 )/_sage_const_2 ) # Integer arithmetic 64 | 65 | def map2curve_ft_slp(alpha): 66 | u = h2b_from_label(h2c_suite, alpha) 67 | tv("u ", u, _sage_const_48 ) 68 | 69 | u = F(u) 70 | t0 = u**_sage_const_2 # u^2 71 | t0 = t0+B+_sage_const_1 # u^2+B+1 72 | t0 = _sage_const_1 /t0 # 1/(u^2+B+1) 73 | t0 = t0*u # u/(u^2+B+1) 74 | t0 = t0*SQRT_MINUS3 # sqrt(-3)u/(u^2+B+1) 75 | assert t0 == F(sqrt(F(-_sage_const_3 ))*u/(u**_sage_const_2 +B+_sage_const_1 )) 76 | tv("t0", t0, _sage_const_48 ) 77 | 78 | x1 = ONE_SQRT3_DIV2-u*t0 # (-1+sqrt(-3))/2-sqrt(-3)u^2/(u^2+B+1) 79 | assert x1 == F((-_sage_const_1 +sqrt(F(-_sage_const_3 )))/_sage_const_2 -sqrt(F(-_sage_const_3 ))*u**_sage_const_2 /(u**_sage_const_2 +B+_sage_const_1 )) 80 | tv("x1", x1, _sage_const_48 ) 81 | 82 | x2 = -_sage_const_1 -x1 83 | assert x2 == F(-_sage_const_1 -((-_sage_const_1 +sqrt(F(-_sage_const_3 )))/_sage_const_2 -sqrt(F(-_sage_const_3 ))*u**_sage_const_2 /(u**_sage_const_2 +B+_sage_const_1 ))) 84 | tv("x2", x2, _sage_const_48 ) 85 | 86 | t1 = t0**_sage_const_2 87 | t1 = _sage_const_1 /t1 88 | x3 = t1+_sage_const_1 89 | assert x3 == F(_sage_const_1 +_sage_const_1 /t0**_sage_const_2 ) 90 | tv("x3", x3, _sage_const_48 ) 91 | 92 | e = u**ORDER_OVER_2 93 | assert e == legendre_symbol(u,p) 94 | tv("e", e, _sage_const_48 ) 95 | 96 | fx1 = x1**_sage_const_3 +B 97 | assert fx1 == F(x1**_sage_const_3 +B) 98 | tv("fx1", fx1, _sage_const_48 ) 99 | 100 | s1 = fx1**ORDER_OVER_2 101 | if s1 == _sage_const_1 : 102 | y1 = e*sqrt(fx1) 103 | tv("y1", y1, _sage_const_48 ) 104 | return E(x1, y1) 105 | 106 | fx2 = x2**_sage_const_3 +B 107 | assert fx2 == F(x2**_sage_const_3 +B) 108 | tv("fx2", fx2, _sage_const_48 ) 109 | 110 | s2 = fx2**ORDER_OVER_2 111 | if s2 == _sage_const_1 : 112 | y2 = e*sqrt(fx2) 113 | tv("y2", y2, _sage_const_48 ) 114 | return E(x2, y2) 115 | 116 | fx3 = x3**_sage_const_3 +B 117 | assert fx3 == F(x3**_sage_const_3 +B) 118 | tv("fx3", fx3, _sage_const_48 ) 119 | 120 | y3 = e*sqrt(fx3) 121 | tv("y3", y3, _sage_const_48 ) 122 | return E(x3, y3) 123 | 124 | 125 | if __name__ == "__main__": 126 | enable_debug() 127 | print "## Fouque-Tibouchi to BLS12-381 G1" 128 | for alpha in map2curve_alphas: 129 | tv_text("alpha", pprint_hex(alpha)) 130 | for alpha in map2curve_alphas: 131 | print "\n~~~" 132 | print("Input:") 133 | print("") 134 | tv_text("alpha", pprint_hex(alpha)) 135 | print("") 136 | print("Intermediate values:") 137 | print("") 138 | pA, pB = map2curve_ft(alpha), map2curve_ft_slp(alpha) 139 | assert pA == pB 140 | print("") 141 | print("Output:") 142 | print("") 143 | tv("x", pB[_sage_const_0 ], _sage_const_48 ) 144 | tv("y", pB[_sage_const_1 ], _sage_const_48 ) 145 | print "~~~" 146 | 147 | -------------------------------------------------------------------------------- /poc/map2curve_ft.sage.py: -------------------------------------------------------------------------------- 1 | 2 | # This file was *autogenerated* from the file map2curve_ft.sage 3 | from sage.all_cmdline import * # import sage library 4 | 5 | _sage_const_3 = Integer(3); _sage_const_2 = Integer(2); _sage_const_1 = Integer(1); _sage_const_0 = Integer(0); _sage_const_4 = Integer(4); _sage_const_48 = Integer(48); _sage_const_0x396c8c005555e1568c00aaab0000aaab = Integer(0x396c8c005555e1568c00aaab0000aaab); _sage_const_0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab = Integer(0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab); _sage_const_0xd201000000010000 = Integer(0xd201000000010000); _sage_const_0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5 = Integer(0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5)# H2C-xxx-SHA512-FT- outputs curve points that do not necessarily lie in the subgroup. 6 | # H2C-xxx-SHA512-FT-Clear would include cofactor clearing. 7 | # https://www.ietf.org/id/draft-irtf-cfrg-hash-to-curve-03.txt 8 | 9 | from hash_to_base import * 10 | from utils import * 11 | 12 | # BLS12-381 G1 curve 13 | t = -_sage_const_0xd201000000010000 14 | pp = lambda x: ((x-_sage_const_1 )**_sage_const_2 ) * ((x**_sage_const_4 - x**_sage_const_2 + _sage_const_1 )/_sage_const_3 ) + x 15 | p = _sage_const_0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab 16 | assert is_prime(p) 17 | assert p%_sage_const_3 == _sage_const_1 18 | assert p == pp(t) 19 | 20 | F = GF(p) 21 | A = F(_sage_const_0 ) 22 | B = F(_sage_const_4 ) 23 | E = EllipticCurve([A,B]) # y^2 = x^3 + 4 24 | S = sqrt(F(-_sage_const_3 )) 25 | assert is_square(_sage_const_1 +B) == false 26 | h = _sage_const_0x396c8c005555e1568c00aaab0000aaab # co-factor for G1 27 | 28 | # BLS12-381 G2 curve 29 | K2 = F ['U']; (U,) = K2._first_ngens(1) 30 | F2 = F.extension(U**_sage_const_2 +_sage_const_1 , names=('root',)); (root,) = F2._first_ngens(1) 31 | A2 = F2(_sage_const_0 ) 32 | B2 = F2(_sage_const_4 *root+_sage_const_1 ) 33 | E2 = EllipticCurve([A2,B2]) 34 | ## define S2? 35 | h2 = _sage_const_0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5 # co-factor for G2 36 | 37 | h2c_suite = "H2C-BLS12_381_1-SHA512-FT-" 38 | 39 | def f(x): 40 | return F(x**_sage_const_3 + A*x + B) 41 | 42 | def map2curve_ft(alpha): 43 | u = h2b_from_label(h2c_suite, alpha) 44 | u = F(u) 45 | 46 | w = (S*u)/(_sage_const_1 +B+u**_sage_const_2 ) 47 | x1 = (-_sage_const_1 +S)/_sage_const_2 -u*w 48 | x2 = -_sage_const_1 -x1 49 | x3 = _sage_const_1 +_sage_const_1 /w**_sage_const_2 50 | e = legendre_symbol(u,p) 51 | if is_square( f(x1) ) : 52 | return E( [ x1, e * sqrt(f(x1)) ]) 53 | elif is_square( f(x2) ) : 54 | return E( [ x2, e * sqrt(f(x2)) ]) 55 | else: 56 | return E( [ x3, e * sqrt(f(x3)) ]) 57 | 58 | def map2curve_ft_clear(alpha): 59 | return h * map2curve_ft(alpha) 60 | 61 | SQRT_MINUS3 = sqrt(F(-_sage_const_3 )) # Field arithmetic 62 | ONE_SQRT3_DIV2 = F((-_sage_const_1 +SQRT_MINUS3)/_sage_const_2 ) # Field arithmetic 63 | ORDER_OVER_2 = ZZ((p - _sage_const_1 )/_sage_const_2 ) # Integer arithmetic 64 | 65 | def map2curve_ft_slp(alpha): 66 | u = h2b_from_label(h2c_suite, alpha) 67 | tv("u ", u, _sage_const_48 ) 68 | 69 | u = F(u) 70 | t0 = u**_sage_const_2 # u^2 71 | t0 = t0+B+_sage_const_1 # u^2+B+1 72 | t0 = _sage_const_1 /t0 # 1/(u^2+B+1) 73 | t0 = t0*u # u/(u^2+B+1) 74 | t0 = t0*SQRT_MINUS3 # sqrt(-3)u/(u^2+B+1) 75 | assert t0 == F(sqrt(F(-_sage_const_3 ))*u/(u**_sage_const_2 +B+_sage_const_1 )) 76 | tv("t0", t0, _sage_const_48 ) 77 | 78 | x1 = ONE_SQRT3_DIV2-u*t0 # (-1+sqrt(-3))/2-sqrt(-3)u^2/(u^2+B+1) 79 | assert x1 == F((-_sage_const_1 +sqrt(F(-_sage_const_3 )))/_sage_const_2 -sqrt(F(-_sage_const_3 ))*u**_sage_const_2 /(u**_sage_const_2 +B+_sage_const_1 )) 80 | tv("x1", x1, _sage_const_48 ) 81 | 82 | x2 = -_sage_const_1 -x1 83 | assert x2 == F(-_sage_const_1 -((-_sage_const_1 +sqrt(F(-_sage_const_3 )))/_sage_const_2 -sqrt(F(-_sage_const_3 ))*u**_sage_const_2 /(u**_sage_const_2 +B+_sage_const_1 ))) 84 | tv("x2", x2, _sage_const_48 ) 85 | 86 | t1 = t0**_sage_const_2 87 | t1 = _sage_const_1 /t1 88 | x3 = t1+_sage_const_1 89 | assert x3 == F(_sage_const_1 +_sage_const_1 /t0**_sage_const_2 ) 90 | tv("x3", x3, _sage_const_48 ) 91 | 92 | e = u**ORDER_OVER_2 93 | assert e == legendre_symbol(u,p) 94 | tv("e", e, _sage_const_48 ) 95 | 96 | fx1 = x1**_sage_const_3 +B 97 | assert fx1 == F(x1**_sage_const_3 +B) 98 | tv("fx1", fx1, _sage_const_48 ) 99 | 100 | s1 = fx1**ORDER_OVER_2 101 | if s1 == _sage_const_1 : 102 | y1 = e*sqrt(fx1) 103 | tv("y1", y1, _sage_const_48 ) 104 | return E(x1, y1) 105 | 106 | fx2 = x2**_sage_const_3 +B 107 | assert fx2 == F(x2**_sage_const_3 +B) 108 | tv("fx2", fx2, _sage_const_48 ) 109 | 110 | s2 = fx2**ORDER_OVER_2 111 | if s2 == _sage_const_1 : 112 | y2 = e*sqrt(fx2) 113 | tv("y2", y2, _sage_const_48 ) 114 | return E(x2, y2) 115 | 116 | fx3 = x3**_sage_const_3 +B 117 | assert fx3 == F(x3**_sage_const_3 +B) 118 | tv("fx3", fx3, _sage_const_48 ) 119 | 120 | y3 = e*sqrt(fx3) 121 | tv("y3", y3, _sage_const_48 ) 122 | return E(x3, y3) 123 | 124 | 125 | if __name__ == "__main__": 126 | enable_debug() 127 | print "## Fouque-Tibouchi to BLS12-381 G1" 128 | for alpha in map2curve_alphas: 129 | tv_text("alpha", pprint_hex(alpha)) 130 | for alpha in map2curve_alphas: 131 | print "\n~~~" 132 | print("Input:") 133 | print("") 134 | tv_text("alpha", pprint_hex(alpha)) 135 | print("") 136 | print("Intermediate values:") 137 | print("") 138 | pA, pB = map2curve_ft(alpha), map2curve_ft_slp(alpha) 139 | assert pA == pB 140 | print("") 141 | print("Output:") 142 | print("") 143 | tv("x", pB[_sage_const_0 ], _sage_const_48 ) 144 | tv("y", pB[_sage_const_1 ], _sage_const_48 ) 145 | print "~~~" 146 | 147 | -------------------------------------------------------------------------------- /old_versions/draft-boneh-bls-signature-01.md: -------------------------------------------------------------------------------- 1 | %%% 2 | Title = "draft-boneh-bls-signature-00.txt" 3 | abbrev = "BLS-signature" 4 | category = "info" 5 | docName = "draft-boneh-bls-signature-00.txt" 6 | ipr= "trust200902" 7 | workgroup = "CFRG" 8 | 9 | date = 2019-02-08 10 | 11 | 12 | [[author]] 13 | initials="R." 14 | surname="Wahby" 15 | fullname="Riad S. Wahby" 16 | organization="Stanford University" 17 | [author.address] 18 | email = "rsw@cs.stanford.edu" 19 | [author.address.postal] 20 | city = "" 21 | country = "USA" 22 | [[author]] 23 | initials="D." 24 | surname="Boneh" 25 | fullname="Dan Boneh" 26 | organization="Stanford University" 27 | [author.address] 28 | email = "dabo@cs.stanford.edu" 29 | [author.address.postal] 30 | city = "" 31 | country = "USA" 32 | [[author]] 33 | initials="S." 34 | surname="Gorbunov" 35 | fullname="Sergey Gorbunov" 36 | organization="Algorand and University of Waterloo" 37 | [author.address] 38 | email = "sergey@algorand.com" 39 | [author.address.postal] 40 | city = "Boston, MA" 41 | country = "USA" 42 | [[author]] 43 | initials="H." 44 | surname="Wee" 45 | fullname="Hoeteck Wee" 46 | organization="Algorand and ENS, Paris" 47 | [author.address] 48 | email = "wee@di.ens.fr" 49 | [author.address.postal] 50 | city = "Boston, MA" 51 | country = "USA" 52 | [[author]] 53 | initials="Z." 54 | surname="Zhang" 55 | fullname="Zhenfei Zhang" 56 | organization="Algorand" 57 | [author.address] 58 | email = "zhenfei@algorand.com" 59 | [author.address.postal] 60 | city = "Boston, MA" 61 | country = "USA" 62 | %%% 63 | 64 | 65 | .# Abstract 66 | 67 | 68 | BLS is a digital signature scheme with compression properties. 69 | With a given set of signatures (sig_1, ..., sig_n) anyone can produce 70 | a compressed signature sig_compressed. The same is true for a set of 71 | private keys or public keys, while keeping the connection between sets 72 | (a compressed public key is associated to its compressed public key). 73 | Furthermore, the BLS signature scheme is deterministic, non-malleable, 74 | and efficient. Its simplicity and cryptographic properties allows it 75 | to be useful in a variety of use-cases, specifically when minimal 76 | storage space or bandwidth are required. 77 | 78 | 90 | 91 | 92 | 93 | {mainmatter} 94 | 95 | 96 | # Introduction 97 | 98 | A signature scheme is a fundamental cryptographic primitive 99 | used on the Internet and beyond that is used to protect authenticity and 100 | integrity of communication. 101 | Only holder of the secret key can sign messages, but anyone can 102 | verify the signature using the associated public key. 103 | 104 | Signature schemes are used in point-to-point secure communication 105 | protocols, PKI, remote connections, etc. 106 | Designing efficient and secure digital signature is very important 107 | for these applications. 108 | 109 | This document describes the BLS signature scheme. The scheme enjoys a variety 110 | of important efficiency properties: 111 | 112 | 1. The public key and the signatures are encoded as single group elements. 113 | 1. Verification requires 2 pairing operations. 114 | 1. A collection of signatures (signature_1, ..., signature_n) can be compressed 115 | into a single signature (signature). Moreover, the compressed signature can 116 | be verified using only n+1 pairings (as opposed to 2n pairings, when verifying 117 | naively n signatures). 118 | 119 | Given the above properties, 120 | 124 | the scheme enables many interesting applications. 125 | The immediate applications include 126 | * authentication and integrity for Public Key Infrastructure (PKI) and blockchains. 127 | 128 | * The usage is similar to classical digital signatures, such as ECDSA. 129 | 130 | * compressing signature chains for PKI and Secure Border Gateway Protocol (SBGP). 131 | 132 | * Concretely, in a PKI signature chain of depth n, we have n signatures by n 133 | certificate authorities on n distinct certificates. Similarly, in SBGP, 134 | each router receives a list of n signatures attesting to a path of length n 135 | in the network. In both settings, using the BLS signature scheme would allow us 136 | to compress the n signatures into a single signature. 137 | 138 | * consensus protocols for blockchains. 139 | 140 | * There, BLS signatures 141 | are used for authenticating transactions as well as votes during the consensus 142 | protocol, and the use of aggregation significantly reduces the bandwidth 143 | and storage requirements. 144 | 145 | ## Comparison with ECDSA 146 | 147 | The following comparison assumes BLS signatures with curve BLS12-381, targeting 148 | 128 bits security. 149 | 150 | For 128 bits security, ECDSA takes 37 and 79 micro-seconds to sign and verify 151 | a signature on a typical laptop. In comparison, for the same level of security, 152 | BLS takes 370 and 2700 micro-seconds to sign and verify 153 | a signature. 154 | 155 | In terms of sizes, ECDSA uses 32 bytes for public keys and 64 bytes for signatures; 156 | while BLS uses 96 bytes for public keys, and 48 bytes for signatures. 157 | Alternatively, BLS can also be instantiated with 48 bytes of public keys and 96 bytes 158 | of signatures. 159 | BLS also allows for signature compression. In other words, a single signature is 160 | sufficient to anthenticate multiple messages and public keys. 161 | 162 | 166 | 167 | ## Terminology 168 | 169 | The following terminology is used through this document: 170 | 171 | * SK: The private key for the signature scheme. 172 | 173 | * PK: The public key for the signature scheme. 174 | 175 | * message: The input to be signed by the signature scheme. 176 | 177 | * signature: The digital signature output. 178 | 179 | * compression: Given a list of signatures for a list of messages and public keys, 180 | generate a new signature that authenticates the same list of messages and public keys. 181 | 182 | 191 | 192 | ## Signature Scheme Algorithms and Properties 193 | 194 | Like most signature schemes, 195 | BLS comes with the following API: 196 | 197 | * a key generation algorithm that generates a public 198 | key PK and a private key SK 199 | 200 | KeyGen() -> PK, SK 201 | 202 | * a sign algorithm that generates a deterministic signature for a message and a 203 | secret key 204 | 205 | Sign(SK, message) -> signature 206 | 218 | 219 | * a verification algorithm that outputs VALID if signature is a valid signature of message, and INVALID otherwise. 220 | 221 | 225 | 226 | Verify(PK, message, signature) -> VALID or INVALID 227 | 228 | 231 | We require that SK, PK, signature and message are octet strings. 232 | 233 | ### Aggregation 234 | 235 | An aggregatable signature scheme includes an algorithm that allows to compress a 236 | collection of signatures into a short signature. 237 | 238 | Aggregate((PK_1, signature_1), ..., (PK_n, signature_n)) -> signature 239 | 240 | Note that the aggregator does not need to know the messages corresponding to individual 241 | signatures. 242 | 243 | The scheme also includes an algorithm to verify an aggregated signature, given a collection 244 | of corresponding public keys, the aggregated signature, and one or more messages. 245 | 246 | Verify-Aggregated((PK_1, message_1), ..., (PK_n, message_n), signature) -> VALID or INVALID 247 | 248 | that outputs VALID if signature is a valid aggregated signature of messages message_1, ..., message_n, and 249 | INVALID otherwise. 250 | 251 | The verification algorithm may also accept a simpler interface that allows 252 | to verify an aggregate signature of the same message. That is, message_1 = message_2 = ... = message_n. 253 | 254 | Verify-Aggregated(PK_1, ..., PK_n, message, signature) -> VALID or INVALID 255 | 256 | 257 | 258 | 259 | ## Dependencies 260 | 261 | This draft has the following dependencies: 262 | 263 | 264 | * it relies on the [I-D.irtf-cfrg-hash-to-curve] 265 | for methods to convert binary strings 266 | into group elements 267 | * it relies on [I-D.pairing-friendly-curves] for pairings 268 | and related operations. 269 | 270 | # BLS Signature 271 | 272 | BLS signatures require pairing-friendly curves 273 | given by e : G1 x G2 -> GT, where G1, G2 are prime-order 274 | subgroups of elliptic curve groups E1, E2. 275 | This draft suggests to use curve BLS12-381 as 276 | described in [I-D.pairing-friendly-curves]. 277 | Support of other curves SHALL be defined in 278 | extensions or future versions of this draft, or in 279 | separate 280 | documents. 281 | 282 | There are two variants of the scheme: 283 | 284 | 1. (minimizing signature size) Use G1 to host data types of signatures 285 | and G2 for public keys, where G1/E1 has the more compact representation. 286 | For instance, when instantiated with the pairing-friendly curve 287 | BLS12-381, this yields signature size of 48 bytes, whereas 288 | the ECDSA signature over curve25519 has a signature size of 289 | 64 byes. 290 | 291 | 2. (minimizing public key size) Use G1 to host data types of public keys and 292 | G2 for signatures. This latter case comes up when we do signature aggregation, 293 | where most of the communication costs come from public keys. This 294 | is particularly relevant in applications such as blockchains 295 | and compressing certificate chains, where the goal is to minimize 296 | the total size of multiple public keys and aggregated signatures. 297 | 298 | The rest of the write-up assumes the first variant. 299 | It is straightforward to obtain algorithms for the 300 | second variant from those of the first variant where we simply 301 | swap G1,E1 with G2,E2 respectively. 302 | 303 | 304 | 328 | 329 | ## Preliminaries 330 | 331 | Notation and primitives used: 332 | 333 | - E1, E2 - elliptic curves (EC) defined over a field 334 | 335 | - P1, P2 - elements of E1,E2 of prime order r 336 | 337 | - G1, G2 - prime-order subgroups of E1, E2 generated by P1, P2 338 | 339 | - GT - order r subgroup of the multiplicative group over a field 340 | 341 | - We require an efficient pairing: (G1, G2) -> GT that is 342 | bilinear and non-degenerate. 343 | 344 | - Elliptic curve operations in E1 and E2 are written in additive notation, with P+Q 345 | denoting point addition and x*P denoting scalar multiplication 346 | of a point P by a scalar x. 347 | 348 | TBD: [I-D.pairing-friendly-curves] uses the notation x[P]. 349 | 350 | - Field operations in GT are written in multiplicative notation, with a*b denoting 351 | field element multiplication. 352 | 353 | - || - octet string concatenation 354 | 355 | - domain_separator - an identifier for the ciphersuite. In current draft "BLS12_381-SHA384-try_and_increment". Future identifiers MUST include 356 | an identifier of the curve, for example BLS12-381, an identifier of the hash function, for example SHA512, and the algorithm in use, for example, try-and-increment. 357 | 358 | Type conversions: 359 | 360 | - int_to_string(a, len) - conversion of nonnegative integer a to 361 | octet string of length len. 362 | 363 | - string_to_int(a_string) - conversion of octet string a_string 364 | to nonnegative integer. 365 | 366 | - E1_to_string - conversion of E1 point to octet string 367 | 368 | - string_to_E1 - conversion of octet string to E1 point. 369 | Returns INVALID if the octet string does not convert to a valid E1 point. 370 | 371 | Hashing Algorithms 372 | 373 | - hash_to_G1 - cryptographic hashing of octet string to G1 element. 374 | Must return a valid G1 element. Specified in Section {{auxiliary}}. 375 | 376 | 379 | 380 | ## Keygen: Key Generation 381 | 382 | 383 | Output: PK, SK 384 | 385 | 1. SK = x, chosen as a random integer in the range 1 and r-1 386 | 1. PK = x*P2 387 | 1. Output PK, SK 388 | 389 | 390 | ## Sign: Signature Generation 391 | 392 | Input: SK = x, message Output: signature 393 | 394 | 1. Input a secret key SK = x and a message digest message 395 | 1. H = hash_to_G1(suite_string, message) 396 | 1. Gamma = x*H 397 | 1. signature = E1_to_string(Gamma) 398 | 1. Output signature 399 | 400 | 401 | ## Verify: Signature Verification 402 | 403 | Input: PK, message, signature Output: "VALID" or "INVALID" 404 | 405 | 1. H = hash_to_G1(suite_string, message) 406 | 1. Gamma = string_to_E1(signature) 407 | 1. If Gamma is "INVALID", output "INVALID" and stop 408 | 1. If r*Gamma != 0, output "INVALID" and stop 409 | 1. Compute c = pairing(Gamma, P2) 410 | 1. Compute c' = pairing(H, PK) 411 | 1. If c and c' are equal, output "VALID", 412 | else output "INVALID" 413 | 414 | ## Aggregate 415 | The following algorithm works for both the same message aggregation and different 416 | message aggregation. 417 | 418 | 419 | Input: (PK_1, signature_1), ..., (PK_n, signature_n) Output: signature 420 | 421 | 1. Output signature = E1_to_string(string_to_E1(signature_1) + ... + 422 | string_to_E1(signature_n)) 423 | 424 | ### Verify-Aggregated-1 425 | 426 | Input: (PK_1, ..., PK_n), message, signature Output: "VALID" or "INVALID" 427 | 428 | 1. PK' = PK_1 + ... + PK_n 429 | 1. Output Verify(PK', message, signature) 430 | 431 | ### Verify-Aggregated-n 432 | 433 | Input: (PK_1, message_1), ..., (PK_n, message_n), signature 434 | Output: "VALID" or "INVALID" 435 | 436 | 1. H_i = hash_to_G1(suite_string, message_i) 437 | 1. Gamma = string_to_E1(signature) 438 | 1. If Gamma is "INVALID", output "INVALID" and stop 439 | 1. If r*Gamma != 0, output "INVALID" and stop 440 | 1. Compute c = pairing(Gamma, P2) 441 | 1. Compute c' = pairing(H_1, PK_1) * ... * pairing(H_n, PK_n) 442 | 1. If c and c' are equal, output "VALID", 443 | else output "INVALID" 444 | 445 | 446 | 447 | 448 | ## Auxiliary Functions {#auxiliary} 449 | 450 | Here, we describe the auxiliary functions relating to serialization 451 | and hashing to the elliptic curves E, where E may be E1 or E2. 452 | 453 | (Authors' note: this section is extremely preliminary and we anticipate 454 | substantial updates pending feedback from the community. We describe 455 | a generic approach for hashing, in order to cover hashing into 456 | curves defined over prime power extension fields, which are not covered in 457 | [I-D.irtf-cfrg-hash-to-curve]. We expect to support several different hashing 458 | algorithms specified via the suite_string.) 459 | 460 | ### Preliminaries 461 | In all the pairing-friendly curves, E is defined over a field 462 | GF(p^k). We also assume an explicit isomorphism that allows us to 463 | treat GF(p^k) as GF(p). In most of the curves in [I-D.pairing-friendly-curves], 464 | we have k=1 for E1 and k=2 for E2. 465 | 466 | Each point (x,y) on E can be specified by the 467 | x-coordinate in GP(p)^k plus a single bit to determine whether the point 468 | is (x,y) or (x,-y), thus requiring k log(p) + 1 bits [I-D.irtf-cfrg-hash-to-curve]. 469 | 470 | Concretely, we encode a point (x,y) on E as a string comprising k substrings 471 | s_1, ..., s_k each of length log(p)+2 bits, where 472 | 473 | * the first bit of s_1 indicates whether E is the point at infinity 474 | * the second bit of s_1 indicates whether the point is (x,y) or (x,-y) 475 | * the first two bits of s_2, ..., s_k are 00 476 | * the x-coordinate is specified by the last log(p) bits of s_1, ..., s_k 477 | 478 | In fact, we will pad each substring with 0 bits so that the length of each substring 479 | is a multiple of 8 bits. 480 | 481 | This section uses the following constants: 482 | 483 | * pbits: the number of bits to represent integers modulo p. 484 | * padded_pbits: the smallest multiple of 8 that is greater than pbits+2. 485 | * padlen: padded_pbits - padlen 486 | 487 | | curve | pbits | padded_pbits | padlen | 488 | |-------|-------|--------------|--------| 489 | |BLS-381| 381 | 384 | 3 | 490 | 491 | 492 | ### Type conversions 493 | 494 | 497 | 498 | In general we view a string str as a vector of substrings s_1, ... s_k for k >= 1; 499 | each substring is of padded_pbits bits; and k is set properly according to the individual 500 | curve. 501 | For example, for BLS12-381 curve, k=1 for E1 and 2 for E2. 502 | If the input string is not a multiple of padded_pbits, we 503 | tail pad the string to meet the correct length. 504 | 505 | A string that encodes an E1/E2 point may have the following structure: 506 | * for the first substring s_1 507 | * the first bit indicates if the point is the point at infinity 508 | * the second bit is either 0 or 1, denoted by y_bit 509 | * the third to padlen bits are 0 510 | 511 | * for the rest substrings s_2, ... s_k 512 | * the first padlen bits are 0s 513 | 514 | TBD: some implementation uses an additional leading bit to indicate the 515 | string is in a compressed form (give x coordinate and the parity/sign of y coordinate) 516 | or in an uncompressed form (give both x and y coordinate). 517 | 518 | #### curve-to-string 519 | 520 | Input: 521 | 522 | input_string - a point P = (x, y) on the curve 523 | 524 | Output: 525 | 526 | a string of k * padded_pbits 527 | 528 | Steps: 529 | 530 | 1. If P is the point at infinity, output 0b1000...0 531 | 2. Parse y as y_1, ..., y_k; set y_bit as y_1 mod 2 532 | 2. Parse x as x_1, ..., x_k 533 | 3. set the substring s_1 = 0 | y_bit | padlen-2 of 0s | int_to_string(x_1) 534 | 4. set substrings s_i = padlen of 0s | int_to_string(x_i) for 2<=i<=k 535 | 5. Output the string s_1 | s_2 | ... | s_k 536 | 537 | 538 | #### string-to-curve 539 | 540 | The algorithm takes as follows: 541 | 542 | Input: 543 | 544 | input_string - a single octet string. 545 | 546 | Output: 547 | 548 | Either a point P on the curve, or INVALID 549 | 550 | Steps: 551 | 552 | 1. If length(input_string) is < padded_pbits/8 bytes, lead pad input_string with 0s; 553 | 554 | 1. If length(input_string) is not a multiple of padded_pbits/8 bytes, tail pad with 0, ..., 0; 555 | 556 | 1. Parse input_string as a vector of substrings s_1, ..., s_k 557 | 558 | 3. b = s_1[0]; i.e., the first byte of the first substring; 559 | 560 | 4. If the first bit of b is 1, return P = 0 (the point at infinity) 561 | 562 | 5. Set y_bit to be the second bit of b and then set the second bit of b to 0 563 | 564 | 6. If the third to plen bits of input_string are not 0, return INVALID 565 | 566 | 6. Set x_1 = string_to_int(s_1) 567 | 1. if x_1 > p then return INVALID 568 | 569 | 7. for i in [2 ... k] 570 | 571 | 1. b = s_i[0] 572 | 2. if top plen bits of b is not 0, return INVALID 573 | 3. set x_i = string_to_int(s_i) 574 | 1. if x_1 > p then return INVALID 575 | 8. Set x= (x_1, ..., x_k) 576 | 577 | 7. solve for y so that (x, y) satisfies elliptic curve equation; 578 | * output INVALID if equation is not solvable with x 579 | * parse y as (y_1, ..., y_k) 580 | * if solutions exist, there should be a pair of ys where y_1-s differ by parity 581 | * set y to be the solution where y_1 is odd if y_bit = 1 582 | * set y to be the solution where y_1 is even if y_bit = 0 583 | 8. output P = (x, y) as a curve point. 584 | 585 | TBD: check the parity property remains true for E2. The Chia and Etherum implementations 586 | use lexicographic ordering. 587 | 588 | ### Membership test 589 | 590 | The following g1_membership_test and g1_membership_test algorithms is to 591 | check if a E1 or E2 point is in the correct prime subgroup. Example: 592 | 593 | r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 594 | 595 | for curve BLS12-381. 596 | 597 | 598 | 599 | g1_membership_test(input_point) 600 | 601 | input: 602 | 603 | input_point - a point P = (x, y) on the curve E1 604 | 605 | Output: 606 | 607 | "VALID" if P is in G1; "INVALID" otherwise 608 | 609 | Steps: 610 | 611 | 1. r = order of group G1 612 | 1. if r * P == 1 return "VALID", otherwise, return "INVALID" 613 | 614 | 615 | 616 | g2_membership_test(input_point) 617 | 618 | input: 619 | 620 | input_point - a point P = (x, y) on the curve E2 621 | 622 | Output: 623 | 624 | "VALID" if P is in G2; "INVALID" otherwise 625 | 626 | Steps: 627 | 628 | 1. r = order of group G2 629 | 1. if r * P == 1 return "VALID", otherwise, return "INVALID" 630 | 631 | 632 | 633 | # Security Considerations 634 | 635 | ## Verifying public keys 636 | When users register a public key, we should ensure that it is well-formed. 637 | This requires a G2 membership test. In applications where we use aggregation, 638 | we need to enforce security against rogue key attacks [Boneh-Drijvers-Neven 18a](https://crypto.stanford.edu/~dabo/pubs/papers/BLSmultisig.html). 639 | This can be achieved in one of three ways: 640 | 641 | * Message augmentation: pk = g^sk, sig = H(pk, m)^sk 642 | (BGLS, [Bellare-Namprempre-Neven 07](https://eprint.iacr.org/2006/285)). 643 | 644 | * Proof of possession: pk = ( u=g^sk, H'(u)^sk ), sig = H(m)^sk 645 | (see concrete mechanisms in [Ristenpart-Yilek 06]) 646 | 647 | * Linear combination: agg = sig_1^t_1 ... sig_n^t_n 648 | (see [Boneh-Drijvers-Neven 18b](https://eprint.iacr.org/2018/483.pdf); 649 | there, pre-processing public keys would speed up verification.) 650 | 651 | ## Skipping membership check 652 | Several existing implementations skip step 4 (membership in G1) in Verify. 653 | In this setting, the BLS signature remains unforgeable (but not strongly 654 | unforgeable) under a stronger assumption: 655 | 656 | given P1, a*P1, P2, b*P2, it is hard to compute U in E1 such that 657 | pairing(U,P2) = pairing(a*P1, b*P2). 658 | 659 | ## Side channel attacks 660 | It is important to protect the secret key in implementations of the 661 | signing algorithm. We can protect against some side-channel attacks by 662 | ensuring that the implementation executes exactly the same sequence of 663 | instructions and performs exactly the same memory accesses, for any 664 | value of the secret key. To achieve this, we require that 665 | point multiplication in G1 should run in constant time with respect to 666 | the scalar. 667 | 668 | ## Randomness considerations 669 | BLS signatures are deterministic. This protects against attacks 670 | arising from signing with bad randomness, for example, the nounce reusing 671 | attack in ECDSA [HDWH 12]. 672 | 673 | 681 | 682 | ## Implementing the hash function 683 | The security analysis models the hash function H as a random oracle, 684 | and it is crucial that we implement H using a cryptographically 685 | secure hash function. 686 | 690 | 691 | 692 | # Implementation Status 693 | 694 | This section will be removed in the final version of the draft. 695 | There are currently several implementations of BLS signatures using the BLS12-381 curve. 696 | 697 | * Algorand: TBA 698 | 699 | * Chia: [spec](https://github.com/Chia-Network/bls-signatures/blob/master/SPEC.md) 700 | [python/C++](https://github.com/Chia-Network/bls-signatures). Here, they are 701 | swapping G1 and G2 so that the public keys are small, and the benefits 702 | of avoiding a membership check during signature verification would even be more 703 | substantial. The current implementation does not seem to implement the membership check. 704 | Chia uses the Fouque-Tibouchi hashing to the curve, which can be done in constant time. 705 | 706 | * Dfinity: [go](https://github.com/dfinity/go-dfinity-crypto) [BLS](https://github.com/dfinity/bls). The current implementations do not seem to implement the membership check. 707 | 708 | * Ethereum 2.0: [spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/bls_signature.md) 709 | 710 | # Related Standards 711 | 712 | * Pairing-friendly curves [draft-yonezawa-pairing-friendly-curves](https://tools.ietf.org/html/draft-yonezawa-pairing-friendly-curves-00) 713 | 714 | * Pairing-based Identity-Based Encryption [IEEE 1363.3](https://ieeexplore.ieee.org/document/6662370). 715 | 716 | * Identity-Based Cryptography Standard [rfc5901](https://tools.ietf.org/html/rfc5091). 717 | 718 | * Hashing to Elliptic Curves [draft-irtf-cfrg-hash-to-curve-02](https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-02), in order to implement the hash function H. The current draft does not cover pairing-friendly curves, where we need to handle curves over prime power extension fields GF(p^k). 719 | 720 | * Verifiable random functions [draft-irtf-cfrg-vrf-03](https://tools.ietf.org/html/draft-irtf-cfrg-vrf-03). Section 5.4.1 also discusses instantiations for H. 721 | 722 | * EdDSA [rfc8032](https://tools.ietf.org/html/rfc8032) 723 | 724 | 725 | 730 | 731 | # Appendix A. Test Vectors 732 | 733 | 734 | TBA: (i) test vectors for both variants of the signature scheme 735 | (signatures in G2 instead of G1) , (ii) test vectors ensuring 736 | membership checks, (iii) intermediate computations ctr, hm. 737 | 738 | 794 | 795 | # Appendix B. Security 796 | 797 | ## Definitions 798 | ### Message Unforgeability 799 | 800 | Consider the following game between an adversary and a challenger. 801 | The challenger generates a key-pair (PK, SK) and gives PK to the adversary. 802 | The adversary may repeatedly query the challenger on any message message to obtain 803 | its corresponding signature signature. Eventually the adversary outputs a pair 804 | (message', signature'). 805 | 806 | Unforgeability means no adversary can produce a pair (message', signature') for a message message' which he never queried the challenger and Verify(PK, message, signature) outputs VALID. 807 | 808 | 809 | ### Strong Message Unforgeability 810 | 811 | In the strong unforgeability game, the game proceeds as above, except 812 | no adversary should be able to produce a pair (message', signature') that verifies (i.e. Verify(PK, message, signature) 813 | outputs VALID) given that he never queried the challenger on message', or if he did query and obtained 814 | a reply signature, then signature != signature'. 815 | 816 | More informally, the strong unforgeability means that no adversary can produce 817 | a different signature (not provided by the challenger) on a message which he queried before. 818 | 819 | ### Aggregation Unforgeability 820 | 821 | Consider the following game between an adversary and a challenger. 822 | The challenger generates a key-pair (PK, SK) and gives PK to the adversary. 823 | The adversary may repeatedly query the challenger on any message message to obtain 824 | its corresponding signature signature. 825 | Eventually the adversary outputs a sequence ((PK_1, message_1), ..., (PK_n, message_n), (PK, message), signature). 826 | 827 | Aggregation unforgeability means that no adversary can produce a sequence 828 | where it did not query the challenger on the message message, and 829 | Verify-Aggregated((PK_1, message_1), ..., (PK_n, message_n), (PK, message), signature) outputs VALID. 830 | 831 | We note that aggregation unforgeability implies message unforgeability. 832 | 833 | TODO: We may also consider a strong aggregation unforgeability property. 834 | 835 | ## Security analysis 836 | 837 | The BLS signature scheme achieves strong message unforgeability and aggregation 838 | unforgeability under the co-CDH 839 | assumption, namely that given P1, a*P1, P2, b*P2, it is hard to 840 | compute {ab}*P1. [BLS01, BGLS03] 841 | 842 | 843 | # Appendix C. Reference 844 | 845 | [BLS 01] Dan Boneh, Ben Lynn, Hovav Shacham: 846 | Short Signatures from the Weil Pairing. ASIACRYPT 2001: 514-532. 847 | 848 | [BGLS 03] Dan Boneh, Craig Gentry, Ben Lynn, Hovav Shacham: 849 | Aggregate and Verifiably Encrypted Signatures from Bilinear Maps. EUROCRYPT 2003: 416-432. 850 | 851 | [HDWH 12] 852 | Heninger, N., Durumeric, Z., Wustrow, E., Halderman, J.A.: 853 | "Mining your Ps and Qs: Detection of widespread weak keys in network devices.", 854 | USENIX 2012. 855 | 856 | [I-D.irtf-cfrg-hash-to-curve] 857 | S. Scott, N. Sullivan, and C. Wood: 858 | "Hashing to Elliptic Curves", 859 | draft-irtf-cfrg-hash-to-curve-01 (work in progress), 860 | July 2018. 861 | 862 | [I-D.pairing-friendly-curves] 863 | S. Yonezawa, S. Chikara, T. Kobayashi, T. Saito: 864 | "Pairing-Friendly Curves", 865 | draft-yonezawa-pairing-friendly-curves-00, 866 | Jan 2019. 867 | -------------------------------------------------------------------------------- /old_versions/draft-boneh-bls-signature.md: -------------------------------------------------------------------------------- 1 | %%% 2 | Title = "draft-boneh-bls-signature-00.txt" 3 | abbrev = "BLS-signature" 4 | category = "info" 5 | docName = "draft-boneh-bls-signature-00.txt" 6 | ipr= "trust200902" 7 | workgroup = "CFRG" 8 | 9 | date = 2019-02-08 10 | 11 | 12 | [[author]] 13 | initials="D." 14 | surname="Boneh" 15 | fullname="Dan Boneh" 16 | organization="Stanford University" 17 | [author.address] 18 | email = "" 19 | [author.address.postal] 20 | city = "" 21 | country = "USA" 22 | [[author]] 23 | initials="S." 24 | surname="Gorbunov" 25 | fullname="Sergey Gorbunov" 26 | organization="Algorand and University of Waterloo" 27 | [author.address] 28 | email = "sergey@algorand.com" 29 | [author.address.postal] 30 | city = "Boston, MA" 31 | country = "USA" 32 | [[author]] 33 | initials="H." 34 | surname="Wee" 35 | fullname="Hoeteck Wee" 36 | organization="Algorand and ENS, Paris" 37 | [author.address] 38 | email = "hoeteck@algorand.com" 39 | [author.address.postal] 40 | city = "Boston, MA" 41 | country = "USA" 42 | [[author]] 43 | initials="Z." 44 | surname="Zhang" 45 | fullname="Zhenfei Zhang" 46 | organization="Algorand" 47 | [author.address] 48 | email = "zhenfei@algorand.com" 49 | [author.address.postal] 50 | city = "Boston, MA" 51 | country = "USA" 52 | %%% 53 | 54 | 55 | .# Abstract 56 | 57 | 58 | BLS is a digital signature scheme with compression properties. 59 | With a given set of signatures (sig_1, ..., sig_n) anyone can produce 60 | a compressed signature sig_compressed. The same is true for a set of 61 | private keys or public keys, while keeping the connection between sets 62 | (a compressed public key is associated to its compressed public key). 63 | Furthermore, the BLS signature scheme is deterministic, non-malleable, 64 | and efficient. Its simplicity and cryptographic properties allows it 65 | to be useful in a variety of use-cases, specifically when minimal 66 | storage space or bandwidth are required. 67 | 68 | 80 | 81 | 82 | 83 | {mainmatter} 84 | 85 | 86 | # Introduction 87 | 88 | A signature scheme is a fundamental cryptographic primitive 89 | used on the Internet and beyond that is used to protect authenticity and 90 | integrity of communication. 91 | Only holder of the secret key can sign messages, but anyone can 92 | verify the signature using the associated public key. 93 | 94 | Signature schemes are used in point-to-point secure communication 95 | protocols, PKI, remote connections, etc. 96 | Designing efficient and secure digital signature is very important 97 | for these applications. 98 | 99 | This document describes the BLS signature scheme. The scheme enjoys a variety 100 | of important efficiency properties: 101 | 102 | 1. The public key and the signatures are encoded as single group elements. 103 | 1. Verification requires 2 pairing operations. 104 | 1. A collection of signatures (signature_1, ..., signature_n) can be compressed 105 | into a single signature (signature). Moreover, the compressed signature can 106 | be verified using only n+1 pairings (as opposed to 2n pairings, when verifying 107 | naively n signatures). 108 | 109 | Given the above properties, 110 | 114 | the scheme enables many interesting applications. 115 | The immediate applications include 116 | * authentication and integrity for Public Key Infrastructure (PKI) and blockchains. 117 | 118 | * The usage is similar to classical digital signatures, such as ECDSA. 119 | 120 | * compressing signature chains for PKI and Secure Border Gateway Protocol (SBGP). 121 | 122 | * Concretely, in a PKI signature chain of depth n, we have n signatures by n 123 | certificate authorities on n distinct certificates. Similarly, in SBGP, 124 | each router receives a list of n signatures attesting to a path of length n 125 | in the network. In both settings, using the BLS signature scheme would allow us 126 | to compress the n signatures into a single signature. 127 | 128 | * consensus protocols for blockchains. 129 | 130 | * There, BLS signatures 131 | are used for authenticating transactions as well as votes during the consensus 132 | protocol, and the use of aggregation significantly reduces the bandwidth 133 | and storage requirements. 134 | 135 | ## Comparison with ECDSA 136 | 137 | The following comparison assumes BLS signatures with curve BLS12-381, targeting 138 | 128 bits security. 139 | 140 | For 128 bits security, ECDSA takes 37 and 79 micro-seconds to sign and verify 141 | a signature on a typical laptop. In comparison, for the same level of security, 142 | BLS takes 370 and 2700 micro-seconds to sign and verify 143 | a signature. 144 | 145 | In terms of sizes, ECDSA uses 32 bytes for public keys and 64 bytes for signatures; 146 | while BLS uses 96 bytes for public keys, and 48 bytes for signatures. 147 | Alternatively, BLS can also be instantiated with 48 bytes of public keys and 96 bytes 148 | of signatures. 149 | BLS also allows for signature compression. In other words, a single signature is 150 | sufficient to anthenticate multiple messages and public keys. 151 | 152 | 156 | 157 | ## Terminology 158 | 159 | The following terminology is used through this document: 160 | 161 | * SK: The private key for the signature scheme. 162 | 163 | * PK: The public key for the signature scheme. 164 | 165 | * message: The input to be signed by the signature scheme. 166 | 167 | * signature: The digital signature output. 168 | 169 | * compression: Given a list of signatures for a list of messages and public keys, 170 | generate a new signature that authenticates the same list of messages and public keys. 171 | 172 | 181 | 182 | ## Signature Scheme Algorithms and Properties 183 | 184 | Like most signature schemes, 185 | BLS comes with the following API: 186 | 187 | * a key generation algorithm that generates a public 188 | key PK and a private key SK 189 | 190 | KeyGen() -> PK, SK 191 | 192 | * a sign algorithm that generates a deterministic signature for a message and a 193 | secret key 194 | 195 | Sign(SK, message) -> signature 196 | 208 | 209 | * a verification algorithm that outputs VALID if signature is a valid signature of message, and INVALID otherwise. 210 | 211 | 215 | 216 | Verify(PK, message, signature) -> VALID or INVALID 217 | 218 | 221 | We require that SK, PK, signature and message are octet strings. 222 | 223 | ### Aggregation 224 | 225 | An aggregatable signature scheme includes an algorithm that allows to compress a 226 | collection of signatures into a short signature. 227 | 228 | Aggregate((PK_1, signature_1), ..., (PK_n, signature_n)) -> signature 229 | 230 | Note that the aggregator does not need to know the messages corresponding to individual 231 | signatures. 232 | 233 | The scheme also includes an algorithm to verify an aggregated signature, given a collection 234 | of corresponding public keys, the aggregated signature, and one or more messages. 235 | 236 | Verify-Aggregated((PK_1, message_1), ..., (PK_n, message_n), signature) -> VALID or INVALID 237 | 238 | that outputs VALID if signature is a valid aggregated signature of messages message_1, ..., message_n, and 239 | INVALID otherwise. 240 | 241 | The verification algorithm may also accept a simpler interface that allows 242 | to verify an aggregate signature of the same message. That is, message_1 = message_2 = ... = message_n. 243 | 244 | Verify-Aggregated(PK_1, ..., PK_n, message, signature) -> VALID or INVALID 245 | 246 | 247 | 248 | 249 | ## Dependencies 250 | 251 | This draft has the following dependencies: 252 | 253 | 254 | * it relies on the [I-D.irtf-cfrg-hash-to-curve] 255 | for methods to convert binary strings 256 | into group elements 257 | * it relies on [I-D.pairing-friendly-curves] for pairings 258 | and related operations. 259 | 260 | # BLS Signature 261 | 262 | BLS signatures require pairing-friendly curves 263 | given by e : G1 x G2 -> GT, where G1, G2 are prime-order 264 | subgroups of elliptic curve groups E1, E2. 265 | This draft suggests to use curve BLS12-381 as 266 | described in [I-D.pairing-friendly-curves]. 267 | Support of other curves SHALL be defined in 268 | extensions or future versions of this draft, or in 269 | separate 270 | documents. 271 | 272 | There are two variants of the scheme: 273 | 274 | 1. (minimizing signature size) Use G1 to host data types of signatures 275 | and G2 for public keys, where G1/E1 has the more compact representation. 276 | For instance, when instantiated with the pairing-friendly curve 277 | BLS12-381, this yields signature size of 48 bytes, whereas 278 | the ECDSA signature over curve25519 has a signature size of 279 | 64 byes. 280 | 281 | 2. (minimizing public key size) Use G1 to host data types of public keys and 282 | G2 for signatures. This latter case comes up when we do signature aggregation, 283 | where most of the communication costs come from public keys. This 284 | is particularly relevant in applications such as blockchains 285 | and compressing certificate chains, where the goal is to minimize 286 | the total size of multiple public keys and aggregated signatures. 287 | 288 | The rest of the write-up assumes the first variant. 289 | It is straightforward to obtain algorithms for the 290 | second variant from those of the first variant where we simply 291 | swap G1,E1 with G2,E2 respectively. 292 | 293 | 294 | 318 | 319 | ## Preliminaries 320 | 321 | Notation and primitives used: 322 | 323 | - E1, E2 - elliptic curves (EC) defined over a field 324 | 325 | - P1, P2 - elements of E1,E2 of prime order r 326 | 327 | - G1, G2 - prime-order subgroups of E1, E2 generated by P1, P2 328 | 329 | - GT - order r subgroup of the multiplicative group over a field 330 | 331 | - We require an efficient pairing: (G1, G2) -> GT that is 332 | bilinear and non-degenerate. 333 | 334 | - Elliptic curve operations in E1 and E2 are written in additive notation, with P+Q 335 | denoting point addition and x*P denoting scalar multiplication 336 | of a point P by a scalar x. 337 | 338 | TBD: [I-D.pairing-friendly-curves] uses the notation x[P]. 339 | 340 | - Field operations in GT are written in multiplicative notation, with a*b denoting 341 | field element multiplication. 342 | 343 | - || - octet string concatenation 344 | 345 | - domain_separator - an identifier for the ciphersuite. In current draft "BLS12_381-SHA384-try_and_increment". Future identifiers MUST include 346 | an identifier of the curve, for example BLS12-381, an identifier of the hash function, for example SHA512, and the algorithm in use, for example, try-and-increment. 347 | 348 | Type conversions: 349 | 350 | - int_to_string(a, len) - conversion of nonnegative integer a to 351 | octet string of length len. 352 | 353 | - string_to_int(a_string) - conversion of octet string a_string 354 | to nonnegative integer. 355 | 356 | - E1_to_string - conversion of E1 point to octet string 357 | 358 | - string_to_E1 - conversion of octet string to E1 point. 359 | Returns INVALID if the octet string does not convert to a valid E1 point. 360 | 361 | Hashing Algorithms 362 | 363 | - hash_to_G1 - cryptographic hashing of octet string to G1 element. 364 | Must return a valid G1 element. Specified in Section {{auxiliary}}. 365 | 366 | 369 | 370 | ## Keygen: Key Generation 371 | 372 | 373 | Output: PK, SK 374 | 375 | 1. SK = x, chosen as a random integer in the range 1 and r-1 376 | 1. PK = x*P2 377 | 1. Output PK, SK 378 | 379 | 380 | ## Sign: Signature Generation 381 | 382 | Input: SK = x, message Output: signature 383 | 384 | 1. Input a secret key SK = x and a message digest message 385 | 1. H = hash_to_G1(suite_string, message) 386 | 1. Gamma = x*H 387 | 1. signature = E1_to_string(Gamma) 388 | 1. Output signature 389 | 390 | 391 | ## Verify: Signature Verification 392 | 393 | Input: PK, message, signature Output: "VALID" or "INVALID" 394 | 395 | 1. H = hash_to_G1(suite_string, message) 396 | 1. Gamma = string_to_E1(signature) 397 | 1. If Gamma is "INVALID", output "INVALID" and stop 398 | 1. If r*Gamma != 0, output "INVALID" and stop 399 | 1. Compute c = pairing(Gamma, P2) 400 | 1. Compute c' = pairing(H, PK) 401 | 1. If c and c' are equal, output "VALID", 402 | else output "INVALID" 403 | 404 | ## Aggregate 405 | The following algorithm works for both the same message aggregation and different 406 | message aggregation. 407 | 408 | 409 | Input: (PK_1, signature_1), ..., (PK_n, signature_n) Output: signature 410 | 411 | 1. Output signature = E1_to_string(string_to_E1(signature_1) + ... + 412 | string_to_E1(signature_n)) 413 | 414 | ### Verify-Aggregated-1 415 | 416 | Input: (PK_1, ..., PK_n), message, signature Output: "VALID" or "INVALID" 417 | 418 | 1. PK' = PK_1 + ... + PK_n 419 | 1. Output Verify(PK', message, signature) 420 | 421 | ### Verify-Aggregated-n 422 | 423 | Input: (PK_1, message_1), ..., (PK_n, message_n), signature 424 | Output: "VALID" or "INVALID" 425 | 426 | 1. H_i = hash_to_G1(suite_string, message_i) 427 | 1. Gamma = string_to_E1(signature) 428 | 1. If Gamma is "INVALID", output "INVALID" and stop 429 | 1. If r*Gamma != 0, output "INVALID" and stop 430 | 1. Compute c = pairing(Gamma, P2) 431 | 1. Compute c' = pairing(H_1, PK_1) * ... * pairing(H_n, PK_n) 432 | 1. If c and c' are equal, output "VALID", 433 | else output "INVALID" 434 | 435 | 445 | 446 | 447 | 448 | 449 | ## Auxiliary Functions {#auxiliary} 450 | 451 | Here, we describe the auxiliary functions relating to serialization 452 | and hashing to the elliptic curves E, where E may be E1 or E2. 453 | 454 | (Authors' note: this section is extremely preliminary and we anticipate 455 | substantial updates pending feedback from the community. We describe 456 | a generic approach for hashing, in order to cover hashing into 457 | curves defined over prime power extension fields, which are not covered in 458 | [I-D.irtf-cfrg-hash-to-curve]. We expect to support several different hashing 459 | algorithms specified via the suite_string.) 460 | 461 | ### Preliminaries 462 | In all the pairing-friendly curves, E is defined over a field 463 | GF(p^k). We also assume an explicit isomorphism that allows us to 464 | treat GF(p^k) as GF(p). In most of the curves in [I-D.pairing-friendly-curves], 465 | we have k=1 for E1 and k=2 for E2. 466 | 467 | Each point (x,y) on E can be specified by the 468 | x-coordinate in GP(p)^k plus a single bit to determine whether the point 469 | is (x,y) or (x,-y), thus requiring k log(p) + 1 bits [I-D.irtf-cfrg-hash-to-curve]. 470 | 471 | Concretely, we encode a point (x,y) on E as a string comprising k substrings 472 | s_1, ..., s_k each of length log(p)+2 bits, where 473 | 474 | * the first bit of s_1 indicates whether E is the point at infinity 475 | * the second bit of s_1 indicates whether the point is (x,y) or (x,-y) 476 | * the first two bits of s_2, ..., s_k are 00 477 | * the x-coordinate is specified by the last log(p) bits of s_1, ..., s_k 478 | 479 | In fact, we will pad each substring with 0 bits so that the length of each substring 480 | is a multiple of 8 bits. 481 | 482 | This section uses the following constants: 483 | 484 | * pbits: the number of bits to represent integers modulo p. 485 | * padded_pbits: the smallest multiple of 8 that is greater than pbits+2. 486 | * padlen: padded_pbits - padlen 487 | 488 | | curve | pbits | padded_pbits | padlen | 489 | |-------|-------|--------------|--------| 490 | |BLS-381| 381 | 384 | 3 | 491 | 492 | 493 | ### Type conversions 494 | 495 | 498 | 499 | In general we view a string str as a vector of substrings s_1, ... s_k for k >= 1; 500 | each substring is of padded_pbits bits; and k is set properly according to the individual 501 | curve. 502 | For example, for BLS12-381 curve, k=1 for E1 and 2 for E2. 503 | If the input string is not a multiple of padded_pbits, we 504 | tail pad the string to meet the correct length. 505 | 506 | A string that encodes an E1/E2 point may have the following structure: 507 | * for the first substring s_1 508 | * the first bit indicates if the point is the point at infinity 509 | * the second bit is either 0 or 1, denoted by y_bit 510 | * the third to padlen bits are 0 511 | 512 | * for the rest substrings s_2, ... s_k 513 | * the first padlen bits are 0s 514 | 515 | TBD: some implementation uses an additional leading bit to indicate the 516 | string is in a compressed form (give x coordinate and the parity/sign of y coordinate) 517 | or in an uncompressed form (give both x and y coordinate). 518 | 519 | #### curve-to-string 520 | 521 | Input: 522 | 523 | input_string - a point P = (x, y) on the curve 524 | 525 | Output: 526 | 527 | a string of k * padded_pbits 528 | 529 | Steps: 530 | 531 | 1. If P is the point at infinity, output 0b1000...0 532 | 2. Parse y as y_1, ..., y_k; set y_bit as y_1 mod 2 533 | 2. Parse x as x_1, ..., x_k 534 | 3. set the substring s_1 = 0 | y_bit | padlen-2 of 0s | int_to_string(x_1) 535 | 4. set substrings s_i = padlen of 0s | int_to_string(x_i) for 2<=i<=k 536 | 5. Output the string s_1 | s_2 | ... | s_k 537 | 538 | 539 | #### string-to-curve 540 | 541 | The algorithm takes as follows: 542 | 543 | Input: 544 | 545 | input_string - a single octet string. 546 | 547 | Output: 548 | 549 | Either a point P on the curve, or INVALID 550 | 551 | Steps: 552 | 553 | 1. If length(input_string) is < padded_pbits/8 bytes, lead pad input_string with 0s; 554 | 555 | 1. If length(input_string) is not a multiple of padded_pbits/8 bytes, tail pad with 0, ..., 0; 556 | 557 | 1. Parse input_string as a vector of substrings s_1, ..., s_k 558 | 559 | 3. b = s_1[0]; i.e., the first byte of the first substring; 560 | 561 | 4. If the first bit of b is 1, return P = 0 (the point at infinity) 562 | 563 | 5. Set y_bit to be the second bit of b and then set the second bit of b to 0 564 | 565 | 6. If the third to plen bits of input_string are not 0, return INVALID 566 | 567 | 6. Set x_1 = string_to_int(s_1) 568 | 1. if x_1 > p then return INVALID 569 | 570 | 7. for i in [2 ... k] 571 | 572 | 1. b = s_i[0] 573 | 2. if top plen bits of b is not 0, return INVALID 574 | 3. set x_i = string_to_int(s_i) 575 | 1. if x_1 > p then return INVALID 576 | 8. Set x= (x_1, ..., x_k) 577 | 578 | 7. solve for y so that (x, y) satisfies elliptic curve equation; 579 | * output INVALID if equation is not solvable with x 580 | * parse y as (y_1, ..., y_k) 581 | * if solutions exist, there should be a pair of ys where y_1-s differ by parity 582 | * set y to be the solution where y_1 is odd if y_bit = 1 583 | * set y to be the solution where y_1 is even if y_bit = 0 584 | 8. output P = (x, y) as a curve point. 585 | 586 | TBD: check the parity property remains true for E2. The Chia and Etherum implementations 587 | use lexicographic ordering. 588 | 589 | #### alt-str-to-curve 590 | 591 | The algorithm takes as follows: 592 | 593 | Input: 594 | 595 | input_string - a single octet string. 596 | 597 | Output: 598 | 599 | Either a point P on the curve, or INVALID 600 | 601 | 602 | Steps: 603 | 604 | 1. If length(input_string) is < padded_pbits/8 bytes, lead pad input_string with 0s; 605 | 606 | 1. If length(input_string) is not a multiple of 48 bytes, tail pad with 0, ..., 0s; 607 | 608 | 609 | 1. Parse input_string as a vector of substrings s_1, ..., s_k 610 | 611 | 1. Set the first padlen bits except for the second bit of s_1[0] to 0 612 | 1. Set the first padlen bits for s_2[0], ..., s_k[0] to 0 613 | 1. call string_to_curve(input_string) 614 | 615 | 616 | ### Hash to groups 617 | 618 | Note: this section will be removed in later versions. We will refer to 619 | [I-D.irtf-cfrg-hash-to-curve] once it is updated with methods for hash into 620 | pairing friendly curves. The rest of the material are for information only. 621 | 622 | The following hash_to_G1_try_and_increment algorithm implements 623 | hash_to_G1 in a simple and generic way that works for any 624 | pairing-friendly curve. It follows the try-and-increment approach 625 | [I-D.irtf-cfrg-hash-to-curve] and uses alt_str_to_curve as a subroutine. 626 | The running depends on alpha_string, and for the appropriate 627 | instantiations, is expected to find a valid G1 element after 628 | approximately two attempts (i.e., when ctr=1) on average. 629 | 630 | The following pseudocode is adapted from draft-irtf-cfrg-vrf-03 631 | Section 5.4.1.1. 632 | 633 | Recall that cofactor = |E1|/|G1|. This algorithm also uses a hash functions 634 | that hashes arbitrary strings into strings of 384 bits. 635 | 636 | hash_to_G1_try_and_increment(suite_string, alpha_string) 637 | 638 | input: 639 | 640 | suite_string - an identifier to indicate the curves and a hash function 641 | that outputs k*padded_pbits bits 642 | 643 | alpha_string - the input string to be hashed 644 | 645 | Output: 646 | 647 | H - hashed value, a point in G1 648 | 649 | Steps: 650 | 651 | 1. ctr = 0 652 | 653 | 1. one_string = 0x01 = int_to_string(1, 1), a single octet with 654 | value 1 655 | 656 | 1. H = "INVALID" 657 | 658 | 1. While H is "INVALID" or H is EC point at infinity: 659 | 660 | 1. ctr_string = int_to_string(ctr, 1) 661 | 662 | 1. hash_string = Hash(suite_string || one_string || 663 | alpha_string || ctr_string) 664 | 665 | 3. H = alt_str_to_curve(hash_string) 666 | 667 | 4. If H is not "INVALID" and cofactor > 1, set H = cofactor * H 668 | 669 | 5. ctr = ctr + 1 670 | 671 | 1. Output H 672 | 673 | Note that this hash to group function will never hash into the point at infinity. 674 | This does not affect the security since the output distribution is statistically 675 | indistinguishable from the uniform distribution over the group. 676 | 677 | ### Membership test 678 | 679 | The following g1_membership_test and g1_membership_test algorithms is to 680 | check if a E1 or E2 point is in the correct prime subgroup. Example: 681 | 682 | r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 683 | 684 | for curve BLS12-381. 685 | 686 | 687 | 688 | g1_membership_test(input_point) 689 | 690 | input: 691 | 692 | input_point - a point P = (x, y) on the curve E1 693 | 694 | Output: 695 | 696 | "VALID" if P is in G1; "INVALID" otherwise 697 | 698 | Steps: 699 | 700 | 1. r = order of group G1 701 | 1. if r * P == 1 return "VALID", otherwise, return "INVALID" 702 | 703 | 704 | 705 | g2_membership_test(input_point) 706 | 707 | input: 708 | 709 | input_point - a point P = (x, y) on the curve E2 710 | 711 | Output: 712 | 713 | "VALID" if P is in G2; "INVALID" otherwise 714 | 715 | Steps: 716 | 717 | 1. r = order of group G2 718 | 1. if r * P == 1 return "VALID", otherwise, return "INVALID" 719 | 720 | 721 | 722 | # Security Considerations 723 | 724 | ## Verifying public keys 725 | When users register a public key, we should ensure that it is well-formed. 726 | This requires a G2 membership test. In applications where we use aggregation, 727 | we need to enforce security against rogue key attacks [Boneh-Drijvers-Neven 18a](https://crypto.stanford.edu/~dabo/pubs/papers/BLSmultisig.html). 728 | This can be achieved in one of three ways: 729 | 730 | * Message augmentation: pk = g^sk, sig = H(pk, m)^sk 731 | (BGLS, [Bellare-Namprempre-Neven 07](https://eprint.iacr.org/2006/285)). 732 | 733 | * Proof of possession: pk = ( u=g^sk, H'(u)^sk ), sig = H(m)^sk 734 | (see concrete mechanisms in [Ristenpart-Yilek 06]) 735 | 736 | * Linear combination: agg = sig_1^t_1 ... sig_n^t_n 737 | (see [Boneh-Drijvers-Neven 18b](https://eprint.iacr.org/2018/483.pdf); 738 | there, pre-processing public keys would speed up verification.) 739 | 740 | ## Skipping membership check 741 | Several existing implementations skip step 4 (membership in G1) in Verify. 742 | In this setting, the BLS signature remains unforgeable (but not strongly 743 | unforgeable) under a stronger assumption: 744 | 745 | given P1, a*P1, P2, b*P2, it is hard to compute U in E1 such that 746 | pairing(U,P2) = pairing(a*P1, b*P2). 747 | 748 | ## Side channel attacks 749 | It is important to protect the secret key in implementations of the 750 | signing algorithm. We can protect against some side-channel attacks by 751 | ensuring that the implementation executes exactly the same sequence of 752 | instructions and performs exactly the same memory accesses, for any 753 | value of the secret key. To achieve this, we require that 754 | point multiplication in G1 should run in constant time with respect to 755 | the scalar. 756 | 757 | ## Randomness considerations 758 | BLS signatures are deterministic. This protects against attacks 759 | arising from signing with bad randomness, for example, the nounce reusing 760 | attack in ECDSA [HDWH 12]. 761 | 762 | 770 | 771 | ## Implementing the hash function 772 | The security analysis models the hash function H as a random oracle, 773 | and it is crucial that we implement H using a cryptographically 774 | secure hash function. 775 | 779 | 780 | 791 | 792 | 807 | 808 | # Implementation Status 809 | 810 | This section will be removed in the final version of the draft. 811 | There are currently several implementations of BLS signatures using the BLS12-381 curve. 812 | 813 | * Algorand: TBA 814 | 815 | * Chia: [spec](https://github.com/Chia-Network/bls-signatures/blob/master/SPEC.md) 816 | [python/C++](https://github.com/Chia-Network/bls-signatures). Here, they are 817 | swapping G1 and G2 so that the public keys are small, and the benefits 818 | of avoiding a membership check during signature verification would even be more 819 | substantial. The current implementation does not seem to implement the membership check. 820 | Chia uses the Fouque-Tibouchi hashing to the curve, which can be done in constant time. 821 | 822 | * Dfinity: [go](https://github.com/dfinity/go-dfinity-crypto) [BLS](https://github.com/dfinity/bls). The current implementations do not seem to implement the membership check. 823 | 824 | * Ethereum 2.0: [spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/bls_signature.md) 825 | 826 | # Related Standards 827 | 828 | * Pairing-friendly curves [draft-yonezawa-pairing-friendly-curves](https://tools.ietf.org/html/draft-yonezawa-pairing-friendly-curves-00) 829 | 830 | * Pairing-based Identity-Based Encryption [IEEE 1363.3](https://ieeexplore.ieee.org/document/6662370). 831 | 832 | * Identity-Based Cryptography Standard [rfc5901](https://tools.ietf.org/html/rfc5091). 833 | 834 | * Hashing to Elliptic Curves [draft-irtf-cfrg-hash-to-curve-02](https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-02), in order to implement the hash function H. The current draft does not cover pairing-friendly curves, where we need to handle curves over prime power extension fields GF(p^k). 835 | 836 | * Verifiable random functions [draft-irtf-cfrg-vrf-03](https://tools.ietf.org/html/draft-irtf-cfrg-vrf-03). Section 5.4.1 also discusses instantiations for H. 837 | 838 | * EdDSA [rfc8032](https://tools.ietf.org/html/rfc8032) 839 | 840 | 841 | 846 | 847 | # Appendix A. Test Vectors 848 | 849 | 850 | TBA: (i) test vectors for both variants of the signature scheme 851 | (signatures in G2 instead of G1) , (ii) test vectors ensuring 852 | membership checks, (iii) intermediate computations ctr, hm. 853 | 854 | 910 | 911 | # Appendix B. Security 912 | 913 | ## Definitions 914 | ### Message Unforgeability 915 | 916 | Consider the following game between an adversary and a challenger. 917 | The challenger generates a key-pair (PK, SK) and gives PK to the adversary. 918 | The adversary may repeatedly query the challenger on any message message to obtain 919 | its corresponding signature signature. Eventually the adversary outputs a pair 920 | (message', signature'). 921 | 922 | Unforgeability means no adversary can produce a pair (message', signature') for a message message' which he never queried the challenger and Verify(PK, message, signature) outputs VALID. 923 | 924 | 925 | ### Strong Message Unforgeability 926 | 927 | In the strong unforgeability game, the game proceeds as above, except 928 | no adversary should be able to produce a pair (message', signature') that verifies (i.e. Verify(PK, message, signature) 929 | outputs VALID) given that he never queried the challenger on message', or if he did query and obtained 930 | a reply signature, then signature != signature'. 931 | 932 | More informally, the strong unforgeability means that no adversary can produce 933 | a different signature (not provided by the challenger) on a message which he queried before. 934 | 935 | ### Aggregation Unforgeability 936 | 937 | Consider the following game between an adversary and a challenger. 938 | The challenger generates a key-pair (PK, SK) and gives PK to the adversary. 939 | The adversary may repeatedly query the challenger on any message message to obtain 940 | its corresponding signature signature. 941 | Eventually the adversary outputs a sequence ((PK_1, message_1), ..., (PK_n, message_n), (PK, message), signature). 942 | 943 | Aggregation unforgeability means that no adversary can produce a sequence 944 | where it did not query the challenger on the message message, and 945 | Verify-Aggregated((PK_1, message_1), ..., (PK_n, message_n), (PK, message), signature) outputs VALID. 946 | 947 | We note that aggregation unforgeability implies message unforgeability. 948 | 949 | TODO: We may also consider a strong aggregation unforgeability property. 950 | 951 | ## Security analysis 952 | 953 | The BLS signature scheme achieves strong message unforgeability and aggregation 954 | unforgeability under the co-CDH 955 | assumption, namely that given P1, a*P1, P2, b*P2, it is hard to 956 | compute {ab}*P1. [BLS01, BGLS03] 957 | 958 | 959 | # Appendix C. Reference 960 | 961 | [BLS 01] Dan Boneh, Ben Lynn, Hovav Shacham: 962 | Short Signatures from the Weil Pairing. ASIACRYPT 2001: 514-532. 963 | 964 | [BGLS 03] Dan Boneh, Craig Gentry, Ben Lynn, Hovav Shacham: 965 | Aggregate and Verifiably Encrypted Signatures from Bilinear Maps. EUROCRYPT 2003: 416-432. 966 | 967 | [HDWH 12] 968 | Heninger, N., Durumeric, Z., Wustrow, E., Halderman, J.A.: 969 | "Mining your Ps and Qs: Detection of widespread weak keys in network devices.", 970 | USENIX 2012. 971 | 972 | [I-D.irtf-cfrg-hash-to-curve] 973 | S. Scott, N. Sullivan, and C. Wood: 974 | "Hashing to Elliptic Curves", 975 | draft-irtf-cfrg-hash-to-curve-01 (work in progress), 976 | July 2018. 977 | 978 | [I-D.pairing-friendly-curves] 979 | S. Yonezawa, S. Chikara, T. Kobayashi, T. Saito: 980 | "Pairing-Friendly Curves", 981 | draft-yonezawa-pairing-friendly-curves-00, 982 | Jan 2019. 983 | -------------------------------------------------------------------------------- /old_versions/draft-irtf-cfrg-bls-signature-00.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | draft-irtf-cfrg-bls-signature-00.txtStanford University
8 | USA 9 | dabo@cs.stanford.edu 10 |
11 | Stanford University
12 | USA 13 | rsw@cs.stanford.edu 14 |
15 | Algorand and University of Waterloo
16 | Boston, MA 17 | USA 18 | sergey@algorand.com 19 |
20 | Algorand and ENS, Paris
21 | Boston, MA 22 | USA 23 | wee@di.ens.fr 24 |
25 | Algorand
26 | Boston, MA 27 | USA 28 | zhenfei@algorand.com 29 |
30 | 31 | InternetCFRG 32 | BLS is a digital signature scheme with compression properties. 33 | With a given set of signatures (signature_1, ..., signature_n) anyone can produce 34 | a compressed signature signature_compressed. The same is true for a set of 35 | secret keys or public keys, while keeping the connection between sets 36 | (i.e., a compressed public key is associated to its compressed secret key). 37 | Furthermore, the BLS signature scheme is deterministic, non-malleable, 38 | and efficient. Its simplicity and cryptographic properties allows it 39 | to be useful in a variety of use-cases, specifically when minimal 40 | storage space or bandwidth are required. 41 | 42 | 43 |
44 | 45 | 46 | 47 |
48 | A signature scheme is a fundamental cryptographic primitive 49 | that is used to protect authenticity and integrity of communication. 50 | Only the holder of a secret key can sign messages, but anyone can 51 | verify the signature using the associated public key. 52 | Signature schemes are used in point-to-point secure communication 53 | protocols, PKI, remote connections, etc. 54 | Designing efficient and secure digital signature is very important 55 | for these applications. 56 | This document describes the BLS signature scheme. The scheme enjoys a variety 57 | of important efficiency properties: 58 | 59 | 60 | The public key and the signatures are encoded as single group elements. 61 | Verification requires 2 pairing operations. 62 | A collection of signatures (signature_1, ..., signature_n) can be compressed 63 | into a single signature (signature). Moreover, the compressed signature can 64 | be verified using only n+1 pairings (as opposed to 2n pairings, when verifying 65 | n signatures separately). 66 | 67 | 68 | Given the above properties, 69 | the scheme enables many interesting applications. 70 | The immediate applications include 71 | 72 | 73 | authentication and integrity for Public Key Infrastructure (PKI) and blockchains. 74 | 75 | The usage is similar to classical digital signatures, such as ECDSA. 76 | 77 | compressing signature chains for PKI and Secure Border Gateway Protocol (SBGP). 78 | 79 | Concretely, in a PKI signature chain of depth n, we have n signatures by n 80 | certificate authorities on n distinct certificates. Similarly, in SBGP, 81 | each router receives a list of n signatures attesting to a path of length n 82 | in the network. In both settings, using the BLS signature scheme would allow us 83 | to compress the n signatures into a single signature. 84 | 85 | consensus protocols for blockchains. 86 | 87 | There, BLS signatures 88 | are used for authenticating transactions as well as votes during the consensus 89 | protocol, and the use of aggregation significantly reduces the bandwidth 90 | and storage requirements. 91 | 92 | 93 | 94 | 95 |
96 | The following comparison assumes BLS signatures with curve BLS12-381, targeting 97 | 128 bits security. 98 | For 128 bits security, ECDSA takes 37 and 79 micro-seconds to sign and verify 99 | a signature on a typical laptop. In comparison, for the same level of security, 100 | BLS takes 370 and 2700 micro-seconds to sign and verify 101 | a signature. 102 | In terms of sizes, ECDSA uses 32 bytes for public keys and 64 bytes for signatures; 103 | while BLS uses 96 bytes for public keys, and 48 bytes for signatures. 104 | Alternatively, BLS can also be instantiated with 48 bytes of public keys and 96 bytes 105 | of signatures. 106 | BLS also allows for signature compression. In other words, a single signature is 107 | sufficient to anthenticate multiple messages and public keys. 108 |
109 | 110 |
111 | This document is organized as follows: 112 | 113 | 114 | The remainder of this section defines terminology and the high-level API. 115 | defines primitive operations used in the BLS signature scheme. 116 | These operations MUST NOT be used alone. 117 | defines three BLS Signature schemes giving slightly different 118 | security and performance properties. 119 | defines the format for a ciphersuites and gives recommended ciphersuites. 120 | The appendices give test vectors, etc. 121 | 122 | 123 |
124 | 125 |
126 | The following terminology is used through this document: 127 | 128 | 129 | SK: The secret key for the signature scheme. 130 | PK: The public key for the signature scheme. 131 | message: The input to be signed by the signature scheme. 132 | signature: The digital signature output. 133 | aggregation: Given a list of signatures for a list of messages and public keys, 134 | an aggregation algorithm generates one signature that authenticates the same 135 | list of messages and public keys. 136 | rogue key attack: 137 | An attack in which a specially crafted public key (the "rogue" key) is used 138 | to forge an aggregated signature. 139 | specifies methods for securing against rogue key attacks. 140 | 141 | 142 | The following notation and primitives are used: 143 | 144 | 145 | a || b denotes the concatenation of octet strings a and b. 146 | A pairing-friendly elliptic curve defines the following primitives 147 | (see for detailed discussion): 148 | 149 | E1, E2: elliptic curve groups defined over finite fields. 150 | This document assumes that E1 has a more compact representation than 151 | E2, i.e., because E1 is defined over a smaller field than E2. 152 | G1, G2: subgroups of E1 and E2 (respectively) having prime order r. 153 | P1, P2: distinguished points that generate of G1 and G2, respectively. 154 | GT: a subgroup, of prime order r, of the multiplicative group of a field extension. 155 | e : G1 x G2 -> GT: a non-degenerate bilinear map. 156 | 157 | For the above pairing-friendly curve, this document 158 | writes operations in E1 and E2 in additive notation, i.e., 159 | P + Q denotes point addition and x * P denotes scalar multiplication. 160 | Operations in GT are written in multiplicative notation, i.e., a * b 161 | is field multiplication. 162 | 163 | 164 | 165 | 166 | For each of E1 and E2 defined by the above pairing-friendly curve, 167 | we assume that the pairing-friendly elliptic curve definition provides 168 | several primitives, described below. 169 | Note that these primitives are named generically. 170 | When referring to one of these primitives for a specific group, 171 | this document appends the name of the group, e.g., 172 | point_to_octets_E1, subgroup_check_E2, etc. 173 | 174 | point_to_octets(P) -> ostr: returns the canonical representation of 175 | the point P as an octet string. 176 | This operation is also known as serialization. 177 | octets_to_point(ostr) -> P: returns the point P corresponding to the 178 | canonical representation ostr, or INVALID if ostr is not a valid output 179 | of point_to_octets. 180 | This operation is also known as deserialization. 181 | subgroup_check(P) -> VALID or INVALID: returns VALID when the point P 182 | is an element of the subgroup of order r, and INVALID otherwise. 183 | This function can always be implemented by checking that r * P is equal 184 | to the identity element. In some cases, faster checks may also exist, 185 | e.g., . 186 | 187 | I2OSP and OS2IP are the functions defined in , Section 4. 188 | hash_to_point(ostr) -> P: a cryptographic hash function that takes as input an 189 | arbitrary octet string and returns a point on an elliptic curve. 190 | Functions of this kind are defined in . 191 | Each of the ciphersuites in specifies the hash_to_point 192 | algorithm to be used. 193 | 194 | 195 |
196 | 197 |
198 | The BLS signature scheme defines the following API: 199 | 200 | 201 | KeyGen(IKM) -> PK, SK: a key generation algorithm that 202 | takes as input an octet string comprising secret keying material, 203 | and outputs a public key PK and corresponding secret key SK. 204 | Sign(SK, message) -> signature: a signing algorithm that generates a 205 | deterministic signature given a secret key SK and a message. 206 | Verify(PK, message, signature) -> VALID or INVALID: 207 | a verification algorithm that outputs VALID if signature is a valid 208 | signature of message under public key PK, and INVALID otherwise. 209 | Aggregate(signature_1, ..., signature_n) -> signature: 210 | an aggregation algorithm that compresses a collection of signatures 211 | into a single signature. 212 | AggregateVerify((PK_1, message_1), ..., (PK_n, message_n), signature) -> VALID or INVALID: 213 | an aggregate verification algorithm that outputs VALID if signature 214 | is a valid aggregated signature for a collection of public keys and messages, 215 | and outputs INVALID otherwise. 216 | 217 | 218 |
219 | 220 |
221 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 222 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 223 | document are to be interpreted as described in . 224 |
225 |
226 | 227 |
228 | This section defines core operations used by the schemes defined in . 229 | These operations MUST NOT be used except as described in that section. 230 | 231 |
232 | Each core operation has two variants that trade off signature 233 | and public key size: 234 | 235 | 236 | Minimal-signature-size: signatures are points in G1, 237 | public keys are points in G2. 238 | (Recall from that E1 has a more compact representation than E2.) 239 | Minimal-pubkey-size: public keys are points in G1, 240 | signatures are points in G2. 241 | Implementations using signature aggregation SHOULD use this approach, 242 | since the size of (PK_1, ..., PK_n, signature) is dominated by 243 | the public keys even for small n. 244 | 245 | 246 |
247 | 248 |
249 | The core operations in this section depend on several parameters: 250 | 251 | 252 | A signature variant, either minimal-signature-size or minimal-pubkey-size. 253 | These are defined in . 254 | A pairing-friendly elliptic curve, plus associated functionality 255 | given in . 256 | H, a hash function H that MUST be a secure cryptographic hash function, 257 | e.g., SHA-256 . 258 | For security, H MUST output at least ceil(log2(r)) bits, where r is 259 | the order of the subgroups G1 and G2 defined by the pairing-friendly 260 | elliptic curve. 261 | hash_to_point, a function whose interface is described in . 262 | When the signature variant is minimal-signature-size, this function 263 | MUST output a point in G1. 264 | When the signature variant is minimal-pubkey size, this function 265 | MUST output a point in G2. 266 | For security, this function MUST be either a random oracle encoding or a 267 | nonuniform encoding, as defined in . 268 | 269 | 270 | In addition, the following primitives are determined by the above parameters: 271 | 272 | 273 | P, an elliptic curve point. 274 | When the signature variant is minimal-signature-size, P is the 275 | distinguished point P2 that generates the group G2 (see ). 276 | When the signature variant is minimal-pubkey-size, P is the 277 | distinguished point P1 that generates the group G1. 278 | r, the order of the subgroups G1 and G2 defined by the pairing-friendly curve. 279 | pairing, a function that invokes the function e of , 280 | with argument order depending on signature variant: 281 | 282 | For minimal-signature-size: 283 | pairing(U, V) := e(U, V) 284 | For minimal-pubkey-size: 285 | pairing(U, V) := e(V, U) 286 | 287 | point_to_pubkey and point_to_signature, functions that invoke the 288 | appropriate serialization routine () depending on 289 | signature variant: 290 | 291 | For minimal-signature-size: 292 | point_to_pubkey(P) := point_to_octets_E2(P) 293 | point_to_signature(P) := point_to_octets_E1(P) 294 | For minimal-pubkey-size: 295 | point_to_pubkey(P) := point_to_octets_E1(P) 296 | point_to_signature(P) := point_to_octets_E2(P) 297 | 298 | pubkey_to_point and signature_to_point, functions that invoke the 299 | appropriate deserialization routine () depending on 300 | signature variant: 301 | 302 | For minimal-signature-size: 303 | pubkey_to_point(ostr) := octets_to_point_E2(ostr) 304 | signature_to_point(ostr) := octets_to_point_E1(ostr) 305 | For minimal-pubkey-size: 306 | pubkey_to_point(ostr) := octets_to_point_E1(ostr) 307 | signature_to_point(ostr) := octets_to_point_E2(ostr) 308 | 309 | pubkey_subgroup_check and signature_subgroup_check, functions 310 | that invoke the appropriate subgroup check routine () 311 | depending on signature variant: 312 | 313 | For minimal-signature-size: 314 | pubkey_subgroup_check(P) := subgroup_check_E2(P) 315 | signature_subgroup_check(P) := subgroup_check_E1(P) 316 | For minimal-pubkey-size: 317 | pubkey_subgroup_check(P) := subgroup_check_E1(P) 318 | signature_subgroup_check(P) := subgroup_check_E2(P) 319 | 320 | 321 | 322 |
323 | 324 |
325 | The KeyGen algorithm generates a pair (PK, SK) deterministically using 326 | the secret octet string IKM. 327 | KeyGen uses HKDF instantiated with the hash function H. 328 | For security, IKM MUST be infeasible to guess, e.g., 329 | generated by a trusted source of randomness. 330 | IKM MUST be at least 32 bytes long, but it MAY be longer. 331 | Because KeyGen is deterministic, implementations MAY choose either to 332 | store the resulting (PK, SK) or to store IKM and call KeyGen to derive 333 | the keys when necessary. 334 | 335 |
(PK, SK) = KeyGen(IKM) 336 | 337 | Inputs: 338 | - IKM, a secret octet string. See requirements above. 339 | 340 | Outputs: 341 | - PK, a public key encoded as an octet string. 342 | - SK, the corresponding secret key, an integer 0 <= SK < r. 343 | 344 | Definitions: 345 | - HKDF-Extract is as defined in RFC5869, instantiated with hash H. 346 | - HKDF-Expand is as defined in RFC5869, instantiated with hash H. 347 | - L is the integer given by ceil((1.5 * ceil(log2(r))) / 8). 348 | - "BLS-SIG-KEYGEN-SALT-" is an ASCII string comprising 20 octets. 349 | - "" is the empty string. 350 | 351 | Procedure: 352 | 1. PRK = HKDF-Extract("BLS-SIG-KEYGEN-SALT-", IKM) 353 | 2. OKM = HKDF-Expand(PRK, "", L) 354 | 3. x = OS2IP(OKM) mod r 355 | 4. xP = x * P 356 | 5. SK = x 357 | 6. PK = point_to_pubkey(xP) 358 | 7. return (PK, SK) 359 |
360 | 361 |
362 | 363 |
364 | The KeyValidate algorithm ensures that a public key is valid. 365 | 366 |
result = KeyValidate(PK) 367 | 368 | Inputs: 369 | - PK, a public key in the format output by KeyGen. 370 | 371 | Outputs: 372 | - result, either VALID or INVALID 373 | 374 | Procedure: 375 | 1. xP = pubkey_to_point(PK) 376 | 2. If xP is INVALID, return INVALID 377 | 3. If pubkey_subgroup_check(xP) is INVALID, return INVALID 378 | 4. return VALID 379 |
380 | 381 |
382 | 383 |
384 | The CoreSign algorithm computes a signature from SK, a secret key, 385 | and message, an octet string. 386 | 387 |
signature = CoreSign(SK, message) 388 | 389 | Inputs: 390 | - SK, the secret key output by an invocation of KeyGen. 391 | - message, an octet string. 392 | 393 | Outputs: 394 | - signature, an octet string. 395 | 396 | Procedure: 397 | 1. Q = hash_to_point(message) 398 | 2. R = SK * Q 399 | 3. signature = point_to_signature(R) 400 | 4. return signature 401 |
402 | 403 |
404 | 405 |
406 | The CoreVerify algorithm checks that a signature is valid for 407 | the octet string message under the public key PK. 408 | The public key PK must satisfy KeyValidate(PK) == VALID (). 409 | 410 |
result = CoreVerify(PK, message, signature) 411 | 412 | Inputs: 413 | - PK, a public key in the format output by KeyGen. 414 | - message, an octet string. 415 | - signature, an octet string in the format output by CoreSign. 416 | 417 | Outputs: 418 | - result, either VALID or INVALID. 419 | 420 | Procedure: 421 | 1. R = signature_to_point(signature) 422 | 2. If R is INVALID, return INVALID 423 | 3. If signature_subgroup_check(R) is INVALID, return INVALID 424 | 4. xP = pubkey_to_point(PK) 425 | 5. Q = hash_to_point(message) 426 | 6. C1 = pairing(Q, xP) 427 | 7. C2 = pairing(R, P) 428 | 8. If C1 == C2, return VALID, else return INVALID 429 |
430 | 431 |
432 | 433 |
434 | The Aggregate algorithm compresses multiple signatures into one. 435 | 436 |
signature = Aggregate(signature_1, ..., signature_n) 437 | 438 | Inputs: 439 | - signature_1, ..., signature_n, octet strings output by 440 | either CoreSign or Aggregate. 441 | 442 | Outputs: 443 | - signature, an octet string encoding a compressed signature 444 | that combines all inputs; or INVALID. 445 | 446 | Procedure: 447 | 1. accum = signature_to_point(signature_1) 448 | 2. If accum is INVALID, return INVALID 449 | 3. for i in 2, ..., n: 450 | 4. next = signature_to_point(signature_i) 451 | 5. If next is INVALID, return INVALID 452 | 6. accum = accum + next 453 | 7. signature = point_to_signature(accum) 454 | 8. return signature 455 |
456 | 457 |
458 | 459 |
460 | The CoreAggregateVerify algorithm checks an aggregated signature 461 | over several (PK, message) pairs. 462 | All public keys PK_i must satisfy KeyValidate(PK_i) == VALID 463 | (). 464 | 465 |
result = CoreAggregateVerify((PK_1, message_1), ..., (PK_n, message_n), 466 | signature) 467 | 468 | Inputs: 469 | - PK_1, ..., PK_n, public keys in the format output by KeyGen. 470 | - message_1, ..., message_n, octet strings. 471 | - signature, an octet string output by Aggregate. 472 | 473 | Outputs: 474 | - result, either VALID or INVALID. 475 | 476 | Procedure: 477 | 1. R = signature_to_point(signature) 478 | 2. If R is INVALID, return INVALID 479 | 3. If signature_subgroup_check(R) is INVALID, return INVALID 480 | 4. C1 = 1 (the identity element in GT) 481 | 5. for i in 1, ..., n: 482 | 6. xP = pubkey_to_point(PK_i) 483 | 7. Q = hash_to_point(message_i) 484 | 8. C1 = C1 * pairing(Q, xP) 485 | 9. C2 = pairing(R, P) 486 | 10. If C1 == C2, return VALID, else return INVALID 487 |
488 | 489 |
490 |
491 | 492 |
493 | This section defines three signature schemes: basic, message augmentation, 494 | and proof of possession. 495 | These schemes differ in the ways that they defend against rogue key 496 | attacks (). 497 | All of the schemes in this section are built on a set of core operations 498 | defined in . 499 | Thus, defining a scheme requires fixing a set of parameters as 500 | defined in . 501 | All three schemes expose the KeyGen and Aggregate operations 502 | that are defined in . 503 | The sections below define the other API functions () 504 | for each scheme. 505 | 506 |
507 | In a basic scheme, rogue key attacks are handled by requiring 508 | all messages signed by an aggregate signature to be distinct. 509 | This requirement is enforced in the definition of AggregateVerify. 510 | The Sign and Verify functions are identical to CoreSign and 511 | CoreVerify (), respectively. 512 | AggregateVerify is defined below. 513 | All public keys PK supplied as arguments to Verify and AggregateVerify 514 | MUST satisfy KeyValidate(PK) == VALID (). 515 | 516 |
517 | This function first ensures that all messages are distinct, and then 518 | invokes CoreAggregateVerify. 519 | 520 |
result = AggregateVerify((PK_1, message_1), ..., (PK_n, message_n), 521 | signature) 522 | 523 | Inputs: 524 | - PK_1, ..., PK_n, public keys in the format output by KeyGen. 525 | - message_1, ..., message_n, octet strings. 526 | - signature, an octet string output by Aggregate. 527 | 528 | Outputs: 529 | - result, either VALID or INVALID. 530 | 531 | Procedure: 532 | 1. If any two input messages are equal, return INVALID. 533 | 2. return CoreAggregateVerify((PK_1, message_1), ..., (PK_n, message_n), 534 | signature) 535 |
536 | 537 |
538 |
539 | 540 |
541 | In a message augmentation scheme, signatures are generated 542 | over the concatenation of the public key and the message, 543 | ensuring that messages signed by different public keys are 544 | distinct. 545 | All public keys PK supplied as arguments to Verify and AggregateVerify 546 | MUST satisfy KeyValidate(PK) == VALID (). 547 | 548 |
549 | To match the API for Sign defined in , this function 550 | recomputes the public key corresponding to the input SK. 551 | Implementations MAY instead implement an interface that takes 552 | the public key as an input. 553 | Note that the point P and the point_to_pubkey function are 554 | defined in . 555 | 556 |
signature = Sign(SK, message) 557 | 558 | Inputs: 559 | - SK, a secret key output by an invocation of KeyGen. 560 | - message, an octet string. 561 | 562 | Outputs: 563 | - signature, an octet string. 564 | 565 | Procedure: 566 | 1. xP = SK * P 567 | 2. PK = point_to_pubkey(xP) 568 | 3. return CoreSign(SK, PK || message) 569 |
570 | 571 |
572 | 573 |
574 | 575 |
result = Verify(PK, message, signature) 576 | 577 | Inputs: 578 | - PK, a public key in the format output by KeyGen. 579 | - message, an octet string. 580 | - signature, an octet string in the format output by CoreSign. 581 | 582 | Outputs: 583 | - result, either VALID or INVALID. 584 | 585 | Procedure: 586 | 1. return CoreVerify(PK, PK || message, signature) 587 |
588 | 589 |
590 | 591 |
592 | 593 |
result = AggregateVerify((PK_1, message_1), ..., (PK_n, message_n), 594 | signature) 595 | 596 | Inputs: 597 | - PK_1, ..., PK_n, public keys in the format output by KeyGen. 598 | - message_1, ..., message_n, octet strings. 599 | - signature, an octet string output by Aggregate. 600 | 601 | Outputs: 602 | - result, either VALID or INVALID. 603 | 604 | Procedure: 605 | 1. for i in 1, ..., n: 606 | 2. mprime_i = PK_i || message_i 607 | 3. return CoreAggregateVerify((PK_1, mprime_1), ..., (PK_n, mprime_n), 608 | signature) 609 |
610 | 611 |
612 |
613 | 614 |
615 | A proof of possession scheme uses a separate public key 616 | validation step, called a proof of possession, to defend against 617 | rogue key attacks. 618 | This enables an optimization to aggregate signature verification 619 | for the case that all signatures are on the same message. 620 | The Sign, Verify, and AggregateVerify functions 621 | are identical to CoreSign, CoreVerify, and CoreAggregateVerify 622 | (), respectively. 623 | In addition, a proof of possession scheme defines three functions beyond 624 | the standard API (): 625 | 626 | 627 | PopProve(SK) -> proof: an algorithm that generates a proof of possession 628 | for the public key corresponding to secret key SK. 629 | PopVerify(PK, proof) -> VALID or INVALID: 630 | an algorithm that outputs VALID if proof is valid for PK, and INVALID otherwise. 631 | FastAggregateVerify(PK_1, ..., PK_n, message, signature) -> VALID or INVALID: 632 | a verification algorithm for the aggregate of multiple signatures on 633 | the same message. 634 | This function is faster than AggregateVerify. 635 | 636 | 637 | All public keys used by Verify, AggregateVerify, and FastAggregateVerify 638 | MUST be accompanied by a proof of possession generated by PopProve, 639 | and the result of PopVerify on this proof MUST be VALID. 640 | 641 |
642 | In addition to the parameters required to instantiate the core operations 643 | (), a proof of possession scheme requires one further parameter: 644 | 645 | 646 | hash_pubkey_to_point(PK) -> P: a cryptographic hash function that takes as 647 | input a public key and outputs a point in the same subgroup as the 648 | hash_to_point algorithm used to instantiate the core operations. 649 | For security, this function MUST be orthogonal to the hash_to_point function. 650 | In addition, this function MUST be either a random oracle encoding or a 651 | nonuniform encoding, as defined in . 652 | The RECOMMENDED way of instantiating hash_pubkey_to_point is to use 653 | the same hash-to-curve function as hash_to_point, with a 654 | different domain separation tag (see , Section 5.1). 655 | 656 | 657 |
658 | 659 |
660 | This function recomputes the public key coresponding to the input SK. 661 | Implementations MAY instead implement an interface that takes the 662 | public key as input. 663 | Note that the point P and the point_to_pubkey and point_to_signature 664 | functions are defined in . 665 | The hash_pubkey_to_point function is defined in . 666 | 667 |
proof = PopProve(SK) 668 | 669 | Inputs: 670 | - SK, a secret key output by an invocation of KeyGen. 671 | 672 | Outputs: 673 | - proof, an octet string. 674 | 675 | Procedure: 676 | 1. xP = SK * P 677 | 2. PK = point_to_pubkey(xP) 678 | 3. Q = hash_pubkey_to_point(PK) 679 | 4. R = SK * Q 680 | 5. proof = point_to_signature(R) 681 | 6. return signature 682 |
683 | 684 |
685 | 686 |
687 | Note that the following uses several functions defined in . 688 | The hash_pubkey_to_point function is defined in . 689 | 690 |
result = PopVerify(PK, proof) 691 | 692 | Inputs: 693 | - PK, a public key in the format output by KeyGen. 694 | - proof, an octet string in the format output by PopProve. 695 | 696 | Outputs: 697 | - result, either VALID or INVALID 698 | 699 | Procedure: 700 | 1. R = signature_to_point(proof) 701 | 2. If R is INVALID, return INVALID 702 | 3. If signature_subgroup_check(R) is INVALID, return INVALID 703 | 4. If KeyValidate(PK) is INVALID, return INVALID 704 | 5. xP = pubkey_to_point(PK) 705 | 6. Q = hash_pubkey_to_point(PK) 706 | 7. C1 = pairing(Q, xP) 707 | 8. C2 = pairing(R, P) 708 | 9. If C1 == C2, return VALID, else return INVALID 709 |
710 | 711 |
712 | 713 |
714 | Note that the following uses several functions defined in . 715 | 716 |
result = FastAggregateVerify(PK_1, ..., PK_n, message, signature) 717 | 718 | Inputs: 719 | - PK_1, ..., PK_n, public keys in the format output by KeyGen. 720 | - message, an octet string. 721 | - signature, an octet string output by Aggregate. 722 | 723 | Outputs: 724 | - result, either VALID or INVALID. 725 | 726 | Procedure: 727 | 1. accum = pubkey_to_point(PK_1) 728 | 2. for i in 2, ..., n: 729 | 3. next = pubkey_to_point(PK_i) 730 | 4. accum = accum + next 731 | 5. PK = point_to_pubkey(accum) 732 | 6. return CoreVerify(PK, message, signature) 733 |
734 | 735 |
736 |
737 |
738 | 739 |
740 | This section defines the format for a BLS ciphersuite. 741 | It also gives concrete ciphersuites based on the BLS12-381 pairing-friendly 742 | elliptic curve . 743 | 744 |
745 | A ciphersuite specifies all parameters from , 746 | a scheme from , and any parameters the scheme requires. 747 | In particular, a ciphersuite comprises: 748 | 749 | 750 | ID: the ciphersuite ID, an ASCII string. The RECOMMENDED format for 751 | this string is 752 | "BLS_SIG_" || H2C_SUITE || "_" || SC_TAG || "_" 753 | 754 | strings in double quotes are literal ASCII octet sequences 755 | H2C_SUITE is the name of the hash-to-curve ciphersuite 756 | used to define the hash_to_point and hash_pubkey_to_point 757 | functions. 758 | SC_TAG SHOULD be "NUL" when SC is basic, 759 | "AUG" when SC is message-augmentation, or 760 | "POP" when SC is proof-of-possession. 761 | 762 | SC: the scheme, either basic, message-augmentation, or proof-of-possession. 763 | SV: the signature variant, either minimal-signature-size or 764 | minimal-pubkey-size. 765 | EC: a pairing-friendly elliptic curve, plus all associated functionality 766 | (). 767 | H: a cryptographic hash function. 768 | hash_to_point: a hash from arbitrary strings to elliptic curve points. 769 | It is RECOMMENDED that hash_to_point be defined in terms of a 770 | hash-to-curve suite with domain separation tag equal 771 | to the ID string. 772 | hash_pubkey_to_point (only specified when SC is proof-of-possession): 773 | a hash from serialized public keys to elliptic curve points. 774 | It is RECOMMENDED that hash_pubkey_to_point be defined in terms of a 775 | has-to-curve suite , with domain separation tag 776 | constructed similarly to the ID string, namely: 777 | "BLS_POP_" || H2C_SUITE || "_" || SC_TAG || "_" 778 | 779 | 780 |
781 | 782 |
783 | The following ciphersuites are all built on the BLS12-381 elliptic curve. 784 | The required primitives for this curve are given in . 785 | These ciphersuites use the hash-to-curve suites BLS12381G1-SHA256-SSWU-RO- 786 | and BLS12381G2-SHA256-SSWU-RO- defined in . 787 | Each ciphersuite defines a unique hash_to_point function by specifying 788 | a domain separation tag (see [@I-D.irtf-cfrg-hash-to-curve, Section 5.1). 789 | 790 |
791 | The ciphersuite with ID 792 | BLS_SIG_BLS12381G1-SHA256-SSWU-RO-_NUL_ 793 | uses the following parameters, in addition to the common parameters below. 794 | 795 | 796 | SV: minimal-signature-size 797 | hash_to_point: BLS12381G1-SHA256-SSWU-RO- with the ASCII domain separation tag 798 | BLS_SIG_BLS12381G1-SHA256-SSWU-RO-_NUL_ 799 | 800 | 801 | The ciphersuite with ID 802 | BLS_SIG_BLS12381G2-SHA256-SSWU-RO-_NUL_ 803 | uses the following parameters, in addition to the common parameters below. 804 | 805 | 806 | SV: minimal-pubkey-size 807 | hash_to_point: BLS12381G2-SHA256-SSWU-RO- with the ASCII domain separation tag 808 | BLS_SIG_BLS12381G2-SHA256-SSWU-RO-_NUL_ 809 | 810 | 811 | The above ciphersuites share the following common parameters: 812 | 813 | 814 | SC: basic 815 | EC: BLS12-381, as defined in . 816 | H: SHA-256 817 | 818 | 819 |
820 | 821 |
822 | The ciphersuite with ID 823 | BLS_SIG_BLS12381G1-SHA256-SSWU-RO-_AUG_ 824 | uses the following parameters, in addition to the common parameters below. 825 | 826 | 827 | SV: minimal-signature-size 828 | hash_to_point: BLS12381G1-SHA256-SSWU-RO- with the ASCII domain separation tag 829 | BLS_SIG_BLS12381G1-SHA256-SSWU-RO-_AUG_ 830 | 831 | 832 | The ciphersuite with ID 833 | BLS_SIG_BLS12381G2-SHA256-SSWU-RO-_AUG_ 834 | uses the following parameters, in addition to the common parameters below. 835 | 836 | 837 | SV: minimal-pubkey-size 838 | hash_to_point: BLS12381G2-SHA256-SSWU-RO- with the ASCII domain separation tag 839 | BLS_SIG_BLS12381G2-SHA256-SSWU-RO-_AUG_ 840 | 841 | 842 | The above ciphersuites share the following common parameters: 843 | 844 | 845 | SC: message-augmentation 846 | EC: BLS12-381, as defined in . 847 | H: SHA-256 848 | 849 | 850 |
851 | 852 |
853 | The ciphersuite with ID 854 | BLS_SIG_BLS12381G1-SHA256-SSWU-RO-_POP_ 855 | uses the following parameters, in addition to the common parameters below. 856 | 857 | 858 | SV: minimal-signature-size 859 | hash_to_point: BLS12381G1-SHA256-SSWU-RO- with the ASCII domain separation tag 860 | BLS_SIG_BLS12381G1-SHA256-SSWU-RO-_POP_ 861 | hash_pubkey_to_point: BLS12381G1-SHA256-SSWU-RO- with the ASCII domain separation tag 862 | BLS_POP_BLS12381G1-SHA256-SSWU-RO-_POP_ 863 | 864 | 865 | The ciphersuite with ID 866 | BLS_SIG_BLS12381G2-SHA256-SSWU-RO-_POP_ 867 | uses the following parameters, in addition to the common parameters below. 868 | 869 | 870 | SV: minimal-pubkey-size 871 | hash_to_point: BLS12381G2-SHA256-SSWU-RO- with the ASCII domain separation tag 872 | BLS_SIG_BLS12381G2-SHA256-SSWU-RO-_POP_ 873 | hash_pubkey_to_point: BLS12381G2-SHA256-SSWU-RO- with the ASCII domain separation tag 874 | BLS_POP_BLS12381G2-SHA256-SSWU-RO-_POP_ 875 | 876 | 877 | The above ciphersuites share the following common parameters: 878 | 879 | 880 | SC: proof-of-possession 881 | EC: BLS12-381, as defined in . 882 | H: SHA-256 883 | 884 | 885 |
886 |
887 |
888 | 889 |
890 | 891 |
892 | All algorithms in and that operate on public keys 893 | require first validating these keys. 894 | For the basic and message augmentation schemes, the use of KeyValidate 895 | is REQUIRED. 896 | For the proof of possession scheme, each public key MUST be accompanied by 897 | a proof of possession, and use of PopVerify is REQUIRED. 898 | Note that implementations MAY cache validation results for public keys 899 | in order to avoid unnecessarily repeating validation for known keys. 900 |
901 | 902 |
903 | Some existing implementations skip the signature_subgroup_check invocation 904 | in CoreVerify (), whose purpose is ensuring that the signature 905 | is an element of a prime-order subgroup. 906 | This check is REQUIRED of conforming implementations, for two reasons. 907 | 908 | 909 | For most pairing-friendly elliptic curves used in practice, the pairing 910 | operation e () is undefined when its input points are not 911 | in the prime-order subgroups of E1 and E2. 912 | The resulting behavior is unpredictable, and may enable forgeries. 913 | Even if the pairing operation behaves properly on inputs that are outside 914 | the correct subgroups, skipping the subgroup check breaks the strong 915 | unforgeability property. 916 | 917 | 918 |
919 | 920 |
921 | Implementations of the signing algorithm SHOULD protect the secret key 922 | from side-channel attacks. 923 | One method for protecting against certain side-channel attacks is ensuring 924 | that the implementation executes exactly the same sequence of 925 | instructions and performs exactly the same memory accesses, for any 926 | value of the secret key. 927 | In other words, implementations on the underlying pairing-friendly elliptic 928 | curve SHOULD run in constant time. 929 |
930 | 931 |
932 | BLS signatures are deterministic. This protects against attacks 933 | arising from signing with bad randomness, for example, the nonce reuse 934 | attack on ECDSA . 935 | As discussed in , the IKM input to KeyGen MUST be infeasible 936 | to guess and MUST be kept secret. 937 | One possibility is to generate IKM from a trusted source of randomness. 938 | Guidelines on constructing such a source are outside the scope of this 939 | document. 940 |
941 | 942 |
943 | The security analysis models hash_to_point and hash_pubkey_to_point 944 | as random oracles. 945 | It is crucial that these functions are implemented using a cryptographically 946 | secure hash function. 947 | For this purpose, implementations MUST meet the requirements of 948 | . 949 | In addition, ciphersuites MUST specify unique domain separation tags 950 | for hash_to_point and hash_pubkey_to_point. 951 | The domain separation tag format used in is the RECOMMENDED one. 952 |
953 |
954 | 955 |
956 | This section will be removed in the final version of the draft. 957 | There are currently several implementations of BLS signatures using the BLS12-381 curve. 958 | 959 | 960 | Algorand: bls_sigs_ref 961 | Chia: spec 962 | python/C++. Here, they are 963 | swapping G1 and G2 so that the public keys are small, and the benefits 964 | of avoiding a membership check during signature verification would even be more 965 | substantial. The current implementation does not seem to implement the membership check. 966 | Chia uses the Fouque-Tibouchi hashing to the curve, which can be done in constant time. 967 | Dfinity: go BLS. The current implementations do not seem to implement the membership check. 968 | Ethereum 2.0: spec 969 | 970 | 971 |
972 | 973 |
974 | 975 | 976 | Pairing-friendly curves draft-yonezawa-pairing-friendly-curves 977 | Pairing-based Identity-Based Encryption IEEE 1363.3. 978 | Identity-Based Cryptography Standard rfc5901. 979 | Hashing to Elliptic Curves draft-irtf-cfrg-hash-to-curve-04, in order to implement the hash function hash_to_point. 980 | EdDSA rfc8032 981 | 982 | 983 |
984 | 985 |
986 | TBD (consider to register ciphersuite identifiers for BLS signature and underlying 987 | pairing curves) 988 |
989 | 990 |
991 | 992 | 993 | 994 | 995 | 996 | 997 | BLS12-381 998 | 999 | Electric Coin Company 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | Threshold Signatures, Multisignatures and Blind Signatures Based on the Gap-Diffie-Hellman-Group Signature Scheme 1009 | 1010 | University of California, San Diego 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | Compact multi-signatures for shorter blockchains 1018 | 1019 | Stanford University 1020 | 1021 | 1022 | DFINITY 1023 | 1024 | 1025 | ETH Zurich 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | Faster subgroup checks for BLS12-381 1033 | 1034 | Electric Coin Company 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | FIPS Publication 180-4: Secure Hash Standard 1044 | 1045 | National Institute of Standards and Technology (NIST) 1046 | 1047 | 1048 | 1049 | 1050 | 1051 | 1052 | Unrestricted aggregate signatures 1053 | 1054 | University of California, San Diego 1055 | 1056 | 1057 | Thammasat University 1058 | 1059 | 1060 | Katholieke Universiteit Leuven 1061 | 1062 | 1063 | 1064 | 1065 | 1066 | 1067 | Sequential Aggregate Signatures and Multisignatures Without Random Oracles 1068 | 1069 | University of California, Los Angeles 1070 | 1071 | 1072 | University of California, Los Angeles 1073 | 1074 | 1075 | University of California, Los Angeles 1076 | 1077 | 1078 | Weizmann Institute 1079 | 1080 | 1081 | SRI International 1082 | 1083 | 1084 | 1085 | 1086 | 1087 | 1088 | 1089 | Mining your Ps and Qs: Detection of widespread weak keys in network devices 1090 | 1091 | University of California, San Diego 1092 | 1093 | 1094 | The University of Michigan 1095 | 1096 | 1097 | The University of Michigan 1098 | 1099 | 1100 | The University of Michigan 1101 | 1102 | 1103 | 1104 | 1105 | 1106 | 1107 | Short signatures from the Weil pairing 1108 | 1109 | Stanford University 1110 | 1111 | 1112 | Stanford University 1113 | 1114 | 1115 | Stanford University 1116 | 1117 | 1118 | 1119 | 1120 | 1121 | 1122 | Aggregate and verifiably encrypted signatures from bilinear maps 1123 | 1124 | Stanford University 1125 | 1126 | 1127 | Stanford University 1128 | 1129 | 1130 | Stanford University 1131 | 1132 | 1133 | Stanford University 1134 | 1135 | 1136 | 1137 | 1138 | 1139 | 1140 | The Power of Proofs-of-Possession: Securing Multiparty Signatures against Rogue-Key Attacks 1141 | 1142 | University of California, San Diego 1143 | 1144 | 1145 | University of California, San Diego 1146 | 1147 | 1148 | 1149 | 1150 | 1151 | 1152 | 1153 |
1154 | The ciphersuites in are based upon the BLS12-381 1155 | pairing-friendly elliptic curve. 1156 | The following defines the correspondence between the primitives 1157 | in and the parameters given in Section 4.2.2 of 1158 | . 1159 | 1160 | 1161 | E1, G1: the curve E and its order-r subgroup. 1162 | E2, G2: the curve E' and its order-r subgroup. 1163 | GT: the subgroup G_T. 1164 | P1: the point BP. 1165 | P2: the point BP'. 1166 | e: the optimal Ate pairing defined in Appendix A of 1167 | . 1168 | point_to_octets and octets_to_point use the compressed 1169 | serialization formats for E1 and E2 defined by . 1170 | subgroup_check MAY use either the naive check described 1171 | in or the optimized check given by . 1172 | 1173 | 1174 |
1175 | 1176 |
1177 | TBA: (i) test vectors for both variants of the signature scheme 1178 | (signatures in G2 instead of G1) , (ii) test vectors ensuring 1179 | membership checks, (iii) intermediate computations ctr, hm. 1180 |
1181 | 1182 |
1183 | The security properties of the BLS signature scheme are proved in . 1184 | prove the security of aggregate signatures over distinct messages, 1185 | as in the basic scheme of . 1186 | prove security of the message augmentation scheme of . 1187 | prove security of constructions related to the proof 1188 | of possession scheme of . 1189 | prove the security of another rogue key defense; this 1190 | defense is not standardized in this document. 1191 |
1192 | 1193 |
1194 | 1195 |
1196 | --------------------------------------------------------------------------------