secp256k1-zkp/src/modules/whitelist/whitelist_impl.h
Jonas Nick 938725c1c9 Merge commits 'd7ec49a6 9a5a87e0 aa5d34a8 2a3a97c6 ' into temp-merge-976
Also remove remaining uses of ecmult context in secp-zkp and update API tests
accordingly.
2021-09-16 15:21:11 +00:00

130 lines
4.4 KiB
C

/**********************************************************************
* Copyright (c) 2016 Andrew Poelstra *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
#ifndef _SECP256K1_WHITELIST_IMPL_H_
#define _SECP256K1_WHITELIST_IMPL_H_
static int secp256k1_whitelist_hash_pubkey(secp256k1_scalar* output, secp256k1_gej* pubkey) {
unsigned char h[32];
unsigned char c[33];
secp256k1_sha256 sha;
int overflow = 0;
size_t size = 33;
secp256k1_ge ge;
secp256k1_ge_set_gej(&ge, pubkey);
secp256k1_sha256_initialize(&sha);
if (!secp256k1_eckey_pubkey_serialize(&ge, c, &size, SECP256K1_EC_COMPRESSED)) {
return 0;
}
secp256k1_sha256_write(&sha, c, size);
secp256k1_sha256_finalize(&sha, h);
secp256k1_scalar_set_b32(output, h, &overflow);
if (overflow || secp256k1_scalar_is_zero(output)) {
/* This return path is mathematically impossible to hit */
secp256k1_scalar_clear(output);
return 0;
}
return 1;
}
static int secp256k1_whitelist_tweak_pubkey(secp256k1_gej* pub_tweaked) {
secp256k1_scalar tweak;
secp256k1_scalar zero;
int ret;
secp256k1_scalar_set_int(&zero, 0);
ret = secp256k1_whitelist_hash_pubkey(&tweak, pub_tweaked);
if (ret) {
secp256k1_ecmult(pub_tweaked, pub_tweaked, &tweak, &zero);
}
return ret;
}
static int secp256k1_whitelist_compute_tweaked_privkey(const secp256k1_context* ctx, secp256k1_scalar* skey, const unsigned char *online_key, const unsigned char *summed_key) {
secp256k1_scalar tweak;
int ret = 1;
int overflow = 0;
secp256k1_scalar_set_b32(skey, summed_key, &overflow);
if (overflow || secp256k1_scalar_is_zero(skey)) {
ret = 0;
}
if (ret) {
secp256k1_gej pkeyj;
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pkeyj, skey);
ret = secp256k1_whitelist_hash_pubkey(&tweak, &pkeyj);
}
if (ret) {
secp256k1_scalar sonline;
secp256k1_scalar_mul(skey, skey, &tweak);
secp256k1_scalar_set_b32(&sonline, online_key, &overflow);
if (overflow || secp256k1_scalar_is_zero(&sonline)) {
ret = 0;
}
secp256k1_scalar_add(skey, skey, &sonline);
secp256k1_scalar_clear(&sonline);
secp256k1_scalar_clear(&tweak);
}
if (!ret) {
secp256k1_scalar_clear(skey);
}
return ret;
}
/* Takes a list of pubkeys and combines them to form the public keys needed
* for the ring signature; also produce a commitment to every one that will
* be our "message". */
static int secp256k1_whitelist_compute_keys_and_message(const secp256k1_context* ctx, unsigned char *msg32, secp256k1_gej *keys, const secp256k1_pubkey *online_pubkeys, const secp256k1_pubkey *offline_pubkeys, const int n_keys, const secp256k1_pubkey *sub_pubkey) {
unsigned char c[33];
size_t size = 33;
secp256k1_sha256 sha;
int i;
secp256k1_ge subkey_ge;
secp256k1_sha256_initialize(&sha);
secp256k1_pubkey_load(ctx, &subkey_ge, sub_pubkey);
/* commit to sub-key */
if (!secp256k1_eckey_pubkey_serialize(&subkey_ge, c, &size, SECP256K1_EC_COMPRESSED)) {
return 0;
}
secp256k1_sha256_write(&sha, c, size);
for (i = 0; i < n_keys; i++) {
secp256k1_ge offline_ge;
secp256k1_ge online_ge;
secp256k1_gej tweaked_gej;
/* commit to fixed keys */
secp256k1_pubkey_load(ctx, &offline_ge, &offline_pubkeys[i]);
if (!secp256k1_eckey_pubkey_serialize(&offline_ge, c, &size, SECP256K1_EC_COMPRESSED)) {
return 0;
}
secp256k1_sha256_write(&sha, c, size);
secp256k1_pubkey_load(ctx, &online_ge, &online_pubkeys[i]);
if (!secp256k1_eckey_pubkey_serialize(&online_ge, c, &size, SECP256K1_EC_COMPRESSED)) {
return 0;
}
secp256k1_sha256_write(&sha, c, size);
/* compute tweaked keys */
secp256k1_gej_set_ge(&tweaked_gej, &offline_ge);
secp256k1_gej_add_ge_var(&tweaked_gej, &tweaked_gej, &subkey_ge, NULL);
secp256k1_whitelist_tweak_pubkey(&tweaked_gej);
secp256k1_gej_add_ge_var(&keys[i], &tweaked_gej, &online_ge, NULL);
}
secp256k1_sha256_finalize(&sha, msg32);
return 1;
}
#endif