#include "scratch_impl.h"
This commit is contained in:
@@ -42,6 +42,8 @@ noinst_HEADERS += src/field_5x52_asm_impl.h
|
||||
noinst_HEADERS += src/java/org_bitcoin_NativeSecp256k1.h
|
||||
noinst_HEADERS += src/java/org_bitcoin_Secp256k1Context.h
|
||||
noinst_HEADERS += src/util.h
|
||||
noinst_HEADERS += src/scratch.h
|
||||
noinst_HEADERS += src/scratch_impl.h
|
||||
noinst_HEADERS += src/testrand.h
|
||||
noinst_HEADERS += src/testrand_impl.h
|
||||
noinst_HEADERS += src/hash.h
|
||||
|
||||
@@ -222,120 +222,3 @@ static void secp256k1_scalar_chacha20(secp256k1_scalar *r1, secp256k1_scalar *r2
|
||||
|
||||
#endif /* SECP256K1_SCALAR_H */
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
/**********************************************************************
|
||||
* Copyright (c) 2014 Pieter Wuille *
|
||||
* Distributed under the MIT software license, see the accompanying *
|
||||
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef SECP256K1_SCALAR_H
|
||||
#define SECP256K1_SCALAR_H
|
||||
|
||||
#include "num.h"
|
||||
|
||||
#if defined HAVE_CONFIG_H
|
||||
#include "libsecp256k1-config.h"
|
||||
#endif
|
||||
|
||||
#if defined(EXHAUSTIVE_TEST_ORDER)
|
||||
#include "scalar_low.h"
|
||||
#elif defined(USE_SCALAR_4X64)
|
||||
#include "scalar_4x64.h"
|
||||
#elif defined(USE_SCALAR_8X32)
|
||||
#include "scalar_8x32.h"
|
||||
#else
|
||||
#error "Please select scalar implementation"
|
||||
#endif
|
||||
|
||||
/** Clear a scalar to prevent the leak of sensitive data. */
|
||||
static void secp256k1_scalar_clear(secp256k1_scalar *r);
|
||||
|
||||
/** Access bits from a scalar. All requested bits must belong to the same 32-bit limb. */
|
||||
static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count);
|
||||
|
||||
/** Access bits from a scalar. Not constant time. */
|
||||
static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count);
|
||||
|
||||
/** Set a scalar from a big endian byte array. */
|
||||
static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *bin, int *overflow);
|
||||
|
||||
/** Set a scalar to an unsigned integer. */
|
||||
static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v);
|
||||
|
||||
/** Set a scalar to an unsigned 64-bit integer */
|
||||
static void secp256k1_scalar_set_u64(secp256k1_scalar *r, uint64_t v);
|
||||
|
||||
/** Convert a scalar to a byte array. */
|
||||
static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a);
|
||||
|
||||
/** Add two scalars together (modulo the group order). Returns whether it overflowed. */
|
||||
static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b);
|
||||
|
||||
/** Conditionally add a power of two to a scalar. The result is not allowed to overflow. */
|
||||
static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag);
|
||||
|
||||
/** Multiply two scalars (modulo the group order). */
|
||||
static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b);
|
||||
|
||||
/** Shift a scalar right by some amount strictly between 0 and 16, returning
|
||||
* the low bits that were shifted off */
|
||||
static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n);
|
||||
|
||||
/** Compute the square of a scalar (modulo the group order). */
|
||||
static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a);
|
||||
|
||||
/** Compute the inverse of a scalar (modulo the group order). */
|
||||
static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *a);
|
||||
|
||||
/** Compute the inverse of a scalar (modulo the group order), without constant-time guarantee. */
|
||||
static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *a);
|
||||
|
||||
/** Compute the complement of a scalar (modulo the group order). */
|
||||
static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a);
|
||||
|
||||
/** Check whether a scalar equals zero. */
|
||||
static int secp256k1_scalar_is_zero(const secp256k1_scalar *a);
|
||||
|
||||
/** Check whether a scalar equals one. */
|
||||
static int secp256k1_scalar_is_one(const secp256k1_scalar *a);
|
||||
|
||||
/** Check whether a scalar, considered as an nonnegative integer, is even. */
|
||||
static int secp256k1_scalar_is_even(const secp256k1_scalar *a);
|
||||
|
||||
/** Check whether a scalar is higher than the group order divided by 2. */
|
||||
static int secp256k1_scalar_is_high(const secp256k1_scalar *a);
|
||||
|
||||
/** Conditionally negate a number, in constant time.
|
||||
* Returns -1 if the number was negated, 1 otherwise */
|
||||
static int secp256k1_scalar_cond_negate(secp256k1_scalar *a, int flag);
|
||||
|
||||
#ifndef USE_NUM_NONE
|
||||
/** Convert a scalar to a number. */
|
||||
static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a);
|
||||
|
||||
/** Get the order of the group as a number. */
|
||||
static void secp256k1_scalar_order_get_num(secp256k1_num *r);
|
||||
#endif
|
||||
|
||||
/** Compare two scalars. */
|
||||
static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b);
|
||||
|
||||
#ifdef USE_ENDOMORPHISM
|
||||
/** Find r1 and r2 such that r1+r2*2^128 = a. */
|
||||
static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a);
|
||||
/** Find r1 and r2 such that r1+r2*lambda = a, and r1 and r2 are maximum 128 bits long (see secp256k1_gej_mul_lambda). */
|
||||
static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a);
|
||||
#endif
|
||||
|
||||
/** Multiply a and b (without taking the modulus!), divide by 2**shift, and round to the nearest integer. Shift must be at least 256. */
|
||||
static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift);
|
||||
|
||||
/** Generate two scalars from a 32-byte seed and an integer using the chacha20 stream cipher */
|
||||
static void secp256k1_scalar_chacha20(secp256k1_scalar *r1, secp256k1_scalar *r2, const unsigned char *seed, uint64_t idx);
|
||||
|
||||
#endif /* SECP256K1_SCALAR_H */
|
||||
#endif
|
||||
|
||||
|
||||
@@ -42,27 +42,3 @@ typedef struct {
|
||||
#endif /* SECP256K1_SCALAR_REPR_H */
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
/**********************************************************************
|
||||
* Copyright (c) 2014 Pieter Wuille *
|
||||
* Distributed under the MIT software license, see the accompanying *
|
||||
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef SECP256K1_SCALAR_REPR_H
|
||||
#define SECP256K1_SCALAR_REPR_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** A scalar modulo the group order of the secp256k1 curve. */
|
||||
typedef struct {
|
||||
uint64_t d[4];
|
||||
} secp256k1_scalar;
|
||||
|
||||
#define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{((uint64_t)(d1)) << 32 | (d0), ((uint64_t)(d3)) << 32 | (d2), ((uint64_t)(d5)) << 32 | (d4), ((uint64_t)(d7)) << 32 | (d6)}}
|
||||
|
||||
#endif /* SECP256K1_SCALAR_REPR_H */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
40
src/secp256k1/src/scratch.h
Normal file
40
src/secp256k1/src/scratch.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/**********************************************************************
|
||||
* Copyright (c) 2017 Andrew Poelstra *
|
||||
* Distributed under the MIT software license, see the accompanying *
|
||||
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef _SECP256K1_SCRATCH_
|
||||
#define _SECP256K1_SCRATCH_
|
||||
|
||||
#define SECP256K1_SCRATCH_MAX_FRAMES 5
|
||||
|
||||
/* The typedef is used internally; the struct name is used in the public API
|
||||
* (where it is exposed as a different typedef) */
|
||||
typedef struct secp256k1_scratch_space_struct {
|
||||
void *data[SECP256K1_SCRATCH_MAX_FRAMES];
|
||||
size_t offset[SECP256K1_SCRATCH_MAX_FRAMES];
|
||||
size_t frame_size[SECP256K1_SCRATCH_MAX_FRAMES];
|
||||
size_t frame;
|
||||
size_t max_size;
|
||||
const secp256k1_callback* error_callback;
|
||||
} secp256k1_scratch;
|
||||
|
||||
static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t max_size);
|
||||
|
||||
static void secp256k1_scratch_destroy(secp256k1_scratch* scratch);
|
||||
|
||||
/** Attempts to allocate a new stack frame with `n` available bytes. Returns 1 on success, 0 on failure */
|
||||
static int secp256k1_scratch_allocate_frame(secp256k1_scratch* scratch, size_t n, size_t objects);
|
||||
|
||||
/** Deallocates a stack frame */
|
||||
static void secp256k1_scratch_deallocate_frame(secp256k1_scratch* scratch);
|
||||
|
||||
/** Returns the maximum allocation the scratch space will allow */
|
||||
static size_t secp256k1_scratch_max_allocation(const secp256k1_scratch* scratch, size_t n_objects);
|
||||
|
||||
/** Returns a pointer into the most recently allocated frame, or NULL if there is insufficient available space */
|
||||
static void *secp256k1_scratch_alloc(secp256k1_scratch* scratch, size_t n);
|
||||
|
||||
#endif
|
||||
|
||||
87
src/secp256k1/src/scratch_impl.h
Normal file
87
src/secp256k1/src/scratch_impl.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/**********************************************************************
|
||||
* Copyright (c) 2017 Andrew Poelstra *
|
||||
* Distributed under the MIT software license, see the accompanying *
|
||||
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef _SECP256K1_SCRATCH_IMPL_H_
|
||||
#define _SECP256K1_SCRATCH_IMPL_H_
|
||||
|
||||
#include "scratch.h"
|
||||
|
||||
/* Using 16 bytes alignment because common architectures never have alignment
|
||||
* requirements above 8 for any of the types we care about. In addition we
|
||||
* leave some room because currently we don't care about a few bytes.
|
||||
* TODO: Determine this at configure time. */
|
||||
#define ALIGNMENT 16
|
||||
|
||||
static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t max_size) {
|
||||
secp256k1_scratch* ret = (secp256k1_scratch*)checked_malloc(error_callback, sizeof(*ret));
|
||||
if (ret != NULL) {
|
||||
memset(ret, 0, sizeof(*ret));
|
||||
ret->max_size = max_size;
|
||||
ret->error_callback = error_callback;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void secp256k1_scratch_destroy(secp256k1_scratch* scratch) {
|
||||
if (scratch != NULL) {
|
||||
VERIFY_CHECK(scratch->frame == 0);
|
||||
free(scratch);
|
||||
}
|
||||
}
|
||||
|
||||
static size_t secp256k1_scratch_max_allocation(const secp256k1_scratch* scratch, size_t objects) {
|
||||
size_t i = 0;
|
||||
size_t allocated = 0;
|
||||
for (i = 0; i < scratch->frame; i++) {
|
||||
allocated += scratch->frame_size[i];
|
||||
}
|
||||
if (scratch->max_size - allocated <= objects * ALIGNMENT) {
|
||||
return 0;
|
||||
}
|
||||
return scratch->max_size - allocated - objects * ALIGNMENT;
|
||||
}
|
||||
|
||||
static int secp256k1_scratch_allocate_frame(secp256k1_scratch* scratch, size_t n, size_t objects) {
|
||||
VERIFY_CHECK(scratch->frame < SECP256K1_SCRATCH_MAX_FRAMES);
|
||||
|
||||
if (n <= secp256k1_scratch_max_allocation(scratch, objects)) {
|
||||
n += objects * ALIGNMENT;
|
||||
scratch->data[scratch->frame] = checked_malloc(scratch->error_callback, n);
|
||||
if (scratch->data[scratch->frame] == NULL) {
|
||||
return 0;
|
||||
}
|
||||
scratch->frame_size[scratch->frame] = n;
|
||||
scratch->offset[scratch->frame] = 0;
|
||||
scratch->frame++;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void secp256k1_scratch_deallocate_frame(secp256k1_scratch* scratch) {
|
||||
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;
|
||||
size_t frame = scratch->frame - 1;
|
||||
size = ((size + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT;
|
||||
|
||||
if (scratch->frame == 0 || size + scratch->offset[frame] > scratch->frame_size[frame]) {
|
||||
return NULL;
|
||||
}
|
||||
ret = (void *) ((unsigned char *) scratch->data[frame] + scratch->offset[frame]);
|
||||
memset(ret, 0, size);
|
||||
scratch->offset[frame] += size;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "ecdsa_impl.h"
|
||||
#include "eckey_impl.h"
|
||||
#include "hash_impl.h"
|
||||
#include "scratch_impl.h"
|
||||
|
||||
#define ARG_CHECK(cond) do { \
|
||||
if (EXPECT(!(cond), 0)) { \
|
||||
|
||||
Reference in New Issue
Block a user