github.com/aquanetwork/aquachain@v1.7.8/crypto/secp256k1/libsecp256k1/src/scratch_impl.h (about)

     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 "scratch.h"
    11  
    12  /* Using 16 bytes alignment because common architectures never have alignment
    13   * requirements above 8 for any of the types we care about. In addition we
    14   * leave some room because currently we don't care about a few bytes.
    15   * TODO: Determine this at configure time. */
    16  #define ALIGNMENT 16
    17  
    18  static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t max_size) {
    19      secp256k1_scratch* ret = (secp256k1_scratch*)checked_malloc(error_callback, sizeof(*ret));
    20      if (ret != NULL) {
    21          memset(ret, 0, sizeof(*ret));
    22          ret->max_size = max_size;
    23          ret->error_callback = error_callback;
    24      }
    25      return ret;
    26  }
    27  
    28  static void secp256k1_scratch_destroy(secp256k1_scratch* scratch) {
    29      if (scratch != NULL) {
    30          VERIFY_CHECK(scratch->frame == 0);
    31          free(scratch);
    32      }
    33  }
    34  
    35  static size_t secp256k1_scratch_max_allocation(const secp256k1_scratch* scratch, size_t objects) {
    36      size_t i = 0;
    37      size_t allocated = 0;
    38      for (i = 0; i < scratch->frame; i++) {
    39          allocated += scratch->frame_size[i];
    40      }
    41      if (scratch->max_size - allocated <= objects * ALIGNMENT) {
    42          return 0;
    43      }
    44      return scratch->max_size - allocated - objects * ALIGNMENT;
    45  }
    46  
    47  static int secp256k1_scratch_allocate_frame(secp256k1_scratch* scratch, size_t n, size_t objects) {
    48      VERIFY_CHECK(scratch->frame < SECP256K1_SCRATCH_MAX_FRAMES);
    49  
    50      if (n <= secp256k1_scratch_max_allocation(scratch, objects)) {
    51          n += objects * ALIGNMENT;
    52          scratch->data[scratch->frame] = checked_malloc(scratch->error_callback, n);
    53          if (scratch->data[scratch->frame] == NULL) {
    54              return 0;
    55          }
    56          scratch->frame_size[scratch->frame] = n;
    57          scratch->offset[scratch->frame] = 0;
    58          scratch->frame++;
    59          return 1;
    60      } else {
    61          return 0;
    62      }
    63  }
    64  
    65  static void secp256k1_scratch_deallocate_frame(secp256k1_scratch* scratch) {
    66      VERIFY_CHECK(scratch->frame > 0);
    67      scratch->frame -= 1;
    68      free(scratch->data[scratch->frame]);
    69  }
    70  
    71  static void *secp256k1_scratch_alloc(secp256k1_scratch* scratch, size_t size) {
    72      void *ret;
    73      size_t frame = scratch->frame - 1;
    74      size = ((size + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT;
    75  
    76      if (scratch->frame == 0 || size + scratch->offset[frame] > scratch->frame_size[frame]) {
    77          return NULL;
    78      }
    79      ret = (void *) ((unsigned char *) scratch->data[frame] + scratch->offset[frame]);
    80      memset(ret, 0, size);
    81      scratch->offset[frame] += size;
    82  
    83      return ret;
    84  }
    85  
    86  #endif