Deterministic Nonce Generation for ECDSA #46
+91
−3
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This adds the main algorithm from RFC 6979, which generates deterministic nonces for ECDSA signing from the private key and the message hash to be signed.
According to RFC 6979 Section 3.3, the nonce generation can be viewed as a result of generating bits using the
HMAC_DRBG
PRNG from NIST.SP.800-90Ar1. This architecture allows for a more clean separation between the generation of random bits and the usage of those bits for generating a nonce to be used in ECDSA. Thus, I added a newDRG
instanceHmacDRG
inCrypto.Random.HmacDRG
.It was important to me to implement the algorithm from RFC 6979 faithfully and to make sure that the resulting nonces are exactly the same. The RFC contains 150 test cases across 15 curves, 2 messages, and 5 hash functions (see also #44). By making sure that the results are exact, they can be compared to these test cases to gain some confidence in the correctness of the algorithm.
This requirement also meant that I could not use the
Crypto.Number.Generate.generateParams
function to generate the nonce from a properly initializedHmacDRG
, sincegenerateParams
takes the bits from the wrong end of a sequence of generated bytes. Because of this, I added the functionCrypto.Number.Generate.generatePrefix
.Finally, the function
Crypto.PubKey.ECC.ECDSA.deterministicNonce
implements the main algorithm. The description in RFC 6979 Section 3.2 contains many technical details about shifting bits, and converting and truncating sequences. It turned out that existing functions likei2ospOf_
anddsaTruncHashDigest
implemented most of the required semantics so the final implementation is a lot shorter than the version presented in the RFC.The function
deterministicNonce
has the following signature:The idea is that the parameter with type
Integer -> Maybe a
is one of thesign*With
functions. The algorithm will continue generating nonces until the givensign*With
function accepts one and then pass on the result.