This PR implements creation and verification of sign-to-contract commitments in the
schnorrsig module. The following snippet for example puts a commitment to data32
into the (Schnorr) signature.
0/* Signer */
1secp256k1_s2c_commit_context s2c_ctx;
2secp256k1_s2c_commit_context_create(ctx, &s2c_ctx, data32);
3secp256k1_schnorrsig_sign(sign, &sig, &nonce_is_negated, msg, sk1, NULL, &s2c_ctx);
4secp256k1_s2c_commit_get_original_nonce(ctx, &s2c_original_nonce, &s2c_ctx);
5
6/* Verifier */
7secp256k1_schnorrsig_verify_s2c_commit(ctx, &sig, data32, &s2c_original_nonce, nonce_is_negated);
This PR is based on #558. The commits in this PR was previously included in #572. The tests should provide full coverage of the reachable lines.
There is also functionality for doing pay-to-contract style commitments (ec_commit), but it’s not exposed yet. If it will be in the future it would make sense to add an optional argument with a SHA midstate to allow hashing arbitrary version prefixes before hashing the public key (which would be useful in taproot for example).
Sign-to-contract and right now only work with schnorrsig_sign and nonce_function_bipschnorr. It should be straightforward to add support for ECDSA too in the future.
One thing to keep in mind is that for some users moving from ecdsa to schnorrsigs requires reading the documentation carefully. There is undocumented functionality in nonce_function_rfc6979 where the additional nonce data is hashed into the secret. If someone uses that and then call schnorrsig_sign with similar nonce data this results in a segmentation fault because nonce_function_bipschnorr which is used by default in schnorrsig_sign expects an s2c_commit_context object as nonce data and writes back to it.