Expose ability to deep-copy a context
This commit is contained in:
parent
3608c7f2f6
commit
d899b5b67c
|
@ -59,6 +59,14 @@ secp256k1_context_t* secp256k1_context_create(
|
|||
int flags
|
||||
) SECP256K1_WARN_UNUSED_RESULT;
|
||||
|
||||
/** Copies a secp256k1 context object.
|
||||
* Returns: a newly created context object.
|
||||
* In: ctx: an existing context to copy
|
||||
*/
|
||||
secp256k1_context_t* secp256k1_context_clone(
|
||||
const secp256k1_context_t* ctx
|
||||
) SECP256K1_WARN_UNUSED_RESULT;
|
||||
|
||||
/** Destroy a secp256k1 context object.
|
||||
* The context pointer may not be used afterwards.
|
||||
*/
|
||||
|
|
|
@ -20,6 +20,8 @@ typedef struct {
|
|||
|
||||
static void secp256k1_ecmult_context_init(secp256k1_ecmult_context_t *ctx);
|
||||
static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx);
|
||||
static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context_t *dst,
|
||||
const secp256k1_ecmult_context_t *src);
|
||||
static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context_t *ctx);
|
||||
static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context_t *ctx);
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@ typedef struct {
|
|||
|
||||
static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context_t* ctx);
|
||||
static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t* ctx);
|
||||
static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context_t *dst,
|
||||
const secp256k1_ecmult_gen_context_t* src);
|
||||
static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context_t* ctx);
|
||||
static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context_t* ctx);
|
||||
|
||||
|
|
|
@ -80,6 +80,16 @@ static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_cont
|
|||
return ctx->prec != NULL;
|
||||
}
|
||||
|
||||
static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context_t *dst,
|
||||
const secp256k1_ecmult_gen_context_t *src) {
|
||||
if (src->prec == NULL) {
|
||||
dst->prec = NULL;
|
||||
} else {
|
||||
dst->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(sizeof(*dst->prec));
|
||||
memcpy(dst->prec, src->prec, sizeof(*dst->prec));
|
||||
}
|
||||
}
|
||||
|
||||
static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context_t *ctx) {
|
||||
free(ctx->prec);
|
||||
ctx->prec = NULL;
|
||||
|
|
|
@ -131,6 +131,26 @@ static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context_t *dst,
|
||||
const secp256k1_ecmult_context_t *src) {
|
||||
if (src->pre_g == NULL) {
|
||||
dst->pre_g = NULL;
|
||||
} else {
|
||||
size_t size = sizeof((*dst->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G);
|
||||
dst->pre_g = (secp256k1_ge_storage_t (*)[])checked_malloc(size);
|
||||
memcpy(dst->pre_g, src->pre_g, size);
|
||||
}
|
||||
#ifdef USE_ENDOMORPHISM
|
||||
if (src->pre_g_128 == NULL) {
|
||||
dst->pre_g_128 = NULL;
|
||||
} else {
|
||||
size_t size = sizeof((*dst->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G);
|
||||
dst->pre_g_128 = (secp256k1_ge_storage_t (*)[])checked_malloc(size);
|
||||
memcpy(dst->pre_g_128, src->pre_g_128, size);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context_t *ctx) {
|
||||
return ctx->pre_g != NULL;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,13 @@ secp256k1_context_t* secp256k1_context_create(int flags) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
secp256k1_context_t* secp256k1_context_clone(const secp256k1_context_t* ctx) {
|
||||
secp256k1_context_t* ret = (secp256k1_context_t*)checked_malloc(sizeof(secp256k1_context_t));
|
||||
secp256k1_ecmult_context_clone(&ret->ecmult_ctx, &ctx->ecmult_ctx);
|
||||
secp256k1_ecmult_gen_context_clone(&ret->ecmult_gen_ctx, &ctx->ecmult_gen_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void secp256k1_context_destroy(secp256k1_context_t* ctx) {
|
||||
secp256k1_ecmult_context_clear(&ctx->ecmult_ctx);
|
||||
secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx);
|
||||
|
|
42
src/tests.c
42
src/tests.c
|
@ -103,6 +103,47 @@ void random_scalar_order(secp256k1_scalar_t *num) {
|
|||
} while(1);
|
||||
}
|
||||
|
||||
void run_context_tests(void) {
|
||||
secp256k1_context_t *none = secp256k1_context_create(0);
|
||||
secp256k1_context_t *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
|
||||
secp256k1_context_t *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
|
||||
secp256k1_context_t *both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
|
||||
|
||||
secp256k1_gej_t pubj;
|
||||
secp256k1_ge_t pub;
|
||||
secp256k1_scalar_t msg, key, nonce;
|
||||
secp256k1_ecdsa_sig_t sig;
|
||||
|
||||
/*** clone and destroy all of them to make sure cloning was complete ***/
|
||||
{
|
||||
secp256k1_context_t *ctx_tmp;
|
||||
|
||||
ctx_tmp = none; none = secp256k1_context_clone(none); secp256k1_context_destroy(ctx_tmp);
|
||||
ctx_tmp = sign; sign = secp256k1_context_clone(sign); secp256k1_context_destroy(ctx_tmp);
|
||||
ctx_tmp = vrfy; vrfy = secp256k1_context_clone(vrfy); secp256k1_context_destroy(ctx_tmp);
|
||||
ctx_tmp = both; both = secp256k1_context_clone(both); secp256k1_context_destroy(ctx_tmp);
|
||||
}
|
||||
|
||||
/*** attempt to use them ***/
|
||||
random_scalar_order_test(&msg);
|
||||
random_scalar_order_test(&key);
|
||||
secp256k1_ecmult_gen(&both->ecmult_gen_ctx, &pubj, &key);
|
||||
secp256k1_ge_set_gej(&pub, &pubj);
|
||||
|
||||
/* obtain a working nonce */
|
||||
do {
|
||||
random_scalar_order_test(&nonce);
|
||||
} while(!secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sig, &key, &msg, &nonce, NULL));
|
||||
|
||||
/* try signing */
|
||||
CHECK(secp256k1_ecdsa_sig_sign(&sign->ecmult_gen_ctx, &sig, &key, &msg, &nonce, NULL));
|
||||
CHECK(secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sig, &key, &msg, &nonce, NULL));
|
||||
|
||||
/* try verifying */
|
||||
CHECK(secp256k1_ecdsa_sig_verify(&vrfy->ecmult_ctx, &sig, &pub, &msg));
|
||||
CHECK(secp256k1_ecdsa_sig_verify(&both->ecmult_ctx, &sig, &pub, &msg));
|
||||
}
|
||||
|
||||
/***** HASH TESTS *****/
|
||||
|
||||
void run_sha256_tests(void) {
|
||||
|
@ -1863,6 +1904,7 @@ int main(int argc, char **argv) {
|
|||
printf("random seed = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", seed16[0], seed16[1], seed16[2], seed16[3], seed16[4], seed16[5], seed16[6], seed16[7], seed16[8], seed16[9], seed16[10], seed16[11], seed16[12], seed16[13], seed16[14], seed16[15]);
|
||||
|
||||
/* initialize */
|
||||
run_context_tests();
|
||||
ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
|
||||
|
||||
run_sha256_tests();
|
||||
|
|
Loading…
Reference in New Issue