Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@hpke/dhkem-x448

Package Overview
Dependencies
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@hpke/dhkem-x448 - npm Package Compare versions

Comparing version 1.0.4 to 1.1.0

esm/src/interfaces/dhkemPrimitives.d.ts

8

esm/src/algorithm.d.ts

@@ -1,9 +0,5 @@

export declare class AlgorithmBase {
export declare class NativeAlgorithm {
protected _api: SubtleCrypto | undefined;
constructor();
protected _setup(): Promise<void>;
}
export declare class Algorithm extends AlgorithmBase {
constructor();
init(api: SubtleCrypto): void;
protected checkInit(): void;
}

@@ -1,2 +0,20 @@

export class AlgorithmBase {
import { NotSupportedError } from "./errors.js";
import { isBrowser, isCloudflareWorkers } from "./utils/misc.js";
async function loadSubtleCrypto() {
if (isBrowser() || isCloudflareWorkers()) {
if (globalThis.crypto !== undefined) {
return globalThis.crypto.subtle;
}
// jsdom
}
try {
// @ts-ignore: to ignore "crypto"
const { webcrypto } = await import("crypto"); // node:crypto
return webcrypto.subtle;
}
catch (e) {
throw new NotSupportedError(e);
}
}
export class NativeAlgorithm {
constructor() {

@@ -10,15 +28,8 @@ Object.defineProperty(this, "_api", {

}
}
export class Algorithm extends AlgorithmBase {
constructor() {
super();
}
init(api) {
this._api = api;
}
checkInit() {
if (this._api === undefined) {
throw new Error("Not initialized. Call init()");
async _setup() {
if (this._api !== undefined) {
return;
}
this._api = await loadSubtleCrypto();
}
}

@@ -20,2 +20,3 @@ /**

export declare const Kem: {
readonly NotAssigned: 0;
readonly DhkemP256HkdfSha256: 16;

@@ -38,2 +39,3 @@ readonly DhkemP384HkdfSha384: 17;

export declare const KemId: {
readonly NotAssigned: 0;
readonly DhkemP256HkdfSha256: 16;

@@ -40,0 +42,0 @@ readonly DhkemP384HkdfSha384: 17;

@@ -16,2 +16,3 @@ /**

export const Kem = {
NotAssigned: 0x0000,
DhkemP256HkdfSha256: 0x0010,

@@ -18,0 +19,0 @@ DhkemP384HkdfSha384: 0x0011,

@@ -19,22 +19,23 @@ import type { RecipientContextParams } from "./recipientContextParams.js";

/**
* Generates a key pair.
* Serializes a public key as CryptoKey to a byte string of length `Npk`.
*
* If the error occurred, throws {@link NotSupportedError}.
* If the error occurred, throws {@link SerializeError}.
*
* @returns A key pair generated.
* @throws {@link NotSupportedError}
* @param key A CryptoKey.
* @returns A key as bytes.
* @throws {@link SerializeError}
*/
generateKeyPair(): Promise<CryptoKeyPair>;
serializePublicKey(key: CryptoKey): Promise<ArrayBuffer>;
/**
* Derives a key pair from the byte string ikm.
* Deserializes a public key as a byte string of length `Npk` to CryptoKey.
*
* If the error occurred, throws {@link DeriveKeyPairError}.
* If the error occurred, throws {@link DeserializeError}.
*
* @param ikm An input keying material.
* @returns A key pair derived.
* @throws {@link DeriveKeyPairError}
* @param key A key as bytes.
* @returns A CryptoKey.
* @throws {@link DeserializeError}
*/
deriveKeyPair(ikm: ArrayBuffer): Promise<CryptoKeyPair>;
deserializePublicKey(key: ArrayBuffer): Promise<CryptoKey>;
/**
* Serializes a public key as CryptoKey to a byte string of length `Npk`.
* Serializes a private key as CryptoKey to a byte string of length `Nsk`.
*

@@ -47,5 +48,5 @@ * If the error occurred, throws {@link SerializeError}.

*/
serializePublicKey(key: CryptoKey): Promise<ArrayBuffer>;
serializePrivateKey(key: CryptoKey): Promise<ArrayBuffer>;
/**
* Deserializes a public key as a byte string of length `Npk` to CryptoKey.
* Deserializes a private key as a byte string of length `Nsk` to CryptoKey.
*

@@ -58,3 +59,3 @@ * If the error occurred, throws {@link DeserializeError}.

*/
deserializePublicKey(key: ArrayBuffer): Promise<CryptoKey>;
deserializePrivateKey(key: ArrayBuffer): Promise<CryptoKey>;
/**

@@ -80,2 +81,21 @@ * Imports a public or private key and converts to a {@link CryptoKey}.

/**
* Generates a key pair.
*
* If the error occurred, throws {@link NotSupportedError}.
*
* @returns A key pair generated.
* @throws {@link NotSupportedError}
*/
generateKeyPair(): Promise<CryptoKeyPair>;
/**
* Derives a key pair from the byte string ikm.
*
* If the error occurred, throws {@link DeriveKeyPairError}.
*
* @param ikm An input keying material.
* @returns A key pair derived.
* @throws {@link DeriveKeyPairError}
*/
deriveKeyPair(ikm: ArrayBuffer): Promise<CryptoKeyPair>;
/**
* Generates an ephemeral, fixed-length symmetric key and

@@ -82,0 +102,0 @@ * a fixed-length encapsulation of the key that can be decapsulated

import type { KdfInterface } from "../interfaces/kdfInterface.js";
import { AlgorithmBase } from "../algorithm.js";
import { NativeAlgorithm } from "../algorithm.js";
import { KdfId } from "../identifiers.js";
export declare class KdfAlgorithm extends AlgorithmBase {
protected _suiteId: Uint8Array;
constructor();
init(suiteId: Uint8Array): void;
protected checkInit(): void;
}
export declare class HkdfNative extends KdfAlgorithm implements KdfInterface {
export declare class HkdfNative extends NativeAlgorithm implements KdfInterface {
readonly id: KdfId;
readonly hashSize: number;
protected _suiteId: Uint8Array;
protected readonly algHash: HmacKeyGenParams;
constructor();
init(suiteId: Uint8Array): void;
buildLabeledIkm(label: Uint8Array, ikm: Uint8Array): Uint8Array;

@@ -22,3 +18,3 @@ buildLabeledInfo(label: Uint8Array, info: Uint8Array, len: number): Uint8Array;

labeledExpand(prk: ArrayBuffer, label: Uint8Array, info: Uint8Array, len: number): Promise<ArrayBuffer>;
protected setup(): Promise<void>;
protected _checkInit(): void;
}

@@ -25,0 +21,0 @@ export declare class HkdfSha256Native extends HkdfNative {

@@ -1,4 +0,3 @@

import { AlgorithmBase } from "../algorithm.js";
import { NativeAlgorithm } from "../algorithm.js";
import { KdfId } from "../identifiers.js";
import { loadSubtleCrypto } from "../webCrypto.js";
import * as consts from "../consts.js";

@@ -8,24 +7,5 @@ import * as errors from "../errors.js";

const HPKE_VERSION = new Uint8Array([72, 80, 75, 69, 45, 118, 49]);
export class KdfAlgorithm extends AlgorithmBase {
export class HkdfNative extends NativeAlgorithm {
constructor() {
super();
Object.defineProperty(this, "_suiteId", {
enumerable: true,
configurable: true,
writable: true,
value: consts.EMPTY
});
}
init(suiteId) {
this._suiteId = suiteId;
}
checkInit() {
if (this._suiteId === consts.EMPTY) {
throw new Error("Not initialized. Call init()");
}
}
}
export class HkdfNative extends KdfAlgorithm {
constructor() {
super();
Object.defineProperty(this, "id", {

@@ -43,2 +23,8 @@ enumerable: true,

});
Object.defineProperty(this, "_suiteId", {
enumerable: true,
configurable: true,
writable: true,
value: consts.EMPTY
});
Object.defineProperty(this, "algHash", {

@@ -55,4 +41,7 @@ enumerable: true,

}
init(suiteId) {
this._suiteId = suiteId;
}
buildLabeledIkm(label, ikm) {
this.checkInit();
this._checkInit();
const ret = new Uint8Array(7 + this._suiteId.byteLength + label.byteLength + ikm.byteLength);

@@ -66,3 +55,3 @@ ret.set(HPKE_VERSION, 0);

buildLabeledInfo(label, info, len) {
this.checkInit();
this._checkInit();
const ret = new Uint8Array(9 + this._suiteId.byteLength + label.byteLength + info.byteLength);

@@ -77,3 +66,3 @@ ret.set(new Uint8Array([0, len]), 0);

async extract(salt, ikm) {
await this.setup();
await this._setup();
if (salt.byteLength === 0) {

@@ -91,3 +80,3 @@ salt = new ArrayBuffer(this.hashSize);

async expand(prk, info, len) {
await this.setup();
await this._setup();
const key = await this._api.importKey("raw", prk, this.algHash, false, [

@@ -123,3 +112,3 @@ "sign",

async extractAndExpand(salt, ikm, info, len) {
await this.setup();
await this._setup();
const baseKey = await this._api.importKey("raw", ikm, "HKDF", false, ["deriveBits"]);

@@ -139,7 +128,6 @@ return await this._api.deriveBits({

}
async setup() {
if (this._api !== undefined) {
return;
_checkInit() {
if (this._suiteId === consts.EMPTY) {
throw new Error("Not initialized. Call init()");
}
this._api = await loadSubtleCrypto();
}

@@ -146,0 +134,0 @@ }

@@ -8,3 +8,3 @@ // @ts-ignore: for "npm:"

async extract(salt, ikm) {
await this.setup();
await this._setup();
if (salt.byteLength === 0) {

@@ -11,0 +11,0 @@ salt = new ArrayBuffer(this.hashSize);

import type { KdfInterface } from "../interfaces/kdfInterface.js";
import type { KemInterface } from "../interfaces/kemInterface.js";
import type { KemPrimitives } from "../interfaces/kemPrimitives.js";
import type { DhkemPrimitives } from "../interfaces/dhkemPrimitives.js";
import type { SenderContextParams } from "../interfaces/senderContextParams.js";
import type { RecipientContextParams } from "../interfaces/recipientContextParams.js";
import { Algorithm } from "../algorithm.js";
import { KemId } from "../identifiers.js";
export declare class Dhkem extends Algorithm implements KemInterface {
export declare class Dhkem implements KemInterface {
readonly id: KemId;

@@ -14,10 +13,12 @@ readonly secretSize: number;

readonly privateKeySize: number;
protected _prim: KemPrimitives;
protected _prim: DhkemPrimitives;
protected _kdf: KdfInterface;
constructor(prim: KemPrimitives, kdf: KdfInterface);
generateKeyPair(): Promise<CryptoKeyPair>;
deriveKeyPair(ikm: ArrayBuffer): Promise<CryptoKeyPair>;
constructor(id: KemId, prim: DhkemPrimitives, kdf: KdfInterface);
serializePublicKey(key: CryptoKey): Promise<ArrayBuffer>;
deserializePublicKey(key: ArrayBuffer): Promise<CryptoKey>;
serializePrivateKey(key: CryptoKey): Promise<ArrayBuffer>;
deserializePrivateKey(key: ArrayBuffer): Promise<CryptoKey>;
importKey(format: "raw" | "jwk", key: ArrayBuffer | JsonWebKey, isPublic?: boolean): Promise<CryptoKey>;
generateKeyPair(): Promise<CryptoKeyPair>;
deriveKeyPair(ikm: ArrayBuffer): Promise<CryptoKeyPair>;
encap(params: SenderContextParams): Promise<{

@@ -28,4 +29,3 @@ sharedSecret: ArrayBuffer;

decap(params: RecipientContextParams): Promise<ArrayBuffer>;
private _setup;
private _generateSharedSecret;
}

@@ -1,5 +0,2 @@

import { Algorithm } from "../algorithm.js";
import { KemId } from "../identifiers.js";
import { loadSubtleCrypto } from "../webCrypto.js";
import { concat, concat3, i2Osp, isCryptoKeyPair } from "../utils/misc.js";
import { i2Osp, isCryptoKeyPair } from "../utils/misc.js";
import { EMPTY, INPUT_LENGTH_LIMIT } from "../consts.js";

@@ -12,20 +9,22 @@ import * as errors from "../errors.js";

// b"shared_secret"
// deno-fmt-ignore
const LABEL_SHARED_SECRET = new Uint8Array([
115,
104,
97,
114,
101,
100,
95,
115,
101,
99,
114,
101,
116,
115, 104, 97, 114, 101, 100, 95, 115, 101, 99,
114, 101, 116,
]);
export class Dhkem extends Algorithm {
constructor(prim, kdf) {
super();
function concat(a, b) {
const ret = new Uint8Array(a.length + b.length);
ret.set(a, 0);
ret.set(b, a.length);
return ret;
}
function concat3(a, b, c) {
const ret = new Uint8Array(a.length + b.length + c.length);
ret.set(a, 0);
ret.set(b, a.length);
ret.set(c, a.length + b.length);
return ret;
}
export class Dhkem {
constructor(id, prim, kdf) {
Object.defineProperty(this, "id", {

@@ -35,3 +34,3 @@ enumerable: true,

writable: true,
value: KemId.DhkemP256HkdfSha256
value: void 0
});

@@ -74,13 +73,26 @@ Object.defineProperty(this, "secretSize", {

});
this.id = id;
this._prim = prim;
this._kdf = kdf;
const suiteId = new Uint8Array(SUITE_ID_HEADER_KEM);
suiteId.set(i2Osp(this.id, 2), 3);
this._kdf.init(suiteId);
}
async serializePublicKey(key) {
return await this._prim.serializePublicKey(key);
}
async deserializePublicKey(key) {
return await this._prim.deserializePublicKey(key);
}
async serializePrivateKey(key) {
return await this._prim.serializePrivateKey(key);
}
async deserializePrivateKey(key) {
return await this._prim.deserializePrivateKey(key);
}
async importKey(format, key, isPublic = true) {
return await this._prim.importKey(format, key, isPublic);
}
async generateKeyPair() {
await this._setup();
try {
return await this._prim.generateKeyPair();
}
catch (e) {
throw new errors.NotSupportedError(e);
}
return await this._prim.generateKeyPair();
}

@@ -91,45 +103,11 @@ async deriveKeyPair(ikm) {

}
await this._setup();
try {
return await this._prim.deriveKeyPair(ikm);
}
catch (e) {
throw new errors.DeriveKeyPairError(e);
}
return await this._prim.deriveKeyPair(ikm);
}
async serializePublicKey(key) {
await this._setup();
try {
return await this._prim.serializePublicKey(key);
}
catch (e) {
throw new errors.SerializeError(e);
}
}
async deserializePublicKey(key) {
await this._setup();
try {
return await this._prim.deserializePublicKey(key);
}
catch (e) {
throw new errors.DeserializeError(e);
}
}
async importKey(format, key, isPublic = true) {
await this._setup();
try {
return await this._prim.importKey(format, key, isPublic);
}
catch (e) {
throw new errors.DeserializeError(e);
}
}
async encap(params) {
await this._setup();
const ke = params.nonEphemeralKeyPair === undefined
? await this.generateKeyPair()
: params.nonEphemeralKeyPair;
const enc = await this._prim.serializePublicKey(ke.publicKey);
const pkrm = await this._prim.serializePublicKey(params.recipientPublicKey);
try {
const ke = params.nonEphemeralKeyPair === undefined
? await this.generateKeyPair()
: params.nonEphemeralKeyPair;
const enc = await this._prim.serializePublicKey(ke.publicKey);
const pkrm = await this._prim.serializePublicKey(params.recipientPublicKey);
let dh;

@@ -169,18 +147,11 @@ if (params.senderKey === undefined) {

async decap(params) {
let pke;
await this._setup();
const pke = await this._prim.deserializePublicKey(params.enc);
const skr = isCryptoKeyPair(params.recipientKey)
? params.recipientKey.privateKey
: params.recipientKey;
const pkr = isCryptoKeyPair(params.recipientKey)
? params.recipientKey.publicKey
: await this._prim.derivePublicKey(params.recipientKey);
const pkrm = await this._prim.serializePublicKey(pkr);
try {
pke = await this._prim.deserializePublicKey(params.enc);
}
catch (e) {
throw new errors.DeserializeError(e);
}
try {
const skr = isCryptoKeyPair(params.recipientKey)
? params.recipientKey.privateKey
: params.recipientKey;
const pkr = isCryptoKeyPair(params.recipientKey)
? params.recipientKey.publicKey
: await this._prim.derivePublicKey(params.recipientKey);
const pkrm = await this._prim.serializePublicKey(pkr);
let dh;

@@ -212,13 +183,2 @@ if (params.senderPublicKey === undefined) {

}
async _setup() {
if (this._api !== undefined) {
return;
}
const api = await loadSubtleCrypto();
const suiteId = new Uint8Array(SUITE_ID_HEADER_KEM);
suiteId.set(i2Osp(this.id, 2), 3);
this._prim.init(api);
this._kdf.init(suiteId);
super.init(api);
}
async _generateSharedSecret(dh, kemContext) {

@@ -225,0 +185,0 @@ const labeledIkm = this._kdf.buildLabeledIkm(LABEL_EAE_PRK, dh);

@@ -1,5 +0,4 @@

import type { KemPrimitives } from "../../interfaces/kemPrimitives.js";
import type { DhkemPrimitives } from "../../interfaces/dhkemPrimitives.js";
import type { KdfInterface } from "../../interfaces/kdfInterface.js";
import { Algorithm } from "../../algorithm.js";
export declare class X448 extends Algorithm implements KemPrimitives {
export declare class X448 implements DhkemPrimitives {
private _hkdf;

@@ -11,9 +10,11 @@ private _nPk;

deserializePublicKey(key: ArrayBuffer): Promise<CryptoKey>;
serializePrivateKey(key: CryptoKey): Promise<ArrayBuffer>;
deserializePrivateKey(key: ArrayBuffer): Promise<CryptoKey>;
importKey(format: "raw" | "jwk", key: ArrayBuffer | JsonWebKey, isPublic: boolean): Promise<CryptoKey>;
derivePublicKey(key: CryptoKey): Promise<CryptoKey>;
generateKeyPair(): Promise<CryptoKeyPair>;
deriveKeyPair(ikm: ArrayBuffer): Promise<CryptoKeyPair>;
derivePublicKey(key: CryptoKey): Promise<CryptoKey>;
dh(sk: CryptoKey, pk: CryptoKey): Promise<ArrayBuffer>;
private _serializePublicKey;
private _deserializePublicKey;
private _serializePrivateKey;
private _importRawKey;

@@ -20,0 +21,0 @@ private _importJWK;

// @ts-ignore: for "npm:"
import { ed448, x448 } from "@noble/curves/ed448";
import { Algorithm } from "../../algorithm.js";
import { KEM_USAGES, LABEL_DKP_PRK, LABEL_SK, } from "../../interfaces/kemPrimitives.js";
import { XCryptoKey } from "../../xCryptoKey.js";
import * as consts from "../../consts.js";
import * as errors from "../../errors.js";
import { KEM_USAGES, LABEL_DKP_PRK, LABEL_SK, } from "../../interfaces/dhkemPrimitives.js";
import { base64UrlToBytes } from "../../utils/misc.js";
import { XCryptoKey } from "../../xCryptoKey.js";
const ALG_NAME = "X448";
export class X448 extends Algorithm {
export class X448 {
constructor(hkdf) {
super();
Object.defineProperty(this, "_hkdf", {

@@ -35,37 +34,88 @@ enumerable: true,

async serializePublicKey(key) {
return await this._serializePublicKey(key);
try {
return await this._serializePublicKey(key);
}
catch (e) {
throw new errors.SerializeError(e);
}
}
async deserializePublicKey(key) {
return await this._deserializePublicKey(key);
try {
return await this._importRawKey(key, true);
}
catch (e) {
throw new errors.DeserializeError(e);
}
}
async serializePrivateKey(key) {
try {
return await this._serializePrivateKey(key);
}
catch (e) {
throw new errors.SerializeError(e);
}
}
async deserializePrivateKey(key) {
try {
return await this._importRawKey(key, false);
}
catch (e) {
throw new errors.DeserializeError(e);
}
}
async importKey(format, key, isPublic) {
if (format === "raw") {
return await this._importRawKey(key, isPublic);
try {
if (format === "raw") {
return await this._importRawKey(key, isPublic);
}
// jwk
if (key instanceof ArrayBuffer) {
throw new Error("Invalid jwk key format");
}
return await this._importJWK(key, isPublic);
}
// jwk
if (key instanceof ArrayBuffer) {
throw new Error("Invalid jwk key format");
catch (e) {
throw new errors.DeserializeError(e);
}
return await this._importJWK(key, isPublic);
}
async derivePublicKey(key) {
return await this._derivePublicKey(key);
}
async generateKeyPair() {
const rawSk = ed448.utils.randomPrivateKey();
const sk = new XCryptoKey(ALG_NAME, rawSk, "private", KEM_USAGES);
const pk = await this.derivePublicKey(sk);
return { publicKey: pk, privateKey: sk };
try {
const rawSk = ed448.utils.randomPrivateKey();
const sk = new XCryptoKey(ALG_NAME, rawSk, "private", KEM_USAGES);
const pk = await this.derivePublicKey(sk);
return { publicKey: pk, privateKey: sk };
}
catch (e) {
throw new errors.NotSupportedError(e);
}
}
async deriveKeyPair(ikm) {
const dkpPrk = await this._hkdf.labeledExtract(consts.EMPTY, LABEL_DKP_PRK, new Uint8Array(ikm));
const rawSk = await this._hkdf.labeledExpand(dkpPrk, LABEL_SK, consts.EMPTY, this._nSk);
const sk = new XCryptoKey(ALG_NAME, new Uint8Array(rawSk), "private", KEM_USAGES);
return {
privateKey: sk,
publicKey: await this.derivePublicKey(sk),
};
try {
const dkpPrk = await this._hkdf.labeledExtract(consts.EMPTY, LABEL_DKP_PRK, new Uint8Array(ikm));
const rawSk = await this._hkdf.labeledExpand(dkpPrk, LABEL_SK, consts.EMPTY, this._nSk);
const sk = new XCryptoKey(ALG_NAME, new Uint8Array(rawSk), "private", KEM_USAGES);
return {
privateKey: sk,
publicKey: await this.derivePublicKey(sk),
};
}
catch (e) {
throw new errors.DeriveKeyPairError(e);
}
}
async derivePublicKey(key) {
try {
return await this._derivePublicKey(key);
}
catch (e) {
throw new errors.DeserializeError(e);
}
}
async dh(sk, pk) {
return await this._dh(sk, pk);
try {
return await this._dh(sk, pk);
}
catch (e) {
throw new errors.SerializeError(e);
}
}

@@ -77,10 +127,5 @@ _serializePublicKey(k) {

}
_deserializePublicKey(k) {
return new Promise((resolve, reject) => {
if (k.byteLength !== this._nPk) {
reject(new Error("Invalid public key for the ciphersuite"));
}
else {
resolve(new XCryptoKey(ALG_NAME, new Uint8Array(k), "public"));
}
_serializePrivateKey(k) {
return new Promise((resolve) => {
resolve(k.key.buffer);
});

@@ -91,6 +136,7 @@ }

if (isPublic && key.byteLength !== this._nPk) {
reject(new Error("Invalid public key for the ciphersuite"));
reject(new Error("Invalid length of the key"));
}
if (!isPublic && key.byteLength !== this._nSk) {
reject(new Error("Invalid private key for the ciphersuite"));
if (!isPublic &&
(key.byteLength !== this._nSk && key.byteLength !== this._nSk + 1)) {
reject(new Error("Invalid length of the key"));
}

@@ -126,5 +172,10 @@ resolve(new XCryptoKey(ALG_NAME, new Uint8Array(key), isPublic ? "public" : "private", isPublic ? [] : KEM_USAGES));

_derivePublicKey(k) {
return new Promise((resolve) => {
const pk = x448.getPublicKey(k.key);
resolve(new XCryptoKey(ALG_NAME, pk, "public"));
return new Promise((resolve, reject) => {
try {
const pk = x448.getPublicKey(k.key);
resolve(new XCryptoKey(ALG_NAME, pk, "public"));
}
catch (e) {
reject(e);
}
});

@@ -131,0 +182,0 @@ }

@@ -28,4 +28,3 @@ import { KemId } from "../identifiers.js";

const kdf = new HkdfSha512();
const prim = new X448(kdf);
super(prim, kdf);
super(KemId.DhkemX448HkdfSha512, new X448(kdf), kdf);
Object.defineProperty(this, "id", {

@@ -32,0 +31,0 @@ enumerable: true,

@@ -22,24 +22,4 @@ /**

/**
* Executes XOR of two byte strings.
*/
export declare function xor(a: Uint8Array, b: Uint8Array): Uint8Array;
/**
* Concatenates two Uint8Arrays.
*/
export declare function concat(a: Uint8Array, b: Uint8Array): Uint8Array;
/**
* Concatenates three Uint8Arrays.
*/
export declare function concat3(a: Uint8Array, b: Uint8Array, c: Uint8Array): Uint8Array;
/**
* Converts hex string to bytes.
*/
export declare function hexToBytes(v: string): Uint8Array;
/**
* Converts bytes to hex string.
*/
export declare function bytesToHex(v: Uint8Array): string;
/**
* Decodes Base64Url-encoded data.
*/
export declare function base64UrlToBytes(v: string): Uint8Array;

@@ -39,55 +39,2 @@ import * as dntShim from "../../_dnt.shims.js";

/**
* Executes XOR of two byte strings.
*/
export function xor(a, b) {
if (a.byteLength !== b.byteLength) {
throw new Error("xor: different length inputs");
}
const buf = new Uint8Array(a.byteLength);
for (let i = 0; i < a.byteLength; i++) {
buf[i] = a[i] ^ b[i];
}
return buf;
}
/**
* Concatenates two Uint8Arrays.
*/
export function concat(a, b) {
const ret = new Uint8Array(a.length + b.length);
ret.set(a, 0);
ret.set(b, a.length);
return ret;
}
/**
* Concatenates three Uint8Arrays.
*/
export function concat3(a, b, c) {
const ret = new Uint8Array(a.length + b.length + c.length);
ret.set(a, 0);
ret.set(b, a.length);
ret.set(c, a.length + b.length);
return ret;
}
/**
* Converts hex string to bytes.
*/
export function hexToBytes(v) {
if (v.length === 0) {
return new Uint8Array([]);
}
const res = v.match(/[\da-f]{2}/gi);
if (res == null) {
throw new Error("hexToBytes: not hex string");
}
return new Uint8Array(res.map(function (h) {
return parseInt(h, 16);
}));
}
/**
* Converts bytes to hex string.
*/
export function bytesToHex(v) {
return [...v].map((x) => x.toString(16).padStart(2, "0")).join("");
}
/**
* Decodes Base64Url-encoded data.

@@ -94,0 +41,0 @@ */

@@ -6,3 +6,3 @@ {

"name": "@hpke/dhkem-x448",
"version": "1.0.4",
"version": "1.1.0",
"description": "A Hybrid Public Key Encryption (HPKE) module extension for X448",

@@ -9,0 +9,0 @@ "repository": {

@@ -34,4 +34,4 @@ <h1 align="center">@hpke/dhkem-x448</h1>

<script type="module">
import * as hpke from "https://esm.sh/@hpke/core@1.0.4";
import * as x448 from "https://esm.sh/@hpke/dhkem-x448@1.0.4";
import * as hpke from "https://esm.sh/@hpke/core@1.1.0";
import * as x448 from "https://esm.sh/@hpke/dhkem-x448@1.1.0";
// ...

@@ -53,4 +53,4 @@ </script>

<script type="module">
import * as hpke from "https://unpkg.com/@hpke/core@1.0.4/esm/mod.js";
import * as x448 from "https://unpkg.com/@hpke/dhkem-x448@1.0.4/esm/mod.js";
import * as hpke from "https://unpkg.com/@hpke/core@1.1.0/esm/mod.js";
import * as x448 from "https://unpkg.com/@hpke/dhkem-x448@1.1.0/esm/mod.js";
// ...

@@ -80,4 +80,4 @@ </script>

// use a specific version
import * as hpke from "https://deno.land/x/hpke@1.0.4/core/mod.ts";
import * as x448 from "https://deno.land/x/hpke@1.0.4/x/dhkem-x448/mod.ts";
import * as hpke from "https://deno.land/x/hpke@1.1.0/core/mod.ts";
import * as x448 from "https://deno.land/x/hpke@1.1.0/x/dhkem-x448/mod.ts";

@@ -110,4 +110,4 @@ // use the latest stable version

<script type="module">
import { KdfId, AeadId, CipherSuite } from "https://esm.sh/@hpke/core@1.0.4";
import { DhkemX448HkdfSha512 } from "https://esm.sh/@hpke/dhkem-x448@1.0.4";
import { KdfId, AeadId, CipherSuite } from "https://esm.sh/@hpke/core@1.1.0";
import { DhkemX448HkdfSha512 } from "https://esm.sh/@hpke/dhkem-x448@1.1.0";

@@ -199,4 +199,4 @@ globalThis.doHpke = async () => {

```js
import { KdfId, AeadId, CipherSuite } from "https://deno.land/x/hpke@1.0.4/core/mod.ts";
import { DhkemX448HkdfSha512 } from "https://deno.land/x/hpke@1.0.4/x/dhkem-x448/mod.ts";
import { KdfId, AeadId, CipherSuite } from "https://deno.land/x/hpke@1.1.0/core/mod.ts";
import { DhkemX448HkdfSha512 } from "https://deno.land/x/hpke@1.1.0/x/dhkem-x448/mod.ts";

@@ -203,0 +203,0 @@ async function doHpke() {

@@ -1,9 +0,5 @@

export declare class AlgorithmBase {
export declare class NativeAlgorithm {
protected _api: SubtleCrypto | undefined;
constructor();
protected _setup(): Promise<void>;
}
export declare class Algorithm extends AlgorithmBase {
constructor();
init(api: SubtleCrypto): void;
protected checkInit(): void;
}

@@ -0,1 +1,24 @@

var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
(function (factory) {

@@ -7,9 +30,28 @@ if (typeof module === "object" && typeof module.exports === "object") {

else if (typeof define === "function" && define.amd) {
define(["require", "exports"], factory);
define(["require", "exports", "./errors.js", "./utils/misc.js"], factory);
}
})(function (require, exports) {
"use strict";
var __syncRequire = typeof module === "object" && typeof module.exports === "object";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Algorithm = exports.AlgorithmBase = void 0;
class AlgorithmBase {
exports.NativeAlgorithm = void 0;
const errors_js_1 = require("./errors.js");
const misc_js_1 = require("./utils/misc.js");
async function loadSubtleCrypto() {
if ((0, misc_js_1.isBrowser)() || (0, misc_js_1.isCloudflareWorkers)()) {
if (globalThis.crypto !== undefined) {
return globalThis.crypto.subtle;
}
// jsdom
}
try {
// @ts-ignore: to ignore "crypto"
const { webcrypto } = await (__syncRequire ? Promise.resolve().then(() => __importStar(require("crypto"))) : new Promise((resolve_1, reject_1) => { require(["crypto"], resolve_1, reject_1); }).then(__importStar)); // node:crypto
return webcrypto.subtle;
}
catch (e) {
throw new errors_js_1.NotSupportedError(e);
}
}
class NativeAlgorithm {
constructor() {

@@ -23,18 +65,10 @@ Object.defineProperty(this, "_api", {

}
}
exports.AlgorithmBase = AlgorithmBase;
class Algorithm extends AlgorithmBase {
constructor() {
super();
}
init(api) {
this._api = api;
}
checkInit() {
if (this._api === undefined) {
throw new Error("Not initialized. Call init()");
async _setup() {
if (this._api !== undefined) {
return;
}
this._api = await loadSubtleCrypto();
}
}
exports.Algorithm = Algorithm;
exports.NativeAlgorithm = NativeAlgorithm;
});

@@ -20,2 +20,3 @@ /**

export declare const Kem: {
readonly NotAssigned: 0;
readonly DhkemP256HkdfSha256: 16;

@@ -38,2 +39,3 @@ readonly DhkemP384HkdfSha384: 17;

export declare const KemId: {
readonly NotAssigned: 0;
readonly DhkemP256HkdfSha256: 16;

@@ -40,0 +42,0 @@ readonly DhkemP384HkdfSha384: 17;

@@ -28,2 +28,3 @@ (function (factory) {

exports.Kem = {
NotAssigned: 0x0000,
DhkemP256HkdfSha256: 0x0010,

@@ -30,0 +31,0 @@ DhkemP384HkdfSha384: 0x0011,

@@ -19,22 +19,23 @@ import type { RecipientContextParams } from "./recipientContextParams.js";

/**
* Generates a key pair.
* Serializes a public key as CryptoKey to a byte string of length `Npk`.
*
* If the error occurred, throws {@link NotSupportedError}.
* If the error occurred, throws {@link SerializeError}.
*
* @returns A key pair generated.
* @throws {@link NotSupportedError}
* @param key A CryptoKey.
* @returns A key as bytes.
* @throws {@link SerializeError}
*/
generateKeyPair(): Promise<CryptoKeyPair>;
serializePublicKey(key: CryptoKey): Promise<ArrayBuffer>;
/**
* Derives a key pair from the byte string ikm.
* Deserializes a public key as a byte string of length `Npk` to CryptoKey.
*
* If the error occurred, throws {@link DeriveKeyPairError}.
* If the error occurred, throws {@link DeserializeError}.
*
* @param ikm An input keying material.
* @returns A key pair derived.
* @throws {@link DeriveKeyPairError}
* @param key A key as bytes.
* @returns A CryptoKey.
* @throws {@link DeserializeError}
*/
deriveKeyPair(ikm: ArrayBuffer): Promise<CryptoKeyPair>;
deserializePublicKey(key: ArrayBuffer): Promise<CryptoKey>;
/**
* Serializes a public key as CryptoKey to a byte string of length `Npk`.
* Serializes a private key as CryptoKey to a byte string of length `Nsk`.
*

@@ -47,5 +48,5 @@ * If the error occurred, throws {@link SerializeError}.

*/
serializePublicKey(key: CryptoKey): Promise<ArrayBuffer>;
serializePrivateKey(key: CryptoKey): Promise<ArrayBuffer>;
/**
* Deserializes a public key as a byte string of length `Npk` to CryptoKey.
* Deserializes a private key as a byte string of length `Nsk` to CryptoKey.
*

@@ -58,3 +59,3 @@ * If the error occurred, throws {@link DeserializeError}.

*/
deserializePublicKey(key: ArrayBuffer): Promise<CryptoKey>;
deserializePrivateKey(key: ArrayBuffer): Promise<CryptoKey>;
/**

@@ -80,2 +81,21 @@ * Imports a public or private key and converts to a {@link CryptoKey}.

/**
* Generates a key pair.
*
* If the error occurred, throws {@link NotSupportedError}.
*
* @returns A key pair generated.
* @throws {@link NotSupportedError}
*/
generateKeyPair(): Promise<CryptoKeyPair>;
/**
* Derives a key pair from the byte string ikm.
*
* If the error occurred, throws {@link DeriveKeyPairError}.
*
* @param ikm An input keying material.
* @returns A key pair derived.
* @throws {@link DeriveKeyPairError}
*/
deriveKeyPair(ikm: ArrayBuffer): Promise<CryptoKeyPair>;
/**
* Generates an ephemeral, fixed-length symmetric key and

@@ -82,0 +102,0 @@ * a fixed-length encapsulation of the key that can be decapsulated

import type { KdfInterface } from "../interfaces/kdfInterface.js";
import { AlgorithmBase } from "../algorithm.js";
import { NativeAlgorithm } from "../algorithm.js";
import { KdfId } from "../identifiers.js";
export declare class KdfAlgorithm extends AlgorithmBase {
protected _suiteId: Uint8Array;
constructor();
init(suiteId: Uint8Array): void;
protected checkInit(): void;
}
export declare class HkdfNative extends KdfAlgorithm implements KdfInterface {
export declare class HkdfNative extends NativeAlgorithm implements KdfInterface {
readonly id: KdfId;
readonly hashSize: number;
protected _suiteId: Uint8Array;
protected readonly algHash: HmacKeyGenParams;
constructor();
init(suiteId: Uint8Array): void;
buildLabeledIkm(label: Uint8Array, ikm: Uint8Array): Uint8Array;

@@ -22,3 +18,3 @@ buildLabeledInfo(label: Uint8Array, info: Uint8Array, len: number): Uint8Array;

labeledExpand(prk: ArrayBuffer, label: Uint8Array, info: Uint8Array, len: number): Promise<ArrayBuffer>;
protected setup(): Promise<void>;
protected _checkInit(): void;
}

@@ -25,0 +21,0 @@ export declare class HkdfSha256Native extends HkdfNative {

@@ -30,3 +30,3 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {

else if (typeof define === "function" && define.amd) {
define(["require", "exports", "../algorithm.js", "../identifiers.js", "../webCrypto.js", "../consts.js", "../errors.js"], factory);
define(["require", "exports", "../algorithm.js", "../identifiers.js", "../consts.js", "../errors.js"], factory);
}

@@ -36,6 +36,5 @@ })(function (require, exports) {

Object.defineProperty(exports, "__esModule", { value: true });
exports.HkdfSha512Native = exports.HkdfSha384Native = exports.HkdfSha256Native = exports.HkdfNative = exports.KdfAlgorithm = void 0;
exports.HkdfSha512Native = exports.HkdfSha384Native = exports.HkdfSha256Native = exports.HkdfNative = void 0;
const algorithm_js_1 = require("../algorithm.js");
const identifiers_js_1 = require("../identifiers.js");
const webCrypto_js_1 = require("../webCrypto.js");
const consts = __importStar(require("../consts.js"));

@@ -45,25 +44,5 @@ const errors = __importStar(require("../errors.js"));

const HPKE_VERSION = new Uint8Array([72, 80, 75, 69, 45, 118, 49]);
class KdfAlgorithm extends algorithm_js_1.AlgorithmBase {
class HkdfNative extends algorithm_js_1.NativeAlgorithm {
constructor() {
super();
Object.defineProperty(this, "_suiteId", {
enumerable: true,
configurable: true,
writable: true,
value: consts.EMPTY
});
}
init(suiteId) {
this._suiteId = suiteId;
}
checkInit() {
if (this._suiteId === consts.EMPTY) {
throw new Error("Not initialized. Call init()");
}
}
}
exports.KdfAlgorithm = KdfAlgorithm;
class HkdfNative extends KdfAlgorithm {
constructor() {
super();
Object.defineProperty(this, "id", {

@@ -81,2 +60,8 @@ enumerable: true,

});
Object.defineProperty(this, "_suiteId", {
enumerable: true,
configurable: true,
writable: true,
value: consts.EMPTY
});
Object.defineProperty(this, "algHash", {

@@ -93,4 +78,7 @@ enumerable: true,

}
init(suiteId) {
this._suiteId = suiteId;
}
buildLabeledIkm(label, ikm) {
this.checkInit();
this._checkInit();
const ret = new Uint8Array(7 + this._suiteId.byteLength + label.byteLength + ikm.byteLength);

@@ -104,3 +92,3 @@ ret.set(HPKE_VERSION, 0);

buildLabeledInfo(label, info, len) {
this.checkInit();
this._checkInit();
const ret = new Uint8Array(9 + this._suiteId.byteLength + label.byteLength + info.byteLength);

@@ -115,3 +103,3 @@ ret.set(new Uint8Array([0, len]), 0);

async extract(salt, ikm) {
await this.setup();
await this._setup();
if (salt.byteLength === 0) {

@@ -129,3 +117,3 @@ salt = new ArrayBuffer(this.hashSize);

async expand(prk, info, len) {
await this.setup();
await this._setup();
const key = await this._api.importKey("raw", prk, this.algHash, false, [

@@ -161,3 +149,3 @@ "sign",

async extractAndExpand(salt, ikm, info, len) {
await this.setup();
await this._setup();
const baseKey = await this._api.importKey("raw", ikm, "HKDF", false, ["deriveBits"]);

@@ -177,7 +165,6 @@ return await this._api.deriveBits({

}
async setup() {
if (this._api !== undefined) {
return;
_checkInit() {
if (this._suiteId === consts.EMPTY) {
throw new Error("Not initialized. Call init()");
}
this._api = await (0, webCrypto_js_1.loadSubtleCrypto)();
}

@@ -184,0 +171,0 @@ }

@@ -20,3 +20,3 @@ (function (factory) {

async extract(salt, ikm) {
await this.setup();
await this._setup();
if (salt.byteLength === 0) {

@@ -23,0 +23,0 @@ salt = new ArrayBuffer(this.hashSize);

import type { KdfInterface } from "../interfaces/kdfInterface.js";
import type { KemInterface } from "../interfaces/kemInterface.js";
import type { KemPrimitives } from "../interfaces/kemPrimitives.js";
import type { DhkemPrimitives } from "../interfaces/dhkemPrimitives.js";
import type { SenderContextParams } from "../interfaces/senderContextParams.js";
import type { RecipientContextParams } from "../interfaces/recipientContextParams.js";
import { Algorithm } from "../algorithm.js";
import { KemId } from "../identifiers.js";
export declare class Dhkem extends Algorithm implements KemInterface {
export declare class Dhkem implements KemInterface {
readonly id: KemId;

@@ -14,10 +13,12 @@ readonly secretSize: number;

readonly privateKeySize: number;
protected _prim: KemPrimitives;
protected _prim: DhkemPrimitives;
protected _kdf: KdfInterface;
constructor(prim: KemPrimitives, kdf: KdfInterface);
generateKeyPair(): Promise<CryptoKeyPair>;
deriveKeyPair(ikm: ArrayBuffer): Promise<CryptoKeyPair>;
constructor(id: KemId, prim: DhkemPrimitives, kdf: KdfInterface);
serializePublicKey(key: CryptoKey): Promise<ArrayBuffer>;
deserializePublicKey(key: ArrayBuffer): Promise<CryptoKey>;
serializePrivateKey(key: CryptoKey): Promise<ArrayBuffer>;
deserializePrivateKey(key: ArrayBuffer): Promise<CryptoKey>;
importKey(format: "raw" | "jwk", key: ArrayBuffer | JsonWebKey, isPublic?: boolean): Promise<CryptoKey>;
generateKeyPair(): Promise<CryptoKeyPair>;
deriveKeyPair(ikm: ArrayBuffer): Promise<CryptoKeyPair>;
encap(params: SenderContextParams): Promise<{

@@ -28,4 +29,3 @@ sharedSecret: ArrayBuffer;

decap(params: RecipientContextParams): Promise<ArrayBuffer>;
private _setup;
private _generateSharedSecret;
}

@@ -30,3 +30,3 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {

else if (typeof define === "function" && define.amd) {
define(["require", "exports", "../algorithm.js", "../identifiers.js", "../webCrypto.js", "../utils/misc.js", "../consts.js", "../errors.js"], factory);
define(["require", "exports", "../utils/misc.js", "../consts.js", "../errors.js"], factory);
}

@@ -37,5 +37,2 @@ })(function (require, exports) {

exports.Dhkem = void 0;
const algorithm_js_1 = require("../algorithm.js");
const identifiers_js_1 = require("../identifiers.js");
const webCrypto_js_1 = require("../webCrypto.js");
const misc_js_1 = require("../utils/misc.js");

@@ -49,20 +46,22 @@ const consts_js_1 = require("../consts.js");

// b"shared_secret"
// deno-fmt-ignore
const LABEL_SHARED_SECRET = new Uint8Array([
115,
104,
97,
114,
101,
100,
95,
115,
101,
99,
114,
101,
116,
115, 104, 97, 114, 101, 100, 95, 115, 101, 99,
114, 101, 116,
]);
class Dhkem extends algorithm_js_1.Algorithm {
constructor(prim, kdf) {
super();
function concat(a, b) {
const ret = new Uint8Array(a.length + b.length);
ret.set(a, 0);
ret.set(b, a.length);
return ret;
}
function concat3(a, b, c) {
const ret = new Uint8Array(a.length + b.length + c.length);
ret.set(a, 0);
ret.set(b, a.length);
ret.set(c, a.length + b.length);
return ret;
}
class Dhkem {
constructor(id, prim, kdf) {
Object.defineProperty(this, "id", {

@@ -72,3 +71,3 @@ enumerable: true,

writable: true,
value: identifiers_js_1.KemId.DhkemP256HkdfSha256
value: void 0
});

@@ -111,13 +110,26 @@ Object.defineProperty(this, "secretSize", {

});
this.id = id;
this._prim = prim;
this._kdf = kdf;
const suiteId = new Uint8Array(SUITE_ID_HEADER_KEM);
suiteId.set((0, misc_js_1.i2Osp)(this.id, 2), 3);
this._kdf.init(suiteId);
}
async serializePublicKey(key) {
return await this._prim.serializePublicKey(key);
}
async deserializePublicKey(key) {
return await this._prim.deserializePublicKey(key);
}
async serializePrivateKey(key) {
return await this._prim.serializePrivateKey(key);
}
async deserializePrivateKey(key) {
return await this._prim.deserializePrivateKey(key);
}
async importKey(format, key, isPublic = true) {
return await this._prim.importKey(format, key, isPublic);
}
async generateKeyPair() {
await this._setup();
try {
return await this._prim.generateKeyPair();
}
catch (e) {
throw new errors.NotSupportedError(e);
}
return await this._prim.generateKeyPair();
}

@@ -128,45 +140,11 @@ async deriveKeyPair(ikm) {

}
await this._setup();
try {
return await this._prim.deriveKeyPair(ikm);
}
catch (e) {
throw new errors.DeriveKeyPairError(e);
}
return await this._prim.deriveKeyPair(ikm);
}
async serializePublicKey(key) {
await this._setup();
try {
return await this._prim.serializePublicKey(key);
}
catch (e) {
throw new errors.SerializeError(e);
}
}
async deserializePublicKey(key) {
await this._setup();
try {
return await this._prim.deserializePublicKey(key);
}
catch (e) {
throw new errors.DeserializeError(e);
}
}
async importKey(format, key, isPublic = true) {
await this._setup();
try {
return await this._prim.importKey(format, key, isPublic);
}
catch (e) {
throw new errors.DeserializeError(e);
}
}
async encap(params) {
await this._setup();
const ke = params.nonEphemeralKeyPair === undefined
? await this.generateKeyPair()
: params.nonEphemeralKeyPair;
const enc = await this._prim.serializePublicKey(ke.publicKey);
const pkrm = await this._prim.serializePublicKey(params.recipientPublicKey);
try {
const ke = params.nonEphemeralKeyPair === undefined
? await this.generateKeyPair()
: params.nonEphemeralKeyPair;
const enc = await this._prim.serializePublicKey(ke.publicKey);
const pkrm = await this._prim.serializePublicKey(params.recipientPublicKey);
let dh;

@@ -182,7 +160,7 @@ if (params.senderKey === undefined) {

const dh2 = new Uint8Array(await this._prim.dh(sks, params.recipientPublicKey));
dh = (0, misc_js_1.concat)(dh1, dh2);
dh = concat(dh1, dh2);
}
let kemContext;
if (params.senderKey === undefined) {
kemContext = (0, misc_js_1.concat)(new Uint8Array(enc), new Uint8Array(pkrm));
kemContext = concat(new Uint8Array(enc), new Uint8Array(pkrm));
}

@@ -194,3 +172,3 @@ else {

const pksm = await this._prim.serializePublicKey(pks);
kemContext = (0, misc_js_1.concat3)(new Uint8Array(enc), new Uint8Array(pkrm), new Uint8Array(pksm));
kemContext = concat3(new Uint8Array(enc), new Uint8Array(pkrm), new Uint8Array(pksm));
}

@@ -208,18 +186,11 @@ const sharedSecret = await this._generateSharedSecret(dh, kemContext);

async decap(params) {
let pke;
await this._setup();
const pke = await this._prim.deserializePublicKey(params.enc);
const skr = (0, misc_js_1.isCryptoKeyPair)(params.recipientKey)
? params.recipientKey.privateKey
: params.recipientKey;
const pkr = (0, misc_js_1.isCryptoKeyPair)(params.recipientKey)
? params.recipientKey.publicKey
: await this._prim.derivePublicKey(params.recipientKey);
const pkrm = await this._prim.serializePublicKey(pkr);
try {
pke = await this._prim.deserializePublicKey(params.enc);
}
catch (e) {
throw new errors.DeserializeError(e);
}
try {
const skr = (0, misc_js_1.isCryptoKeyPair)(params.recipientKey)
? params.recipientKey.privateKey
: params.recipientKey;
const pkr = (0, misc_js_1.isCryptoKeyPair)(params.recipientKey)
? params.recipientKey.publicKey
: await this._prim.derivePublicKey(params.recipientKey);
const pkrm = await this._prim.serializePublicKey(pkr);
let dh;

@@ -232,7 +203,7 @@ if (params.senderPublicKey === undefined) {

const dh2 = new Uint8Array(await this._prim.dh(skr, params.senderPublicKey));
dh = (0, misc_js_1.concat)(dh1, dh2);
dh = concat(dh1, dh2);
}
let kemContext;
if (params.senderPublicKey === undefined) {
kemContext = (0, misc_js_1.concat)(new Uint8Array(params.enc), new Uint8Array(pkrm));
kemContext = concat(new Uint8Array(params.enc), new Uint8Array(pkrm));
}

@@ -252,13 +223,2 @@ else {

}
async _setup() {
if (this._api !== undefined) {
return;
}
const api = await (0, webCrypto_js_1.loadSubtleCrypto)();
const suiteId = new Uint8Array(SUITE_ID_HEADER_KEM);
suiteId.set((0, misc_js_1.i2Osp)(this.id, 2), 3);
this._prim.init(api);
this._kdf.init(suiteId);
super.init(api);
}
async _generateSharedSecret(dh, kemContext) {

@@ -265,0 +225,0 @@ const labeledIkm = this._kdf.buildLabeledIkm(LABEL_EAE_PRK, dh);

@@ -1,5 +0,4 @@

import type { KemPrimitives } from "../../interfaces/kemPrimitives.js";
import type { DhkemPrimitives } from "../../interfaces/dhkemPrimitives.js";
import type { KdfInterface } from "../../interfaces/kdfInterface.js";
import { Algorithm } from "../../algorithm.js";
export declare class X448 extends Algorithm implements KemPrimitives {
export declare class X448 implements DhkemPrimitives {
private _hkdf;

@@ -11,9 +10,11 @@ private _nPk;

deserializePublicKey(key: ArrayBuffer): Promise<CryptoKey>;
serializePrivateKey(key: CryptoKey): Promise<ArrayBuffer>;
deserializePrivateKey(key: ArrayBuffer): Promise<CryptoKey>;
importKey(format: "raw" | "jwk", key: ArrayBuffer | JsonWebKey, isPublic: boolean): Promise<CryptoKey>;
derivePublicKey(key: CryptoKey): Promise<CryptoKey>;
generateKeyPair(): Promise<CryptoKeyPair>;
deriveKeyPair(ikm: ArrayBuffer): Promise<CryptoKeyPair>;
derivePublicKey(key: CryptoKey): Promise<CryptoKey>;
dh(sk: CryptoKey, pk: CryptoKey): Promise<ArrayBuffer>;
private _serializePublicKey;
private _deserializePublicKey;
private _serializePrivateKey;
private _importRawKey;

@@ -20,0 +21,0 @@ private _importJWK;

@@ -30,3 +30,3 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {

else if (typeof define === "function" && define.amd) {
define(["require", "exports", "@noble/curves/ed448", "../../algorithm.js", "../../interfaces/kemPrimitives.js", "../../xCryptoKey.js", "../../consts.js", "../../utils/misc.js"], factory);
define(["require", "exports", "@noble/curves/ed448", "../../consts.js", "../../errors.js", "../../interfaces/dhkemPrimitives.js", "../../utils/misc.js", "../../xCryptoKey.js"], factory);
}

@@ -39,11 +39,10 @@ })(function (require, exports) {

const ed448_1 = require("@noble/curves/ed448");
const algorithm_js_1 = require("../../algorithm.js");
const kemPrimitives_js_1 = require("../../interfaces/kemPrimitives.js");
const xCryptoKey_js_1 = require("../../xCryptoKey.js");
const consts = __importStar(require("../../consts.js"));
const errors = __importStar(require("../../errors.js"));
const dhkemPrimitives_js_1 = require("../../interfaces/dhkemPrimitives.js");
const misc_js_1 = require("../../utils/misc.js");
const xCryptoKey_js_1 = require("../../xCryptoKey.js");
const ALG_NAME = "X448";
class X448 extends algorithm_js_1.Algorithm {
class X448 {
constructor(hkdf) {
super();
Object.defineProperty(this, "_hkdf", {

@@ -72,37 +71,88 @@ enumerable: true,

async serializePublicKey(key) {
return await this._serializePublicKey(key);
try {
return await this._serializePublicKey(key);
}
catch (e) {
throw new errors.SerializeError(e);
}
}
async deserializePublicKey(key) {
return await this._deserializePublicKey(key);
try {
return await this._importRawKey(key, true);
}
catch (e) {
throw new errors.DeserializeError(e);
}
}
async serializePrivateKey(key) {
try {
return await this._serializePrivateKey(key);
}
catch (e) {
throw new errors.SerializeError(e);
}
}
async deserializePrivateKey(key) {
try {
return await this._importRawKey(key, false);
}
catch (e) {
throw new errors.DeserializeError(e);
}
}
async importKey(format, key, isPublic) {
if (format === "raw") {
return await this._importRawKey(key, isPublic);
try {
if (format === "raw") {
return await this._importRawKey(key, isPublic);
}
// jwk
if (key instanceof ArrayBuffer) {
throw new Error("Invalid jwk key format");
}
return await this._importJWK(key, isPublic);
}
// jwk
if (key instanceof ArrayBuffer) {
throw new Error("Invalid jwk key format");
catch (e) {
throw new errors.DeserializeError(e);
}
return await this._importJWK(key, isPublic);
}
async derivePublicKey(key) {
return await this._derivePublicKey(key);
}
async generateKeyPair() {
const rawSk = ed448_1.ed448.utils.randomPrivateKey();
const sk = new xCryptoKey_js_1.XCryptoKey(ALG_NAME, rawSk, "private", kemPrimitives_js_1.KEM_USAGES);
const pk = await this.derivePublicKey(sk);
return { publicKey: pk, privateKey: sk };
try {
const rawSk = ed448_1.ed448.utils.randomPrivateKey();
const sk = new xCryptoKey_js_1.XCryptoKey(ALG_NAME, rawSk, "private", dhkemPrimitives_js_1.KEM_USAGES);
const pk = await this.derivePublicKey(sk);
return { publicKey: pk, privateKey: sk };
}
catch (e) {
throw new errors.NotSupportedError(e);
}
}
async deriveKeyPair(ikm) {
const dkpPrk = await this._hkdf.labeledExtract(consts.EMPTY, kemPrimitives_js_1.LABEL_DKP_PRK, new Uint8Array(ikm));
const rawSk = await this._hkdf.labeledExpand(dkpPrk, kemPrimitives_js_1.LABEL_SK, consts.EMPTY, this._nSk);
const sk = new xCryptoKey_js_1.XCryptoKey(ALG_NAME, new Uint8Array(rawSk), "private", kemPrimitives_js_1.KEM_USAGES);
return {
privateKey: sk,
publicKey: await this.derivePublicKey(sk),
};
try {
const dkpPrk = await this._hkdf.labeledExtract(consts.EMPTY, dhkemPrimitives_js_1.LABEL_DKP_PRK, new Uint8Array(ikm));
const rawSk = await this._hkdf.labeledExpand(dkpPrk, dhkemPrimitives_js_1.LABEL_SK, consts.EMPTY, this._nSk);
const sk = new xCryptoKey_js_1.XCryptoKey(ALG_NAME, new Uint8Array(rawSk), "private", dhkemPrimitives_js_1.KEM_USAGES);
return {
privateKey: sk,
publicKey: await this.derivePublicKey(sk),
};
}
catch (e) {
throw new errors.DeriveKeyPairError(e);
}
}
async derivePublicKey(key) {
try {
return await this._derivePublicKey(key);
}
catch (e) {
throw new errors.DeserializeError(e);
}
}
async dh(sk, pk) {
return await this._dh(sk, pk);
try {
return await this._dh(sk, pk);
}
catch (e) {
throw new errors.SerializeError(e);
}
}

@@ -114,10 +164,5 @@ _serializePublicKey(k) {

}
_deserializePublicKey(k) {
return new Promise((resolve, reject) => {
if (k.byteLength !== this._nPk) {
reject(new Error("Invalid public key for the ciphersuite"));
}
else {
resolve(new xCryptoKey_js_1.XCryptoKey(ALG_NAME, new Uint8Array(k), "public"));
}
_serializePrivateKey(k) {
return new Promise((resolve) => {
resolve(k.key.buffer);
});

@@ -128,8 +173,9 @@ }

if (isPublic && key.byteLength !== this._nPk) {
reject(new Error("Invalid public key for the ciphersuite"));
reject(new Error("Invalid length of the key"));
}
if (!isPublic && key.byteLength !== this._nSk) {
reject(new Error("Invalid private key for the ciphersuite"));
if (!isPublic &&
(key.byteLength !== this._nSk && key.byteLength !== this._nSk + 1)) {
reject(new Error("Invalid length of the key"));
}
resolve(new xCryptoKey_js_1.XCryptoKey(ALG_NAME, new Uint8Array(key), isPublic ? "public" : "private", isPublic ? [] : kemPrimitives_js_1.KEM_USAGES));
resolve(new xCryptoKey_js_1.XCryptoKey(ALG_NAME, new Uint8Array(key), isPublic ? "public" : "private", isPublic ? [] : dhkemPrimitives_js_1.KEM_USAGES));
});

@@ -158,3 +204,3 @@ }

}
resolve(new xCryptoKey_js_1.XCryptoKey(ALG_NAME, (0, misc_js_1.base64UrlToBytes)(key.d), "private", kemPrimitives_js_1.KEM_USAGES));
resolve(new xCryptoKey_js_1.XCryptoKey(ALG_NAME, (0, misc_js_1.base64UrlToBytes)(key.d), "private", dhkemPrimitives_js_1.KEM_USAGES));
}

@@ -164,5 +210,10 @@ });

_derivePublicKey(k) {
return new Promise((resolve) => {
const pk = ed448_1.x448.getPublicKey(k.key);
resolve(new xCryptoKey_js_1.XCryptoKey(ALG_NAME, pk, "public"));
return new Promise((resolve, reject) => {
try {
const pk = ed448_1.x448.getPublicKey(k.key);
resolve(new xCryptoKey_js_1.XCryptoKey(ALG_NAME, pk, "public"));
}
catch (e) {
reject(e);
}
});

@@ -169,0 +220,0 @@ }

@@ -40,4 +40,3 @@ (function (factory) {

const kdf = new hkdfSha512_js_1.HkdfSha512();
const prim = new x448_js_1.X448(kdf);
super(prim, kdf);
super(identifiers_js_1.KemId.DhkemX448HkdfSha512, new x448_js_1.X448(kdf), kdf);
Object.defineProperty(this, "id", {

@@ -44,0 +43,0 @@ enumerable: true,

@@ -22,24 +22,4 @@ /**

/**
* Executes XOR of two byte strings.
*/
export declare function xor(a: Uint8Array, b: Uint8Array): Uint8Array;
/**
* Concatenates two Uint8Arrays.
*/
export declare function concat(a: Uint8Array, b: Uint8Array): Uint8Array;
/**
* Concatenates three Uint8Arrays.
*/
export declare function concat3(a: Uint8Array, b: Uint8Array, c: Uint8Array): Uint8Array;
/**
* Converts hex string to bytes.
*/
export declare function hexToBytes(v: string): Uint8Array;
/**
* Converts bytes to hex string.
*/
export declare function bytesToHex(v: Uint8Array): string;
/**
* Decodes Base64Url-encoded data.
*/
export declare function base64UrlToBytes(v: string): Uint8Array;

@@ -35,3 +35,3 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {

Object.defineProperty(exports, "__esModule", { value: true });
exports.base64UrlToBytes = exports.bytesToHex = exports.hexToBytes = exports.concat3 = exports.concat = exports.xor = exports.i2Osp = exports.isCryptoKeyPair = exports.isDeno = exports.isCloudflareWorkers = exports.isBrowser = void 0;
exports.base64UrlToBytes = exports.i2Osp = exports.isCryptoKeyPair = exports.isDeno = exports.isCloudflareWorkers = exports.isBrowser = void 0;
const dntShim = __importStar(require("../../_dnt.shims.js"));

@@ -80,60 +80,2 @@ /**

/**
* Executes XOR of two byte strings.
*/
function xor(a, b) {
if (a.byteLength !== b.byteLength) {
throw new Error("xor: different length inputs");
}
const buf = new Uint8Array(a.byteLength);
for (let i = 0; i < a.byteLength; i++) {
buf[i] = a[i] ^ b[i];
}
return buf;
}
exports.xor = xor;
/**
* Concatenates two Uint8Arrays.
*/
function concat(a, b) {
const ret = new Uint8Array(a.length + b.length);
ret.set(a, 0);
ret.set(b, a.length);
return ret;
}
exports.concat = concat;
/**
* Concatenates three Uint8Arrays.
*/
function concat3(a, b, c) {
const ret = new Uint8Array(a.length + b.length + c.length);
ret.set(a, 0);
ret.set(b, a.length);
ret.set(c, a.length + b.length);
return ret;
}
exports.concat3 = concat3;
/**
* Converts hex string to bytes.
*/
function hexToBytes(v) {
if (v.length === 0) {
return new Uint8Array([]);
}
const res = v.match(/[\da-f]{2}/gi);
if (res == null) {
throw new Error("hexToBytes: not hex string");
}
return new Uint8Array(res.map(function (h) {
return parseInt(h, 16);
}));
}
exports.hexToBytes = hexToBytes;
/**
* Converts bytes to hex string.
*/
function bytesToHex(v) {
return [...v].map((x) => x.toString(16).padStart(2, "0")).join("");
}
exports.bytesToHex = bytesToHex;
/**
* Decodes Base64Url-encoded data.

@@ -140,0 +82,0 @@ */

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc