117 lines
3.5 KiB
C
117 lines
3.5 KiB
C
/**********************************************************************
|
|
* Copyright (c) 2020 Andrew Poelstra *
|
|
* Distributed under the MIT software license, see the accompanying *
|
|
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
|
|
**********************************************************************/
|
|
|
|
#ifndef SECP256K1_MODULE_BPPP_MAIN_IMPL_H
|
|
#define SECP256K1_MODULE_BPPP_MAIN_IMPL_H
|
|
|
|
#include "../../../include/secp256k1_bppp.h"
|
|
#include "../../../include/secp256k1_generator.h"
|
|
#include "../generator/main_impl.h" /* for generator_{load, save} */
|
|
#include "../../hash.h"
|
|
#include "../../util.h"
|
|
#include "../bppp/main.h"
|
|
#include "../bppp/bppp_norm_product_impl.h"
|
|
|
|
secp256k1_bppp_generators *secp256k1_bppp_generators_create(const secp256k1_context *ctx, size_t n) {
|
|
secp256k1_bppp_generators *ret;
|
|
secp256k1_rfc6979_hmac_sha256 rng;
|
|
const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(ctx);
|
|
unsigned char seed[64];
|
|
size_t i;
|
|
|
|
VERIFY_CHECK(ctx != NULL);
|
|
|
|
ret = checked_malloc(&ctx->error_callback, sizeof(*ret));
|
|
if (ret == NULL) {
|
|
return NULL;
|
|
}
|
|
ret->gens = checked_malloc(&ctx->error_callback, n * sizeof(*ret->gens));
|
|
if (ret->gens == NULL) {
|
|
free(ret);
|
|
return NULL;
|
|
}
|
|
ret->n = n;
|
|
|
|
secp256k1_fe_get_b32(&seed[0], &secp256k1_ge_const_g.x);
|
|
secp256k1_fe_get_b32(&seed[32], &secp256k1_ge_const_g.y);
|
|
|
|
secp256k1_rfc6979_hmac_sha256_initialize(hash_ctx, &rng, seed, 64);
|
|
for (i = 0; i < n; i++) {
|
|
secp256k1_generator gen;
|
|
unsigned char tmp[32] = { 0 };
|
|
secp256k1_rfc6979_hmac_sha256_generate(hash_ctx, &rng, tmp, 32);
|
|
CHECK(secp256k1_generator_generate(ctx, &gen, tmp));
|
|
secp256k1_generator_load(&ret->gens[i], &gen);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
secp256k1_bppp_generators* secp256k1_bppp_generators_parse(const secp256k1_context* ctx, const unsigned char* data, size_t data_len) {
|
|
size_t n = data_len / 33;
|
|
secp256k1_bppp_generators* ret;
|
|
|
|
VERIFY_CHECK(ctx != NULL);
|
|
ARG_CHECK(data != NULL);
|
|
|
|
if (data_len % 33 != 0) {
|
|
return NULL;
|
|
}
|
|
|
|
ret = checked_malloc(&ctx->error_callback, sizeof(*ret));
|
|
if (ret == NULL) {
|
|
return NULL;
|
|
}
|
|
ret->n = n;
|
|
ret->gens = checked_malloc(&ctx->error_callback, n * sizeof(*ret->gens));
|
|
if (ret->gens == NULL) {
|
|
free(ret);
|
|
return NULL;
|
|
}
|
|
|
|
while (n--) {
|
|
secp256k1_generator gen;
|
|
if (!secp256k1_generator_parse(ctx, &gen, &data[33 * n])) {
|
|
free(ret->gens);
|
|
free(ret);
|
|
return NULL;
|
|
}
|
|
secp256k1_generator_load(&ret->gens[n], &gen);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int secp256k1_bppp_generators_serialize(const secp256k1_context* ctx, const secp256k1_bppp_generators* gens, unsigned char* data, size_t *data_len) {
|
|
size_t i;
|
|
|
|
VERIFY_CHECK(ctx != NULL);
|
|
ARG_CHECK(gens != NULL);
|
|
ARG_CHECK(data != NULL);
|
|
ARG_CHECK(data_len != NULL);
|
|
ARG_CHECK(*data_len >= 33 * gens->n);
|
|
|
|
memset(data, 0, *data_len);
|
|
for (i = 0; i < gens->n; i++) {
|
|
secp256k1_generator gen;
|
|
secp256k1_generator_save(&gen, &gens->gens[i]);
|
|
secp256k1_generator_serialize(ctx, &data[33 * i], &gen);
|
|
}
|
|
|
|
*data_len = 33 * gens->n;
|
|
return 1;
|
|
}
|
|
|
|
void secp256k1_bppp_generators_destroy(const secp256k1_context* ctx, secp256k1_bppp_generators *gens) {
|
|
VERIFY_CHECK(ctx != NULL);
|
|
(void) ctx;
|
|
if (gens != NULL) {
|
|
free(gens->gens);
|
|
free(gens);
|
|
}
|
|
}
|
|
|
|
#endif
|