Changeset View
Changeset View
Standalone View
Standalone View
src/secp256k1/src/scratch_impl.h
/********************************************************************** | /********************************************************************** | ||||
* Copyright (c) 2017 Andrew Poelstra * | * Copyright (c) 2017 Andrew Poelstra * | ||||
* Distributed under the MIT software license, see the accompanying * | * Distributed under the MIT software license, see the accompanying * | ||||
* file COPYING or http://www.opensource.org/licenses/mit-license.php.* | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* | ||||
**********************************************************************/ | **********************************************************************/ | ||||
#ifndef _SECP256K1_SCRATCH_IMPL_H_ | #ifndef _SECP256K1_SCRATCH_IMPL_H_ | ||||
#define _SECP256K1_SCRATCH_IMPL_H_ | #define _SECP256K1_SCRATCH_IMPL_H_ | ||||
#include "util.h" | #include "util.h" | ||||
#include "scratch.h" | #include "scratch.h" | ||||
static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t max_size) { | static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t size) { | ||||
secp256k1_scratch* ret = (secp256k1_scratch*)checked_malloc(error_callback, sizeof(*ret)); | const size_t base_alloc = ((sizeof(secp256k1_scratch) + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT; | ||||
void *alloc = checked_malloc(error_callback, base_alloc + size); | |||||
secp256k1_scratch* ret = (secp256k1_scratch *)alloc; | |||||
if (ret != NULL) { | if (ret != NULL) { | ||||
memset(ret, 0, sizeof(*ret)); | memset(ret, 0, sizeof(*ret)); | ||||
ret->max_size = max_size; | memcpy(ret->magic, "scratch", 8); | ||||
ret->error_callback = error_callback; | ret->data = (void *) ((char *) alloc + base_alloc); | ||||
ret->max_size = size; | |||||
} | } | ||||
return ret; | return ret; | ||||
} | } | ||||
static void secp256k1_scratch_destroy(secp256k1_scratch* scratch) { | static void secp256k1_scratch_destroy(const secp256k1_callback* error_callback, secp256k1_scratch* scratch) { | ||||
if (scratch != NULL) { | if (scratch != NULL) { | ||||
VERIFY_CHECK(scratch->frame == 0); | VERIFY_CHECK(scratch->alloc_size == 0); /* all checkpoints should be applied */ | ||||
if (memcmp(scratch->magic, "scratch", 8) != 0) { | |||||
secp256k1_callback_call(error_callback, "invalid scratch space"); | |||||
return; | |||||
} | |||||
memset(scratch->magic, 0, sizeof(scratch->magic)); | |||||
free(scratch); | free(scratch); | ||||
} | } | ||||
} | } | ||||
static size_t secp256k1_scratch_max_allocation(const secp256k1_scratch* scratch, size_t objects) { | static size_t secp256k1_scratch_checkpoint(const secp256k1_callback* error_callback, const secp256k1_scratch* scratch) { | ||||
size_t i = 0; | if (memcmp(scratch->magic, "scratch", 8) != 0) { | ||||
size_t allocated = 0; | secp256k1_callback_call(error_callback, "invalid scratch space"); | ||||
for (i = 0; i < scratch->frame; i++) { | |||||
allocated += scratch->frame_size[i]; | |||||
} | |||||
if (scratch->max_size - allocated <= objects * ALIGNMENT) { | |||||
return 0; | return 0; | ||||
} | } | ||||
return scratch->max_size - allocated - objects * ALIGNMENT; | return scratch->alloc_size; | ||||
} | } | ||||
static int secp256k1_scratch_allocate_frame(secp256k1_scratch* scratch, size_t n, size_t objects) { | static void secp256k1_scratch_apply_checkpoint(const secp256k1_callback* error_callback, secp256k1_scratch* scratch, size_t checkpoint) { | ||||
VERIFY_CHECK(scratch->frame < SECP256K1_SCRATCH_MAX_FRAMES); | if (memcmp(scratch->magic, "scratch", 8) != 0) { | ||||
secp256k1_callback_call(error_callback, "invalid scratch space"); | |||||
return; | |||||
} | |||||
if (checkpoint > scratch->alloc_size) { | |||||
secp256k1_callback_call(error_callback, "invalid checkpoint"); | |||||
return; | |||||
} | |||||
scratch->alloc_size = checkpoint; | |||||
} | |||||
if (n <= secp256k1_scratch_max_allocation(scratch, objects)) { | static size_t secp256k1_scratch_max_allocation(const secp256k1_callback* error_callback, const secp256k1_scratch* scratch, size_t objects) { | ||||
n += objects * ALIGNMENT; | if (memcmp(scratch->magic, "scratch", 8) != 0) { | ||||
scratch->data[scratch->frame] = checked_malloc(scratch->error_callback, n); | secp256k1_callback_call(error_callback, "invalid scratch space"); | ||||
if (scratch->data[scratch->frame] == NULL) { | |||||
return 0; | return 0; | ||||
} | } | ||||
scratch->frame_size[scratch->frame] = n; | if (scratch->max_size - scratch->alloc_size <= objects * (ALIGNMENT - 1)) { | ||||
scratch->offset[scratch->frame] = 0; | |||||
scratch->frame++; | |||||
return 1; | |||||
} else { | |||||
return 0; | return 0; | ||||
} | } | ||||
return scratch->max_size - scratch->alloc_size - objects * (ALIGNMENT - 1); | |||||
} | } | ||||
static void secp256k1_scratch_deallocate_frame(secp256k1_scratch* scratch) { | static void *secp256k1_scratch_alloc(const secp256k1_callback* error_callback, secp256k1_scratch* scratch, size_t size) { | ||||
VERIFY_CHECK(scratch->frame > 0); | |||||
scratch->frame -= 1; | |||||
free(scratch->data[scratch->frame]); | |||||
} | |||||
static void *secp256k1_scratch_alloc(secp256k1_scratch* scratch, size_t size) { | |||||
void *ret; | void *ret; | ||||
size_t frame = scratch->frame - 1; | |||||
size = ROUND_TO_ALIGN(size); | size = ROUND_TO_ALIGN(size); | ||||
if (scratch->frame == 0 || size + scratch->offset[frame] > scratch->frame_size[frame]) { | if (memcmp(scratch->magic, "scratch", 8) != 0) { | ||||
secp256k1_callback_call(error_callback, "invalid scratch space"); | |||||
return NULL; | |||||
} | |||||
if (size > scratch->max_size - scratch->alloc_size) { | |||||
return NULL; | return NULL; | ||||
} | } | ||||
ret = (void *) ((unsigned char *) scratch->data[frame] + scratch->offset[frame]); | ret = (void *) ((char *) scratch->data + scratch->alloc_size); | ||||
memset(ret, 0, size); | memset(ret, 0, size); | ||||
scratch->offset[frame] += size; | scratch->alloc_size += size; | ||||
return ret; | return ret; | ||||
} | } | ||||
#endif | #endif |