csecp256k1

Haskell FFI bindings to bitcoin-core/secp256k1 (docs.ppad.tech/csecp256k1).
git clone git://git.ppad.tech/csecp256k1.git
Log | Files | Refs | README | LICENSE

scratch_impl.h (4125B)


      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 
     13 static haskellsecp256k1_v0_1_0_scratch* haskellsecp256k1_v0_1_0_scratch_create(const haskellsecp256k1_v0_1_0_callback* error_callback, size_t size) {
     14     const size_t base_alloc = ROUND_TO_ALIGN(sizeof(haskellsecp256k1_v0_1_0_scratch));
     15     void *alloc = checked_malloc(error_callback, base_alloc + size);
     16     haskellsecp256k1_v0_1_0_scratch* ret = (haskellsecp256k1_v0_1_0_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 haskellsecp256k1_v0_1_0_scratch_destroy(const haskellsecp256k1_v0_1_0_callback* error_callback, haskellsecp256k1_v0_1_0_scratch* scratch) {
     27     if (scratch != NULL) {
     28         if (haskellsecp256k1_v0_1_0_memcmp_var(scratch->magic, "scratch", 8) != 0) {
     29             haskellsecp256k1_v0_1_0_callback_call(error_callback, "invalid scratch space");
     30             return;
     31         }
     32         VERIFY_CHECK(scratch->alloc_size == 0); /* all checkpoints should be applied */
     33         memset(scratch->magic, 0, sizeof(scratch->magic));
     34         free(scratch);
     35     }
     36 }
     37 
     38 static size_t haskellsecp256k1_v0_1_0_scratch_checkpoint(const haskellsecp256k1_v0_1_0_callback* error_callback, const haskellsecp256k1_v0_1_0_scratch* scratch) {
     39     if (haskellsecp256k1_v0_1_0_memcmp_var(scratch->magic, "scratch", 8) != 0) {
     40         haskellsecp256k1_v0_1_0_callback_call(error_callback, "invalid scratch space");
     41         return 0;
     42     }
     43     return scratch->alloc_size;
     44 }
     45 
     46 static void haskellsecp256k1_v0_1_0_scratch_apply_checkpoint(const haskellsecp256k1_v0_1_0_callback* error_callback, haskellsecp256k1_v0_1_0_scratch* scratch, size_t checkpoint) {
     47     if (haskellsecp256k1_v0_1_0_memcmp_var(scratch->magic, "scratch", 8) != 0) {
     48         haskellsecp256k1_v0_1_0_callback_call(error_callback, "invalid scratch space");
     49         return;
     50     }
     51     if (checkpoint > scratch->alloc_size) {
     52         haskellsecp256k1_v0_1_0_callback_call(error_callback, "invalid checkpoint");
     53         return;
     54     }
     55     scratch->alloc_size = checkpoint;
     56 }
     57 
     58 static size_t haskellsecp256k1_v0_1_0_scratch_max_allocation(const haskellsecp256k1_v0_1_0_callback* error_callback, const haskellsecp256k1_v0_1_0_scratch* scratch, size_t objects) {
     59     if (haskellsecp256k1_v0_1_0_memcmp_var(scratch->magic, "scratch", 8) != 0) {
     60         haskellsecp256k1_v0_1_0_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 *haskellsecp256k1_v0_1_0_scratch_alloc(const haskellsecp256k1_v0_1_0_callback* error_callback, haskellsecp256k1_v0_1_0_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 (haskellsecp256k1_v0_1_0_memcmp_var(scratch->magic, "scratch", 8) != 0) {
     85         haskellsecp256k1_v0_1_0_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