compiles...

This commit is contained in:
Pieter Wuille 2013-03-09 22:47:40 +01:00
parent 581ef48ba8
commit cb4d29c81e
7 changed files with 224 additions and 78 deletions

View file

@ -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

View file

@ -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
View file

@ -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
View file

@ -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
View file

@ -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

View file

@ -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) {}
};
}

View file

@ -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;
}