mirror of
https://github.com/openpgpjs/openpgpjs.git
synced 2025-06-08 07:06:42 +00:00
Internal: improve tree-shaking for crypto modules
Every submodule under the 'crypto' directory was exported-imported even if a handful of functions where actually needed. We now only export entire modules behind default exports if it makes sense for readability and if the different submodules would be imported together anyway (e.g. `cipherMode` exports are all needed by the SEIPD class). We've also dropped exports that are not used outside of the crypto modules, e.g. pkcs5 helpers.
This commit is contained in:
parent
bf85deedb8
commit
2a8969b437
@ -27,6 +27,7 @@ import * as stream from '@openpgp/web-stream-tools';
|
||||
import util from '../../util';
|
||||
import enums from '../../enums';
|
||||
import { getLegacyCipher, getCipherParams } from '../cipher';
|
||||
import { getRandomBytes } from '../random';
|
||||
|
||||
const webCrypto = util.getWebCrypto();
|
||||
const nodeCrypto = util.getNodeCrypto();
|
||||
@ -43,6 +44,20 @@ const nodeAlgos = {
|
||||
/* twofish is not implemented in OpenSSL */
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates a random byte prefix for the specified algorithm
|
||||
* See {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2} for algorithms.
|
||||
* @param {module:enums.symmetric} algo - Symmetric encryption algorithm
|
||||
* @returns {Promise<Uint8Array>} Random bytes with length equal to the block size of the cipher, plus the last two bytes repeated.
|
||||
* @async
|
||||
*/
|
||||
export async function getPrefixRandom(algo) {
|
||||
const { blockSize } = getCipherParams(algo);
|
||||
const prefixrandom = await getRandomBytes(blockSize);
|
||||
const repeat = new Uint8Array([prefixrandom[prefixrandom.length - 2], prefixrandom[prefixrandom.length - 1]]);
|
||||
return util.concat([prefixrandom, repeat]);
|
||||
}
|
||||
|
||||
/**
|
||||
* CFB encryption
|
||||
* @param {enums.symmetric} algo - block cipher algorithm
|
35
src/crypto/cipherMode/index.js
Normal file
35
src/crypto/cipherMode/index.js
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @fileoverview Cipher modes
|
||||
* @module crypto/cipherMode
|
||||
*/
|
||||
|
||||
export * as cfb from './cfb';
|
||||
import eax from './eax';
|
||||
import ocb from './ocb';
|
||||
import gcm from './gcm';
|
||||
import enums from '../../enums';
|
||||
|
||||
/**
|
||||
* Get implementation of the given AEAD mode
|
||||
* @param {enums.aead} algo
|
||||
* @param {Boolean} [acceptExperimentalGCM] - whether to allow the non-standard, legacy `experimentalGCM` algo
|
||||
* @returns {Object}
|
||||
* @throws {Error} on invalid algo
|
||||
*/
|
||||
export function getAEADMode(algo, acceptExperimentalGCM = false) {
|
||||
switch (algo) {
|
||||
case enums.aead.eax:
|
||||
return eax;
|
||||
case enums.aead.ocb:
|
||||
return ocb;
|
||||
case enums.aead.gcm:
|
||||
return gcm;
|
||||
case enums.aead.experimentalGCM:
|
||||
if (!acceptExperimentalGCM) {
|
||||
throw new Error('Unexpected non-standard `experimentalGCM` AEAD algorithm provided in `config.preferredAEADAlgorithm`: use `gcm` instead');
|
||||
}
|
||||
return gcm;
|
||||
default:
|
||||
throw new Error('Unsupported AEAD mode');
|
||||
}
|
||||
}
|
@ -23,8 +23,7 @@
|
||||
* @module crypto/crypto
|
||||
*/
|
||||
|
||||
import publicKey from './public_key';
|
||||
import mode from './mode';
|
||||
import { rsa, elliptic, elgamal, dsa } from './public_key';
|
||||
import { getRandomBytes } from './random';
|
||||
import { getCipherParams } from './cipher';
|
||||
import ECDHSymkey from '../type/ecdh_symkey';
|
||||
@ -51,16 +50,16 @@ export async function publicKeyEncrypt(keyAlgo, symmetricAlgo, publicParams, dat
|
||||
case enums.publicKey.rsaEncrypt:
|
||||
case enums.publicKey.rsaEncryptSign: {
|
||||
const { n, e } = publicParams;
|
||||
const c = await publicKey.rsa.encrypt(data, n, e);
|
||||
const c = await rsa.encrypt(data, n, e);
|
||||
return { c };
|
||||
}
|
||||
case enums.publicKey.elgamal: {
|
||||
const { p, g, y } = publicParams;
|
||||
return publicKey.elgamal.encrypt(data, p, g, y);
|
||||
return elgamal.encrypt(data, p, g, y);
|
||||
}
|
||||
case enums.publicKey.ecdh: {
|
||||
const { oid, Q, kdfParams } = publicParams;
|
||||
const { publicKey: V, wrappedKey: C } = await publicKey.elliptic.ecdh.encrypt(
|
||||
const { publicKey: V, wrappedKey: C } = await elliptic.ecdh.encrypt(
|
||||
oid, kdfParams, data, Q, fingerprint);
|
||||
return { V, C: new ECDHSymkey(C) };
|
||||
}
|
||||
@ -71,7 +70,7 @@ export async function publicKeyEncrypt(keyAlgo, symmetricAlgo, publicParams, dat
|
||||
throw new Error('X25519 and X448 keys can only encrypt AES session keys');
|
||||
}
|
||||
const { A } = publicParams;
|
||||
const { ephemeralPublicKey, wrappedKey } = await publicKey.elliptic.ecdhX.encrypt(
|
||||
const { ephemeralPublicKey, wrappedKey } = await elliptic.ecdhX.encrypt(
|
||||
keyAlgo, data, A);
|
||||
const C = ECDHXSymmetricKey.fromObject({ algorithm: symmetricAlgo, wrappedKey });
|
||||
return { ephemeralPublicKey, C };
|
||||
@ -102,19 +101,19 @@ export async function publicKeyDecrypt(algo, publicKeyParams, privateKeyParams,
|
||||
const { c } = sessionKeyParams;
|
||||
const { n, e } = publicKeyParams;
|
||||
const { d, p, q, u } = privateKeyParams;
|
||||
return publicKey.rsa.decrypt(c, n, e, d, p, q, u, randomPayload);
|
||||
return rsa.decrypt(c, n, e, d, p, q, u, randomPayload);
|
||||
}
|
||||
case enums.publicKey.elgamal: {
|
||||
const { c1, c2 } = sessionKeyParams;
|
||||
const p = publicKeyParams.p;
|
||||
const x = privateKeyParams.x;
|
||||
return publicKey.elgamal.decrypt(c1, c2, p, x, randomPayload);
|
||||
return elgamal.decrypt(c1, c2, p, x, randomPayload);
|
||||
}
|
||||
case enums.publicKey.ecdh: {
|
||||
const { oid, Q, kdfParams } = publicKeyParams;
|
||||
const { d } = privateKeyParams;
|
||||
const { V, C } = sessionKeyParams;
|
||||
return publicKey.elliptic.ecdh.decrypt(
|
||||
return elliptic.ecdh.decrypt(
|
||||
oid, kdfParams, V, C.data, Q, d, fingerprint);
|
||||
}
|
||||
case enums.publicKey.x25519:
|
||||
@ -125,7 +124,7 @@ export async function publicKeyDecrypt(algo, publicKeyParams, privateKeyParams,
|
||||
if (C.algorithm !== null && !util.isAES(C.algorithm)) {
|
||||
throw new Error('AES session key expected');
|
||||
}
|
||||
return publicKey.elliptic.ecdhX.decrypt(
|
||||
return elliptic.ecdhX.decrypt(
|
||||
algo, ephemeralPublicKey, C.wrappedKey, A, k);
|
||||
}
|
||||
default:
|
||||
@ -338,22 +337,22 @@ export function generateParams(algo, bits, oid) {
|
||||
case enums.publicKey.rsaEncrypt:
|
||||
case enums.publicKey.rsaEncryptSign:
|
||||
case enums.publicKey.rsaSign:
|
||||
return publicKey.rsa.generate(bits, 65537).then(({ n, e, d, p, q, u }) => ({
|
||||
return rsa.generate(bits, 65537).then(({ n, e, d, p, q, u }) => ({
|
||||
privateParams: { d, p, q, u },
|
||||
publicParams: { n, e }
|
||||
}));
|
||||
case enums.publicKey.ecdsa:
|
||||
return publicKey.elliptic.generate(oid).then(({ oid, Q, secret }) => ({
|
||||
return elliptic.generate(oid).then(({ oid, Q, secret }) => ({
|
||||
privateParams: { d: secret },
|
||||
publicParams: { oid: new OID(oid), Q }
|
||||
}));
|
||||
case enums.publicKey.eddsaLegacy:
|
||||
return publicKey.elliptic.generate(oid).then(({ oid, Q, secret }) => ({
|
||||
return elliptic.generate(oid).then(({ oid, Q, secret }) => ({
|
||||
privateParams: { seed: secret },
|
||||
publicParams: { oid: new OID(oid), Q }
|
||||
}));
|
||||
case enums.publicKey.ecdh:
|
||||
return publicKey.elliptic.generate(oid).then(({ oid, Q, secret, hash, cipher }) => ({
|
||||
return elliptic.generate(oid).then(({ oid, Q, secret, hash, cipher }) => ({
|
||||
privateParams: { d: secret },
|
||||
publicParams: {
|
||||
oid: new OID(oid),
|
||||
@ -363,13 +362,13 @@ export function generateParams(algo, bits, oid) {
|
||||
}));
|
||||
case enums.publicKey.ed25519:
|
||||
case enums.publicKey.ed448:
|
||||
return publicKey.elliptic.eddsa.generate(algo).then(({ A, seed }) => ({
|
||||
return elliptic.eddsa.generate(algo).then(({ A, seed }) => ({
|
||||
privateParams: { seed },
|
||||
publicParams: { A }
|
||||
}));
|
||||
case enums.publicKey.x25519:
|
||||
case enums.publicKey.x448:
|
||||
return publicKey.elliptic.ecdhX.generate(algo).then(({ A, k }) => ({
|
||||
return elliptic.ecdhX.generate(algo).then(({ A, k }) => ({
|
||||
privateParams: { k },
|
||||
publicParams: { A }
|
||||
}));
|
||||
@ -399,21 +398,21 @@ export async function validateParams(algo, publicParams, privateParams) {
|
||||
case enums.publicKey.rsaSign: {
|
||||
const { n, e } = publicParams;
|
||||
const { d, p, q, u } = privateParams;
|
||||
return publicKey.rsa.validateParams(n, e, d, p, q, u);
|
||||
return rsa.validateParams(n, e, d, p, q, u);
|
||||
}
|
||||
case enums.publicKey.dsa: {
|
||||
const { p, q, g, y } = publicParams;
|
||||
const { x } = privateParams;
|
||||
return publicKey.dsa.validateParams(p, q, g, y, x);
|
||||
return dsa.validateParams(p, q, g, y, x);
|
||||
}
|
||||
case enums.publicKey.elgamal: {
|
||||
const { p, g, y } = publicParams;
|
||||
const { x } = privateParams;
|
||||
return publicKey.elgamal.validateParams(p, g, y, x);
|
||||
return elgamal.validateParams(p, g, y, x);
|
||||
}
|
||||
case enums.publicKey.ecdsa:
|
||||
case enums.publicKey.ecdh: {
|
||||
const algoModule = publicKey.elliptic[enums.read(enums.publicKey, algo)];
|
||||
const algoModule = elliptic[enums.read(enums.publicKey, algo)];
|
||||
const { oid, Q } = publicParams;
|
||||
const { d } = privateParams;
|
||||
return algoModule.validateParams(oid, Q, d);
|
||||
@ -421,39 +420,25 @@ export async function validateParams(algo, publicParams, privateParams) {
|
||||
case enums.publicKey.eddsaLegacy: {
|
||||
const { Q, oid } = publicParams;
|
||||
const { seed } = privateParams;
|
||||
return publicKey.elliptic.eddsaLegacy.validateParams(oid, Q, seed);
|
||||
return elliptic.eddsaLegacy.validateParams(oid, Q, seed);
|
||||
}
|
||||
case enums.publicKey.ed25519:
|
||||
case enums.publicKey.ed448: {
|
||||
const { A } = publicParams;
|
||||
const { seed } = privateParams;
|
||||
return publicKey.elliptic.eddsa.validateParams(algo, A, seed);
|
||||
return elliptic.eddsa.validateParams(algo, A, seed);
|
||||
}
|
||||
case enums.publicKey.x25519:
|
||||
case enums.publicKey.x448: {
|
||||
const { A } = publicParams;
|
||||
const { k } = privateParams;
|
||||
return publicKey.elliptic.ecdhX.validateParams(algo, A, k);
|
||||
return elliptic.ecdhX.validateParams(algo, A, k);
|
||||
}
|
||||
default:
|
||||
throw new Error('Unknown public key algorithm.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random byte prefix for the specified algorithm
|
||||
* See {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2} for algorithms.
|
||||
* @param {module:enums.symmetric} algo - Symmetric encryption algorithm
|
||||
* @returns {Promise<Uint8Array>} Random bytes with length equal to the block size of the cipher, plus the last two bytes repeated.
|
||||
* @async
|
||||
*/
|
||||
export async function getPrefixRandom(algo) {
|
||||
const { blockSize } = getCipherParams(algo);
|
||||
const prefixrandom = await getRandomBytes(blockSize);
|
||||
const repeat = new Uint8Array([prefixrandom[prefixrandom.length - 2], prefixrandom[prefixrandom.length - 1]]);
|
||||
return util.concat([prefixrandom, repeat]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generating a session key for the specified symmetric algorithm
|
||||
* See {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2} for algorithms.
|
||||
@ -465,31 +450,6 @@ export function generateSessionKey(algo) {
|
||||
return getRandomBytes(keySize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get implementation of the given AEAD mode
|
||||
* @param {enums.aead} algo
|
||||
* @param {Boolean} [acceptExperimentalGCM] - whether to allow the non-standard, legacy `experimentalGCM` algo
|
||||
* @returns {Object}
|
||||
* @throws {Error} on invalid algo
|
||||
*/
|
||||
export function getAEADMode(algo, acceptExperimentalGCM = false) {
|
||||
switch (algo) {
|
||||
case enums.aead.eax:
|
||||
return mode.eax;
|
||||
case enums.aead.ocb:
|
||||
return mode.ocb;
|
||||
case enums.aead.gcm:
|
||||
return mode.gcm;
|
||||
case enums.aead.experimentalGCM:
|
||||
if (!acceptExperimentalGCM) {
|
||||
throw new Error('Unexpected non-standard `experimentalGCM` AEAD algorithm provided in `config.preferredAEADAlgorithm`: use `gcm` instead');
|
||||
}
|
||||
return mode.gcm;
|
||||
default:
|
||||
throw new Error('Unsupported AEAD mode');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given curve OID is supported
|
||||
* @param {module:type/oid} oid - EC object identifier
|
||||
@ -513,13 +473,13 @@ export function getCurvePayloadSize(algo, oid) {
|
||||
case enums.publicKey.ecdsa:
|
||||
case enums.publicKey.ecdh:
|
||||
case enums.publicKey.eddsaLegacy:
|
||||
return new publicKey.elliptic.CurveWithOID(oid).payloadSize;
|
||||
return new elliptic.CurveWithOID(oid).payloadSize;
|
||||
case enums.publicKey.ed25519:
|
||||
case enums.publicKey.ed448:
|
||||
return publicKey.elliptic.eddsa.getPayloadSize(algo);
|
||||
return elliptic.eddsa.getPayloadSize(algo);
|
||||
case enums.publicKey.x25519:
|
||||
case enums.publicKey.x448:
|
||||
return publicKey.elliptic.ecdhX.getPayloadSize(algo);
|
||||
return elliptic.ecdhX.getPayloadSize(algo);
|
||||
default:
|
||||
throw new Error('Unknown elliptic algo');
|
||||
}
|
||||
@ -534,14 +494,12 @@ export function getPreferredCurveHashAlgo(algo, oid) {
|
||||
switch (algo) {
|
||||
case enums.publicKey.ecdsa:
|
||||
case enums.publicKey.eddsaLegacy:
|
||||
return publicKey.elliptic.getPreferredHashAlgo(oid);
|
||||
return elliptic.getPreferredHashAlgo(oid);
|
||||
case enums.publicKey.ed25519:
|
||||
case enums.publicKey.ed448:
|
||||
return publicKey.elliptic.eddsa.getPreferredHashAlgo(algo);
|
||||
return elliptic.eddsa.getPreferredHashAlgo(algo);
|
||||
default:
|
||||
throw new Error('Unknown elliptic signing algo');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export { getCipherParams };
|
||||
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
import * as stream from '@openpgp/web-stream-tools';
|
||||
import md5 from './md5';
|
||||
import computeMd5 from './md5';
|
||||
import util from '../../util';
|
||||
import enums from '../../enums';
|
||||
|
||||
@ -55,76 +55,72 @@ function nobleHash(nobleHashName, webCryptoHashName) {
|
||||
};
|
||||
}
|
||||
|
||||
export default {
|
||||
const md5 = nodeHash('md5') || computeMd5;
|
||||
const sha1 = nodeHash('sha1') || nobleHash('sha1', 'SHA-1');
|
||||
const sha224 = nodeHash('sha224') || nobleHash('sha224');
|
||||
const sha256 = nodeHash('sha256') || nobleHash('sha256', 'SHA-256');
|
||||
const sha384 = nodeHash('sha384') || nobleHash('sha384', 'SHA-384');
|
||||
const sha512 = nodeHash('sha512') || nobleHash('sha512', 'SHA-512');
|
||||
const ripemd = nodeHash('ripemd160') || nobleHash('ripemd160');
|
||||
const sha3_256 = nodeHash('sha3-256') || nobleHash('sha3_256');
|
||||
const sha3_512 = nodeHash('sha3-512') || nobleHash('sha3_512');
|
||||
|
||||
/** @see module:md5 */
|
||||
md5: nodeHash('md5') || md5,
|
||||
sha1: nodeHash('sha1') || nobleHash('sha1', 'SHA-1'),
|
||||
sha224: nodeHash('sha224') || nobleHash('sha224'),
|
||||
sha256: nodeHash('sha256') || nobleHash('sha256', 'SHA-256'),
|
||||
sha384: nodeHash('sha384') || nobleHash('sha384', 'SHA-384'),
|
||||
sha512: nodeHash('sha512') || nobleHash('sha512', 'SHA-512'),
|
||||
ripemd: nodeHash('ripemd160') || nobleHash('ripemd160'),
|
||||
sha3_256: nodeHash('sha3-256') || nobleHash('sha3_256'),
|
||||
sha3_512: nodeHash('sha3-512') || nobleHash('sha3_512'),
|
||||
|
||||
/**
|
||||
* Create a hash on the specified data using the specified algorithm
|
||||
* @param {module:enums.hash} algo - Hash algorithm type (see {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4})
|
||||
* @param {Uint8Array} data - Data to be hashed
|
||||
* @returns {Promise<Uint8Array>} Hash value.
|
||||
*/
|
||||
digest: function(algo, data) {
|
||||
switch (algo) {
|
||||
case enums.hash.md5:
|
||||
return this.md5(data);
|
||||
case enums.hash.sha1:
|
||||
return this.sha1(data);
|
||||
case enums.hash.ripemd:
|
||||
return this.ripemd(data);
|
||||
case enums.hash.sha256:
|
||||
return this.sha256(data);
|
||||
case enums.hash.sha384:
|
||||
return this.sha384(data);
|
||||
case enums.hash.sha512:
|
||||
return this.sha512(data);
|
||||
case enums.hash.sha224:
|
||||
return this.sha224(data);
|
||||
case enums.hash.sha3_256:
|
||||
return this.sha3_256(data);
|
||||
case enums.hash.sha3_512:
|
||||
return this.sha3_512(data);
|
||||
default:
|
||||
throw new Error('Unsupported hash function');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the hash size in bytes of the specified hash algorithm type
|
||||
* @param {module:enums.hash} algo - Hash algorithm type (See {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4})
|
||||
* @returns {Integer} Size in bytes of the resulting hash.
|
||||
*/
|
||||
getHashByteLength: function(algo) {
|
||||
switch (algo) {
|
||||
case enums.hash.md5:
|
||||
return 16;
|
||||
case enums.hash.sha1:
|
||||
case enums.hash.ripemd:
|
||||
return 20;
|
||||
case enums.hash.sha256:
|
||||
return 32;
|
||||
case enums.hash.sha384:
|
||||
return 48;
|
||||
case enums.hash.sha512:
|
||||
return 64;
|
||||
case enums.hash.sha224:
|
||||
return 28;
|
||||
case enums.hash.sha3_256:
|
||||
return 32;
|
||||
case enums.hash.sha3_512:
|
||||
return 64;
|
||||
default:
|
||||
throw new Error('Invalid hash algorithm.');
|
||||
}
|
||||
/**
|
||||
* Create a hash on the specified data using the specified algorithm
|
||||
* @param {module:enums.hash} algo - Hash algorithm type (see {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4})
|
||||
* @param {Uint8Array} data - Data to be hashed
|
||||
* @returns {Promise<Uint8Array>} Hash value.
|
||||
*/
|
||||
export function computeDigest(algo, data) {
|
||||
switch (algo) {
|
||||
case enums.hash.md5:
|
||||
return md5(data);
|
||||
case enums.hash.sha1:
|
||||
return sha1(data);
|
||||
case enums.hash.ripemd:
|
||||
return ripemd(data);
|
||||
case enums.hash.sha256:
|
||||
return sha256(data);
|
||||
case enums.hash.sha384:
|
||||
return sha384(data);
|
||||
case enums.hash.sha512:
|
||||
return sha512(data);
|
||||
case enums.hash.sha224:
|
||||
return sha224(data);
|
||||
case enums.hash.sha3_256:
|
||||
return sha3_256(data);
|
||||
case enums.hash.sha3_512:
|
||||
return sha3_512(data);
|
||||
default:
|
||||
throw new Error('Unsupported hash function');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash size in bytes of the specified hash algorithm type
|
||||
* @param {module:enums.hash} algo - Hash algorithm type (See {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4})
|
||||
* @returns {Integer} Size in bytes of the resulting hash.
|
||||
*/
|
||||
export function getHashByteLength(algo) {
|
||||
switch (algo) {
|
||||
case enums.hash.md5:
|
||||
return 16;
|
||||
case enums.hash.sha1:
|
||||
case enums.hash.ripemd:
|
||||
return 20;
|
||||
case enums.hash.sha256:
|
||||
return 32;
|
||||
case enums.hash.sha384:
|
||||
return 48;
|
||||
case enums.hash.sha512:
|
||||
return 64;
|
||||
case enums.hash.sha224:
|
||||
return 28;
|
||||
case enums.hash.sha3_256:
|
||||
return 32;
|
||||
case enums.hash.sha3_512:
|
||||
return 64;
|
||||
default:
|
||||
throw new Error('Invalid hash algorithm.');
|
||||
}
|
||||
}
|
||||
|
@ -9,39 +9,10 @@
|
||||
* @module crypto
|
||||
*/
|
||||
|
||||
import * as cipher from './cipher';
|
||||
import hash from './hash';
|
||||
import mode from './mode';
|
||||
import publicKey from './public_key';
|
||||
import * as signature from './signature';
|
||||
import * as random from './random';
|
||||
import * as pkcs1 from './pkcs1';
|
||||
import * as pkcs5 from './pkcs5';
|
||||
import * as crypto from './crypto';
|
||||
import * as aesKW from './aes_kw';
|
||||
|
||||
// TODO move cfb and gcm to cipher
|
||||
const mod = {
|
||||
/** @see module:crypto/cipher */
|
||||
cipher: cipher,
|
||||
/** @see module:crypto/hash */
|
||||
hash: hash,
|
||||
/** @see module:crypto/mode */
|
||||
mode: mode,
|
||||
/** @see module:crypto/public_key */
|
||||
publicKey: publicKey,
|
||||
/** @see module:crypto/signature */
|
||||
signature: signature,
|
||||
/** @see module:crypto/random */
|
||||
random: random,
|
||||
/** @see module:crypto/pkcs1 */
|
||||
pkcs1: pkcs1,
|
||||
/** @see module:crypto/pkcs5 */
|
||||
pkcs5: pkcs5,
|
||||
/** @see module:crypto/aes_kw */
|
||||
aesKW: aesKW
|
||||
};
|
||||
|
||||
Object.assign(mod, crypto);
|
||||
|
||||
export default mod;
|
||||
export * from './crypto';
|
||||
export { getCipherParams } from './cipher';
|
||||
export * from './hash';
|
||||
export * as cipherMode from './cipherMode';
|
||||
export * as publicKey from './public_key';
|
||||
export * as signature from './signature';
|
||||
export { getRandomBytes } from './random';
|
||||
|
@ -1,21 +0,0 @@
|
||||
/**
|
||||
* @fileoverview Cipher modes
|
||||
* @module crypto/mode
|
||||
*/
|
||||
|
||||
import * as cfb from './cfb';
|
||||
import eax from './eax';
|
||||
import ocb from './ocb';
|
||||
import gcm from './gcm';
|
||||
|
||||
export default {
|
||||
/** @see module:crypto/mode/cfb */
|
||||
cfb: cfb,
|
||||
/** @see module:crypto/mode/gcm */
|
||||
gcm: gcm,
|
||||
experimentalGCM: gcm,
|
||||
/** @see module:crypto/mode/eax */
|
||||
eax: eax,
|
||||
/** @see module:crypto/mode/ocb */
|
||||
ocb: ocb
|
||||
};
|
@ -24,7 +24,7 @@
|
||||
*/
|
||||
|
||||
import { getRandomBytes } from './random';
|
||||
import hash from './hash';
|
||||
import { getHashByteLength } from './hash';
|
||||
import util from '../util';
|
||||
|
||||
/**
|
||||
@ -134,7 +134,7 @@ export function emeDecode(encoded, randomPayload) {
|
||||
*/
|
||||
export function emsaEncode(algo, hashed, emLen) {
|
||||
let i;
|
||||
if (hashed.length !== hash.getHashByteLength(algo)) {
|
||||
if (hashed.length !== getHashByteLength(algo)) {
|
||||
throw new Error('Invalid hash length');
|
||||
}
|
||||
// produce an ASN.1 DER value for the hash function used.
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
import { CurveWithOID, jwkToRawPublic, rawPublicToJWK, privateToJWK, validateStandardParams, checkPublicPointEnconding } from './oid_curves';
|
||||
import * as aesKW from '../../aes_kw';
|
||||
import hash from '../../hash';
|
||||
import { computeDigest } from '../../hash';
|
||||
import enums from '../../../enums';
|
||||
import util from '../../../util';
|
||||
import { b64ToUint8Array } from '../../../encoding/base64';
|
||||
@ -72,7 +72,7 @@ async function kdf(hashAlgo, X, length, param, stripLeading = false, stripTraili
|
||||
for (i = X.length - 1; i >= 0 && X[i] === 0; i--);
|
||||
X = X.subarray(0, i + 1);
|
||||
}
|
||||
const digest = await hash.digest(hashAlgo, util.concatUint8Array([
|
||||
const digest = await computeDigest(hashAlgo, util.concatUint8Array([
|
||||
new Uint8Array([0, 0, 0, 1]),
|
||||
X,
|
||||
param
|
||||
|
@ -23,7 +23,7 @@
|
||||
import enums from '../../../enums';
|
||||
import util from '../../../util';
|
||||
import { getRandomBytes } from '../../random';
|
||||
import hash from '../../hash';
|
||||
import { computeDigest } from '../../hash';
|
||||
import { CurveWithOID, webCurves, privateToJWK, rawPublicToJWK, validateStandardParams, nodeCurves, checkPublicPointEnconding } from './oid_curves';
|
||||
import { bigIntToUint8Array } from '../../biginteger';
|
||||
|
||||
@ -156,7 +156,7 @@ export async function validateParams(oid, Q, d) {
|
||||
case 'node': {
|
||||
const message = getRandomBytes(8);
|
||||
const hashAlgo = enums.hash.sha256;
|
||||
const hashed = await hash.digest(hashAlgo, message);
|
||||
const hashed = await computeDigest(hashAlgo, message);
|
||||
try {
|
||||
const signature = await sign(oid, hashAlgo, message, Q, d, hashed);
|
||||
// eslint-disable-next-line @typescript-eslint/return-await
|
||||
|
@ -23,7 +23,7 @@
|
||||
import ed25519 from '@openpgp/tweetnacl';
|
||||
import util from '../../../util';
|
||||
import enums from '../../../enums';
|
||||
import hash from '../../hash';
|
||||
import { getHashByteLength } from '../../hash';
|
||||
import { getRandomBytes } from '../../random';
|
||||
import { b64ToUint8Array, uint8ArrayToB64 } from '../../../encoding/base64';
|
||||
|
||||
@ -81,7 +81,7 @@ export async function generate(algo) {
|
||||
* @async
|
||||
*/
|
||||
export async function sign(algo, hashAlgo, message, publicKey, privateKey, hashed) {
|
||||
if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(getPreferredHashAlgo(algo))) {
|
||||
if (getHashByteLength(hashAlgo) < getHashByteLength(getPreferredHashAlgo(algo))) {
|
||||
// Enforce digest sizes:
|
||||
// - Ed25519: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.4-4
|
||||
// - Ed448: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.5-4
|
||||
@ -131,7 +131,7 @@ export async function sign(algo, hashAlgo, message, publicKey, privateKey, hashe
|
||||
* @async
|
||||
*/
|
||||
export async function verify(algo, hashAlgo, { RS }, m, publicKey, hashed) {
|
||||
if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(getPreferredHashAlgo(algo))) {
|
||||
if (getHashByteLength(hashAlgo) < getHashByteLength(getPreferredHashAlgo(algo))) {
|
||||
// Enforce digest sizes:
|
||||
// - Ed25519: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.4-4
|
||||
// - Ed448: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.5-4
|
||||
|
@ -24,7 +24,7 @@
|
||||
import nacl from '@openpgp/tweetnacl';
|
||||
import util from '../../../util';
|
||||
import enums from '../../../enums';
|
||||
import hash from '../../hash';
|
||||
import { getHashByteLength } from '../../hash';
|
||||
import { CurveWithOID, checkPublicPointEnconding } from './oid_curves';
|
||||
import { sign as eddsaSign, verify as eddsaVerify } from './eddsa';
|
||||
|
||||
@ -45,7 +45,7 @@ import { sign as eddsaSign, verify as eddsaVerify } from './eddsa';
|
||||
export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
||||
const curve = new CurveWithOID(oid);
|
||||
checkPublicPointEnconding(curve, publicKey);
|
||||
if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) {
|
||||
if (getHashByteLength(hashAlgo) < getHashByteLength(enums.hash.sha256)) {
|
||||
// Enforce digest sizes, since the constraint was already present in RFC4880bis:
|
||||
// see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
|
||||
// and https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.3-3
|
||||
@ -74,7 +74,7 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed
|
||||
export async function verify(oid, hashAlgo, { r, s }, m, publicKey, hashed) {
|
||||
const curve = new CurveWithOID(oid);
|
||||
checkPublicPointEnconding(curve, publicKey);
|
||||
if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) {
|
||||
if (getHashByteLength(hashAlgo) < getHashByteLength(enums.hash.sha256)) {
|
||||
// Enforce digest sizes, since the constraint was already present in RFC4880bis:
|
||||
// see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
|
||||
// and https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.3-3
|
||||
|
@ -3,18 +3,7 @@
|
||||
* @module crypto/public_key
|
||||
*/
|
||||
|
||||
import * as rsa from './rsa';
|
||||
import * as elgamal from './elgamal';
|
||||
import * as elliptic from './elliptic';
|
||||
import * as dsa from './dsa';
|
||||
|
||||
export default {
|
||||
/** @see module:crypto/public_key/rsa */
|
||||
rsa: rsa,
|
||||
/** @see module:crypto/public_key/elgamal */
|
||||
elgamal: elgamal,
|
||||
/** @see module:crypto/public_key/elliptic */
|
||||
elliptic: elliptic,
|
||||
/** @see module:crypto/public_key/dsa */
|
||||
dsa: dsa
|
||||
};
|
||||
export * as rsa from './rsa';
|
||||
export * as elgamal from './elgamal';
|
||||
export * as elliptic from './elliptic';
|
||||
export * as dsa from './dsa';
|
||||
|
@ -26,7 +26,7 @@ import { uint8ArrayToB64, b64ToUint8Array } from '../../encoding/base64';
|
||||
import { emsaEncode, emeEncode, emeDecode } from '../pkcs1';
|
||||
import enums from '../../enums';
|
||||
import { bigIntToNumber, bigIntToUint8Array, bitLength, byteLength, mod, modExp, modInv, uint8ArrayToBigInt } from '../biginteger';
|
||||
import hash from '../hash';
|
||||
import { getHashByteLength } from '../hash';
|
||||
|
||||
const webCrypto = util.getWebCrypto();
|
||||
const nodeCrypto = util.getNodeCrypto();
|
||||
@ -46,7 +46,7 @@ const _1n = BigInt(1);
|
||||
* @async
|
||||
*/
|
||||
export async function sign(hashAlgo, data, n, e, d, p, q, u, hashed) {
|
||||
if (hash.getHashByteLength(hashAlgo) >= n.length) {
|
||||
if (getHashByteLength(hashAlgo) >= n.length) {
|
||||
// Throw here instead of `emsaEncode` below, to provide a clearer and consistent error
|
||||
// e.g. if a 512-bit RSA key is used with a SHA-512 digest.
|
||||
// The size limit is actually slightly different but here we only care about throwing
|
||||
|
@ -3,7 +3,7 @@
|
||||
* @module crypto/signature
|
||||
*/
|
||||
|
||||
import publicKey from './public_key';
|
||||
import { elliptic, rsa, dsa } from './public_key';
|
||||
import enums from '../enums';
|
||||
import util from '../util';
|
||||
import { UnsupportedError } from '../packet/packet';
|
||||
@ -61,7 +61,7 @@ export function parseSignatureParams(algo, signature) {
|
||||
// - 114 octets of the native signature
|
||||
case enums.publicKey.ed25519:
|
||||
case enums.publicKey.ed448: {
|
||||
const rsSize = 2 * publicKey.elliptic.eddsa.getPayloadSize(algo);
|
||||
const rsSize = 2 * elliptic.eddsa.getPayloadSize(algo);
|
||||
const RS = util.readExactSubarray(signature, read, read + rsSize); read += RS.length;
|
||||
return { read, signatureParams: { RS } };
|
||||
}
|
||||
@ -92,34 +92,34 @@ export async function verify(algo, hashAlgo, signature, publicParams, data, hash
|
||||
case enums.publicKey.rsaSign: {
|
||||
const { n, e } = publicParams;
|
||||
const s = util.leftPad(signature.s, n.length); // padding needed for webcrypto and node crypto
|
||||
return publicKey.rsa.verify(hashAlgo, data, s, n, e, hashed);
|
||||
return rsa.verify(hashAlgo, data, s, n, e, hashed);
|
||||
}
|
||||
case enums.publicKey.dsa: {
|
||||
const { g, p, q, y } = publicParams;
|
||||
const { r, s } = signature; // no need to pad, since we always handle them as BigIntegers
|
||||
return publicKey.dsa.verify(hashAlgo, r, s, hashed, g, p, q, y);
|
||||
return dsa.verify(hashAlgo, r, s, hashed, g, p, q, y);
|
||||
}
|
||||
case enums.publicKey.ecdsa: {
|
||||
const { oid, Q } = publicParams;
|
||||
const curveSize = new publicKey.elliptic.CurveWithOID(oid).payloadSize;
|
||||
const curveSize = new elliptic.CurveWithOID(oid).payloadSize;
|
||||
// padding needed for webcrypto
|
||||
const r = util.leftPad(signature.r, curveSize);
|
||||
const s = util.leftPad(signature.s, curveSize);
|
||||
return publicKey.elliptic.ecdsa.verify(oid, hashAlgo, { r, s }, data, Q, hashed);
|
||||
return elliptic.ecdsa.verify(oid, hashAlgo, { r, s }, data, Q, hashed);
|
||||
}
|
||||
case enums.publicKey.eddsaLegacy: {
|
||||
const { oid, Q } = publicParams;
|
||||
const curveSize = new publicKey.elliptic.CurveWithOID(oid).payloadSize;
|
||||
const curveSize = new elliptic.CurveWithOID(oid).payloadSize;
|
||||
// When dealing little-endian MPI data, we always need to left-pad it, as done with big-endian values:
|
||||
// https://www.ietf.org/archive/id/draft-ietf-openpgp-rfc4880bis-10.html#section-3.2-9
|
||||
const r = util.leftPad(signature.r, curveSize);
|
||||
const s = util.leftPad(signature.s, curveSize);
|
||||
return publicKey.elliptic.eddsaLegacy.verify(oid, hashAlgo, { r, s }, data, Q, hashed);
|
||||
return elliptic.eddsaLegacy.verify(oid, hashAlgo, { r, s }, data, Q, hashed);
|
||||
}
|
||||
case enums.publicKey.ed25519:
|
||||
case enums.publicKey.ed448: {
|
||||
const { A } = publicParams;
|
||||
return publicKey.elliptic.eddsa.verify(algo, hashAlgo, signature, data, A, hashed);
|
||||
return elliptic.eddsa.verify(algo, hashAlgo, signature, data, A, hashed);
|
||||
}
|
||||
default:
|
||||
throw new Error('Unknown signature algorithm.');
|
||||
@ -150,31 +150,31 @@ export async function sign(algo, hashAlgo, publicKeyParams, privateKeyParams, da
|
||||
case enums.publicKey.rsaSign: {
|
||||
const { n, e } = publicKeyParams;
|
||||
const { d, p, q, u } = privateKeyParams;
|
||||
const s = await publicKey.rsa.sign(hashAlgo, data, n, e, d, p, q, u, hashed);
|
||||
const s = await rsa.sign(hashAlgo, data, n, e, d, p, q, u, hashed);
|
||||
return { s };
|
||||
}
|
||||
case enums.publicKey.dsa: {
|
||||
const { g, p, q } = publicKeyParams;
|
||||
const { x } = privateKeyParams;
|
||||
return publicKey.dsa.sign(hashAlgo, hashed, g, p, q, x);
|
||||
return dsa.sign(hashAlgo, hashed, g, p, q, x);
|
||||
}
|
||||
case enums.publicKey.elgamal:
|
||||
throw new Error('Signing with Elgamal is not defined in the OpenPGP standard.');
|
||||
case enums.publicKey.ecdsa: {
|
||||
const { oid, Q } = publicKeyParams;
|
||||
const { d } = privateKeyParams;
|
||||
return publicKey.elliptic.ecdsa.sign(oid, hashAlgo, data, Q, d, hashed);
|
||||
return elliptic.ecdsa.sign(oid, hashAlgo, data, Q, d, hashed);
|
||||
}
|
||||
case enums.publicKey.eddsaLegacy: {
|
||||
const { oid, Q } = publicKeyParams;
|
||||
const { seed } = privateKeyParams;
|
||||
return publicKey.elliptic.eddsaLegacy.sign(oid, hashAlgo, data, Q, seed, hashed);
|
||||
return elliptic.eddsaLegacy.sign(oid, hashAlgo, data, Q, seed, hashed);
|
||||
}
|
||||
case enums.publicKey.ed25519:
|
||||
case enums.publicKey.ed448: {
|
||||
const { A } = publicKeyParams;
|
||||
const { seed } = privateKeyParams;
|
||||
return publicKey.elliptic.eddsa.sign(algo, hashAlgo, data, A, seed, hashed);
|
||||
return elliptic.eddsa.sign(algo, hashAlgo, data, A, seed, hashed);
|
||||
}
|
||||
default:
|
||||
throw new Error('Unknown signature algorithm.');
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
SignaturePacket
|
||||
} from '../packet';
|
||||
import enums from '../enums';
|
||||
import crypto from '../crypto';
|
||||
import { getPreferredCurveHashAlgo, getHashByteLength } from '../crypto';
|
||||
import util from '../util';
|
||||
import defaultConfig from '../config';
|
||||
|
||||
@ -149,10 +149,10 @@ export async function getPreferredHashAlgo(targetKeys, signingKeyPacket, date =
|
||||
}
|
||||
const sortedHashAlgos = Array.from(supportedAlgosMap.keys())
|
||||
.filter(hashAlgo => isSupportedHashAlgo(hashAlgo))
|
||||
.sort((algoA, algoB) => crypto.hash.getHashByteLength(algoA) - crypto.hash.getHashByteLength(algoB));
|
||||
.sort((algoA, algoB) => getHashByteLength(algoA) - getHashByteLength(algoB));
|
||||
const strongestHashAlgo = sortedHashAlgos[0];
|
||||
// defaultAlgo is always implicilty supported, and might be stronger than the rest
|
||||
return crypto.hash.getHashByteLength(strongestHashAlgo) >= crypto.hash.getHashByteLength(defaultAlgo) ? strongestHashAlgo : defaultAlgo;
|
||||
return getHashByteLength(strongestHashAlgo) >= getHashByteLength(defaultAlgo) ? strongestHashAlgo : defaultAlgo;
|
||||
};
|
||||
|
||||
const eccAlgos = new Set([
|
||||
@ -171,16 +171,16 @@ export async function getPreferredHashAlgo(targetKeys, signingKeyPacket, date =
|
||||
// Hence, we return the `preferredHashAlgo` as long as it's supported and strong enough;
|
||||
// Otherwise, we look at the strongest supported algo, and ultimately fallback to the curve
|
||||
// preferred algo, even if not supported by all targets.
|
||||
const preferredCurveAlgo = crypto.getPreferredCurveHashAlgo(signingKeyPacket.algorithm, signingKeyPacket.publicParams.oid);
|
||||
const preferredCurveAlgo = getPreferredCurveHashAlgo(signingKeyPacket.algorithm, signingKeyPacket.publicParams.oid);
|
||||
|
||||
const preferredSenderAlgoIsSupported = isSupportedHashAlgo(preferredSenderAlgo);
|
||||
const preferredSenderAlgoStrongerThanCurveAlgo = crypto.hash.getHashByteLength(preferredSenderAlgo) >= crypto.hash.getHashByteLength(preferredCurveAlgo);
|
||||
const preferredSenderAlgoStrongerThanCurveAlgo = getHashByteLength(preferredSenderAlgo) >= getHashByteLength(preferredCurveAlgo);
|
||||
|
||||
if (preferredSenderAlgoIsSupported && preferredSenderAlgoStrongerThanCurveAlgo) {
|
||||
return preferredSenderAlgo;
|
||||
} else {
|
||||
const strongestSupportedAlgo = getStrongestSupportedHashAlgo();
|
||||
return crypto.hash.getHashByteLength(strongestSupportedAlgo) >= crypto.hash.getHashByteLength(preferredCurveAlgo) ?
|
||||
return getHashByteLength(strongestSupportedAlgo) >= getHashByteLength(preferredCurveAlgo) ?
|
||||
strongestSupportedAlgo :
|
||||
preferredCurveAlgo;
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ import * as stream from '@openpgp/web-stream-tools';
|
||||
import { armor, unarmor } from './encoding/armor';
|
||||
import { Argon2OutOfMemoryError } from './type/s2k';
|
||||
import defaultConfig from './config';
|
||||
import crypto from './crypto';
|
||||
import { generateSessionKey } from './crypto';
|
||||
import enums from './enums';
|
||||
import util from './util';
|
||||
import { Signature } from './signature';
|
||||
@ -255,7 +255,7 @@ export class Message {
|
||||
pkeskPacketCopy.read(serialisedPKESK);
|
||||
const randomSessionKey = {
|
||||
sessionKeyAlgorithm,
|
||||
sessionKey: crypto.generateSessionKey(sessionKeyAlgorithm)
|
||||
sessionKey: generateSessionKey(sessionKeyAlgorithm)
|
||||
};
|
||||
try {
|
||||
await pkeskPacketCopy.decrypt(decryptionKeyPacket, randomSessionKey);
|
||||
@ -368,7 +368,7 @@ export class Message {
|
||||
})
|
||||
));
|
||||
|
||||
const sessionKeyData = crypto.generateSessionKey(symmetricAlgo);
|
||||
const sessionKeyData = generateSessionKey(symmetricAlgo);
|
||||
return { data: sessionKeyData, algorithm: symmetricAlgoName, aeadAlgorithm: aeadAlgoName };
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import * as stream from '@openpgp/web-stream-tools';
|
||||
import crypto from '../crypto';
|
||||
import { cipherMode, getRandomBytes } from '../crypto';
|
||||
import enums from '../enums';
|
||||
import util from '../util';
|
||||
import defaultConfig from '../config';
|
||||
@ -78,7 +78,7 @@ class AEADEncryptedDataPacket {
|
||||
this.aeadAlgorithm = await reader.readByte();
|
||||
this.chunkSizeByte = await reader.readByte();
|
||||
|
||||
const mode = crypto.getAEADMode(this.aeadAlgorithm, true);
|
||||
const mode = cipherMode.getAEADMode(this.aeadAlgorithm, true);
|
||||
this.iv = await reader.readBytes(mode.ivLength);
|
||||
this.encrypted = reader.remainder();
|
||||
});
|
||||
@ -119,8 +119,8 @@ class AEADEncryptedDataPacket {
|
||||
async encrypt(sessionKeyAlgorithm, key, config = defaultConfig) {
|
||||
this.cipherAlgorithm = sessionKeyAlgorithm;
|
||||
|
||||
const { ivLength } = crypto.getAEADMode(this.aeadAlgorithm, true);
|
||||
this.iv = crypto.random.getRandomBytes(ivLength); // generate new random IV
|
||||
const { ivLength } = cipherMode.getAEADMode(this.aeadAlgorithm, true);
|
||||
this.iv = getRandomBytes(ivLength); // generate new random IV
|
||||
this.chunkSizeByte = config.aeadChunkSizeByte;
|
||||
const data = this.packets.write();
|
||||
this.encrypted = await runAEAD(this, 'encrypt', key, data);
|
||||
|
@ -15,7 +15,7 @@
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import crypto from '../crypto';
|
||||
import { getRandomBytes } from '../crypto';
|
||||
import enums from '../enums';
|
||||
|
||||
/**
|
||||
@ -56,7 +56,7 @@ class PaddingPacket {
|
||||
* @async
|
||||
*/
|
||||
async createPadding(length) {
|
||||
this.padding = await crypto.random.getRandomBytes(length);
|
||||
this.padding = await getRandomBytes(length);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import KeyID from '../type/keyid';
|
||||
import defaultConfig from '../config';
|
||||
import crypto from '../crypto';
|
||||
import { computeDigest, parsePublicKeyParams, serializeParams } from '../crypto';
|
||||
import enums from '../enums';
|
||||
import util from '../util';
|
||||
import { UnsupportedError } from './packet';
|
||||
@ -126,7 +126,7 @@ class PublicKeyPacket {
|
||||
}
|
||||
|
||||
// - A series of values comprising the key material.
|
||||
const { read, publicParams } = crypto.parsePublicKeyParams(this.algorithm, bytes.subarray(pos));
|
||||
const { read, publicParams } = parsePublicKeyParams(this.algorithm, bytes.subarray(pos));
|
||||
// The deprecated OIDs for Ed25519Legacy and Curve25519Legacy are used in legacy version 4 keys and signatures.
|
||||
// Implementations MUST NOT accept or generate v6 key material using the deprecated OIDs.
|
||||
if (
|
||||
@ -160,7 +160,7 @@ class PublicKeyPacket {
|
||||
// A one-octet number denoting the public-key algorithm of this key
|
||||
arr.push(new Uint8Array([this.algorithm]));
|
||||
|
||||
const params = crypto.serializeParams(this.algorithm, this.publicParams);
|
||||
const params = serializeParams(this.algorithm, this.publicParams);
|
||||
if (this.version >= 5) {
|
||||
// A four-octet scalar octet count for the following key material
|
||||
arr.push(util.writeNumber(params.length, 4));
|
||||
@ -230,9 +230,9 @@ class PublicKeyPacket {
|
||||
const toHash = this.writeForHash(this.version);
|
||||
|
||||
if (this.version >= 5) {
|
||||
this.fingerprint = await crypto.hash.sha256(toHash);
|
||||
this.fingerprint = await computeDigest(enums.hash.sha256, toHash);
|
||||
} else if (this.version === 4) {
|
||||
this.fingerprint = await crypto.hash.sha1(toHash);
|
||||
this.fingerprint = await computeDigest(enums.hash.sha1, toHash);
|
||||
} else {
|
||||
throw new Error('Unsupported key version');
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import KeyID from '../type/keyid';
|
||||
import crypto from '../crypto';
|
||||
import { parseEncSessionKeyParams, publicKeyEncrypt, publicKeyDecrypt, getCipherParams, serializeParams } from '../crypto';
|
||||
import enums from '../enums';
|
||||
import util from '../util';
|
||||
import { UnsupportedError } from './packet';
|
||||
@ -127,7 +127,7 @@ class PublicKeyEncryptedSessionKeyPacket {
|
||||
offset += this.publicKeyID.read(bytes.subarray(offset, offset + 8));
|
||||
}
|
||||
this.publicKeyAlgorithm = bytes[offset++];
|
||||
this.encrypted = crypto.parseEncSessionKeyParams(this.publicKeyAlgorithm, bytes.subarray(offset));
|
||||
this.encrypted = parseEncSessionKeyParams(this.publicKeyAlgorithm, bytes.subarray(offset));
|
||||
if (this.publicKeyAlgorithm === enums.publicKey.x25519 || this.publicKeyAlgorithm === enums.publicKey.x448) {
|
||||
if (this.version === 3) {
|
||||
this.sessionKeyAlgorithm = enums.write(enums.symmetric, this.encrypted.C.algorithm);
|
||||
@ -163,7 +163,7 @@ class PublicKeyEncryptedSessionKeyPacket {
|
||||
|
||||
arr.push(
|
||||
new Uint8Array([this.publicKeyAlgorithm]),
|
||||
crypto.serializeParams(this.publicKeyAlgorithm, this.encrypted)
|
||||
serializeParams(this.publicKeyAlgorithm, this.encrypted)
|
||||
);
|
||||
|
||||
return util.concatUint8Array(arr);
|
||||
@ -182,7 +182,7 @@ class PublicKeyEncryptedSessionKeyPacket {
|
||||
const sessionKeyAlgorithm = this.version === 3 ? this.sessionKeyAlgorithm : null;
|
||||
const fingerprint = key.version === 5 ? key.getFingerprintBytes().subarray(0, 20) : key.getFingerprintBytes();
|
||||
const encoded = encodeSessionKey(this.version, algo, sessionKeyAlgorithm, this.sessionKey);
|
||||
this.encrypted = await crypto.publicKeyEncrypt(
|
||||
this.encrypted = await publicKeyEncrypt(
|
||||
algo, sessionKeyAlgorithm, key.publicParams, encoded, fingerprint);
|
||||
}
|
||||
|
||||
@ -204,7 +204,7 @@ class PublicKeyEncryptedSessionKeyPacket {
|
||||
encodeSessionKey(this.version, this.publicKeyAlgorithm, randomSessionKey.sessionKeyAlgorithm, randomSessionKey.sessionKey) :
|
||||
null;
|
||||
const fingerprint = key.version === 5 ? key.getFingerprintBytes().subarray(0, 20) : key.getFingerprintBytes();
|
||||
const decryptedData = await crypto.publicKeyDecrypt(this.publicKeyAlgorithm, key.publicParams, key.privateParams, this.encrypted, fingerprint, randomPayload);
|
||||
const decryptedData = await publicKeyDecrypt(this.publicKeyAlgorithm, key.publicParams, key.privateParams, this.encrypted, fingerprint, randomPayload);
|
||||
|
||||
const { sessionKey, sessionKeyAlgorithm } = decodeSessionKey(this.version, this.publicKeyAlgorithm, decryptedData, randomSessionKey);
|
||||
|
||||
@ -213,7 +213,7 @@ class PublicKeyEncryptedSessionKeyPacket {
|
||||
const hasEncryptedAlgo = this.publicKeyAlgorithm !== enums.publicKey.x25519 && this.publicKeyAlgorithm !== enums.publicKey.x448;
|
||||
this.sessionKeyAlgorithm = hasEncryptedAlgo ? sessionKeyAlgorithm : this.sessionKeyAlgorithm;
|
||||
|
||||
if (sessionKey.length !== crypto.getCipherParams(this.sessionKeyAlgorithm).keySize) {
|
||||
if (sessionKey.length !== getCipherParams(this.sessionKeyAlgorithm).keySize) {
|
||||
throw new Error('Unexpected session key size');
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import PublicKeyPacket from './public_key';
|
||||
import { newS2KFromConfig, newS2KFromType } from '../type/s2k';
|
||||
import crypto from '../crypto';
|
||||
import { computeDigest, getCipherParams, parsePrivateKeyParams, serializeParams, generateParams, validateParams, getRandomBytes, cipherMode } from '../crypto';
|
||||
import enums from '../enums';
|
||||
import util from '../util';
|
||||
import defaultConfig from '../config';
|
||||
@ -174,7 +174,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
||||
if (this.s2kUsage !== 253 || this.isLegacyAEAD) {
|
||||
this.iv = bytes.subarray(
|
||||
i,
|
||||
i + crypto.getCipherParams(this.symmetric).blockSize
|
||||
i + getCipherParams(this.symmetric).blockSize
|
||||
);
|
||||
this.usedModernAEAD = false;
|
||||
} else {
|
||||
@ -183,7 +183,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
||||
// is used as the nonce for the AEAD algorithm.
|
||||
this.iv = bytes.subarray(
|
||||
i,
|
||||
i + crypto.getAEADMode(this.aead).ivLength
|
||||
i + cipherMode.getAEADMode(this.aead).ivLength
|
||||
);
|
||||
// the non-legacy AEAD encryption mechanism also authenticates public key params; no need for manual validation.
|
||||
this.usedModernAEAD = true;
|
||||
@ -221,7 +221,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
||||
}
|
||||
}
|
||||
try {
|
||||
const { read, privateParams } = crypto.parsePrivateKeyParams(this.algorithm, cleartext, this.publicParams);
|
||||
const { read, privateParams } = parsePrivateKeyParams(this.algorithm, cleartext, this.publicParams);
|
||||
if (read < cleartext.length) {
|
||||
throw new Error('Error reading MPIs');
|
||||
}
|
||||
@ -290,7 +290,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
||||
|
||||
if (!this.isDummy()) {
|
||||
if (!this.s2kUsage) {
|
||||
this.keyMaterial = crypto.serializeParams(this.algorithm, this.privateParams);
|
||||
this.keyMaterial = serializeParams(this.algorithm, this.privateParams);
|
||||
}
|
||||
|
||||
if (this.version === 5) {
|
||||
@ -385,15 +385,15 @@ class SecretKeyPacket extends PublicKeyPacket {
|
||||
|
||||
this.s2k = newS2KFromConfig(config);
|
||||
this.s2k.generateSalt();
|
||||
const cleartext = crypto.serializeParams(this.algorithm, this.privateParams);
|
||||
const cleartext = serializeParams(this.algorithm, this.privateParams);
|
||||
this.symmetric = enums.symmetric.aes256;
|
||||
|
||||
const { blockSize } = crypto.getCipherParams(this.symmetric);
|
||||
const { blockSize } = getCipherParams(this.symmetric);
|
||||
|
||||
if (config.aeadProtect) {
|
||||
this.s2kUsage = 253;
|
||||
this.aead = config.preferredAEADAlgorithm;
|
||||
const mode = crypto.getAEADMode(this.aead);
|
||||
const mode = cipherMode.getAEADMode(this.aead);
|
||||
this.isLegacyAEAD = this.version === 5; // v4 is always re-encrypted with standard format instead.
|
||||
this.usedModernAEAD = !this.isLegacyAEAD; // legacy AEAD does not guarantee integrity of public key material
|
||||
|
||||
@ -401,7 +401,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
||||
const key = await produceEncryptionKey(this.version, this.s2k, passphrase, this.symmetric, this.aead, serializedPacketTag, this.isLegacyAEAD);
|
||||
|
||||
const modeInstance = await mode(this.symmetric, key);
|
||||
this.iv = this.isLegacyAEAD ? crypto.random.getRandomBytes(blockSize) : crypto.random.getRandomBytes(mode.ivLength);
|
||||
this.iv = this.isLegacyAEAD ? getRandomBytes(blockSize) : getRandomBytes(mode.ivLength);
|
||||
const associateData = this.isLegacyAEAD ?
|
||||
new Uint8Array() :
|
||||
util.concatUint8Array([serializedPacketTag, this.writePublicKey()]);
|
||||
@ -411,10 +411,10 @@ class SecretKeyPacket extends PublicKeyPacket {
|
||||
this.s2kUsage = 254;
|
||||
this.usedModernAEAD = false;
|
||||
const key = await produceEncryptionKey(this.version, this.s2k, passphrase, this.symmetric);
|
||||
this.iv = crypto.random.getRandomBytes(blockSize);
|
||||
this.keyMaterial = await crypto.mode.cfb.encrypt(this.symmetric, key, util.concatUint8Array([
|
||||
this.iv = getRandomBytes(blockSize);
|
||||
this.keyMaterial = await cipherMode.cfb.encrypt(this.symmetric, key, util.concatUint8Array([
|
||||
cleartext,
|
||||
await crypto.hash.sha1(cleartext, config)
|
||||
await computeDigest(enums.hash.sha1, cleartext, config)
|
||||
]), this.iv, config);
|
||||
}
|
||||
}
|
||||
@ -454,7 +454,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
||||
|
||||
let cleartext;
|
||||
if (this.s2kUsage === 253) {
|
||||
const mode = crypto.getAEADMode(this.aead, true);
|
||||
const mode = cipherMode.getAEADMode(this.aead, true);
|
||||
const modeInstance = await mode(this.symmetric, key);
|
||||
try {
|
||||
const associateData = this.isLegacyAEAD ?
|
||||
@ -468,10 +468,10 @@ class SecretKeyPacket extends PublicKeyPacket {
|
||||
throw err;
|
||||
}
|
||||
} else {
|
||||
const cleartextWithHash = await crypto.mode.cfb.decrypt(this.symmetric, key, this.keyMaterial, this.iv);
|
||||
const cleartextWithHash = await cipherMode.cfb.decrypt(this.symmetric, key, this.keyMaterial, this.iv);
|
||||
|
||||
cleartext = cleartextWithHash.subarray(0, -20);
|
||||
const hash = await crypto.hash.sha1(cleartext);
|
||||
const hash = await computeDigest(enums.hash.sha1, cleartext);
|
||||
|
||||
if (!util.equalsUint8Array(hash, cleartextWithHash.subarray(-20))) {
|
||||
throw new Error('Incorrect key passphrase');
|
||||
@ -479,7 +479,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
||||
}
|
||||
|
||||
try {
|
||||
const { privateParams } = crypto.parsePrivateKeyParams(this.algorithm, cleartext, this.publicParams);
|
||||
const { privateParams } = parsePrivateKeyParams(this.algorithm, cleartext, this.publicParams);
|
||||
this.privateParams = privateParams;
|
||||
} catch (err) {
|
||||
throw new Error('Error reading MPIs');
|
||||
@ -514,7 +514,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
||||
let validParams;
|
||||
try {
|
||||
// this can throw if some parameters are undefined
|
||||
validParams = await crypto.validateParams(this.algorithm, this.publicParams, this.privateParams);
|
||||
validParams = await validateParams(this.algorithm, this.publicParams, this.privateParams);
|
||||
} catch (_) {
|
||||
validParams = false;
|
||||
}
|
||||
@ -532,7 +532,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
||||
)) {
|
||||
throw new Error(`Cannot generate v6 keys of type 'ecc' with curve ${curve}. Generate a key of type 'curve25519' instead`);
|
||||
}
|
||||
const { privateParams, publicParams } = await crypto.generateParams(this.algorithm, bits, curve);
|
||||
const { privateParams, publicParams } = await generateParams(this.algorithm, bits, curve);
|
||||
this.privateParams = privateParams;
|
||||
this.publicParams = publicParams;
|
||||
this.isEncrypted = false;
|
||||
@ -574,7 +574,7 @@ async function produceEncryptionKey(keyVersion, s2k, passphrase, cipherAlgo, aea
|
||||
if (s2k.type === 'simple' && keyVersion === 6) {
|
||||
throw new Error('Using Simple S2K with version 6 keys is not allowed');
|
||||
}
|
||||
const { keySize } = crypto.getCipherParams(cipherAlgo);
|
||||
const { keySize } = getCipherParams(cipherAlgo);
|
||||
const derivedKey = await s2k.produceKey(passphrase, keySize);
|
||||
if (!aeadMode || keyVersion === 5 || isLegacyAEAD) {
|
||||
return derivedKey;
|
||||
|
@ -18,7 +18,7 @@
|
||||
import * as stream from '@openpgp/web-stream-tools';
|
||||
import { readSimpleLength, UnsupportedError, writeSimpleLength } from './packet';
|
||||
import KeyID from '../type/keyid';
|
||||
import crypto from '../crypto';
|
||||
import { signature, serializeParams, getRandomBytes, getHashByteLength, computeDigest } from '../crypto';
|
||||
import enums from '../enums';
|
||||
import util from '../util';
|
||||
import defaultConfig from '../config';
|
||||
@ -166,7 +166,7 @@ class SignaturePacket {
|
||||
}
|
||||
|
||||
const signatureMaterial = bytes.subarray(i, bytes.length);
|
||||
const { read, signatureParams } = crypto.signature.parseSignatureParams(this.publicKeyAlgorithm, signatureMaterial);
|
||||
const { read, signatureParams } = signature.parseSignatureParams(this.publicKeyAlgorithm, signatureMaterial);
|
||||
if (read < signatureMaterial.length) {
|
||||
throw new Error('Error reading MPIs');
|
||||
}
|
||||
@ -179,10 +179,10 @@ class SignaturePacket {
|
||||
writeParams() {
|
||||
if (this.params instanceof Promise) {
|
||||
return stream.fromAsync(
|
||||
async () => crypto.serializeParams(this.publicKeyAlgorithm, await this.params)
|
||||
async () => serializeParams(this.publicKeyAlgorithm, await this.params)
|
||||
);
|
||||
}
|
||||
return crypto.serializeParams(this.publicKeyAlgorithm, this.params);
|
||||
return serializeParams(this.publicKeyAlgorithm, this.params);
|
||||
}
|
||||
|
||||
write() {
|
||||
@ -221,7 +221,7 @@ class SignaturePacket {
|
||||
if (this.version === 6) {
|
||||
const saltLength = saltLengthForHash(this.hashAlgorithm);
|
||||
if (this.salt === null) {
|
||||
this.salt = crypto.random.getRandomBytes(saltLength);
|
||||
this.salt = getRandomBytes(saltLength);
|
||||
} else if (saltLength !== this.salt.length) {
|
||||
throw new Error('Provided salt does not have the required length');
|
||||
}
|
||||
@ -230,7 +230,7 @@ class SignaturePacket {
|
||||
// since re-signing the same object is not supported, it's not expected to have multiple salt notations,
|
||||
// but we guard against it as a sanity check
|
||||
if (saltNotations.length === 0) {
|
||||
const saltValue = crypto.random.getRandomBytes(saltLengthForHash(this.hashAlgorithm));
|
||||
const saltValue = getRandomBytes(saltLengthForHash(this.hashAlgorithm));
|
||||
this.rawNotations.push({
|
||||
name: SALT_NOTATION_NAME,
|
||||
value: saltValue,
|
||||
@ -256,7 +256,7 @@ class SignaturePacket {
|
||||
const hash = await this.hash(this.signatureType, data, toHash, detached);
|
||||
|
||||
this.signedHashValue = stream.slice(stream.clone(hash), 0, 2);
|
||||
const signed = async () => crypto.signature.sign(
|
||||
const signed = async () => signature.sign(
|
||||
this.publicKeyAlgorithm, this.hashAlgorithm, key.publicParams, key.privateParams, toHash, await stream.readToEnd(hash)
|
||||
);
|
||||
if (util.isStream(hash)) {
|
||||
@ -570,7 +570,7 @@ class SignaturePacket {
|
||||
this.signatureTargetPublicKeyAlgorithm = bytes[mypos++];
|
||||
this.signatureTargetHashAlgorithm = bytes[mypos++];
|
||||
|
||||
const len = crypto.getHashByteLength(this.signatureTargetHashAlgorithm);
|
||||
const len = getHashByteLength(this.signatureTargetHashAlgorithm);
|
||||
|
||||
this.signatureTargetHash = util.uint8ArrayToString(bytes.subarray(mypos, mypos + len));
|
||||
break;
|
||||
@ -738,7 +738,7 @@ class SignaturePacket {
|
||||
}
|
||||
|
||||
if (!toHash) toHash = this.toHash(signatureType, data, detached);
|
||||
return crypto.hash.digest(this.hashAlgorithm, toHash);
|
||||
return computeDigest(this.hashAlgorithm, toHash);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -782,7 +782,7 @@ class SignaturePacket {
|
||||
|
||||
this.params = await this.params;
|
||||
|
||||
this[verified] = await crypto.signature.verify(
|
||||
this[verified] = await signature.verify(
|
||||
this.publicKeyAlgorithm, this.hashAlgorithm, this.params, key.publicParams,
|
||||
toHash, hash
|
||||
);
|
||||
|
@ -16,7 +16,7 @@
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import * as stream from '@openpgp/web-stream-tools';
|
||||
import crypto from '../crypto';
|
||||
import { cipherMode, getRandomBytes, getCipherParams, computeDigest } from '../crypto';
|
||||
import computeHKDF from '../crypto/hkdf';
|
||||
import enums from '../enums';
|
||||
import util from '../util';
|
||||
@ -133,7 +133,7 @@ class SymEncryptedIntegrityProtectedDataPacket {
|
||||
// but we want to ensure that the input key isn't e.g. too short.
|
||||
// The check is done here, instead of on encrypted session key (ESK) encryption, because v6 ESK packets do not store the session key algorithm,
|
||||
// which is instead included in the SEIPDv2 data.
|
||||
const { blockSize, keySize } = crypto.getCipherParams(sessionKeyAlgorithm);
|
||||
const { blockSize, keySize } = getCipherParams(sessionKeyAlgorithm);
|
||||
if (key.length !== keySize) {
|
||||
throw new Error('Unexpected session key size');
|
||||
}
|
||||
@ -144,18 +144,18 @@ class SymEncryptedIntegrityProtectedDataPacket {
|
||||
if (this.version === 2) {
|
||||
this.cipherAlgorithm = sessionKeyAlgorithm;
|
||||
|
||||
this.salt = crypto.random.getRandomBytes(32);
|
||||
this.salt = getRandomBytes(32);
|
||||
this.chunkSizeByte = config.aeadChunkSizeByte;
|
||||
this.encrypted = await runAEAD(this, 'encrypt', key, bytes);
|
||||
} else {
|
||||
const prefix = await crypto.getPrefixRandom(sessionKeyAlgorithm);
|
||||
const prefix = await cipherMode.cfb.getPrefixRandom(sessionKeyAlgorithm);
|
||||
const mdc = new Uint8Array([0xD3, 0x14]); // modification detection code packet
|
||||
|
||||
const tohash = util.concat([prefix, bytes, mdc]);
|
||||
const hash = await crypto.hash.sha1(stream.passiveClone(tohash));
|
||||
const hash = await computeDigest(enums.hash.sha1, stream.passiveClone(tohash));
|
||||
const plaintext = util.concat([tohash, hash]);
|
||||
|
||||
this.encrypted = await crypto.mode.cfb.encrypt(sessionKeyAlgorithm, key, plaintext, new Uint8Array(blockSize), config);
|
||||
this.encrypted = await cipherMode.cfb.encrypt(sessionKeyAlgorithm, key, plaintext, new Uint8Array(blockSize), config);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -175,7 +175,7 @@ class SymEncryptedIntegrityProtectedDataPacket {
|
||||
// but we want to ensure that the input key isn't e.g. too short.
|
||||
// The check is done here, instead of on encrypted session key (ESK) decryption, because v6 ESK packets do not store the session key algorithm,
|
||||
// which is instead included in the SEIPDv2 data.
|
||||
if (key.length !== crypto.getCipherParams(sessionKeyAlgorithm).keySize) {
|
||||
if (key.length !== getCipherParams(sessionKeyAlgorithm).keySize) {
|
||||
throw new Error('Unexpected session key size');
|
||||
}
|
||||
|
||||
@ -190,15 +190,15 @@ class SymEncryptedIntegrityProtectedDataPacket {
|
||||
}
|
||||
packetbytes = await runAEAD(this, 'decrypt', key, encrypted);
|
||||
} else {
|
||||
const { blockSize } = crypto.getCipherParams(sessionKeyAlgorithm);
|
||||
const decrypted = await crypto.mode.cfb.decrypt(sessionKeyAlgorithm, key, encrypted, new Uint8Array(blockSize));
|
||||
const { blockSize } = getCipherParams(sessionKeyAlgorithm);
|
||||
const decrypted = await cipherMode.cfb.decrypt(sessionKeyAlgorithm, key, encrypted, new Uint8Array(blockSize));
|
||||
|
||||
// there must be a modification detection code packet as the
|
||||
// last packet and everything gets hashed except the hash itself
|
||||
const realHash = stream.slice(stream.passiveClone(decrypted), -20);
|
||||
const tohash = stream.slice(decrypted, 0, -20);
|
||||
const verifyHash = Promise.all([
|
||||
stream.readToEnd(await crypto.hash.sha1(stream.passiveClone(tohash))),
|
||||
stream.readToEnd(await computeDigest(enums.hash.sha1, stream.passiveClone(tohash))),
|
||||
stream.readToEnd(realHash)
|
||||
]).then(([hash, mdc]) => {
|
||||
if (!util.equalsUint8Array(hash, mdc)) {
|
||||
@ -237,7 +237,7 @@ export async function runAEAD(packet, fn, key, data) {
|
||||
// we allow `experimentalGCM` for AEADP for backwards compatibility, since v5 keys from OpenPGP.js v5 might be declaring
|
||||
// that preference, as the `gcm` ID had not been standardized at the time.
|
||||
// NB: AEADP are never automatically generate as part of message encryption by OpenPGP.js, the packet must be manually created.
|
||||
const mode = crypto.getAEADMode(packet.aeadAlgorithm, isAEADP);
|
||||
const mode = cipherMode.getAEADMode(packet.aeadAlgorithm, isAEADP);
|
||||
const tagLengthIfDecrypting = fn === 'decrypt' ? mode.tagLength : 0;
|
||||
const tagLengthIfEncrypting = fn === 'encrypt' ? mode.tagLength : 0;
|
||||
const chunkSize = 2 ** (packet.chunkSizeByte + 6) + tagLengthIfDecrypting; // ((uint64_t)1 << (c + 6))
|
||||
@ -255,7 +255,7 @@ export async function runAEAD(packet, fn, key, data) {
|
||||
let iv;
|
||||
let ivView;
|
||||
if (isSEIPDv2) {
|
||||
const { keySize } = crypto.getCipherParams(packet.cipherAlgorithm);
|
||||
const { keySize } = getCipherParams(packet.cipherAlgorithm);
|
||||
const { ivLength } = mode;
|
||||
const info = new Uint8Array(adataBuffer, 0, 5);
|
||||
const derived = await computeHKDF(enums.hash.sha256, key, packet.salt, info, keySize + ivLength);
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { newS2KFromConfig, newS2KFromType } from '../type/s2k';
|
||||
import defaultConfig from '../config';
|
||||
import crypto from '../crypto';
|
||||
import { cipherMode, generateSessionKey, getCipherParams, getRandomBytes } from '../crypto';
|
||||
import computeHKDF from '../crypto/hkdf';
|
||||
import enums from '../enums';
|
||||
import util from '../util';
|
||||
@ -105,7 +105,7 @@ class SymEncryptedSessionKeyPacket {
|
||||
offset += this.s2k.read(bytes.subarray(offset, bytes.length));
|
||||
|
||||
if (this.version >= 5) {
|
||||
const mode = crypto.getAEADMode(this.aeadAlgorithm, true);
|
||||
const mode = cipherMode.getAEADMode(this.aeadAlgorithm, true);
|
||||
|
||||
// A starting initialization vector of size specified by the AEAD
|
||||
// algorithm.
|
||||
@ -163,21 +163,21 @@ class SymEncryptedSessionKeyPacket {
|
||||
this.sessionKeyEncryptionAlgorithm :
|
||||
this.sessionKeyAlgorithm;
|
||||
|
||||
const { blockSize, keySize } = crypto.getCipherParams(algo);
|
||||
const { blockSize, keySize } = getCipherParams(algo);
|
||||
const key = await this.s2k.produceKey(passphrase, keySize);
|
||||
|
||||
if (this.version >= 5) {
|
||||
const mode = crypto.getAEADMode(this.aeadAlgorithm, true);
|
||||
const mode = cipherMode.getAEADMode(this.aeadAlgorithm, true);
|
||||
const adata = new Uint8Array([0xC0 | SymEncryptedSessionKeyPacket.tag, this.version, this.sessionKeyEncryptionAlgorithm, this.aeadAlgorithm]);
|
||||
const encryptionKey = this.version === 6 ? await computeHKDF(enums.hash.sha256, key, new Uint8Array(), adata, keySize) : key;
|
||||
const modeInstance = await mode(algo, encryptionKey);
|
||||
this.sessionKey = await modeInstance.decrypt(this.encrypted, this.iv, adata);
|
||||
} else if (this.encrypted !== null) {
|
||||
const decrypted = await crypto.mode.cfb.decrypt(algo, key, this.encrypted, new Uint8Array(blockSize));
|
||||
const decrypted = await cipherMode.cfb.decrypt(algo, key, this.encrypted, new Uint8Array(blockSize));
|
||||
|
||||
this.sessionKeyAlgorithm = enums.write(enums.symmetric, decrypted[0]);
|
||||
this.sessionKey = decrypted.subarray(1, decrypted.length);
|
||||
if (this.sessionKey.length !== crypto.getCipherParams(this.sessionKeyAlgorithm).keySize) {
|
||||
if (this.sessionKey.length !== getCipherParams(this.sessionKeyAlgorithm).keySize) {
|
||||
throw new Error('Unexpected session key size');
|
||||
}
|
||||
} else {
|
||||
@ -203,16 +203,16 @@ class SymEncryptedSessionKeyPacket {
|
||||
this.s2k = newS2KFromConfig(config);
|
||||
this.s2k.generateSalt();
|
||||
|
||||
const { blockSize, keySize } = crypto.getCipherParams(algo);
|
||||
const { blockSize, keySize } = getCipherParams(algo);
|
||||
const key = await this.s2k.produceKey(passphrase, keySize);
|
||||
|
||||
if (this.sessionKey === null) {
|
||||
this.sessionKey = crypto.generateSessionKey(this.sessionKeyAlgorithm);
|
||||
this.sessionKey = generateSessionKey(this.sessionKeyAlgorithm);
|
||||
}
|
||||
|
||||
if (this.version >= 5) {
|
||||
const mode = crypto.getAEADMode(this.aeadAlgorithm);
|
||||
this.iv = crypto.random.getRandomBytes(mode.ivLength); // generate new random IV
|
||||
const mode = cipherMode.getAEADMode(this.aeadAlgorithm);
|
||||
this.iv = getRandomBytes(mode.ivLength); // generate new random IV
|
||||
const adata = new Uint8Array([0xC0 | SymEncryptedSessionKeyPacket.tag, this.version, this.sessionKeyEncryptionAlgorithm, this.aeadAlgorithm]);
|
||||
const encryptionKey = this.version === 6 ? await computeHKDF(enums.hash.sha256, key, new Uint8Array(), adata, keySize) : key;
|
||||
const modeInstance = await mode(algo, encryptionKey);
|
||||
@ -222,7 +222,7 @@ class SymEncryptedSessionKeyPacket {
|
||||
new Uint8Array([this.sessionKeyAlgorithm]),
|
||||
this.sessionKey
|
||||
]);
|
||||
this.encrypted = await crypto.mode.cfb.encrypt(algo, key, toEncrypt, new Uint8Array(blockSize), config);
|
||||
this.encrypted = await cipherMode.cfb.encrypt(algo, key, toEncrypt, new Uint8Array(blockSize), config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import * as stream from '@openpgp/web-stream-tools';
|
||||
import crypto from '../crypto';
|
||||
import { cipherMode, getCipherParams } from '../crypto';
|
||||
import enums from '../enums';
|
||||
import util from '../util';
|
||||
import defaultConfig from '../config';
|
||||
@ -86,9 +86,9 @@ class SymmetricallyEncryptedDataPacket {
|
||||
throw new Error('Message is not authenticated.');
|
||||
}
|
||||
|
||||
const { blockSize } = crypto.getCipherParams(sessionKeyAlgorithm);
|
||||
const { blockSize } = getCipherParams(sessionKeyAlgorithm);
|
||||
const encrypted = await stream.readToEnd(stream.clone(this.encrypted));
|
||||
const decrypted = await crypto.mode.cfb.decrypt(sessionKeyAlgorithm, key,
|
||||
const decrypted = await cipherMode.cfb.decrypt(sessionKeyAlgorithm, key,
|
||||
encrypted.subarray(blockSize + 2),
|
||||
encrypted.subarray(2, blockSize + 2)
|
||||
);
|
||||
@ -107,11 +107,11 @@ class SymmetricallyEncryptedDataPacket {
|
||||
*/
|
||||
async encrypt(sessionKeyAlgorithm, key, config = defaultConfig) {
|
||||
const data = this.packets.write();
|
||||
const { blockSize } = crypto.getCipherParams(sessionKeyAlgorithm);
|
||||
const { blockSize } = getCipherParams(sessionKeyAlgorithm);
|
||||
|
||||
const prefix = await crypto.getPrefixRandom(sessionKeyAlgorithm);
|
||||
const FRE = await crypto.mode.cfb.encrypt(sessionKeyAlgorithm, key, prefix, new Uint8Array(blockSize), config);
|
||||
const ciphertext = await crypto.mode.cfb.encrypt(sessionKeyAlgorithm, key, data, FRE.subarray(2), config);
|
||||
const prefix = await cipherMode.cfb.getPrefixRandom(sessionKeyAlgorithm);
|
||||
const FRE = await cipherMode.cfb.encrypt(sessionKeyAlgorithm, key, prefix, new Uint8Array(blockSize), config);
|
||||
const ciphertext = await cipherMode.cfb.encrypt(sessionKeyAlgorithm, key, data, FRE.subarray(2), config);
|
||||
this.encrypted = util.concat([FRE, ciphertext]);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import defaultConfig from '../../config';
|
||||
import enums from '../../enums';
|
||||
import util from '../../util';
|
||||
import crypto from '../../crypto';
|
||||
import { getRandomBytes } from '../../crypto';
|
||||
|
||||
const ARGON2_TYPE = 0x02; // id
|
||||
const ARGON2_VERSION = 0x13;
|
||||
@ -56,7 +56,7 @@ class Argon2S2K {
|
||||
}
|
||||
|
||||
generateSalt() {
|
||||
this.salt = crypto.random.getRandomBytes(ARGON2_SALT_SIZE);
|
||||
this.salt = getRandomBytes(ARGON2_SALT_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -28,7 +28,7 @@
|
||||
*/
|
||||
|
||||
import defaultConfig from '../../config';
|
||||
import crypto from '../../crypto';
|
||||
import { getRandomBytes, computeDigest } from '../../crypto';
|
||||
import enums from '../../enums';
|
||||
import { UnsupportedError } from '../../packet/packet';
|
||||
import util from '../../util';
|
||||
@ -60,7 +60,7 @@ class GenericS2K {
|
||||
switch (this.type) {
|
||||
case 'salted':
|
||||
case 'iterated':
|
||||
this.salt = crypto.random.getRandomBytes(8);
|
||||
this.salt = getRandomBytes(8);
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,7 +188,7 @@ class GenericS2K {
|
||||
default:
|
||||
throw new Error('Unknown s2k type.');
|
||||
}
|
||||
const result = await crypto.hash.digest(this.algorithm, toHash);
|
||||
const result = await computeDigest(this.algorithm, toHash);
|
||||
arr.push(result);
|
||||
rlength += result.length;
|
||||
prefixlen++;
|
||||
|
@ -3,7 +3,7 @@ import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/new
|
||||
chaiUse(chaiAsPromised);
|
||||
|
||||
import openpgp from '../initOpenpgp.js';
|
||||
import crypto from '../../src/crypto';
|
||||
import * as crypto from '../../src/crypto';
|
||||
import util from '../../src/util.js';
|
||||
|
||||
export default () => describe('API functional testing', function() {
|
||||
@ -211,20 +211,20 @@ export default () => describe('API functional testing', function() {
|
||||
describe('Sign and verify', function () {
|
||||
it('RSA', async function () {
|
||||
const RSAsignedData = await crypto.signature.sign(
|
||||
openpgp.enums.publicKey.rsaEncryptSign, openpgp.enums.hash.sha1, RSAPublicParams, RSAPrivateParams, data, await crypto.hash.digest(2, data)
|
||||
openpgp.enums.publicKey.rsaEncryptSign, openpgp.enums.hash.sha1, RSAPublicParams, RSAPrivateParams, data, await crypto.computeDigest(2, data)
|
||||
);
|
||||
const success = await crypto.signature.verify(
|
||||
openpgp.enums.publicKey.rsaEncryptSign, openpgp.enums.hash.sha1, RSAsignedData, RSAPublicParams, data, await crypto.hash.digest(2, data)
|
||||
openpgp.enums.publicKey.rsaEncryptSign, openpgp.enums.hash.sha1, RSAsignedData, RSAPublicParams, data, await crypto.computeDigest(2, data)
|
||||
);
|
||||
return expect(success).to.be.true;
|
||||
});
|
||||
|
||||
it('DSA', async function () {
|
||||
const DSAsignedData = await crypto.signature.sign(
|
||||
openpgp.enums.publicKey.dsa, openpgp.enums.hash.sha1, DSAPublicParams, DSAPrivateParams, data, await crypto.hash.digest(2, data)
|
||||
openpgp.enums.publicKey.dsa, openpgp.enums.hash.sha1, DSAPublicParams, DSAPrivateParams, data, await crypto.computeDigest(2, data)
|
||||
);
|
||||
const success = await crypto.signature.verify(
|
||||
openpgp.enums.publicKey.dsa, openpgp.enums.hash.sha1, DSAsignedData, DSAPublicParams, data, await crypto.hash.digest(2, data)
|
||||
openpgp.enums.publicKey.dsa, openpgp.enums.hash.sha1, DSAsignedData, DSAPublicParams, data, await crypto.computeDigest(2, data)
|
||||
);
|
||||
|
||||
return expect(success).to.be.true;
|
||||
@ -234,7 +234,7 @@ export default () => describe('API functional testing', function() {
|
||||
// key data from https://www.rfc-editor.org/rfc/rfc8032#section-7.4
|
||||
const seed = util.hexToUint8Array('d65df341ad13e008567688baedda8e9dcdc17dc024974ea5b4227b6530e339bff21f99e68ca6968f3cca6dfe0fb9f4fab4fa135d5542ea3f01');
|
||||
const A = util.hexToUint8Array('df9705f58edbab802c7f8363cfe5560ab1c6132c20a9f1dd163483a26f8ac53a39d6808bf4a1dfbd261b099bb03b3fb50906cb28bd8a081f00');
|
||||
const toSign = await crypto.hash.digest(openpgp.enums.hash.sha512, data);
|
||||
const toSign = await crypto.computeDigest(openpgp.enums.hash.sha512, data);
|
||||
const signedData = await crypto.signature.sign(
|
||||
openpgp.enums.publicKey.ed448, openpgp.enums.hash.sha512, { A }, { seed }, data, toSign
|
||||
);
|
||||
@ -257,8 +257,8 @@ export default () => describe('API functional testing', function() {
|
||||
const { blockSize } = crypto.getCipherParams(algo);
|
||||
const symmKey = crypto.generateSessionKey(algo);
|
||||
const IV = new Uint8Array(blockSize);
|
||||
const symmencData = await crypto.mode.cfb.encrypt(algo, symmKey, util.stringToUint8Array(plaintext), IV, config);
|
||||
const text = util.uint8ArrayToString(await crypto.mode.cfb.decrypt(algo, symmKey, symmencData, new Uint8Array(blockSize)));
|
||||
const symmencData = await crypto.cipherMode.cfb.encrypt(algo, symmKey, util.stringToUint8Array(plaintext), IV, config);
|
||||
const text = util.uint8ArrayToString(await crypto.cipherMode.cfb.decrypt(algo, symmKey, symmencData, new Uint8Array(blockSize)));
|
||||
expect(text).to.equal(plaintext);
|
||||
}));
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/new
|
||||
chaiUse(chaiAsPromised);
|
||||
|
||||
import openpgp from '../initOpenpgp.js';
|
||||
import EAX from '../../src/crypto/mode/eax.js';
|
||||
import { cipherMode } from '../../src/crypto';
|
||||
import util from '../../src/util.js';
|
||||
|
||||
function testAESEAX() {
|
||||
@ -95,7 +95,8 @@ function testAESEAX() {
|
||||
const headerBytes = util.hexToUint8Array(vec.header);
|
||||
const ctBytes = util.hexToUint8Array(vec.ct);
|
||||
|
||||
const eax = await EAX(cipher, keyBytes);
|
||||
const eaxMode = cipherMode.getAEADMode(openpgp.enums.aead.eax);
|
||||
const eax = await eaxMode(cipher, keyBytes);
|
||||
|
||||
// encryption test
|
||||
let ct = await eax.encrypt(msgBytes, nonceBytes, headerBytes);
|
||||
|
@ -5,7 +5,7 @@ chaiUse(chaiAsPromised);
|
||||
|
||||
import openpgp from '../initOpenpgp.js';
|
||||
import * as elliptic_curves from '../../src/crypto/public_key/elliptic';
|
||||
import hashMod from '../../src/crypto/hash';
|
||||
import { computeDigest } from '../../src/crypto/hash';
|
||||
import config from '../../src/config';
|
||||
import util from '../../src/util.js';
|
||||
|
||||
@ -151,7 +151,7 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi
|
||||
const curve = new elliptic_curves.CurveWithOID(curveName);
|
||||
const oid = new OID(curve.oid);
|
||||
return ecdsa.verify(
|
||||
oid, hash, { r: new Uint8Array(r), s: new Uint8Array(s) }, message, new Uint8Array(pub), await hashMod.digest(hash, message)
|
||||
oid, hash, { r: new Uint8Array(r), s: new Uint8Array(s) }, message, new Uint8Array(pub), await computeDigest(hash, message)
|
||||
);
|
||||
};
|
||||
const secp256k1_point = new Uint8Array([
|
||||
@ -249,7 +249,7 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
|
||||
]);
|
||||
const messageDigest = await hashMod.digest(openpgp.enums.hash.sha512, message);
|
||||
const messageDigest = await computeDigest(openpgp.enums.hash.sha512, message);
|
||||
await testNativeAndFallback(async () => {
|
||||
const signature = await elliptic_curves.ecdsa.sign(oid, openpgp.enums.hash.sha512, message, keyPublic, keyPrivate, messageDigest);
|
||||
await expect(elliptic_curves.ecdsa.verify(oid, openpgp.enums.hash.sha512, signature, message, keyPublic, messageDigest)).to.eventually.be.true;
|
||||
|
@ -4,10 +4,9 @@ import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/new
|
||||
chaiUse(chaiAsPromised);
|
||||
|
||||
import openpgp from '../initOpenpgp.js';
|
||||
import crypto from '../../src/crypto';
|
||||
import * as crypto from '../../src/crypto';
|
||||
import util from '../../src/util.js';
|
||||
|
||||
|
||||
export default () => describe('Symmetric AES-GCM (experimental)', function() {
|
||||
let sinonSandbox;
|
||||
let getWebCryptoStub;
|
||||
@ -46,18 +45,19 @@ export default () => describe('Symmetric AES-GCM (experimental)', function() {
|
||||
}
|
||||
const algo = openpgp.enums.write(openpgp.enums.symmetric, algoName);
|
||||
const key = crypto.generateSessionKey(algo);
|
||||
const iv = crypto.random.getRandomBytes(crypto.mode.gcm.ivLength);
|
||||
const gcmMode = crypto.cipherMode.getAEADMode(openpgp.enums.aead.gcm);
|
||||
const iv = crypto.getRandomBytes(gcmMode.ivLength);
|
||||
|
||||
const nativeEncryptSpy = nodeCrypto ? sinonSandbox.spy(nodeCrypto, 'createCipheriv') : sinonSandbox.spy(webCrypto, 'encrypt');
|
||||
const nativeDecryptSpy = nodeCrypto ? sinonSandbox.spy(nodeCrypto, 'createDecipheriv') : sinonSandbox.spy(webCrypto, 'decrypt');
|
||||
|
||||
nativeEncrypt || disableNative();
|
||||
let modeInstance = await crypto.mode.gcm(algo, key);
|
||||
let modeInstance = await gcmMode(algo, key);
|
||||
const ciphertext = await modeInstance.encrypt(util.stringToUint8Array(plaintext), iv);
|
||||
enableNative();
|
||||
|
||||
nativeDecrypt || disableNative();
|
||||
modeInstance = await crypto.mode.gcm(algo, key);
|
||||
modeInstance = await gcmMode(algo, key);
|
||||
const decrypted = await modeInstance.decrypt(util.stringToUint8Array(util.uint8ArrayToString(ciphertext)), iv);
|
||||
enableNative();
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
import { expect } from 'chai';
|
||||
|
||||
import md5 from '../../../src/crypto/hash/md5.js';
|
||||
import util from '../../../src/util.js';
|
||||
import { computeDigest } from '../../../src/crypto/hash';
|
||||
import enums from '../../../src/enums.js';
|
||||
|
||||
export default () => it('MD5 with test vectors from RFC 1321', async function() {
|
||||
expect(util.uint8ArrayToHex(await md5(util.stringToUint8Array('')), 'MD5("") = d41d8cd98f00b204e9800998ecf8427e')).to.equal('d41d8cd98f00b204e9800998ecf8427e');
|
||||
expect(util.uint8ArrayToHex(await md5(util.stringToUint8Array('abc')), 'MD5("a") = 0cc175b9c0f1b6a831c399e269772661')).to.equal('900150983cd24fb0d6963f7d28e17f72');
|
||||
expect(util.uint8ArrayToHex(await md5(util.stringToUint8Array('message digest')), 'MD5("message digest") = f96b697d7cb7938d525a2f31aaf161d0')).to.equal('f96b697d7cb7938d525a2f31aaf161d0');
|
||||
expect(util.uint8ArrayToHex(await md5(util.stringToUint8Array('abcdefghijklmnopqrstuvwxyz')), 'MD5("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b')).to.equal('c3fcd3d76192e4007dfb496cca67e13b');
|
||||
expect(util.uint8ArrayToHex(await md5(util.stringToUint8Array('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789')), 'MD5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = d174ab98d277d9f5a5611c2c9f419d9f')).to.equal('d174ab98d277d9f5a5611c2c9f419d9f');
|
||||
expect(util.uint8ArrayToHex(await md5(util.stringToUint8Array('12345678901234567890123456789012345678901234567890123456789012345678901234567890')), 'MD5("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = 57edf4a22be3c955ac49da2e2107b67a')).to.equal('57edf4a22be3c955ac49da2e2107b67a');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.md5, util.stringToUint8Array('')), 'MD5("") = d41d8cd98f00b204e9800998ecf8427e')).to.equal('d41d8cd98f00b204e9800998ecf8427e');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.md5, util.stringToUint8Array('abc')), 'MD5("a") = 0cc175b9c0f1b6a831c399e269772661')).to.equal('900150983cd24fb0d6963f7d28e17f72');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.md5, util.stringToUint8Array('message digest')), 'MD5("message digest") = f96b697d7cb7938d525a2f31aaf161d0')).to.equal('f96b697d7cb7938d525a2f31aaf161d0');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.md5, util.stringToUint8Array('abcdefghijklmnopqrstuvwxyz')), 'MD5("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b')).to.equal('c3fcd3d76192e4007dfb496cca67e13b');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.md5, util.stringToUint8Array('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789')), 'MD5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = d174ab98d277d9f5a5611c2c9f419d9f')).to.equal('d174ab98d277d9f5a5611c2c9f419d9f');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.md5, util.stringToUint8Array('12345678901234567890123456789012345678901234567890123456789012345678901234567890')), 'MD5("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = 57edf4a22be3c955ac49da2e2107b67a')).to.equal('57edf4a22be3c955ac49da2e2107b67a');
|
||||
});
|
||||
|
@ -1,11 +1,12 @@
|
||||
import { expect } from 'chai';
|
||||
|
||||
import hash from '../../../src/crypto/hash';
|
||||
import { computeDigest } from '../../../src/crypto/hash';
|
||||
import util from '../../../src/util.js';
|
||||
import enums from '../../../src/enums.js';
|
||||
|
||||
export default () => it('RIPE-MD 160 bits with test vectors from https://homes.esat.kuleuven.be/~bosselae/ripemd160.html', async function() {
|
||||
expect(util.uint8ArrayToHex(await hash.ripemd(util.stringToUint8Array('')), 'RMDstring("") = 9c1185a5c5e9fc54612808977ee8f548b2258d31')).to.equal('9c1185a5c5e9fc54612808977ee8f548b2258d31');
|
||||
expect(util.uint8ArrayToHex(await hash.ripemd(util.stringToUint8Array('a')), 'RMDstring("a") = 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe')).to.equal('0bdc9d2d256b3ee9daae347be6f4dc835a467ffe');
|
||||
expect(util.uint8ArrayToHex(await hash.ripemd(util.stringToUint8Array('abc')), 'RMDstring("abc") = 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc')).to.equal('8eb208f7e05d987a9b044a8e98c6b087f15a0bfc');
|
||||
expect(util.uint8ArrayToHex(await hash.ripemd(util.stringToUint8Array('message digest')), 'RMDstring("message digest") = 5d0689ef49d2fae572b881b123a85ffa21595f36')).to.equal('5d0689ef49d2fae572b881b123a85ffa21595f36');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.ripemd, util.stringToUint8Array('')), 'RMDstring("") = 9c1185a5c5e9fc54612808977ee8f548b2258d31')).to.equal('9c1185a5c5e9fc54612808977ee8f548b2258d31');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.ripemd, util.stringToUint8Array('a')), 'RMDstring("a") = 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe')).to.equal('0bdc9d2d256b3ee9daae347be6f4dc835a467ffe');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.ripemd, util.stringToUint8Array('abc')), 'RMDstring("abc") = 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc')).to.equal('8eb208f7e05d987a9b044a8e98c6b087f15a0bfc');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.ripemd, util.stringToUint8Array('message digest')), 'RMDstring("message digest") = 5d0689ef49d2fae572b881b123a85ffa21595f36')).to.equal('5d0689ef49d2fae572b881b123a85ffa21595f36');
|
||||
});
|
||||
|
@ -1,21 +1,22 @@
|
||||
import { expect } from 'chai';
|
||||
|
||||
import hash from '../../../src/crypto/hash';
|
||||
import { computeDigest } from '../../../src/crypto/hash';
|
||||
import util from '../../../src/util.js';
|
||||
import enums from '../../../src/enums.js';
|
||||
|
||||
export default () => it('SHA* with test vectors from NIST FIPS 180-2', async function() {
|
||||
expect(util.uint8ArrayToHex(await hash.sha1(util.stringToUint8Array('abc')), 'hash.sha1("abc") = a9993e364706816aba3e25717850c26c9cd0d89d')).to.equal('a9993e364706816aba3e25717850c26c9cd0d89d');
|
||||
expect(util.uint8ArrayToHex(await hash.sha1(util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')), 'hash.sha1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 84983e441c3bd26ebaae4aa1f95129e5e54670f1')).to.equal('84983e441c3bd26ebaae4aa1f95129e5e54670f1');
|
||||
expect(util.uint8ArrayToHex(await hash.sha224(util.stringToUint8Array('abc')), 'hash.sha224("abc") = 23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7')).to.equal('23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7');
|
||||
expect(util.uint8ArrayToHex(await hash.sha224(util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')), 'hash.sha224("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525')).to.equal('75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525');
|
||||
expect(util.uint8ArrayToHex(await hash.sha256(util.stringToUint8Array('abc')), 'hash.sha256("abc") = ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad')).to.equal('ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad');
|
||||
expect(util.uint8ArrayToHex(await hash.sha256(util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')), 'hash.sha256("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1')).to.equal('248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1');
|
||||
expect(util.uint8ArrayToHex(await hash.sha384(util.stringToUint8Array('abc')), 'hash.sha384("abc") = cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7')).to.equal('cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7');
|
||||
expect(util.uint8ArrayToHex(await hash.sha384(util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')), 'hash.sha384("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b')).to.equal('3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b');
|
||||
expect(util.uint8ArrayToHex(await hash.sha512(util.stringToUint8Array('abc')), 'hash.sha512("abc") = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f')).to.equal('ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f');
|
||||
expect(util.uint8ArrayToHex(await hash.sha512(util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')), 'hash.sha512("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445')).to.equal('204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445');
|
||||
expect(util.uint8ArrayToHex(await hash.sha3_256(util.stringToUint8Array('abc')), 'hash.sha3_256("abc") = 3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532')).to.equal('3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532');
|
||||
expect(util.uint8ArrayToHex(await hash.sha3_256(util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')), 'hash.sha3_256("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376')).to.equal('41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376');
|
||||
expect(util.uint8ArrayToHex(await hash.sha3_512(util.stringToUint8Array('abc')), 'hash.sha3_512("abc") = b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0')).to.equal('b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0');
|
||||
expect(util.uint8ArrayToHex(await hash.sha3_512(util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')), 'hash.sha3_512("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee691fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e')).to.equal('04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee691fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.sha1, util.stringToUint8Array('abc')), 'hash.sha1("abc") = a9993e364706816aba3e25717850c26c9cd0d89d')).to.equal('a9993e364706816aba3e25717850c26c9cd0d89d');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.sha1, util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')), 'hash.sha1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 84983e441c3bd26ebaae4aa1f95129e5e54670f1')).to.equal('84983e441c3bd26ebaae4aa1f95129e5e54670f1');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.sha224, util.stringToUint8Array('abc')), 'hash.sha224("abc") = 23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7')).to.equal('23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.sha224, util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')), 'hash.sha224("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525')).to.equal('75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.sha256, util.stringToUint8Array('abc')), 'hash.sha256("abc") = ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad')).to.equal('ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.sha256, util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')), 'hash.sha256("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1')).to.equal('248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.sha384, util.stringToUint8Array('abc')), 'hash.sha384("abc") = cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7')).to.equal('cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.sha384, util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')), 'hash.sha384("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b')).to.equal('3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.sha512, util.stringToUint8Array('abc')), 'hash.sha512("abc") = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f')).to.equal('ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.sha512, util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')), 'hash.sha512("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445')).to.equal('204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.sha3_256, util.stringToUint8Array('abc')), 'hash.sha3_256("abc") = 3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532')).to.equal('3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.sha3_256, util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')), 'hash.sha3_256("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376')).to.equal('41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.sha3_512, util.stringToUint8Array('abc')), 'hash.sha3_512("abc") = b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0')).to.equal('b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0');
|
||||
expect(util.uint8ArrayToHex(await computeDigest(enums.hash.sha3_512, util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')), 'hash.sha3_512("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee691fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e')).to.equal('04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee691fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e');
|
||||
});
|
||||
|
@ -6,7 +6,7 @@ import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/new
|
||||
chaiUse(chaiAsPromised);
|
||||
|
||||
import openpgp from '../initOpenpgp.js';
|
||||
import OCB from '../../src/crypto/mode/ocb.js';
|
||||
import { cipherMode } from '../../src/crypto';
|
||||
import util from '../../src/util.js';
|
||||
|
||||
export default () => describe('Symmetric AES-OCB', function() {
|
||||
@ -122,7 +122,8 @@ export default () => describe('Symmetric AES-OCB', function() {
|
||||
const headerBytes = util.hexToUint8Array(vec.A);
|
||||
const ctBytes = util.hexToUint8Array(vec.C);
|
||||
|
||||
const ocb = await OCB(cipher, keyBytes);
|
||||
const ocbMode = cipherMode.getAEADMode(openpgp.enums.aead.ocb);
|
||||
const ocb = await ocbMode(cipher, keyBytes);
|
||||
|
||||
// encryption test
|
||||
let ct = await ocb.encrypt(msgBytes, nonceBytes, headerBytes);
|
||||
@ -163,7 +164,8 @@ export default () => describe('Symmetric AES-OCB', function() {
|
||||
k[k.length - 1] = taglen;
|
||||
|
||||
const algo = openpgp.enums.write(openpgp.enums.symmetric, 'aes' + keylen);
|
||||
const ocb = await OCB(algo, k);
|
||||
const ocbMode = cipherMode.getAEADMode(openpgp.enums.aead.ocb);
|
||||
const ocb = await ocbMode(algo, k);
|
||||
|
||||
const c = [];
|
||||
let n;
|
||||
|
@ -4,7 +4,7 @@ import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/new
|
||||
chaiUse(chaiAsPromised);
|
||||
|
||||
import openpgp from '../initOpenpgp.js';
|
||||
import crypto from '../../src/crypto';
|
||||
import * as crypto from '../../src/crypto';
|
||||
import * as random from '../../src/crypto/random.js';
|
||||
import util from '../../src/util.js';
|
||||
|
||||
@ -67,7 +67,7 @@ export default () => describe('basic RSA cryptography', function () {
|
||||
const { publicParams, privateParams } = await crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
|
||||
const message = random.getRandomBytes(64);
|
||||
const hashAlgo = openpgp.enums.write(openpgp.enums.hash, 'sha256');
|
||||
const hashed = await crypto.hash.digest(hashAlgo, message);
|
||||
const hashed = await crypto.computeDigest(hashAlgo, message);
|
||||
const { n, e, d, p, q, u } = { ...publicParams, ...privateParams };
|
||||
const signature = await crypto.publicKey.rsa.sign(hashAlgo, message, n, e, d, p, q, u, hashed);
|
||||
expect(signature).to.exist;
|
||||
@ -113,7 +113,7 @@ export default () => describe('basic RSA cryptography', function () {
|
||||
const message = random.getRandomBytes(64);
|
||||
const hashName = 'sha256';
|
||||
const hashAlgo = openpgp.enums.write(openpgp.enums.hash, hashName);
|
||||
const hashed = await crypto.hash.digest(hashAlgo, message);
|
||||
const hashed = await crypto.computeDigest(hashAlgo, message);
|
||||
enableNative();
|
||||
const signatureNative = await crypto.publicKey.rsa.sign(hashAlgo, message, n, e, d, p, q, u, hashed);
|
||||
disableNative();
|
||||
@ -130,7 +130,7 @@ export default () => describe('basic RSA cryptography', function () {
|
||||
const { n, e, d, p, q, u } = { ...publicParams, ...privateParams };
|
||||
const message = random.getRandomBytes(64);
|
||||
const hashAlgo = openpgp.enums.write(openpgp.enums.hash, hashName);
|
||||
const hashed = await crypto.hash.digest(hashAlgo, message);
|
||||
const hashed = await crypto.computeDigest(hashAlgo, message);
|
||||
enableNative();
|
||||
await expect(crypto.publicKey.rsa.sign(hashAlgo, message, n, e, d, p, q, u, hashed)).to.be.rejectedWith(/Digest size cannot exceed key modulus size/);
|
||||
disableNative();
|
||||
@ -146,7 +146,7 @@ export default () => describe('basic RSA cryptography', function () {
|
||||
const message = random.getRandomBytes(64);
|
||||
const hashName = 'sha256';
|
||||
const hashAlgo = openpgp.enums.write(openpgp.enums.hash, hashName);
|
||||
const hashed = await crypto.hash.digest(hashAlgo, message);
|
||||
const hashed = await crypto.computeDigest(hashAlgo, message);
|
||||
enableNative();
|
||||
const signatureNative = await crypto.publicKey.rsa.sign(hashAlgo, message, n, e, d, p, q, u, hashed);
|
||||
const verifyNative = await crypto.publicKey.rsa.verify(hashAlgo, message, signatureNative, n, e);
|
||||
|
@ -7,8 +7,7 @@ import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/new
|
||||
chaiUse(chaiAsPromised);
|
||||
|
||||
import openpgp from '../initOpenpgp.js';
|
||||
import crypto from '../../src/crypto';
|
||||
import * as random from '../../src/crypto/random.js';
|
||||
import * as crypto from '../../src/crypto';
|
||||
import util from '../../src/util.js';
|
||||
import keyIDType from '../../src/type/keyid.js';
|
||||
import { getPreferredCipherSuite } from '../../src/key';
|
||||
@ -3706,7 +3705,7 @@ XfA3pqV4mTzF
|
||||
const data = new globalThis.ReadableStream({
|
||||
pull(controller) {
|
||||
if (i++ < 4) {
|
||||
const randomBytes = random.getRandomBytes(10);
|
||||
const randomBytes = crypto.getRandomBytes(10);
|
||||
controller.enqueue(randomBytes);
|
||||
plaintext.push(randomBytes.slice());
|
||||
} else {
|
||||
|
@ -6,7 +6,7 @@ import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/new
|
||||
chaiUse(chaiAsPromised);
|
||||
|
||||
import openpgp from '../initOpenpgp.js';
|
||||
import crypto from '../../src/crypto';
|
||||
import * as crypto from '../../src/crypto';
|
||||
import util from '../../src/util.js';
|
||||
import * as packet from '../../src/packet';
|
||||
import * as random from '../../src/crypto/random';
|
||||
|
Loading…
x
Reference in New Issue
Block a user