diff --git a/src/crypto/public_key/elliptic/curves.js b/src/crypto/public_key/elliptic/curves.js
index a4046bd9..2759661c 100644
--- a/src/crypto/public_key/elliptic/curves.js
+++ b/src/crypto/public_key/elliptic/curves.js
@@ -225,7 +225,7 @@ function getPreferredHashAlgo(oid) {
 }
 
 /**
- * Validate ECDH and EcDSA parameters
+ * Validate ECDH and ECDSA parameters
  * Not suitable for EdDSA (different secret key format)
  * @param {module:enums.publicKey} algo - EC algorithm, to filter supported curves
  * @param {module:type/oid} oid - EC object identifier
diff --git a/src/crypto/public_key/elliptic/ecdsa.js b/src/crypto/public_key/elliptic/ecdsa.js
index 099eeb95..40d2572a 100644
--- a/src/crypto/public_key/elliptic/ecdsa.js
+++ b/src/crypto/public_key/elliptic/ecdsa.js
@@ -117,10 +117,10 @@ export async function verify(oid, hashAlgo, signature, message, publicKey, hashe
 }
 
 /**
- * Validate EcDSA parameters
+ * Validate ECDSA parameters
  * @param {module:type/oid} oid - Elliptic curve object identifier
- * @param {Uint8Array} Q - EcDSA public point
- * @param {Uint8Array} d - EcDSA secret scalar
+ * @param {Uint8Array} Q - ECDSA public point
+ * @param {Uint8Array} d - ECDSA secret scalar
  * @returns {Promise<Boolean>} Whether params are valid.
  * @async
  */
diff --git a/src/key/factory.js b/src/key/factory.js
index d5670eeb..194be753 100644
--- a/src/key/factory.js
+++ b/src/key/factory.js
@@ -76,7 +76,7 @@ export async function generate(options, config) {
  * @param {Array<String|Object>} options.userIDs  User IDs as strings or objects: 'Jo Doe <info@jo.com>' or { name:'Jo Doe', email:'info@jo.com' }
  * @param {String} options.passphrase             Passphrase used to encrypt the resulting private key
  * @param {Number} options.keyExpirationTime      Number of seconds from the key creation time after which the key expires
- * @param {Date}   options.date                   Override the creation date of the key and the key signatures
+ * @param {Date}   options.date                   Override the creation date of the key signatures
  * @param {Array<Object>} options.subkeys         (optional) options for each subkey, default to main key options. e.g. [{sign: true, passphrase: '123'}]
  * @param {Object} config - Full configuration
  *
diff --git a/src/key/helper.js b/src/key/helper.js
index 505f875d..8e57e186 100644
--- a/src/key/helper.js
+++ b/src/key/helper.js
@@ -21,6 +21,7 @@ export async function generateSecretSubkey(options, config) {
   secretSubkeyPacket.packets = null;
   secretSubkeyPacket.algorithm = enums.read(enums.publicKey, options.algorithm);
   await secretSubkeyPacket.generate(options.rsaBits, options.curve);
+  await secretSubkeyPacket.computeFingerprintAndKeyID();
   return secretSubkeyPacket;
 }
 
@@ -29,6 +30,7 @@ export async function generateSecretKey(options, config) {
   secretKeyPacket.packets = null;
   secretKeyPacket.algorithm = enums.read(enums.publicKey, options.algorithm);
   await secretKeyPacket.generate(options.rsaBits, options.curve, options.config);
+  await secretKeyPacket.computeFingerprintAndKeyID();
   return secretKeyPacket;
 }
 
diff --git a/src/key/key.js b/src/key/key.js
index 5f900bcd..dc7b08fc 100644
--- a/src/key/key.js
+++ b/src/key/key.js
@@ -82,6 +82,9 @@ class Key {
           }
           this.keyPacket = packetlist[i];
           primaryKeyID = this.getKeyID();
+          if (!primaryKeyID) {
+            throw new Error('Missing Key ID');
+          }
           break;
         case enums.packet.userID:
         case enums.packet.userAttribute:
@@ -186,25 +189,22 @@ class Key {
 
   /**
    * Returns an array containing all public or private subkeys matching keyID;
-   * If keyID is not present, returns all subkeys.
-   * @param {type/keyid} keyID
-   * @returns {Array<SubKey>}
+   * If no keyID is given, returns all subkeys.
+   * @param {type/keyID} [keyID] - key ID to look for
+   * @returns {Array<SubKey>} array of subkeys
    */
   getSubkeys(keyID = null) {
-    const subKeys = [];
-    this.subKeys.forEach(subKey => {
-      if (!keyID || subKey.getKeyID().equals(keyID, true)) {
-        subKeys.push(subKey);
-      }
-    });
+    const subKeys = this.subKeys.filter(subKey => (
+      !keyID || subKey.getKeyID().equals(keyID, true)
+    ));
     return subKeys;
   }
 
   /**
    * Returns an array containing all public or private keys matching keyID.
-   * If keyID is not present, returns all keys starting with the primary key.
-   * @param {type/keyid} keyID
-   * @returns {Array<Key|SubKey>}
+   * If no keyID is given, returns all keys, starting with the primary key.
+   * @param {type/keyid~KeyID} [keyID] - key ID to look for
+   * @returns {Array<Key|SubKey>} array of keys
    */
   getKeys(keyID = null) {
     const keys = [];
@@ -250,31 +250,25 @@ class Key {
 
   /**
    * Returns key as public key (shallow copy)
-   * @param {Object} [config] - Full configuration, defaults to openpgp.config
-   * @returns {Key} New public Key.
+   * @returns {Key} New public Key
    */
   toPublic() {
     const packetlist = new PacketList();
     const keyPackets = this.toPacketList();
-    let bytes;
-    let pubKeyPacket;
-    let pubSubkeyPacket;
-    for (let i = 0; i < keyPackets.length; i++) {
-      switch (keyPackets[i].constructor.tag) {
-        case enums.packet.secretKey:
-          bytes = keyPackets[i].writePublicKey();
-          pubKeyPacket = new PublicKeyPacket();
-          pubKeyPacket.read(bytes);
+    for (const keyPacket of keyPackets) {
+      switch (keyPacket.constructor.tag) {
+        case enums.packet.secretKey: {
+          const pubKeyPacket = PublicKeyPacket.fromSecretKeyPacket(keyPacket);
           packetlist.push(pubKeyPacket);
           break;
-        case enums.packet.secretSubkey:
-          bytes = keyPackets[i].writePublicKey();
-          pubSubkeyPacket = new PublicSubkeyPacket();
-          pubSubkeyPacket.read(bytes);
+        }
+        case enums.packet.secretSubkey: {
+          const pubSubkeyPacket = PublicSubkeyPacket.fromSecretSubkeyPacket(keyPacket);
           packetlist.push(pubSubkeyPacket);
           break;
+        }
         default:
-          packetlist.push(keyPackets[i]);
+          packetlist.push(keyPacket);
       }
     }
     return new Key(packetlist);
@@ -827,7 +821,7 @@ class Key {
     const primaryKey = this.keyPacket;
     const { user } = await this.getPrimaryUser(date, userID, config);
     const results = keys ? await user.verifyAllCertifications(primaryKey, keys, undefined, config) :
-      [{ keyID: primaryKey.keyID, valid: await user.verify(primaryKey, undefined, config).catch(() => false) }];
+      [{ keyID: primaryKey.getKeyID(), valid: await user.verify(primaryKey, undefined, config).catch(() => false) }];
     return results;
   }
 
@@ -849,7 +843,7 @@ class Key {
     const primaryKey = this.keyPacket;
     await Promise.all(this.users.map(async function(user) {
       const signatures = keys ? await user.verifyAllCertifications(primaryKey, keys, undefined, config) :
-        [{ keyID: primaryKey.keyID, valid: await user.verify(primaryKey, undefined, config).catch(() => false) }];
+        [{ keyID: primaryKey.getKeyID(), valid: await user.verify(primaryKey, undefined, config).catch(() => false) }];
       signatures.forEach(signature => {
         results.push({
           userID: user.userID.userID,
diff --git a/src/message.js b/src/message.js
index 782a4835..345c7509 100644
--- a/src/message.js
+++ b/src/message.js
@@ -694,7 +694,7 @@ export async function createSignaturePackets(literalDataPacket, privateKeys, sig
 
 /**
  * Create object containing signer's keyID and validity of signature
- * @param {SignaturePacket} signature - Signature packets
+ * @param {SignaturePacket} signature - Signature packet
  * @param {Array<LiteralDataPacket>} literalDataList - Array of literal data packets
  * @param {Array<Key>} keys - Array of keys to verify signatures
  * @param {Date} date - Verify the signature against the given date,
diff --git a/src/openpgp.js b/src/openpgp.js
index 30219f65..5233fcdd 100644
--- a/src/openpgp.js
+++ b/src/openpgp.js
@@ -83,6 +83,7 @@ export function generateKey({ userIDs = [], passphrase = "", type = "ecc", rsaBi
  * @param {Object|Array<Object>} options.userIDs - User IDs as objects: `{ name: 'Jo Doe', email: 'info@jo.com' }`
  * @param {String} [options.passphrase=(not protected)] - The passphrase used to encrypt the generated private key
  * @param {Number} [options.keyExpirationTime=0 (never expires)] - Number of seconds from the key creation time after which the key expires
+ * @param {Date}   [options.date] - Override the creation date of the key signatures
  * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
  * @returns {Promise<Object>} The generated key object in the form:
  *                                     { key:Key, privateKeyArmored:String, publicKeyArmored:String, revocationCertificate:String }
diff --git a/src/packet/public_key.js b/src/packet/public_key.js
index 23b30945..b03d5d2b 100644
--- a/src/packet/public_key.js
+++ b/src/packet/public_key.js
@@ -17,8 +17,6 @@
 
 /* eslint class-methods-use-this: ["error", { "exceptMethods": ["isDecrypted"] }] */
 
-import { Sha1 } from '@openpgp/asmcrypto.js/dist_es8/hash/sha1/sha1';
-import { Sha256 } from '@openpgp/asmcrypto.js/dist_es8/hash/sha256/sha256';
 import KeyID from '../type/keyid';
 import defaultConfig from '../config';
 import crypto from '../crypto';
@@ -72,8 +70,8 @@ class PublicKeyPacket {
      */
     this.expirationTimeV3 = 0;
     /**
-     * Fingerprint in lowercase hex
-     * @type {String}
+     * Fingerprint bytes
+     * @type {Uint8Array}
      */
     this.fingerprint = null;
     /**
@@ -84,12 +82,30 @@ class PublicKeyPacket {
   }
 
   /**
-   * Internal Parser for public keys as specified in {@link https://tools.ietf.org/html/rfc4880#section-5.5.2|RFC 4880 section 5.5.2 Public-Key Packet Formats}
-   * called by read_tag&lt;num&gt;
-   * @param {Uint8Array} bytes - Input array to read the packet from
-   * @returns {Object} This object with attributes set by the parser.
+   * Create a PublicKeyPacket from a SecretKeyPacket
+   * @param {SecretKeyPacket} secretKeyPacket - key packet to convert
+   * @returns {PublicKeyPacket} public key packet
+   * @static
    */
-  read(bytes) {
+  static fromSecretKeyPacket(secretKeyPacket) {
+    const keyPacket = new PublicKeyPacket();
+    const { version, created, algorithm, publicParams, keyID, fingerprint } = secretKeyPacket;
+    keyPacket.version = version;
+    keyPacket.created = created;
+    keyPacket.algorithm = algorithm;
+    keyPacket.publicParams = publicParams;
+    keyPacket.keyID = keyID;
+    keyPacket.fingerprint = fingerprint;
+    return keyPacket;
+  }
+
+  /**
+   * Internal Parser for public keys as specified in {@link https://tools.ietf.org/html/rfc4880#section-5.5.2|RFC 4880 section 5.5.2 Public-Key Packet Formats}
+   * @param {Uint8Array} bytes - Input array to read the packet from
+   * @returns {Object} This object with attributes set by the parser
+   * @async
+   */
+  async read(bytes) {
     let pos = 0;
     // A one-octet version number (3, 4 or 5).
     this.version = bytes[pos++];
@@ -117,6 +133,8 @@ class PublicKeyPacket {
         throw new Error('Error reading MPIs');
       }
 
+      // we set the fingerprint and keyID already to make it possible to put together the key packets directly in the Key constructor
+      await this.computeFingerprintAndKeyID();
       return pos;
     }
     throw new Error('Version ' + this.version + ' of the key packet is unsupported.');
@@ -146,7 +164,8 @@ class PublicKeyPacket {
   }
 
   /**
-   * Write packet in order to be hashed; either for a signature or a fingerprint.
+   * Write packet in order to be hashed; either for a signature or a fingerprint
+   * @param {Integer} version - target version of signature or key
    */
   writeForHash(version) {
     const bytes = this.writePublicKey();
@@ -174,42 +193,56 @@ class PublicKeyPacket {
   }
 
   /**
-   * Calculates the key id of the key
-   * @returns {module:type/keyid~KeyID} A 8 byte key id.
+   * Return the key ID of the key
+   * @returns {module:type/keyid~KeyID} The 8-byte key ID
    */
   getKeyID() {
-    if (this.keyID) {
-      return this.keyID;
-    }
-    this.keyID = new KeyID();
-    if (this.version === 5) {
-      this.keyID.read(util.hexToUint8Array(this.getFingerprint()).subarray(0, 8));
-    } else if (this.version === 4) {
-      this.keyID.read(util.hexToUint8Array(this.getFingerprint()).subarray(12, 20));
-    }
     return this.keyID;
   }
 
   /**
-   * Calculates the fingerprint of the key
-   * @returns {Uint8Array} A Uint8Array containing the fingerprint.
+   * Computes and set the key ID and fingerprint of the key
+   * @async
+   */
+  async computeFingerprintAndKeyID() {
+    await this.computeFingerprint();
+    this.keyID = new KeyID();
+
+    if (this.version === 5) {
+      this.keyID.read(this.fingerprint.subarray(0, 8));
+    } else if (this.version === 4) {
+      this.keyID.read(this.fingerprint.subarray(12, 20));
+    } else {
+      throw new Error('Unsupported key version');
+    }
+  }
+
+  /**
+   * Computes and set the fingerprint of the key
+   */
+  async computeFingerprint() {
+    const toHash = this.writeForHash(this.version);
+
+    if (this.version === 5) {
+      this.fingerprint = await crypto.hash.sha256(toHash);
+    } else if (this.version === 4) {
+      this.fingerprint = await crypto.hash.sha1(toHash);
+    } else {
+      throw new Error('Unsupported key version');
+    }
+  }
+
+  /**
+   * Returns the fingerprint of the key, as an array of bytes
+   * @returns {Uint8Array} A Uint8Array containing the fingerprint
    */
   getFingerprintBytes() {
-    if (this.fingerprint) {
-      return this.fingerprint;
-    }
-    const toHash = this.writeForHash(this.version);
-    if (this.version === 5) {
-      this.fingerprint = Sha256.bytes(toHash);
-    } else if (this.version === 4) {
-      this.fingerprint = Sha1.bytes(toHash);
-    }
     return this.fingerprint;
   }
 
   /**
-   * Calculates the fingerprint of the key
-   * @returns {String} A string containing the fingerprint in lowercase hex.
+   * Calculates and returns the fingerprint of the key, as a string
+   * @returns {String} A string containing the fingerprint in lowercase hex
    */
   getFingerprint() {
     return util.uint8ArrayToHex(this.getFingerprintBytes());
diff --git a/src/packet/public_subkey.js b/src/packet/public_subkey.js
index eb7514a7..731fc222 100644
--- a/src/packet/public_subkey.js
+++ b/src/packet/public_subkey.js
@@ -39,6 +39,24 @@ class PublicSubkeyPacket extends PublicKeyPacket {
   constructor(date, config) {
     super(date, config);
   }
+
+  /**
+   * Create a PublicSubkeyPacket from a SecretSubkeyPacket
+   * @param {SecretSubkeyPacket} secretSubkeyPacket - subkey packet to convert
+   * @returns {SecretSubkeyPacket} public key packet
+   * @static
+   */
+  static fromSecretSubkeyPacket(secretSubkeyPacket) {
+    const keyPacket = new PublicSubkeyPacket();
+    const { version, created, algorithm, publicParams, keyID, fingerprint } = secretSubkeyPacket;
+    keyPacket.version = version;
+    keyPacket.created = created;
+    keyPacket.algorithm = algorithm;
+    keyPacket.publicParams = publicParams;
+    keyPacket.keyID = keyID;
+    keyPacket.fingerprint = fingerprint;
+    return keyPacket;
+  }
 }
 
 export default PublicSubkeyPacket;
diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js
index 49ecf0b6..76584b76 100644
--- a/src/packet/secret_key.js
+++ b/src/packet/secret_key.js
@@ -80,10 +80,11 @@ class SecretKeyPacket extends PublicKeyPacket {
    * Internal parser for private keys as specified in
    * {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.5.3|RFC4880bis-04 section 5.5.3}
    * @param {String} bytes - Input string to read the packet from
+   * @async
    */
-  read(bytes) {
+  async read(bytes) {
     // - A Public-Key or Public-Subkey packet, as described above.
-    let i = this.readPublicKey(bytes);
+    let i = await this.readPublicKey(bytes);
 
     // - One octet indicating string-to-key usage conventions.  Zero
     //   indicates that the secret-key data is not encrypted.  255 or 254
diff --git a/test/crypto/validate.js b/test/crypto/validate.js
index a700b35d..31ef9569 100644
--- a/test/crypto/validate.js
+++ b/test/crypto/validate.js
@@ -74,9 +74,9 @@ vqBGKJzmO5q3cECw
 =X9kJ
 -----END PGP PRIVATE KEY BLOCK-----`;
 
-function cloneKeyPacket(key) {
+async function cloneKeyPacket(key) {
   const keyPacket = new openpgp.SecretKeyPacket();
-  keyPacket.read(key.keyPacket.write());
+  await keyPacket.read(key.keyPacket.write());
   return keyPacket;
 }
 
@@ -93,7 +93,7 @@ module.exports = () => {
     });
 
     it('detect invalid edDSA Q', async function() {
-      const eddsaKeyPacket = cloneKeyPacket(eddsaKey);
+      const eddsaKeyPacket = await cloneKeyPacket(eddsaKey);
       const Q = eddsaKeyPacket.publicParams.Q;
       Q[0]++;
       await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid');
@@ -118,7 +118,7 @@ module.exports = () => {
       const { oid, Q } = eddsaKey.keyPacket.publicParams;
       const { seed } = eddsaKey.keyPacket.privateParams;
 
-      const ecdhKeyPacket = cloneKeyPacket(ecdhKey);
+      const ecdhKeyPacket = await cloneKeyPacket(ecdhKey);
       const ecdhOID = ecdhKeyPacket.publicParams.oid;
 
       ecdhKeyPacket.publicParams.oid = oid;
@@ -130,11 +130,11 @@ module.exports = () => {
       await expect(ecdhKeyPacket.validate()).to.be.rejectedWith('Key is invalid');
     });
 
-    it('EdDSA params are not valid for EcDSA', async function() {
+    it('EdDSA params are not valid for ECDSA', async function() {
       const { oid, Q } = eddsaKey.keyPacket.publicParams;
       const { seed } = eddsaKey.keyPacket.privateParams;
 
-      const ecdsaKeyPacket = cloneKeyPacket(ecdsaKey);
+      const ecdsaKeyPacket = await cloneKeyPacket(ecdsaKey);
       const ecdsaOID = ecdsaKeyPacket.publicParams.oid;
       ecdsaKeyPacket.publicParams.oid = oid;
       await expect(ecdsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid');
@@ -145,22 +145,22 @@ module.exports = () => {
       await expect(ecdsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid');
     });
 
-    it('ECDH x25519 params are not valid for EcDSA', async function() {
+    it('ECDH x25519 params are not valid for ECDSA', async function() {
       const { oid, Q } = ecdhKey.keyPacket.publicParams;
       const { d } = ecdhKey.keyPacket.privateParams;
 
-      const ecdsaKeyPacket = cloneKeyPacket(ecdsaKey);
+      const ecdsaKeyPacket = await cloneKeyPacket(ecdsaKey);
       ecdsaKeyPacket.publicParams.oid = oid;
       ecdsaKeyPacket.publicParams.Q = Q;
       ecdsaKeyPacket.privateParams.d = d;
       await expect(ecdsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid');
     });
 
-    it('EcDSA params are not valid for EdDSA', async function() {
+    it('ECDSA params are not valid for EdDSA', async function() {
       const { oid, Q } = ecdsaKey.keyPacket.publicParams;
       const { d } = ecdsaKey.keyPacket.privateParams;
 
-      const eddsaKeyPacket = cloneKeyPacket(eddsaKey);
+      const eddsaKeyPacket = await cloneKeyPacket(eddsaKey);
       const eddsaOID = eddsaKeyPacket.publicParams.oid;
       eddsaKeyPacket.publicParams.oid = oid;
       await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid');
@@ -175,7 +175,7 @@ module.exports = () => {
       const { oid, Q } = ecdhKey.keyPacket.publicParams;
       const { d } = ecdhKey.keyPacket.privateParams;
 
-      const eddsaKeyPacket = cloneKeyPacket(eddsaKey);
+      const eddsaKeyPacket = await cloneKeyPacket(eddsaKey);
       const eddsaOID = eddsaKeyPacket.publicParams.oid;
       eddsaKeyPacket.publicParams.oid = oid;
       await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid');
@@ -202,7 +202,7 @@ module.exports = () => {
         }
       });
 
-      it(`EcDSA ${curve} params should be valid`, async function() {
+      it(`ECDSA ${curve} params should be valid`, async function() {
         if (!ecdsaKey) {
           this.skip();
         }
@@ -213,7 +213,7 @@ module.exports = () => {
         if (!ecdsaKey) {
           this.skip();
         }
-        const keyPacket = cloneKeyPacket(ecdsaKey);
+        const keyPacket = await cloneKeyPacket(ecdsaKey);
         const Q = keyPacket.publicParams.Q;
         Q[16]++;
         await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
@@ -228,7 +228,7 @@ module.exports = () => {
       });
 
       it(`ECDH ${curve} - detect invalid Q`, async function() {
-        const keyPacket = cloneKeyPacket(ecdhKey);
+        const keyPacket = await cloneKeyPacket(ecdhKey);
         const Q = keyPacket.publicParams.Q;
         Q[16]++;
         await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
@@ -252,14 +252,14 @@ module.exports = () => {
     });
 
     it('detect invalid RSA n', async function() {
-      const keyPacket = cloneKeyPacket(rsaKey);
+      const keyPacket = await cloneKeyPacket(rsaKey);
       const n = keyPacket.publicParams.n;
       n[0]++;
       await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
     });
 
     it('detect invalid RSA e', async function() {
-      const keyPacket = cloneKeyPacket(rsaKey);
+      const keyPacket = await cloneKeyPacket(rsaKey);
       const e = keyPacket.publicParams.e;
       e[0]++;
       await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
@@ -277,14 +277,14 @@ module.exports = () => {
     });
 
     it('detect invalid DSA p', async function() {
-      const keyPacket = cloneKeyPacket(dsaKey);
+      const keyPacket = await cloneKeyPacket(dsaKey);
       const p = keyPacket.publicParams.p;
       p[0]++;
       await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
     });
 
     it('detect invalid DSA y', async function() {
-      const keyPacket = cloneKeyPacket(dsaKey);
+      const keyPacket = await cloneKeyPacket(dsaKey);
       const y = keyPacket.publicParams.y;
 
       y[0]++;
@@ -292,7 +292,7 @@ module.exports = () => {
     });
 
     it('detect invalid DSA g', async function() {
-      const keyPacket = cloneKeyPacket(dsaKey);
+      const keyPacket = await cloneKeyPacket(dsaKey);
       const g = keyPacket.publicParams.g;
 
       g[0]++;
@@ -314,21 +314,21 @@ module.exports = () => {
     });
 
     it('detect invalid p', async function() {
-      const keyPacket = cloneKeyPacket(egKey);
+      const keyPacket = await cloneKeyPacket(egKey);
       const p = keyPacket.publicParams.p;
       p[0]++;
       await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
     });
 
     it('detect invalid y', async function() {
-      const keyPacket = cloneKeyPacket(egKey);
+      const keyPacket = await cloneKeyPacket(egKey);
       const y = keyPacket.publicParams.y;
       y[0]++;
       await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
     });
 
     it('detect invalid g', async function() {
-      const keyPacket = cloneKeyPacket(egKey);
+      const keyPacket = await cloneKeyPacket(egKey);
       const g = keyPacket.publicParams.g;
 
       g[0]++;
@@ -339,7 +339,7 @@ module.exports = () => {
     });
 
     it('detect g with small order', async function() {
-      const keyPacket = cloneKeyPacket(egKey);
+      const keyPacket = await cloneKeyPacket(egKey);
       const p = keyPacket.publicParams.p;
       const g = keyPacket.publicParams.g;
 
diff --git a/test/general/key.js b/test/general/key.js
index 7cf5dee5..3fc84869 100644
--- a/test/general/key.js
+++ b/test/general/key.js
@@ -3,7 +3,8 @@
 
 const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..');
 const util = require('../../src/util');
-const key = require('../../src/key');
+const { isAEADSupported, getPreferredAlgo } = require('../../src/key');
+const KeyID = require('../../src/type/keyid');
 
 const chai = require('chai');
 chai.use(require('chai-as-promised'));
@@ -166,55 +167,54 @@ zoGJ6s48HcP591pN93uAitCcYcinY2ZslmdiCXw+zbeoX4spNrV4T4CYxBjNQdIa
 =8d2d
 -----END PGP PUBLIC KEY BLOCK-----`;
 
-const twoKeys =
-     ['-----BEGIN PGP PUBLIC KEY BLOCK-----',
-       'Version: GnuPG v2.0.19 (GNU/Linux)',
-       '',
-       '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',
-       'PepQmgsu',
-       '=w6wd',
-       '-----END PGP PUBLIC KEY BLOCK-----'].join("\n");
+const twoKeys = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2.0.19 (GNU/Linux)
+
+mI0EUmEvTgEEANyWtQQMOybQ9JltDqmaX0WnNPJeLILIM36sw6zL0nfTQ5zXSS3+
+fIF6P29lJFxpblWk02PSID5zX/DYU9/zjM2xPO8Oa4xo0cVTOTLj++Ri5mtr//f5
+GLsIXxFrBJhD/ghFsL3Op0GXOeLJ9A5bsOn8th7x6JucNKuaRB6bQbSPABEBAAG0
+JFRlc3QgTWNUZXN0aW5ndG9uIDx0ZXN0QGV4YW1wbGUuY29tPoi5BBMBAgAjBQJS
+YS9OAhsvBwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AACgkQSmNhOk1uQJQwDAP6
+AgrTyqkRlJVqz2pb46TfbDM2TDF7o9CBnBzIGoxBhlRwpqALz7z2kxBDmwpQa+ki
+Bq3jZN/UosY9y8bhwMAlnrDY9jP1gdCo+H0sD48CdXybblNwaYpwqC8VSpDdTndf
+9j2wE/weihGp/DAdy/2kyBCaiOY1sjhUfJ1GogF49rC4jQRSYS9OAQQA6R/PtBFa
+JaT4jq10yqASk4sqwVMsc6HcifM5lSdxzExFP74naUMMyEsKHP53QxTF0Grqusag
+Qg/ZtgT0CN1HUM152y7ACOdp1giKjpMzOTQClqCoclyvWOFB+L/SwGEIJf7LSCEr
+woBuJifJc8xAVr0XX0JthoW+uP91eTQ3XpsAEQEAAYkBPQQYAQIACQUCUmEvTgIb
+LgCoCRBKY2E6TW5AlJ0gBBkBAgAGBQJSYS9OAAoJEOCE90RsICyXuqIEANmmiRCA
+SF7YK7PvFkieJNwzeK0V3F2lGX+uu6Y3Q/Zxdtwc4xR+me/CSBmsURyXTO29OWhP
+GLszPH9zSJU9BdDi6v0yNprmFPX/1Ng0Abn/sCkwetvjxC1YIvTLFwtUL/7v6NS2
+bZpsUxRTg9+cSrMWWSNjiY9qUKajm1tuzPDZXAUEAMNmAN3xXN/Kjyvj2OK2ck0X
+W748sl/tc3qiKPMJ+0AkMF7Pjhmh9nxqE9+QCEl7qinFqqBLjuzgUhBU4QlwX1GD
+AtNTq6ihLMD5v1d82ZC7tNatdlDMGWnIdvEMCv2GZcuIqDQ9rXWs49e7tq1NncLY
+hz3tYjKhoFTKEIq3y3PpmQENBFKV0FUBCACtZliApy01KBGbGNB36YGH4lpr+5Ko
+qF1I8A5IT0YeNjyGisOkWsDsUzOqaNvgzQ82I3MY/jQV5rLBhH/6LiRmCA16WkKc
+qBrHfNGIxJ+Q+ofVBHUbaS9ClXYI88j747QgWzirnLuEA0GfilRZcewII1pDA/G7
++m1HwV4qHsPataYLeboqhPA3h1EVVQFMAcwlqjOuS8+weHQRfNVRGQdRMm6H7166
+PseDVRUHdkJpVaKFhptgrDoNI0lO+UujdqeF1o5tVZ0j/s7RbyBvdLTXNuBbcpq9
+3ceSWuJPZmi1XztQXKYey0f+ltgVtZDEc7TGV5WDX9erRECCcA3+s7J3ABEBAAG0
+G0pTIENyeXB0byA8ZGlmZmllQGhvbWUub3JnPokBPwQTAQIAKQUCUpXQVQIbAwUJ
+CWYBgAcLCQgHAwIBBhUIAgkKCwQWAgMBAh4BAheAAAoJENvyI+hwU030yRAIAKX/
+mGEgi/miqasbbQoyK/CSa7sRxgZwOWQLdi2xxpE5V4W4HJIDNLJs5vGpRN4mmcNK
+2fmJAh74w0PskmVgJEhPdFJ14UC3fFPq5nbqkBl7hU0tDP5jZxo9ruQZfDOWpHKx
+OCz5guYJ0CW97bz4fChZNFDyfU7VsJQwRIoViVcMCipP0fVZQkIhhwpzQpmVmN8E
+0a6jWezTZv1YpMdlzbEfH79l3StaOh9/Un9CkIyqEWdYiKvIYms9nENyehN7r/OK
+YN3SW+qlt5GaL+ws+N1w6kEZjPFwnsr+Y4A3oHcAwXq7nfOz71USojSmmo8pgdN8
+je16CP98vw3/k6TncLS5AQ0EUpXQVQEIAMEjHMeqg7B04FliUFWr/8C6sJDb492M
+lGAWgghIbnuJfXAnUGdNoAzn0S+n93Y/qHbW6YcjHD4/G+kK3MuxthAFqcVjdHZQ
+XK0rkhXO/u1co7v1cdtkOTEcyOpyLXolM/1S2UYImhrml7YulTHMnWVja7xu6QIR
+so+7HBFT/u9D47L/xXrXMzXFVZfBtVY+yoeTrOY3OX9cBMOAu0kuN9eT18Yv2yi6
+XMzP3iONVHtl6HfFrAA7kAtx4ne0jgAPWZ+a8hMy59on2ZFs/AvSpJtSc1kw/vMT
+WkyVP1Ky20vAPHQ6Ej5q1NGJ/JbcFgolvEeI/3uDueLjj4SdSIbLOXMAEQEAAYkB
+JQQYAQIADwUCUpXQVQIbDAUJCWYBgAAKCRDb8iPocFNN9NLkB/wO4iRxia0zf4Kw
+2RLVZG8qcuo3Bw9UTXYYlI0AutoLNnSURMLLCq6rcJ0BCXGj/2iZ0NBxZq3t5vbR
+h6uUv+hpiSxK1nF7AheN4aAAzhbWx0UDTF04ebG/neE4uDklRIJLhif6+Bwu+EUe
+TlGbDj7fqGSsNe8g92w71e41rF/9CMoOswrKgIjXAou3aexogWcHvKY2D+1q9exO
+Re1rIa1+sUGl5PG2wsEsznN6qtN5gMlGY1ofWDY+I02gO4qzaZ/FxRZfittCw7v5
+dmQYKot9qRi2Kx3Fvw+hivFBpC4TWgppFBnJJnAsFXZJQcejMW4nEmOViRQXY8N8
+PepQmgsu
+=w6wd
+-----END PGP PUBLIC KEY BLOCK-----`;
 
 const pub_revoked_subkeys =
     ['-----BEGIN PGP PUBLIC KEY BLOCK-----',
@@ -2693,8 +2693,8 @@ function versionSpecificTests() {
     // ssb   cv25519 2019-03-20 [E]
     //       E4557C2B02FFBF4B04F87401EC336AF7133D0F85BE7FD09BAEFD9CAEB8C93965
     const key = await openpgp.readKey({ armoredKey: v5_sample_key });
-    expect(key.primaryKey.getFingerprint()).to.equal('19347bc9872464025f99df3ec2e0000ed9884892e1f7b3ea4c94009159569b54');
-    expect(key.subKeys[0].getFingerprint()).to.equal('e4557c2b02ffbf4b04f87401ec336af7133d0f85be7fd09baefd9caeb8c93965');
+    expect(await key.primaryKey.getFingerprint()).to.equal('19347bc9872464025f99df3ec2e0000ed9884892e1f7b3ea4c94009159569b54');
+    expect(await key.subKeys[0].getFingerprint()).to.equal('e4557c2b02ffbf4b04f87401ec336af7133d0f85be7fd09baefd9caeb8c93965');
     await key.verifyPrimaryKey();
   });
 }
@@ -2777,14 +2777,14 @@ module.exports = () => describe('Key', function() {
     expect(pubKeyV4).to.exist;
 
     expect(pubKeyV4.getKeyID().toHex()).to.equal('4a63613a4d6e4094');
-    expect(pubKeyV4.getFingerprint()).to.equal('f470e50dcb1ad5f1e64e08644a63613a4d6e4094');
+    expect(await pubKeyV4.getFingerprint()).to.equal('f470e50dcb1ad5f1e64e08644a63613a4d6e4094');
   });
 
   it('Create new key ID with fromID()', async function() {
     const [pubKeyV4] = await openpgp.readKeys({ armoredKeys: twoKeys });
     const keyID = pubKeyV4.getKeyID();
-    const newKeyID = keyID.constructor.fromID(keyID.toHex());
-    expect(newKeyID.toHex()).to.equal(keyID.toHex());
+    const newKeyID = KeyID.fromID(keyID.toHex());
+    expect(newKeyID.equals(keyID)).to.be.true;
   });
 
   it('Testing key method getSubkeys', async function() {
@@ -2797,11 +2797,12 @@ module.exports = () => describe('Key', function() {
       openpgp.config
     );
 
-    const subkeys = pubKey.getSubkeys();
+    const subkeyPackets = [packetlist[8], packetlist[11]];
+    const subkeys = await pubKey.getSubkeys();
     expect(subkeys).to.exist;
     expect(subkeys).to.have.length(2);
-    expect(subkeys[0].getKeyID().equals(packetlist[8].getKeyID())).to.be.true;
-    expect(subkeys[1].getKeyID().equals(packetlist[11].getKeyID())).to.be.true;
+    expect(subkeys[0].getKeyID().equals(subkeyPackets[0].getKeyID())).to.be.true;
+    expect(subkeys[1].getKeyID().equals(subkeyPackets[1].getKeyID())).to.be.true;
   });
 
   it('Verify status of revoked primary key', async function() {
@@ -3133,12 +3134,13 @@ module.exports = () => describe('Key', function() {
     const dest = await openpgp.readKey({ armoredKey: pub_sig_test });
     expect(source.subKeys[1]).to.exist;
     dest.subKeys.pop();
-    return dest.update(source).then(() => {
-      expect(dest.subKeys[1]).to.exist;
-      expect(
-        dest.subKeys[1].getKeyID().toHex()
-      ).to.equal(source.subKeys[1].getKeyID().toHex());
-    });
+    await dest.update(source);
+    expect(dest.subKeys[1]).to.exist;
+    expect(
+      dest.subKeys[1].getKeyID().toHex()
+    ).to.equal(
+      source.subKeys[1].getKeyID().toHex()
+    );
   });
 
   it('update() - merge subkey - revocation signature', async function() {
@@ -3300,7 +3302,7 @@ module.exports = () => describe('Key', function() {
 
   it("getPreferredAlgo('symmetric') - one key", async function() {
     const [key1] = await openpgp.readKeys({ armoredKeys: twoKeys });
-    const prefAlgo = await key.getPreferredAlgo('symmetric', [key1], undefined, undefined, {
+    const prefAlgo = await getPreferredAlgo('symmetric', [key1], undefined, undefined, {
       ...openpgp.config, preferredSymmetricAlgorithm: openpgp.enums.symmetric.aes256
     });
     expect(prefAlgo).to.equal(openpgp.enums.symmetric.aes256);
@@ -3311,11 +3313,11 @@ module.exports = () => describe('Key', function() {
     const [key1, key2] = await openpgp.readKeys({ armoredKeys: twoKeys });
     const primaryUser = await key2.getPrimaryUser();
     primaryUser.selfCertification.preferredSymmetricAlgorithms = [6, aes192, cast5];
-    const prefAlgo = await key.getPreferredAlgo('symmetric', [key1, key2], undefined, undefined, {
+    const prefAlgo = await getPreferredAlgo('symmetric', [key1, key2], undefined, undefined, {
       ...openpgp.config, preferredSymmetricAlgorithm: openpgp.enums.symmetric.aes192
     });
     expect(prefAlgo).to.equal(aes192);
-    const prefAlgo2 = await key.getPreferredAlgo('symmetric', [key1, key2], undefined, undefined, {
+    const prefAlgo2 = await getPreferredAlgo('symmetric', [key1, key2], undefined, undefined, {
       ...openpgp.config, preferredSymmetricAlgorithm: openpgp.enums.symmetric.aes256
     });
     expect(prefAlgo2).to.equal(aes128);
@@ -3325,7 +3327,7 @@ module.exports = () => describe('Key', function() {
     const [key1, key2] = await openpgp.readKeys({ armoredKeys: twoKeys });
     const primaryUser = await key2.getPrimaryUser();
     primaryUser.selfCertification.preferredSymmetricAlgorithms = null;
-    const prefAlgo = await key.getPreferredAlgo('symmetric', [key1, key2]);
+    const prefAlgo = await getPreferredAlgo('symmetric', [key1, key2]);
     expect(prefAlgo).to.equal(openpgp.enums.symmetric.aes128);
   });
 
@@ -3334,11 +3336,11 @@ module.exports = () => describe('Key', function() {
     const primaryUser = await key1.getPrimaryUser();
     primaryUser.selfCertification.features = [7]; // Monkey-patch AEAD feature flag
     primaryUser.selfCertification.preferredAEADAlgorithms = [2,1];
-    const prefAlgo = await key.getPreferredAlgo('aead', [key1], undefined, undefined, {
+    const prefAlgo = await getPreferredAlgo('aead', [key1], undefined, undefined, {
       ...openpgp.config, preferredAEADAlgorithm: openpgp.enums.aead.ocb
     });
     expect(prefAlgo).to.equal(openpgp.enums.aead.ocb);
-    const supported = await key.isAEADSupported([key1]);
+    const supported = await isAEADSupported([key1]);
     expect(supported).to.be.true;
   });
 
@@ -3351,9 +3353,9 @@ module.exports = () => describe('Key', function() {
     primaryUser.selfCertification.preferredAEADAlgorithms = [2,1];
     const primaryUser2 = await key2.getPrimaryUser();
     primaryUser2.selfCertification.features = [7]; // Monkey-patch AEAD feature flag
-    const prefAlgo = await key.getPreferredAlgo('aead', [key1, key2]);
+    const prefAlgo = await getPreferredAlgo('aead', [key1, key2]);
     expect(prefAlgo).to.equal(openpgp.enums.aead.eax);
-    const supported = await key.isAEADSupported([key1, key2]);
+    const supported = await isAEADSupported([key1, key2]);
     expect(supported).to.be.true;
   });
 
@@ -3364,9 +3366,9 @@ module.exports = () => describe('Key', function() {
     const primaryUser = await key1.getPrimaryUser();
     primaryUser.selfCertification.features = [7]; // Monkey-patch AEAD feature flag
     primaryUser.selfCertification.preferredAEADAlgorithms = [2,1];
-    const prefAlgo = await key.getPreferredAlgo('aead', [key1, key2]);
+    const prefAlgo = await getPreferredAlgo('aead', [key1, key2]);
     expect(prefAlgo).to.equal(openpgp.enums.aead.eax);
-    const supported = await key.isAEADSupported([key1, key2]);
+    const supported = await isAEADSupported([key1, key2]);
     expect(supported).to.be.false;
   });
 
@@ -3529,7 +3531,7 @@ VYGdb3eNlV8CfoEC
     key.users[0].revocationSignatures = [];
     return openpgp.encrypt({ publicKeys: [key], message: await openpgp.createMessage({ text: 'random data' }), date: new Date(1386842743000) }).then(() => {
       throw new Error('encryptSessionKey should not encrypt with revoked public key');
-    }).catch(function(error) {
+    }).catch(error => {
       expect(error.message).to.equal('Error encrypting message: Could not find valid encryption key packet in key ' + key.getKeyID().toHex() + ': Subkey is revoked');
     });
   });
@@ -3550,8 +3552,7 @@ VYGdb3eNlV8CfoEC
     expect(updateKey).to.exist;
     expect(key.users).to.have.length(1);
     return key.update(updateKey).then(() => {
-      expect(key.getFingerprint()).to.equal(
-        updateKey.getFingerprint());
+      expect(key.getFingerprint()).to.equal(updateKey.getFingerprint());
       expect(key.users).to.have.length(2);
       expect(key.users[1].userID).to.be.null;
     });
diff --git a/test/general/openpgp.js b/test/general/openpgp.js
index 625b96be..5146c7fa 100644
--- a/test/general/openpgp.js
+++ b/test/general/openpgp.js
@@ -822,7 +822,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
       return openpgp.decryptKey({
         privateKey: privateKey,
         passphrase: passphrase
-      }).then(function(unlocked){
+      }).then(unlocked => {
         expect(unlocked.getKeyID().toHex()).to.equal(privateKey.getKeyID().toHex());
         expect(unlocked.subKeys[0].getKeyID().toHex()).to.equal(privateKey.subKeys[0].getKeyID().toHex());
         expect(unlocked.isDecrypted()).to.be.true;
@@ -830,7 +830,6 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
         // original key should be unchanged
         expect(privateKey.isDecrypted()).to.be.false;
         expect(privateKey.keyPacket.privateParams).to.be.null;
-        originalKey.subKeys[0].getKeyID(); // fill in keyID
         expect(privateKey).to.deep.equal(originalKey);
       });
     });
@@ -841,7 +840,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
       return openpgp.decryptKey({
         privateKey: privateKey,
         passphrase: ['rubbish', passphrase]
-      }).then(function(unlocked){
+      }).then(unlocked => {
         expect(unlocked.getKeyID().toHex()).to.equal(privateKey.getKeyID().toHex());
         expect(unlocked.subKeys[0].getKeyID().toHex()).to.equal(privateKey.subKeys[0].getKeyID().toHex());
         expect(unlocked.isDecrypted()).to.be.true;
@@ -849,7 +848,6 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
         // original key should be unchanged
         expect(privateKey.isDecrypted()).to.be.false;
         expect(privateKey.keyPacket.privateParams).to.be.null;
-        originalKey.subKeys[0].getKeyID(); // fill in keyID
         expect(privateKey).to.deep.equal(originalKey);
       });
     });
@@ -897,7 +895,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
       return openpgp.encryptKey({
         privateKey: key,
         passphrase: passphrase
-      }).then(function(locked){
+      }).then(locked => {
         expect(locked.getKeyID().toHex()).to.equal(key.getKeyID().toHex());
         expect(locked.subKeys[0].getKeyID().toHex()).to.equal(key.subKeys[0].getKeyID().toHex());
         expect(locked.isDecrypted()).to.be.false;
@@ -905,7 +903,6 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
         // original key should be unchanged
         expect(key.isDecrypted()).to.be.true;
         expect(key.keyPacket.privateParams).to.not.be.null;
-        originalKey.subKeys[0].getKeyID(); // fill in keyID
         expect(key).to.deep.equal(originalKey);
       });
     });
diff --git a/test/general/packet.js b/test/general/packet.js
index 537dfa63..adef8676 100644
--- a/test/general/packet.js
+++ b/test/general/packet.js
@@ -927,12 +927,13 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+
     const rsa = openpgp.enums.publicKey.rsaEncryptSign;
     const key = new openpgp.SecretKeyPacket();
 
-    return crypto.generateParams(rsa, 1024, 65537).then(function({ privateParams, publicParams }) {
+    return crypto.generateParams(rsa, 1024, 65537).then(async ({ privateParams, publicParams }) => {
       const testText = input.createSomeMessage();
 
       key.publicParams = publicParams;
       key.privateParams = privateParams;
       key.algorithm = "rsaSign";
+      await key.computeFingerprintAndKeyID();
 
       const signed = new openpgp.PacketList();
       const literal = new openpgp.LiteralDataPacket();