secp256k1-zkp/src/modules/surjection/surjection_impl.h

87 lines
3.0 KiB
C
Raw Normal View History

/**********************************************************************
* 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_SURJECTION_IMPL_H_
#define _SECP256K1_SURJECTION_IMPL_H_
#include <assert.h>
#include <string.h>
#include "eckey.h"
#include "group.h"
#include "scalar.h"
#include "hash.h"
SECP256K1_INLINE static void secp256k1_surjection_genmessage(unsigned char *msg32, secp256k1_ge *ephemeral_input_tags, size_t n_input_tags, secp256k1_ge *ephemeral_output_tag) {
/* compute message */
size_t i;
unsigned char pk_ser[33];
size_t pk_len = sizeof(pk_ser);
secp256k1_sha256 sha256_en;
secp256k1_sha256_initialize(&sha256_en);
for (i = 0; i < n_input_tags; i++) {
secp256k1_eckey_pubkey_serialize(&ephemeral_input_tags[i], pk_ser, &pk_len, 1);
assert(pk_len == sizeof(pk_ser));
secp256k1_sha256_write(&sha256_en, pk_ser, pk_len);
}
secp256k1_eckey_pubkey_serialize(ephemeral_output_tag, pk_ser, &pk_len, 1);
assert(pk_len == sizeof(pk_ser));
secp256k1_sha256_write(&sha256_en, pk_ser, pk_len);
secp256k1_sha256_finalize(&sha256_en, msg32);
}
SECP256K1_INLINE static int secp256k1_surjection_genrand(secp256k1_scalar *s, size_t ns, const secp256k1_scalar *blinding_key) {
size_t i;
unsigned char sec_input[36];
secp256k1_sha256 sha256_en;
/* compute s values */
secp256k1_scalar_get_b32(&sec_input[4], blinding_key);
for (i = 0; i < ns; i++) {
int overflow = 0;
sec_input[0] = i;
sec_input[1] = i >> 8;
sec_input[2] = i >> 16;
sec_input[3] = i >> 24;
secp256k1_sha256_initialize(&sha256_en);
secp256k1_sha256_write(&sha256_en, sec_input, 36);
secp256k1_sha256_finalize(&sha256_en, sec_input);
secp256k1_scalar_set_b32(&s[i], sec_input, &overflow);
if (overflow == 1) {
memset(sec_input, 0, 32);
return 0;
}
}
memset(sec_input, 0, 32);
return 1;
}
SECP256K1_INLINE static int secp256k1_surjection_compute_public_keys(secp256k1_gej *pubkeys, size_t n_pubkeys, const secp256k1_ge *input_tags, size_t n_input_tags, const unsigned char *used_tags, const secp256k1_ge *output_tag, size_t input_index, size_t *ring_input_index) {
size_t i;
size_t j = 0;
for (i = 0; i < n_input_tags; i++) {
if (used_tags[i / 8] & (1 << (i % 8))) {
secp256k1_ge tmpge;
secp256k1_ge_neg(&tmpge, &input_tags[i]);
secp256k1_gej_set_ge(&pubkeys[j], &tmpge);
secp256k1_gej_add_ge_var(&pubkeys[j], &pubkeys[j], output_tag, NULL);
if (ring_input_index != NULL && input_index == i) {
*ring_input_index = j;
}
j++;
if (j > n_pubkeys) {
return 0;
}
}
}
return 1;
}
#endif