Internet-Draft | joseph-tls-batch-signatures | November 2023 |
Joseph, et al. | Expires 8 May 2024 | [Page] |
This document proposes a construction for batch signatures where a single, potentially expensive, "base" digital signature authenticates a Merkle tree constructed from many messages.¶
Discussion of this work is encouraged to happen on the IETF TLSWG mailing list tls@ietf.org or on the GitHub repository which contains the draft: https://github.com/PhDJsandboxaq/draft-joseph-batch-signatures¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 8 May 2024.¶
Copyright (c) 2023 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
The computational complexity of unkeyed and symmetric cryptography is known to be significantly lower than asymmetric cryptography. Indeed, hash functions, stream or block ciphers typically require between a few cycles [AES-NI] to a few hundred cycles [GK12], whereas key establishment and digital signature primitives require between tens of thousands to hundreds of millions of cycles [SUPERCOP]. In situations where a substantial volume of signatures must be handled -- e.g. a Hardware Security Module (HSM) renewing a large set of short-lived certificates or a load balancer terminating a large number of TLS connections per second -- this may pose serious limitations on scaling these and related scenarios.¶
These challenges are amplified by upcoming public-key cryptography standards: in July 2022, the US National Institute of Standards and Technology (NIST) announced four algorithms for post-quantum cryptography (PQC) standardisation. In particular, three digital signature algorithms -- Dilithium [CRYSTALS-DILITHIUM], Falcon [FALCON] and SPHINCS [SPHINCS] -- were selected, and migration from current standards to these new algorithms is already underway [NSM10]. One of the key issues when considering migrating to PQC is that the computational costs of the new digital signature algorithms are significantly higher than those of ECDSA; the fastest currently-deployed primitive for signing. This severely impacts the ability of systems to scale and inhibits their migration to PQC, especially in higher-throughput settings.¶
DSA Digital Signature Algorithm, a public key cryptography primitive consisting of a triple of algorithms KeyGen, Sign, Verify whereby:¶
In this work we consider tweakable hash functions. These are keyed hash functions that take an additional input which can be thought of as a domain separator (while the key or public parameter serves as a separator between users). Tweakable hash functions allow us to tightly achieve target collision resistance even in multi-target settings where an adversary wins when they manage to attack one out of many targets.¶
Keyed Hash function A keyed hash function is one that outputs a hash that depends both on a message msg and a key v that is shared by both the hash generator and the hash validator. It is easiest to compute via prepending the key to the message before computing the hash h <-- H(v | msg). Let Hv denote the family of hash functions keyed with v.¶
Collision resistance - no two inputs x1, x2 should map to the same output hash (regardless of choice of key in the case of a keyed hash).¶
Preimage resistance - it should be difficult to guess the input value x for a hash function given only its output H(x).¶
Second preimage resistance - given an input x1, it should be difficult to find another distinct input x2 such that H(x1)=H(x2).¶
Target collision resistance - choose input x1. Then given a key v, find x2 such that Hv(x1) = Hv(x2).¶
Target collision resistance is a weaker requirement than collision resistance but is sufficient for signing purposes. Tweakable hash functions enable us to tightly achieve TCR even in multi-target settings where an adversary can attack one out of many targets. Specifically, the property achieved in the following is single-function multi-target collision resistance (SM-TCR) which is described more formally in [AABBHHJM23].¶
One form of keyed hash function is a tweakable hash function, which enables one to obtain SM-TCR:¶
Tweakable Hash functions A tweakable hash function is a tuple of algorithms H=(KeyGen, Eval) such that:¶
Batch signing enables the scaling of slow algorithms by signing large batches of messages simultaneously. This comes at a relatively low latency cost, and significant throughput improvements. These advantages are particularly pertinent when considering the use of post-quantum signatures, such as those being standardised by NIST at the time of writing. In some applications, the amount of data that needs to be sent can be reduced in addition; namely, if a given entity (is aware that it) receives multiple signatures from the same batch. In this case, sending the signed root multiple times is redundant and we can asymptotically reduce the amount of received information to a few hashes per message.¶
This document describes a construction for batch signatures based upon a Merkle tree design. The total signature consists of a signature of the root of the Merkle tree, as well as the sibling path of the individual message. We discuss the applicability of such signatures to various protocols, but only at a high level. The document describes a scheme which enables smaller signatures than outlined in [BEN20] by relying not on hash collision resistance, but instead on target collision resistance, however for the security proofs the reader should see [AABBHHJM23].¶
We define a batch signature as a triple of algorithms - Batch signature a batch signature scheme is comprised of KeyGen, BSign, Verify whereby: - KeyGen(k) outputs a keypair sk, pk where k is a security parameter - BSign(sk, M) the batch signing algorithm takes as input a list of messages M = {msg-i} and outputs a list of signatures S={sig-i}. We write S <-- BSign(sk,M) - PVerify(pk, sig, msg). We call the verification _PVerify to represent Path Verification, because in the construction outlined below, verification involves an extra step of verifying a sibling path, which Verify in the ordinary DSA setting does not do.¶
Our construction relies on a Merkle tree. When addressing nodes in a Merkle tree of height h with N leaves, we may label nodes and leaves in the tree by their position: T[i,k] is the i-th node at height k, counting from left to right and from bottom upwards (i.e. leaves are on height 0 and the root is on height h. We illustrate this in Figure 1.¶
Let Sig=(KeyGen, Sign, Verify) be a DSA as defined in Section 2.1, let thash be a tweakable hash function as defined in Section 2.2.2. We define our batch signature scheme BSig = (KeyGen, BSign, BVerify with KeyGen := Sig.KeyGen and BSign, Verify as in Section 3.1 respectively.¶
Here we describe the case of binary Merkle trees. In the case where N is not a power of 2, one can pad the tree by repeating leaves, or else continue with an incomplete tree.¶
BSign(sk, M=[msg-0,...,msg-N-1]) where N=2^n. We first treat the case that N is a power of 2, and then consider incomplete trees using standard methods.¶
Initialize tree T[ ], which is indexed by the level, and then the row index, e.g. T[3,5] is the fifth node on level 3 of T. Height h <-- log2(N)¶
Tree identifier Sample a tree identifier id <--$ {0,1}^k¶
Generate leaves For leaf i in [0,...,N-1], sample randomness r-i <--$ {0,1}^k. Then set T[0,i] = H(id, 0, i, r-i, msg-i).¶
Populate tree For levels l in [1,..., h] compute level l from level l-1 as follows:¶
Root set root <-- T[h,0]¶
Sign the root Use the base DSA to sign the root of the Merkle tree rootsig <-- Sign(sk, id, root, N)¶
Sibling path For each leaf: The sibling path is an array of h-1 hashes. Compute the sibling path as follows:¶
Generate batch signatures bsig-i <-- (id, N, sig, i, r-i, path-i)¶
Return batch of signatures batch signatures are {bsig-1, ..., bsig-N}¶
Figure 1 illustrates the construction of the Merkle tree and the signature of the root.¶
lvl3=root (T30)--DSA--> sig / \ lvl2 T20---- ----T21 /\ /\ / \ / \ lvl2 T10 T11 T12 T13 /\ /\ /\ /\ / \ / \ / \ / \ lvl1 T00 T01 T02 T03 T04 T05 T06 T07 | | | | | | | | | | | H(_) ... H(id,0,3,r3,msg3) ...H(_)
Verification proceeds by first reconstructing the root hash via the leaf information (public parameters, tweak, message) and iteratively hashing with the nodes provided in the sibling path. Next the base verification algorithm is called to verify the base DSA signature of the root.¶
A reduction in certificate sizes is proposed by a new type of CA (certificate authority) which would exclusively sign a new type of batch oriented certificates. Such a CA would only be used together with a Certificate Transparency log, which changes the usual required flows for authentication. The benefits obtained in certificate size and verification/signature costs are significant. It also implies that the main criterion for being on a same batch are: being signed by the same CA, and being signed roughly at the same time.¶
Correctness can be broken down into correctness of the base DSA, and correctness of the Merkle tree. Correctness is considered a security property, and is generally proven for each DSA, so we only need to demonstrate correctness of the Merkle tree root. The Merkle proof assures that a message is a leaf at a given index or address, in the tree identified by id, and nothing more.¶
Hash functions are symmetric and therefore deterministic in nature, therefore, given the correct sibling path as part of the signer's signature, will generate the Merkle tree root correctly. Given an accepting (message, signature) pair, so long as one uses a hash function that provides second preimage resistance (from which the tweakable hash then provides SM-TCR), this guarantees that - except with negligible probability - the proof must be valid only for the message provided.¶
Our construction uses tweakable hashfunctions which take as input a public parameter id, a tweak t, and a message msg. The public parameter domain separates between Merkle trees used in the same protocol. In [BEN20] it is suggested that TLS context strings are used to prevent cross-protocol attacks, however we note here that msg, which is the full protocol transcript up to that point, includes such protocol context strings. Therefore domain separation is handled implicitly. However in an idea world all protocols would agree on a uniform approach to domain separation, and so we invite comment on how to concretely handle this aspect.¶
Instead of collision resistance, relying on the weaker assumption of TCR, and more specifically SM-TCR, increases the attack complexity of finding a forgery and breaking the scheme. The result is that smaller hash outputs are required to achieve an equivalent security level. This key modification versus [BEN20] thus provides smaller signatures or higher security for the same sized signatures.¶
The reduction in signature size is (h-1) * d where h is the tree height and d is the difference between the hash output length based on SM-TCR and that based on collision resistance. Usually TCR implies using, for example, 128b digests to achieve 128b security, whereas basing on CR would require 256b digests. This change therefore in essence halves the size of the Merkle tree proofs.¶
Digital signatures The transition to post-quantum cryptography (PQC) coincides with increasing demands on performance and throughput. Post-quantum signatures suffer worse performance both on computation and public key/signature sizes versus their quantum-vulnerable counterparts which are based on elliptic curve cryptography and RSA. As a result, techniques to boost performance are especially relevant in this case. In Section 5.1 one can see that the extra size cost due to the sibling path is roughly independent of the algorithm used (therefore relatively much smaller for PQC).¶
Hash functions In contrast to DSAs, Hash functions are purely symmetric cryptography which is weakened but not broken by quantum computers. Therefore the Merkle tree construction is not affected in the post-quantum era, other than a doubling of parameters (in the worst case) to achieve the same security level.¶
In Figure 2 one can see the size of a batch signature which signs 16 or 32 transcripts, relative to the size of the underlying primitive. For post-quantum schemes the overhead in size is relatively small due to the much larger sizes of the base DSAs.¶
+--------------------+-----+------+-------+----+--------+ | Scheme | k | |vk| | |sig| | N | |bsig| | +--------------------+-----+------+-------+----+--------+ | ECDSA P256 | 128 | 64 | 64 | 32 | 180 | | Dilithium2 | 128 | 1312 | 2420 | 32 | 2536 | | Dilithium5 | 256 | 2592 | 4595 | 32 | 4823 | | Falcon-512 | 128 | 897 | 666 | 16 | 766 | | Falcon-1024 | 256 | 1793 | 1280 | 32 | 1508 | | Falcon-512-fpuemu | 128 | 897 | 666 | 16 | 766 | | Falcon-1024-fpuemu | 256 | 1793 | 1280 | 16 | 1476 | | SPHINGS+-128f | 128 | 32 | 17088 | 16 | 17188 | | SPHINCS-256f | 256 | 64 | 49856 | 32 | 50084 | +--------------------+-----+------+-------+----+--------+
A likely mode of transition to PQC will be via 'hybrid mode', where data is protected independently via two algorithms, one quantum-vulnerable (but well studied and understood) and one PQC algorithm. This is to mitigate the risk of a complete break - classical or quantum - of a PQC algorithm. Breaking a hybrid scheme should imply breaking both of the algorithms used.¶
We do not discuss the details of such hybrid signatures or hybrid certificates in this document, but simply state that so long as the hybrid scheme adheres to the API described above, the Batch signature Merkle tree construction described in this document remains unaltered. Explicitly, the root is generated via the procedure of Section 3.3.1. Then the root is signed by the hybrid DSA, whose functions KeyGen, Sign, Verify are constructed via some composition of KeyGen, Sign, Verify for a PQC algorithm and KeyGen, Sign, Verify for some presently-used algorithm.¶
In [AABBHHJM23] two privacy notions are defined:¶
Batch Privacy can one cannot deduce whether two messages were signed in the same batch.¶
weak Batch Privacy for two messages signed in the same batch, if one is given the signature for one¶
message, it does not leak any information about the other message, for which no signature is available.¶
The authors prove in [AABBHHJM23] that this construction achieves the weaker variant, but not full Batch Privacy.¶
A Merkle tree construction for TLS certificates [BEN23] is being developed at the time of writing, by the same author of the original Merkle tree signing draft [BEN20]. The construction bears strong similarities to the current proposal. In ordinary TLS certificates, a Certificate Authority (CA) signs a certificate which asserts that a public key belongs to a given subscriber. In the Merkle tree construction, many certificates are batched together using a similar Merkle tree construction to the one presented in this document. The CA then signs only the root of the Merkle tree, and returns (root signature + sibling path) to the subscriber.¶
A client verifies a server's identity by:¶
Verifying a server's signature: the server signs the TLS transcript up to that point with their private key and the client verifies with the server's public key pk.¶
Verifying that the public key belongs to the server by verifying the trusted CA's signatures certificate which states that the server owns pk.¶
Doing this repeatedly in the case of certificate chains until reaching a root CA.¶
The document of [BEN23] relates specifically to signing certificates, the second bullet above, whereas the constructions of [BEN20] and this document pertain to a server authenticating itself online, relating to the first bullet above. The two have slightly different usecases, which both benefit from Merkle tree constructions under different scenarios.¶
Cases where Merkle tree certificates may be appropriate have certain properties:¶
Certificates are short-lived.¶
Certificates are issued after a significant delay, e.g. around one hour.¶
Batch sizes can be estimated to be up to 2^24 (based on unexpired number of certificates in certificate transparency logs)¶
Cases where TLS batch signing may be appropriate differ slightly, for example:¶
High throughput servers and load balancers - in particular when rate of incoming signing requests exceeds (time * threads) where time is the average time for a signing thread to generate a signature, and threads is the number of available signing threads.¶
In scenarios where the latency is not extremely sensitive: waiting for signatures to arrive before constructing a Merkle tree incurs a small extra latency cost which is amortised by the significant extra throughput achievable.¶
Batch sizes are likely to be smaller than the usecase for Merkle tree certificates. Batch sizes of 16 or 32 can already improve throughput by an order of magnitude.¶