mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-26 03:03:22 -03:00
compiles...
This commit is contained in:
parent
581ef48ba8
commit
cb4d29c81e
7 changed files with 224 additions and 78 deletions
34
consts.h
34
consts.h
|
@ -1,34 +0,0 @@
|
|||
#ifndef _SECP256K1_CONSTS_
|
||||
#define _SECP256K1_CONSTS_
|
||||
|
||||
#include "num.h"
|
||||
|
||||
namespace secp256k1 {
|
||||
|
||||
static const unsigned char order_[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
|
||||
0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,
|
||||
0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41};
|
||||
|
||||
static const unsigned char field_[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F};
|
||||
|
||||
class Constants {
|
||||
private:
|
||||
Context ctx;
|
||||
|
||||
public:
|
||||
const Number order;
|
||||
const Number field;
|
||||
|
||||
Constants() : order(ctx, order_, sizeof(order_)),
|
||||
field(ctx, field_, sizeof(field_)) {}
|
||||
};
|
||||
|
||||
const Constants consts;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
97
ecmult.h
97
ecmult.h
|
@ -1,6 +1,9 @@
|
|||
#ifndef _SECP256K1_ECMULT_
|
||||
#define _SECP256K1_ECMULT_
|
||||
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "group.h"
|
||||
#include "scalar.h"
|
||||
|
||||
|
@ -11,17 +14,17 @@ private:
|
|||
G pre[1 << (W-2)];
|
||||
|
||||
public:
|
||||
WNAFPrecomp(G &base) {
|
||||
WNAFPrecomp(const G &base) {
|
||||
pre[0] = base;
|
||||
GroupElemJac x = base;
|
||||
GroupElemJac d; d.SetDouble(x);
|
||||
for (int i=1; i<(1 << (W-2)); i++) {
|
||||
x.SetAdd(d,pre[i-1]);
|
||||
pre[i] = x;
|
||||
pre[i].SetJac(x);
|
||||
}
|
||||
}
|
||||
|
||||
void Get(G &out, int exp) {
|
||||
void Get(G &out, int exp) const {
|
||||
assert((exp & 1) == 1);
|
||||
assert(exp >= -((1 << (W-1)) - 1));
|
||||
assert(exp <= ((1 << (W-1)) - 1));
|
||||
|
@ -33,11 +36,97 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class WNAF {
|
||||
template<int B> class WNAF {
|
||||
private:
|
||||
int naf[B+1];
|
||||
int used;
|
||||
|
||||
void PushNAF(int num, int zeroes) {
|
||||
for (int i=0; i<zeroes; i++) {
|
||||
naf[used++]=0;
|
||||
}
|
||||
naf[used++]=num;
|
||||
}
|
||||
|
||||
public:
|
||||
WNAF(Context &ctx, Scalar &exp, int w) : used(0) {
|
||||
int zeroes = 0;
|
||||
while (!exp.IsZero()) {
|
||||
while (!exp.IsOdd()) {
|
||||
zeroes++;
|
||||
exp.Shift1();
|
||||
}
|
||||
int word = exp.ShiftLowBits(ctx,w);
|
||||
if (word & (1 << (w-1))) {
|
||||
exp.Inc();
|
||||
PushNAF(word - (1 << w), zeroes);
|
||||
} else {
|
||||
PushNAF(word, zeroes);
|
||||
}
|
||||
zeroes = w-1;
|
||||
}
|
||||
}
|
||||
|
||||
int GetSize() const {
|
||||
return used;
|
||||
}
|
||||
|
||||
int Get(int pos) const {
|
||||
return naf[used-1-pos];
|
||||
}
|
||||
|
||||
std::string ToString() {
|
||||
std::stringstream ss;
|
||||
ss << "(";
|
||||
for (int i=0; i<GetSize(); i++) {
|
||||
ss << Get(i);
|
||||
if (i != used-1)
|
||||
ss << ',';
|
||||
}
|
||||
ss << ")";
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
class ECMultConsts {
|
||||
public:
|
||||
const WNAFPrecomp<GroupElem,10> wpg;
|
||||
|
||||
ECMultConsts() : wpg(GetGroupConst().g) {}
|
||||
};
|
||||
|
||||
const ECMultConsts &GetECMultConsts() {
|
||||
static const ECMultConsts ecmult_consts;
|
||||
return ecmult_consts;
|
||||
}
|
||||
|
||||
void ECMult(Context &ctx, GroupElemJac &out, GroupElemJac &a, Scalar &an, Scalar &gn) {
|
||||
WNAF<256> wa(ctx, an, 5);
|
||||
WNAF<256> wg(ctx, gn, 10);
|
||||
WNAFPrecomp<GroupElemJac,5> wpa(a);
|
||||
const WNAFPrecomp<GroupElem,10> &wpg = GetECMultConsts().wpg;
|
||||
|
||||
int size = std::max(wa.GetSize(), wg.GetSize());
|
||||
|
||||
out = GroupElemJac();
|
||||
GroupElemJac tmpj;
|
||||
GroupElem tmpa;
|
||||
|
||||
for (int i=0; i<size; i++) {
|
||||
out.SetDouble(out);
|
||||
int anw = wa.Get(i);
|
||||
if (anw) {
|
||||
wpa.Get(tmpj, anw);
|
||||
out.SetAdd(out, tmpj);
|
||||
}
|
||||
int gnw = wg.Get(i);
|
||||
if (gnw) {
|
||||
wpg.Get(tmpa, gnw);
|
||||
out.SetAdd(out, tmpa);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
39
field.h
39
field.h
|
@ -1,12 +1,13 @@
|
|||
#ifndef _SECP256K1_FIELD_
|
||||
#define _SECP256K1_FIELD_
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
#include "num.h"
|
||||
#include "consts.h"
|
||||
|
||||
// #define VERIFY_MAGNITUDE 1
|
||||
|
||||
|
@ -38,6 +39,10 @@ public:
|
|||
#endif
|
||||
}
|
||||
|
||||
FieldElem(const unsigned char *b32) {
|
||||
SetBytes(b32);
|
||||
}
|
||||
|
||||
/** Normalizes the internal representation entries. Magnitude=1 */
|
||||
void Normalize() {
|
||||
uint64_t c;
|
||||
|
@ -302,18 +307,6 @@ public:
|
|||
return n[0] & 1;
|
||||
}
|
||||
|
||||
void SetInverse_Number(Context &ctx, FieldElem &a) {
|
||||
unsigned char tmp[32];
|
||||
a.GetBytes(tmp);
|
||||
{
|
||||
Context cctx(ctx);
|
||||
Number n(cctx, tmp, 32);
|
||||
n.SetModInverse(cctx, n, consts.field);
|
||||
n.GetBytes(tmp, 32);
|
||||
}
|
||||
SetBytes(tmp);
|
||||
}
|
||||
|
||||
/** Set this to be the (modular) inverse of another FieldElem. Magnitude=1 */
|
||||
void SetInverse(const FieldElem &a) {
|
||||
// calculate a^p, with p={45,63,1019,1023}
|
||||
|
@ -386,6 +379,26 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
static const unsigned char field_p_[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F};
|
||||
|
||||
class FieldConstants {
|
||||
private:
|
||||
Context ctx;
|
||||
|
||||
public:
|
||||
const Number field_p;
|
||||
|
||||
FieldConstants() : field_p(ctx, field_p_, sizeof(field_p_)) {}
|
||||
};
|
||||
|
||||
const FieldConstants &GetFieldConst() {
|
||||
static const FieldConstants field_const;
|
||||
return field_const;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
64
group.h
64
group.h
|
@ -5,6 +5,8 @@
|
|||
|
||||
namespace secp256k1 {
|
||||
|
||||
class GroupElemJac;
|
||||
|
||||
/** Defines a point on the secp256k1 curve (y^2 = x^3 + 7) */
|
||||
class GroupElem {
|
||||
protected:
|
||||
|
@ -31,11 +33,10 @@ public:
|
|||
return fInfinity;
|
||||
}
|
||||
|
||||
void SetNeg(GroupElem &p) {
|
||||
fInfinity = p.fInfinity;
|
||||
x = p.x;
|
||||
p.y.Normalize();
|
||||
y.SetNeg(p.y, 1);
|
||||
void SetNeg(const GroupElem &p) {
|
||||
*this = p;
|
||||
y.Normalize();
|
||||
y.SetNeg(y, 1);
|
||||
}
|
||||
|
||||
std::string ToString() {
|
||||
|
@ -44,6 +45,8 @@ public:
|
|||
return "(" + x.ToString() + "," + y.ToString() + ")";
|
||||
}
|
||||
|
||||
void SetJac(GroupElemJac &jac);
|
||||
|
||||
friend class GroupElemJac;
|
||||
};
|
||||
|
||||
|
@ -59,6 +62,12 @@ public:
|
|||
/** Creates the point with given affine coordinates */
|
||||
GroupElemJac(const FieldElem &xin, const FieldElem &yin) : GroupElem(xin,yin), z(1) {}
|
||||
|
||||
GroupElemJac(const GroupElem &in) : GroupElem(in), z(1) {}
|
||||
|
||||
void SetJac(GroupElemJac &jac) {
|
||||
*this = jac;
|
||||
}
|
||||
|
||||
/** Checks whether this is a non-infinite point on the curve */
|
||||
bool IsValid() {
|
||||
if (IsInfinity())
|
||||
|
@ -91,6 +100,12 @@ public:
|
|||
aff.y = y;
|
||||
}
|
||||
|
||||
void SetNeg(const GroupElemJac &p) {
|
||||
*this = p;
|
||||
y.Normalize();
|
||||
y.SetNeg(y, 1);
|
||||
}
|
||||
|
||||
/** Sets this point to have a given X coordinate & given Y oddness */
|
||||
void SetCompressed(const FieldElem &xin, bool fOdd) {
|
||||
x = xin;
|
||||
|
@ -222,6 +237,45 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
void GroupElem::SetJac(GroupElemJac &jac) {
|
||||
jac.GetAffine(*this);
|
||||
}
|
||||
|
||||
static const unsigned char order_[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
|
||||
0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,
|
||||
0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41};
|
||||
|
||||
static const unsigned char g_x_[] = {0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,
|
||||
0x55,0xA0,0x62,0x95,0xCE,0x87,0x0B,0x07,
|
||||
0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,
|
||||
0x59,0xF2,0x81,0x5B,0x16,0xF8,0x17,0x98};
|
||||
|
||||
static const unsigned char g_y_[] = {0x48,0x3A,0xDA,0x77,0x26,0xA3,0xC4,0x65,
|
||||
0x5D,0xA4,0xFB,0xFC,0x0E,0x11,0x08,0xA8,
|
||||
0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19,
|
||||
0x9C,0x47,0xD0,0x8F,0xFB,0x10,0xD4,0xB8};
|
||||
|
||||
class GroupConstants {
|
||||
private:
|
||||
Context ctx;
|
||||
const FieldElem g_x;
|
||||
const FieldElem g_y;
|
||||
|
||||
public:
|
||||
const Number order;
|
||||
const GroupElem g;
|
||||
|
||||
GroupConstants() : order(ctx, order_, sizeof(order_)),
|
||||
g_x(g_x_), g_y(g_y_),
|
||||
g(g_x,g_y) {}
|
||||
};
|
||||
|
||||
const GroupConstants &GetGroupConst() {
|
||||
static const GroupConstants group_const;
|
||||
return group_const;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
41
num.h
41
num.h
|
@ -2,8 +2,10 @@
|
|||
#define _SECP256K1_NUM_
|
||||
|
||||
#include <assert.h>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
namespace secp256k1 {
|
||||
|
||||
|
@ -60,15 +62,50 @@ public:
|
|||
void GetBytes(unsigned char *bin, int len) {
|
||||
int size = BN_num_bytes(bn);
|
||||
assert(size <= len);
|
||||
::memset(bin,0,len);
|
||||
memset(bin,0,len);
|
||||
BN_bn2bin(bn, bin + size - len);
|
||||
}
|
||||
void SetModInverse(Context &ctx, const Number &x, const Number &m) {
|
||||
BN_mod_inverse(bn, x.bn, m.bn, ctx);
|
||||
}
|
||||
int GetBits() const {
|
||||
return BN_num_bits(bn);
|
||||
}
|
||||
// return the lowest (rightmost) bits bits, and rshift them away
|
||||
int ShiftLowBits(Context &ctx, int bits) {
|
||||
Context ct(ctx);
|
||||
BIGNUM *tmp = ct.Get();
|
||||
BN_copy(tmp, bn);
|
||||
BN_mask_bits(tmp, bits);
|
||||
int ret = BN_get_word(tmp);
|
||||
BN_rshift(bn, bn, bits);
|
||||
return ret;
|
||||
}
|
||||
// check whether number is 0
|
||||
bool IsZero() {
|
||||
return BN_is_zero(bn);
|
||||
}
|
||||
// right-shift as many zeroes as possible
|
||||
int IsOdd() {
|
||||
return BN_is_odd(bn);
|
||||
}
|
||||
void Shift1() {
|
||||
BN_rshift1(bn,bn);
|
||||
}
|
||||
void Inc() {
|
||||
BN_add_word(bn,1);
|
||||
}
|
||||
void SetHex(const std::string &str) {
|
||||
BN_hex2bn(&bn, str.c_str());
|
||||
}
|
||||
std::string ToString() {
|
||||
char *str = BN_bn2hex(bn);
|
||||
std::string ret(str);
|
||||
OPENSSL_free(str);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
4
scalar.h
4
scalar.h
|
@ -2,14 +2,14 @@
|
|||
#define _SECP256K1_SCALAR_
|
||||
|
||||
#include "num.h"
|
||||
#include "consts.h"
|
||||
|
||||
namespace secp256k1 {
|
||||
/** Implements arithmetic modulo FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141,
|
||||
* using OpenSSL's BIGNUM
|
||||
*/
|
||||
class Scalar : private Number {
|
||||
class Scalar : public Number {
|
||||
public:
|
||||
Scalar(Context &ctx) : Number(ctx) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "num.h"
|
||||
#include "consts.h"
|
||||
#include "scalar.h"
|
||||
#include "field.h"
|
||||
#include "group.h"
|
||||
|
@ -11,22 +10,10 @@ using namespace secp256k1;
|
|||
|
||||
int main() {
|
||||
Context ctx;
|
||||
FieldElem f1,f2;
|
||||
f1.SetHex("8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846115");
|
||||
// f2.SetHex("8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846115");
|
||||
printf("%s\n",f1.ToString().c_str());
|
||||
// printf("%s\n",f2.ToString().c_str());
|
||||
for (int i=0; i<1000000; i++) {
|
||||
f1.SetInverse_Number(ctx,f1);
|
||||
// f2.SetInverse_(f2);
|
||||
// if (!(f1 == f2)) {
|
||||
// printf("f1 %i: %s\n",i,f1.ToString().c_str());
|
||||
// printf("f2 %i: %s\n",i,f2.ToString().c_str());
|
||||
// }
|
||||
// f1 *= 2;
|
||||
// f2 *= 2;
|
||||
}
|
||||
printf("%s\n",f1.ToString().c_str());
|
||||
// printf("%s\n",f2.ToString().c_str());
|
||||
Scalar scal(ctx);
|
||||
scal.SetHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
|
||||
printf("scal=%s\n", scal.ToString().c_str());
|
||||
WNAF<256> w(ctx, scal, 5);
|
||||
printf("wnaf=%s\n", w.ToString().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue