Right now, we have two different ways of handling invalid inputs in constant-time functions:
- The function is constant-time, even for invalid inputs. For example,
secp256k1_schnorrsig_sign_internal
continues with the signing procedure even ifkeypair_load
fails (which happens when the keypair is unitialized):This works because even if0ret &= secp256k1_keypair_load(ctx, &sk, &pk, keypair); 1... 2return ret;
secp256k1_keypair_load
fails, valid values (sk=1, pk=G) are returned. - The function is constant-time only for valid inputs. For example, in
secp256k1_musig_partial_sign
, we haveThis works because the return value of0if (!secp256k1_keypair_load(ctx, &sk, &keypair_pk, keypair)) { 1 secp256k1_musig_partial_sign_clear(&sk, k); 2 return 0; 3}
keypair_load
is declassified.
I think we should make functions only constant-time with respect to valid inputs. This leads to more readable and maintainable code (due to fewer ret &=
). Calling functions with invalid inputs (such as an unitialized keypair) should never happen outside of development.
Whatever version we’re choosing, we should document it in CONTRIBUTING.md.