Bitcoin Core  0.20.99
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 http://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 
13 static 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 = checked_malloc(error_callback, base_alloc + size);
16  secp256k1_scratch* ret = (secp256k1_scratch *)alloc;
17  if (ret != NULL) {
18  memset(ret, 0, sizeof(*ret));
19  memcpy(ret->magic, "scratch", 8);
20  ret->data = (void *) ((char *) alloc + base_alloc);
21  ret->max_size = size;
22  }
23  return ret;
24 }
25 
26 static void secp256k1_scratch_destroy(const secp256k1_callback* error_callback, secp256k1_scratch* scratch) {
27  if (scratch != NULL) {
28  VERIFY_CHECK(scratch->alloc_size == 0); /* all checkpoints should be applied */
29  if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) {
30  secp256k1_callback_call(error_callback, "invalid scratch space");
31  return;
32  }
33  memset(scratch->magic, 0, sizeof(scratch->magic));
34  free(scratch);
35  }
36 }
37 
38 static size_t secp256k1_scratch_checkpoint(const secp256k1_callback* error_callback, const secp256k1_scratch* scratch) {
39  if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) {
40  secp256k1_callback_call(error_callback, "invalid scratch space");
41  return 0;
42  }
43  return scratch->alloc_size;
44 }
45 
46 static void secp256k1_scratch_apply_checkpoint(const secp256k1_callback* error_callback, secp256k1_scratch* scratch, size_t checkpoint) {
47  if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) {
48  secp256k1_callback_call(error_callback, "invalid scratch space");
49  return;
50  }
51  if (checkpoint > scratch->alloc_size) {
52  secp256k1_callback_call(error_callback, "invalid checkpoint");
53  return;
54  }
55  scratch->alloc_size = checkpoint;
56 }
57 
58 static size_t secp256k1_scratch_max_allocation(const secp256k1_callback* error_callback, const secp256k1_scratch* scratch, size_t objects) {
59  if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) {
60  secp256k1_callback_call(error_callback, "invalid scratch space");
61  return 0;
62  }
63  /* Ensure that multiplication will not wrap around */
64  if (ALIGNMENT > 1 && objects > SIZE_MAX/(ALIGNMENT - 1)) {
65  return 0;
66  }
67  if (scratch->max_size - scratch->alloc_size <= objects * (ALIGNMENT - 1)) {
68  return 0;
69  }
70  return scratch->max_size - scratch->alloc_size - objects * (ALIGNMENT - 1);
71 }
72 
73 static void *secp256k1_scratch_alloc(const secp256k1_callback* error_callback, secp256k1_scratch* scratch, size_t size) {
74  void *ret;
75  size_t rounded_size;
76 
77  rounded_size = ROUND_TO_ALIGN(size);
78  /* Check that rounding did not wrap around */
79  if (rounded_size < size) {
80  return NULL;
81  }
82  size = rounded_size;
83 
84  if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) {
85  secp256k1_callback_call(error_callback, "invalid scratch space");
86  return NULL;
87  }
88 
89  if (size > scratch->max_size - scratch->alloc_size) {
90  return NULL;
91  }
92  ret = (void *) ((char *) scratch->data + scratch->alloc_size);
93  memset(ret, 0, size);
94  scratch->alloc_size += size;
95 
96  return ret;
97 }
98 
99 #endif
#define VERIFY_CHECK(cond)
Definition: util.h:68
size_t max_size
maximum size available to allocate
Definition: scratch.h:21
#define ALIGNMENT
Definition: util.h:113
static void secp256k1_scratch_apply_checkpoint(const secp256k1_callback *error_callback, secp256k1_scratch *scratch, size_t checkpoint)
Definition: scratch_impl.h:46
unsigned char magic[8]
guard against interpreting this object as other types
Definition: scratch.h:14
static secp256k1_scratch * secp256k1_scratch_create(const secp256k1_callback *error_callback, size_t size)
Definition: scratch_impl.h:13
size_t alloc_size
amount that has been allocated (i.e.
Definition: scratch.h:19
static size_t secp256k1_scratch_max_allocation(const secp256k1_callback *error_callback, const secp256k1_scratch *scratch, size_t objects)
Definition: scratch_impl.h:58
static void secp256k1_scratch_destroy(const secp256k1_callback *error_callback, secp256k1_scratch *scratch)
Definition: scratch_impl.h:26
static void * secp256k1_scratch_alloc(const secp256k1_callback *error_callback, secp256k1_scratch *scratch, size_t size)
Definition: scratch_impl.h:73
static size_t secp256k1_scratch_checkpoint(const secp256k1_callback *error_callback, const secp256k1_scratch *scratch)
Definition: scratch_impl.h:38
void * memcpy(void *a, const void *b, size_t c)
static SECP256K1_INLINE int secp256k1_memcmp_var(const void *s1, const void *s2, size_t n)
Semantics like memcmp.
Definition: util.h:224
static SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback *const cb, const char *const text)
Definition: util.h:24
#define ROUND_TO_ALIGN(size)
Definition: util.h:116
void * data
actual allocated data
Definition: scratch.h:16
static SECP256K1_INLINE void * checked_malloc(const secp256k1_callback *cb, size_t size)
Definition: util.h:91