fix issue by outputing proper pubkey format

The way I was outputting the pubkeys would be incorrect if the first byte of
one of the coordinates was 0, since it would print the first non-zero byte
first. The solution was to use the standard openssl function that outputs a
public key to oct.
This commit is contained in:
Ryan X. Charles 2014-03-23 15:11:32 -07:00
parent d11361be9e
commit a686e63b0b
2 changed files with 55 additions and 13 deletions

View File

@ -435,12 +435,10 @@ Key::AddUncompressed(const Arguments& args)
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;
BIGNUM *p0x, *p0y, *p1x, *p1y, *rx, *ry;
Buffer *rbuf;
unsigned char *rcx, *rcy;
p0 = EC_POINT_new(group);
p1 = EC_POINT_new(group);
@ -461,19 +459,11 @@ Key::AddUncompressed(const Arguments& args)
rx = BN_new();
ry = BN_new();
EC_POINT_get_affine_coordinates_GFp(group, r, rx, ry, ctx);
rbuf = Buffer::New(65);
rcx = (unsigned char *)malloc(32);
rcy = (unsigned char *)malloc(32);
BN_bn2bin(rx, rcx);
BN_bn2bin(ry, rcy);
memcpy(&(((unsigned char *)Buffer::Data(rbuf))[1]), rcx, 32);
memcpy(&(((unsigned char *)Buffer::Data(rbuf))[33]), rcy, 32);
((unsigned char *)Buffer::Data(rbuf))[0] = 0x04;
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
free(rcy); //TODO: also clear
free(rcx); //TODO: also clear
BN_clear_free(ry);
BN_clear_free(rx);
//do not free rbuf - this is returned

View File

@ -1,8 +1,9 @@
'use strict';
var assert = require('assert');
var chai = chai || require('chai');
var bitcore = bitcore || require('../bitcore');
var coinUtil = coinUtil || require('../util/util');
var buffertools = require('buffertools');
var should = chai.should();
@ -118,6 +119,7 @@ describe('Key', function() {
it('should exist', function() {
should.exist(Key.addUncompressed);
});
it('should add two uncompressed public keys', function() {
var key1 = Key.generateSync();
key1.compressed = false;
@ -128,6 +130,56 @@ describe('Key', function() {
var pubkey = Key.addUncompressed(pubkey1, pubkey2);
pubkey.length.should.equal(65);
});
it('a + b should equal b + a', function() {
var key1 = Key.generateSync();
key1.compressed = false;
var key2 = Key.generateSync();
key2.compressed = false;
var pubkey1 = key1.public;
var pubkey2 = key2.public;
var r1 = Key.addUncompressed(pubkey1, pubkey2);
var r2 = Key.addUncompressed(pubkey2, pubkey1);
r1.toString('hex').should.equal(r2.toString('hex'));
});
it('should be able to add these two public keys without error', function() {
var key1 = new Key();
key1.private = coinUtil.sha256("first " + 3);
key1.compressed = false;
key1.regenerateSync();
var key2 = new Key();
key2.private = coinUtil.sha256("second " + 3);
key2.compressed = false;
key2.regenerateSync();
var pubkey1 = key1.public;
var pubkey2 = key2.public;
var pubkey = Key.addUncompressed(pubkey1, pubkey2);
pubkey.length.should.equal(65);
var key = new Key();
key.public = pubkey;
assert(key.public !== null);
});
it('should be able to add many public keys without error', function() {
for (var i = 0; i <= 1000; i++) {
var key1 = new Key();
key1.private = coinUtil.sha256("first " + i);
key1.compressed = false;
key1.regenerateSync();
var key2 = new Key();
key2.private = coinUtil.sha256("second " + i);
key2.compressed = false;
key2.regenerateSync();
var pubkey1 = key1.public;
var pubkey2 = key2.public;
var pubkey = Key.addUncompressed(pubkey1, pubkey2);
pubkey.length.should.equal(65);
var key = new Key();
key.public = pubkey;
assert(key.public !== null);
};
});
});
});