mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-04-04 04:45:10 +02:00
First step in converting to C: num
This commit is contained in:
185
num_gmp.cpp
185
num_gmp.cpp
@@ -1,171 +1,148 @@
|
||||
#include <assert.h>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmp.h>
|
||||
|
||||
#include "num_gmp.h"
|
||||
#include "num.h"
|
||||
|
||||
namespace secp256k1 {
|
||||
|
||||
class NumberState {
|
||||
private:
|
||||
typedef struct {
|
||||
int initialized;
|
||||
gmp_randstate_t rng;
|
||||
} secp256k1_num_state_t;
|
||||
|
||||
public:
|
||||
NumberState() {
|
||||
gmp_randinit_default(rng);
|
||||
}
|
||||
static secp256k1_num_state_t secp256k1_num_state = {};
|
||||
|
||||
~NumberState() {
|
||||
gmp_randclear(rng);
|
||||
}
|
||||
|
||||
void gen(mpz_t out, mpz_t size) {
|
||||
mpz_urandomm(out, rng, size);
|
||||
}
|
||||
};
|
||||
|
||||
static NumberState number_state;
|
||||
|
||||
Number::Number(const Number &x) {
|
||||
mpz_init_set(bn, x.bn);
|
||||
void static secp256k1_num_start(void) {
|
||||
if (secp256k1_num_state.initialized)
|
||||
return;
|
||||
secp256k1_num_state.initialized = 1;
|
||||
gmp_randinit_default(secp256k1_num_state.rng);
|
||||
}
|
||||
|
||||
Number::Number() {
|
||||
mpz_init(bn);
|
||||
void static secp256k1_num_init(secp256k1_num_t *r) {
|
||||
mpz_init(r->bn);
|
||||
}
|
||||
|
||||
Number::~Number() {
|
||||
mpz_clear(bn);
|
||||
void static secp256k1_num_free(secp256k1_num_t *r) {
|
||||
mpz_clear(r->bn);
|
||||
}
|
||||
|
||||
Number &Number::operator=(const Number &x) {
|
||||
mpz_set(bn, x.bn);
|
||||
return *this;
|
||||
void static secp256k1_num_copy(secp256k1_num_t *r, const secp256k1_num_t *a) {
|
||||
mpz_set(r->bn, a->bn);
|
||||
}
|
||||
|
||||
void Number::SetNumber(const Number &x) {
|
||||
mpz_set(bn, x.bn);
|
||||
}
|
||||
|
||||
Number::Number(const unsigned char *bin, int len) {
|
||||
mpz_init(bn);
|
||||
SetBytes(bin,len);
|
||||
}
|
||||
|
||||
void Number::SetBytes(const unsigned char *bin, unsigned int len) {
|
||||
mpz_import(bn, len, 1, 1, 1, 0, bin);
|
||||
}
|
||||
|
||||
bool Number::CheckBit(int pos) const {
|
||||
return mpz_tstbit(bn, pos);
|
||||
}
|
||||
|
||||
void Number::GetBytes(unsigned char *bin, unsigned int len) {
|
||||
unsigned int size = (mpz_sizeinbase(bn,2)+7)/8;
|
||||
assert(size <= len);
|
||||
memset(bin,0,len);
|
||||
void static secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num_t *a) {
|
||||
unsigned int size = (mpz_sizeinbase(a->bn,2)+7)/8;
|
||||
assert(size <= rlen);
|
||||
memset(r,0,rlen);
|
||||
size_t count = 0;
|
||||
mpz_export(bin + len - size, &count, 1, 1, 1, 0, bn);
|
||||
mpz_export(r + rlen - size, &count, 1, 1, 1, 0, a->bn);
|
||||
assert(count == 0 || size == count);
|
||||
}
|
||||
|
||||
void Number::SetInt(int x) {
|
||||
mpz_set_si(bn, x);
|
||||
void static secp256k1_num_set_bin(secp256k1_num_t *r, const unsigned char *a, unsigned int alen) {
|
||||
mpz_import(r->bn, alen, 1, 1, 1, 0, a);
|
||||
}
|
||||
|
||||
void Number::SetModInverse(const Number &x, const Number &m) {
|
||||
mpz_invert(bn, x.bn, m.bn);
|
||||
void static secp256k1_num_set_int(secp256k1_num_t *r, int a) {
|
||||
mpz_set_si(r->bn, a);
|
||||
}
|
||||
|
||||
void Number::SetModMul(const Number &a, const Number &b, const Number &m) {
|
||||
mpz_mul(bn, a.bn, b.bn);
|
||||
mpz_mod(bn, bn, m.bn);
|
||||
void static secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *m) {
|
||||
mpz_invert(r->bn, a->bn, m->bn);
|
||||
}
|
||||
|
||||
void Number::SetAdd(const Number &a1, const Number &a2) {
|
||||
mpz_add(bn, a1.bn, a2.bn);
|
||||
void static secp256k1_num_mod_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b, const secp256k1_num_t *m) {
|
||||
mpz_mul(r->bn, a->bn, b->bn);
|
||||
mpz_mod(r->bn, r->bn, m->bn);
|
||||
}
|
||||
|
||||
void Number::SetSub(const Number &a1, const Number &a2) {
|
||||
mpz_sub(bn, a1.bn, a2.bn);
|
||||
int static secp256k1_num_cmp(const secp256k1_num_t *a, const secp256k1_num_t *b) {
|
||||
return mpz_cmp(a->bn, b->bn);
|
||||
}
|
||||
|
||||
void Number::SetMult(const Number &a1, const Number &a2) {
|
||||
mpz_mul(bn, a1.bn, a2.bn);
|
||||
void static secp256k1_num_add(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) {
|
||||
mpz_add(r->bn, a->bn, b->bn);
|
||||
}
|
||||
|
||||
void Number::SetDiv(const Number &a1, const Number &a2) {
|
||||
mpz_tdiv_q(bn, a1.bn, a2.bn);
|
||||
void static secp256k1_num_sub(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) {
|
||||
mpz_sub(r->bn, a->bn, b->bn);
|
||||
}
|
||||
|
||||
void Number::SetMod(const Number &a, const Number &m) {
|
||||
mpz_mod(bn, a.bn, m.bn);
|
||||
void static secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) {
|
||||
mpz_mul(r->bn, a->bn, b->bn);
|
||||
}
|
||||
|
||||
int Number::Compare(const Number &a) const {
|
||||
return mpz_cmp(bn, a.bn);
|
||||
void static secp256k1_num_div(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) {
|
||||
mpz_tdiv_q(r->bn, a->bn, b->bn);
|
||||
}
|
||||
|
||||
int Number::GetBits() const {
|
||||
return mpz_sizeinbase(bn,2);
|
||||
void static secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) {
|
||||
mpz_mod(r->bn, a->bn, b->bn);
|
||||
}
|
||||
|
||||
int Number::ShiftLowBits(int bits) {
|
||||
int ret = mpz_get_ui(bn) & ((1 << bits) - 1);
|
||||
mpz_fdiv_q_2exp(bn, bn, bits);
|
||||
int static secp256k1_num_bits(const secp256k1_num_t *a) {
|
||||
return mpz_sizeinbase(a->bn,2);
|
||||
}
|
||||
|
||||
int static secp256k1_num_shift(secp256k1_num_t *r, int bits) {
|
||||
int ret = mpz_get_ui(r->bn) & ((1 << bits) - 1);
|
||||
mpz_fdiv_q_2exp(r->bn, r->bn, bits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Number::IsZero() const {
|
||||
return mpz_size(bn) == 0;
|
||||
int static secp256k1_num_is_zero(const secp256k1_num_t *a) {
|
||||
return mpz_size(a->bn) == 0;
|
||||
}
|
||||
|
||||
bool Number::IsOdd() const {
|
||||
return mpz_get_ui(bn) & 1;
|
||||
int static secp256k1_num_is_odd(const secp256k1_num_t *a) {
|
||||
return mpz_get_ui(a->bn) & 1;
|
||||
}
|
||||
|
||||
bool Number::IsNeg() const {
|
||||
return mpz_sgn(bn) < 0;
|
||||
int static secp256k1_num_is_neg(const secp256k1_num_t *a) {
|
||||
return mpz_sgn(a->bn) < 0;
|
||||
}
|
||||
|
||||
void Number::Negate() {
|
||||
mpz_neg(bn, bn);
|
||||
int static secp256k1_num_get_bit(const secp256k1_num_t *a, int pos) {
|
||||
return mpz_tstbit(a->bn, pos);
|
||||
}
|
||||
|
||||
void Number::Shift1() {
|
||||
mpz_fdiv_q_2exp(bn, bn, 1);
|
||||
void static secp256k1_num_inc(secp256k1_num_t *r) {
|
||||
mpz_add_ui(r->bn, r->bn, 1);
|
||||
}
|
||||
|
||||
void Number::Inc() {
|
||||
mpz_add_ui(bn, bn, 1);
|
||||
void static secp256k1_num_set_hex(secp256k1_num_t *r, const char *a, int alen) {
|
||||
char *str = (char*)malloc(alen+1);
|
||||
memcpy(str, a, alen);
|
||||
str[alen] = 0;
|
||||
mpz_set_str(r->bn, str, 16);
|
||||
free(str);
|
||||
}
|
||||
|
||||
void Number::SetHex(const std::string &str) {
|
||||
mpz_set_str(bn, str.c_str(), 16);
|
||||
void static secp256k1_num_get_hex(char *r, int *rlen, const secp256k1_num_t *a) {
|
||||
int len = mpz_sizeinbase(a->bn, 16) + 2;
|
||||
if (*rlen < len) {
|
||||
*rlen = len;
|
||||
return;
|
||||
}
|
||||
mpz_get_str(r, 16, a->bn);
|
||||
*rlen = len;
|
||||
}
|
||||
|
||||
void Number::SetPseudoRand(const Number &max) {
|
||||
number_state.gen(bn, max.bn);
|
||||
}
|
||||
|
||||
void Number::SplitInto(int bits, Number &low, Number &high) const {
|
||||
void static secp256k1_num_split(secp256k1_num_t *rl, secp256k1_num_t *rh, const secp256k1_num_t *a, int bits) {
|
||||
mpz_t tmp;
|
||||
mpz_init_set_ui(tmp,1);
|
||||
mpz_mul_2exp(tmp,tmp,bits);
|
||||
mpz_mul_2exp(tmp, tmp, bits);
|
||||
mpz_sub_ui(tmp,tmp,1);
|
||||
mpz_and(low.bn, bn, tmp);
|
||||
mpz_and(rl->bn, a->bn, tmp);
|
||||
mpz_clear(tmp);
|
||||
mpz_fdiv_q_2exp(high.bn, bn, bits);
|
||||
mpz_fdiv_q_2exp(rh->bn, a->bn, bits);
|
||||
}
|
||||
|
||||
std::string Number::ToString() const {
|
||||
char *str = (char*)malloc(mpz_sizeinbase(bn,16) + 2);
|
||||
mpz_get_str(str, 16, bn);
|
||||
std::string ret(str);
|
||||
free(str);
|
||||
return ret;
|
||||
void static secp256k1_num_negate(secp256k1_num_t *r) {
|
||||
mpz_neg(r->bn, r->bn);
|
||||
}
|
||||
|
||||
void static secp256k1_num_set_rand(secp256k1_num_t *r, const secp256k1_num_t *a) {
|
||||
mpz_urandomm(r->bn, secp256k1_num_state.rng, a->bn);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user