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

did-jwt

Package Overview
Dependencies
Maintainers
8
Versions
142
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

did-jwt - npm Package Compare versions

Comparing version 5.5.3 to 5.6.0

lib/ECDH.d.ts

7

CHANGELOG.md

@@ -0,1 +1,8 @@

# [5.6.0](https://github.com/decentralized-identity/did-jwt/compare/5.5.3...5.6.0) (2021-06-09)
### Features
* enable remote ECDH for JWE [de]encrypters ([#186](https://github.com/decentralized-identity/did-jwt/issues/186)) ([ff26440](https://github.com/decentralized-identity/did-jwt/commit/ff264405658f54a6f0f1a236284a03cb47027225)), closes [#183](https://github.com/decentralized-identity/did-jwt/issues/183)
## [5.5.3](https://github.com/decentralized-identity/did-jwt/compare/5.5.2...5.5.3) (2021-06-07)

@@ -2,0 +9,0 @@

1

lib/index.d.ts

@@ -9,4 +9,5 @@ import SimpleSigner from './signers/SimpleSigner';

export { JWE, createJWE, decryptJWE, Encrypter, Decrypter } from './JWE';
export { ECDH, createX25519ECDH } from './ECDH';
export { xc20pDirEncrypter, xc20pDirDecrypter, x25519Encrypter, x25519Decrypter, resolveX25519Encrypters, createAuthEncrypter, createAnonEncrypter, createAuthDecrypter, createAnonDecrypter, xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2, xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2 } from './xc20pEncryption';
export { SimpleSigner, EllipticSigner, NaclSigner, ES256KSigner, EdDSASigner, verifyJWT, createJWT, decodeJWT, verifyJWS, createJWS, toEthereumAddress, Signer, JWTHeader, JWTPayload, JWTVerified };
//# sourceMappingURL=index.d.ts.map

233

lib/index.js

@@ -7,4 +7,4 @@ var u8a = require('uint8arrays');

var canonicalizeData = require('canonicalize');
var x25519 = require('@stablelib/x25519');
var xchacha20poly1305 = require('@stablelib/xchacha20poly1305');
var x25519 = require('@stablelib/x25519');
var random = require('@stablelib/random');

@@ -1312,9 +1312,44 @@

/**
* Wraps an X25519 secret key into an ECDH method that can be used to compute a shared secret with a public key.
* @param mySecretKey A `Uint8Array` of length 32 representing the bytes of my secret key
* @returns an `ECDH` method with the signature `(theirPublicKey: Uint8Array) => Promise<Uint8Array>`
*
* @throws 'invalid_argument:...' if the secret key size is wrong
*/
function createX25519ECDH(mySecretKey) {
if (mySecretKey.length !== 32) {
throw new Error('invalid_argument: incorrect secret key length for X25519');
}
return function (theirPublicKey) {
try {
if (theirPublicKey.length !== 32) {
throw new Error('invalid_argument: incorrect publicKey key length for X25519');
}
return Promise.resolve(x25519.sharedKey(mySecretKey, theirPublicKey));
} catch (e) {
return Promise.reject(e);
}
};
}
/**
* Recommended encrypter for authenticated encryption (i.e. sender authentication and requires
* sender private key to encrypt the data).
* Uses ECDH-1PU [v3](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03) and
* XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU v3 } and
* {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW v2 }.
*
* @param recipientPublicKey the byte array representing the recipient public key
* @param senderSecret either a Uint8Array representing the sender secret key or
* an ECDH function that wraps the key and can promise a shared secret given a public key
* @param options {@link AuthEncryptParams} used to specify extra header parameters
*
* @returns an {@link Encrypter} instance usable with {@link createJWE}
*
* NOTE: ECDH-1PU and XC20PKW are proposed drafts in IETF and not a standard yet and
* are subject to change as new revisions or until the official CFRG specification are released.
*
* @beta
*/

@@ -1365,15 +1400,22 @@

};
function createAuthEncrypter(recipientPublicKey, senderSecretKey, options = {}) {
return xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2(recipientPublicKey, senderSecretKey, options);
function createAuthEncrypter(recipientPublicKey, senderSecret, options = {}) {
return xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2(recipientPublicKey, senderSecret, options);
}
/**
* Recommended encrypter for anonymous encryption (i.e. no sender authentication).
* Uses ECDH-ES+XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | ECDH-ES+XC20PKW v2}.
*
* @param publicKey the byte array representing the recipient public key
* @param options {@link AnonEncryptParams} used to specify the recipient key ID (`kid`)
*
* @returns an {@link Encrypter} instance usable with {@link createJWE}
*
* NOTE: ECDH-ES+XC20PKW is a proposed draft in IETF and not a standard yet and
* is subject to change as new revisions or until the official CFRG specification is released.
*
* @beta
*/
function createAnonEncrypter(publicKey, options = {}) {
return options !== undefined ? x25519Encrypter(publicKey, options.kid) : x25519Encrypter(publicKey);
return x25519Encrypter(publicKey, options == null ? void 0 : options.kid);
}

@@ -1383,22 +1425,37 @@ /**

* sender public key to decrypt the data).
* Uses ECDH-1PU [v3](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03) and
* XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU v3 } and
* {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW v2 }.
*
* @param recipientSecret either a Uint8Array representing the recipient secret key or
* an ECDH function that wraps the key and can promise a shared secret given a public key
* @param senderPublicKey the byte array representing the sender public key
*
* @returns a {@link Decrypter} instance usable with {@link decryptJWE}
*
* NOTE: ECDH-1PU and XC20PKW are proposed drafts in IETF and not a standard yet and
* are subject to change as new revisions or until the official CFRG specification are released.
*
* @beta
*/
function createAuthDecrypter(recipientSecretKey, senderPublicKey) {
return xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2(recipientSecretKey, senderPublicKey);
function createAuthDecrypter(recipientSecret, senderPublicKey) {
return xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2(recipientSecret, senderPublicKey);
}
/**
* Recommended decrypter for anonymous encryption (i.e. no sender authentication).
* Uses ECDH-ES+XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | ECDH-ES+XC20PKW v2 }.
*
* @param recipientSecret either a Uint8Array representing the recipient secret key or
* an ECDH function that wraps the key and can promise a shared secret given a public key
*
* @returns a {@link Decrypter} instance usable with {@link decryptJWE}
*
* NOTE: ECDH-ES+XC20PKW is a proposed draft in IETF and not a standard yet and
* is subject to change as new revisions or until the official CFRG specification is released.
*
* @beta
*/
function createAnonDecrypter(secretKey) {
return x25519Decrypter(secretKey);
function createAnonDecrypter(recipientSecret) {
return x25519Decrypter(recipientSecret);
}

@@ -1522,7 +1579,7 @@

* Implements ECDH-1PU+XC20PKW with XChaCha20Poly1305 based on the following specs:
* - [XC20PKW](https://tools.ietf.org/html/draft-amringer-jose-chacha-02)
* - [ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03)
* - {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW}
* - {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU}
*/
function xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2(recipientPublicKey, senderSecretKey, options = {}) {
function xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2(recipientPublicKey, senderSecret, options = {}) {
const encrypt = function (cleartext, protectedHeader = {}, aad) {

@@ -1552,2 +1609,28 @@ try {

try {
function _temp2() {
const sharedSecret = new Uint8Array(zE.length + zS.length);
sharedSecret.set(zE);
sharedSecret.set(zS, zE.length); // Key Encryption Key
const kek = concatKDF(sharedSecret, keyLen, alg, partyUInfo, partyVInfo);
const res = xc20pEncrypter(kek)(cek);
const recipient = {
encrypted_key: bytesToBase64url(res.ciphertext),
header: {
alg,
iv: bytesToBase64url(res.iv),
tag: bytesToBase64url(res.tag),
epk: {
kty: 'OKP',
crv,
x: bytesToBase64url(epk.publicKey)
}
}
};
if (options.kid) recipient.header.kid = options.kid;
if (options.apu) recipient.header.apu = options.apu;
if (options.apv) recipient.header.apv = options.apv;
return recipient;
}
const epk = x25519.generateKeyPair();

@@ -1557,26 +1640,15 @@ const zE = x25519.sharedKey(epk.secretKey, recipientPublicKey); // ECDH-1PU requires additional shared secret between

const zS = x25519.sharedKey(senderSecretKey, recipientPublicKey);
const sharedSecret = new Uint8Array(zE.length + zS.length);
sharedSecret.set(zE);
sharedSecret.set(zS, zE.length); // Key Encryption Key
let zS;
const kek = concatKDF(sharedSecret, keyLen, alg, partyUInfo, partyVInfo);
const res = xc20pEncrypter(kek)(cek);
const recipient = {
encrypted_key: bytesToBase64url(res.ciphertext),
header: {
alg,
iv: bytesToBase64url(res.iv),
tag: bytesToBase64url(res.tag),
epk: {
kty: 'OKP',
crv,
x: bytesToBase64url(epk.publicKey)
}
const _temp = function () {
if (senderSecret instanceof Uint8Array) {
zS = x25519.sharedKey(senderSecret, recipientPublicKey);
} else {
return Promise.resolve(senderSecret(recipientPublicKey)).then(function (_senderSecret) {
zS = _senderSecret;
});
}
};
if (options.kid) recipient.header.kid = options.kid;
if (options.apu) recipient.header.apu = options.apu;
if (options.apv) recipient.header.apv = options.apv;
return Promise.resolve(recipient);
}();
return Promise.resolve(_temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp));
} catch (e) {

@@ -1608,3 +1680,3 @@ return Promise.reject(e);

function x25519Decrypter(secretKey) {
function x25519Decrypter(receiverSecret) {
const decrypt = function (sealed, iv, aad, recipient) {

@@ -1614,2 +1686,12 @@ try {

function _temp4() {
// Key Encryption Key
const kek = concatKDF(sharedSecret, keyLen, alg); // Content Encryption Key
const sealedCek = toSealed(recipient.encrypted_key, recipient.header.tag);
return Promise.resolve(xc20pDirDecrypter(kek).decrypt(sealedCek, base64ToBytes(recipient.header.iv))).then(function (cek) {
return cek === null ? null : xc20pDirDecrypter(cek).decrypt(sealed, iv, aad);
});
}
validateHeader((_recipient = recipient) == null ? void 0 : _recipient.header);

@@ -1619,10 +1701,15 @@ recipient = recipient;

const publicKey = base64ToBytes(recipient.header.epk.x);
const sharedSecret = x25519.sharedKey(secretKey, publicKey); // Key Encryption Key
let sharedSecret;
const kek = concatKDF(sharedSecret, keyLen, alg); // Content Encryption Key
const _temp3 = function () {
if (receiverSecret instanceof Uint8Array) {
sharedSecret = x25519.sharedKey(receiverSecret, publicKey);
} else {
return Promise.resolve(receiverSecret(publicKey)).then(function (_receiverSecret) {
sharedSecret = _receiverSecret;
});
}
}();
const sealedCek = toSealed(recipient.encrypted_key, recipient.header.tag);
return Promise.resolve(xc20pDirDecrypter(kek).decrypt(sealedCek, base64ToBytes(recipient.header.iv))).then(function (cek) {
return cek === null ? null : xc20pDirDecrypter(cek).decrypt(sealed, iv, aad);
});
return Promise.resolve(_temp3 && _temp3.then ? _temp3.then(_temp4) : _temp4(_temp3));
} catch (e) {

@@ -1644,7 +1731,7 @@ return Promise.reject(e);

* Implements ECDH-1PU+XC20PKW with XChaCha20Poly1305 based on the following specs:
* - [XC20PKW](https://tools.ietf.org/html/draft-amringer-jose-chacha-02)
* - [ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03)
* - {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW}
* - {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU}
*/
function xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2(recipientSecretKey, senderPublicKey) {
function xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2(recipientSecret, senderPublicKey) {
const decrypt = function (sealed, iv, aad, recipient) {

@@ -1654,2 +1741,19 @@ try {

function _temp6() {
const sharedSecret = new Uint8Array(zE.length + zS.length);
sharedSecret.set(zE);
sharedSecret.set(zS, zE.length); // Key Encryption Key
let producerInfo;
let consumerInfo;
if (recipient.header.apu) producerInfo = base64ToBytes(recipient.header.apu);
if (recipient.header.apv) consumerInfo = base64ToBytes(recipient.header.apv);
const kek = concatKDF(sharedSecret, keyLen, alg, producerInfo, consumerInfo); // Content Encryption Key
const sealedCek = toSealed(recipient.encrypted_key, recipient.header.tag);
return Promise.resolve(xc20pDirDecrypter(kek).decrypt(sealedCek, base64ToBytes(recipient.header.iv))).then(function (cek) {
return cek === null ? null : xc20pDirDecrypter(cek).decrypt(sealed, iv, aad);
});
}
recipient = recipient;

@@ -1661,18 +1765,20 @@ validateHeader(recipient.header);

const publicKey = base64ToBytes(recipient.header.epk.x);
const zE = x25519.sharedKey(recipientSecretKey, publicKey);
const zS = x25519.sharedKey(recipientSecretKey, senderPublicKey);
const sharedSecret = new Uint8Array(zE.length + zS.length);
sharedSecret.set(zE);
sharedSecret.set(zS, zE.length); // Key Encryption Key
let zE;
let zS;
let producerInfo;
let consumerInfo;
if (recipient.header.apu) producerInfo = base64ToBytes(recipient.header.apu);
if (recipient.header.apv) consumerInfo = base64ToBytes(recipient.header.apv);
const kek = concatKDF(sharedSecret, keyLen, alg, producerInfo, consumerInfo); // Content Encryption Key
const _temp5 = function () {
if (recipientSecret instanceof Uint8Array) {
zE = x25519.sharedKey(recipientSecret, publicKey);
zS = x25519.sharedKey(recipientSecret, senderPublicKey);
} else {
return Promise.resolve(recipientSecret(publicKey)).then(function (_recipientSecret) {
zE = _recipientSecret;
return Promise.resolve(recipientSecret(senderPublicKey)).then(function (_recipientSecret2) {
zS = _recipientSecret2;
});
});
}
}();
const sealedCek = toSealed(recipient.encrypted_key, recipient.header.tag);
return Promise.resolve(xc20pDirDecrypter(kek).decrypt(sealedCek, base64ToBytes(recipient.header.iv))).then(function (cek) {
return cek === null ? null : xc20pDirDecrypter(cek).decrypt(sealed, iv, aad);
});
return Promise.resolve(_temp5 && _temp5.then ? _temp5.then(_temp6) : _temp6(_temp5));
} catch (e) {

@@ -1705,2 +1811,3 @@ return Promise.reject(e);

exports.createJWT = createJWT;
exports.createX25519ECDH = createX25519ECDH;
exports.decodeJWT = decodeJWT;

@@ -1707,0 +1814,0 @@ exports.decryptJWE = decryptJWE;

@@ -7,4 +7,4 @@ import { toString, fromString, concat } from 'uint8arrays';

import canonicalizeData from 'canonicalize';
import { sharedKey, generateKeyPair } from '@stablelib/x25519';
import { XChaCha20Poly1305 } from '@stablelib/xchacha20poly1305';
import { generateKeyPair, sharedKey } from '@stablelib/x25519';
import { randomBytes } from '@stablelib/random';

@@ -946,24 +946,62 @@

/**
* Wraps an X25519 secret key into an ECDH method that can be used to compute a shared secret with a public key.
* @param mySecretKey A `Uint8Array` of length 32 representing the bytes of my secret key
* @returns an `ECDH` method with the signature `(theirPublicKey: Uint8Array) => Promise<Uint8Array>`
*
* @throws 'invalid_argument:...' if the secret key size is wrong
*/
function createX25519ECDH(mySecretKey) {
if (mySecretKey.length !== 32) {
throw new Error('invalid_argument: incorrect secret key length for X25519');
}
return async theirPublicKey => {
if (theirPublicKey.length !== 32) {
throw new Error('invalid_argument: incorrect publicKey key length for X25519');
}
return sharedKey(mySecretKey, theirPublicKey);
};
}
/**
* Recommended encrypter for authenticated encryption (i.e. sender authentication and requires
* sender private key to encrypt the data).
* Uses ECDH-1PU [v3](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03) and
* XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU v3 } and
* {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW v2 }.
*
* @param recipientPublicKey the byte array representing the recipient public key
* @param senderSecret either a Uint8Array representing the sender secret key or
* an ECDH function that wraps the key and can promise a shared secret given a public key
* @param options {@link AuthEncryptParams} used to specify extra header parameters
*
* @returns an {@link Encrypter} instance usable with {@link createJWE}
*
* NOTE: ECDH-1PU and XC20PKW are proposed drafts in IETF and not a standard yet and
* are subject to change as new revisions or until the official CFRG specification are released.
*
* @beta
*/
function createAuthEncrypter(recipientPublicKey, senderSecretKey, options = {}) {
return xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2(recipientPublicKey, senderSecretKey, options);
function createAuthEncrypter(recipientPublicKey, senderSecret, options = {}) {
return xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2(recipientPublicKey, senderSecret, options);
}
/**
* Recommended encrypter for anonymous encryption (i.e. no sender authentication).
* Uses ECDH-ES+XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | ECDH-ES+XC20PKW v2}.
*
* @param publicKey the byte array representing the recipient public key
* @param options {@link AnonEncryptParams} used to specify the recipient key ID (`kid`)
*
* @returns an {@link Encrypter} instance usable with {@link createJWE}
*
* NOTE: ECDH-ES+XC20PKW is a proposed draft in IETF and not a standard yet and
* is subject to change as new revisions or until the official CFRG specification is released.
*
* @beta
*/
function createAnonEncrypter(publicKey, options = {}) {
return options !== undefined ? x25519Encrypter(publicKey, options.kid) : x25519Encrypter(publicKey);
return x25519Encrypter(publicKey, options == null ? void 0 : options.kid);
}

@@ -973,22 +1011,37 @@ /**

* sender public key to decrypt the data).
* Uses ECDH-1PU [v3](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03) and
* XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU v3 } and
* {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW v2 }.
*
* @param recipientSecret either a Uint8Array representing the recipient secret key or
* an ECDH function that wraps the key and can promise a shared secret given a public key
* @param senderPublicKey the byte array representing the sender public key
*
* @returns a {@link Decrypter} instance usable with {@link decryptJWE}
*
* NOTE: ECDH-1PU and XC20PKW are proposed drafts in IETF and not a standard yet and
* are subject to change as new revisions or until the official CFRG specification are released.
*
* @beta
*/
function createAuthDecrypter(recipientSecretKey, senderPublicKey) {
return xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2(recipientSecretKey, senderPublicKey);
function createAuthDecrypter(recipientSecret, senderPublicKey) {
return xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2(recipientSecret, senderPublicKey);
}
/**
* Recommended decrypter for anonymous encryption (i.e. no sender authentication).
* Uses ECDH-ES+XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | ECDH-ES+XC20PKW v2 }.
*
* @param recipientSecret either a Uint8Array representing the recipient secret key or
* an ECDH function that wraps the key and can promise a shared secret given a public key
*
* @returns a {@link Decrypter} instance usable with {@link decryptJWE}
*
* NOTE: ECDH-ES+XC20PKW is a proposed draft in IETF and not a standard yet and
* is subject to change as new revisions or until the official CFRG specification is released.
*
* @beta
*/
function createAnonDecrypter(secretKey) {
return x25519Decrypter(secretKey);
function createAnonDecrypter(recipientSecret) {
return x25519Decrypter(recipientSecret);
}

@@ -1095,7 +1148,7 @@

* Implements ECDH-1PU+XC20PKW with XChaCha20Poly1305 based on the following specs:
* - [XC20PKW](https://tools.ietf.org/html/draft-amringer-jose-chacha-02)
* - [ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03)
* - {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW}
* - {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU}
*/
function xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2(recipientPublicKey, senderSecretKey, options = {}) {
function xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2(recipientPublicKey, senderSecret, options = {}) {
const alg = 'ECDH-1PU+XC20PKW';

@@ -1114,3 +1167,10 @@ const keyLen = 256;

const zS = sharedKey(senderSecretKey, recipientPublicKey);
let zS;
if (senderSecret instanceof Uint8Array) {
zS = sharedKey(senderSecret, recipientPublicKey);
} else {
zS = await senderSecret(recipientPublicKey);
}
const sharedSecret = new Uint8Array(zE.length + zS.length);

@@ -1203,3 +1263,3 @@ sharedSecret.set(zE);

function x25519Decrypter(secretKey) {
function x25519Decrypter(receiverSecret) {
const alg = 'ECDH-ES+XC20PKW';

@@ -1216,4 +1276,11 @@ const keyLen = 256;

const publicKey = base64ToBytes(recipient.header.epk.x);
const sharedSecret = sharedKey(secretKey, publicKey); // Key Encryption Key
let sharedSecret;
if (receiverSecret instanceof Uint8Array) {
sharedSecret = sharedKey(receiverSecret, publicKey);
} else {
sharedSecret = await receiverSecret(publicKey);
} // Key Encryption Key
const kek = concatKDF(sharedSecret, keyLen, alg); // Content Encryption Key

@@ -1235,7 +1302,7 @@

* Implements ECDH-1PU+XC20PKW with XChaCha20Poly1305 based on the following specs:
* - [XC20PKW](https://tools.ietf.org/html/draft-amringer-jose-chacha-02)
* - [ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03)
* - {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW}
* - {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU}
*/
function xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2(recipientSecretKey, senderPublicKey) {
function xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2(recipientSecret, senderPublicKey) {
const alg = 'ECDH-1PU+XC20PKW';

@@ -1254,4 +1321,13 @@ const keyLen = 256;

const publicKey = base64ToBytes(recipient.header.epk.x);
const zE = sharedKey(recipientSecretKey, publicKey);
const zS = sharedKey(recipientSecretKey, senderPublicKey);
let zE;
let zS;
if (recipientSecret instanceof Uint8Array) {
zE = sharedKey(recipientSecret, publicKey);
zS = sharedKey(recipientSecret, senderPublicKey);
} else {
zE = await recipientSecret(publicKey);
zS = await recipientSecret(senderPublicKey);
}
const sharedSecret = new Uint8Array(zE.length + zS.length);

@@ -1280,3 +1356,3 @@ sharedSecret.set(zE);

export { ES256KSigner, EdDSASigner, EllipticSigner, NaclSigner, SimpleSigner, createAnonDecrypter, createAnonEncrypter, createAuthDecrypter, createAuthEncrypter, createJWE, createJWS, createJWT, decodeJWT, decryptJWE, resolveX25519Encrypters, toEthereumAddress, verifyJWS, verifyJWT, x25519Decrypter, x25519Encrypter, xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2, xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2, xc20pDirDecrypter, xc20pDirEncrypter };
export { ES256KSigner, EdDSASigner, EllipticSigner, NaclSigner, SimpleSigner, createAnonDecrypter, createAnonEncrypter, createAuthDecrypter, createAuthEncrypter, createJWE, createJWS, createJWT, createX25519ECDH, decodeJWT, decryptJWE, resolveX25519Encrypters, toEthereumAddress, verifyJWS, verifyJWT, x25519Decrypter, x25519Encrypter, xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2, xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2, xc20pDirDecrypter, xc20pDirEncrypter };
//# sourceMappingURL=index.modern.js.map

@@ -7,4 +7,4 @@ import { toString, fromString, concat } from 'uint8arrays';

import canonicalizeData from 'canonicalize';
import { sharedKey, generateKeyPair } from '@stablelib/x25519';
import { XChaCha20Poly1305 } from '@stablelib/xchacha20poly1305';
import { generateKeyPair, sharedKey } from '@stablelib/x25519';
import { randomBytes } from '@stablelib/random';

@@ -1308,9 +1308,44 @@

/**
* Wraps an X25519 secret key into an ECDH method that can be used to compute a shared secret with a public key.
* @param mySecretKey A `Uint8Array` of length 32 representing the bytes of my secret key
* @returns an `ECDH` method with the signature `(theirPublicKey: Uint8Array) => Promise<Uint8Array>`
*
* @throws 'invalid_argument:...' if the secret key size is wrong
*/
function createX25519ECDH(mySecretKey) {
if (mySecretKey.length !== 32) {
throw new Error('invalid_argument: incorrect secret key length for X25519');
}
return function (theirPublicKey) {
try {
if (theirPublicKey.length !== 32) {
throw new Error('invalid_argument: incorrect publicKey key length for X25519');
}
return Promise.resolve(sharedKey(mySecretKey, theirPublicKey));
} catch (e) {
return Promise.reject(e);
}
};
}
/**
* Recommended encrypter for authenticated encryption (i.e. sender authentication and requires
* sender private key to encrypt the data).
* Uses ECDH-1PU [v3](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03) and
* XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU v3 } and
* {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW v2 }.
*
* @param recipientPublicKey the byte array representing the recipient public key
* @param senderSecret either a Uint8Array representing the sender secret key or
* an ECDH function that wraps the key and can promise a shared secret given a public key
* @param options {@link AuthEncryptParams} used to specify extra header parameters
*
* @returns an {@link Encrypter} instance usable with {@link createJWE}
*
* NOTE: ECDH-1PU and XC20PKW are proposed drafts in IETF and not a standard yet and
* are subject to change as new revisions or until the official CFRG specification are released.
*
* @beta
*/

@@ -1361,15 +1396,22 @@

};
function createAuthEncrypter(recipientPublicKey, senderSecretKey, options = {}) {
return xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2(recipientPublicKey, senderSecretKey, options);
function createAuthEncrypter(recipientPublicKey, senderSecret, options = {}) {
return xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2(recipientPublicKey, senderSecret, options);
}
/**
* Recommended encrypter for anonymous encryption (i.e. no sender authentication).
* Uses ECDH-ES+XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | ECDH-ES+XC20PKW v2}.
*
* @param publicKey the byte array representing the recipient public key
* @param options {@link AnonEncryptParams} used to specify the recipient key ID (`kid`)
*
* @returns an {@link Encrypter} instance usable with {@link createJWE}
*
* NOTE: ECDH-ES+XC20PKW is a proposed draft in IETF and not a standard yet and
* is subject to change as new revisions or until the official CFRG specification is released.
*
* @beta
*/
function createAnonEncrypter(publicKey, options = {}) {
return options !== undefined ? x25519Encrypter(publicKey, options.kid) : x25519Encrypter(publicKey);
return x25519Encrypter(publicKey, options == null ? void 0 : options.kid);
}

@@ -1379,22 +1421,37 @@ /**

* sender public key to decrypt the data).
* Uses ECDH-1PU [v3](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03) and
* XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU v3 } and
* {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW v2 }.
*
* @param recipientSecret either a Uint8Array representing the recipient secret key or
* an ECDH function that wraps the key and can promise a shared secret given a public key
* @param senderPublicKey the byte array representing the sender public key
*
* @returns a {@link Decrypter} instance usable with {@link decryptJWE}
*
* NOTE: ECDH-1PU and XC20PKW are proposed drafts in IETF and not a standard yet and
* are subject to change as new revisions or until the official CFRG specification are released.
*
* @beta
*/
function createAuthDecrypter(recipientSecretKey, senderPublicKey) {
return xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2(recipientSecretKey, senderPublicKey);
function createAuthDecrypter(recipientSecret, senderPublicKey) {
return xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2(recipientSecret, senderPublicKey);
}
/**
* Recommended decrypter for anonymous encryption (i.e. no sender authentication).
* Uses ECDH-ES+XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | ECDH-ES+XC20PKW v2 }.
*
* @param recipientSecret either a Uint8Array representing the recipient secret key or
* an ECDH function that wraps the key and can promise a shared secret given a public key
*
* @returns a {@link Decrypter} instance usable with {@link decryptJWE}
*
* NOTE: ECDH-ES+XC20PKW is a proposed draft in IETF and not a standard yet and
* is subject to change as new revisions or until the official CFRG specification is released.
*
* @beta
*/
function createAnonDecrypter(secretKey) {
return x25519Decrypter(secretKey);
function createAnonDecrypter(recipientSecret) {
return x25519Decrypter(recipientSecret);
}

@@ -1518,7 +1575,7 @@

* Implements ECDH-1PU+XC20PKW with XChaCha20Poly1305 based on the following specs:
* - [XC20PKW](https://tools.ietf.org/html/draft-amringer-jose-chacha-02)
* - [ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03)
* - {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW}
* - {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU}
*/
function xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2(recipientPublicKey, senderSecretKey, options = {}) {
function xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2(recipientPublicKey, senderSecret, options = {}) {
const encrypt = function (cleartext, protectedHeader = {}, aad) {

@@ -1548,2 +1605,28 @@ try {

try {
function _temp2() {
const sharedSecret = new Uint8Array(zE.length + zS.length);
sharedSecret.set(zE);
sharedSecret.set(zS, zE.length); // Key Encryption Key
const kek = concatKDF(sharedSecret, keyLen, alg, partyUInfo, partyVInfo);
const res = xc20pEncrypter(kek)(cek);
const recipient = {
encrypted_key: bytesToBase64url(res.ciphertext),
header: {
alg,
iv: bytesToBase64url(res.iv),
tag: bytesToBase64url(res.tag),
epk: {
kty: 'OKP',
crv,
x: bytesToBase64url(epk.publicKey)
}
}
};
if (options.kid) recipient.header.kid = options.kid;
if (options.apu) recipient.header.apu = options.apu;
if (options.apv) recipient.header.apv = options.apv;
return recipient;
}
const epk = generateKeyPair();

@@ -1553,26 +1636,15 @@ const zE = sharedKey(epk.secretKey, recipientPublicKey); // ECDH-1PU requires additional shared secret between

const zS = sharedKey(senderSecretKey, recipientPublicKey);
const sharedSecret = new Uint8Array(zE.length + zS.length);
sharedSecret.set(zE);
sharedSecret.set(zS, zE.length); // Key Encryption Key
let zS;
const kek = concatKDF(sharedSecret, keyLen, alg, partyUInfo, partyVInfo);
const res = xc20pEncrypter(kek)(cek);
const recipient = {
encrypted_key: bytesToBase64url(res.ciphertext),
header: {
alg,
iv: bytesToBase64url(res.iv),
tag: bytesToBase64url(res.tag),
epk: {
kty: 'OKP',
crv,
x: bytesToBase64url(epk.publicKey)
}
const _temp = function () {
if (senderSecret instanceof Uint8Array) {
zS = sharedKey(senderSecret, recipientPublicKey);
} else {
return Promise.resolve(senderSecret(recipientPublicKey)).then(function (_senderSecret) {
zS = _senderSecret;
});
}
};
if (options.kid) recipient.header.kid = options.kid;
if (options.apu) recipient.header.apu = options.apu;
if (options.apv) recipient.header.apv = options.apv;
return Promise.resolve(recipient);
}();
return Promise.resolve(_temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp));
} catch (e) {

@@ -1604,3 +1676,3 @@ return Promise.reject(e);

function x25519Decrypter(secretKey) {
function x25519Decrypter(receiverSecret) {
const decrypt = function (sealed, iv, aad, recipient) {

@@ -1610,2 +1682,12 @@ try {

function _temp4() {
// Key Encryption Key
const kek = concatKDF(sharedSecret, keyLen, alg); // Content Encryption Key
const sealedCek = toSealed(recipient.encrypted_key, recipient.header.tag);
return Promise.resolve(xc20pDirDecrypter(kek).decrypt(sealedCek, base64ToBytes(recipient.header.iv))).then(function (cek) {
return cek === null ? null : xc20pDirDecrypter(cek).decrypt(sealed, iv, aad);
});
}
validateHeader((_recipient = recipient) == null ? void 0 : _recipient.header);

@@ -1615,10 +1697,15 @@ recipient = recipient;

const publicKey = base64ToBytes(recipient.header.epk.x);
const sharedSecret = sharedKey(secretKey, publicKey); // Key Encryption Key
let sharedSecret;
const kek = concatKDF(sharedSecret, keyLen, alg); // Content Encryption Key
const _temp3 = function () {
if (receiverSecret instanceof Uint8Array) {
sharedSecret = sharedKey(receiverSecret, publicKey);
} else {
return Promise.resolve(receiverSecret(publicKey)).then(function (_receiverSecret) {
sharedSecret = _receiverSecret;
});
}
}();
const sealedCek = toSealed(recipient.encrypted_key, recipient.header.tag);
return Promise.resolve(xc20pDirDecrypter(kek).decrypt(sealedCek, base64ToBytes(recipient.header.iv))).then(function (cek) {
return cek === null ? null : xc20pDirDecrypter(cek).decrypt(sealed, iv, aad);
});
return Promise.resolve(_temp3 && _temp3.then ? _temp3.then(_temp4) : _temp4(_temp3));
} catch (e) {

@@ -1640,7 +1727,7 @@ return Promise.reject(e);

* Implements ECDH-1PU+XC20PKW with XChaCha20Poly1305 based on the following specs:
* - [XC20PKW](https://tools.ietf.org/html/draft-amringer-jose-chacha-02)
* - [ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03)
* - {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW}
* - {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU}
*/
function xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2(recipientSecretKey, senderPublicKey) {
function xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2(recipientSecret, senderPublicKey) {
const decrypt = function (sealed, iv, aad, recipient) {

@@ -1650,2 +1737,19 @@ try {

function _temp6() {
const sharedSecret = new Uint8Array(zE.length + zS.length);
sharedSecret.set(zE);
sharedSecret.set(zS, zE.length); // Key Encryption Key
let producerInfo;
let consumerInfo;
if (recipient.header.apu) producerInfo = base64ToBytes(recipient.header.apu);
if (recipient.header.apv) consumerInfo = base64ToBytes(recipient.header.apv);
const kek = concatKDF(sharedSecret, keyLen, alg, producerInfo, consumerInfo); // Content Encryption Key
const sealedCek = toSealed(recipient.encrypted_key, recipient.header.tag);
return Promise.resolve(xc20pDirDecrypter(kek).decrypt(sealedCek, base64ToBytes(recipient.header.iv))).then(function (cek) {
return cek === null ? null : xc20pDirDecrypter(cek).decrypt(sealed, iv, aad);
});
}
recipient = recipient;

@@ -1657,18 +1761,20 @@ validateHeader(recipient.header);

const publicKey = base64ToBytes(recipient.header.epk.x);
const zE = sharedKey(recipientSecretKey, publicKey);
const zS = sharedKey(recipientSecretKey, senderPublicKey);
const sharedSecret = new Uint8Array(zE.length + zS.length);
sharedSecret.set(zE);
sharedSecret.set(zS, zE.length); // Key Encryption Key
let zE;
let zS;
let producerInfo;
let consumerInfo;
if (recipient.header.apu) producerInfo = base64ToBytes(recipient.header.apu);
if (recipient.header.apv) consumerInfo = base64ToBytes(recipient.header.apv);
const kek = concatKDF(sharedSecret, keyLen, alg, producerInfo, consumerInfo); // Content Encryption Key
const _temp5 = function () {
if (recipientSecret instanceof Uint8Array) {
zE = sharedKey(recipientSecret, publicKey);
zS = sharedKey(recipientSecret, senderPublicKey);
} else {
return Promise.resolve(recipientSecret(publicKey)).then(function (_recipientSecret) {
zE = _recipientSecret;
return Promise.resolve(recipientSecret(senderPublicKey)).then(function (_recipientSecret2) {
zS = _recipientSecret2;
});
});
}
}();
const sealedCek = toSealed(recipient.encrypted_key, recipient.header.tag);
return Promise.resolve(xc20pDirDecrypter(kek).decrypt(sealedCek, base64ToBytes(recipient.header.iv))).then(function (cek) {
return cek === null ? null : xc20pDirDecrypter(cek).decrypt(sealed, iv, aad);
});
return Promise.resolve(_temp5 && _temp5.then ? _temp5.then(_temp6) : _temp6(_temp5));
} catch (e) {

@@ -1689,3 +1795,3 @@ return Promise.reject(e);

export { ES256KSigner, EdDSASigner, EllipticSigner, NaclSigner, SimpleSigner, createAnonDecrypter, createAnonEncrypter, createAuthDecrypter, createAuthEncrypter, createJWE, createJWS, createJWT, decodeJWT, decryptJWE, resolveX25519Encrypters, toEthereumAddress, verifyJWS, verifyJWT, x25519Decrypter, x25519Encrypter, xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2, xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2, xc20pDirDecrypter, xc20pDirEncrypter };
export { ES256KSigner, EdDSASigner, EllipticSigner, NaclSigner, SimpleSigner, createAnonDecrypter, createAnonEncrypter, createAuthDecrypter, createAuthEncrypter, createJWE, createJWS, createJWT, createX25519ECDH, decodeJWT, decryptJWE, resolveX25519Encrypters, toEthereumAddress, verifyJWS, verifyJWT, x25519Decrypter, x25519Encrypter, xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2, xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2, xc20pDirDecrypter, xc20pDirEncrypter };
//# sourceMappingURL=index.module.js.map
import { Encrypter, Decrypter } from './JWE';
import type { Resolvable } from 'did-resolver';
import { ECDH } from './ECDH';
/**
* Extra header parameters for JWE using authenticated encryption
*/
export declare type AuthEncryptParams = {
/**
* recipient key ID
*/
kid?: string;
/**
* See {@link https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-03#section-2.1.1}
*/
skid?: string;
/**
* See {@link https://datatracker.ietf.org/doc/html/rfc7518#section-4.6.1.2}
* base64url encoded
*/
apu?: string;
/**
* See {@link https://datatracker.ietf.org/doc/html/rfc7518#section-4.6.1.3}
* base64url encoded
*/
apv?: string;
};
/**
* Extra header parameters for JWE using anonymous encryption
*/
export declare type AnonEncryptParams = {
/**
* recipient key ID
*/
kid?: string;

@@ -15,15 +39,31 @@ };

* sender private key to encrypt the data).
* Uses ECDH-1PU [v3](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03) and
* XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU v3 } and
* {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW v2 }.
*
* @param recipientPublicKey the byte array representing the recipient public key
* @param senderSecret either a Uint8Array representing the sender secret key or
* an ECDH function that wraps the key and can promise a shared secret given a public key
* @param options {@link AuthEncryptParams} used to specify extra header parameters
*
* @returns an {@link Encrypter} instance usable with {@link createJWE}
*
* NOTE: ECDH-1PU and XC20PKW are proposed drafts in IETF and not a standard yet and
* are subject to change as new revisions or until the official CFRG specification are released.
*
* @beta
*/
export declare function createAuthEncrypter(recipientPublicKey: Uint8Array, senderSecretKey: Uint8Array, options?: Partial<AuthEncryptParams>): Encrypter;
export declare function createAuthEncrypter(recipientPublicKey: Uint8Array, senderSecret: Uint8Array | ECDH, options?: Partial<AuthEncryptParams>): Encrypter;
/**
* Recommended encrypter for anonymous encryption (i.e. no sender authentication).
* Uses ECDH-ES+XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | ECDH-ES+XC20PKW v2}.
*
* @param publicKey the byte array representing the recipient public key
* @param options {@link AnonEncryptParams} used to specify the recipient key ID (`kid`)
*
* @returns an {@link Encrypter} instance usable with {@link createJWE}
*
* NOTE: ECDH-ES+XC20PKW is a proposed draft in IETF and not a standard yet and
* is subject to change as new revisions or until the official CFRG specification is released.
*
* @beta
*/

@@ -34,17 +74,32 @@ export declare function createAnonEncrypter(publicKey: Uint8Array, options?: Partial<AnonEncryptParams>): Encrypter;

* sender public key to decrypt the data).
* Uses ECDH-1PU [v3](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03) and
* XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU v3 } and
* {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW v2 }.
*
* @param recipientSecret either a Uint8Array representing the recipient secret key or
* an ECDH function that wraps the key and can promise a shared secret given a public key
* @param senderPublicKey the byte array representing the sender public key
*
* @returns a {@link Decrypter} instance usable with {@link decryptJWE}
*
* NOTE: ECDH-1PU and XC20PKW are proposed drafts in IETF and not a standard yet and
* are subject to change as new revisions or until the official CFRG specification are released.
*
* @beta
*/
export declare function createAuthDecrypter(recipientSecretKey: Uint8Array, senderPublicKey: Uint8Array): Decrypter;
export declare function createAuthDecrypter(recipientSecret: Uint8Array | ECDH, senderPublicKey: Uint8Array): Decrypter;
/**
* Recommended decrypter for anonymous encryption (i.e. no sender authentication).
* Uses ECDH-ES+XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | ECDH-ES+XC20PKW v2 }.
*
* @param recipientSecret either a Uint8Array representing the recipient secret key or
* an ECDH function that wraps the key and can promise a shared secret given a public key
*
* @returns a {@link Decrypter} instance usable with {@link decryptJWE}
*
* NOTE: ECDH-ES+XC20PKW is a proposed draft in IETF and not a standard yet and
* is subject to change as new revisions or until the official CFRG specification is released.
*
* @beta
*/
export declare function createAnonDecrypter(secretKey: Uint8Array): Decrypter;
export declare function createAnonDecrypter(recipientSecret: Uint8Array | ECDH): Decrypter;
export declare function xc20pDirEncrypter(key: Uint8Array): Encrypter;

@@ -55,14 +110,14 @@ export declare function xc20pDirDecrypter(key: Uint8Array): Decrypter;

* Implements ECDH-1PU+XC20PKW with XChaCha20Poly1305 based on the following specs:
* - [XC20PKW](https://tools.ietf.org/html/draft-amringer-jose-chacha-02)
* - [ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03)
* - {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW}
* - {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU}
*/
export declare function xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2(recipientPublicKey: Uint8Array, senderSecretKey: Uint8Array, options?: Partial<AuthEncryptParams>): Encrypter;
export declare function xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2(recipientPublicKey: Uint8Array, senderSecret: Uint8Array | ECDH, options?: Partial<AuthEncryptParams>): Encrypter;
export declare function resolveX25519Encrypters(dids: string[], resolver: Resolvable): Promise<Encrypter[]>;
export declare function x25519Decrypter(secretKey: Uint8Array): Decrypter;
export declare function x25519Decrypter(receiverSecret: Uint8Array | ECDH): Decrypter;
/**
* Implements ECDH-1PU+XC20PKW with XChaCha20Poly1305 based on the following specs:
* - [XC20PKW](https://tools.ietf.org/html/draft-amringer-jose-chacha-02)
* - [ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03)
* - {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW}
* - {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU}
*/
export declare function xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2(recipientSecretKey: Uint8Array, senderPublicKey: Uint8Array): Decrypter;
export declare function xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2(recipientSecret: Uint8Array | ECDH, senderPublicKey: Uint8Array): Decrypter;
//# sourceMappingURL=xc20pEncryption.d.ts.map
{
"name": "did-jwt",
"version": "5.5.3",
"version": "5.6.0",
"description": "Library for Signing and Verifying JWTs that use DIDs as issuers and JWEs that use DIDs as recipients",

@@ -5,0 +5,0 @@ "source": "src/index.ts",

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

import { decryptJWE, createJWE, Encrypter } from '../JWE'
import { decryptJWE, createJWE, Encrypter, JWE } from '../JWE'
import vectors from './jwe-vectors.js'

@@ -9,3 +9,7 @@ import {

xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2,
xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2
xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2,
createAnonEncrypter,
createAnonDecrypter,
createAuthEncrypter,
createAuthDecrypter
} from '../xc20pEncryption'

@@ -16,2 +20,3 @@ import { decodeBase64url, encodeBase64url } from '../util'

import { generateKeyPairFromSeed } from '@stablelib/x25519'
import { createX25519ECDH, ECDH } from '../ECDH'

@@ -331,2 +336,43 @@ describe('JWE', () => {

})
describe('using remote ECDH', () => {
const message = 'hello world'
const receiverPair = generateKeyPairFromSeed(randomBytes(32))
const receiverRemoteECDH = createX25519ECDH(receiverPair.secretKey)
const senderPair = generateKeyPairFromSeed(randomBytes(32))
const senderRemoteECDH: ECDH = createX25519ECDH(senderPair.secretKey)
it('creates anon JWE with remote ECDH', async () => {
const encrypter = createAnonEncrypter(receiverPair.publicKey)
const jwe: JWE = await createJWE(u8a.fromString(message), [encrypter])
const decrypter = createAnonDecrypter(receiverRemoteECDH)
const decryptedBytes = await decryptJWE(jwe, decrypter)
const receivedMessage = u8a.toString(decryptedBytes)
expect(receivedMessage).toEqual(message)
})
it('creates and decrypts auth JWE', async () => {
const encrypter = createAuthEncrypter(receiverPair.publicKey, senderRemoteECDH)
const jwe: JWE = await createJWE(u8a.fromString(message), [encrypter])
const decrypter = createAuthDecrypter(receiverRemoteECDH, senderPair.publicKey)
const decryptedBytes = await decryptJWE(jwe, decrypter)
const receivedMessage = u8a.toString(decryptedBytes)
expect(receivedMessage).toEqual(message)
})
it(`throws error when using bad secret key size`, async () => {
expect.assertions(1)
const badSecretKey = randomBytes(64)
expect(() => {
createX25519ECDH(badSecretKey)
}).toThrow('invalid_argument')
})
it(`throws error when using bad public key size`, async () => {
expect.assertions(1)
const ecdh: ECDH = createX25519ECDH(randomBytes(32))
const badPublicKey = randomBytes(64)
expect(ecdh(badPublicKey)).rejects.toThrow('invalid_argument')
})
})
})

@@ -333,0 +379,0 @@

@@ -6,2 +6,3 @@ import { x25519Decrypter, resolveX25519Encrypters } from '../xc20pEncryption'

import { generateKeyPair } from '@stablelib/x25519'
import { createX25519ECDH } from '../ECDH'

@@ -17,2 +18,3 @@ describe('xc20pEncryption', () => {

let decrypter1, decrypter2
let decrypter1remote, decrypter2remote

@@ -27,2 +29,5 @@ let didDocumentResult1, didDocumentResult2, didDocumentResult3, didDocumentResult4

decrypter1remote = x25519Decrypter(createX25519ECDH(kp1.secretKey))
decrypter2remote = x25519Decrypter(createX25519ECDH(kp2.secretKey))
didDocumentResult1 = {

@@ -81,3 +86,3 @@ didDocument: {

it('correctly resolves encrypters for DIDs', async () => {
expect.assertions(4)
expect.assertions(6)
const encrypters = await resolveX25519Encrypters([did1, did2], resolver)

@@ -91,2 +96,4 @@ const cleartext = randomBytes(8)

expect(await decryptJWE(jwe, decrypter2)).toEqual(cleartext)
expect(await decryptJWE(jwe, decrypter1remote)).toEqual(cleartext)
expect(await decryptJWE(jwe, decrypter2remote)).toEqual(cleartext)
})

@@ -105,3 +112,3 @@

it('resolves encrypters for DIDs with multiple valid keys ', async () => {
expect.assertions(6)
expect.assertions(8)

@@ -113,2 +120,4 @@ const secondKp1 = generateKeyPair()

const newDecrypter2 = x25519Decrypter(secondKp2.secretKey)
const newDecrypter1remote = x25519Decrypter(createX25519ECDH(secondKp1.secretKey))
const newDecrypter2remote = x25519Decrypter(createX25519ECDH(secondKp2.secretKey))

@@ -140,4 +149,6 @@ didDocumentResult1.didDocument.verificationMethod.push({

expect(await decryptJWE(jwe, newDecrypter2)).toEqual(cleartext)
expect(await decryptJWE(jwe, newDecrypter1remote)).toEqual(cleartext)
expect(await decryptJWE(jwe, newDecrypter2remote)).toEqual(cleartext)
})
})
})

@@ -19,2 +19,3 @@ import SimpleSigner from './signers/SimpleSigner'

export { JWE, createJWE, decryptJWE, Encrypter, Decrypter } from './JWE'
export { ECDH, createX25519ECDH } from './ECDH'
export {

@@ -21,0 +22,0 @@ xc20pDirEncrypter,

@@ -8,13 +8,38 @@ import { XChaCha20Poly1305 } from '@stablelib/xchacha20poly1305'

import type { VerificationMethod, Resolvable } from 'did-resolver'
import { ECDH } from './ECDH'
/**
* Extra header parameters for JWE using authenticated encryption
*/
export type AuthEncryptParams = {
/**
* recipient key ID
*/
kid?: string
/**
* See {@link https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-03#section-2.1.1}
*/
skid?: string
// base64url encoded
/**
* See {@link https://datatracker.ietf.org/doc/html/rfc7518#section-4.6.1.2}
* base64url encoded
*/
apu?: string
// base64url encoded
/**
* See {@link https://datatracker.ietf.org/doc/html/rfc7518#section-4.6.1.3}
* base64url encoded
*/
apv?: string
}
/**
* Extra header parameters for JWE using anonymous encryption
*/
export type AnonEncryptParams = {
/**
* recipient key ID
*/
kid?: string

@@ -26,14 +51,23 @@ }

* sender private key to encrypt the data).
* Uses ECDH-1PU [v3](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03) and
* XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU v3 } and
* {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW v2 }.
*
* @param recipientPublicKey the byte array representing the recipient public key
* @param senderSecret either a Uint8Array representing the sender secret key or
* an ECDH function that wraps the key and can promise a shared secret given a public key
* @param options {@link AuthEncryptParams} used to specify extra header parameters
*
* @returns an {@link Encrypter} instance usable with {@link createJWE}
*
* NOTE: ECDH-1PU and XC20PKW are proposed drafts in IETF and not a standard yet and
* are subject to change as new revisions or until the official CFRG specification are released.
*
* @beta
*/
export function createAuthEncrypter(
recipientPublicKey: Uint8Array,
senderSecretKey: Uint8Array,
senderSecret: Uint8Array | ECDH,
options: Partial<AuthEncryptParams> = {}
): Encrypter {
return xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2(recipientPublicKey, senderSecretKey, options)
return xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2(recipientPublicKey, senderSecret, options)
}

@@ -43,9 +77,16 @@

* Recommended encrypter for anonymous encryption (i.e. no sender authentication).
* Uses ECDH-ES+XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | ECDH-ES+XC20PKW v2}.
*
* @param publicKey the byte array representing the recipient public key
* @param options {@link AnonEncryptParams} used to specify the recipient key ID (`kid`)
*
* @returns an {@link Encrypter} instance usable with {@link createJWE}
*
* NOTE: ECDH-ES+XC20PKW is a proposed draft in IETF and not a standard yet and
* is subject to change as new revisions or until the official CFRG specification is released.
*
* @beta
*/
export function createAnonEncrypter(publicKey: Uint8Array, options: Partial<AnonEncryptParams> = {}): Encrypter {
return options !== undefined ? x25519Encrypter(publicKey, options.kid) : x25519Encrypter(publicKey)
return x25519Encrypter(publicKey, options?.kid)
}

@@ -56,10 +97,18 @@

* sender public key to decrypt the data).
* Uses ECDH-1PU [v3](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03) and
* XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU v3 } and
* {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW v2 }.
*
* @param recipientSecret either a Uint8Array representing the recipient secret key or
* an ECDH function that wraps the key and can promise a shared secret given a public key
* @param senderPublicKey the byte array representing the sender public key
*
* @returns a {@link Decrypter} instance usable with {@link decryptJWE}
*
* NOTE: ECDH-1PU and XC20PKW are proposed drafts in IETF and not a standard yet and
* are subject to change as new revisions or until the official CFRG specification are released.
*
* @beta
*/
export function createAuthDecrypter(recipientSecretKey: Uint8Array, senderPublicKey: Uint8Array): Decrypter {
return xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2(recipientSecretKey, senderPublicKey)
export function createAuthDecrypter(recipientSecret: Uint8Array | ECDH, senderPublicKey: Uint8Array): Decrypter {
return xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2(recipientSecret, senderPublicKey)
}

@@ -69,9 +118,16 @@

* Recommended decrypter for anonymous encryption (i.e. no sender authentication).
* Uses ECDH-ES+XC20PKW [v2](https://tools.ietf.org/html/draft-amringer-jose-chacha-02).
* Uses {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | ECDH-ES+XC20PKW v2 }.
*
* @param recipientSecret either a Uint8Array representing the recipient secret key or
* an ECDH function that wraps the key and can promise a shared secret given a public key
*
* @returns a {@link Decrypter} instance usable with {@link decryptJWE}
*
* NOTE: ECDH-ES+XC20PKW is a proposed draft in IETF and not a standard yet and
* is subject to change as new revisions or until the official CFRG specification is released.
*
* @beta
*/
export function createAnonDecrypter(secretKey: Uint8Array): Decrypter {
return x25519Decrypter(secretKey)
export function createAnonDecrypter(recipientSecret: Uint8Array | ECDH): Decrypter {
return x25519Decrypter(recipientSecret)
}

@@ -161,8 +217,8 @@

* Implements ECDH-1PU+XC20PKW with XChaCha20Poly1305 based on the following specs:
* - [XC20PKW](https://tools.ietf.org/html/draft-amringer-jose-chacha-02)
* - [ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03)
* - {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW}
* - {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU}
*/
export function xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2(
recipientPublicKey: Uint8Array,
senderSecretKey: Uint8Array,
senderSecret: Uint8Array | ECDH,
options: Partial<AuthEncryptParams> = {}

@@ -185,3 +241,8 @@ ): Encrypter {

// static key of sender and static key of recipient
const zS = sharedKey(senderSecretKey, recipientPublicKey)
let zS
if (senderSecret instanceof Uint8Array) {
zS = sharedKey(senderSecret, recipientPublicKey)
} else {
zS = await senderSecret(recipientPublicKey)
}

@@ -268,3 +329,3 @@ const sharedSecret = new Uint8Array(zE.length + zS.length)

export function x25519Decrypter(secretKey: Uint8Array): Decrypter {
export function x25519Decrypter(receiverSecret: Uint8Array | ECDH): Decrypter {
const alg = 'ECDH-ES+XC20PKW'

@@ -283,3 +344,8 @@ const keyLen = 256

const publicKey = base64ToBytes(recipient.header.epk.x)
const sharedSecret = sharedKey(secretKey, publicKey)
let sharedSecret
if (receiverSecret instanceof Uint8Array) {
sharedSecret = sharedKey(receiverSecret, publicKey)
} else {
sharedSecret = await receiverSecret(publicKey)
}

@@ -300,7 +366,7 @@ // Key Encryption Key

* Implements ECDH-1PU+XC20PKW with XChaCha20Poly1305 based on the following specs:
* - [XC20PKW](https://tools.ietf.org/html/draft-amringer-jose-chacha-02)
* - [ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03)
* - {@link https://tools.ietf.org/html/draft-amringer-jose-chacha-02 | XC20PKW}
* - {@link https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03 | ECDH-1PU}
*/
export function xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2(
recipientSecretKey: Uint8Array,
recipientSecret: Uint8Array | ECDH,
senderPublicKey: Uint8Array

@@ -323,5 +389,13 @@ ): Decrypter {

const publicKey = base64ToBytes(recipient.header.epk.x)
const zE = sharedKey(recipientSecretKey, publicKey)
const zS = sharedKey(recipientSecretKey, senderPublicKey)
let zE: Uint8Array
let zS: Uint8Array
if (recipientSecret instanceof Uint8Array) {
zE = sharedKey(recipientSecret, publicKey)
zS = sharedKey(recipientSecret, senderPublicKey)
} else {
zE = await recipientSecret(publicKey)
zS = await recipientSecret(senderPublicKey)
}
const sharedSecret = new Uint8Array(zE.length + zS.length)

@@ -328,0 +402,0 @@ sharedSecret.set(zE)

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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