ecdsa: adhere strictly to RFC6979
The previous impl. was in breach of the following section: > Please note that when k is generated from T, the result of bits2int is > compared to q, not reduced modulo q. If the value is not between 1 and > q-1, the process loops. > Performing a simple modular reduction would induce biases that would be > detrimental to signature security.
This commit is contained in:
parent
d93623e2b1
commit
776656df8b
2 changed files with 27 additions and 8 deletions
33
src/ecdsa.js
33
src/ecdsa.js
|
@ -5,6 +5,7 @@ var BigInteger = require('bigi')
|
|||
var ECSignature = require('./ecsignature')
|
||||
var Point = require('ecurve').Point
|
||||
|
||||
// https://tools.ietf.org/html/rfc6979#section-3.2
|
||||
function deterministicGenerateK(curve, hash, d) {
|
||||
assert(Buffer.isBuffer(hash), 'Hash must be a Buffer, not ' + hash)
|
||||
assert.equal(hash.length, 32, 'Hash must be 256 bit')
|
||||
|
@ -13,22 +14,40 @@ function deterministicGenerateK(curve, hash, d) {
|
|||
var x = d.toBuffer(32)
|
||||
var k = new Buffer(32)
|
||||
var v = new Buffer(32)
|
||||
k.fill(0)
|
||||
|
||||
// Step B
|
||||
v.fill(1)
|
||||
|
||||
// Step C
|
||||
k.fill(0)
|
||||
|
||||
// Step D
|
||||
k = crypto.HmacSHA256(Buffer.concat([v, new Buffer([0]), x, hash]), k)
|
||||
|
||||
// Step E
|
||||
v = crypto.HmacSHA256(v, k)
|
||||
|
||||
// Step F
|
||||
k = crypto.HmacSHA256(Buffer.concat([v, new Buffer([1]), x, hash]), k)
|
||||
v = crypto.HmacSHA256(v, k)
|
||||
|
||||
// Step G
|
||||
v = crypto.HmacSHA256(v, k)
|
||||
|
||||
var n = curve.n
|
||||
var kB = BigInteger.fromBuffer(v).mod(n)
|
||||
assert(kB.compareTo(BigInteger.ONE) > 0, 'Invalid k value')
|
||||
assert(kB.compareTo(n) < 0, 'Invalid k value')
|
||||
// Step H1/H2a, ignored as tlen === qlen (256 bit)
|
||||
// Step H2b
|
||||
v = crypto.HmacSHA256(v, k)
|
||||
|
||||
return kB
|
||||
var T = BigInteger.fromBuffer(v)
|
||||
|
||||
// Step H3, repeat until T is within the interval [0, n - 1]
|
||||
while ((T.signum() <= 0) || (T.compareTo(curve.n) >= 0)) {
|
||||
k = crypto.HmacSHA256(Buffer.concat([v, new Buffer([0])]), k)
|
||||
v = crypto.HmacSHA256(v, k)
|
||||
|
||||
T = BigInteger.fromBuffer(v)
|
||||
}
|
||||
|
||||
return T
|
||||
}
|
||||
|
||||
function sign(curve, hash, d) {
|
||||
|
|
|
@ -15,7 +15,7 @@ var fixtures = require('./fixtures/ecdsa.json')
|
|||
describe('ecdsa', function() {
|
||||
describe('deterministicGenerateK', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('determines k for \"' + f.message + '\"', function() {
|
||||
it('for \"' + f.message + '\"', function() {
|
||||
var d = BigInteger.fromHex(f.d)
|
||||
var h1 = crypto.sha256(f.message)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue