change some variable names, add some curve parameters

This commit is contained in:
Sanjana Rajan 2017-11-26 22:15:03 -08:00
parent 311d288bb7
commit 8794446a66
5 changed files with 68 additions and 38 deletions

View File

@ -45,11 +45,14 @@ function createType(data, type) {
case 'oid': case 'oid':
return new type_oid(data); return new type_oid(data);
case 'kdf': case 'kdf':
return new type_kdf_params(data); if (data) {
return new type_kdf_params(data[0], data[1]);
}
return new type_kdf_params();
case 'ecdh_symkey': case 'ecdh_symkey':
return new type_ecdh_symkey(data); return new type_ecdh_symkey(data);
default: default:
return null; throw new Error('Unknown type.');
} }
} }
@ -280,12 +283,12 @@ export default {
case 'ecdsa': case 'ecdsa':
return publicKey.elliptic.generate(curve).then(function (keyObject) { return publicKey.elliptic.generate(curve).then(function (keyObject) {
return constructParams([keyObject.oid, keyObject.R, keyObject.r], types); return constructParams([keyObject.oid, keyObject.Q, keyObject.d], types);
}); });
case 'ecdh': case 'ecdh':
return publicKey.elliptic.generate(curve).then(function (keyObject) { return publicKey.elliptic.generate(curve).then(function (keyObject) {
return constructParams([keyObject.oid, keyObject.R, [keyObject.hash, keyObject.cipher], keyObject.r], types); return constructParams([keyObject.oid, keyObject.Q, [keyObject.hash, keyObject.cipher], keyObject.d], types);
}); });
default: default:
@ -294,6 +297,21 @@ export default {
}, },
getCloneFn: function(type) {
switch(type) {
case 'mpi':
return type_mpi.fromClone;
case 'oid':
return type_oid.fromClone;
case 'kdf':
return type_kdf_params.fromClone;
case 'ecdh_symkey':
return type_ecdh_symkey.fromClone;
default:
throw new Error('Unknown type.');
}
},
/** /**
* generate random byte prefix as string for the specified algorithm * generate random byte prefix as string for the specified algorithm
* @param {module:enums.symmetric} algo Algorithm to use (see {@link http://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2}) * @param {module:enums.symmetric} algo Algorithm to use (see {@link http://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2})

View File

@ -36,36 +36,47 @@ import util from '../../../util.js';
const curves = { const curves = {
p256: { p256: {
oid: util.bin2str([0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07]), oid: util.bin2str([0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07]),
bits: 256, curveName: 'P-256',
hashName: 'SHA-256',
hash: enums.hash.sha256, hash: enums.hash.sha256,
cipher: enums.symmetric.aes128, cipher: enums.symmetric.aes128,
nist: true
}, },
p384: { p384: {
oid: util.bin2str([0x2B, 0x81, 0x04, 0x00, 0x22]), oid: util.bin2str([0x2B, 0x81, 0x04, 0x00, 0x22]),
bits: 384, curveName: 'P-384',
hashName: 'SHA-384',
hash: enums.hash.sha384, hash: enums.hash.sha384,
cipher: enums.symmetric.aes192, cipher: enums.symmetric.aes192,
nist: true
}, },
p521: { p521: {
oid: util.bin2str([0x2B, 0x81, 0x04, 0x00, 0x23]), oid: util.bin2str([0x2B, 0x81, 0x04, 0x00, 0x23]),
bits: 521, curveName: 'P-521',
hashName: 'SHA-512',
hash: enums.hash.sha512, hash: enums.hash.sha512,
cipher: enums.symmetric.aes256, cipher: enums.symmetric.aes256,
nist: true
}, },
secp256k1: { secp256k1: {
oid: util.bin2str([0x2B, 0x81, 0x04, 0x00, 0x0A]), oid: util.bin2str([0x2B, 0x81, 0x04, 0x00, 0x0A]),
bits: 256, curveName: 'SECP-256K1',
hashName: 'SHA-256',
hash: enums.hash.sha256, hash: enums.hash.sha256,
cipher: enums.symmetric.aes128, cipher: enums.symmetric.aes128,
nist: false
} }
}; };
function Curve(name, {oid, hash, cipher}) { function Curve(name, {oid, hash, cipher, curveName, hashName, nist}) {
this.curve = new EC(name); this.curve = new EC(name);
this.name = name; this.name = name;
this.oid = oid; this.oid = oid;
this.hash = hash; this.hash = hash;
this.cipher = cipher; this.cipher = cipher;
this.curveName= curveName;
this.hashName = hashName;
this.nist = nist;
} }
Curve.prototype.keyFromPrivate = function (priv) { Curve.prototype.keyFromPrivate = function (priv) {
@ -91,7 +102,10 @@ function get(oid_or_name) {
return new Curve(name, { return new Curve(name, {
oid: curves[name].oid, oid: curves[name].oid,
hash: curves[name].hash, hash: curves[name].hash,
cipher: curves[name].cipher cipher: curves[name].cipher,
curveName: curves[name].curveName,
hashName: curves[name].hashName,
nist: curves[name].nist
}); });
} }
} }
@ -104,8 +118,8 @@ function generate(curve) {
var keyPair = curve.genKeyPair(); var keyPair = curve.genKeyPair();
resolve({ resolve({
oid: curve.oid, oid: curve.oid,
R: new BigInteger(keyPair.getPublic()), Q: new BigInteger(keyPair.getPublic()),
r: new BigInteger(keyPair.getPrivate()), d: new BigInteger(keyPair.getPrivate()),
hash: curve.hash, hash: curve.hash,
cipher: curve.cipher cipher: curve.cipher
}); });

View File

@ -73,18 +73,18 @@ function kdf(hash_algo, X, length, param) {
* @param {Enums} cipher_algo Symmetric cipher to use * @param {Enums} cipher_algo Symmetric cipher to use
* @param {Enums} hash_algo Hash to use * @param {Enums} hash_algo Hash to use
* @param {Uint8Array} m Value derived from session key (RFC 6637) * @param {Uint8Array} m Value derived from session key (RFC 6637)
* @param {BigInteger} R Recipient public key * @param {BigInteger} Q Recipient public key
* @param {String} fingerprint Recipient fingerprint * @param {String} fingerprint Recipient fingerprint
* @return {{V: BigInteger, C: Uint8Array}} Returns ephemeral key and encoded session key * @return {{V: BigInteger, C: Uint8Array}} Returns ephemeral key and encoded session key
*/ */
function encrypt(oid, cipher_algo, hash_algo, m, R, fingerprint) { function encrypt(oid, cipher_algo, hash_algo, m, Q, fingerprint) {
fingerprint = util.hex2Uint8Array(fingerprint); fingerprint = util.hex2Uint8Array(fingerprint);
const param = buildEcdhParam(enums.publicKey.ecdh, oid, cipher_algo, hash_algo, fingerprint); const param = buildEcdhParam(enums.publicKey.ecdh, oid, cipher_algo, hash_algo, fingerprint);
const curve = curves.get(oid); const curve = curves.get(oid);
cipher_algo = enums.read(enums.symmetric, cipher_algo); cipher_algo = enums.read(enums.symmetric, cipher_algo);
const v = curve.genKeyPair(); const v = curve.genKeyPair();
R = curve.keyFromPublic(R.toByteArray()); Q = curve.keyFromPublic(Q.toByteArray());
const S = v.derive(R); const S = v.derive(Q);
const Z = kdf(hash_algo, S, cipher[cipher_algo].keySize, param); const Z = kdf(hash_algo, S, cipher[cipher_algo].keySize, param);
const C = aes_kw.wrap(Z, m.toBytes()); const C = aes_kw.wrap(Z, m.toBytes());
return { return {
@ -101,18 +101,18 @@ function encrypt(oid, cipher_algo, hash_algo, m, R, fingerprint) {
* @param {Enums} hash_algo Hash algorithm to use * @param {Enums} hash_algo Hash algorithm to use
* @param {BigInteger} V Public part of ephemeral key * @param {BigInteger} V Public part of ephemeral key
* @param {Uint8Array} C Encrypted and wrapped value derived from session key * @param {Uint8Array} C Encrypted and wrapped value derived from session key
* @param {BigInteger} r Recipient private key * @param {BigInteger} d Recipient private key
* @param {String} fingerprint Recipient fingerprint * @param {String} fingerprint Recipient fingerprint
* @return {Uint8Array} Value derived from session * @return {Uint8Array} Value derived from session
*/ */
function decrypt(oid, cipher_algo, hash_algo, V, C, r, fingerprint) { function decrypt(oid, cipher_algo, hash_algo, V, C, d, fingerprint) {
fingerprint = util.hex2Uint8Array(fingerprint); fingerprint = util.hex2Uint8Array(fingerprint);
const param = buildEcdhParam(enums.publicKey.ecdh, oid, cipher_algo, hash_algo, fingerprint); const param = buildEcdhParam(enums.publicKey.ecdh, oid, cipher_algo, hash_algo, fingerprint);
const curve = curves.get(oid); const curve = curves.get(oid);
cipher_algo = enums.read(enums.symmetric, cipher_algo); cipher_algo = enums.read(enums.symmetric, cipher_algo);
V = curve.keyFromPublic(V.toByteArray()); V = curve.keyFromPublic(V.toByteArray());
r = curve.keyFromPrivate(r.toByteArray()); d = curve.keyFromPrivate(d.toByteArray());
const S = r.derive(V); const S = d.derive(V);
const Z = kdf(hash_algo, S, cipher[cipher_algo].keySize, param); const Z = kdf(hash_algo, S, cipher[cipher_algo].keySize, param);
return new BigInteger(aes_kw.unwrap(Z, C)); return new BigInteger(aes_kw.unwrap(Z, C));
} }

View File

@ -31,14 +31,15 @@ import BigInteger from '../jsbn.js';
/** /**
* Sign a message using the provided key * Sign a message using the provided key
* @param {String} oid Elliptic curve for the key * @param {String} oid Elliptic curve for the key
* @param {BigInteger} Q Public key used to sign
* @param {enums.hash} hash_algo Hash algorithm used to sign * @param {enums.hash} hash_algo Hash algorithm used to sign
* @param {Uint8Array} m Message to sign * @param {Uint8Array} m Message to sign
* @param {BigInteger} w Private key used to sign * @param {BigInteger} d Private key used to sign
* @return {{r: BigInteger, s: BigInteger}} Signature of the message * @return {{r: BigInteger, s: BigInteger}} Signature of the message
*/ */
function sign(oid, hash_algo, m, w) { function sign(oid, hash_algo, m, d) {
const curve = curves.get(oid); const curve = curves.get(oid);
const key = curve.keyFromPrivate(w.toByteArray()); const key = curve.keyFromPrivate(d.toByteArray());
const signature = key.sign(m, hash_algo); const signature = key.sign(m, hash_algo);
return { return {
r: new BigInteger(signature.r), r: new BigInteger(signature.r),
@ -52,11 +53,11 @@ function sign(oid, hash_algo, m, w) {
* @param {enums.hash} hash_algo Hash algorithm used in the signature * @param {enums.hash} hash_algo Hash algorithm used in the signature
* @param {{r: BigInteger, s: BigInteger}} signature Signature to verify * @param {{r: BigInteger, s: BigInteger}} signature Signature to verify
* @param {Uint8Array} m Message to verify * @param {Uint8Array} m Message to verify
* @param {BigInteger} gw Public key used to verify the message * @param {BigInteger} Q Public key used to verify the message
*/ */
function verify(oid, hash_algo, signature, m, gw) { function verify(oid, hash_algo, signature, m, Q) {
const curve = curves.get(oid); const curve = curves.get(oid);
const key = curve.keyFromPublic(gw.toByteArray()); const key = curve.keyFromPublic(Q.toByteArray());
return key.verify(m, {r: signature.r.toByteArray(), s: signature.s.toByteArray()}, hash_algo); return key.verify(m, {r: signature.r.toByteArray(), s: signature.s.toByteArray()}, hash_algo);
} }

View File

@ -63,8 +63,8 @@ export default {
const r = msg_MPIs[0].toBigInteger(); const r = msg_MPIs[0].toBigInteger();
const s = msg_MPIs[1].toBigInteger(); const s = msg_MPIs[1].toBigInteger();
m = data; m = data;
const gw = publickey_MPIs[1].toBigInteger(); const Q = publickey_MPIs[1].toBigInteger();
return ecdsa.verify(curve.oid, hash_algo, {r: r, s: s}, m, gw); return ecdsa.verify(curve.oid, hash_algo, {r: r, s: s}, m, Q);
default: default:
throw new Error('Invalid signature algorithm.'); throw new Error('Invalid signature algorithm.');
} }
@ -74,10 +74,7 @@ export default {
* Create a signature on data using the specified algorithm * Create a signature on data using the specified algorithm
* @param {module:enums.hash} hash_algo hash Algorithm to use (See {@link http://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4}) * @param {module:enums.hash} hash_algo hash Algorithm to use (See {@link http://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4})
* @param {module:enums.publicKey} algo Asymmetric cipher algorithm to use (See {@link http://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1}) * @param {module:enums.publicKey} algo Asymmetric cipher algorithm to use (See {@link http://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1})
* @param {Array<module:type/mpi>} publicMPIs Public key multiprecision integers * @param {Array<module:type/mpi>} publicMPIs Public followed by Private key multiprecision algorithm-specific parameters
* of the private key
* @param {Array<module:type/mpi>} secretMPIs Private key multiprecision
* integers which is used to sign the data
* @param {Uint8Array} data Data to be signed * @param {Uint8Array} data Data to be signed
* @return {Array<module:type/mpi>} * @return {Array<module:type/mpi>}
*/ */
@ -86,6 +83,7 @@ export default {
data = util.Uint8Array2str(data); data = util.Uint8Array2str(data);
var m; var m;
var d;
switch (algo) { switch (algo) {
case 1: case 1:
@ -95,7 +93,7 @@ export default {
case 3: case 3:
// RSA Sign-Only [HAC] // RSA Sign-Only [HAC]
var rsa = new publicKey.rsa(); var rsa = new publicKey.rsa();
var d = keyIntegers[2].toBigInteger(); d = keyIntegers[2].toBigInteger();
var n = keyIntegers[0].toBigInteger(); var n = keyIntegers[0].toBigInteger();
m = pkcs1.emsa.encode(hash_algo, m = pkcs1.emsa.encode(hash_algo,
data, keyIntegers[0].byteLength()); data, keyIntegers[0].byteLength());
@ -111,7 +109,6 @@ export default {
var x = keyIntegers[4].toBigInteger(); var x = keyIntegers[4].toBigInteger();
m = data; m = data;
var result = dsa.sign(hash_algo, m, g, p, q, x); var result = dsa.sign(hash_algo, m, g, p, q, x);
return util.str2Uint8Array(result[0].toString() + result[1].toString()); return util.str2Uint8Array(result[0].toString() + result[1].toString());
case 16: case 16:
// Elgamal (Encrypt-Only) [ELGAMAL] [HAC] // Elgamal (Encrypt-Only) [ELGAMAL] [HAC]
@ -119,11 +116,11 @@ export default {
case 19: case 19:
// ECDSA // ECDSA
const ecdsa = publicKey.elliptic.ecdsa; var ecdsa = publicKey.elliptic.ecdsa;
const curve = keyIntegers[0]; var curve = keyIntegers[0];
const w = keyIntegers[2].toBigInteger(); d = keyIntegers[2].toBigInteger();
m = data; m = data;
const signature = ecdsa.sign(curve.oid, hash_algo, m, w); const signature = ecdsa.sign(curve.oid, hash_algo, m, d);
return util.str2Uint8Array(signature.r.toMPI() + signature.s.toMPI()); return util.str2Uint8Array(signature.r.toMPI() + signature.s.toMPI());
default: default: