status-im / nim-secp256k1

A wrapper for libsecp256k1
Apache License 2.0
7 stars 5 forks source link

use external rng instead of nimcrypto #23

Closed arnetheduck closed 4 years ago

arnetheduck commented 4 years ago

allows passing in different RNG's to generate keys

arnetheduck commented 4 years ago

I would be more comfortable if we were completely deterministic and only passing an Input-Keying-Material

well, I suspect this would simply move the loop outside - ie there's not a lot of options the caller has if they want a key - if they care enough, they could pass in an RNG that simply fails after an iteration, but in the most common case, they just want key no matter what.

that said, I don't really mind changing this to take an array of random bytes - as far as secp is concerned, we just pass that through verify and we're done (as long as there's enough bytes). The API becomes slightly more tricky because now you need to verify the length of it, and you need tell the caller that it's "safe" to try again with a different number etc so there's a few more ways to fail when calling it.

constant-time

Is this relevant in the context? ie that the RNG produces a quality number (presumably in constant time) seems important but how many tries we take to get there seems less of an issue?

entropy

the nist-based CSPRNGS run out after something like 2^48 bytes - I think we can safely ignore this for anything but the most secure generation methods - ie for generating long-running keys like your main wallet, there exist better ways - this function is basically here for the default "let's set up an ephemeral secure channel" kind of use

mratsim commented 4 years ago

well, I suspect this would simply move the loop outside - ie there's not a lot of options the caller has if they want a key

The scheme used in Eth2 always produce a valid key with a single RNG call. It works like this:

  1. Get a random input
  2. Take the input modulo r, the curve order

What we are doing here is just testing repeatedly until we find an integer below the curve order.

In the BLS spec, the Get a random input is split into

  1. Get the output of a CSPRNG as a 32 bytes Input-Keying-Material
  2. HKDF it

constant-time

Is this relevant in the context? ie that the RNG produces a quality number (presumably in constant time) seems important but how many tries we take to get there seems less of an issue?

It is, source https://cfrg.github.io/draft-irtf-cfrg-hash-to-curve/draft-irtf-cfrg-hash-to-curve.html image

The first iteration of WPA3 was broken due to non-constant-time password encoding:

As long as we touch secret data, we SHOULD be constant-time.