Ryan X. Charles
10 years ago
11 changed files with 221 additions and 118 deletions
@ -1,32 +0,0 @@ |
|||
"use strict"; |
|||
var bignum = require('bignum'); |
|||
var Point = require('./Point'); |
|||
|
|||
var n = bignum.fromBuffer(new Buffer("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 'hex'), { |
|||
size: 32 |
|||
}); |
|||
|
|||
|
|||
var Curve = function() {}; |
|||
|
|||
/* secp256k1 curve */ |
|||
var G; |
|||
Curve.getG = function() { |
|||
// don't use Point in top scope, causes exception in browser
|
|||
// when Point is not loaded yet
|
|||
|
|||
// use cached version if available
|
|||
G = G || new Point(bignum.fromBuffer(new Buffer("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 'hex'), { |
|||
size: 32 |
|||
}), |
|||
bignum.fromBuffer(new Buffer("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 'hex'), { |
|||
size: 32 |
|||
})); |
|||
return G; |
|||
}; |
|||
|
|||
Curve.getN = function() { |
|||
return n; |
|||
}; |
|||
|
|||
module.exports = Curve; |
@ -1 +1,9 @@ |
|||
module.exports = require('bindings')('KeyModule').Key; |
|||
var Key = require('bindings')('KeyModule').Key; |
|||
var CommonKey = require('./common/Key'); |
|||
|
|||
for (var i in CommonKey) { |
|||
if (CommonKey.hasOwnProperty(i)) |
|||
Key[i] = CommonKey[i]; |
|||
} |
|||
|
|||
module.exports = Key; |
|||
|
@ -0,0 +1,106 @@ |
|||
var bignum = require('bignum'); |
|||
var Point = require('./Point'); |
|||
var SecureRandom = require('./SecureRandom'); |
|||
var Key = function() {} |
|||
|
|||
Key.parseDERsig = function(sig) { |
|||
if (!Buffer.isBuffer(sig)) |
|||
throw new Error('DER formatted signature should be a buffer'); |
|||
|
|||
var header = sig[0]; |
|||
|
|||
if (header !== 0x30) |
|||
throw new Error('Header byte should be 0x30'); |
|||
|
|||
var length = sig[1]; |
|||
if (length !== sig.slice(2).length) |
|||
throw new Error('Length byte should length of what follows'); |
|||
|
|||
var rheader = sig[2 + 0]; |
|||
if (rheader !== 0x02) |
|||
throw new Error('Integer byte for r should be 0x02'); |
|||
|
|||
var rlength = sig[2 + 1]; |
|||
var rbuf = sig.slice(2 + 2, 2 + 2 + rlength); |
|||
var r = bignum.fromBuffer(rbuf); |
|||
var rneg = sig[2 + 1 + 1] === 0x00 ? true : false; |
|||
if (rlength !== rbuf.length) |
|||
throw new Error('Length of r incorrect'); |
|||
|
|||
var sheader = sig[2 + 2 + rlength + 0]; |
|||
if (sheader !== 0x02) |
|||
throw new Error('Integer byte for s should be 0x02'); |
|||
|
|||
var slength = sig[2 + 2 + rlength + 1]; |
|||
var sbuf = sig.slice(2 + 2 + rlength + 2, 2 + 2 + rlength + 2 + slength); |
|||
var s = bignum.fromBuffer(sbuf); |
|||
var sneg = sig[2 + 2 + rlength + 2 + 2] === 0x00 ? true : false; |
|||
if (slength !== sbuf.length) |
|||
throw new Error('Length of s incorrect'); |
|||
|
|||
var sumlength = 2 + 2 + rlength + 2 + slength; |
|||
if (length !== sumlength - 2) |
|||
throw new Error('Length of signature incorrect'); |
|||
|
|||
|
|||
var obj = { |
|||
header: header, |
|||
length: length, |
|||
rheader: rheader, |
|||
rlength: rlength, |
|||
rneg: rneg, |
|||
rbuf: rbuf, |
|||
r: r, |
|||
sheader: sheader, |
|||
slength: slength, |
|||
sneg: sneg, |
|||
sbuf: sbuf, |
|||
s: s |
|||
}; |
|||
|
|||
return obj; |
|||
}; |
|||
|
|||
Key.rs2DER = function(r, s) { |
|||
var rnbuf = r.toBuffer(); |
|||
var snbuf = s.toBuffer(); |
|||
|
|||
var rneg = rnbuf[0] & 0x80 ? true : false; |
|||
var sneg = snbuf[0] & 0x80 ? true : false; |
|||
|
|||
var rbuf = rneg ? Buffer.concat([new Buffer([0x00]), rnbuf]) : rnbuf; |
|||
var sbuf = sneg ? Buffer.concat([new Buffer([0x00]), snbuf]) : snbuf; |
|||
|
|||
var length = 2 + rbuf.length + 2 + sbuf.length; |
|||
var rlength = rbuf.length; |
|||
var slength = sbuf.length; |
|||
var rheader = 0x02; |
|||
var sheader = 0x02; |
|||
var header = 0x30; |
|||
|
|||
var der = Buffer.concat([new Buffer([header, length, rheader, rlength]), rbuf, new Buffer([sheader, slength]), sbuf]); |
|||
return der; |
|||
}; |
|||
|
|||
Key.sign = function(hash, priv, k) { |
|||
var d = priv; |
|||
var n = Point.getN(); |
|||
var e = new bignum(hash); |
|||
|
|||
do { |
|||
var k = k || Key.genk(); |
|||
var G = Point.getG(); |
|||
var Q = Point.multiply(G, k); |
|||
var r = Q.x.mod(n); |
|||
var s = k.invm(n).mul(e.add(d.mul(r))).mod(n); |
|||
} while (r.cmp(new bignum(0)) <= 0 || s.cmp(new bignum(0)) <= 0); |
|||
|
|||
return {r: r, s: s}; |
|||
}; |
|||
|
|||
Key.genk = function() { |
|||
//TODO: account for when >= n
|
|||
return new bignum(SecureRandom.getRandomBuffer(8)); |
|||
}; |
|||
|
|||
module.exports = Key; |
@ -1,37 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
var chai = chai || require('chai'); |
|||
var bitcore = bitcore || require('../bitcore'); |
|||
var coinUtil = coinUtil || bitcore.util; |
|||
var buffertools = require('buffertools'); |
|||
var bignum = bitcore.Bignum; |
|||
|
|||
var should = chai.should(); |
|||
var assert = chai.assert; |
|||
|
|||
var Curve = bitcore.Curve; |
|||
|
|||
describe('Curve', function() { |
|||
|
|||
it('should initialize the main object', function() { |
|||
should.exist(Curve); |
|||
}); |
|||
|
|||
describe('getN', function() { |
|||
it('should return a big number', function() { |
|||
var N = Curve.getN(); |
|||
should.exist(N); |
|||
N.toBuffer({size: 32}).toString('hex').length.should.equal(64); |
|||
}); |
|||
}); |
|||
|
|||
describe('getG', function() { |
|||
it('should return a Point', function() { |
|||
var G = Curve.getG(); |
|||
should.exist(G.x); |
|||
G.x.toBuffer({size: 32}).toString('hex').length.should.equal(64); |
|||
G.y.toBuffer({size: 32}).toString('hex').length.should.equal(64); |
|||
}); |
|||
}); |
|||
|
|||
}); |
Loading…
Reference in new issue