UNPKG

hpke-js

Version:

A Hybrid Public Key Encryption (HPKE) module for various JavaScript runtimes

194 lines (193 loc) 8.34 kB
(function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "@hpke/core", "@hpke/chacha20poly1305", "@hpke/dhkem-x25519", "@hpke/dhkem-x448", "./kdfs/hkdfSha384.js", "./kems/dhkemP256.js", "./kems/dhkemP384.js", "./kems/dhkemP521.js"], factory); } })(function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CipherSuite = void 0; const core_1 = require("@hpke/core"); const chacha20poly1305_1 = require("@hpke/chacha20poly1305"); const dhkem_x25519_1 = require("@hpke/dhkem-x25519"); const dhkem_x448_1 = require("@hpke/dhkem-x448"); const hkdfSha384_js_1 = require("./kdfs/hkdfSha384.js"); const dhkemP256_js_1 = require("./kems/dhkemP256.js"); const dhkemP384_js_1 = require("./kems/dhkemP384.js"); const dhkemP521_js_1 = require("./kems/dhkemP521.js"); /** * The Hybrid Public Key Encryption (HPKE) ciphersuite, * which supports all of the ciphersuites defined in * {@link https://datatracker.ietf.org/doc/html/rfc9180 | RFC9180}. * * The class consists of the {@link https://jsr.io/@hpke/core/doc | @hpke/core}, * {@link https://jsr.io/@hpke/chacha20Poly1305/doc | @hpke/chcha20poly1305}, * {@link https://jsr.io/@hpke/dhkem-x25519/doc | @hpke/dhkem-x25519} and * {@link https://jsr.io/@hpke/dhkem-x448/doc | @hpke/dhkem-x448} internally. * * This class provides following functions: * * - [DEPRECATED] Generates a key pair for the cipher suite. * - [DEPRECATED] Derives a key pair for the cipher suite. * - [DEPRECATED] Imports and converts a key to a CryptoKey. * - Creates encryption contexts both for senders and recipients. * - {@link createSenderContext} * - {@link createRecipientContext} * - Provides single-shot encryption API. * - {@link seal} * - {@link open} * * The calling of the constructor of this class is the starting * point for HPKE operations for both senders and recipients. * * @example Use only ciphersuites supported internally. * * ```ts * import { AeadId, CipherSuite, KdfId, KemId } from "@hpke/hpke-js"; * * const suite = new CipherSuite({ * kem: KemId.DhkemP256HkdfSha256, * kdf: KdfId.HkdfSha256, * aead: AeadId.Aes128Gcm, * }); * ``` * * @example Use a ciphersuite consisting of an external module. * * ```ts * import { AeadId, CipherSuite, KdfId } from "@hpke/hpke-js"; * // Use an extension module. * import { * HybridkemX25519Kyber768, * } from "@hpke/hybridkem-x25519-kyber768"; * * const suite = new CipherSuite({ * kem: new HybridkemX25519Kyber768(), * kdf: KdfId.HkdfSha256, * aead: AeadId.Aes128Gcm, * }); * ``` */ class CipherSuite extends core_1.CipherSuite { /** * @param params A set of parameters for building a cipher suite. * @throws {@link InvalidParamError} */ constructor(params) { // KEM if (typeof params.kem === "number") { switch (params.kem) { case core_1.KemId.DhkemP256HkdfSha256: params.kem = new dhkemP256_js_1.DhkemP256HkdfSha256(); break; case core_1.KemId.DhkemP384HkdfSha384: params.kem = new dhkemP384_js_1.DhkemP384HkdfSha384(); break; case core_1.KemId.DhkemP521HkdfSha512: params.kem = new dhkemP521_js_1.DhkemP521HkdfSha512(); break; case core_1.KemId.DhkemX25519HkdfSha256: params.kem = new dhkem_x25519_1.DhkemX25519HkdfSha256(); break; case core_1.KemId.DhkemX448HkdfSha512: params.kem = new dhkem_x448_1.DhkemX448HkdfSha512(); break; default: throw new core_1.InvalidParamError(`The KEM (${params.kem}) cannot be specified by KemId. Use submodule for the KEM`); } } // KDF if (typeof params.kdf === "number") { switch (params.kdf) { case core_1.KdfId.HkdfSha256: params.kdf = new dhkem_x25519_1.HkdfSha256(); break; case core_1.KdfId.HkdfSha384: params.kdf = new hkdfSha384_js_1.HkdfSha384(); break; default: // case KdfId.HkdfSha512: params.kdf = new dhkem_x448_1.HkdfSha512(); break; } } // AEAD if (typeof params.aead === "number") { switch (params.aead) { case core_1.AeadId.Aes128Gcm: params.aead = new core_1.Aes128Gcm(); break; case core_1.AeadId.Aes256Gcm: params.aead = new core_1.Aes256Gcm(); break; case core_1.AeadId.Chacha20Poly1305: params.aead = new chacha20poly1305_1.Chacha20Poly1305(); break; default: // case AeadId.ExportOnly: params.aead = new core_1.ExportOnly(); break; } } super(params); } /** * Generates a key pair for the cipher suite. * * If the error occurred, throws {@link NotSupportedError}. * * @deprecated Use {@link KemInterface.generateKeyPair} instead. * * @returns A key pair generated. * @throws {@link NotSupportedError} */ async generateKeyPair() { await this._setup(); return await this._kem.generateKeyPair(); } /** * Derives a key pair for the cipher suite in the manner * defined in [RFC9180 Section 7.1.3](https://www.rfc-editor.org/rfc/rfc9180.html#section-7.1.3). * * If the error occurred, throws {@link DeriveKeyPairError}. * * @deprecated Use {@link KemInterface.deriveKeyPair} instead. * * @param ikm A byte string of input keying material. The maximum length is 128 bytes. * @returns A key pair derived. * @throws {@link DeriveKeyPairError} */ async deriveKeyPair(ikm) { await this._setup(); return await this._kem.deriveKeyPair(ikm); } /** * Imports a public or private key and converts to a {@link CryptoKey}. * * Since key parameters for {@link createSenderContext} or {@link createRecipientContext} * are {@link CryptoKey} format, you have to use this function to convert provided keys * to {@link CryptoKey}. * * Basically, this is a thin wrapper function of * [SubtleCrypto.importKey](https://www.w3.org/TR/WebCryptoAPI/#dfn-SubtleCrypto-method-importKey). * * If the error occurred, throws {@link DeserializeError}. * * @deprecated Use {@link KemInterface.generateKeyPair} instead. * * @param format For now, `'raw'` and `'jwk'` are supported. * @param key A byte string of a raw key or A {@link JsonWebKey} object. * @param isPublic The indicator whether the provided key is a public key or not, which is used only for `'raw'` format. * @returns A public or private CryptoKey. * @throws {@link DeserializeError} */ async importKey(format, key, isPublic = true) { await this._setup(); return await this._kem.importKey(format, key, isPublic); } } exports.CipherSuite = CipherSuite; });