Partial one-time-signature chains | Level-keys |
One-time signatures
In the previous post we discussed partial one-time-signature chains for signing a small amount of bits with. In this post, we look how these partial signatures and these partial one-time signing keys can be used to compose the actual one-time signing key and signatures.
As you will remember, each signing-key chunk results in two pieces of a public key, of sorts.
The number of signing-key chunks we need to create a full one-time signing key is determined by the otsbits and the hashlen parameters. In this explanatory series of post, we use an otsbits value of 3 and a hashlen of 2. Please note that otbits of 3 is rather low, and a hashlen of 2 is not just small, but is actually not supported by coinZdense, that has a minimum value for hashlen of 16.
A fictional hashlen of 2 means we will be signing two bytes or 16 bits. Encoding 3 bits per chunk, this means we will need 6 one-time signing-key chunks to get ourselves one full one-time signing key.
Each of our six OTS sub-keys has two pub-key chunks. The operation for creating the actual one-time signing key pubkey, we simply concatenate all the chunk pubkey fragments and hash the result, again using the level-key saltas key in the generic hash operation. The result of this hashing operation is the OTS level public key.
Now when we want to sign a transaction with a one-time signing key, the first thing we need to do is to calculate a digest over the transaction. As we don't know anything about the properties of the transaction, it is wise to salt the hashing we do for calculating this digest. The transaction salt, like the level-key salt in the previous post, is derived from the master key using libsodium key derivation and an index generated by the index space allocation functionality that we will talk about in a future post.
Note that transactions are not the only things that need signing. There are also level-keys and attenuated-privilege keys. We will get back to these later, but an important thing to note now is that the signature for neither of these keys uses salting.
So now to the actual signing. Creation of the one-time signature.
We start off with the digest from our previous salted hashing operation. We chop up the hash into otsbits long chunks, padding the most significant bits with zero bits if needed. On each otsbits chunk we apply the siging process as described in our previous post, and then we simply concattenate the chunk signature parts into one large one-time signature.
In our case, the one-time signature will be six times two times hashlen bytes long, in our fictional case 24 bytes, what we must stress is rather unrealistic. If for example our hashlen has the minimum value of 16 bytes (128 bits) and we use an otsbits value of 7, our signature would end up as 19 x 2 x 16 = 608 bytes. It is important to realize that coinZdense signatures will be significantly longer than for example ECDSA signatures.
In this post we looked at combining multiple partial one-time-signature chains into a one time signing key. In our next post we are going to look into combining a collection of one-time signature keys into a level-key, that as we will see later is a building block of the actual coinZdense signing key. .
Partial one-time-signature chains | Level-keys |
|