Bitcoin Core 32.99.0
P2P Digital Currency
scratch_impl.h
Go to the documentation of this file.
1/***********************************************************************
2 * Copyright (c) 2017 Andrew Poelstra *
3 * Distributed under the MIT software license, see the accompanying *
4 * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5 ***********************************************************************/
6
7#ifndef SECP256K1_SCRATCH_IMPL_H
8#define SECP256K1_SCRATCH_IMPL_H
9
10#include "util.h"
11#include "scratch.h"
12
13static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t size) {
14 const size_t base_alloc = ROUND_TO_ALIGN(sizeof(secp256k1_scratch));
15 void *alloc;
17 /* Reject sizes that would wrap when added to the aligned header. */
18 if (size > SIZE_MAX - base_alloc) {
19 return NULL;
20 }
21 alloc = checked_malloc(error_callback, base_alloc + size);
22 ret = (secp256k1_scratch *)alloc;
23 if (ret != NULL) {
24 memset(ret, 0, sizeof(*ret));
25 memcpy(ret->magic, "scratch", 8);
26 ret->data = (void *) ((char *) alloc + base_alloc);
27 ret->max_size = size;
28 }
29 return ret;
30}
31
32static void secp256k1_scratch_destroy(const secp256k1_callback* error_callback, secp256k1_scratch* scratch) {
33 if (scratch != NULL) {
34 if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) {
35 secp256k1_callback_call(error_callback, "invalid scratch space");
36 return;
37 }
38 VERIFY_CHECK(scratch->alloc_size == 0); /* all checkpoints should be applied */
39 memset(scratch->magic, 0, sizeof(scratch->magic));
40 free(scratch);
41 }
42}
43
44static size_t secp256k1_scratch_checkpoint(const secp256k1_callback* error_callback, const secp256k1_scratch* scratch) {
45 if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) {
46 secp256k1_callback_call(error_callback, "invalid scratch space");
47 return 0;
48 }
49 return scratch->alloc_size;
50}
51
52static void secp256k1_scratch_apply_checkpoint(const secp256k1_callback* error_callback, secp256k1_scratch* scratch, size_t checkpoint) {
53 if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) {
54 secp256k1_callback_call(error_callback, "invalid scratch space");
55 return;
56 }
57 if (checkpoint > scratch->alloc_size) {
58 secp256k1_callback_call(error_callback, "invalid checkpoint");
59 return;
60 }
61 scratch->alloc_size = checkpoint;
62}
63
64static size_t secp256k1_scratch_max_allocation(const secp256k1_callback* error_callback, const secp256k1_scratch* scratch, size_t objects) {
65 if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) {
66 secp256k1_callback_call(error_callback, "invalid scratch space");
67 return 0;
68 }
69 /* Ensure that multiplication will not wrap around */
70 if (ALIGNMENT > 1 && objects > SIZE_MAX/(ALIGNMENT - 1)) {
71 return 0;
72 }
73 if (scratch->max_size - scratch->alloc_size <= objects * (ALIGNMENT - 1)) {
74 return 0;
75 }
76 return scratch->max_size - scratch->alloc_size - objects * (ALIGNMENT - 1);
77}
78
79static void *secp256k1_scratch_alloc(const secp256k1_callback* error_callback, secp256k1_scratch* scratch, size_t size) {
80 void *ret;
81 size_t rounded_size;
82
83 rounded_size = ROUND_TO_ALIGN(size);
84 /* Check that rounding did not wrap around */
85 if (rounded_size < size) {
86 return NULL;
87 }
88 size = rounded_size;
89
90 if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) {
91 secp256k1_callback_call(error_callback, "invalid scratch space");
92 return NULL;
93 }
94
95 if (size > scratch->max_size - scratch->alloc_size) {
96 return NULL;
97 }
98 ret = (void *) ((char *) scratch->data + scratch->alloc_size);
99 memset(ret, 0, size);
100 scratch->alloc_size += size;
101
102 return ret;
103}
104
105#endif
int ret
static void secp256k1_scratch_apply_checkpoint(const secp256k1_callback *error_callback, secp256k1_scratch *scratch, size_t checkpoint)
Definition: scratch_impl.h:52
static void secp256k1_scratch_destroy(const secp256k1_callback *error_callback, secp256k1_scratch *scratch)
Definition: scratch_impl.h:32
static void * secp256k1_scratch_alloc(const secp256k1_callback *error_callback, secp256k1_scratch *scratch, size_t size)
Definition: scratch_impl.h:79
static size_t secp256k1_scratch_checkpoint(const secp256k1_callback *error_callback, const secp256k1_scratch *scratch)
Definition: scratch_impl.h:44
static secp256k1_scratch * secp256k1_scratch_create(const secp256k1_callback *error_callback, size_t size)
Definition: scratch_impl.h:13
static size_t secp256k1_scratch_max_allocation(const secp256k1_callback *error_callback, const secp256k1_scratch *scratch, size_t objects)
Definition: scratch_impl.h:64
static SECP256K1_INLINE int secp256k1_memcmp_var(const void *s1, const void *s2, size_t n)
Semantics like memcmp.
Definition: util.h:281
#define ALIGNMENT
Definition: util.h:186
#define ROUND_TO_ALIGN(size)
Definition: util.h:192
#define VERIFY_CHECK(cond)
Definition: util.h:169
static SECP256K1_INLINE void * checked_malloc(const secp256k1_callback *cb, size_t size)
Definition: util.h:172
static SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback *const cb, const char *const text)
Definition: util.h:102
size_t alloc_size
amount that has been allocated (i.e.
Definition: scratch.h:19
size_t max_size
maximum size available to allocate
Definition: scratch.h:21
void * data
actual allocated data
Definition: scratch.h:16
unsigned char magic[8]
guard against interpreting this object as other types
Definition: scratch.h:14