Skip to content

Commit ae4f0c6

Browse files
committed
Merge pull request #278
995c548 Introduce callback functions for dealing with errors. (Pieter Wuille)
2 parents c333074 + 995c548 commit ae4f0c6

File tree

11 files changed

+206
-117
lines changed

11 files changed

+206
-117
lines changed

include/secp256k1.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,37 @@ void secp256k1_context_destroy(
7474
secp256k1_context_t* ctx
7575
) SECP256K1_ARG_NONNULL(1);
7676

77+
/** Set a callback function to be called when an illegal argument is passed to
78+
* an API call. The philosophy is that these shouldn't be dealt with through a
79+
* specific return value, as calling code should not have branches to deal with
80+
* the case that this code itself is broken.
81+
* On the other hand, during debug stage, one would want to be informed about
82+
* such mistakes, and the default (crashing) may be inadvisable.
83+
* When this callback is triggered, the API function called is guaranteed not
84+
* to cause a crash, though its return value and output arguments are
85+
* undefined.
86+
*/
87+
void secp256k1_context_set_illegal_callback(
88+
secp256k1_context_t* ctx,
89+
void (*fun)(const char* message, void* data),
90+
void* data
91+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
92+
93+
/** Set a callback function to be called when an internal consistency check
94+
* fails. The default is crashing.
95+
* This can only trigger in case of a hardware failure, miscompilation,
96+
* memory corruption, serious bug in the library, or other error would can
97+
* otherwise result in undefined behaviour. It will not trigger due to mere
98+
* incorrect usage of the API (see secp256k1_context_set_illegal_callback
99+
* for that). After this callback returns, anything may happen, including
100+
* crashing.
101+
*/
102+
void secp256k1_context_set_error_callback(
103+
secp256k1_context_t* ctx,
104+
void (*fun)(const char* message, void* data),
105+
void* data
106+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
107+
77108
/** Data type to hold a parsed and valid public key.
78109
This data type should be considered opaque to the user, and only created
79110
through API functions. It is not guaranteed to be compatible between

src/ecmult.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ typedef struct {
1919
} secp256k1_ecmult_context_t;
2020

2121
static void secp256k1_ecmult_context_init(secp256k1_ecmult_context_t *ctx);
22-
static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx);
22+
static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx, const callback_t *cb);
2323
static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context_t *dst,
24-
const secp256k1_ecmult_context_t *src);
24+
const secp256k1_ecmult_context_t *src, const callback_t *cb);
2525
static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context_t *ctx);
2626
static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context_t *ctx);
2727

src/ecmult_gen.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ typedef struct {
2929
} secp256k1_ecmult_gen_context_t;
3030

3131
static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context_t* ctx);
32-
static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t* ctx);
32+
static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t* ctx, const callback_t* cb);
3333
static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context_t *dst,
34-
const secp256k1_ecmult_gen_context_t* src);
34+
const secp256k1_ecmult_gen_context_t* src, const callback_t* cb);
3535
static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context_t* ctx);
3636
static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context_t* ctx);
3737

src/ecmult_gen_impl.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context_t *ct
1818
ctx->prec = NULL;
1919
}
2020

21-
static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t *ctx) {
21+
static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t *ctx, const callback_t* cb) {
2222
#ifndef USE_ECMULT_STATIC_PRECOMPUTATION
2323
secp256k1_ge_t prec[1024];
2424
secp256k1_gej_t gj;
@@ -30,7 +30,7 @@ static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t *c
3030
return;
3131
}
3232
#ifndef USE_ECMULT_STATIC_PRECOMPUTATION
33-
ctx->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(sizeof(*ctx->prec));
33+
ctx->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(cb, sizeof(*ctx->prec));
3434

3535
/* get the generator */
3636
secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g);
@@ -72,14 +72,15 @@ static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t *c
7272
secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL);
7373
}
7474
}
75-
secp256k1_ge_set_all_gej_var(1024, prec, precj);
75+
secp256k1_ge_set_all_gej_var(1024, prec, precj, cb);
7676
}
7777
for (j = 0; j < 64; j++) {
7878
for (i = 0; i < 16; i++) {
7979
secp256k1_ge_to_storage(&(*ctx->prec)[j][i], &prec[j*16 + i]);
8080
}
8181
}
8282
#else
83+
(void)cb;
8384
ctx->prec = (secp256k1_ge_storage_t (*)[64][16])secp256k1_ecmult_static_context;
8485
#endif
8586
secp256k1_ecmult_gen_blind(ctx, NULL);
@@ -90,14 +91,15 @@ static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_cont
9091
}
9192

9293
static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context_t *dst,
93-
const secp256k1_ecmult_gen_context_t *src) {
94+
const secp256k1_ecmult_gen_context_t *src, const callback_t* cb) {
9495
if (src->prec == NULL) {
9596
dst->prec = NULL;
9697
} else {
9798
#ifndef USE_ECMULT_STATIC_PRECOMPUTATION
98-
dst->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(sizeof(*dst->prec));
99+
dst->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(cb, sizeof(*dst->prec));
99100
memcpy(dst->prec, src->prec, sizeof(*dst->prec));
100101
#else
102+
(void)cb;
101103
dst->prec = src->prec;
102104
#endif
103105
dst->initial = src->initial;

src/ecmult_impl.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,10 @@ static void secp256k1_ecmult_odd_multiples_table_globalz_windowa(secp256k1_ge_t
9292
secp256k1_ge_globalz_set_table_gej(ECMULT_TABLE_SIZE(WINDOW_A), pre, globalz, prej, zr);
9393
}
9494

95-
static void secp256k1_ecmult_odd_multiples_table_storage_var(int n, secp256k1_ge_storage_t *pre, const secp256k1_gej_t *a) {
96-
secp256k1_gej_t *prej = (secp256k1_gej_t*)checked_malloc(sizeof(secp256k1_gej_t) * n);
97-
secp256k1_ge_t *prea = (secp256k1_ge_t*)checked_malloc(sizeof(secp256k1_ge_t) * n);
98-
secp256k1_fe_t *zr = (secp256k1_fe_t*)checked_malloc(sizeof(secp256k1_fe_t) * n);
95+
static void secp256k1_ecmult_odd_multiples_table_storage_var(int n, secp256k1_ge_storage_t *pre, const secp256k1_gej_t *a, const callback_t *cb) {
96+
secp256k1_gej_t *prej = (secp256k1_gej_t*)checked_malloc(cb, sizeof(secp256k1_gej_t) * n);
97+
secp256k1_ge_t *prea = (secp256k1_ge_t*)checked_malloc(cb, sizeof(secp256k1_ge_t) * n);
98+
secp256k1_fe_t *zr = (secp256k1_fe_t*)checked_malloc(cb, sizeof(secp256k1_fe_t) * n);
9999
int i;
100100

101101
/* Compute the odd multiples in Jacobian form. */
@@ -144,7 +144,7 @@ static void secp256k1_ecmult_context_init(secp256k1_ecmult_context_t *ctx) {
144144
#endif
145145
}
146146

147-
static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx) {
147+
static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx, const callback_t *cb) {
148148
secp256k1_gej_t gj;
149149

150150
if (ctx->pre_g != NULL) {
@@ -154,43 +154,43 @@ static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx) {
154154
/* get the generator */
155155
secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g);
156156

157-
ctx->pre_g = (secp256k1_ge_storage_t (*)[])checked_malloc(sizeof((*ctx->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G));
157+
ctx->pre_g = (secp256k1_ge_storage_t (*)[])checked_malloc(cb, sizeof((*ctx->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G));
158158

159159
/* precompute the tables with odd multiples */
160-
secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g, &gj);
160+
secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g, &gj, cb);
161161

162162
#ifdef USE_ENDOMORPHISM
163163
{
164164
secp256k1_gej_t g_128j;
165165
int i;
166166

167-
ctx->pre_g_128 = (secp256k1_ge_storage_t (*)[])checked_malloc(sizeof((*ctx->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G));
167+
ctx->pre_g_128 = (secp256k1_ge_storage_t (*)[])checked_malloc(cb, sizeof((*ctx->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G));
168168

169169
/* calculate 2^128*generator */
170170
g_128j = gj;
171171
for (i = 0; i < 128; i++) {
172172
secp256k1_gej_double_var(&g_128j, &g_128j, NULL);
173173
}
174-
secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g_128, &g_128j);
174+
secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g_128, &g_128j, cb);
175175
}
176176
#endif
177177
}
178178

179179
static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context_t *dst,
180-
const secp256k1_ecmult_context_t *src) {
180+
const secp256k1_ecmult_context_t *src, const callback_t *cb) {
181181
if (src->pre_g == NULL) {
182182
dst->pre_g = NULL;
183183
} else {
184184
size_t size = sizeof((*dst->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G);
185-
dst->pre_g = (secp256k1_ge_storage_t (*)[])checked_malloc(size);
185+
dst->pre_g = (secp256k1_ge_storage_t (*)[])checked_malloc(cb, size);
186186
memcpy(dst->pre_g, src->pre_g, size);
187187
}
188188
#ifdef USE_ENDOMORPHISM
189189
if (src->pre_g_128 == NULL) {
190190
dst->pre_g_128 = NULL;
191191
} else {
192192
size_t size = sizeof((*dst->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G);
193-
dst->pre_g_128 = (secp256k1_ge_storage_t (*)[])checked_malloc(size);
193+
dst->pre_g_128 = (secp256k1_ge_storage_t (*)[])checked_malloc(cb, size);
194194
memcpy(dst->pre_g_128, src->pre_g_128, size);
195195
}
196196
#endif

src/gen_context.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,17 @@
1313
#include "group_impl.h"
1414
#include "ecmult_gen_impl.h"
1515

16+
static void default_error_callback_fn(const char* str, void* data) {
17+
(void)data;
18+
fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str);
19+
abort();
20+
}
21+
22+
static const callback_t default_error_callback = {
23+
default_error_callback_fn,
24+
NULL
25+
};
26+
1627
int main(int argc, char **argv) {
1728
secp256k1_ecmult_gen_context_t ctx;
1829
int inner;
@@ -35,7 +46,7 @@ int main(int argc, char **argv) {
3546
fprintf(fp, "static const secp256k1_ge_storage_t secp256k1_ecmult_static_context[64][16] = {\n");
3647

3748
secp256k1_ecmult_gen_context_init(&ctx);
38-
secp256k1_ecmult_gen_context_build(&ctx);
49+
secp256k1_ecmult_gen_context_build(&ctx, &default_error_callback);
3950
for(outer = 0; outer != 64; outer++) {
4051
fprintf(fp,"{\n");
4152
for(inner = 0; inner != 16; inner++) {

src/group.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a);
6262
static void secp256k1_ge_set_gej(secp256k1_ge_t *r, secp256k1_gej_t *a);
6363

6464
/** Set a batch of group elements equal to the inputs given in jacobian coordinates */
65-
static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a);
65+
static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a, const callback_t *cb);
6666

6767
/** Set a batch of group elements equal to the inputs given in jacobian
6868
* coordinates (with known z-ratios). zr must contain the known z-ratios such

src/group_impl.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,19 +82,19 @@ static void secp256k1_ge_set_gej_var(secp256k1_ge_t *r, secp256k1_gej_t *a) {
8282
r->y = a->y;
8383
}
8484

85-
static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a) {
85+
static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a, const callback_t *cb) {
8686
secp256k1_fe_t *az;
8787
secp256k1_fe_t *azi;
8888
size_t i;
8989
size_t count = 0;
90-
az = (secp256k1_fe_t *)checked_malloc(sizeof(secp256k1_fe_t) * len);
90+
az = (secp256k1_fe_t *)checked_malloc(cb, sizeof(secp256k1_fe_t) * len);
9191
for (i = 0; i < len; i++) {
9292
if (!a[i].infinity) {
9393
az[count++] = a[i].z;
9494
}
9595
}
9696

97-
azi = (secp256k1_fe_t *)checked_malloc(sizeof(secp256k1_fe_t) * count);
97+
azi = (secp256k1_fe_t *)checked_malloc(cb, sizeof(secp256k1_fe_t) * count);
9898
secp256k1_fe_inv_all_var(count, azi, az);
9999
free(az);
100100

0 commit comments

Comments
 (0)