Merkle signatures #
Merkle's tree signature ([Mer90], Section 6) authenticates 2 ^ d one-time verification
keys by the root of a Merkle tree, which is the public key. The signature at leaf u is the
one-time key of leaf u, its one-time signature and its authentication path. Each leaf may be used
once, so the scheme is an indexed signature scheme (IndexedSignatureScheme) whose index is the
leaf ([BS23], Section 14.6.1, "Shrinking the public-key").
MerkleSignature.scheme S H depth builds it from any signature scheme S, used as a one-time
scheme on n-bit messages, and a keyed hash H with n-bit digests under n-bit keys:
- key generation samples a hash key
k ← {0, 1}^nand2 ^ depth nkey pairs ofS, and publisheskand the Merkle root of the one-time verification keys; - signing
msgat leafusigns the digestH k msgwith the one-time key of leafu(hash-and-sign, [BS23], Section 13.2), and attaches the verification key and the authentication path; - verification checks the opening of leaf
uwithmerkleVerify, which fixes the path length todepth nand checksu < 2 ^ depth n, and then the one-time signature onH k msg.
The capacity is 2 ^ depth n, required to be computable in unary in polynomial time, hence
polynomial in n. Security is in Complexity.Crypto.Computational.MerkleSignature.Security.
The scheme is stateful in use: the signer must sign at most once per leaf, for instance with a
counter. IndexedSignatureScheme makes the leaf an explicit input, and its security game refuses
a repeated leaf.
Main definitions #
Cslib.Crypto.MerkleSignature.encodeSignature,Cslib.Crypto.MerkleSignature.signatureDecoder: the signature word.Cslib.Crypto.MerkleSignature.publicKey,Cslib.Crypto.MerkleSignature.secretKey,Cslib.Crypto.MerkleSignature.secretKeyDecoder: the key words.Cslib.Crypto.MerkleSignature.keyGen,Cslib.Crypto.MerkleSignature.signWith,Cslib.Crypto.MerkleSignature.sign,Cslib.Crypto.MerkleSignature.verify: the algorithms.Cslib.Crypto.MerkleSignature.scheme: the indexed signature scheme.
Main results #
Cslib.Crypto.MerkleSignature.verify_sign: completeness.Cslib.Crypto.MerkleSignature.isPPTOn_keyGen,Cslib.Crypto.MerkleSignature.isPPTOn_sign,Cslib.Crypto.MerkleSignature.computableInPolyTime_verify: efficiency.
References #
- R. C. Merkle, A Certified Digital Signature, Section 6.
- D. Boneh, V. Shoup, A Graduate Course in Applied Cryptography, Sections 8.9, 13.2 and 14.6.1.
Words #
Read the one-time verification key, the one-time signature and the authentication path of a signature word.
Instances For
Read the hash key and the one-time key pairs of a secret key word.
Instances For
Algorithms #
Sign msg at leaf u, given the hash key and the one-time key pairs: sign the digest
H k msg with the one-time key of leaf u, and attach its verification key and authentication
path.
Instances For
Verify a signature on msg at leaf u under the public key pk = (k, root): the attached
verification key opens leaf u of the depth-depth k.length tree with root root
(merkleVerify, which checks the path length and u < 2 ^ depth k.length), and the one-time
signature verifies on H k msg.
Instances For
Completeness #
Every supported key generation produces an n-bit hash key and 2 ^ depth n supported
one-time key pairs.
Completeness: an honest signature at a leaf u < 2 ^ depth n verifies.
Efficiency #
The depth is computable from the capacity.
Computing the public key from the hash key and the one-time key pairs takes polynomial time.
Merkle key generation is uniformly strict PPT.
Merkle signing is uniformly strict PPT.
Merkle verification is computable in polynomial time.
Merkle's tree signature ([Mer90], Section 6; [BS23], Section 14.6.1) as
an indexed signature scheme of capacity 2 ^ depth n, from a signature scheme S used as a
one-time scheme and a keyed hash H with digests of the key's length.