Eckey: implemented point multiplication

This commit is contained in:
olalonde 2014-05-07 13:08:10 +08:00
parent af942f9b06
commit b5c1a7d387
3 changed files with 91 additions and 0 deletions

View File

@ -19,6 +19,12 @@ Point.add = function(p1, p2) {
return Point.fromUncompressedPubKey(pubKey);
};
Point.multiply = function(p1, x) {
var u1 = p1.toUncompressedPubKey();
var pubKey = CPPKey.multiply(u1, x);
return Point.fromUncompressedPubKey(pubKey);
};
//convert the public key of a Key into a Point
Point.fromUncompressedPubKey = function(pubkey) {
var point = new Point();

View File

@ -124,6 +124,7 @@ void Key::Init(Handle<Object> target)
NODE_SET_METHOD(s_ct->GetFunction(), "generateSync", GenerateSync);
NODE_SET_METHOD(s_ct->GetFunction(), "fromDER", FromDER);
NODE_SET_METHOD(s_ct->GetFunction(), "addUncompressed", AddUncompressed);
NODE_SET_METHOD(s_ct->GetFunction(), "multiply", Multiply);
target->Set(String::NewSymbol("Key"),
s_ct->GetFunction());
@ -486,6 +487,87 @@ Key::AddUncompressed(const Arguments& args)
return scope.Close(rbuf->handle_);
}
Handle<Value>
Key::Multiply(const Arguments& args)
{
HandleScope scope;
if (args.Length() != 2) {
return VException("Two arguments expected: point0, x");
}
if (!Buffer::HasInstance(args[0])) {
return VException("Argument 'point0' must be of type Buffer");
}
if (Buffer::Length(args[0]) != 65) {
return VException("Argument 'point0' must have length 65");
}
if (!Buffer::HasInstance(args[1])) {
return VException("Argument 'x' must be of type Buffer");
}
if (Buffer::Length(args[1]) != 32) {
return VException("Argument 'x' must have length 32");
}
Handle<Object> point0_buf = args[0]->ToObject();
unsigned char *point0 = (unsigned char*) Buffer::Data(point0_buf);
Handle<Object> x_buf = args[1]->ToObject();
unsigned char *xval = (unsigned char*) Buffer::Data(x_buf);
EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_secp256k1);
const EC_GROUP *group = EC_KEY_get0_group(eckey);
BN_CTX *ctx;
//EC_POINT *p0, *p1, *r;
EC_POINT *p0, *r;
//BIGNUM *p0x, *p0y, *p1x, *p1y, *rx, *ry;
BIGNUM *p0x, *p0y, *x, *rx, *ry;
Buffer *rbuf;
p0 = EC_POINT_new(group);
//p1 = EC_POINT_new(group);
r = EC_POINT_new(group);
p0x = BN_bin2bn(&point0[1], 32, BN_new());
p0y = BN_bin2bn(&point0[33], 32, BN_new());
x = BN_bin2bn(&xval[0], 32, BN_new());
//p1x = BN_bin2bn(&point1[1], 32, BN_new());
//p1y = BN_bin2bn(&point1[33], 32, BN_new());
ctx = BN_CTX_new();
EC_POINT_set_affine_coordinates_GFp(group, p0, p0x, p0y, ctx);
//EC_POINT_set_affine_coordinates_GFp(group, p1, p1x, p1y, ctx);
//int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, size_t num, const EC_POINT *p[], const BIGNUM *m[], BN_CTX *ctx);
//int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);
EC_POINT_mul(group, r, NULL, p0, x, ctx);
rx = BN_new();
ry = BN_new();
EC_POINT_get_affine_coordinates_GFp(group, r, rx, ry, ctx);
rbuf = Buffer::New(65);
EC_POINT_point2oct(group, r, POINT_CONVERSION_UNCOMPRESSED, (unsigned char *)Buffer::Data(rbuf), 65, ctx);
//free: eckey, p0, p1, r, p0x, p0y, p1x, p1y, ctx, rx, ry, /*rbuf,*/ rcx, rcy
BN_clear_free(ry);
BN_clear_free(rx);
//do not free rbuf - this is returned
BN_CTX_free(ctx);
BN_clear_free(p0x);
BN_clear_free(p0y);
BN_clear_free(x);
//BN_clear_free(p1x);
//BN_clear_free(p1y);
EC_POINT_free(r);
//EC_POINT_free(p1);
EC_POINT_free(p0);
EC_KEY_free(eckey);
return scope.Close(rbuf->handle_);
}
Handle<Value>
Key::VerifySignature(const Arguments& args)
{

View File

@ -89,6 +89,9 @@ public:
static Handle<Value>
AddUncompressed(const Arguments& args);
static Handle<Value>
Multiply(const Arguments& args);
static Handle<Value>
VerifySignature(const Arguments& args);