From 85cc1ce1d567afcbc42e0fd89eb2515505044c83 Mon Sep 17 00:00:00 2001 From: Mircea Nistor Date: Thu, 11 Jul 2024 18:10:52 +0200 Subject: [PATCH] fix(did-comm): remove isomorphic-webcrypto dependency (#1401) fixes #1381 fixes #1387 Signed-off-by: Mircea Nistor --- package.json | 4 +- packages/did-comm/package.json | 7 +- .../did-comm/src/__tests__/encryption.test.ts | 2157 +++++++++-------- .../src/encryption/a256cbc-hs512-dir.ts | 57 +- .../did-comm/src/encryption/a256gcm-dir.ts | 16 +- packages/did-comm/src/encryption/xc20pkw.ts | 16 +- packages/did-provider-ion/package.json | 4 +- packages/did-provider-jwk/package.json | 2 +- packages/key-manager/package.json | 2 +- packages/kms-local/package.json | 3 +- .../kms-local/src/__tests__/kms-local.test.ts | 2 +- packages/kms-local/src/secret-box.ts | 3 +- packages/utils/package.json | 2 +- pnpm-lock.yaml | 360 ++- 14 files changed, 1284 insertions(+), 1351 deletions(-) diff --git a/package.json b/package.json index d6c417e20..12bc07570 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "@microsoft/api-extractor": "7.40.6", "@microsoft/api-extractor-model": "7.28.13", "@microsoft/tsdoc": "0.14.2", - "@noble/hashes": "1.3.3", + "@noble/hashes": "1.4.0", "@stablelib/ed25519": "1.0.3", "@transmute/credentials-context": "0.7.0-unstable.82", "@types/express": "4.17.21", @@ -49,7 +49,7 @@ "did-resolver": "4.1.0", "ethers": "6.11.1", "ethr-did-resolver": "10.1.9", - "express": "4.18.2", + "express": "4.19.2", "ganache": "7.9.2", "jest": "29.7.0", "jest-config": "29.7.0", diff --git a/packages/did-comm/package.json b/packages/did-comm/package.json index 3714e851e..9abbb49e3 100644 --- a/packages/did-comm/package.json +++ b/packages/did-comm/package.json @@ -17,11 +17,9 @@ } }, "dependencies": { - "@noble/curves": "^1.1.0", - "@stablelib/aes": "^2.0.0", + "@noble/curves": "^1.4.2", + "@noble/ciphers": "^0.5.3", "@stablelib/aes-kw": "^1.0.1", - "@stablelib/gcm": "^1.0.2", - "@stablelib/xchacha20poly1305": "^1.0.1", "@veramo/core-types": "workspace:^", "@veramo/kv-store": "workspace:^", "@veramo/mediation-manager": "workspace:^", @@ -31,7 +29,6 @@ "debug": "^4.3.3", "did-jwt": "^8.0.0", "did-resolver": "^4.1.0", - "isomorphic-webcrypto": "^2.3.8", "uuid": "^9.0.0" }, "devDependencies": { diff --git a/packages/did-comm/src/__tests__/encryption.test.ts b/packages/did-comm/src/__tests__/encryption.test.ts index a6258ef82..bc9389ea5 100644 --- a/packages/did-comm/src/__tests__/encryption.test.ts +++ b/packages/did-comm/src/__tests__/encryption.test.ts @@ -1,4 +1,4 @@ -import { createJWE, createX25519ECDH, Decrypter, decryptJWE, ECDH, Encrypter, JWE } from 'did-jwt' +import { base64ToBytes, createJWE, createX25519ECDH, Decrypter, decryptJWE, ECDH, Encrypter, JWE } from 'did-jwt' import { randomBytes } from '@noble/hashes/utils' import { generateX25519KeyPairFromSeed } from '../utils.js' import { @@ -15,17 +15,21 @@ import { xc20pAuthDecrypterEcdh1PuV3x25519WithA256KW, xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW, } from '../encryption/a256kw-encrypters.js' +import { xc20pAnonDecrypterX25519WithXC20PKW } from '../encryption/xc20pkw-encrypters.js' + import { decodeBase64url, encodeBase64url } from '../../../utils/src' import * as u8a from 'uint8arrays' +import { bytesToUtf8String } from '@veramo/utils' + +describe('didcomm encryption tests', () => { -const test_vectors = { - pass: [ - { - key: 'b9NnuOCB0hm7YGNvaE9DMhwH_wjZA1-gWD6dA0JWdL0', - cleartext: - '{"id":"1234567890","typ":"application/didcomm-plain+json","type":"http://example.com/protocols/lets_do_lunch/1.0/proposal","from":"did:example:alice","to":["did:example:bob"],"created_time":1516269022,"expires_time":1516385931,"body":{"messagespecificattribute":"and its value"}}', - jwe: { + describe('using test vectors', () => { + + it('XC20P with ECDH-ES+A256KW and protected header', async () => { + const key = base64ToBytes('b9NnuOCB0hm7YGNvaE9DMhwH_wjZA1-gWD6dA0JWdL0') + const decrypter = xc20pAnonDecrypterX25519WithA256KW(key) + const jwe = { ciphertext: 'KWS7gJU7TbyJlcT9dPkCw-ohNigGaHSukR9MUqFM0THbCTCNkY-g5tahBFyszlKIKXs7qOtqzYyWbPou2q77XlAeYs93IhF6NvaIjyNqYklvj-OtJt9W2Pj5CLOMdsR0C30wchGoXd6wEQZY4ttbzpxYznqPmJ0b9KW6ZP-l4_DSRYe9B-1oSWMNmqMPwluKbtguC-riy356Xbu2C9ShfWmpmjz1HyJWQhZfczuwkWWlE63g26FMskIZZd_jGpEhPFHKUXCFwbuiw_Iy3R0BIzmXXdK_w7PZMMPbaxssl2UeJmLQgCAP8j8TukxV96EKa6rGgULvlo7qibjJqsS5j03bnbxkuxwbfyu3OxwgVzFWlyHbUH6p', protected: @@ -40,13 +44,17 @@ const test_vectors = { ], tag: '6ylC_iAs4JvDQzXeY6MuYQ', iv: 'ESpmcyGiZpRjc5urDela21TOOTW8Wqd1', - }, - }, + } + const clearbytes = await decryptJWE(jwe, decrypter) + const cleartext = bytesToUtf8String(clearbytes) + const expected = '{"id":"1234567890","typ":"application/didcomm-plain+json","type":"http://example.com/protocols/lets_do_lunch/1.0/proposal","from":"did:example:alice","to":["did:example:bob"],"created_time":1516269022,"expires_time":1516385931,"body":{"messagespecificattribute":"and its value"}}' + expect(cleartext).toEqual(expected) + }) - { - key: '+Egu1APNlDqx3YHm1LAsAHeEQi7kCUvhIXunTMpuplQ=', - cleartext: 'i1WprsPZJy9VP2xiqbyHIQ3q0hOdleHb+e7wlV0u9e/+lzO4IYue0NqBcsrPfnF9EVqQkEpi2maC5ym79H4k4w==', - jwe: { + it('XC20P with ECDH-ES+XC20PKW 1', async () => { + const key = base64ToBytes('+Egu1APNlDqx3YHm1LAsAHeEQi7kCUvhIXunTMpuplQ=') + const decrypter = xc20pAnonDecrypterX25519WithXC20PKW(key) + const jwe = { protected: 'eyJlbmMiOiJYQzIwUCJ9', recipients: [ { @@ -70,13 +78,18 @@ const test_vectors = { ciphertext: 'X9Qp6fnJIpcxbsKQete7nioEFC4sC9d0gS7SH4TDeSlSlSqT9ln3UP6x2hmjz-gn5hg5PEUFaIUkETNuBSyMzHyUpE_Lx5iNAzuRnstfpQ_ZG6hka93Mbw', tag: '9FQnp03c5Us_d1OdPYM7hA', - }, - }, + } + const + clearbytes = await decryptJWE(jwe, decrypter) + const cleartext = bytesToUtf8String(clearbytes) + const expected = 'i1WprsPZJy9VP2xiqbyHIQ3q0hOdleHb+e7wlV0u9e/+lzO4IYue0NqBcsrPfnF9EVqQkEpi2maC5ym79H4k4w==' + expect(cleartext).toEqual(expected) + }) - { - key: 'MCFWVpCL17Y6+Ck8mVhlHv0ezly3SWDEya4DS/4zU14=', - cleartext: 'q3kCxeF6O/OSCD2R2UjkhS+DMjCN09QPchTK91LOEk5w2HQEJ+Ewo1BpkEYAuRE2CDfcMp4hIYIKc+n88BDALA==', - jwe: { + it('XC20P with ECDH-ES+XC20PKW 2', async () => { + const key = base64ToBytes('MCFWVpCL17Y6+Ck8mVhlHv0ezly3SWDEya4DS/4zU14=') + const decrypter = xc20pAnonDecrypterX25519WithXC20PKW(key) + const jwe = { protected: 'eyJlbmMiOiJYQzIwUCJ9', recipients: [ { @@ -100,13 +113,17 @@ const test_vectors = { ciphertext: 'tcFKEWxhz-Q-nsnJppYqmFC5R0VT8fdNR0vJzUynlx--_3KDFIuDUdf0lwuwycbYXrEw94EyxfVZb3tkOADHXNaIC0njlB07_D7__eyK0N5bD88TXSe4lA', tag: 'GNnsfuK6-OYVwVc5N0jyHg', - }, - }, + } + const clearbytes = await decryptJWE(jwe, decrypter) + const cleartext = bytesToUtf8String(clearbytes) + const expected = 'q3kCxeF6O/OSCD2R2UjkhS+DMjCN09QPchTK91LOEk5w2HQEJ+Ewo1BpkEYAuRE2CDfcMp4hIYIKc+n88BDALA==' + expect(cleartext).toEqual(expected) + }) - { - key: 'KHJWEr94Z1qgaCCbsKu/oCxb07LR/ufntkr1Lu0stWU=', - cleartext: '2+YQ5xghWN7RL1BUPHgv39BJRynuZ2+KaiMRsBlnvZzjJclMYSY67SneTmysv3X3yP/DEDkZH2TVPFcHrJRYGg==', - jwe: { + it('XC20P with ECDH-ES+XC20PKW 3', async () => { + const key = base64ToBytes('KHJWEr94Z1qgaCCbsKu/oCxb07LR/ufntkr1Lu0stWU=') + const decrypter = xc20pAnonDecrypterX25519WithXC20PKW(key) + const jwe = { protected: 'eyJlbmMiOiJYQzIwUCJ9', recipients: [ { @@ -130,211 +147,43 @@ const test_vectors = { ciphertext: '3ODDtCTQKlX6k0CKOBEE0LsbdUreF7ZeeIj27_pmyZ6uYTKikePR1N24ozdO2oGIGuvC-e9aNMLD8lJmfIbQrCzO6DD-c0AB3xULUF-z92EtI9XaGp08uA', tag: 'g0IWefR0xt-ubzkUJ2Ufeg', - }, - }, - ], - fail: [], - invalid: [], -} - -describe('One recipient A256KW', () => { - let pubkey, secretkey, cleartext: Uint8Array, encrypter: Encrypter, decrypter: Decrypter - - beforeEach(() => { - secretkey = randomBytes(32) - pubkey = generateX25519KeyPairFromSeed(secretkey).publicKey - cleartext = u8a.fromString('hello world') - encrypter = xc20pAnonEncrypterX25519WithA256KW(pubkey) - decrypter = xc20pAnonDecrypterX25519WithA256KW(secretkey) - }) - - it('Creates with only ciphertext', async () => { - expect.assertions(3) - const jwe = await createJWE(cleartext, [encrypter], {}, undefined, true) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected)).enc).toEqual('XC20P') - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) - - it('Creates with data in protected header', async () => { - expect.assertions(3) - const jwe = await createJWE(cleartext, [encrypter], { more: 'protected' }) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P', more: 'protected' }) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) - - it('Creates with aad', async () => { - expect.assertions(4) - const aad = u8a.fromString('this data is authenticated') - const jwe = await createJWE(cleartext, [encrypter], { more: 'protected' }, aad) - expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P', more: 'protected' }) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - delete jwe.aad - await expect(decryptJWE(jwe, decrypter)).rejects.toThrowError('Failed to decrypt') - }) -}) - -describe('Multiple recipients A256KW', () => { - let pubkey1, secretkey1, pubkey2, secretkey2, cleartext: Uint8Array - let encrypter1: Encrypter, decrypter1: Decrypter, encrypter2: Encrypter, decrypter2: Decrypter - - beforeEach(() => { - secretkey1 = randomBytes(32) - pubkey1 = generateX25519KeyPairFromSeed(secretkey1).publicKey - secretkey2 = randomBytes(32) - pubkey2 = generateX25519KeyPairFromSeed(secretkey2).publicKey - cleartext = u8a.fromString('my secret message') - encrypter1 = xc20pAnonEncrypterX25519WithA256KW(pubkey1) - decrypter1 = xc20pAnonDecrypterX25519WithA256KW(secretkey1) - encrypter2 = xc20pAnonEncrypterX25519WithA256KW(pubkey2) - decrypter2 = xc20pAnonDecrypterX25519WithA256KW(secretkey2) - }) - - it('Creates with only ciphertext', async () => { - expect.assertions(4) - const jwe = await createJWE(cleartext, [encrypter1, encrypter2]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P' }) - expect(await decryptJWE(jwe, decrypter1)).toEqual(cleartext) - expect(await decryptJWE(jwe, decrypter2)).toEqual(cleartext) - }) - - it('Creates with data in protected header', async () => { - expect.assertions(4) - const jwe = await createJWE(cleartext, [encrypter1, encrypter2], { more: 'protected' }) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P', more: 'protected' }) - expect(await decryptJWE(jwe, decrypter2)).toEqual(cleartext) - expect(await decryptJWE(jwe, decrypter1)).toEqual(cleartext) - }) - - it('Creates with aad', async () => { - expect.assertions(6) - const aad = u8a.fromString('this data is authenticated') - const jwe = await createJWE(cleartext, [encrypter1, encrypter2], { more: 'protected' }, aad) - expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P', more: 'protected' }) - expect(await decryptJWE(jwe, decrypter1)).toEqual(cleartext) - expect(await decryptJWE(jwe, decrypter2)).toEqual(cleartext) - delete jwe.aad - await expect(decryptJWE(jwe, decrypter1)).rejects.toThrowError('Failed to decrypt') - await expect(decryptJWE(jwe, decrypter2)).rejects.toThrowError('Failed to decrypt') - }) + } + const clearbytes = await decryptJWE(jwe, decrypter) + const cleartext = bytesToUtf8String(clearbytes) + const expected = '2+YQ5xghWN7RL1BUPHgv39BJRynuZ2+KaiMRsBlnvZzjJclMYSY67SneTmysv3X3yP/DEDkZH2TVPFcHrJRYGg==' + expect(cleartext).toEqual(expected) + }) - it('Incompatible encrypters throw', async () => { - expect.assertions(1) - const enc1 = { enc: 'cool enc alg1' } as Encrypter - const enc2 = { enc: 'cool enc alg2' } as Encrypter - await expect(createJWE(cleartext, [enc1, enc2])).rejects.toThrowError('Incompatible encrypters passed') }) -}) -describe('ECDH-1PU+A256KW (X25519), Key Wrapping Mode with XC20P content encryption', () => { - describe('One recipient', () => { - let cleartext: Uint8Array, recipientKey: any, senderKey: any, decrypter: Decrypter + describe('One recipient A256KW', () => { + let pubkey, secretkey, cleartext: Uint8Array, encrypter: Encrypter, decrypter: Decrypter beforeEach(() => { - recipientKey = generateX25519KeyPairFromSeed(randomBytes(32)) - senderKey = generateX25519KeyPairFromSeed(randomBytes(32)) - cleartext = u8a.fromString('my secret message') - decrypter = xc20pAuthDecrypterEcdh1PuV3x25519WithA256KW(recipientKey.secretKey, senderKey.publicKey) + secretkey = randomBytes(32) + pubkey = generateX25519KeyPairFromSeed(secretkey).publicKey + cleartext = u8a.fromString('hello world') + encrypter = xc20pAnonEncrypterX25519WithA256KW(pubkey) + decrypter = xc20pAnonDecrypterX25519WithA256KW(secretkey) }) it('Creates with only ciphertext', async () => { - const encrypter = xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW( - recipientKey.publicKey, - senderKey.secretKey, - ) expect.assertions(3) - const jwe = await createJWE(cleartext, [encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P' }) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) - - it('Creates with kid, no apu and no apv', async () => { - const kid = 'did:example:receiver#key-1' - const encrypter = xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW( - recipientKey.publicKey, - senderKey.secretKey, - { - kid, - }, - ) - expect.assertions(6) - const jwe = await createJWE(cleartext, [encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P' }) - expect(jwe.recipients!![0].header.kid).toEqual(kid) - expect(jwe.recipients!![0].header.apu).toBeUndefined() - expect(jwe.recipients!![0].header.apv).toBeUndefined() - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) - - it('Creates with no kid, apu and apv', async () => { - const apu = encodeBase64url('Alice') - const apv = encodeBase64url('Bob') - const encrypter = xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW( - recipientKey.publicKey, - senderKey.secretKey, - { - apu, - apv, - }, - ) - expect.assertions(6) - const jwe = await createJWE(cleartext, [encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P' }) - expect(jwe.recipients!![0].header.kid).toBeUndefined() - expect(jwe.recipients!![0].header.apu).toEqual(apu) - expect(jwe.recipients!![0].header.apv).toEqual(apv) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) - - it('Creates with kid, apu and apv', async () => { - const kid = 'did:example:receiver#key-1' - const apu = encodeBase64url('Alice') - const apv = encodeBase64url('Bob') - const encrypter = xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW( - recipientKey.publicKey, - senderKey.secretKey, - { - kid, - apu, - apv, - }, - ) - expect.assertions(6) - const jwe = await createJWE(cleartext, [encrypter]) + const jwe = await createJWE(cleartext, [encrypter], {}, undefined, true) expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P' }) - expect(jwe.recipients!![0].header.kid).toEqual(kid) - expect(jwe.recipients!![0].header.apu).toEqual(apu) - expect(jwe.recipients!![0].header.apv).toEqual(apv) + expect(JSON.parse(decodeBase64url(jwe.protected)).enc).toEqual('XC20P') expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) }) it('Creates with data in protected header', async () => { - const encrypter = xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW( - recipientKey.publicKey, - senderKey.secretKey, - ) - const skid = 'did:example:sender#key-1' expect.assertions(3) - const jwe = await createJWE(cleartext, [encrypter], { skid, more: 'protected' }) + const jwe = await createJWE(cleartext, [encrypter], { more: 'protected' }) expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P', skid, more: 'protected' }) + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P', more: 'protected' }) expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) }) it('Creates with aad', async () => { - const encrypter = xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW( - recipientKey.publicKey, - senderKey.secretKey, - ) expect.assertions(4) const aad = u8a.fromString('this data is authenticated') const jwe = await createJWE(cleartext, [encrypter], { more: 'protected' }, aad) @@ -344,140 +193,53 @@ describe('ECDH-1PU+A256KW (X25519), Key Wrapping Mode with XC20P content encrypt delete jwe.aad await expect(decryptJWE(jwe, decrypter)).rejects.toThrowError('Failed to decrypt') }) - - describe('using remote ECDH', () => { - const message = 'hello world' - const receiverPair = generateX25519KeyPairFromSeed(randomBytes(32)) - const receiverRemoteECDH = createX25519ECDH(receiverPair.secretKey) - const senderPair = generateX25519KeyPairFromSeed(randomBytes(32)) - const senderRemoteECDH: ECDH = createX25519ECDH(senderPair.secretKey) - - it('creates anon JWE with remote ECDH', async () => { - const encrypter = xc20pAnonEncrypterX25519WithA256KW(receiverPair.publicKey) - const jwe: JWE = await createJWE(u8a.fromString(message), [encrypter]) - const decrypter = xc20pAnonDecrypterX25519WithA256KW(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 = xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW( - receiverPair.publicKey, - senderRemoteECDH, - ) - const jwe: JWE = await createJWE(u8a.fromString(message), [encrypter]) - const decrypter = xc20pAuthDecrypterEcdh1PuV3x25519WithA256KW( - 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') - }) - }) }) - describe('Multiple recipients', () => { - let cleartext: any, senderkey: any - const recipients: any[] = [] + describe('Multiple recipients A256KW', () => { + let pubkey1, secretkey1, pubkey2, secretkey2, cleartext: Uint8Array + let encrypter1: Encrypter, decrypter1: Decrypter, encrypter2: Encrypter, decrypter2: Decrypter beforeEach(() => { - senderkey = generateX25519KeyPairFromSeed(randomBytes(32)) + secretkey1 = randomBytes(32) + pubkey1 = generateX25519KeyPairFromSeed(secretkey1).publicKey + secretkey2 = randomBytes(32) + pubkey2 = generateX25519KeyPairFromSeed(secretkey2).publicKey cleartext = u8a.fromString('my secret message') - - recipients[0] = { - kid: 'did:example:receiver1#key-1', - recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), - } - recipients[0] = { - ...recipients[0], - ...{ - encrypter: xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW( - recipients[0].recipientkey.publicKey, - senderkey.secretKey, - { kid: recipients[0].kid }, - ), - decrypter: xc20pAuthDecrypterEcdh1PuV3x25519WithA256KW( - recipients[0].recipientkey.secretKey, - senderkey.publicKey, - ), - }, - } - - recipients[1] = { - kid: 'did:example:receiver2#key-1', - recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), - } - recipients[1] = { - ...recipients[1], - ...{ - encrypter: xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW( - recipients[1].recipientkey.publicKey, - senderkey.secretKey, - { kid: recipients[1].kid }, - ), - decrypter: xc20pAuthDecrypterEcdh1PuV3x25519WithA256KW( - recipients[1].recipientkey.secretKey, - senderkey.publicKey, - ), - }, - } + encrypter1 = xc20pAnonEncrypterX25519WithA256KW(pubkey1) + decrypter1 = xc20pAnonDecrypterX25519WithA256KW(secretkey1) + encrypter2 = xc20pAnonEncrypterX25519WithA256KW(pubkey2) + decrypter2 = xc20pAnonDecrypterX25519WithA256KW(secretkey2) }) it('Creates with only ciphertext', async () => { expect.assertions(4) - const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter]) + const jwe = await createJWE(cleartext, [encrypter1, encrypter2]) expect(jwe.aad).toBeUndefined() expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P' }) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) - expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) + expect(await decryptJWE(jwe, decrypter1)).toEqual(cleartext) + expect(await decryptJWE(jwe, decrypter2)).toEqual(cleartext) }) it('Creates with data in protected header', async () => { expect.assertions(4) - const skid = 'did:example:sender#key-1' - const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter], { - more: 'protected', - skid, - }) + const jwe = await createJWE(cleartext, [encrypter1, encrypter2], { more: 'protected' }) expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P', more: 'protected', skid }) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P', more: 'protected' }) + expect(await decryptJWE(jwe, decrypter2)).toEqual(cleartext) + expect(await decryptJWE(jwe, decrypter1)).toEqual(cleartext) }) it('Creates with aad', async () => { expect.assertions(6) const aad = u8a.fromString('this data is authenticated') - const jwe = await createJWE( - cleartext, - [recipients[0].encrypter, recipients[1].encrypter], - { more: 'protected' }, - aad, - ) + const jwe = await createJWE(cleartext, [encrypter1, encrypter2], { more: 'protected' }, aad) expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P', more: 'protected' }) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) - expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) + expect(await decryptJWE(jwe, decrypter1)).toEqual(cleartext) + expect(await decryptJWE(jwe, decrypter2)).toEqual(cleartext) delete jwe.aad - await expect(decryptJWE(jwe, recipients[0].decrypter)).rejects.toThrowError('Failed to decrypt') - await expect(decryptJWE(jwe, recipients[0].decrypter)).rejects.toThrowError('Failed to decrypt') + await expect(decryptJWE(jwe, decrypter1)).rejects.toThrowError('Failed to decrypt') + await expect(decryptJWE(jwe, decrypter2)).rejects.toThrowError('Failed to decrypt') }) it('Incompatible encrypters throw', async () => { @@ -487,841 +249,1100 @@ describe('ECDH-1PU+A256KW (X25519), Key Wrapping Mode with XC20P content encrypt await expect(createJWE(cleartext, [enc1, enc2])).rejects.toThrowError('Incompatible encrypters passed') }) }) -}) - -describe('ECDH-ES+A256KW (X25519), Key Wrapping Mode with A256GCM content encryption', () => { - describe('One recipient', () => { - let cleartext: Uint8Array, recipientKey: any, senderKey: any, decrypter: Decrypter - beforeEach(() => { - recipientKey = generateX25519KeyPairFromSeed(randomBytes(32)) - senderKey = generateX25519KeyPairFromSeed(randomBytes(32)) - cleartext = u8a.fromString('my secret message') - decrypter = a256gcmAnonDecrypterX25519WithA256KW(recipientKey.secretKey) - }) + describe('ECDH-1PU+A256KW (X25519), Key Wrapping Mode with XC20P content encryption', () => { + describe('One recipient', () => { + let cleartext: Uint8Array, recipientKey: any, senderKey: any, decrypter: Decrypter - it('Creates with only ciphertext', async () => { - const encrypter = a256gcmAnonEncrypterX25519WithA256KW(recipientKey.publicKey) - expect.assertions(3) - const jwe = await createJWE(cleartext, [encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) + beforeEach(() => { + recipientKey = generateX25519KeyPairFromSeed(randomBytes(32)) + senderKey = generateX25519KeyPairFromSeed(randomBytes(32)) + cleartext = u8a.fromString('my secret message') + decrypter = xc20pAuthDecrypterEcdh1PuV3x25519WithA256KW(recipientKey.secretKey, senderKey.publicKey) + }) - it('Creates with kid, no apu and no apv', async () => { - const kid = 'did:example:receiver#key-1' - const encrypter = a256gcmAnonEncrypterX25519WithA256KW(recipientKey.publicKey, kid) - expect.assertions(6) - const jwe = await createJWE(cleartext, [encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) - expect(jwe.recipients!![0].header.kid).toEqual(kid) - expect(jwe.recipients!![0].header.apu).toBeUndefined() - expect(jwe.recipients!![0].header.apv).toBeUndefined() - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) + it('Creates with only ciphertext', async () => { + const encrypter = xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW( + recipientKey.publicKey, + senderKey.secretKey, + ) + expect.assertions(3) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P' }) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - it('Creates with no kid, with apv', async () => { - const apv = encodeBase64url('Bob') - const encrypter = a256gcmAnonEncrypterX25519WithA256KW(recipientKey.publicKey, undefined, apv) - expect.assertions(5) - const jwe = await createJWE(cleartext, [encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) - expect(jwe.recipients!![0].header.kid).toBeUndefined() - expect(jwe.recipients!![0].header.apv).toEqual(apv) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) + it('Creates with kid, no apu and no apv', async () => { + const kid = 'did:example:receiver#key-1' + const encrypter = xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW( + recipientKey.publicKey, + senderKey.secretKey, + { + kid, + }, + ) + expect.assertions(6) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P' }) + expect(jwe.recipients!![0].header.kid).toEqual(kid) + expect(jwe.recipients!![0].header.apu).toBeUndefined() + expect(jwe.recipients!![0].header.apv).toBeUndefined() + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - it('Creates with kid and apv', async () => { - const kid = 'did:example:receiver#key-1' - const apv = encodeBase64url('Bob') - const encrypter = a256gcmAnonEncrypterX25519WithA256KW(recipientKey.publicKey, kid, apv) - expect.assertions(5) - const jwe = await createJWE(cleartext, [encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) - expect(jwe.recipients!![0].header.kid).toEqual(kid) - expect(jwe.recipients!![0].header.apv).toEqual(apv) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) + it('Creates with no kid, apu and apv', async () => { + const apu = encodeBase64url('Alice') + const apv = encodeBase64url('Bob') + const encrypter = xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW( + recipientKey.publicKey, + senderKey.secretKey, + { + apu, + apv, + }, + ) + expect.assertions(6) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P' }) + expect(jwe.recipients!![0].header.kid).toBeUndefined() + expect(jwe.recipients!![0].header.apu).toEqual(apu) + expect(jwe.recipients!![0].header.apv).toEqual(apv) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - it('Creates with data in protected header', async () => { - const encrypter = a256gcmAnonEncrypterX25519WithA256KW(recipientKey.publicKey) - const skid = 'did:example:sender#key-1' - expect.assertions(3) - const jwe = await createJWE(cleartext, [encrypter], { skid, more: 'protected' }) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM', skid, more: 'protected' }) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) + it('Creates with kid, apu and apv', async () => { + const kid = 'did:example:receiver#key-1' + const apu = encodeBase64url('Alice') + const apv = encodeBase64url('Bob') + const encrypter = xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW( + recipientKey.publicKey, + senderKey.secretKey, + { + kid, + apu, + apv, + }, + ) + expect.assertions(6) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P' }) + expect(jwe.recipients!![0].header.kid).toEqual(kid) + expect(jwe.recipients!![0].header.apu).toEqual(apu) + expect(jwe.recipients!![0].header.apv).toEqual(apv) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - it('Creates with aad', async () => { - const encrypter = a256gcmAnonEncrypterX25519WithA256KW(recipientKey.publicKey) - expect.assertions(4) - const aad = u8a.fromString('this data is authenticated') - const jwe = await createJWE(cleartext, [encrypter], { more: 'protected' }, aad) - expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM', more: 'protected' }) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - delete jwe.aad - await expect(decryptJWE(jwe, decrypter)).rejects.toThrowError('Failed to decrypt') - }) + it('Creates with data in protected header', async () => { + const encrypter = xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW( + recipientKey.publicKey, + senderKey.secretKey, + ) + const skid = 'did:example:sender#key-1' + expect.assertions(3) + const jwe = await createJWE(cleartext, [encrypter], { skid, more: 'protected' }) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P', skid, more: 'protected' }) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - describe('using remote ECDH', () => { - const message = 'hello world' - const receiverPair = generateX25519KeyPairFromSeed(randomBytes(32)) - const receiverRemoteECDH = createX25519ECDH(receiverPair.secretKey) + it('Creates with aad', async () => { + const encrypter = xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW( + recipientKey.publicKey, + senderKey.secretKey, + ) + expect.assertions(4) + const aad = u8a.fromString('this data is authenticated') + const jwe = await createJWE(cleartext, [encrypter], { more: 'protected' }, aad) + expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P', more: 'protected' }) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + delete jwe.aad + await expect(decryptJWE(jwe, decrypter)).rejects.toThrowError('Failed to decrypt') + }) - it('creates JWE with remote ECDH', async () => { - const encrypter = a256gcmAnonEncrypterX25519WithA256KW(receiverPair.publicKey) - const jwe: JWE = await createJWE(u8a.fromString(message), [encrypter]) - const decrypter = a256gcmAnonDecrypterX25519WithA256KW(receiverRemoteECDH) - const decryptedBytes = await decryptJWE(jwe, decrypter) - const receivedMessage = u8a.toString(decryptedBytes) - expect(receivedMessage).toEqual(message) + describe('using remote ECDH', () => { + const message = 'hello world' + const receiverPair = generateX25519KeyPairFromSeed(randomBytes(32)) + const receiverRemoteECDH = createX25519ECDH(receiverPair.secretKey) + const senderPair = generateX25519KeyPairFromSeed(randomBytes(32)) + const senderRemoteECDH: ECDH = createX25519ECDH(senderPair.secretKey) + + it('creates anon JWE with remote ECDH', async () => { + const encrypter = xc20pAnonEncrypterX25519WithA256KW(receiverPair.publicKey) + const jwe: JWE = await createJWE(u8a.fromString(message), [encrypter]) + const decrypter = xc20pAnonDecrypterX25519WithA256KW(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 = xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW( + receiverPair.publicKey, + senderRemoteECDH, + ) + const jwe: JWE = await createJWE(u8a.fromString(message), [encrypter]) + const decrypter = xc20pAuthDecrypterEcdh1PuV3x25519WithA256KW( + 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') + }) }) }) - }) - - describe('Multiple recipients', () => { - let cleartext: any, senderkey: any - const recipients: any[] = [] - - beforeEach(() => { - senderkey = generateX25519KeyPairFromSeed(randomBytes(32)) - cleartext = u8a.fromString('my secret message') - recipients[0] = { - kid: 'did:example:receiver1#key-1', - recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), - } - recipients[0] = { - ...recipients[0], - ...{ - encrypter: a256gcmAnonEncrypterX25519WithA256KW( - recipients[0].recipientkey.publicKey, - recipients[0].kid, - ), - decrypter: a256gcmAnonDecrypterX25519WithA256KW(recipients[0].recipientkey.secretKey), - }, - } - - recipients[1] = { - kid: 'did:example:receiver2#key-1', - recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), - } - recipients[1] = { - ...recipients[1], - ...{ - encrypter: a256gcmAnonEncrypterX25519WithA256KW( - recipients[1].recipientkey.publicKey, - recipients[1].kid, - ), - decrypter: a256gcmAnonDecrypterX25519WithA256KW(recipients[1].recipientkey.secretKey), - }, - } - }) + describe('Multiple recipients', () => { + let cleartext: any, senderkey: any + const recipients: any[] = [] + + beforeEach(() => { + senderkey = generateX25519KeyPairFromSeed(randomBytes(32)) + cleartext = u8a.fromString('my secret message') + + recipients[0] = { + kid: 'did:example:receiver1#key-1', + recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), + } + recipients[0] = { + ...recipients[0], + ...{ + encrypter: xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW( + recipients[0].recipientkey.publicKey, + senderkey.secretKey, + { kid: recipients[0].kid }, + ), + decrypter: xc20pAuthDecrypterEcdh1PuV3x25519WithA256KW( + recipients[0].recipientkey.secretKey, + senderkey.publicKey, + ), + }, + } + + recipients[1] = { + kid: 'did:example:receiver2#key-1', + recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), + } + recipients[1] = { + ...recipients[1], + ...{ + encrypter: xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW( + recipients[1].recipientkey.publicKey, + senderkey.secretKey, + { kid: recipients[1].kid }, + ), + decrypter: xc20pAuthDecrypterEcdh1PuV3x25519WithA256KW( + recipients[1].recipientkey.secretKey, + senderkey.publicKey, + ), + }, + } + }) - it('Creates with only ciphertext', async () => { - expect.assertions(4) - const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) - expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) - }) + it('Creates with only ciphertext', async () => { + expect.assertions(4) + const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P' }) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) + }) - it('Creates with data in protected header', async () => { - expect.assertions(4) - const skid = 'did:example:sender#key-1' - const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter], { - more: 'protected', - skid, + it('Creates with data in protected header', async () => { + expect.assertions(4) + const skid = 'did:example:sender#key-1' + const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter], { + more: 'protected', + skid, + }) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P', more: 'protected', skid }) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) }) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM', more: 'protected', skid }) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) - }) - it('Creates with aad', async () => { - expect.assertions(6) - const aad = u8a.fromString('this data is authenticated') - const jwe = await createJWE( - cleartext, - [recipients[0].encrypter, recipients[1].encrypter], - { more: 'protected' }, - aad, - ) - expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM', more: 'protected' }) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) - expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) - delete jwe.aad - await expect(decryptJWE(jwe, recipients[0].decrypter)).rejects.toThrowError('Failed to decrypt') - await expect(decryptJWE(jwe, recipients[0].decrypter)).rejects.toThrowError('Failed to decrypt') - }) + it('Creates with aad', async () => { + expect.assertions(6) + const aad = u8a.fromString('this data is authenticated') + const jwe = await createJWE( + cleartext, + [recipients[0].encrypter, recipients[1].encrypter], + { more: 'protected' }, + aad, + ) + expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P', more: 'protected' }) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) + delete jwe.aad + await expect(decryptJWE(jwe, recipients[0].decrypter)).rejects.toThrowError('Failed to decrypt') + await expect(decryptJWE(jwe, recipients[0].decrypter)).rejects.toThrowError('Failed to decrypt') + }) - it('Incompatible encrypters throw', async () => { - expect.assertions(1) - const enc1 = { enc: 'cool enc alg1' } as Encrypter - const enc2 = { enc: 'cool enc alg2' } as Encrypter - await expect(createJWE(cleartext, [enc1, enc2])).rejects.toThrowError('Incompatible encrypters passed') + it('Incompatible encrypters throw', async () => { + expect.assertions(1) + const enc1 = { enc: 'cool enc alg1' } as Encrypter + const enc2 = { enc: 'cool enc alg2' } as Encrypter + await expect(createJWE(cleartext, [enc1, enc2])).rejects.toThrowError('Incompatible encrypters passed') + }) }) }) -}) - -describe('ECDH-1PU+A256KW (X25519), Key Wrapping Mode with A256GCM content encryption', () => { - describe('One recipient', () => { - let cleartext: Uint8Array, recipientKey: any, senderKey: any, decrypter: Decrypter - beforeEach(() => { - recipientKey = generateX25519KeyPairFromSeed(randomBytes(32)) - senderKey = generateX25519KeyPairFromSeed(randomBytes(32)) - cleartext = u8a.fromString('my secret message') - decrypter = a256gcmAuthDecrypterEcdh1PuV3x25519WithA256KW(recipientKey.secretKey, senderKey.publicKey) - }) + describe('ECDH-ES+A256KW (X25519), Key Wrapping Mode with A256GCM content encryption', () => { + describe('One recipient', () => { + let cleartext: Uint8Array, recipientKey: any, senderKey: any, decrypter: Decrypter - it('Creates with only ciphertext', async () => { - const encrypter = a256gcmAuthEncrypterEcdh1PuV3x25519WithA256KW( - recipientKey.publicKey, - senderKey.secretKey, - ) - expect.assertions(3) - const jwe = await createJWE(cleartext, [encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) + beforeEach(() => { + recipientKey = generateX25519KeyPairFromSeed(randomBytes(32)) + senderKey = generateX25519KeyPairFromSeed(randomBytes(32)) + cleartext = u8a.fromString('my secret message') + decrypter = a256gcmAnonDecrypterX25519WithA256KW(recipientKey.secretKey) + }) - it('Creates with kid, no apu and no apv', async () => { - const kid = 'did:example:receiver#key-1' - const encrypter = a256gcmAuthEncrypterEcdh1PuV3x25519WithA256KW( - recipientKey.publicKey, - senderKey.secretKey, - { - kid, - }, - ) - expect.assertions(6) - const jwe = await createJWE(cleartext, [encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) - expect(jwe.recipients!![0].header.kid).toEqual(kid) - expect(jwe.recipients!![0].header.apu).toBeUndefined() - expect(jwe.recipients!![0].header.apv).toBeUndefined() - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) + it('Creates with only ciphertext', async () => { + const encrypter = a256gcmAnonEncrypterX25519WithA256KW(recipientKey.publicKey) + expect.assertions(3) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - it('Creates with no kid, with apu and apv', async () => { - const apu = encodeBase64url('Alice') - const apv = encodeBase64url('Bob') - const encrypter = a256gcmAuthEncrypterEcdh1PuV3x25519WithA256KW( - recipientKey.publicKey, - senderKey.secretKey, - { - apu, - apv, - }, - ) - expect.assertions(6) - const jwe = await createJWE(cleartext, [encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) - expect(jwe.recipients!![0].header.kid).toBeUndefined() - expect(jwe.recipients!![0].header.apu).toEqual(apu) - expect(jwe.recipients!![0].header.apv).toEqual(apv) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) + it('Creates with kid, no apu and no apv', async () => { + const kid = 'did:example:receiver#key-1' + const encrypter = a256gcmAnonEncrypterX25519WithA256KW(recipientKey.publicKey, kid) + expect.assertions(6) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) + expect(jwe.recipients!![0].header.kid).toEqual(kid) + expect(jwe.recipients!![0].header.apu).toBeUndefined() + expect(jwe.recipients!![0].header.apv).toBeUndefined() + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - it('Creates with kid and apu and apv', async () => { - const kid = 'did:example:receiver#key-1' - const apu = encodeBase64url('Alice') - const apv = encodeBase64url('Bob') - const encrypter = a256gcmAuthEncrypterEcdh1PuV3x25519WithA256KW( - recipientKey.publicKey, - senderKey.secretKey, - { - kid, - apu, - apv, - }, - ) - expect.assertions(6) - const jwe = await createJWE(cleartext, [encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) - expect(jwe.recipients!![0].header.kid).toEqual(kid) - expect(jwe.recipients!![0].header.apu).toEqual(apu) - expect(jwe.recipients!![0].header.apv).toEqual(apv) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) + it('Creates with no kid, with apv', async () => { + const apv = encodeBase64url('Bob') + const encrypter = a256gcmAnonEncrypterX25519WithA256KW(recipientKey.publicKey, undefined, apv) + expect.assertions(5) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) + expect(jwe.recipients!![0].header.kid).toBeUndefined() + expect(jwe.recipients!![0].header.apv).toEqual(apv) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - it('Creates with data in protected header', async () => { - const encrypter = a256gcmAuthEncrypterEcdh1PuV3x25519WithA256KW( - recipientKey.publicKey, - senderKey.secretKey, - ) - const skid = 'did:example:sender#key-1' - expect.assertions(3) - const jwe = await createJWE(cleartext, [encrypter], { skid, more: 'protected' }) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM', skid, more: 'protected' }) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) + it('Creates with kid and apv', async () => { + const kid = 'did:example:receiver#key-1' + const apv = encodeBase64url('Bob') + const encrypter = a256gcmAnonEncrypterX25519WithA256KW(recipientKey.publicKey, kid, apv) + expect.assertions(5) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) + expect(jwe.recipients!![0].header.kid).toEqual(kid) + expect(jwe.recipients!![0].header.apv).toEqual(apv) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - it('Creates with aad', async () => { - const encrypter = a256gcmAuthEncrypterEcdh1PuV3x25519WithA256KW( - recipientKey.publicKey, - senderKey.secretKey, - ) - expect.assertions(4) - const aad = u8a.fromString('this data is authenticated') - const jwe = await createJWE(cleartext, [encrypter], { more: 'protected' }, aad) - expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM', more: 'protected' }) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - delete jwe.aad - await expect(decryptJWE(jwe, decrypter)).rejects.toThrowError('Failed to decrypt') - }) + it('Creates with data in protected header', async () => { + const encrypter = a256gcmAnonEncrypterX25519WithA256KW(recipientKey.publicKey) + const skid = 'did:example:sender#key-1' + expect.assertions(3) + const jwe = await createJWE(cleartext, [encrypter], { skid, more: 'protected' }) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM', skid, more: 'protected' }) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - describe('using remote ECDH', () => { - const message = 'hello world' - const receiverPair = generateX25519KeyPairFromSeed(randomBytes(32)) - const receiverRemoteECDH = createX25519ECDH(receiverPair.secretKey) - const senderPair = generateX25519KeyPairFromSeed(randomBytes(32)) - const senderRemoteECDH: ECDH = createX25519ECDH(senderPair.secretKey) + it('Creates with aad', async () => { + const encrypter = a256gcmAnonEncrypterX25519WithA256KW(recipientKey.publicKey) + expect.assertions(4) + const aad = u8a.fromString('this data is authenticated') + const jwe = await createJWE(cleartext, [encrypter], { more: 'protected' }, aad) + expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM', more: 'protected' }) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + delete jwe.aad + await expect(decryptJWE(jwe, decrypter)).rejects.toThrow() + }) - it('creates JWE with remote ECDH', async () => { - const encrypter = a256gcmAuthEncrypterEcdh1PuV3x25519WithA256KW( - receiverPair.publicKey, - senderRemoteECDH, - ) - const jwe: JWE = await createJWE(u8a.fromString(message), [encrypter]) - const decrypter = a256gcmAuthDecrypterEcdh1PuV3x25519WithA256KW( - receiverRemoteECDH, - senderPair.publicKey, - ) - const decryptedBytes = await decryptJWE(jwe, decrypter) - const receivedMessage = u8a.toString(decryptedBytes) - expect(receivedMessage).toEqual(message) + describe('using remote ECDH', () => { + const message = 'hello world' + const receiverPair = generateX25519KeyPairFromSeed(randomBytes(32)) + const receiverRemoteECDH = createX25519ECDH(receiverPair.secretKey) + + it('creates JWE with remote ECDH', async () => { + const encrypter = a256gcmAnonEncrypterX25519WithA256KW(receiverPair.publicKey) + const jwe: JWE = await createJWE(u8a.fromString(message), [encrypter]) + const decrypter = a256gcmAnonDecrypterX25519WithA256KW(receiverRemoteECDH) + const decryptedBytes = await decryptJWE(jwe, decrypter) + const receivedMessage = u8a.toString(decryptedBytes) + expect(receivedMessage).toEqual(message) + }) }) }) - }) - describe('Multiple recipients', () => { - let cleartext: any, senderkey: any - const recipients: any[] = [] + describe('Multiple recipients', () => { + let cleartext: any, senderkey: any + const recipients: any[] = [] + + beforeEach(() => { + senderkey = generateX25519KeyPairFromSeed(randomBytes(32)) + cleartext = u8a.fromString('my secret message') + + recipients[0] = { + kid: 'did:example:receiver1#key-1', + recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), + } + recipients[0] = { + ...recipients[0], + ...{ + encrypter: a256gcmAnonEncrypterX25519WithA256KW( + recipients[0].recipientkey.publicKey, + recipients[0].kid, + ), + decrypter: a256gcmAnonDecrypterX25519WithA256KW(recipients[0].recipientkey.secretKey), + }, + } + + recipients[1] = { + kid: 'did:example:receiver2#key-1', + recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), + } + recipients[1] = { + ...recipients[1], + ...{ + encrypter: a256gcmAnonEncrypterX25519WithA256KW( + recipients[1].recipientkey.publicKey, + recipients[1].kid, + ), + decrypter: a256gcmAnonDecrypterX25519WithA256KW(recipients[1].recipientkey.secretKey), + }, + } + }) - beforeEach(() => { - senderkey = generateX25519KeyPairFromSeed(randomBytes(32)) - cleartext = u8a.fromString('my secret message') + it('Creates with only ciphertext', async () => { + expect.assertions(4) + const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) + }) - recipients[0] = { - kid: 'did:example:receiver1#key-1', - recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), - } - recipients[0] = { - ...recipients[0], - ...{ - encrypter: a256gcmAuthEncrypterEcdh1PuV3x25519WithA256KW( - recipients[0].recipientkey.publicKey, - senderkey.secretKey, - { kid: recipients[0].kid }, - ), - decrypter: a256gcmAuthDecrypterEcdh1PuV3x25519WithA256KW( - recipients[0].recipientkey.secretKey, - senderkey.publicKey, - ), - }, - } + it('Creates with data in protected header', async () => { + expect.assertions(4) + const skid = 'did:example:sender#key-1' + const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter], { + more: 'protected', + skid, + }) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM', more: 'protected', skid }) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + }) - recipients[1] = { - kid: 'did:example:receiver2#key-1', - recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), - } - recipients[1] = { - ...recipients[1], - ...{ - encrypter: a256gcmAuthEncrypterEcdh1PuV3x25519WithA256KW( - recipients[1].recipientkey.publicKey, - senderkey.secretKey, - { kid: recipients[1].kid }, - ), - decrypter: a256gcmAuthDecrypterEcdh1PuV3x25519WithA256KW( - recipients[1].recipientkey.secretKey, - senderkey.publicKey, - ), - }, - } - }) + it('Creates with aad', async () => { + expect.assertions(6) + const aad = u8a.fromString('this data is authenticated') + const jwe = await createJWE( + cleartext, + [recipients[0].encrypter, recipients[1].encrypter], + { more: 'protected' }, + aad, + ) + expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM', more: 'protected' }) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) + delete jwe.aad + await expect(decryptJWE(jwe, recipients[0].decrypter)).rejects.toThrow() + await expect(decryptJWE(jwe, recipients[1].decrypter)).rejects.toThrow() + }) - it('Creates with only ciphertext', async () => { - expect.assertions(4) - const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) - expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) + it('Incompatible encrypters throw', async () => { + expect.assertions(1) + const enc1 = { enc: 'cool enc alg1' } as Encrypter + const enc2 = { enc: 'cool enc alg2' } as Encrypter + await expect(createJWE(cleartext, [enc1, enc2])).rejects.toThrowError('Incompatible encrypters passed') + }) }) + }) - it('Creates with data in protected header', async () => { - expect.assertions(4) - const skid = 'did:example:sender#key-1' - const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter], { - more: 'protected', - skid, + describe('ECDH-1PU+A256KW (X25519), Key Wrapping Mode with A256GCM content encryption', () => { + describe('One recipient', () => { + let cleartext: Uint8Array, recipientKey: any, senderKey: any, decrypter: Decrypter + + beforeEach(() => { + recipientKey = generateX25519KeyPairFromSeed(randomBytes(32)) + senderKey = generateX25519KeyPairFromSeed(randomBytes(32)) + cleartext = u8a.fromString('my secret message') + decrypter = a256gcmAuthDecrypterEcdh1PuV3x25519WithA256KW(recipientKey.secretKey, senderKey.publicKey) }) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM', more: 'protected', skid }) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) - }) - it('Creates with aad', async () => { - expect.assertions(6) - const aad = u8a.fromString('this data is authenticated') - const jwe = await createJWE( - cleartext, - [recipients[0].encrypter, recipients[1].encrypter], - { more: 'protected' }, - aad, - ) - expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM', more: 'protected' }) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) - expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) - delete jwe.aad - await expect(decryptJWE(jwe, recipients[0].decrypter)).rejects.toThrowError('Failed to decrypt') - await expect(decryptJWE(jwe, recipients[0].decrypter)).rejects.toThrowError('Failed to decrypt') - }) + it('Creates with only ciphertext', async () => { + const encrypter = a256gcmAuthEncrypterEcdh1PuV3x25519WithA256KW( + recipientKey.publicKey, + senderKey.secretKey, + ) + expect.assertions(3) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - it('Incompatible encrypters throw', async () => { - expect.assertions(1) - const enc1 = { enc: 'cool enc alg1' } as Encrypter - const enc2 = { enc: 'cool enc alg2' } as Encrypter - await expect(createJWE(cleartext, [enc1, enc2])).rejects.toThrowError('Incompatible encrypters passed') - }) - }) -}) + it('Creates with kid, no apu and no apv', async () => { + const kid = 'did:example:receiver#key-1' + const encrypter = a256gcmAuthEncrypterEcdh1PuV3x25519WithA256KW( + recipientKey.publicKey, + senderKey.secretKey, + { + kid, + }, + ) + expect.assertions(6) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) + expect(jwe.recipients!![0].header.kid).toEqual(kid) + expect(jwe.recipients!![0].header.apu).toBeUndefined() + expect(jwe.recipients!![0].header.apv).toBeUndefined() + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) -describe('ECDH-ES+A256KW (X25519), Key Wrapping Mode with A256CBC-HS512 content encryption', () => { - describe('One recipient', () => { - let cleartext: Uint8Array, recipientKey: any, senderKey: any, decrypter: Decrypter + it('Creates with no kid, with apu and apv', async () => { + const apu = encodeBase64url('Alice') + const apv = encodeBase64url('Bob') + const encrypter = a256gcmAuthEncrypterEcdh1PuV3x25519WithA256KW( + recipientKey.publicKey, + senderKey.secretKey, + { + apu, + apv, + }, + ) + expect.assertions(6) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) + expect(jwe.recipients!![0].header.kid).toBeUndefined() + expect(jwe.recipients!![0].header.apu).toEqual(apu) + expect(jwe.recipients!![0].header.apv).toEqual(apv) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - beforeEach(() => { - recipientKey = generateX25519KeyPairFromSeed(randomBytes(32)) - senderKey = generateX25519KeyPairFromSeed(randomBytes(32)) - cleartext = u8a.fromString('my secret message') - decrypter = a256cbcHs512AnonDecrypterX25519WithA256KW(recipientKey.secretKey) - }) + it('Creates with kid and apu and apv', async () => { + const kid = 'did:example:receiver#key-1' + const apu = encodeBase64url('Alice') + const apv = encodeBase64url('Bob') + const encrypter = a256gcmAuthEncrypterEcdh1PuV3x25519WithA256KW( + recipientKey.publicKey, + senderKey.secretKey, + { + kid, + apu, + apv, + }, + ) + expect.assertions(6) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) + expect(jwe.recipients!![0].header.kid).toEqual(kid) + expect(jwe.recipients!![0].header.apu).toEqual(apu) + expect(jwe.recipients!![0].header.apv).toEqual(apv) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - it('Creates with only ciphertext', async () => { - const encrypter = a256cbcHs512AnonEncrypterX25519WithA256KW(recipientKey.publicKey) - expect.assertions(3) - const jwe = await createJWE(cleartext, [encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) + it('Creates with data in protected header', async () => { + const encrypter = a256gcmAuthEncrypterEcdh1PuV3x25519WithA256KW( + recipientKey.publicKey, + senderKey.secretKey, + ) + const skid = 'did:example:sender#key-1' + expect.assertions(3) + const jwe = await createJWE(cleartext, [encrypter], { skid, more: 'protected' }) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM', skid, more: 'protected' }) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - it('Creates with kid, no apu and no apv', async () => { - const kid = 'did:example:receiver#key-1' - const encrypter = a256cbcHs512AnonEncrypterX25519WithA256KW(recipientKey.publicKey, kid) - expect.assertions(6) - const jwe = await createJWE(cleartext, [encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) - expect(jwe.recipients!![0].header.kid).toEqual(kid) - expect(jwe.recipients!![0].header.apu).toBeUndefined() - expect(jwe.recipients!![0].header.apv).toBeUndefined() - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) + it('Creates with aad', async () => { + const encrypter = a256gcmAuthEncrypterEcdh1PuV3x25519WithA256KW( + recipientKey.publicKey, + senderKey.secretKey, + ) + expect.assertions(4) + const aad = u8a.fromString('this data is authenticated') + const jwe = await createJWE(cleartext, [encrypter], { more: 'protected' }, aad) + expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM', more: 'protected' }) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + delete jwe.aad + await expect(decryptJWE(jwe, decrypter)).rejects.toThrow() + }) - it('Creates with no kid, with apv', async () => { - const apv = encodeBase64url('Bob') - const encrypter = a256cbcHs512AnonEncrypterX25519WithA256KW(recipientKey.publicKey, undefined, apv) - expect.assertions(5) - const jwe = await createJWE(cleartext, [encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) - expect(jwe.recipients!![0].header.kid).toBeUndefined() - expect(jwe.recipients!![0].header.apv).toEqual(apv) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + describe('using remote ECDH', () => { + const message = 'hello world' + const receiverPair = generateX25519KeyPairFromSeed(randomBytes(32)) + const receiverRemoteECDH = createX25519ECDH(receiverPair.secretKey) + const senderPair = generateX25519KeyPairFromSeed(randomBytes(32)) + const senderRemoteECDH: ECDH = createX25519ECDH(senderPair.secretKey) + + it('creates JWE with remote ECDH', async () => { + const encrypter = a256gcmAuthEncrypterEcdh1PuV3x25519WithA256KW( + receiverPair.publicKey, + senderRemoteECDH, + ) + const jwe: JWE = await createJWE(u8a.fromString(message), [encrypter]) + const decrypter = a256gcmAuthDecrypterEcdh1PuV3x25519WithA256KW( + receiverRemoteECDH, + senderPair.publicKey, + ) + const decryptedBytes = await decryptJWE(jwe, decrypter) + const receivedMessage = u8a.toString(decryptedBytes) + expect(receivedMessage).toEqual(message) + }) + }) }) - it('Creates with kid and apv', async () => { - const kid = 'did:example:receiver#key-1' - const apv = encodeBase64url('Bob') - const encrypter = a256cbcHs512AnonEncrypterX25519WithA256KW(recipientKey.publicKey, kid, apv) - expect.assertions(5) - const jwe = await createJWE(cleartext, [encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) - expect(jwe.recipients!![0].header.kid).toEqual(kid) - expect(jwe.recipients!![0].header.apv).toEqual(apv) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) + describe('Multiple recipients', () => { + let cleartext: any, senderkey: any + const recipients: any[] = [] + + beforeEach(() => { + senderkey = generateX25519KeyPairFromSeed(randomBytes(32)) + cleartext = u8a.fromString('my secret message') + + recipients[0] = { + kid: 'did:example:receiver1#key-1', + recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), + } + recipients[0] = { + ...recipients[0], + ...{ + encrypter: a256gcmAuthEncrypterEcdh1PuV3x25519WithA256KW( + recipients[0].recipientkey.publicKey, + senderkey.secretKey, + { kid: recipients[0].kid }, + ), + decrypter: a256gcmAuthDecrypterEcdh1PuV3x25519WithA256KW( + recipients[0].recipientkey.secretKey, + senderkey.publicKey, + ), + }, + } + + recipients[1] = { + kid: 'did:example:receiver2#key-1', + recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), + } + recipients[1] = { + ...recipients[1], + ...{ + encrypter: a256gcmAuthEncrypterEcdh1PuV3x25519WithA256KW( + recipients[1].recipientkey.publicKey, + senderkey.secretKey, + { kid: recipients[1].kid }, + ), + decrypter: a256gcmAuthDecrypterEcdh1PuV3x25519WithA256KW( + recipients[1].recipientkey.secretKey, + senderkey.publicKey, + ), + }, + } + }) - it('Creates with data in protected header', async () => { - const encrypter = a256cbcHs512AnonEncrypterX25519WithA256KW(recipientKey.publicKey) - const skid = 'did:example:sender#key-1' - expect.assertions(3) - const jwe = await createJWE(cleartext, [encrypter], { skid, more: 'protected' }) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ - enc: 'A256CBC-HS512', - skid, - more: 'protected', + it('Creates with only ciphertext', async () => { + expect.assertions(4) + const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM' }) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) }) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) - it('Creates with aad', async () => { - const encrypter = a256cbcHs512AnonEncrypterX25519WithA256KW(recipientKey.publicKey) - expect.assertions(4) - const aad = u8a.fromString('this data is authenticated') - const jwe = await createJWE(cleartext, [encrypter], { more: 'protected' }, aad) - expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512', more: 'protected' }) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - delete jwe.aad - await expect(decryptJWE(jwe, decrypter)).rejects.toThrowError('Failed to decrypt') - }) + it('Creates with data in protected header', async () => { + expect.assertions(4) + const skid = 'did:example:sender#key-1' + const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter], { + more: 'protected', + skid, + }) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM', more: 'protected', skid }) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + }) - describe('using remote ECDH', () => { - const message = 'hello world' - const receiverPair = generateX25519KeyPairFromSeed(randomBytes(32)) - const receiverRemoteECDH = createX25519ECDH(receiverPair.secretKey) + it('Creates with aad', async () => { + expect.assertions(6) + const aad = u8a.fromString('this data is authenticated') + const jwe = await createJWE( + cleartext, + [recipients[0].encrypter, recipients[1].encrypter], + { more: 'protected' }, + aad, + ) + expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256GCM', more: 'protected' }) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) + delete jwe.aad + await expect(decryptJWE(jwe, recipients[0].decrypter)).rejects.toThrow() + await expect(decryptJWE(jwe, recipients[1].decrypter)).rejects.toThrow() + }) - it('creates JWE with remote ECDH', async () => { - const encrypter = a256cbcHs512AnonEncrypterX25519WithA256KW(receiverPair.publicKey) - const jwe: JWE = await createJWE(u8a.fromString(message), [encrypter]) - const decrypter = a256cbcHs512AnonDecrypterX25519WithA256KW(receiverRemoteECDH) - const decryptedBytes = await decryptJWE(jwe, decrypter) - const receivedMessage = u8a.toString(decryptedBytes) - expect(receivedMessage).toEqual(message) + it('Incompatible encrypters throw', async () => { + expect.assertions(1) + const enc1 = { enc: 'cool enc alg1' } as Encrypter + const enc2 = { enc: 'cool enc alg2' } as Encrypter + await expect(createJWE(cleartext, [enc1, enc2])).rejects.toThrow('Incompatible encrypters passed') }) }) }) - describe('Multiple recipients', () => { - let cleartext: any, senderkey: any - const recipients: any[] = [] + describe('ECDH-ES+A256KW (X25519), Key Wrapping Mode with A256CBC-HS512 content encryption', () => { + describe('One recipient', () => { + let cleartext: Uint8Array, recipientKey: any, senderKey: any, decrypter: Decrypter - beforeEach(() => { - senderkey = generateX25519KeyPairFromSeed(randomBytes(32)) - cleartext = u8a.fromString('my secret message') + beforeEach(() => { + recipientKey = generateX25519KeyPairFromSeed(randomBytes(32)) + senderKey = generateX25519KeyPairFromSeed(randomBytes(32)) + cleartext = u8a.fromString('my secret message') + decrypter = a256cbcHs512AnonDecrypterX25519WithA256KW(recipientKey.secretKey) + }) - recipients[0] = { - kid: 'did:example:receiver1#key-1', - recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), - } - recipients[0] = { - ...recipients[0], - ...{ - encrypter: a256cbcHs512AnonEncrypterX25519WithA256KW( - recipients[0].recipientkey.publicKey, - recipients[0].kid, - ), - decrypter: a256cbcHs512AnonDecrypterX25519WithA256KW(recipients[0].recipientkey.secretKey), - }, - } + it('Creates with only ciphertext', async () => { + const encrypter = a256cbcHs512AnonEncrypterX25519WithA256KW(recipientKey.publicKey) + expect.assertions(3) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - recipients[1] = { - kid: 'did:example:receiver2#key-1', - recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), - } - recipients[1] = { - ...recipients[1], - ...{ - encrypter: a256cbcHs512AnonEncrypterX25519WithA256KW( - recipients[1].recipientkey.publicKey, - recipients[1].kid, - ), - decrypter: a256cbcHs512AnonDecrypterX25519WithA256KW(recipients[1].recipientkey.secretKey), - }, - } - }) + it('Creates with kid, no apu and no apv', async () => { + const kid = 'did:example:receiver#key-1' + const encrypter = a256cbcHs512AnonEncrypterX25519WithA256KW(recipientKey.publicKey, kid) + expect.assertions(6) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) + expect(jwe.recipients!![0].header.kid).toEqual(kid) + expect(jwe.recipients!![0].header.apu).toBeUndefined() + expect(jwe.recipients!![0].header.apv).toBeUndefined() + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - it('Creates with only ciphertext', async () => { - expect.assertions(4) - const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) - expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) - }) + it('Creates with no kid, with apv', async () => { + const apv = encodeBase64url('Bob') + const encrypter = a256cbcHs512AnonEncrypterX25519WithA256KW(recipientKey.publicKey, undefined, apv) + expect.assertions(5) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) + expect(jwe.recipients!![0].header.kid).toBeUndefined() + expect(jwe.recipients!![0].header.apv).toEqual(apv) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - it('Creates with data in protected header', async () => { - expect.assertions(4) - const skid = 'did:example:sender#key-1' - const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter], { - more: 'protected', - skid, + it('Creates with kid and apv', async () => { + const kid = 'did:example:receiver#key-1' + const apv = encodeBase64url('Bob') + const encrypter = a256cbcHs512AnonEncrypterX25519WithA256KW(recipientKey.publicKey, kid, apv) + expect.assertions(5) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) + expect(jwe.recipients!![0].header.kid).toEqual(kid) + expect(jwe.recipients!![0].header.apv).toEqual(apv) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) }) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ - enc: 'A256CBC-HS512', - more: 'protected', - skid, + + it('Creates with data in protected header', async () => { + const encrypter = a256cbcHs512AnonEncrypterX25519WithA256KW(recipientKey.publicKey) + const skid = 'did:example:sender#key-1' + expect.assertions(3) + const jwe = await createJWE(cleartext, [encrypter], { skid, more: 'protected' }) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ + enc: 'A256CBC-HS512', + skid, + more: 'protected', + }) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) }) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) - }) - it('Creates with aad', async () => { - expect.assertions(6) - const aad = u8a.fromString('this data is authenticated') - const jwe = await createJWE( - cleartext, - [recipients[0].encrypter, recipients[1].encrypter], - { more: 'protected' }, - aad, - ) - expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512', more: 'protected' }) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) - expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) - delete jwe.aad - await expect(decryptJWE(jwe, recipients[0].decrypter)).rejects.toThrowError('Failed to decrypt') - await expect(decryptJWE(jwe, recipients[0].decrypter)).rejects.toThrowError('Failed to decrypt') - }) + it('Creates with aad', async () => { + const encrypter = a256cbcHs512AnonEncrypterX25519WithA256KW(recipientKey.publicKey) + expect.assertions(4) + const aad = u8a.fromString('this data is authenticated') + const jwe = await createJWE(cleartext, [encrypter], { more: 'protected' }, aad) + expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512', more: 'protected' }) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + delete jwe.aad + await expect(decryptJWE(jwe, decrypter)).rejects.toThrowError('Failed to decrypt') + }) - it('Incompatible encrypters throw', async () => { - expect.assertions(1) - const enc1 = { enc: 'cool enc alg1' } as Encrypter - const enc2 = { enc: 'cool enc alg2' } as Encrypter - await expect(createJWE(cleartext, [enc1, enc2])).rejects.toThrowError('Incompatible encrypters passed') + describe('using remote ECDH', () => { + const message = 'hello world' + const receiverPair = generateX25519KeyPairFromSeed(randomBytes(32)) + const receiverRemoteECDH = createX25519ECDH(receiverPair.secretKey) + + it('creates JWE with remote ECDH', async () => { + const encrypter = a256cbcHs512AnonEncrypterX25519WithA256KW(receiverPair.publicKey) + const jwe: JWE = await createJWE(u8a.fromString(message), [encrypter]) + const decrypter = a256cbcHs512AnonDecrypterX25519WithA256KW(receiverRemoteECDH) + const decryptedBytes = await decryptJWE(jwe, decrypter) + const receivedMessage = u8a.toString(decryptedBytes) + expect(receivedMessage).toEqual(message) + }) + }) }) - }) -}) -describe('ECDH-1PU+A256KW (X25519), Key Wrapping Mode with A256CBC-HS512 content encryption', () => { - describe('One recipient', () => { - let cleartext: Uint8Array, recipientKey: any, senderKey: any, decrypter: Decrypter + describe('Multiple recipients', () => { + let cleartext: any, senderkey: any + const recipients: any[] = [] + + beforeEach(() => { + senderkey = generateX25519KeyPairFromSeed(randomBytes(32)) + cleartext = u8a.fromString('my secret message') + + recipients[0] = { + kid: 'did:example:receiver1#key-1', + recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), + } + recipients[0] = { + ...recipients[0], + ...{ + encrypter: a256cbcHs512AnonEncrypterX25519WithA256KW( + recipients[0].recipientkey.publicKey, + recipients[0].kid, + ), + decrypter: a256cbcHs512AnonDecrypterX25519WithA256KW(recipients[0].recipientkey.secretKey), + }, + } + + recipients[1] = { + kid: 'did:example:receiver2#key-1', + recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), + } + recipients[1] = { + ...recipients[1], + ...{ + encrypter: a256cbcHs512AnonEncrypterX25519WithA256KW( + recipients[1].recipientkey.publicKey, + recipients[1].kid, + ), + decrypter: a256cbcHs512AnonDecrypterX25519WithA256KW(recipients[1].recipientkey.secretKey), + }, + } + }) - beforeEach(() => { - recipientKey = generateX25519KeyPairFromSeed(randomBytes(32)) - senderKey = generateX25519KeyPairFromSeed(randomBytes(32)) - cleartext = u8a.fromString('my secret message') - decrypter = a256cbcHs512AuthDecrypterX25519WithA256KW(recipientKey.secretKey, senderKey.publicKey) - }) + it('Creates with only ciphertext', async () => { + expect.assertions(4) + const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) + }) - it('Creates with only ciphertext', async () => { - const encrypter = a256cbcHs512AuthEncrypterX25519WithA256KW(recipientKey.publicKey, senderKey.secretKey) - expect.assertions(3) - const jwe = await createJWE(cleartext, [encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) + it('Creates with data in protected header', async () => { + expect.assertions(4) + const skid = 'did:example:sender#key-1' + const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter], { + more: 'protected', + skid, + }) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ + enc: 'A256CBC-HS512', + more: 'protected', + skid, + }) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + }) - it('Creates with kid, no apu and no apv', async () => { - const kid = 'did:example:receiver#key-1' - const encrypter = a256cbcHs512AuthEncrypterX25519WithA256KW( - recipientKey.publicKey, - senderKey.secretKey, - { - kid, - }, - ) - expect.assertions(6) - const jwe = await createJWE(cleartext, [encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) - expect(jwe.recipients!![0].header.kid).toEqual(kid) - expect(jwe.recipients!![0].header.apu).toBeUndefined() - expect(jwe.recipients!![0].header.apv).toBeUndefined() - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) + it('Creates with aad', async () => { + expect.assertions(6) + const aad = u8a.fromString('this data is authenticated') + const jwe = await createJWE( + cleartext, + [recipients[0].encrypter, recipients[1].encrypter], + { more: 'protected' }, + aad, + ) + expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512', more: 'protected' }) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) + delete jwe.aad + await expect(decryptJWE(jwe, recipients[0].decrypter)).rejects.toThrowError('Failed to decrypt') + await expect(decryptJWE(jwe, recipients[0].decrypter)).rejects.toThrowError('Failed to decrypt') + }) - it('Creates with no kid, with apu and apv', async () => { - const apu = encodeBase64url('Alice') - const apv = encodeBase64url('Bob') - const encrypter = a256cbcHs512AuthEncrypterX25519WithA256KW( - recipientKey.publicKey, - senderKey.secretKey, - { - apu, - apv, - }, - ) - expect.assertions(6) - const jwe = await createJWE(cleartext, [encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) - expect(jwe.recipients!![0].header.kid).toBeUndefined() - expect(jwe.recipients!![0].header.apu).toEqual(apu) - expect(jwe.recipients!![0].header.apv).toEqual(apv) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + it('Incompatible encrypters throw', async () => { + expect.assertions(1) + const enc1 = { enc: 'cool enc alg1' } as Encrypter + const enc2 = { enc: 'cool enc alg2' } as Encrypter + await expect(createJWE(cleartext, [enc1, enc2])).rejects.toThrowError('Incompatible encrypters passed') + }) }) + }) - it('Creates with kid and apu and apv', async () => { - const kid = 'did:example:receiver#key-1' - const apu = encodeBase64url('Alice') - const apv = encodeBase64url('Bob') - const encrypter = a256cbcHs512AuthEncrypterX25519WithA256KW( - recipientKey.publicKey, - senderKey.secretKey, - { - kid, - apu, - apv, - }, - ) - expect.assertions(6) - const jwe = await createJWE(cleartext, [encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) - expect(jwe.recipients!![0].header.kid).toEqual(kid) - expect(jwe.recipients!![0].header.apu).toEqual(apu) - expect(jwe.recipients!![0].header.apv).toEqual(apv) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) + describe('ECDH-1PU+A256KW (X25519), Key Wrapping Mode with A256CBC-HS512 content encryption', () => { + describe('One recipient', () => { + let cleartext: Uint8Array, recipientKey: any, senderKey: any, decrypter: Decrypter - it('Creates with data in protected header', async () => { - const encrypter = a256cbcHs512AuthEncrypterX25519WithA256KW(recipientKey.publicKey, senderKey.secretKey) - const skid = 'did:example:sender#key-1' - expect.assertions(3) - const jwe = await createJWE(cleartext, [encrypter], { skid, more: 'protected' }) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ - enc: 'A256CBC-HS512', - skid, - more: 'protected', + beforeEach(() => { + recipientKey = generateX25519KeyPairFromSeed(randomBytes(32)) + senderKey = generateX25519KeyPairFromSeed(randomBytes(32)) + cleartext = u8a.fromString('my secret message') + decrypter = a256cbcHs512AuthDecrypterX25519WithA256KW(recipientKey.secretKey, senderKey.publicKey) }) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - }) - it('Creates with aad', async () => { - const encrypter = a256cbcHs512AuthEncrypterX25519WithA256KW(recipientKey.publicKey, senderKey.secretKey) - expect.assertions(4) - const aad = u8a.fromString('this data is authenticated') - const jwe = await createJWE(cleartext, [encrypter], { more: 'protected' }, aad) - expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512', more: 'protected' }) - expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) - delete jwe.aad - await expect(decryptJWE(jwe, decrypter)).rejects.toThrowError('Failed to decrypt') - }) + it('Creates with only ciphertext', async () => { + const encrypter = a256cbcHs512AuthEncrypterX25519WithA256KW(recipientKey.publicKey, senderKey.secretKey) + expect.assertions(3) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - describe('using remote ECDH', () => { - const message = 'hello world' - const receiverPair = generateX25519KeyPairFromSeed(randomBytes(32)) - const receiverRemoteECDH = createX25519ECDH(receiverPair.secretKey) - const senderPair = generateX25519KeyPairFromSeed(randomBytes(32)) - const senderRemoteECDH: ECDH = createX25519ECDH(senderPair.secretKey) - - it('creates JWE with remote ECDH', async () => { - const encrypter = a256cbcHs512AuthEncrypterX25519WithA256KW(receiverPair.publicKey, senderRemoteECDH) - const jwe: JWE = await createJWE(u8a.fromString(message), [encrypter]) - const decrypter = a256cbcHs512AuthDecrypterX25519WithA256KW(receiverRemoteECDH, senderPair.publicKey) - const decryptedBytes = await decryptJWE(jwe, decrypter) - const receivedMessage = u8a.toString(decryptedBytes) - expect(receivedMessage).toEqual(message) + it('Creates with kid, no apu and no apv', async () => { + const kid = 'did:example:receiver#key-1' + const encrypter = a256cbcHs512AuthEncrypterX25519WithA256KW( + recipientKey.publicKey, + senderKey.secretKey, + { + kid, + }, + ) + expect.assertions(6) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) + expect(jwe.recipients!![0].header.kid).toEqual(kid) + expect(jwe.recipients!![0].header.apu).toBeUndefined() + expect(jwe.recipients!![0].header.apv).toBeUndefined() + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) }) - }) - }) - describe('Multiple recipients', () => { - let cleartext: any, senderkey: any - const recipients: any[] = [] + it('Creates with no kid, with apu and apv', async () => { + const apu = encodeBase64url('Alice') + const apv = encodeBase64url('Bob') + const encrypter = a256cbcHs512AuthEncrypterX25519WithA256KW( + recipientKey.publicKey, + senderKey.secretKey, + { + apu, + apv, + }, + ) + expect.assertions(6) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) + expect(jwe.recipients!![0].header.kid).toBeUndefined() + expect(jwe.recipients!![0].header.apu).toEqual(apu) + expect(jwe.recipients!![0].header.apv).toEqual(apv) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - beforeEach(() => { - senderkey = generateX25519KeyPairFromSeed(randomBytes(32)) - cleartext = u8a.fromString('my secret message') + it('Creates with kid and apu and apv', async () => { + const kid = 'did:example:receiver#key-1' + const apu = encodeBase64url('Alice') + const apv = encodeBase64url('Bob') + const encrypter = a256cbcHs512AuthEncrypterX25519WithA256KW( + recipientKey.publicKey, + senderKey.secretKey, + { + kid, + apu, + apv, + }, + ) + expect.assertions(6) + const jwe = await createJWE(cleartext, [encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) + expect(jwe.recipients!![0].header.kid).toEqual(kid) + expect(jwe.recipients!![0].header.apu).toEqual(apu) + expect(jwe.recipients!![0].header.apv).toEqual(apv) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - recipients[0] = { - kid: 'did:example:receiver1#key-1', - recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), - } - recipients[0] = { - ...recipients[0], - ...{ - encrypter: a256cbcHs512AuthEncrypterX25519WithA256KW( - recipients[0].recipientkey.publicKey, - senderkey.secretKey, - { kid: recipients[0].kid }, - ), - decrypter: a256cbcHs512AuthDecrypterX25519WithA256KW( - recipients[0].recipientkey.secretKey, - senderkey.publicKey, - ), - }, - } + it('Creates with data in protected header', async () => { + const encrypter = a256cbcHs512AuthEncrypterX25519WithA256KW(recipientKey.publicKey, senderKey.secretKey) + const skid = 'did:example:sender#key-1' + expect.assertions(3) + const jwe = await createJWE(cleartext, [encrypter], { skid, more: 'protected' }) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ + enc: 'A256CBC-HS512', + skid, + more: 'protected', + }) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + }) - recipients[1] = { - kid: 'did:example:receiver2#key-1', - recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), - } - recipients[1] = { - ...recipients[1], - ...{ - encrypter: a256cbcHs512AuthEncrypterX25519WithA256KW( - recipients[1].recipientkey.publicKey, - senderkey.secretKey, - { kid: recipients[1].kid }, - ), - decrypter: a256cbcHs512AuthDecrypterX25519WithA256KW( - recipients[1].recipientkey.secretKey, - senderkey.publicKey, - ), - }, - } - }) + it('Creates with aad', async () => { + const encrypter = a256cbcHs512AuthEncrypterX25519WithA256KW(recipientKey.publicKey, senderKey.secretKey) + expect.assertions(4) + const aad = u8a.fromString('this data is authenticated') + const jwe = await createJWE(cleartext, [encrypter], { more: 'protected' }, aad) + expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512', more: 'protected' }) + expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) + delete jwe.aad + await expect(decryptJWE(jwe, decrypter)).rejects.toThrowError('Failed to decrypt') + }) - it('Creates with only ciphertext', async () => { - expect.assertions(4) - const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter]) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) - expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) + describe('using remote ECDH', () => { + const message = 'hello world' + const receiverPair = generateX25519KeyPairFromSeed(randomBytes(32)) + const receiverRemoteECDH = createX25519ECDH(receiverPair.secretKey) + const senderPair = generateX25519KeyPairFromSeed(randomBytes(32)) + const senderRemoteECDH: ECDH = createX25519ECDH(senderPair.secretKey) + + it('creates JWE with remote ECDH', async () => { + const encrypter = a256cbcHs512AuthEncrypterX25519WithA256KW(receiverPair.publicKey, senderRemoteECDH) + const jwe: JWE = await createJWE(u8a.fromString(message), [encrypter]) + const decrypter = a256cbcHs512AuthDecrypterX25519WithA256KW(receiverRemoteECDH, senderPair.publicKey) + const decryptedBytes = await decryptJWE(jwe, decrypter) + const receivedMessage = u8a.toString(decryptedBytes) + expect(receivedMessage).toEqual(message) + }) + }) }) - it('Creates with data in protected header', async () => { - expect.assertions(4) - const skid = 'did:example:sender#key-1' - const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter], { - more: 'protected', - skid, + describe('Multiple recipients', () => { + let cleartext: any, senderkey: any + const recipients: any[] = [] + + beforeEach(() => { + senderkey = generateX25519KeyPairFromSeed(randomBytes(32)) + cleartext = u8a.fromString('my secret message') + + recipients[0] = { + kid: 'did:example:receiver1#key-1', + recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), + } + recipients[0] = { + ...recipients[0], + ...{ + encrypter: a256cbcHs512AuthEncrypterX25519WithA256KW( + recipients[0].recipientkey.publicKey, + senderkey.secretKey, + { kid: recipients[0].kid }, + ), + decrypter: a256cbcHs512AuthDecrypterX25519WithA256KW( + recipients[0].recipientkey.secretKey, + senderkey.publicKey, + ), + }, + } + + recipients[1] = { + kid: 'did:example:receiver2#key-1', + recipientkey: generateX25519KeyPairFromSeed(randomBytes(32)), + } + recipients[1] = { + ...recipients[1], + ...{ + encrypter: a256cbcHs512AuthEncrypterX25519WithA256KW( + recipients[1].recipientkey.publicKey, + senderkey.secretKey, + { kid: recipients[1].kid }, + ), + decrypter: a256cbcHs512AuthDecrypterX25519WithA256KW( + recipients[1].recipientkey.secretKey, + senderkey.publicKey, + ), + }, + } }) - expect(jwe.aad).toBeUndefined() - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ - enc: 'A256CBC-HS512', - more: 'protected', - skid, + + it('Creates with only ciphertext', async () => { + expect.assertions(4) + const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter]) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512' }) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) }) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) - }) - it('Creates with aad', async () => { - expect.assertions(6) - const aad = u8a.fromString('this data is authenticated') - const jwe = await createJWE( - cleartext, - [recipients[0].encrypter, recipients[1].encrypter], - { more: 'protected' }, - aad, - ) - expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) - expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512', more: 'protected' }) - expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) - expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) - delete jwe.aad - await expect(decryptJWE(jwe, recipients[0].decrypter)).rejects.toThrowError('Failed to decrypt') - await expect(decryptJWE(jwe, recipients[0].decrypter)).rejects.toThrowError('Failed to decrypt') - }) + it('Creates with data in protected header', async () => { + expect.assertions(4) + const skid = 'did:example:sender#key-1' + const jwe = await createJWE(cleartext, [recipients[0].encrypter, recipients[1].encrypter], { + more: 'protected', + skid, + }) + expect(jwe.aad).toBeUndefined() + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ + enc: 'A256CBC-HS512', + more: 'protected', + skid, + }) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + }) - it('Incompatible encrypters throw', async () => { - expect.assertions(1) - const enc1 = { enc: 'cool enc alg1' } as Encrypter - const enc2 = { enc: 'cool enc alg2' } as Encrypter - await expect(createJWE(cleartext, [enc1, enc2])).rejects.toThrowError('Incompatible encrypters passed') + it('Creates with aad', async () => { + expect.assertions(6) + const aad = u8a.fromString('this data is authenticated') + const jwe = await createJWE( + cleartext, + [recipients[0].encrypter, recipients[1].encrypter], + { more: 'protected' }, + aad, + ) + expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) + expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'A256CBC-HS512', more: 'protected' }) + expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) + expect(await decryptJWE(jwe, recipients[1].decrypter)).toEqual(cleartext) + delete jwe.aad + await expect(decryptJWE(jwe, recipients[0].decrypter)).rejects.toThrowError('Failed to decrypt') + await expect(decryptJWE(jwe, recipients[0].decrypter)).rejects.toThrowError('Failed to decrypt') + }) + + it('Incompatible encrypters throw', async () => { + expect.assertions(1) + const enc1 = { enc: 'cool enc alg1' } as Encrypter + const enc2 = { enc: 'cool enc alg2' } as Encrypter + await expect(createJWE(cleartext, [enc1, enc2])).rejects.toThrowError('Incompatible encrypters passed') + }) }) }) -}) + +}) \ No newline at end of file diff --git a/packages/did-comm/src/encryption/a256cbc-hs512-dir.ts b/packages/did-comm/src/encryption/a256cbc-hs512-dir.ts index 6cba20bf2..d4fa8efad 100644 --- a/packages/did-comm/src/encryption/a256cbc-hs512-dir.ts +++ b/packages/did-comm/src/encryption/a256cbc-hs512-dir.ts @@ -1,5 +1,7 @@ -import crypto from 'isomorphic-webcrypto' import { randomBytes } from '@noble/hashes/utils' +import { hmac } from '@noble/hashes/hmac' +import { sha512 } from '@noble/hashes/sha512' +import { cbc } from '@noble/ciphers/aes' import { base64ToBytes, bytesToBase64url, concat, encodeBase64url } from '@veramo/utils' import { Decrypter, Encrypter, EncryptionResult, ProtectedHeader } from 'did-jwt' import { fromString } from 'uint8arrays/from-string' @@ -39,38 +41,18 @@ async function cbcEncrypt( ) { // A256CBC-HS512 CEK size should be 512 bits; first 256 bits are used for HMAC with SHA-512 and the rest for AES-CBC const keySize = parseInt(enc.slice(1, 4), 10) - const encKey = await crypto.subtle.importKey('raw', cek.subarray(keySize >> 3), 'AES-CBC', false, [ - 'encrypt', - ]) - const macKey = await crypto.subtle.importKey( - 'raw', - cek.subarray(0, keySize >> 3), - { - hash: `SHA-${keySize << 1}`, - name: 'HMAC', - }, - false, - ['sign'], - ) + const encKey = cek.subarray(keySize >> 3) + const macKey = cek.subarray(0, keySize >> 3) if (providedIV && providedIV.length !== keySize >> 4) { throw new Error(`illegal_argument: Invalid IV size, expected ${keySize >> 4}, got ${providedIV.length}`) } const iv = providedIV ?? randomBytes(keySize >> 4) - const ciphertext = new Uint8Array( - await crypto.subtle.encrypt( - { - iv, - name: 'AES-CBC', - }, - encKey, - plaintext, - ), - ) + const ciphertext = cbc(encKey, iv).encrypt(plaintext) const macData = concat([aad, iv, ciphertext, uint64be(aad.length << 3)]) - const tag = new Uint8Array((await crypto.subtle.sign('HMAC', macKey, macData)).slice(0, keySize >> 3)) + const tag = hmac(sha512, macKey, macData).slice(0, keySize >> 3) return { enc: 'dir', ciphertext, tag, iv } } @@ -96,30 +78,17 @@ async function cbcDecrypt( aad: Uint8Array, ) { const keySize = parseInt(enc.slice(1, 4), 10) - const encKey = await crypto.subtle.importKey('raw', cek.subarray(keySize >> 3), 'AES-CBC', false, [ - 'decrypt', - ]) - const macKey = await crypto.subtle.importKey( - 'raw', - cek.subarray(0, keySize >> 3), - { - hash: `SHA-${keySize << 1}`, - name: 'HMAC', - }, - false, - ['sign'], - ) + const encKey = cek.subarray(keySize >> 3) + const macKey = cek.subarray(0, keySize >> 3) const macData = concat([aad, iv, ciphertext, uint64be(aad.length << 3)]) - const expectedTag = new Uint8Array( - (await crypto.subtle.sign('HMAC', macKey, macData)).slice(0, keySize >> 3), - ) + const expectedTag = hmac(sha512, macKey, macData).slice(0, keySize >> 3) - let macCheckPassed!: boolean + let macCheckPassed: boolean = false try { macCheckPassed = timingSafeEqual(tag, expectedTag) } catch { - // + // nop } if (!macCheckPassed) { // current JWE decryption pipeline tries to decrypt multiple times with different keys, so return null instead of @@ -130,7 +99,7 @@ async function cbcDecrypt( let plaintext: Uint8Array | null = null try { - plaintext = new Uint8Array(await crypto.subtle.decrypt({ iv, name: 'AES-CBC' }, encKey, ciphertext)) + plaintext = cbc(encKey, iv).decrypt(ciphertext) } catch (e: any) { // current JWE decryption pipeline tries to decrypt multiple times with different keys, so return null instead of // throwing an error diff --git a/packages/did-comm/src/encryption/a256gcm-dir.ts b/packages/did-comm/src/encryption/a256gcm-dir.ts index 93cc1a21c..04c6235bc 100644 --- a/packages/did-comm/src/encryption/a256gcm-dir.ts +++ b/packages/did-comm/src/encryption/a256gcm-dir.ts @@ -1,6 +1,5 @@ import type { Decrypter, Encrypter, EncryptionResult, ProtectedHeader } from 'did-jwt' -import { AES } from '@stablelib/aes' -import { GCM } from '@stablelib/gcm' +import { gcm } from '@noble/ciphers/aes' import { randomBytes } from '@noble/hashes/utils' import { bytesToBase64url, encodeBase64url } from '@veramo/utils' import { fromString } from 'uint8arrays/from-string' @@ -8,14 +7,12 @@ import { fromString } from 'uint8arrays/from-string' function createA256GCMEncrypter( key: Uint8Array, ): (cleartext: Uint8Array, aad?: Uint8Array) => EncryptionResult { - const blockcipher = new AES(key) - const cipher = new GCM(blockcipher) return (cleartext: Uint8Array, aad?: Uint8Array) => { - const iv = randomBytes(cipher.nonceLength) - const sealed = cipher.seal(iv, cleartext, aad) + const iv = randomBytes(gcm.nonceLength) + const sealed = gcm(key, iv, aad).encrypt(cleartext) return { - ciphertext: sealed.subarray(0, sealed.length - cipher.tagLength), - tag: sealed.subarray(sealed.length - cipher.tagLength), + ciphertext: sealed.subarray(0, sealed.length - gcm.tagLength), + tag: sealed.subarray(sealed.length - gcm.tagLength), iv, } } @@ -42,10 +39,9 @@ export function a256gcmDirEncrypter(key: Uint8Array): Encrypter { } export function a256gcmDirDecrypter(key: Uint8Array): Decrypter { - const cipher = new GCM(new AES(key)) async function decrypt(sealed: Uint8Array, iv: Uint8Array, aad?: Uint8Array): Promise { - return cipher.open(iv, sealed, aad) + return gcm(key, iv, aad).decrypt(sealed) } return { alg: 'dir', enc: 'A256GCM', decrypt } diff --git a/packages/did-comm/src/encryption/xc20pkw.ts b/packages/did-comm/src/encryption/xc20pkw.ts index f8ead83d0..549bf1224 100644 --- a/packages/did-comm/src/encryption/xc20pkw.ts +++ b/packages/did-comm/src/encryption/xc20pkw.ts @@ -1,17 +1,17 @@ import type { Decrypter, KeyWrapper, WrappingResult } from 'did-jwt' import { randomBytes } from '@noble/hashes/utils' import { concat } from '@veramo/utils' -import { XChaCha20Poly1305 } from '@stablelib/xchacha20poly1305' +import { xchacha20poly1305 } from '@noble/ciphers/chacha' export const xc20pKeyWrapper: KeyWrapper = { from: (wrappingKey: Uint8Array) => { - const cipher = new XChaCha20Poly1305(wrappingKey) const wrap = async (cek: Uint8Array): Promise => { - const iv = randomBytes(cipher.nonceLength) - const sealed = cipher.seal(iv, cek) + const iv = randomBytes(xchacha20poly1305.nonceLength) + const cipher = xchacha20poly1305(wrappingKey, iv) + const sealed = cipher.encrypt(cek) return { - ciphertext: sealed.subarray(0, sealed.length - cipher.tagLength), - tag: sealed.subarray(sealed.length - cipher.tagLength), + ciphertext: sealed.subarray(0, sealed.length - xchacha20poly1305.tagLength), + tag: sealed.subarray(sealed.length - xchacha20poly1305.tagLength), iv, } } @@ -22,10 +22,10 @@ export const xc20pKeyWrapper: KeyWrapper = { } export function xc20pDecrypter(key: Uint8Array): Decrypter { - const cipher = new XChaCha20Poly1305(key) async function decrypt(sealed: Uint8Array, iv: Uint8Array, aad?: Uint8Array): Promise { - return cipher.open(iv, sealed, aad) + const cipher = xchacha20poly1305(key, iv, aad) + return cipher.decrypt(sealed) } return { alg: 'dir', enc: 'XC20P', decrypt } diff --git a/packages/did-provider-ion/package.json b/packages/did-provider-ion/package.json index b0fe4a5ea..899930127 100644 --- a/packages/did-provider-ion/package.json +++ b/packages/did-provider-ion/package.json @@ -11,8 +11,8 @@ }, "dependencies": { "@decentralized-identity/ion-sdk": "^1.0.1", - "@noble/curves": "^1.1.0", - "@noble/hashes": "^1.3.1", + "@noble/curves": "^1.4.2", + "@noble/hashes": "^1.4.0", "@sphereon/ion-pow": "^0.2.0", "@sphereon/isomorphic-argon2": "^1.0.1", "@trust/keyto": "^1.0.1", diff --git a/packages/did-provider-jwk/package.json b/packages/did-provider-jwk/package.json index bc02c3758..e19382a15 100644 --- a/packages/did-provider-jwk/package.json +++ b/packages/did-provider-jwk/package.json @@ -10,7 +10,7 @@ "extract-api": "node ../cli/bin/veramo.js dev extract-api" }, "dependencies": { - "@noble/curves": "^1.1.0", + "@noble/curves": "^1.4.2", "@veramo/core-types": "workspace:^", "@veramo/did-manager": "workspace:^", "@veramo/utils": "workspace:^", diff --git a/packages/key-manager/package.json b/packages/key-manager/package.json index 1607e87c4..9de63f9a4 100644 --- a/packages/key-manager/package.json +++ b/packages/key-manager/package.json @@ -10,7 +10,7 @@ "extract-api": "node ../cli/bin/veramo.js dev extract-api" }, "dependencies": { - "@noble/curves": "^1.1.0", + "@noble/curves": "^1.4.2", "@veramo/core-types": "workspace:^", "@veramo/utils": "workspace:^", "debug": "^4.3.4", diff --git a/packages/kms-local/package.json b/packages/kms-local/package.json index fafbadae9..166e40061 100644 --- a/packages/kms-local/package.json +++ b/packages/kms-local/package.json @@ -10,9 +10,8 @@ "extract-api": "node ../cli/bin/veramo.js dev extract-api" }, "dependencies": { - "@noble/curves": "^1.1.0", + "@noble/curves": "^1.4.2", "@stablelib/nacl": "^1.0.4", - "@stablelib/random": "^1.0.2", "@veramo/core-types": "workspace:^", "@veramo/key-manager": "workspace:^", "@veramo/utils": "workspace:^", diff --git a/packages/kms-local/src/__tests__/kms-local.test.ts b/packages/kms-local/src/__tests__/kms-local.test.ts index aa0302b81..643bd23cd 100644 --- a/packages/kms-local/src/__tests__/kms-local.test.ts +++ b/packages/kms-local/src/__tests__/kms-local.test.ts @@ -8,7 +8,7 @@ import { hexToBytes, stringToUtf8Bytes, } from '../../../utils/src' -import { randomBytes } from '@stablelib/random' +import { randomBytes } from 'ethers' import { convertPublicKeyToX25519, convertSecretKeyToX25519, diff --git a/packages/kms-local/src/secret-box.ts b/packages/kms-local/src/secret-box.ts index ce28f7393..d8ed6de3f 100644 --- a/packages/kms-local/src/secret-box.ts +++ b/packages/kms-local/src/secret-box.ts @@ -1,7 +1,6 @@ import { AbstractSecretBox } from '@veramo/key-manager' import { secretBox, openSecretBox, generateKeyPair } from '@stablelib/nacl' -import { randomBytes } from '@stablelib/random' -import { getBytes, concat, hexlify, toUtf8Bytes, toUtf8String } from 'ethers' +import { getBytes, concat, hexlify, toUtf8Bytes, toUtf8String, randomBytes } from 'ethers' const NONCE_BYTES = 24 diff --git a/packages/utils/package.json b/packages/utils/package.json index 5efb842b8..dd6f8ec9d 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -11,7 +11,7 @@ }, "dependencies": { "@ipld/dag-pb": "^4.0.5", - "@noble/curves": "^1.1.0", + "@noble/curves": "^1.4.2", "@veramo/core-types": "workspace:^", "credential-status": "^3.0.0", "cross-fetch": "^4.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3152de5da..6de59c640 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,8 +31,8 @@ importers: specifier: 0.14.2 version: 0.14.2 '@noble/hashes': - specifier: 1.3.3 - version: 1.3.3 + specifier: 1.4.0 + version: 1.4.0 '@stablelib/ed25519': specifier: 1.0.3 version: 1.0.3 @@ -79,8 +79,8 @@ importers: specifier: 10.1.9 version: 10.1.9(bufferutil@4.0.7)(utf-8-validate@6.0.3) express: - specifier: 4.18.2 - version: 4.18.2 + specifier: 4.19.2 + version: 4.19.2 ganache: specifier: 7.9.2 version: 7.9.2 @@ -119,7 +119,7 @@ importers: version: 23.0.2(typescript@5.3.3) ts-jest: specifier: 29.1.2 - version: 29.1.2(@babel/core@7.23.6)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.6))(jest@29.7.0(@types/node@20.11.19)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.3.3) + version: 29.1.2(@babel/core@7.22.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.22.9))(jest@29.7.0(@types/node@20.11.19)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.3.3) ts-json-schema-generator: specifier: 1.5.0 version: 1.5.0 @@ -465,7 +465,7 @@ importers: version: 4.3.4 did-jwt-vc: specifier: ^4.0.0 - version: 4.0.0 + version: 4.0.4 devDependencies: '@types/debug': specifier: 4.1.8 @@ -589,7 +589,7 @@ importers: optionalDependencies: '@veramo/credential-ld': specifier: ^6.0.0 - version: 6.0.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.7) + version: 6.0.0(bufferutil@4.0.7)(encoding@0.1.13)(expo@49.0.21(@babel/core@7.23.6)(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.7))(react-native@0.73.0(@babel/core@7.23.6)(@babel/preset-env@7.23.6(@babel/core@7.23.6))(bufferutil@4.0.7)(encoding@0.1.13)(react@18.2.0)(utf-8-validate@5.0.7))(utf-8-validate@5.0.7) devDependencies: '@types/debug': specifier: 4.1.8 @@ -686,21 +686,15 @@ importers: packages/did-comm: dependencies: + '@noble/ciphers': + specifier: ^0.5.3 + version: 0.5.3 '@noble/curves': - specifier: ^1.1.0 - version: 1.1.0 - '@stablelib/aes': - specifier: ^2.0.0 - version: 2.0.0 + specifier: ^1.4.2 + version: 1.4.2 '@stablelib/aes-kw': specifier: ^1.0.1 version: 1.0.1 - '@stablelib/gcm': - specifier: ^1.0.2 - version: 1.0.2 - '@stablelib/xchacha20poly1305': - specifier: ^1.0.1 - version: 1.0.1 '@veramo/core-types': specifier: workspace:^ version: link:../core-types @@ -728,9 +722,6 @@ importers: did-resolver: specifier: ^4.1.0 version: 4.1.0 - isomorphic-webcrypto: - specifier: ^2.3.8 - version: 2.3.8(expo@49.0.21(@babel/core@7.23.6)(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.7))(react-native@0.73.0(@babel/core@7.23.6)(@babel/preset-env@7.23.6(@babel/core@7.23.6))(bufferutil@4.0.7)(encoding@0.1.13)(react@18.2.0)(utf-8-validate@5.0.7)) uuid: specifier: ^9.0.0 version: 9.0.0 @@ -830,11 +821,11 @@ importers: specifier: ^1.0.1 version: 1.0.1 '@noble/curves': - specifier: ^1.1.0 - version: 1.1.0 + specifier: ^1.4.2 + version: 1.4.2 '@noble/hashes': - specifier: ^1.3.1 - version: 1.3.1 + specifier: ^1.4.0 + version: 1.4.0 '@sphereon/ion-pow': specifier: ^0.2.0 version: 0.2.0(@sphereon/react-native-argon2@2.0.9(react-native@0.73.0(@babel/core@7.23.6)(@babel/preset-env@7.23.6(@babel/core@7.23.6))(bufferutil@4.0.7)(encoding@0.1.13)(react@18.2.0)(utf-8-validate@5.0.7)))(encoding@0.1.13)(react-native@0.73.0(@babel/core@7.23.6)(@babel/preset-env@7.23.6(@babel/core@7.23.6))(bufferutil@4.0.7)(encoding@0.1.13)(react@18.2.0)(utf-8-validate@5.0.7)) @@ -891,8 +882,8 @@ importers: packages/did-provider-jwk: dependencies: '@noble/curves': - specifier: ^1.1.0 - version: 1.1.0 + specifier: ^1.4.2 + version: 1.4.2 '@veramo/core-types': specifier: workspace:^ version: link:../core-types @@ -1054,7 +1045,7 @@ importers: version: 4.1.8 ethr-did-resolver: specifier: 10.1.9 - version: 10.1.9(bufferutil@4.0.7)(utf-8-validate@6.0.3) + version: 10.1.9(bufferutil@4.0.7)(utf-8-validate@5.0.7) typescript: specifier: 5.3.3 version: 5.3.3 @@ -1065,8 +1056,8 @@ importers: packages/key-manager: dependencies: '@noble/curves': - specifier: ^1.1.0 - version: 1.1.0 + specifier: ^1.4.2 + version: 1.4.2 '@veramo/core-types': specifier: workspace:^ version: link:../core-types @@ -1102,14 +1093,11 @@ importers: packages/kms-local: dependencies: '@noble/curves': - specifier: ^1.1.0 - version: 1.1.0 + specifier: ^1.4.2 + version: 1.4.2 '@stablelib/nacl': specifier: ^1.0.4 version: 1.0.4 - '@stablelib/random': - specifier: ^1.0.2 - version: 1.0.2 '@veramo/core-types': specifier: workspace:^ version: link:../core-types @@ -1617,8 +1605,8 @@ importers: specifier: ^4.0.5 version: 4.0.5 '@noble/curves': - specifier: ^1.1.0 - version: 1.1.0 + specifier: ^1.4.2 + version: 1.4.2 '@veramo/core-types': specifier: workspace:^ version: link:../core-types @@ -1995,7 +1983,6 @@ packages: '@babel/plugin-proposal-class-properties@7.18.6': resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead. peerDependencies: '@babel/core': ^7.0.0-0 @@ -2027,14 +2014,12 @@ packages: '@babel/plugin-proposal-nullish-coalescing-operator@7.18.6': resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead. peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-proposal-numeric-separator@7.18.6': resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==} engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead. peerDependencies: '@babel/core': ^7.0.0-0 @@ -2055,14 +2040,12 @@ packages: '@babel/plugin-proposal-optional-chaining@7.21.0': resolution: {integrity: sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==} engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead. peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-proposal-private-methods@7.18.6': resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead. peerDependencies: '@babel/core': ^7.0.0-0 @@ -2075,14 +2058,12 @@ packages: '@babel/plugin-proposal-private-property-in-object@7.21.11': resolution: {integrity: sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==} engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead. peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-proposal-unicode-property-regex@7.18.6': resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} engines: {node: '>=4'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-unicode-property-regex instead. peerDependencies: '@babel/core': ^7.0.0-0 @@ -3329,7 +3310,6 @@ packages: '@humanwhocodes/config-array@0.11.14': resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} - deprecated: Use @eslint/config-array instead '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} @@ -3337,7 +3317,6 @@ packages: '@humanwhocodes/object-schema@2.0.2': resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} - deprecated: Use @eslint/object-schema instead '@hutson/parse-repository-url@3.0.2': resolution: {integrity: sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==} @@ -3581,7 +3560,6 @@ packages: '@metamask/eth-sig-util@7.0.0': resolution: {integrity: sha512-8KeXZB4SKx3EfNS5ahbjUMegyGvDQYk6Nk3hmM658sXpfAQR5ZlIXBgj+9RF+ZROqsU6EuNVgKt7Fr10re60PQ==} engines: {node: ^16.20 || ^18.16 || >=20} - deprecated: This version generates invalid signatures for messages that include the value "0x" in a "bytes" field. This has been fixed in v6.0.2 and v7.0.1 '@metamask/eth-sig-util@7.0.1': resolution: {integrity: sha512-59GSrMyFH2fPfu7nKeIQdZ150zxXNNhAQIUaFRUW+MGtVA4w/ONbiQobcRBLi+jQProfIyss51G8pfLPcQ0ylg==} @@ -3629,6 +3607,9 @@ packages: '@noble/curves@1.2.0': resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + '@noble/curves@1.4.2': + resolution: {integrity: sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==} + '@noble/ed25519@1.7.1': resolution: {integrity: sha512-Rk4SkJFaXZiznFyC/t77Q0NKS4FL7TLJJsVG2V2oiEq3kJVeTdxysEe/yRWSpnWMe808XRDJ+VFh5pt/FN5plw==} @@ -3647,6 +3628,10 @@ packages: resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} engines: {node: '>= 16'} + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + '@noble/secp256k1@2.0.0': resolution: {integrity: sha512-rUGBd95e2a45rlmFTqQJYEFA4/gdIARFfuTuTqLglz0PZ6AKyzyXsEZZq7UZn8hZsvaBgpCzKKBJizT2cJERXw==} @@ -4260,21 +4245,12 @@ packages: '@stablelib/aes@1.0.1': resolution: {integrity: sha512-bMiezJDeFONDHbMEa+Kic26962+bwkZfsHPAmcqTjLaHCAhEQuK3i1H0POPOkcHCdj75oVRIqFCraCA0cyHPvw==} - '@stablelib/aes@2.0.0': - resolution: {integrity: sha512-/xZT4E1fpmK2ISN4h0BlSbtZorlP6WTA8jG/3PINQYUynJ2fV/DXLDuql2UFm4I3/W4JL/nB7zIdwFhKDy8uFQ==} - '@stablelib/binary@1.0.1': resolution: {integrity: sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==} - '@stablelib/binary@2.0.0': - resolution: {integrity: sha512-dHejKHMtq5OtNwDSMcFx+djhixVAnZ76Rqga3WOOKe6KV3NlnE7JBXlmdLIn04G4FxqhRSEx+zkoO4Izdw10ZA==} - '@stablelib/blockcipher@1.0.1': resolution: {integrity: sha512-4bkpV8HUAv0CgI1fUqkPUEEvv3RXQ3qBkuZaSWhshXGAz1JCpriesgiO9Qs4f0KzBJkCtvcho5n7d/RKvnHbew==} - '@stablelib/blockcipher@2.0.0': - resolution: {integrity: sha512-c0iMTah5a5KxeqVyf6ejpaRkYanODvGaQn8wgvLLAnY23fHZMjhR6ycQVvasW2nIzAmc+faetpRORJqAfaE/yw==} - '@stablelib/bytes@1.0.1': resolution: {integrity: sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ==} @@ -4287,24 +4263,15 @@ packages: '@stablelib/constant-time@1.0.1': resolution: {integrity: sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg==} - '@stablelib/ctr@1.0.2': - resolution: {integrity: sha512-Wq/Zr5QWNiXUu1UMhbeSIWhUm4YOhl01owaZOehxKFOKp6PPuUi9kAUAHv9cE5yQm9PLvIxzhwFco36sRpcOTQ==} - '@stablelib/ed25519@1.0.3': resolution: {integrity: sha512-puIMWaX9QlRsbhxfDc5i+mNPMY+0TmQEskunY1rZEBPi1acBCVQAhnsk/1Hk50DGPtVsZtAWQg4NHGlVaO9Hqg==} - '@stablelib/gcm@1.0.2': - resolution: {integrity: sha512-sQIRPGti1UXm740RTI38Apbl3t0oEEQMsdKN6VbC8a2lFHff6Stg90IqbF1xSrMLmm52gDGwtODhub3rKOMkfQ==} - '@stablelib/hash@1.0.1': resolution: {integrity: sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg==} '@stablelib/int@1.0.1': resolution: {integrity: sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==} - '@stablelib/int@2.0.0': - resolution: {integrity: sha512-EiSYDisTYKk1wuCqoh7wuBySmE0A1isq7TQbsijQ6XFi6nIAozchgAT7Zv2PCl2iY8BTe0URScC4PdYHOe3Yow==} - '@stablelib/keyagreement@1.0.1': resolution: {integrity: sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg==} @@ -4326,9 +4293,6 @@ packages: '@stablelib/wipe@1.0.1': resolution: {integrity: sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==} - '@stablelib/wipe@2.0.0': - resolution: {integrity: sha512-VBMpCJx8py9j9F5DxV5dGmSSO+vkYDnXHXG4alkfpaD08UTfNTqsQoRlUh5obeqBNHiO+3Iv40GxKpM0gfd5xA==} - '@stablelib/x25519@1.0.3': resolution: {integrity: sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw==} @@ -4978,7 +4942,6 @@ packages: abab@2.0.6: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} - deprecated: Use your platform's native atob() and btoa() methods instead abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} @@ -5185,12 +5148,10 @@ packages: are-we-there-yet@2.0.0: resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} engines: {node: '>=10'} - deprecated: This package is no longer supported. are-we-there-yet@3.0.1: resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - deprecated: This package is no longer supported. arg@4.1.0: resolution: {integrity: sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==} @@ -6152,6 +6113,10 @@ packages: resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} engines: {node: '>= 0.6'} + cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + core-js-compat@3.30.2: resolution: {integrity: sha512-nriW1nuJjUgvkEjIot1Spwakz52V9YkYHZAQG6A1eCgC8AA1p0zngrQEP9R0+V6hji5XilWKG1Bd0YRppmGimA==} @@ -6701,12 +6666,10 @@ packages: domexception@2.0.1: resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==} engines: {node: '>=8'} - deprecated: Use your platform's native DOMException instead domexception@4.0.0: resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} engines: {node: '>=12'} - deprecated: Use your platform's native DOMException instead domhandler@4.3.1: resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} @@ -7247,6 +7210,10 @@ packages: resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} engines: {node: '>= 0.10.0'} + express@4.19.2: + resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} + engines: {node: '>= 0.10.0'} + external-editor@3.1.0: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} engines: {node: '>=4'} @@ -7608,12 +7575,10 @@ packages: gauge@3.0.2: resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} engines: {node: '>=10'} - deprecated: This package is no longer supported. gauge@4.0.4: resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - deprecated: This package is no longer supported. gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} @@ -7746,12 +7711,10 @@ packages: glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} - deprecated: Glob versions prior to v9 are no longer supported glob@9.3.5: resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} @@ -8126,7 +8089,6 @@ packages: inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. inherits@2.0.3: resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} @@ -10030,12 +9992,10 @@ packages: npmlog@5.0.1: resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} - deprecated: This package is no longer supported. npmlog@6.0.2: resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - deprecated: This package is no longer supported. nth-check@1.0.2: resolution: {integrity: sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==} @@ -11107,7 +11067,6 @@ packages: puppeteer@22.2.0: resolution: {integrity: sha512-0Ax7zeqqbQL6Zcpo1WAvrqWQAnGsLB4tmQUUwsb5Cfo05XaQ78LWUUjaO4um7qaddKpZfk0vXlGcRVwtedpWfg==} engines: {node: '>=18'} - deprecated: < 22.6.4 is no longer supported hasBin: true pure-rand@6.0.2: @@ -11123,10 +11082,6 @@ packages: q@1.5.1: resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==} engines: {node: '>=0.6.0', teleport: '>=0.2.0'} - deprecated: |- - You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other. - - (For a CapTP with native promises, see @endo/eventual-send and @endo/captp) qrcode-terminal@0.11.0: resolution: {integrity: sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ==} @@ -11283,12 +11238,10 @@ packages: read-package-json@6.0.4: resolution: {integrity: sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - deprecated: This package is no longer supported. Please use @npmcli/package-json instead. read-package-json@7.0.0: resolution: {integrity: sha512-uL4Z10OKV4p6vbdvIXB+OzhInYtIozl/VxUBPgNkBuUi2DeRonnuspmaVAMcrkmfjKGNmRndyQAbE7/AmzGwFg==} engines: {node: ^16.14.0 || >=18.0.0} - deprecated: This package is no longer supported. Please use @npmcli/package-json instead. read-pkg-up@10.0.0: resolution: {integrity: sha512-jgmKiS//w2Zs+YbX039CorlkOp8FIVbSAN8r8GJHDsGlmNPXo+VeHkqAwCiQVTTx5/LwLZTcEw59z3DvcLbr0g==} @@ -11532,7 +11485,6 @@ packages: rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true rimraf@4.4.1: @@ -13068,7 +13020,6 @@ packages: workbox-google-analytics@6.5.4: resolution: {integrity: sha512-8AU1WuaXsD49249Wq0B2zn4a/vvFfHkpcFfqAFHNHwln3jK9QUYmzdkKXGIZl9wyKNP+RRX30vcgcyWMcZ9VAg==} - deprecated: It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained workbox-navigation-preload@6.5.4: resolution: {integrity: sha512-IIwf80eO3cr8h6XSQJF+Hxj26rg2RPFVUmJLUlM0+A2GzB4HFbQyKkrgD5y2d84g2IbJzP4B4j5dPBRzamHrng==} @@ -17678,10 +17629,10 @@ snapshots: '@metamask/utils@8.1.0': dependencies: '@ethereumjs/tx': 4.2.0 - '@noble/hashes': 1.3.3 + '@noble/hashes': 1.4.0 '@types/debug': 4.1.8 debug: 4.3.4 - semver: 7.6.0 + semver: 7.5.4 superstruct: 1.0.3 transitivePeerDependencies: - supports-color @@ -17752,6 +17703,10 @@ snapshots: dependencies: '@noble/hashes': 1.3.2 + '@noble/curves@1.4.2': + dependencies: + '@noble/hashes': 1.4.0 + '@noble/ed25519@1.7.1': {} '@noble/ed25519@2.0.0': {} @@ -17762,6 +17717,8 @@ snapshots: '@noble/hashes@1.3.3': {} + '@noble/hashes@1.4.0': {} + '@noble/secp256k1@2.0.0': {} '@nodelib/fs.scandir@2.1.5': @@ -18687,24 +18644,12 @@ snapshots: '@stablelib/blockcipher': 1.0.1 '@stablelib/wipe': 1.0.1 - '@stablelib/aes@2.0.0': - dependencies: - '@stablelib/binary': 2.0.0 - '@stablelib/blockcipher': 2.0.0 - '@stablelib/wipe': 2.0.0 - '@stablelib/binary@1.0.1': dependencies: '@stablelib/int': 1.0.1 - '@stablelib/binary@2.0.0': - dependencies: - '@stablelib/int': 2.0.0 - '@stablelib/blockcipher@1.0.1': {} - '@stablelib/blockcipher@2.0.0': {} - '@stablelib/bytes@1.0.1': {} '@stablelib/chacha20poly1305@1.0.1': @@ -18723,32 +18668,16 @@ snapshots: '@stablelib/constant-time@1.0.1': {} - '@stablelib/ctr@1.0.2': - dependencies: - '@stablelib/blockcipher': 1.0.1 - '@stablelib/wipe': 1.0.1 - '@stablelib/ed25519@1.0.3': dependencies: '@stablelib/random': 1.0.2 '@stablelib/sha512': 1.0.1 '@stablelib/wipe': 1.0.1 - '@stablelib/gcm@1.0.2': - dependencies: - '@stablelib/aead': 1.0.1 - '@stablelib/binary': 1.0.1 - '@stablelib/blockcipher': 1.0.1 - '@stablelib/constant-time': 1.0.1 - '@stablelib/ctr': 1.0.2 - '@stablelib/wipe': 1.0.1 - '@stablelib/hash@1.0.1': {} '@stablelib/int@1.0.1': {} - '@stablelib/int@2.0.0': {} - '@stablelib/keyagreement@1.0.1': dependencies: '@stablelib/bytes': 1.0.1 @@ -18785,8 +18714,6 @@ snapshots: '@stablelib/wipe@1.0.1': {} - '@stablelib/wipe@2.0.0': {} - '@stablelib/x25519@1.0.3': dependencies: '@stablelib/keyagreement': 1.0.1 @@ -19512,7 +19439,7 @@ snapshots: - supports-color optional: true - '@veramo/credential-ld@6.0.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.7)': + '@veramo/credential-ld@6.0.0(bufferutil@4.0.7)(encoding@0.1.13)(expo@49.0.21(@babel/core@7.23.6)(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.7))(react-native@0.73.0(@babel/core@7.23.6)(@babel/preset-env@7.23.6(@babel/core@7.23.6))(bufferutil@4.0.7)(encoding@0.1.13)(react@18.2.0)(utf-8-validate@5.0.7))(utf-8-validate@5.0.7)': dependencies: '@digitalcredentials/ed25519-signature-2020': 4.0.0(expo-crypto@12.8.1(expo@49.0.21(@babel/core@7.23.6)(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.7)))(expo@49.0.21(@babel/core@7.23.6)(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.7))(msrcrypto@1.5.8)(react-native-securerandom@1.0.1(react-native@0.73.0(@babel/core@7.23.6)(@babel/preset-env@7.23.6(@babel/core@7.23.6))(bufferutil@4.0.7)(encoding@0.1.13)(react@18.2.0)(utf-8-validate@5.0.7)))(react-native@0.73.0(@babel/core@7.23.6)(@babel/preset-env@7.23.6(@babel/core@7.23.6))(bufferutil@4.0.7)(encoding@0.1.13)(react@18.2.0)(utf-8-validate@5.0.7))(web-streams-polyfill@3.2.1) '@digitalcredentials/ed25519-verification-key-2020': 4.0.0 @@ -19545,7 +19472,7 @@ snapshots: '@veramo/utils@6.0.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.7)': dependencies: '@ipld/dag-pb': 4.0.5 - '@noble/curves': 1.2.0 + '@noble/curves': 1.4.2 '@veramo/core-types': 6.0.0 credential-status: 3.0.4 cross-fetch: 4.0.0(encoding@0.1.13) @@ -19908,31 +19835,31 @@ snapshots: array-includes@3.1.6: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.21.1 - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.4 is-string: 1.0.7 array-union@2.1.0: {} array.prototype.flat@1.3.1: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.21.1 es-shim-unscopables: 1.0.0 array.prototype.flatmap@1.3.1: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.21.1 es-shim-unscopables: 1.0.0 array.prototype.reduce@1.0.5: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.21.1 es-array-method-boxes-properly: 1.0.0 @@ -19940,11 +19867,11 @@ snapshots: array.prototype.tosorted@1.1.1: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.21.1 es-shim-unscopables: 1.0.0 - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.4 arrify@1.0.1: {} @@ -20097,20 +20024,6 @@ snapshots: transitivePeerDependencies: - supports-color - babel-jest@29.7.0(@babel/core@7.23.6): - dependencies: - '@babel/core': 7.23.6 - '@jest/transform': 29.7.0 - '@types/babel__core': 7.20.1 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.23.6) - chalk: 4.1.2 - graceful-fs: 4.2.11 - slash: 3.0.0 - transitivePeerDependencies: - - supports-color - optional: true - babel-loader@8.3.0(@babel/core@7.20.12)(webpack@5.75.0): dependencies: '@babel/core': 7.20.12 @@ -20387,13 +20300,6 @@ snapshots: babel-plugin-jest-hoist: 29.6.3 babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.9) - babel-preset-jest@29.6.3(@babel/core@7.23.6): - dependencies: - '@babel/core': 7.23.6 - babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.6) - optional: true - babel-preset-react-app@10.0.1: dependencies: '@babel/core': 7.22.5 @@ -21200,6 +21106,8 @@ snapshots: cookie@0.5.0: {} + cookie@0.6.0: {} + core-js-compat@3.30.2: dependencies: browserslist: 4.22.2 @@ -21313,7 +21221,7 @@ snapshots: credential-status@3.0.0: dependencies: - did-jwt: 8.0.0 + did-jwt: 8.0.4 did-resolver: 4.1.0 credential-status@3.0.4: @@ -21547,7 +21455,7 @@ snapshots: date-fns@2.30.0: dependencies: - '@babel/runtime': 7.23.6 + '@babel/runtime': 7.22.3 date-fns@3.3.1: {} @@ -21588,9 +21496,9 @@ snapshots: deep-equal@2.2.0: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 es-get-iterator: 1.1.2 - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.4 is-arguments: 1.1.1 is-array-buffer: 3.0.1 is-date-object: 1.0.5 @@ -21711,7 +21619,7 @@ snapshots: did-jwt-vc@4.0.0: dependencies: - did-jwt: 8.0.0 + did-jwt: 8.0.4 did-resolver: 4.1.0 did-jwt-vc@4.0.4: @@ -21722,8 +21630,8 @@ snapshots: did-jwt@7.4.2: dependencies: '@noble/ciphers': 0.3.0 - '@noble/curves': 1.2.0 - '@noble/hashes': 1.3.3 + '@noble/curves': 1.4.2 + '@noble/hashes': 1.4.0 '@scure/base': 1.1.3 canonicalize: 2.0.0 did-resolver: 4.1.0 @@ -21734,7 +21642,7 @@ snapshots: dependencies: '@noble/ciphers': 0.4.1 '@noble/curves': 1.2.0 - '@noble/hashes': 1.3.3 + '@noble/hashes': 1.4.0 '@scure/base': 1.1.3 canonicalize: 2.0.0 did-resolver: 4.1.0 @@ -21745,8 +21653,8 @@ snapshots: did-jwt@8.0.4: dependencies: '@noble/ciphers': 0.5.3 - '@noble/curves': 1.2.0 - '@noble/hashes': 1.3.3 + '@noble/curves': 1.4.2 + '@noble/hashes': 1.4.0 '@scure/base': 1.1.3 canonicalize: 2.0.0 did-resolver: 4.1.0 @@ -21964,12 +21872,12 @@ snapshots: es-abstract@1.21.1: dependencies: available-typed-arrays: 1.0.5 - call-bind: 1.0.2 + call-bind: 1.0.7 es-set-tostringtag: 2.0.1 es-to-primitive: 1.2.1 function-bind: 1.1.2 function.prototype.name: 1.1.5 - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.4 get-symbol-description: 1.0.0 globalthis: 1.0.3 gopd: 1.0.1 @@ -22007,8 +21915,8 @@ snapshots: es-get-iterator@1.1.2: dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 is-arguments: 1.1.1 is-map: 2.0.2 @@ -22020,7 +21928,7 @@ snapshots: es-set-tostringtag@2.0.1: dependencies: - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.4 has: 1.0.3 has-tostringtag: 1.0.0 @@ -22347,6 +22255,14 @@ snapshots: - bufferutil - utf-8-validate + ethr-did-resolver@10.1.9(bufferutil@4.0.7)(utf-8-validate@5.0.7): + dependencies: + did-resolver: 4.1.0 + ethers: 6.11.1(bufferutil@4.0.7)(utf-8-validate@5.0.7) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + ethr-did-resolver@10.1.9(bufferutil@4.0.7)(utf-8-validate@6.0.3): dependencies: did-resolver: 4.1.0 @@ -22598,6 +22514,42 @@ snapshots: transitivePeerDependencies: - supports-color + express@4.19.2: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.2 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.6.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.2.0 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.1 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.7 + proxy-addr: 2.0.7 + qs: 6.11.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.18.0 + serve-static: 1.15.0 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + external-editor@3.1.0: dependencies: chardet: 0.7.0 @@ -22975,7 +22927,7 @@ snapshots: function.prototype.name@1.1.5: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.21.1 functions-have-names: 1.2.3 @@ -23073,8 +23025,8 @@ snapshots: get-symbol-description@1.0.0: dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 get-uri@6.0.1: dependencies: @@ -23288,7 +23240,7 @@ snapshots: has-property-descriptors@1.0.0: dependencies: - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.4 has-property-descriptors@1.0.2: dependencies: @@ -23655,7 +23607,7 @@ snapshots: internal-slot@1.0.4: dependencies: - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.4 has: 1.0.3 side-channel: 1.0.4 @@ -23691,8 +23643,8 @@ snapshots: is-array-buffer@3.0.1: dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 is-typed-array: 1.1.12 is-arrayish@0.2.1: {} @@ -23707,7 +23659,7 @@ snapshots: is-boolean-object@1.1.2: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 has-tostringtag: 1.0.0 is-buffer@1.1.6: {} @@ -23804,7 +23756,7 @@ snapshots: is-regex@1.1.4: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 has-tostringtag: 1.0.0 is-regexp@1.0.0: {} @@ -23815,7 +23767,7 @@ snapshots: is-shared-array-buffer@1.0.2: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 is-ssh@1.4.0: dependencies: @@ -23865,12 +23817,12 @@ snapshots: is-weakref@1.0.2: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 is-weakset@2.0.2: dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 is-windows@0.2.0: {} @@ -25413,7 +25365,7 @@ snapshots: cacache: 18.0.2 http-cache-semantics: 4.1.1 is-lambda: 1.0.1 - minipass: 7.0.4 + minipass: 7.0.2 minipass-fetch: 3.0.3 minipass-flush: 1.0.5 minipass-pipeline: 1.2.4 @@ -26070,7 +26022,7 @@ snapshots: nopt: 5.0.0 npmlog: 6.0.2 rimraf: 3.0.2 - semver: 7.6.0 + semver: 7.5.4 tar: 6.2.0 which: 2.0.2 transitivePeerDependencies: @@ -26317,34 +26269,34 @@ snapshots: object-is@1.1.5: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 object-keys@1.1.1: {} object.assign@4.1.4: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 has-symbols: 1.0.3 object-keys: 1.1.1 object.entries@1.1.6: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.21.1 object.fromentries@2.0.6: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.21.1 object.getownpropertydescriptors@2.1.5: dependencies: array.prototype.reduce: 1.0.5 - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.21.1 @@ -26355,7 +26307,7 @@ snapshots: object.values@1.1.6: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.21.1 @@ -27874,7 +27826,7 @@ snapshots: regexp.prototype.flags@1.4.3: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 functions-have-names: 1.2.3 @@ -28068,8 +28020,8 @@ snapshots: safe-regex-test@1.0.0: dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 is-regex: 1.1.4 safe-stable-stringify@2.4.3: {} @@ -28312,8 +28264,8 @@ snapshots: side-channel@1.0.4: dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 object-inspect: 1.12.2 signal-exit@3.0.7: {} @@ -28617,10 +28569,10 @@ snapshots: string.prototype.matchall@4.0.8: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.21.1 - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 internal-slot: 1.0.4 regexp.prototype.flags: 1.4.3 @@ -28628,13 +28580,13 @@ snapshots: string.prototype.trimend@1.0.6: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.21.1 string.prototype.trimstart@1.0.6: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.21.1 @@ -29042,7 +28994,7 @@ snapshots: '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.20.12) - ts-jest@29.1.2(@babel/core@7.23.6)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.6))(jest@29.7.0(@types/node@20.11.19)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.3.3): + ts-jest@29.1.2(@babel/core@7.22.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.22.9))(jest@29.7.0(@types/node@20.11.19)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.3.3): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 @@ -29055,9 +29007,9 @@ snapshots: typescript: 5.3.3 yargs-parser: 21.1.1 optionalDependencies: - '@babel/core': 7.23.6 + '@babel/core': 7.22.9 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.23.6) + babel-jest: 29.7.0(@babel/core@7.22.9) ts-json-schema-generator@1.5.0: dependencies: @@ -29176,7 +29128,7 @@ snapshots: typed-array-length@1.0.4: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 for-each: 0.3.3 is-typed-array: 1.1.12 @@ -29195,7 +29147,7 @@ snapshots: cli-highlight: 2.1.11 date-fns: 2.30.0 debug: 4.3.4 - dotenv: 16.4.5 + dotenv: 16.3.1 glob: 8.1.0 mkdirp: 2.1.6 reflect-metadata: 0.1.13 @@ -29219,7 +29171,7 @@ snapshots: cli-highlight: 2.1.11 date-fns: 2.30.0 debug: 4.3.4 - dotenv: 16.4.5 + dotenv: 16.3.1 glob: 8.1.0 mkdirp: 2.1.6 reflect-metadata: 0.1.13 @@ -29259,7 +29211,7 @@ snapshots: unbox-primitive@1.0.2: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 @@ -29550,7 +29502,7 @@ snapshots: compression: 1.7.4 connect-history-api-fallback: 2.0.0 default-gateway: 6.0.3 - express: 4.18.2 + express: 4.19.2 graceful-fs: 4.2.11 html-entities: 2.3.3 http-proxy-middleware: 2.0.6(@types/express@4.17.21)