crypto: refactor pk.js.
This commit is contained in:
parent
f6fb3ba3b5
commit
5d6e089c92
@ -35,7 +35,6 @@
|
||||
*
|
||||
* @property {Object} crypto
|
||||
* @property {Object} ec
|
||||
* @property {Object} pk
|
||||
* @property {Object} schnorr
|
||||
*
|
||||
* @property {Object} db
|
||||
@ -169,7 +168,6 @@ bcoin.coinview = require('./coins/coinview');
|
||||
bcoin.crypto = require('./crypto');
|
||||
bcoin.bn = require('./crypto/bn');
|
||||
bcoin.ec = require('./crypto/ec');
|
||||
bcoin.pk = require('./crypto/pk');
|
||||
bcoin.schnorr = require('./crypto/schnorr');
|
||||
|
||||
// DB
|
||||
|
||||
@ -35,7 +35,6 @@
|
||||
*
|
||||
* @property {Object} crypto
|
||||
* @property {Object} ec
|
||||
* @property {Object} pk
|
||||
* @property {Object} schnorr
|
||||
*
|
||||
* @property {Object} db
|
||||
@ -189,7 +188,6 @@ bcoin.define('coinview', './coins/coinview');
|
||||
bcoin.define('crypto', './crypto');
|
||||
bcoin.define('bn', './crypto/bn');
|
||||
bcoin.define('ec', './crypto/ec');
|
||||
bcoin.define('pk', './crypto/pk');
|
||||
bcoin.define('schnorr', './crypto/schnorr');
|
||||
|
||||
// DB
|
||||
|
||||
@ -10,28 +10,8 @@
|
||||
* @module bip70/pk
|
||||
*/
|
||||
|
||||
var pk = require('../crypto/pk');
|
||||
|
||||
/**
|
||||
* Verify signature with public key.
|
||||
* @private
|
||||
* @param {String} hash - Hash algorithm.
|
||||
* @param {Buffer} msg
|
||||
* @param {Buffer} sig
|
||||
* @param {Object} key
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
exports._verify = function verify(hash, msg, sig, key) {
|
||||
switch (key.alg) {
|
||||
case 'rsa':
|
||||
return pk.rsa.verify(hash, msg, sig, key.data);
|
||||
case 'ecdsa':
|
||||
return pk.ecdsa.verify(key.curve, hash, msg, sig, key.data);
|
||||
default:
|
||||
throw new Error('Unsupported algorithm.');
|
||||
}
|
||||
};
|
||||
var rsa = require('../crypto/rsa');
|
||||
var ecdsa = require('../crypto/ecdsa');
|
||||
|
||||
/**
|
||||
* Verify signature with public key.
|
||||
@ -43,10 +23,13 @@ exports._verify = function verify(hash, msg, sig, key) {
|
||||
*/
|
||||
|
||||
exports.verify = function verify(hash, msg, sig, key) {
|
||||
try {
|
||||
return exports._verify(hash, msg, sig, key);
|
||||
} catch (e) {
|
||||
return false;
|
||||
switch (key.alg) {
|
||||
case 'rsa':
|
||||
return rsa.verify(hash, msg, sig, key.data);
|
||||
case 'ecdsa':
|
||||
return ecdsa.verify(key.curve, hash, msg, sig, key.data);
|
||||
default:
|
||||
throw new Error('Unsupported algorithm.');
|
||||
}
|
||||
};
|
||||
|
||||
@ -61,9 +44,9 @@ exports.verify = function verify(hash, msg, sig, key) {
|
||||
exports.sign = function sign(hash, msg, key) {
|
||||
switch (key.alg) {
|
||||
case 'rsa':
|
||||
return pk.rsa.sign(hash, msg, key.data);
|
||||
return rsa.sign(hash, msg, key.data);
|
||||
case 'ecdsa':
|
||||
return pk.ecdsa.sign(key.curve, hash, msg, key.data);
|
||||
return ecdsa.sign(key.curve, hash, msg, key.data);
|
||||
default:
|
||||
throw new Error('Unsupported algorithm.');
|
||||
}
|
||||
|
||||
70
lib/crypto/ecdsa.js
Normal file
70
lib/crypto/ecdsa.js
Normal file
@ -0,0 +1,70 @@
|
||||
/*!
|
||||
* ecdsa.js - ecdsa for bcoin
|
||||
* Copyright (c) 2016-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @module crypto/ecdsa
|
||||
*/
|
||||
|
||||
var assert = require('assert');
|
||||
var elliptic = require('elliptic');
|
||||
var backend = require('./backend');
|
||||
|
||||
/**
|
||||
* Verify ECDSA signature.
|
||||
* @param {String} curve - Curve name.
|
||||
* @param {String} alg - Hash algorithm.
|
||||
* @param {Buffer} msg - Signed message.
|
||||
* @param {Buffer} sig - Signature.
|
||||
* @param {Buffer} key - ASN1 serialized ECDSA key.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
exports.verify = function verify(curve, alg, msg, sig, key) {
|
||||
var ec, hash;
|
||||
|
||||
assert(typeof curve === 'string', 'No curve selected.');
|
||||
assert(typeof alg === 'string', 'No algorithm selected.');
|
||||
assert(Buffer.isBuffer(msg));
|
||||
assert(Buffer.isBuffer(sig));
|
||||
assert(Buffer.isBuffer(key));
|
||||
|
||||
ec = elliptic.ec(curve);
|
||||
hash = backend.hash(alg, msg);
|
||||
|
||||
try {
|
||||
return ec.verify(hash, sig, key);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sign message with ECDSA key.
|
||||
* @memberof module:crypto/pk.ecdsa
|
||||
* @param {String} curve - Curve name.
|
||||
* @param {String} alg - Hash algorithm.
|
||||
* @param {Buffer} msg - Signed message.
|
||||
* @param {Buffer} key - ASN1 serialized ECDSA key.
|
||||
* @returns {Buffer} Signature (DER)
|
||||
*/
|
||||
|
||||
exports.sign = function sign(curve, alg, msg, key) {
|
||||
var ec, hash, sig;
|
||||
|
||||
assert(typeof curve === 'string', 'No curve selected.');
|
||||
assert(typeof alg === 'string', 'No algorithm selected.');
|
||||
assert(Buffer.isBuffer(msg));
|
||||
assert(Buffer.isBuffer(key));
|
||||
|
||||
ec = elliptic.ec(curve);
|
||||
hash = backend.hash(alg, msg);
|
||||
|
||||
sig = ec.sign(hash, key, { canonical: true });
|
||||
|
||||
return Buffer.from(sig.toDER());
|
||||
};
|
||||
@ -306,26 +306,19 @@ exports.AEAD = exports.chachapoly.AEAD;
|
||||
|
||||
exports.BN = require('./bn');
|
||||
|
||||
/**
|
||||
* pk module
|
||||
* @see module:crypto/pk
|
||||
*/
|
||||
|
||||
exports.pk = require('./pk');
|
||||
|
||||
/**
|
||||
* RSA
|
||||
* @see module:crypto/pk.rsa
|
||||
* @see module:crypto/rsa
|
||||
*/
|
||||
|
||||
exports.rsa = exports.pk.rsa;
|
||||
exports.rsa = require('./rsa');
|
||||
|
||||
/**
|
||||
* ECDSA
|
||||
* @see module:crypto/pk.ecdsa
|
||||
* @see module:crypto/ecdsa
|
||||
*/
|
||||
|
||||
exports.ecdsa = exports.pk.ecdsa;
|
||||
exports.ecdsa = require('./ecdsa');
|
||||
|
||||
/**
|
||||
* ec module
|
||||
|
||||
168
lib/crypto/pk.js
168
lib/crypto/pk.js
@ -1,168 +0,0 @@
|
||||
/*!
|
||||
* pk.js - public key algorithms for bcoin
|
||||
* Copyright (c) 2016-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @module crypto/pk
|
||||
*/
|
||||
|
||||
var assert = require('assert');
|
||||
var nodeCrypto = require('crypto');
|
||||
var elliptic = require('elliptic');
|
||||
var PEM = require('../utils/pem');
|
||||
var backend = require('./backend');
|
||||
var rsa, ecdsa;
|
||||
|
||||
/**
|
||||
* RSA
|
||||
* @namespace module:crypto/pk.rsa
|
||||
*/
|
||||
|
||||
rsa = {};
|
||||
|
||||
/**
|
||||
* Verify RSA signature.
|
||||
* @memberof module:crypto/pk.rsa
|
||||
* @param {String} alg - Hash algorithm.
|
||||
* @param {Buffer} msg - Signed message.
|
||||
* @param {Buffer} sig - Signature.
|
||||
* @param {Buffer} key - ASN1 serialized RSA key.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
rsa.verify = function _verify(alg, msg, sig, key) {
|
||||
var pem = toPEM('rsa', key, null, 'public key');
|
||||
return verify('rsa', alg, msg, sig, pem);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sign message with RSA key.
|
||||
* @memberof module:crypto/pk.rsa
|
||||
* @param {String} alg - Hash algorithm.
|
||||
* @param {Buffer} msg - Signed message.
|
||||
* @param {Buffer} key - ASN1 serialized RSA key.
|
||||
* @returns {Buffer} Signature (DER)
|
||||
*/
|
||||
|
||||
rsa.sign = function _sign(alg, msg, key) {
|
||||
var pem = toPEM('rsa', key, null, 'private key');
|
||||
return sign('rsa', alg, msg, pem);
|
||||
};
|
||||
|
||||
/**
|
||||
* ECDSA
|
||||
* @namespace module:crypto/pk.ecdsa
|
||||
*/
|
||||
|
||||
ecdsa = {};
|
||||
|
||||
/**
|
||||
* Verify ECDSA signature.
|
||||
* @memberof module:crypto/pk.ecdsa
|
||||
* @param {String} curve - Curve name.
|
||||
* @param {String} alg - Hash algorithm.
|
||||
* @param {Buffer} msg - Signed message.
|
||||
* @param {Buffer} sig - Signature.
|
||||
* @param {Buffer} key - ASN1 serialized ECDSA key.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
ecdsa.verify = function verify(curve, alg, msg, sig, key) {
|
||||
var ec, hash;
|
||||
|
||||
assert(curve, 'No curve selected.');
|
||||
|
||||
ec = elliptic.ec(curve);
|
||||
hash = backend.hash(alg, msg);
|
||||
|
||||
return ec.verify(hash, sig, key);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sign message with ECDSA key.
|
||||
* @memberof module:crypto/pk.ecdsa
|
||||
* @param {String} curve - Curve name.
|
||||
* @param {String} alg - Hash algorithm.
|
||||
* @param {Buffer} msg - Signed message.
|
||||
* @param {Buffer} key - ASN1 serialized ECDSA key.
|
||||
* @returns {Buffer} Signature (DER)
|
||||
*/
|
||||
|
||||
ecdsa.sign = function sign(curve, alg, msg, key) {
|
||||
var ec, hash;
|
||||
|
||||
assert(curve, 'No curve selected.');
|
||||
|
||||
ec = elliptic.ec(curve);
|
||||
hash = backend.hash(alg, msg);
|
||||
|
||||
return Buffer.from(ec.sign(hash, key));
|
||||
};
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function verify(alg, hash, msg, sig, key) {
|
||||
var algo = normalizeAlg(alg, hash);
|
||||
var verifier = nodeCrypto.createVerify(algo);
|
||||
verifier.update(msg);
|
||||
return verifier.verify(key, sig);
|
||||
}
|
||||
|
||||
function sign(alg, hash, msg, key) {
|
||||
var algo = normalizeAlg(alg, hash);
|
||||
var sig = nodeCrypto.createSign(algo);
|
||||
sig.update(msg);
|
||||
return sig.sign(key);
|
||||
}
|
||||
|
||||
function toPEM(alg, key, params, type) {
|
||||
var tag, pem;
|
||||
|
||||
switch (alg) {
|
||||
case 'rsa':
|
||||
tag = 'RSA';
|
||||
break;
|
||||
case 'ecdsa':
|
||||
tag = 'EC';
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unsupported algorithm.');
|
||||
}
|
||||
|
||||
pem = PEM.encode(key, tag, type);
|
||||
|
||||
// Key parameters, usually present
|
||||
// if selecting an EC curve.
|
||||
if (params)
|
||||
pem += PEM.encode(params, tag, 'parameters');
|
||||
|
||||
return pem;
|
||||
}
|
||||
|
||||
function normalizeAlg(alg, hash) {
|
||||
var name = alg.toUpperCase() + '-' + hash.toUpperCase();
|
||||
|
||||
switch (name) {
|
||||
case 'ECDSA-SHA1':
|
||||
name = 'ecdsa-with-SHA1';
|
||||
break;
|
||||
case 'ECDSA-SHA256':
|
||||
name = 'ecdsa-with-SHA256';
|
||||
break;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
exports.rsa = rsa;
|
||||
exports.ecdsa = ecdsa;
|
||||
@ -1,35 +1,26 @@
|
||||
/*!
|
||||
* pk-browser.js - public key algorithms for bcoin
|
||||
* rsa-browser.js - rsa for bcoin
|
||||
* Copyright (c) 2016-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @module crypto/pk-browser
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
var assert = require('assert');
|
||||
var elliptic = require('elliptic');
|
||||
var BN = require('./bn');
|
||||
var ASN1 = require('../utils/asn1');
|
||||
var backend = require('./backend');
|
||||
var rsa, ecdsa;
|
||||
|
||||
/**
|
||||
* RSA
|
||||
* @namespace module:crypto/pk-browser.rsa
|
||||
* @exports crypto/rsa
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
rsa = {};
|
||||
var rsa = exports;
|
||||
|
||||
/**
|
||||
* PKCS signature prefixes.
|
||||
* @type {Object}
|
||||
* @memberof module:crypto/pk-browser.rsa
|
||||
*/
|
||||
|
||||
rsa.prefixes = {
|
||||
@ -44,7 +35,6 @@ rsa.prefixes = {
|
||||
|
||||
/**
|
||||
* Verify RSA signature.
|
||||
* @memberof module:crypto/pk-browser.rsa
|
||||
* @param {String} alg - Hash algorithm.
|
||||
* @param {Buffer} msg - Signed message.
|
||||
* @param {Buffer} sig - Signature.
|
||||
@ -57,6 +47,11 @@ rsa.verify = function verify(alg, msg, sig, key) {
|
||||
var hash, len, pub;
|
||||
var N, e, k, m, em, ok, i;
|
||||
|
||||
assert(typeof alg === 'string', 'No algorithm selected.');
|
||||
assert(Buffer.isBuffer(msg));
|
||||
assert(Buffer.isBuffer(sig));
|
||||
assert(Buffer.isBuffer(key));
|
||||
|
||||
if (!prefix)
|
||||
throw new Error('Unknown PKCS prefix.');
|
||||
|
||||
@ -88,7 +83,6 @@ rsa.verify = function verify(alg, msg, sig, key) {
|
||||
|
||||
/**
|
||||
* Sign message with RSA key.
|
||||
* @memberof module:crypto/pk-browser.rsa
|
||||
* @param {String} alg - Hash algorithm.
|
||||
* @param {Buffer} msg - Signed message.
|
||||
* @param {Buffer} key - ASN1 serialized RSA key.
|
||||
@ -100,6 +94,10 @@ rsa.sign = function sign(alg, msg, key) {
|
||||
var hash, len, priv;
|
||||
var N, D, k, i, em;
|
||||
|
||||
assert(typeof alg === 'string', 'No algorithm selected.');
|
||||
assert(Buffer.isBuffer(msg));
|
||||
assert(Buffer.isBuffer(key));
|
||||
|
||||
if (!prefix)
|
||||
throw new Error('Unknown PKCS prefix.');
|
||||
|
||||
@ -129,7 +127,6 @@ rsa.sign = function sign(alg, msg, key) {
|
||||
|
||||
/**
|
||||
* Decrypt with modulus and exponent.
|
||||
* @memberof module:crypto/pk-browser.rsa
|
||||
* @param {BN} N
|
||||
* @param {BN} D
|
||||
* @param {Buffer} m
|
||||
@ -151,7 +148,6 @@ rsa.decrypt = function decrypt(N, D, m) {
|
||||
|
||||
/**
|
||||
* Encrypt with modulus and exponent.
|
||||
* @memberof module:crypto/pk-browser.rsa
|
||||
* @param {BN} N
|
||||
* @param {BN} e
|
||||
* @param {Buffer} m
|
||||
@ -166,57 +162,6 @@ rsa.encrypt = function encrypt(N, e, m) {
|
||||
.toArrayLike(Buffer, 'be');
|
||||
};
|
||||
|
||||
/**
|
||||
* ECDSA
|
||||
* @namespace module:crypto/pk.ecdsa
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
ecdsa = {};
|
||||
|
||||
/**
|
||||
* Verify ECDSA signature.
|
||||
* @memberof module:crypto/pk-browser.ecdsa
|
||||
* @param {String} curve - Curve name.
|
||||
* @param {String} alg - Hash algorithm.
|
||||
* @param {Buffer} msg - Signed message.
|
||||
* @param {Buffer} sig - Signature.
|
||||
* @param {Buffer} key - ASN1 serialized ECDSA key.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
ecdsa.verify = function verify(curve, alg, msg, sig, key) {
|
||||
var ec, hash;
|
||||
|
||||
assert(curve, 'No curve selected.');
|
||||
|
||||
ec = elliptic.ec(curve);
|
||||
hash = backend.hash(alg, msg);
|
||||
|
||||
return ec.verify(hash, sig, key);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sign message with ECDSA key.
|
||||
* @memberof module:crypto/pk-browser.ecdsa
|
||||
* @param {String} curve - Curve name.
|
||||
* @param {String} alg - Hash algorithm.
|
||||
* @param {Buffer} msg - Signed message.
|
||||
* @param {Buffer} key - ASN1 serialized ECDSA key.
|
||||
* @returns {Buffer} Signature (DER)
|
||||
*/
|
||||
|
||||
ecdsa.sign = function sign(curve, alg, msg, key) {
|
||||
var ec, hash;
|
||||
|
||||
assert(curve, 'No curve selected.');
|
||||
|
||||
ec = elliptic.ec(curve);
|
||||
hash = backend.hash(alg, msg);
|
||||
|
||||
return Buffer.from(ec.sign(hash, key));
|
||||
};
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
@ -243,10 +188,3 @@ function ceq(a, b) {
|
||||
r &= r >>> 1;
|
||||
return r === 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
exports.rsa = rsa;
|
||||
exports.ecdsa = ecdsa;
|
||||
75
lib/crypto/rsa.js
Normal file
75
lib/crypto/rsa.js
Normal file
@ -0,0 +1,75 @@
|
||||
/*!
|
||||
* rsa.js - RSA for bcoin
|
||||
* Copyright (c) 2016-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @module crypto/rsa
|
||||
*/
|
||||
|
||||
var assert = require('assert');
|
||||
var crypto = require('crypto');
|
||||
var PEM = require('../utils/pem');
|
||||
|
||||
/**
|
||||
* Verify RSA signature.
|
||||
* @param {String} alg - Hash algorithm.
|
||||
* @param {Buffer} msg - Signed message.
|
||||
* @param {Buffer} sig - Signature.
|
||||
* @param {Buffer} key - ASN1 serialized RSA key.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
exports.verify = function verify(alg, msg, sig, key) {
|
||||
var pem, name, ctx;
|
||||
|
||||
assert(typeof alg === 'string', 'No algorithm selected.');
|
||||
assert(Buffer.isBuffer(msg));
|
||||
assert(Buffer.isBuffer(sig));
|
||||
assert(Buffer.isBuffer(key));
|
||||
|
||||
pem = PEM.encode(key, 'rsa', 'public key');
|
||||
name = normalizeAlg('rsa', alg);
|
||||
ctx = crypto.createVerify(name);
|
||||
|
||||
try {
|
||||
ctx.update(msg);
|
||||
return ctx.verify(key, sig);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sign message with RSA key.
|
||||
* @param {String} alg - Hash algorithm.
|
||||
* @param {Buffer} msg - Signed message.
|
||||
* @param {Buffer} key - ASN1 serialized RSA key.
|
||||
* @returns {Buffer} Signature (DER)
|
||||
*/
|
||||
|
||||
exports.sign = function sign(alg, msg, key) {
|
||||
var pem, name, ctx;
|
||||
|
||||
assert(typeof alg === 'string', 'No algorithm selected.');
|
||||
assert(Buffer.isBuffer(msg));
|
||||
assert(Buffer.isBuffer(key));
|
||||
|
||||
pem = PEM.encode(key, 'rsa', 'private key');
|
||||
name = normalizeAlg('rsa', alg);
|
||||
ctx = crypto.createSign(name);
|
||||
ctx.update(msg);
|
||||
|
||||
return ctx.sign(key);
|
||||
};
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function normalizeAlg(alg, hash) {
|
||||
return alg.toUpperCase() + '-' + hash.toUpperCase();
|
||||
}
|
||||
@ -80,7 +80,7 @@
|
||||
"./lib/blockchain/layout.js": "./lib/blockchain/layout-browser.js",
|
||||
"./lib/crypto/backend.js": "./lib/crypto/backend-browser.js",
|
||||
"./lib/crypto/ec.js": "./lib/crypto/ec-elliptic.js",
|
||||
"./lib/crypto/pk.js": "./lib/crypto/pk-browser.js",
|
||||
"./lib/crypto/rsa.js": "./lib/crypto/rsa-browser.js",
|
||||
"./lib/db/backends.js": "./lib/db/backends-browser.js",
|
||||
"./lib/hd/wordlist": "./lib/hd/wordlist-browser.js",
|
||||
"./lib/http/base": "./browser/empty.js",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user