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_internalcontinues with the signing procedure even ifkeypair_loadfails (which happens when the keypair is unitialized):ret &= secp256k1_keypair_load(ctx, &sk, &pk, keypair); ... return ret;This works because even if
secp256k1_keypair_loadfails, 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 haveif (!secp256k1_keypair_load(ctx, &sk, &keypair_pk, keypair)) { secp256k1_musig_partial_sign_clear(&sk, k); return 0; }This works because the return value of
keypair_loadis 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.