From 35f18444b058c4117838491344193819ee9600b4 Mon Sep 17 00:00:00 2001 From: Mahrud Sayrafi Date: Thu, 4 Jan 2018 01:43:08 -0800 Subject: [PATCH] keygen and sign/verify with ed25519 works --- src/crypto/crypto.js | 5 +- src/crypto/public_key/elliptic/curves.js | 160 +++++++++++++---------- src/crypto/public_key/elliptic/ecdsa.js | 30 +++-- src/crypto/public_key/elliptic/eddsa.js | 50 +++++++ src/crypto/public_key/elliptic/index.js | 11 +- src/crypto/public_key/elliptic/key.js | 23 ++-- src/crypto/signature.js | 35 ++++- src/enums.js | 34 ++++- src/openpgp.js | 6 +- src/packet/signature.js | 4 +- 10 files changed, 252 insertions(+), 106 deletions(-) create mode 100644 src/crypto/public_key/elliptic/eddsa.js diff --git a/src/crypto/crypto.js b/src/crypto/crypto.js index 92178491..4c832726 100644 --- a/src/crypto/crypto.js +++ b/src/crypto/crypto.js @@ -183,6 +183,7 @@ export default { return ['mpi']; case 'ecdh': case 'ecdsa': + case 'eddsa': // Algorithm-Specific Fields for ECDSA or ECDH secret keys: // - MPI of an integer representing the secret key. return ['mpi']; @@ -217,10 +218,11 @@ export default { // - MPI of DSA public-key value y (= g**x mod p where x is secret). case 'dsa': return ['mpi', 'mpi', 'mpi', 'mpi']; - // Algorithm-Specific Fields for ECDSA public keys: + // Algorithm-Specific Fields for ECDSA/EdDSA public keys: // - OID of curve; // - MPI of EC point representing public key. case 'ecdsa': + case 'eddsa': return ['oid', 'mpi']; // Algorithm-Specific Fields for ECDH public keys: // - OID of curve; @@ -279,6 +281,7 @@ export default { }); case 'ecdsa': + case 'eddsa': return publicKey.elliptic.generate(curve).then(function (keyObject) { return constructParams([keyObject.oid, keyObject.Q, keyObject.d], types); }); diff --git a/src/crypto/public_key/elliptic/curves.js b/src/crypto/public_key/elliptic/curves.js index 4d03e045..16ec7f53 100644 --- a/src/crypto/public_key/elliptic/curves.js +++ b/src/crypto/public_key/elliptic/curves.js @@ -27,118 +27,144 @@ 'use strict'; -import {ec as EC} from 'elliptic'; -import {KeyPair} from './key.js'; -import BigInteger from '../jsbn.js'; +import { ec as EC, eddsa as EdDSA } from 'elliptic'; +import { KeyPair } from './key'; +import BigInteger from '../jsbn'; +import random from '../../random'; import config from '../../../config'; -import enums from '../../../enums.js'; -import util from '../../../util.js'; -import base64 from '../../../encoding/base64.js'; +import enums from '../../../enums'; +import util from '../../../util'; +import base64 from '../../../encoding/base64'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); -var webCurves = [], nodeCurves = []; +var webCurves = {}, nodeCurves = {}; if (webCrypto && config.use_native) { - // see https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API/Supported_algorithms - webCurves = ['P-256', 'P-384', 'P-521']; + webCurves = { + 'p256': 'P-256', + 'p384': 'P-384', + 'p521': 'P-521' + }; } else if (nodeCrypto && config.use_native) { - // FIXME make sure the name translations are correct - nodeCurves = nodeCrypto.getCurves(); + var knownCurves = nodeCrypto.getCurves(); + nodeCurves = { + 'secp256k1': knownCurves.includes('secp256k1') ? 'secp256k1' : undefined, + 'p256': knownCurves.includes('prime256v1') ? 'prime256v1' : undefined, + 'p384': knownCurves.includes('secp384r1') ? 'secp384r1' : undefined, + 'p521': knownCurves.includes('secp521r1') ? 'secp521r1' : undefined + // TODO add more here + }; } const curves = { p256: { oid: util.bin2str([0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07]), - pointSize: 66, // FIXME - namedCurve: 'P-256', - opensslCurve: 'prime256v1', - hashName: 'SHA-256', hash: enums.hash.sha256, cipher: enums.symmetric.aes128, - node: nodeCurves.includes('prime256v1'), - web: webCurves.includes('P-256') + node: nodeCurves.secp256r1, + web: webCurves.secp256r1, + payloadSize: 32 }, p384: { oid: util.bin2str([0x2B, 0x81, 0x04, 0x00, 0x22]), - pointSize: 48, - namedCurve: 'P-384', - opensslCurve: 'secp384r1', // FIXME - hashName: 'SHA-384', hash: enums.hash.sha384, cipher: enums.symmetric.aes192, - node: nodeCurves.includes('secp384r1'), // FIXME - web: webCurves.includes('P-384') + node: nodeCurves.secp384r1, + web: webCurves.secp384r1, + payloadSize: 48 }, p521: { oid: util.bin2str([0x2B, 0x81, 0x04, 0x00, 0x23]), - pointSize: 66, - namedCurve: 'P-521', - opensslCurve: 'secp521r1', // FIXME - hashName: 'SHA-512', hash: enums.hash.sha512, cipher: enums.symmetric.aes256, - node: nodeCurves.includes('secp521r1'), // FIXME - web: webCurves.includes('P-521') + node: nodeCurves.secp521r1, + web: webCurves.secp521r1, + payloadSize: 66 }, secp256k1: { oid: util.bin2str([0x2B, 0x81, 0x04, 0x00, 0x0A]), - pointSize: 66, // FIXME - namedCurve: 'SECP-256K1', - opensslCurve: 'secp256k1', - hashName: 'SHA-256', hash: enums.hash.sha256, cipher: enums.symmetric.aes128, - node: false, // FIXME nodeCurves.includes('secp256k1'), - // this is because jwk-to-pem does not support this curve. - web: false + node: false // FIXME when we replace jwk-to-pem or it supports this curve }, - curve25519 : {}, - ed25519 : {} + ed25519: { + oid: util.bin2str([0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01]), + hash: enums.hash.sha512, + keyType: enums.publicKey.eddsa + }, + curve25519: { + oid: util.bin2str([0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01]), + hash: enums.hash.sha256, + cipher: enums.symmetric.aes128 + }, + brainpoolP256r1: { // TODO 1.3.36.3.3.2.8.1.1.7 + oid: util.bin2str([0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07]) + }, + brainpoolP512r1: { // TODO 1.3.36.3.3.2.8.1.1.13 + oid: util.bin2str([0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D]) + } }; -function Curve(name, {oid, pointSize, hash, cipher, namedCurve, opensslCurve, hashName, node, web}) { - this.curve = new EC(name); - this.name = name; - this.oid = oid; - this.pointSize = pointSize; - this.hash = hash; - this.cipher = cipher; - this.namedCurve= namedCurve; - this.opensslCurve = opensslCurve; - this.hashName = hashName; - this.node = node; - this.web = web; +function Curve(name, params) { + if (params.keyType === enums.publicKey.eddsa) { + this.curve = new EdDSA(name); + this.keyType = enums.publicKey.eddsa; + } else { + this.curve = new EC(name); + this.keyType = enums.publicKey.ecdsa; + } + this.oid = curves[name].oid; + this.hash = params.hash; + this.cipher = params.cipher; + this.node = params.node && curves[name].node; + this.web = params.web && curves[name].web; + this.payloadSize = curves[name].payloadSize; } -Curve.prototype.keyFromPrivate = function (priv) { - return new KeyPair(this.curve, {priv: priv}); +Curve.prototype.keyFromPrivate = function (priv) { // Not for ed25519 + return new KeyPair(this.curve, { priv: priv }); +}; + +Curve.prototype.keyFromSecret = function (secret) { // Only for ed25519 + return new KeyPair(this.curve, { secret: secret }); }; Curve.prototype.keyFromPublic = function (pub) { - return new KeyPair(this.curve, {pub: pub}); + return new KeyPair(this.curve, { pub: pub }); }; Curve.prototype.genKeyPair = async function () { - var keyPair; + var r, keyPair; if (webCrypto && config.use_native && this.web) { - keyPair = await webGenKeyPair(this.namedCurve, "ECDSA"); // FIXME + keyPair = await webGenKeyPair(this.name, "ECDSA"); // FIXME is ECDH different? } else if (nodeCrypto && config.use_native && this.node) { - keyPair = await nodeGenKeyPair(this.opensslCurve); + keyPair = await nodeGenKeyPair(this.name); } else { - var r = this.curve.genKeyPair(); - keyPair = { - pub: r.getPublic().encode(), - priv: r.getPrivate().toArray() - }; + if (this.keyType === enums.publicKey.eddsa) { + keyPair = { + secret: util.hexidump(random.getRandomBytes(32)) + }; + } else { + r = this.curve.genKeyPair(); + keyPair = { + pub: r.getPublic().encode(), + priv: r.getPrivate().toArray() + }; + } } return new KeyPair(this.curve, keyPair); }; function get(oid_or_name) { - for (var name in curves) { - if (curves[name].oid === oid_or_name || name === oid_or_name) { + var name; + if (enums.curve[oid_or_name]) { + name = enums.write(enums.curve, oid_or_name); + return new Curve(name, curves[name]); + } + for (name in curves) { + if (curves[name].oid === oid_or_name) { return new Curve(name, curves[name]); } } @@ -171,11 +197,11 @@ module.exports = { ////////////////////////// -async function webGenKeyPair(namedCurve, algorithm) { +async function webGenKeyPair(name, algorithm) { var webCryptoKey = await webCrypto.generateKey( { name: algorithm === "ECDH" ? "ECDH" : "ECDSA", - namedCurve: namedCurve + namedCurve: webCurves[name] }, true, algorithm === "ECDH" ? ["deriveKey", "deriveBits"] : ["sign", "verify"] @@ -193,8 +219,8 @@ async function webGenKeyPair(namedCurve, algorithm) { }; } -async function nodeGenKeyPair(opensslCurve) { - var ecdh = nodeCrypto.createECDH(opensslCurve); +async function nodeGenKeyPair(name) { + var ecdh = nodeCrypto.createECDH(name === "secp256r1" ? "prime256v1" : name); await ecdh.generateKeys(); return { diff --git a/src/crypto/public_key/elliptic/ecdsa.js b/src/crypto/public_key/elliptic/ecdsa.js index dd75150b..23c60860 100644 --- a/src/crypto/public_key/elliptic/ecdsa.js +++ b/src/crypto/public_key/elliptic/ecdsa.js @@ -37,7 +37,9 @@ import util from '../../../util.js'; import base64 from '../../../encoding/base64.js'; const webCrypto = util.getWebCrypto(); +const webCurves = curves.webCurves; const nodeCrypto = util.getNodeCrypto(); +const nodeCurves = curves.nodeCurves; var ECDSASignature = ASN1.define('ECDSASignature', function() { this.seq().obj( @@ -67,8 +69,8 @@ async function sign(oid, hash_algo, m, d) { signature = await key.sign(m, hash_algo); } return { - r: new BigInteger(signature.r), - s: new BigInteger(signature.s) + r: new BigInteger(signature.r.toArray()), + s: new BigInteger(signature.s.toArray()) }; } @@ -112,7 +114,7 @@ module.exports = { async function webSign(curve, hash_algo, message, keyPair) { - var l = curve.pointSize; + var l = curve.payloadSize; if (typeof message === 'string') { message = util.str2Uint8Array(message); } @@ -120,7 +122,7 @@ async function webSign(curve, hash_algo, message, keyPair) { "jwk", { "kty": "EC", - "crv": curve.namedCurve, + "crv": webCurves[curve.name], "x": base64.encode(new Uint8Array(keyPair.getPublic().getX().toArray('be', l)), null, 'base64url'), "y": base64.encode(new Uint8Array(keyPair.getPublic().getY().toArray('be', l)), null, 'base64url'), "d": base64.encode(new Uint8Array(keyPair.getPrivate().toArray('be', l)), null, 'base64url'), @@ -129,8 +131,8 @@ async function webSign(curve, hash_algo, message, keyPair) { }, { "name": "ECDSA", - "namedCurve": curve.namedCurve, - "hash": { name: curve.hashName } + "namedCurve": webCurves[curve.name], + "hash": { name: enums.read(enums.webHash, curve.hash) } }, false, ["sign"] @@ -139,7 +141,7 @@ async function webSign(curve, hash_algo, message, keyPair) { const signature = new Uint8Array(await webCrypto.sign( { "name": 'ECDSA', - "namedCurve": curve.namedCurve, + "namedCurve": webCurves[curve.name], "hash": { name: enums.read(enums.webHash, hash_algo) } }, key, @@ -152,7 +154,7 @@ async function webSign(curve, hash_algo, message, keyPair) { } async function webVerify(curve, hash_algo, signature, message, publicKey) { - var r = signature.r.toByteArray(), s = signature.s.toByteArray(), l = curve.pointSize; + var r = signature.r.toByteArray(), s = signature.s.toByteArray(), l = curve.payloadSize; r = (r.length === l) ? r : [0].concat(r); s = (s.length === l) ? s : [0].concat(s); signature = new Uint8Array(r.concat(s)).buffer; @@ -163,7 +165,7 @@ async function webVerify(curve, hash_algo, signature, message, publicKey) { "jwk", { "kty": "EC", - "crv": curve.namedCurve, + "crv": webCurves[curve.name], "x": base64.encode(new Uint8Array(publicKey.getX().toArray('be', l)), null, 'base64url'), "y": base64.encode(new Uint8Array(publicKey.getY().toArray('be', l)), null, 'base64url'), "use": "sig", @@ -171,8 +173,8 @@ async function webVerify(curve, hash_algo, signature, message, publicKey) { }, { "name": "ECDSA", - "namedCurve": curve.namedCurve, - "hash": { name: curve.hashName } + "namedCurve": webCurves[curve.name], + "hash": { name: enums.read(enums.webHash, curve.hash) } }, false, ["verify"] @@ -181,7 +183,7 @@ async function webVerify(curve, hash_algo, signature, message, publicKey) { return webCrypto.verify( { "name": 'ECDSA', - "namedCurve": curve.namedCurve, + "namedCurve": webCurves[curve.name], "hash": { name: enums.read(enums.webHash, hash_algo) } }, key, @@ -198,7 +200,7 @@ async function nodeSign(curve, hash_algo, message, keyPair) { const key = jwkToPem( { "kty": "EC", - "crv": curve.namedCurve, + "crv": nodeCurves[curve.name], "x": base64.encode(new Uint8Array(keyPair.getPublic().getX().toArray())), "y": base64.encode(new Uint8Array(keyPair.getPublic().getY().toArray())), "d": base64.encode(new Uint8Array(keyPair.getPrivate().toArray())), @@ -231,7 +233,7 @@ async function nodeVerify(curve, hash_algo, signature, message, publicKey) { const key = jwkToPem( { "kty": "EC", - "crv": curve.namedCurve, + "crv": nodeCurves[curve.name], "x": base64.encode(new Uint8Array(publicKey.getX().toArray())), "y": base64.encode(new Uint8Array(publicKey.getY().toArray())), "use": "sig", diff --git a/src/crypto/public_key/elliptic/eddsa.js b/src/crypto/public_key/elliptic/eddsa.js new file mode 100644 index 00000000..3309979e --- /dev/null +++ b/src/crypto/public_key/elliptic/eddsa.js @@ -0,0 +1,50 @@ +// Implementation of EdDSA for OpenPGP + +'use strict'; + +import curves from './curves.js'; +import BigInteger from '../jsbn.js'; + +/** + * Sign a message using the provided key + * @param {String} oid Elliptic curve for the key + * @param {enums.hash} hash_algo Hash algorithm used to sign + * @param {Uint8Array} m Message to sign + * @param {BigInteger} d Private key used to sign + * @return {{r: BigInteger, s: BigInteger}} Signature of the message + */ +async function sign(oid, hash_algo, m, d) { + var signature; + const curve = curves.get(oid); + hash_algo = hash_algo ? hash_algo : curve.hash; + const key = curve.keyFromSecret(d.toByteArray()); + signature = await key.sign(m, hash_algo); + return { + r: new BigInteger(signature.Rencoded()), + s: new BigInteger(signature.Sencoded()) + }; +} + +/** + * Verifies if a signature is valid for a message + * @param {String} oid Elliptic curve for the key + * @param {enums.hash} hash_algo Hash algorithm used in the signature + * @param {{r: BigInteger, s: BigInteger}} signature Signature to verify + * @param {Uint8Array} m Message to verify + * @param {BigInteger} Q Public key used to verify the message + * @return {Boolean} + */ +async function verify(oid, hash_algo, signature, m, Q) { + var result; + const curve = curves.get(oid); + hash_algo = hash_algo ? hash_algo : curve.hash; // FIXME is this according to the RFC? + const key = curve.keyFromPublic(Q.toByteArray()); + return key.verify( + m, {R: signature.r.toByteArray(), S: signature.s.toByteArray()}, hash_algo + ); +} + +module.exports = { + sign: sign, + verify: verify +}; diff --git a/src/crypto/public_key/elliptic/index.js b/src/crypto/public_key/elliptic/index.js index f6acefb1..f4a5cc47 100644 --- a/src/crypto/public_key/elliptic/index.js +++ b/src/crypto/public_key/elliptic/index.js @@ -21,18 +21,21 @@ * @requires crypto/public_key/elliptic/curve * @requires crypto/public_key/elliptic/ecdh * @requires crypto/public_key/elliptic/ecdsa + * @requires crypto/public_key/elliptic/eddsa * @module crypto/public_key/elliptic */ 'use strict'; -import {get, generate} from './curves.js'; -import ecdh from './ecdh.js'; -import ecdsa from './ecdsa.js'; +import {get, generate} from './curves'; +import ecdsa from './ecdsa'; +import eddsa from './eddsa'; +import ecdh from './ecdh'; module.exports = { - ecdh: ecdh, ecdsa: ecdsa, + eddsa: eddsa, + ecdh: ecdh, get: get, generate: generate }; diff --git a/src/crypto/public_key/elliptic/key.js b/src/crypto/public_key/elliptic/key.js index 875a62f5..66a21c35 100644 --- a/src/crypto/public_key/elliptic/key.js +++ b/src/crypto/public_key/elliptic/key.js @@ -26,10 +26,12 @@ 'use strict'; import hash from '../../hash'; -import util from '../../../util.js'; +import util from '../../../util'; +import enums from '../../../enums'; function KeyPair(curve, options) { this.curve = curve; + this.keyType = curve.curve.type === 'edwards' ? enums.publicKey.eddsa : enums.publicKey.ecdsa; this.keyPair = this.curve.keyPair(options); } @@ -38,11 +40,7 @@ KeyPair.prototype.sign = function (message, hash_algo) { message = util.str2Uint8Array(message); } const digest = (typeof hash_algo === 'undefined') ? message : hash.digest(hash_algo, message); - const signature = this.keyPair.sign(digest); - return { - r: signature.r.toArray(), - s: signature.s.toArray() - }; + return this.keyPair.sign(digest); }; KeyPair.prototype.verify = function (message, signature, hash_algo) { @@ -54,18 +52,25 @@ KeyPair.prototype.verify = function (message, signature, hash_algo) { }; KeyPair.prototype.derive = function (pub) { + if (this.keyType === enums.publicKey.eddsa) { + throw new Error('Key can only be used for EdDSA'); + } return this.keyPair.derive(pub.keyPair.getPublic()).toArray(); }; KeyPair.prototype.getPublic = function () { - return this.keyPair.getPublic().encode(); + return this.keyPair.getPublic('array'); }; KeyPair.prototype.getPrivate = function () { - return this.keyPair.getPrivate().toArray(); + if (this.keyType === enums.publicKey.eddsa) { + return this.keyPair.getSecret(); + } else { + return this.keyPair.getPrivate().toArray(); + } }; -KeyPair.prototype.isValid = function () { +KeyPair.prototype.isValid = function () { // FIXME return this.keyPair.validate().result; }; diff --git a/src/crypto/signature.js b/src/crypto/signature.js index 13bb3ba4..d30d87c3 100644 --- a/src/crypto/signature.js +++ b/src/crypto/signature.js @@ -23,6 +23,10 @@ export default { */ verify: async function(algo, hash_algo, msg_MPIs, publickey_MPIs, data) { var m; + var r; + var s; + var Q; + var curve; data = util.Uint8Array2str(data); @@ -59,12 +63,21 @@ export default { case 19: // ECDSA const ecdsa = publicKey.elliptic.ecdsa; - const curve = publickey_MPIs[0]; - const r = msg_MPIs[0].toBigInteger(); - const s = msg_MPIs[1].toBigInteger(); + curve = publickey_MPIs[0]; + r = msg_MPIs[0].toBigInteger(); + s = msg_MPIs[1].toBigInteger(); m = data; - const Q = publickey_MPIs[1].toBigInteger(); + Q = publickey_MPIs[1].toBigInteger(); return ecdsa.verify(curve.oid, hash_algo, {r: r, s: s}, m, Q); + case 22: + // EdDSA + const eddsa = publicKey.elliptic.eddsa; + curve = publickey_MPIs[0]; + r = msg_MPIs[0].toBigInteger(); + s = msg_MPIs[1].toBigInteger(); + m = data; + Q = publickey_MPIs[1].toBigInteger(); + return eddsa.verify(curve.oid, hash_algo, {r: r, s: s}, m, Q); default: throw new Error('Invalid signature algorithm.'); } @@ -84,6 +97,8 @@ export default { var m; var d; + var curve; + var signature; switch (algo) { case 1: @@ -117,10 +132,18 @@ export default { case 19: // ECDSA var ecdsa = publicKey.elliptic.ecdsa; - var curve = keyIntegers[0]; + curve = keyIntegers[0]; d = keyIntegers[2].toBigInteger(); m = data; - const signature = await ecdsa.sign(curve.oid, hash_algo, m, d); + signature = await ecdsa.sign(curve.oid, hash_algo, m, d); + return util.str2Uint8Array(signature.r.toMPI() + signature.s.toMPI()); + case 22: + // EdDSA + var eddsa = publicKey.elliptic.eddsa; + curve = keyIntegers[0]; + d = keyIntegers[2].toBigInteger(); + m = data; + signature = await eddsa.sign(curve.oid, hash_algo, m, d); return util.str2Uint8Array(signature.r.toMPI() + signature.s.toMPI()); default: diff --git a/src/enums.js b/src/enums.js index a043429b..c4bf3651 100644 --- a/src/enums.js +++ b/src/enums.js @@ -6,6 +6,37 @@ export default { + /** Maps curve names under various standards to one + * @enum {String} + * @readonly + */ + curve: { + "p256": "p256", + "P-256": "p256", + "secp256r1": "p256", + "prime256v1": "p256", + "1.2.840.10045.3.1.7": "p256", + + "p384": "p384", + "P-384": "p384", + "secp384r1": "p384", + "1.3.132.0.34": "p384", + + "p521": "p521", + "P-521": "p521", + "secp521r1": "p521", + "1.3.132.0.35": "p521", + + "secp256k1": "secp256k1", + "1.3.132.0.10": "secp256k1", + + "ed25519": "ed25519", + "1.3.6.1.4.1.11591.15.1": "ed25519", + + "curve25519": "curve25519", + "1.3.6.1.4.1.3029.1.5.1": "curve25519" + }, + /** A string to key specifier type * @enum {Integer} * @readonly @@ -28,7 +59,8 @@ export default { elgamal: 16, dsa: 17, ecdh: 18, - ecdsa: 19 + ecdsa: 19, + eddsa: 22 }, /** {@link http://tools.ietf.org/html/rfc4880#section-9.2|RFC4880, section 9.2} diff --git a/src/openpgp.js b/src/openpgp.js index c2aca38f..006e2ce3 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -89,7 +89,7 @@ export function destroyWorker() { /** - * Generates a new OpenPGP key pair. Currently only supports RSA keys. Primary and subkey will be of same type. + * Generates a new OpenPGP key pair. Supports RSA and ECC keys. Primary and subkey will be of same type. * @param {Array} userIds array of user IDs e.g. [{ name:'Phil Zimmermann', email:'phil@openpgp.org' }] * @param {String} passphrase (optional) The passphrase used to encrypt the resulting private key * @param {Number} numBits (optional) number of bits for the key creation. (should be 2048 or 4096) @@ -100,7 +100,7 @@ export function destroyWorker() { * @static */ -export function generateKey({ userIds=[], passphrase, numBits=2048, unlocked=false, keyExpirationTime=0, curve=""} = {}) { +export function generateKey({ userIds=[], passphrase, numBits=2048, unlocked=false, keyExpirationTime=0, curve="" } = {}) { userIds = formatUserIds(userIds); const options = {userIds, passphrase, numBits, unlocked, keyExpirationTime, curve}; @@ -338,7 +338,7 @@ export function sign({ data, privateKeys, armor=true, detached=false}) { * @param {CleartextMessage} message cleartext message object with signatures * @param {Signature} signature (optional) detached signature for verification * @return {Promise} cleartext with status of verified signatures in the form of: - * { data:String, signatures: [{ keyid:String, valid:Boolean }] } + * { data:String, signatures: [{ keyid:String, valid:Boolean }] } * @static */ export function verify({ message, publicKeys, signature=null }) { diff --git a/src/packet/signature.js b/src/packet/signature.js index cce0fd5c..291611aa 100644 --- a/src/packet/signature.js +++ b/src/packet/signature.js @@ -633,7 +633,9 @@ Signature.prototype.verify = async function (key, data) { // Algorithm-Specific Fields for DSA and ECDSA signatures: // - MPI of DSA value r. // - MPI of DSA value s. - else if (publicKeyAlgorithm === 17 || publicKeyAlgorithm === 19) { + else if (publicKeyAlgorithm === enums.publicKey.dsa || + publicKeyAlgorithm === enums.publicKey.ecdsa || + publicKeyAlgorithm === enums.publicKey.eddsa) { mpicount = 2; }