Comparing version 7.0.0 to 7.1.0-alpha.1
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ | ||
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */ |
export declare function publicKeyToAddress(publicKey: string, otherAddress: string): string; | ||
//# sourceMappingURL=bip122.d.ts.map |
export declare function publicKeyToAddress(publicKey: string, prefix: string): string; | ||
//# sourceMappingURL=cosmos.d.ts.map |
export declare function verifyBlockchainAccountId(publicKey: string, blockchainAccountId: string | undefined): boolean; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -0,0 +0,0 @@ export { ripemd160 } from '@noble/hashes/ripemd160'; |
@@ -0,0 +0,0 @@ /** |
@@ -1,16 +0,18 @@ | ||
import SimpleSigner from './signers/SimpleSigner'; | ||
import EllipticSigner from './signers/EllipticSigner'; | ||
import NaclSigner from './signers/NaclSigner'; | ||
import { ES256KSigner } from './signers/ES256KSigner'; | ||
import { ES256Signer } from './signers/ES256Signer'; | ||
import { EdDSASigner } from './signers/EdDSASigner'; | ||
import { createJWS, createJWT, decodeJWT, JWTHeader, JWTPayload, JWTVerified, Signer, verifyJWS, verifyJWT } from './JWT'; | ||
import { toEthereumAddress } from './Digest'; | ||
export { JWE, createJWE, decryptJWE, Encrypter, Decrypter, ProtectedHeader, Recipient, RecipientHeader } from './JWE'; | ||
export { ECDH, createX25519ECDH } from './ECDH'; | ||
export { xc20pDirEncrypter, xc20pDirDecrypter, x25519Encrypter, x25519Decrypter, resolveX25519Encrypters, createAuthEncrypter, createAnonEncrypter, createAuthDecrypter, createAnonDecrypter, xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2, xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2, } from './xc20pEncryption'; | ||
export { SimpleSigner, EllipticSigner, NaclSigner, ES256Signer, ES256KSigner, EdDSASigner, verifyJWT, createJWT, decodeJWT, verifyJWS, createJWS, toEthereumAddress, Signer, JWTHeader, JWTPayload, JWTVerified, }; | ||
export { JWTOptions, JWTVerifyOptions } from './JWT'; | ||
export { base64ToBytes, base58ToBytes, hexToBytes } from './util'; | ||
export * from './Errors'; | ||
import SimpleSigner from './signers/SimpleSigner.js'; | ||
import EllipticSigner from './signers/EllipticSigner.js'; | ||
import NaclSigner from './signers/NaclSigner.js'; | ||
import { ES256KSigner } from './signers/ES256KSigner.js'; | ||
import { ES256Signer } from './signers/ES256Signer.js'; | ||
import { EdDSASigner } from './signers/EdDSASigner.js'; | ||
import { createJWS, createJWT, decodeJWT, type JWTHeader, type JWTPayload, type JWTVerified, type Signer, verifyJWS, verifyJWT } from './JWT.js'; | ||
import { toEthereumAddress } from './Digest.js'; | ||
export { type JWE, createJWE, decryptJWE, type Encrypter, type Decrypter, type ProtectedHeader, type Recipient, type RecipientHeader, } from './encryption/JWE.js'; | ||
export { type ECDH, createX25519ECDH } from './encryption/ECDH.js'; | ||
export { x25519Encrypter, x25519Decrypter, resolveX25519Encrypters, createAuthEncrypter, createAnonEncrypter, createAuthDecrypter, createAnonDecrypter, xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2, xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2, } from './encryption/xc20pEncryption.js'; | ||
export { SimpleSigner, EllipticSigner, NaclSigner, ES256Signer, ES256KSigner, EdDSASigner, verifyJWT, createJWT, decodeJWT, verifyJWS, createJWS, toEthereumAddress, type Signer, type JWTHeader, type JWTPayload, type JWTVerified, }; | ||
export { type JWTOptions, type JWTVerifyOptions } from './JWT.js'; | ||
export { base64ToBytes, base58ToBytes, hexToBytes } from './util.js'; | ||
export * from './Errors.js'; | ||
export { xc20pDirDecrypter, xc20pDirEncrypter } from './encryption/xc20pDir.js'; | ||
export * from './encryption/aesEncryption.js'; | ||
//# sourceMappingURL=index.d.ts.map |
import type { DIDResolutionResult, Resolvable, VerificationMethod } from 'did-resolver'; | ||
import { EcdsaSignature } from './util'; | ||
import { EcdsaSignature } from './util.js'; | ||
export type Signer = (data: string | Uint8Array) => Promise<EcdsaSignature | string>; | ||
@@ -4,0 +4,0 @@ export type SignerAlgorithm = (payload: string, signer: Signer) => Promise<string>; |
@@ -1,2 +0,2 @@ | ||
import { SignerAlgorithm } from './JWT'; | ||
import type { SignerAlgorithm } from './JWT.js'; | ||
export declare function ES256SignerAlg(): SignerAlgorithm; | ||
@@ -3,0 +3,0 @@ export declare function ES256KSignerAlg(recoverable?: boolean): SignerAlgorithm; |
@@ -1,2 +0,2 @@ | ||
import type { Signer } from '../JWT'; | ||
import type { Signer } from '../JWT.js'; | ||
/** | ||
@@ -3,0 +3,0 @@ * Creates a configured signer function for signing data using the EdDSA (Ed25519) algorithm. |
@@ -1,2 +0,2 @@ | ||
import { Signer } from '../JWT'; | ||
import type { Signer } from '../JWT.js'; | ||
/** | ||
@@ -3,0 +3,0 @@ * @deprecated Please use ES256KSigner |
@@ -1,2 +0,2 @@ | ||
import { Signer } from '../JWT'; | ||
import { Signer } from '../JWT.js'; | ||
/** | ||
@@ -3,0 +3,0 @@ * Creates a configured signer function for signing data using the ES256K (secp256k1 + sha256) algorithm. |
@@ -1,2 +0,2 @@ | ||
import { Signer } from '../JWT'; | ||
import { Signer } from '../JWT.js'; | ||
/** | ||
@@ -3,0 +3,0 @@ * Creates a configured signer function for signing data using the ES256 (secp256r1 + sha256) algorithm. |
@@ -1,2 +0,2 @@ | ||
import { Signer } from '../JWT'; | ||
import type { Signer } from '../JWT.js'; | ||
/** | ||
@@ -7,3 +7,4 @@ * @deprecated Please use EdDSASigner | ||
* | ||
* The signing function itself takes the data as a `string` or `Uint8Array` parameter and returns a `base64Url`-encoded signature. | ||
* The signing function itself takes the data as a `string` or `Uint8Array` parameter and returns a | ||
* `base64Url`-encoded signature. | ||
* | ||
@@ -10,0 +11,0 @@ * @example |
@@ -1,2 +0,2 @@ | ||
import { Signer } from '../JWT'; | ||
import type { Signer } from '../JWT.js'; | ||
/** | ||
@@ -3,0 +3,0 @@ * @deprecated Please use ES256KSigner |
@@ -8,3 +8,3 @@ import { bases } from 'multiformats/basics'; | ||
s: string; | ||
recoveryParam?: number | null; | ||
recoveryParam?: number; | ||
} | ||
@@ -37,3 +37,3 @@ /** | ||
}; | ||
export declare function toSealed(ciphertext: string, tag: string): Uint8Array; | ||
export declare function toSealed(ciphertext: string, tag?: string): Uint8Array; | ||
export declare function leftpad(data: string, size?: number): string; | ||
@@ -40,0 +40,0 @@ /** |
import type { VerificationMethod } from 'did-resolver'; | ||
import { EcdsaSignature, ECDSASignature } from './util'; | ||
import { EcdsaSignature, ECDSASignature } from './util.js'; | ||
export declare function toSignatureObject(signature: string, recoverable?: boolean): EcdsaSignature; | ||
export declare function toSignatureObject2(signature: string, recoverable?: boolean): ECDSASignature; | ||
export declare function extractPublicKeyBytes(pk: VerificationMethod): Uint8Array; | ||
export declare function verifyES256(data: string, signature: string, authenticators: VerificationMethod[]): VerificationMethod; | ||
@@ -12,5 +13,5 @@ export declare function verifyES256K(data: string, signature: string, authenticators: VerificationMethod[]): VerificationMethod; | ||
declare namespace VerifierAlgorithm { | ||
var toSignatureObject: typeof import("./VerifierAlgorithm").toSignatureObject; | ||
var toSignatureObject: typeof import("./VerifierAlgorithm.js").toSignatureObject; | ||
} | ||
export default VerifierAlgorithm; | ||
//# sourceMappingURL=VerifierAlgorithm.d.ts.map |
{ | ||
"name": "did-jwt", | ||
"version": "7.0.0", | ||
"version": "7.1.0-alpha.1", | ||
"description": "Library for Signing and Verifying JWTs that use DIDs as issuers and JWEs that use DIDs as recipients", | ||
"type": "module", | ||
"source": "src/index.ts", | ||
"main": "./lib/index.cjs", | ||
"module": "./lib/index.module.js", | ||
"unpkg": "./lib/index.umd.js", | ||
"module": "./lib/index.js", | ||
"types": "./lib/index.d.ts", | ||
"umd:main": "./lib/index.umd.js", | ||
"files": [ | ||
@@ -21,10 +18,10 @@ "lib", | ||
"types": "./lib/index.d.ts", | ||
"require": "./lib/index.cjs", | ||
"import": "./lib/index.module.js" | ||
"import": "./lib/index.js" | ||
} | ||
}, | ||
"browser": "./dist/did-jwt.js", | ||
"scripts": { | ||
"test": "NODE_OPTIONS=--experimental-vm-modules jest", | ||
"test:ci": "jest --coverage", | ||
"build:js": "microbundle --compress=false", | ||
"test": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" jest", | ||
"test:ci": "yarn test --coverage", | ||
"build:js": "tsc", | ||
"build:browser": "webpack --config webpack.config.cjs", | ||
@@ -41,3 +38,3 @@ "build": "yarn build:js && yarn build:browser", | ||
"Mircea Nistor <mircea.nistor@mesh.xyz>", | ||
"Oliver Terbu <oliver.terbu@mesh.xyz>", | ||
"Oliver Terbu", | ||
"Joel Thorstensson <oed@3box.io>" | ||
@@ -50,39 +47,25 @@ ], | ||
"license": "Apache-2.0", | ||
"jest": { | ||
"clearMocks": true, | ||
"collectCoverageFrom": [ | ||
"src/**/*.{ts,tsx}", | ||
"!src/**/*.d.ts", | ||
"!**/node_modules/**", | ||
"!src/**/index.ts" | ||
], | ||
"testEnvironment": "node", | ||
"extensionsToTreatAsEsm": [ | ||
".ts" | ||
], | ||
"testMatch": [ | ||
"**/__tests__/**/*.test.[jt]s" | ||
] | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "7.21.3", | ||
"@babel/preset-env": "7.20.2", | ||
"@babel/preset-typescript": "7.21.0", | ||
"@babel/core": "7.21.4", | ||
"@babel/preset-env": "7.21.4", | ||
"@babel/preset-typescript": "7.21.4", | ||
"@ethersproject/address": "5.7.0", | ||
"@semantic-release/changelog": "6.0.3", | ||
"@semantic-release/git": "10.0.1", | ||
"@types/jest": "28.1.8", | ||
"@types/jsonwebtoken": "^8.5.9", | ||
"@types/jwk-to-pem": "^2.0.1", | ||
"@typescript-eslint/eslint-plugin": "5.56.0", | ||
"@typescript-eslint/parser": "5.56.0", | ||
"@types/jest": "29.5.0", | ||
"@types/jsonwebtoken": "9.0.1", | ||
"@types/jwk-to-pem": "2.0.1", | ||
"@types/node": "18.15.11", | ||
"@typescript-eslint/eslint-plugin": "5.57.0", | ||
"@typescript-eslint/parser": "5.57.0", | ||
"codecov": "3.8.3", | ||
"eslint": "8.36.0", | ||
"cross-env": "7.0.3", | ||
"eslint": "8.37.0", | ||
"eslint-config-prettier": "8.8.0", | ||
"eslint-plugin-jest": "26.9.0", | ||
"eslint-plugin-jest": "27.2.1", | ||
"eslint-plugin-prettier": "4.2.1", | ||
"jest": "28.1.3", | ||
"jsontokens": "3.1.1", | ||
"jsonwebtoken": "^8.5.1", | ||
"jwk-to-pem": "^2.0.5", | ||
"jest": "29.5.0", | ||
"jsontokens": "4.0.1", | ||
"jsonwebtoken": "9.0.0", | ||
"jwk-to-pem": "2.0.5", | ||
"microbundle": "0.15.1", | ||
@@ -92,7 +75,9 @@ "mockdate": "3.0.5", | ||
"regenerator-runtime": "0.13.11", | ||
"semantic-release": "19.0.5", | ||
"semantic-release": "21.0.1", | ||
"ts-jest": "29.1.0", | ||
"ts-node": "10.9.1", | ||
"tweetnacl": "1.0.3", | ||
"typescript": "4.9.5", | ||
"webpack": "5.76.3", | ||
"webpack-cli": "4.10.0" | ||
"typescript": "5.0.3", | ||
"webpack": "5.77.0", | ||
"webpack-cli": "5.0.1" | ||
}, | ||
@@ -102,8 +87,11 @@ "dependencies": { | ||
"@noble/hashes": "^1.3.0", | ||
"@stablelib/aes": "^1.0.1", | ||
"@stablelib/aes-kw": "^1.0.1", | ||
"@stablelib/gcm": "^1.0.2", | ||
"@stablelib/xchacha20poly1305": "^1.0.1", | ||
"bech32": "^2.0.0", | ||
"canonicalize": "^2.0.0", | ||
"did-resolver": "^4.0.0", | ||
"multiformats": "^9.6.5", | ||
"uint8arrays": "^3.0.0" | ||
"did-resolver": "^4.1.0", | ||
"multiformats": "^11.0.2", | ||
"uint8arrays": "^4.0.3" | ||
}, | ||
@@ -110,0 +98,0 @@ "eslintIgnore": [ |
@@ -1,3 +0,3 @@ | ||
import VerifierAlgorithm from '../VerifierAlgorithm' | ||
import { verifyJWT } from '../JWT' | ||
import VerifierAlgorithm from '../VerifierAlgorithm.js' | ||
import { verifyJWT } from '../JWT.js' | ||
@@ -19,3 +19,3 @@ const edKey58 = { | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
return expect(verifier(parts[1], parts[2], [edKey58])).toEqual(edKey58) | ||
return expect(verifier(parts!![1], parts!![2], [edKey58])).toEqual(edKey58) | ||
}) | ||
@@ -22,0 +22,0 @@ |
@@ -1,4 +0,6 @@ | ||
import { keccak, ripemd160, sha256, toEthereumAddress } from '../Digest' | ||
import * as u8a from 'uint8arrays' | ||
import { keccak, ripemd160, sha256, toEthereumAddress } from '../Digest.js' | ||
import { toString, fromString } from 'uint8arrays' | ||
const u8a = { toString, fromString } | ||
// https://www.di-mgt.com.au/sha_testvectors.html | ||
@@ -5,0 +7,0 @@ describe('sha256', () => { |
@@ -1,3 +0,3 @@ | ||
import { base64ToBytes, base58ToBytes, hexToBytes } from '../util' | ||
import { EdDSASigner } from '../signers/EdDSASigner' | ||
import { base64ToBytes, base58ToBytes, hexToBytes } from '../util.js' | ||
import { EdDSASigner } from '../signers/EdDSASigner.js' | ||
@@ -4,0 +4,0 @@ describe('EdDSASigner', () => { |
@@ -1,2 +0,2 @@ | ||
import EllipticSigner from '../signers/EllipticSigner' | ||
import EllipticSigner from '../signers/EllipticSigner.js' | ||
@@ -3,0 +3,0 @@ const privateKey = '278a5de700e29faae8e40e366ec5012b5ec63d36ec77e8a2417154cc1d25383f' |
@@ -1,3 +0,3 @@ | ||
import { hexToBytes, base58ToBytes, base64ToBytes } from '../util' | ||
import { ES256KSigner } from '../signers/ES256KSigner' | ||
import { hexToBytes, base58ToBytes, base64ToBytes } from '../util.js' | ||
import { ES256KSigner } from '../signers/ES256KSigner.js' | ||
@@ -4,0 +4,0 @@ describe('Secp256k1 Signer', () => { |
@@ -1,3 +0,3 @@ | ||
import { hexToBytes, base58ToBytes, base64ToBytes } from '../util' | ||
import { ES256Signer } from '../signers/ES256Signer' | ||
import { hexToBytes, base58ToBytes, base64ToBytes } from '../util.js' | ||
import { ES256Signer } from '../signers/ES256Signer.js' | ||
@@ -4,0 +4,0 @@ describe('Secp256r1 Signer', () => { |
/* eslint-disable */ | ||
// it.skip('not a test', () => {}) | ||
export default { | ||
export const vectors = { | ||
dir: { | ||
@@ -105,3 +105,6 @@ pass: [ | ||
recipients: [ | ||
{ header: { alg: 'ECDH-ES+XC20PKW' }, encrypted_key: '4Q3gQ8U0FN7F19HDx2Y-d3XhSrWjfUJxAfTHDE2k8Qo' }, | ||
{ | ||
header: { alg: 'ECDH-ES+XC20PKW' }, | ||
encrypted_key: '4Q3gQ8U0FN7F19HDx2Y-d3XhSrWjfUJxAfTHDE2k8Qo', | ||
}, | ||
], | ||
@@ -121,3 +124,6 @@ iv: 'VI7kbLVnMe39GkVXnkol5nmFJRHZjDCI', | ||
recipients: [ | ||
{ header: { alg: 'ECDH-ES+XC20PKW' }, encrypted_key: '7-vOqMDMStkVrm4GVWueZNgSGOaBDyni5Eg1efivsto' }, | ||
{ | ||
header: { alg: 'ECDH-ES+XC20PKW' }, | ||
encrypted_key: '7-vOqMDMStkVrm4GVWueZNgSGOaBDyni5Eg1efivsto', | ||
}, | ||
], | ||
@@ -137,3 +143,6 @@ iv: 'ahAxCFOYSK26KGoYztDPYv5HJjPPSXVs', | ||
recipients: [ | ||
{ header: { alg: 'ECDH-ES+XC20PKW' }, encrypted_key: 'l27ClhqCGF_aVxg0j3oGgJ8IqUlUyDIbeAzzQwe-yIc' }, | ||
{ | ||
header: { alg: 'ECDH-ES+XC20PKW' }, | ||
encrypted_key: 'l27ClhqCGF_aVxg0j3oGgJ8IqUlUyDIbeAzzQwe-yIc', | ||
}, | ||
], | ||
@@ -350,3 +359,6 @@ iv: '4sTe21wDiF6QcXeaMRUpnhwqQ3T17sW0', | ||
recipients: [ | ||
{ header: { alg: 'ECDH-ES+XC20PKW' }, encrypted_key: 'ufEVimxuEjOSL3xxosddCnxAycHyEM6YvZnpnBNcFdU' }, | ||
{ | ||
header: { alg: 'ECDH-ES+XC20PKW' }, | ||
encrypted_key: 'ufEVimxuEjOSL3xxosddCnxAycHyEM6YvZnpnBNcFdU', | ||
}, | ||
], | ||
@@ -366,3 +378,6 @@ iv: 'KH-z-rAni0OXCwZdEsBdr70Nb9ynB-L0', | ||
recipients: [ | ||
{ header: { alg: 'ECDH-ES+XC20PKW' }, encrypted_key: 'mV0ROPhCkbkl6kpqxrJHwtUmp1ag1fX2_Cm1EBVMkH8' }, | ||
{ | ||
header: { alg: 'ECDH-ES+XC20PKW' }, | ||
encrypted_key: 'mV0ROPhCkbkl6kpqxrJHwtUmp1ag1fX2_Cm1EBVMkH8', | ||
}, | ||
], | ||
@@ -382,3 +397,6 @@ iv: 'KvOPK3HF_zQ76CrrGsb6Fsf-uz5f2wpw', | ||
recipients: [ | ||
{ header: { alg: 'ECDH-ES+XC20PKW' }, encrypted_key: 'H6hUldKGflwKIKwgucoJBTEVemkOEJaM5BUH-M0cLQk' }, | ||
{ | ||
header: { alg: 'ECDH-ES+XC20PKW' }, | ||
encrypted_key: 'H6hUldKGflwKIKwgucoJBTEVemkOEJaM5BUH-M0cLQk', | ||
}, | ||
], | ||
@@ -993,2 +1011,29 @@ iv: 'd-qf4TZIGY_CRr5uhqjN0H11-qdppk8l', | ||
}, | ||
'XC20P with X25519-ECDH-ES+A256KW': { | ||
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: { | ||
ciphertext: | ||
'KWS7gJU7TbyJlcT9dPkCw-ohNigGaHSukR9MUqFM0THbCTCNkY-g5tahBFyszlKIKXs7qOtqzYyWbPou2q77XlAeYs93IhF6NvaIjyNqYklvj-OtJt9W2Pj5CLOMdsR0C30wchGoXd6wEQZY4ttbzpxYznqPmJ0b9KW6ZP-l4_DSRYe9B-1oSWMNmqMPwluKbtguC-riy356Xbu2C9ShfWmpmjz1HyJWQhZfczuwkWWlE63g26FMskIZZd_jGpEhPFHKUXCFwbuiw_Iy3R0BIzmXXdK_w7PZMMPbaxssl2UeJmLQgCAP8j8TukxV96EKa6rGgULvlo7qibjJqsS5j03bnbxkuxwbfyu3OxwgVzFWlyHbUH6p', | ||
protected: | ||
'eyJlcGsiOnsia3R5IjoiT0tQIiwiY3J2IjoiWDI1NTE5IiwieCI6IkpIanNtSVJaQWFCMHpSR193TlhMVjJyUGdnRjAwaGRIYlc1cmo4ZzBJMjQifSwiYXB2IjoiTmNzdUFuclJmUEs2OUEtcmtaMEw5WFdVRzRqTXZOQzNaZzc0QlB6NTNQQSIsInR5cCI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tZW5jcnlwdGVkK2pzb24iLCJlbmMiOiJYQzIwUCIsImFsZyI6IkVDREgtRVMrQTI1NktXIn0', | ||
recipients: [ | ||
{ | ||
encrypted_key: '3n1olyBR3nY7ZGAprOx-b7wYAKza6cvOYjNwVg3miTnbLwPP_FmE1A', | ||
header: { | ||
kid: 'did:example:bob#key-x25519-1', | ||
}, | ||
}, | ||
], | ||
tag: '6ylC_iAs4JvDQzXeY6MuYQ', | ||
iv: 'ESpmcyGiZpRjc5urDela21TOOTW8Wqd1', | ||
}, | ||
}, | ||
], | ||
fail: [], | ||
invalid: [], | ||
}, | ||
} |
@@ -1,20 +0,31 @@ | ||
import { decryptJWE, createJWE, Encrypter, JWE } from '../JWE' | ||
import vectors from './jwe-vectors' | ||
import { randomBytes } from '@noble/hashes/utils' | ||
import { base64ToBytes, decodeBase64url, encodeBase64url, generateKeyPairFromSeed } from '../util.js' | ||
import { createJWE, Decrypter, decryptJWE, Encrypter, JWE } from '../encryption/JWE.js' | ||
import { vectors } from './jwe-vectors.js' | ||
import { | ||
xc20pDirEncrypter, | ||
xc20pDirDecrypter, | ||
createAnonDecrypter, | ||
createAnonEncrypter, | ||
createAuthDecrypter, | ||
createAuthEncrypter, | ||
x25519Decrypter, | ||
x25519Encrypter, | ||
x25519Decrypter, | ||
xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2, | ||
xc20pAuthEncrypterEcdh1PuV3x25519WithXc20PkwV2, | ||
createAnonEncrypter, | ||
createAnonDecrypter, | ||
createAuthEncrypter, | ||
createAuthDecrypter, | ||
} from '../xc20pEncryption' | ||
import { decodeBase64url, encodeBase64url, generateKeyPairFromSeed } from '../util' | ||
import * as u8a from 'uint8arrays' | ||
import { randomBytes } from '@noble/hashes/utils' | ||
import { createX25519ECDH, ECDH } from '../ECDH' | ||
} from '../encryption/xc20pEncryption.js' | ||
import { createX25519ECDH, ECDH } from '../encryption/ECDH.js' | ||
import { | ||
xc20pAnonDecrypterX25519WithA256KW, | ||
xc20pAnonEncrypterX25519WithA256KW, | ||
xc20pAuthDecrypterEcdh1PuV3x25519WithA256KW, | ||
xc20pAuthEncrypterEcdh1PuV3x25519WithA256KW, | ||
a256gcmAuthEncrypterEcdh1PuV3x25519WithA256KW, | ||
a256gcmAuthDecrypterEcdh1PuV3x25519WithA256KW, | ||
a256gcmAnonEncrypterX25519WithA256KW, | ||
a256gcmAnonDecrypterX25519WithA256KW, | ||
} from '../encryption/aesEncryption.js' | ||
import { xc20pDirDecrypter, xc20pDirEncrypter } from '../encryption/xc20pDir.js' | ||
import { toString, fromString } from 'uint8arrays' | ||
const u8a = { toString, fromString } | ||
describe('JWE', () => { | ||
@@ -100,2 +111,15 @@ describe('decryptJWE', () => { | ||
}) | ||
describe('XC20P with X25519-ECDH-ES+A256KW', () => { | ||
test.each(vectors['XC20P with X25519-ECDH-ES+A256KW'].pass)( | ||
'decrypts valid jwe', | ||
async ({ key, cleartext, jwe }) => { | ||
expect.assertions(1) | ||
const receiverSecret = base64ToBytes(key) | ||
const decrypter = xc20pAnonDecrypterX25519WithA256KW(receiverSecret) | ||
const cleartextU8a = await decryptJWE(jwe as any, decrypter) | ||
expect(u8a.toString(cleartextU8a)).toEqual(cleartext) | ||
} | ||
) | ||
}) | ||
}) | ||
@@ -105,3 +129,3 @@ | ||
describe('Direct encryption', () => { | ||
let key, cleartext, encrypter, decrypter | ||
let key: Uint8Array, cleartext: Uint8Array, encrypter: Encrypter, decrypter: Decrypter | ||
@@ -135,3 +159,3 @@ beforeEach(() => { | ||
const jwe = await createJWE(cleartext, [encrypter], { more: 'protected' }, aad) | ||
expect(u8a.fromString(jwe.aad, 'base64url')).toEqual(aad) | ||
expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) | ||
expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ alg: 'dir', enc: 'XC20P', more: 'protected' }) | ||
@@ -144,5 +168,5 @@ expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) | ||
describe('X25519 key exchange encryption', () => { | ||
describe('One recipient', () => { | ||
let pubkey, secretkey, cleartext, encrypter, decrypter | ||
describe('ECDH-ES (X25519) key exchange encryption', () => { | ||
describe('One recipient XC20PKW', () => { | ||
let pubkey, secretkey, cleartext: Uint8Array, encrypter: Encrypter, decrypter: Decrypter | ||
@@ -177,3 +201,3 @@ beforeEach(() => { | ||
const jwe = await createJWE(cleartext, [encrypter], { more: 'protected' }, aad) | ||
expect(u8a.fromString(jwe.aad, 'base64url')).toEqual(aad) | ||
expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) | ||
expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P', more: 'protected' }) | ||
@@ -186,7 +210,46 @@ expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) | ||
describe('Multiple recipients', () => { | ||
let pubkey1, secretkey1, pubkey2, secretkey2, cleartext | ||
let encrypter1, decrypter1, encrypter2, decrypter2 | ||
describe('One recipient A256KW', () => { | ||
let pubkey, secretkey, cleartext: Uint8Array, encrypter: Encrypter, decrypter: Decrypter | ||
beforeEach(() => { | ||
secretkey = randomBytes(32) | ||
pubkey = generateKeyPairFromSeed(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 XC20PKW', () => { | ||
let pubkey1, secretkey1, pubkey2, secretkey2, cleartext: Uint8Array | ||
let encrypter1: Encrypter, decrypter1: Decrypter, encrypter2: Encrypter, decrypter2: Decrypter | ||
beforeEach(() => { | ||
secretkey1 = randomBytes(32) | ||
@@ -225,3 +288,3 @@ pubkey1 = generateKeyPairFromSeed(secretkey1).publicKey | ||
const jwe = await createJWE(cleartext, [encrypter1, encrypter2], { more: 'protected' }, aad) | ||
expect(u8a.fromString(jwe.aad, 'base64url')).toEqual(aad) | ||
expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) | ||
expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P', more: 'protected' }) | ||
@@ -242,2 +305,57 @@ expect(await decryptJWE(jwe, decrypter1)).toEqual(cleartext) | ||
}) | ||
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 = generateKeyPairFromSeed(secretkey1).publicKey | ||
secretkey2 = randomBytes(32) | ||
pubkey2 = generateKeyPairFromSeed(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') | ||
}) | ||
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') | ||
}) | ||
}) | ||
}) | ||
@@ -248,3 +366,3 @@ }) | ||
describe('One recipient', () => { | ||
let cleartext, recipientKey, senderKey, decrypter | ||
let cleartext: Uint8Array, recipientKey: any, senderKey: any, decrypter: Decrypter | ||
@@ -276,5 +394,5 @@ beforeEach(() => { | ||
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(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) | ||
@@ -294,5 +412,5 @@ }) | ||
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(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) | ||
@@ -314,5 +432,5 @@ }) | ||
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(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) | ||
@@ -336,3 +454,3 @@ }) | ||
const jwe = await createJWE(cleartext, [encrypter], { more: 'protected' }, aad) | ||
expect(u8a.fromString(jwe.aad, 'base64url')).toEqual(aad) | ||
expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) | ||
expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P', more: 'protected' }) | ||
@@ -387,4 +505,4 @@ expect(await decryptJWE(jwe, decrypter)).toEqual(cleartext) | ||
describe('Multiple recipients', () => { | ||
let cleartext, senderkey | ||
const recipients = [] | ||
let cleartext: any, senderkey: any | ||
const recipients: any[] = [] | ||
@@ -459,3 +577,3 @@ beforeEach(() => { | ||
) | ||
expect(u8a.fromString(jwe.aad, 'base64url')).toEqual(aad) | ||
expect(u8a.fromString(jwe.aad!!, 'base64url')).toEqual(aad) | ||
expect(JSON.parse(decodeBase64url(jwe.protected))).toEqual({ enc: 'XC20P', more: 'protected' }) | ||
@@ -477,2 +595,600 @@ expect(await decryptJWE(jwe, recipients[0].decrypter)).toEqual(cleartext) | ||
}) | ||
describe('ECDH-1PU+A256KW (X25519), Key Wrapping Mode with XC20P content encryption', () => { | ||
describe('One recipient', () => { | ||
let cleartext: Uint8Array, recipientKey: any, senderKey: any, decrypter: Decrypter | ||
beforeEach(() => { | ||
recipientKey = generateKeyPairFromSeed(randomBytes(32)) | ||
senderKey = generateKeyPairFromSeed(randomBytes(32)) | ||
cleartext = u8a.fromString('my secret message') | ||
decrypter = xc20pAuthDecrypterEcdh1PuV3x25519WithA256KW(recipientKey.secretKey, senderKey.publicKey) | ||
}) | ||
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]) | ||
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 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) | ||
}) | ||
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') | ||
}) | ||
describe('using remote ECDH', () => { | ||
const message = 'hello world' | ||
const receiverPair = generateKeyPairFromSeed(randomBytes(32)) | ||
const receiverRemoteECDH = createX25519ECDH(receiverPair.secretKey) | ||
const senderPair = generateKeyPairFromSeed(randomBytes(32)) | ||
const senderRemoteECDH: ECDH = createX25519ECDH(senderPair.secretKey) | ||
it('creates anon JWE with remote ECDH', async () => { | ||
const encrypter = 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 = generateKeyPairFromSeed(randomBytes(32)) | ||
cleartext = u8a.fromString('my secret message') | ||
recipients[0] = { kid: 'did:example:receiver1#key-1', recipientkey: generateKeyPairFromSeed(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: generateKeyPairFromSeed(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: '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, | ||
}) | ||
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) | ||
}) | ||
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') | ||
}) | ||
}) | ||
}) | ||
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 = generateKeyPairFromSeed(randomBytes(32)) | ||
senderKey = generateKeyPairFromSeed(randomBytes(32)) | ||
cleartext = u8a.fromString('my secret message') | ||
decrypter = a256gcmAnonDecrypterX25519WithA256KW(recipientKey.secretKey) | ||
}) | ||
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 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 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 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 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 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') | ||
}) | ||
describe('using remote ECDH', () => { | ||
const message = 'hello world' | ||
const receiverPair = generateKeyPairFromSeed(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[] = [] | ||
beforeEach(() => { | ||
senderkey = generateKeyPairFromSeed(randomBytes(32)) | ||
cleartext = u8a.fromString('my secret message') | ||
recipients[0] = { kid: 'did:example:receiver1#key-1', recipientkey: generateKeyPairFromSeed(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: generateKeyPairFromSeed(randomBytes(32)) } | ||
recipients[1] = { | ||
...recipients[1], | ||
...{ | ||
encrypter: a256gcmAnonEncrypterX25519WithA256KW(recipients[1].recipientkey.publicKey, recipients[1].kid), | ||
decrypter: a256gcmAnonDecrypterX25519WithA256KW(recipients[1].recipientkey.secretKey), | ||
}, | ||
} | ||
}) | ||
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 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) | ||
}) | ||
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('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 = generateKeyPairFromSeed(randomBytes(32)) | ||
senderKey = generateKeyPairFromSeed(randomBytes(32)) | ||
cleartext = u8a.fromString('my secret message') | ||
decrypter = a256gcmAuthDecrypterEcdh1PuV3x25519WithA256KW(recipientKey.secretKey, senderKey.publicKey) | ||
}) | ||
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('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 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 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 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 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') | ||
}) | ||
describe('using remote ECDH', () => { | ||
const message = 'hello world' | ||
const receiverPair = generateKeyPairFromSeed(randomBytes(32)) | ||
const receiverRemoteECDH = createX25519ECDH(receiverPair.secretKey) | ||
const senderPair = generateKeyPairFromSeed(randomBytes(32)) | ||
const senderRemoteECDH: ECDH = createX25519ECDH(senderPair.secretKey) | ||
it('creates 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('Multiple recipients', () => { | ||
let cleartext: any, senderkey: any | ||
const recipients: any[] = [] | ||
beforeEach(() => { | ||
senderkey = generateKeyPairFromSeed(randomBytes(32)) | ||
cleartext = u8a.fromString('my secret message') | ||
recipients[0] = { kid: 'did:example:receiver1#key-1', recipientkey: generateKeyPairFromSeed(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: generateKeyPairFromSeed(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 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 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) | ||
}) | ||
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('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') | ||
}) | ||
}) | ||
}) | ||
}) |
import { jest, describe, expect, it } from '@jest/globals' | ||
import { hexToBytes, base64ToBytes } from '../util' | ||
import { VerificationMethod } from 'did-resolver' | ||
import { base64ToBytes, bytesToBase64url, decodeBase64url, hexToBytes } from '../util.js' | ||
import type { Resolvable, VerificationMethod } from 'did-resolver' | ||
import { TokenVerifier } from 'jsontokens' | ||
import MockDate from 'mockdate' | ||
import { fromString } from 'uint8arrays/from-string' | ||
import { getAddress } from '@ethersproject/address' | ||
@@ -18,12 +17,12 @@ import { | ||
verifyJWT, | ||
} from '../JWT' | ||
import { EdDSASigner } from '../signers/EdDSASigner' | ||
import { ES256KSigner } from '../signers/ES256KSigner' | ||
import { bytesToBase64url, decodeBase64url } from '../util' | ||
} from '../JWT.js' | ||
import { EdDSASigner } from '../signers/EdDSASigner.js' | ||
import { ES256KSigner } from '../signers/ES256KSigner.js' | ||
// add declarations for ES256 Tests | ||
import { ES256Signer } from '../signers/ES256Signer' | ||
// @ts-ignore | ||
import jwt from 'jsonwebtoken' | ||
import * as u8a from 'uint8arrays' | ||
import * as jwkToPem from 'jwk-to-pem' | ||
// @ts-ignore | ||
import jwkToPem from 'jwk-to-pem' | ||
@@ -125,3 +124,2 @@ const NOW = 1485321133 | ||
describe('ES256', () => { | ||
const alg = 'ES256' | ||
const privateKey = '736f625c9dda78a94bb16840c82779bb7bc18014b8ede52f0f03429902fc4ba8' | ||
@@ -141,9 +139,5 @@ const publicKey_x = '14c58e581c7656ba153195669fe4ce53ff78dd5ede60a4039771a90c58cb41de' | ||
interface privateJsonWebKey extends JsonWebKey { | ||
d?: string | ||
} | ||
// verifyTokenFormAndValidity | ||
function verifyTokenFormAndValidity(token: string, pemPublic: string): boolean { | ||
let result = null | ||
let result | ||
try { | ||
@@ -172,6 +166,6 @@ jwt.verify(token, pemPublic) | ||
} | ||
const publicPointUint8_x = u8a.fromString(publicPointHex_x, 'hex') | ||
const publicPointBase64URL_x = u8a.toString(publicPointUint8_x, 'base64url') | ||
const publicPointUint8_y = u8a.fromString(publicPointHex_y, 'hex') | ||
const publicPointBase64URL_y = u8a.toString(publicPointUint8_y, 'base64url') | ||
const publicPointUint8_x = hexToBytes(publicPointHex_x) | ||
const publicPointBase64URL_x = bytesToBase64url(publicPointUint8_x) | ||
const publicPointUint8_y = hexToBytes(publicPointHex_y) | ||
const publicPointBase64URL_y = bytesToBase64url(publicPointUint8_y) | ||
return { | ||
@@ -185,20 +179,6 @@ kty: kty_value, | ||
// input private key in hex, and export pem | ||
function privateToJWK(privatePointHex: string, kty_value: string, crv_value: string): privateJsonWebKey { | ||
if (privatePointHex.length % 2 != 0) { | ||
privatePointHex = '0' + privatePointHex | ||
} | ||
const privatePointUint8 = u8a.fromString(privatePointHex, 'hex') | ||
const privatePointBase64URL = u8a.toString(privatePointUint8, 'base64url') | ||
return { | ||
kty: kty_value, | ||
crv: crv_value, | ||
d: privatePointBase64URL, | ||
} | ||
} | ||
it('creates a valid JWT', async () => { | ||
expect.assertions(1) | ||
const jwt = await createJWT({ requested: ['name', 'phone'] }, { issuer: did, signer }, { alg: 'ES256' }) | ||
const pemPublic = jwkToPem.default(publicToJWK(publicKey_x, publicKey_y, 'EC', 'P-256')) | ||
const pemPublic = jwkToPem(publicToJWK(publicKey_x, publicKey_y, 'EC', 'P-256') as any) | ||
expect(verifyTokenFormAndValidity(jwt, pemPublic)).toBe(true) | ||
@@ -210,3 +190,3 @@ }) | ||
const jwt = await createJWT({ requested: ['name', 'phone'] }, { issuer: address, signer }, { alg: 'ES256' }) | ||
const pemPublic = jwkToPem.default(publicToJWK(publicKey_x, publicKey_y, 'EC', 'P-256')) | ||
const pemPublic = jwkToPem(publicToJWK(publicKey_x, publicKey_y, 'EC', 'P-256') as any) | ||
expect(verifyTokenFormAndValidity(jwt, pemPublic)).toBe(true) | ||
@@ -238,3 +218,3 @@ }) | ||
const { payload } = decodeJWT(jwt) | ||
return expect(payload.exp).toEqual(payload.nbf + 10000) | ||
return expect(payload.exp).toEqual(payload.nbf!! + 10000) | ||
}) | ||
@@ -247,3 +227,3 @@ | ||
) | ||
return expect(payload.exp).toEqual(payload.iat + 10000) | ||
return expect(payload.exp).toEqual(payload.iat!! + 10000) | ||
}) | ||
@@ -322,3 +302,3 @@ | ||
const { payload } = decodeJWT(jwt) | ||
return expect(payload.exp).toEqual(payload.nbf + 10000) | ||
return expect(payload.exp).toEqual(payload.nbf!! + 10000) | ||
}) | ||
@@ -331,3 +311,3 @@ | ||
) | ||
return expect(payload.exp).toEqual(payload.iat + 10000) | ||
return expect(payload.exp).toEqual(payload.iat!! + 10000) | ||
}) | ||
@@ -389,3 +369,3 @@ | ||
}), | ||
} | ||
} as Resolvable | ||
@@ -447,3 +427,3 @@ it('creates a valid JWT with did:nacl issuer', async () => { | ||
const { payload } = decodeJWT(jwt) | ||
return expect(payload.exp).toEqual(payload.nbf + 10000) | ||
return expect(payload.exp).toEqual(payload.nbf!! + 10000) | ||
}) | ||
@@ -454,10 +434,4 @@ }) | ||
describe('verifyJWT() for ES256', () => { | ||
const alg = 'ES256' | ||
const privateKey = '736f625c9dda78a94bb16840c82779bb7bc18014b8ede52f0f03429902fc4ba8' | ||
// const privateKey = '736f625c9dda78a94bb16840c82779bb7bc18014b8ede52f0f03429902fc4ba8' | ||
const publicKey = '0314c58e581c7656ba153195669fe4ce53ff78dd5ede60a4039771a90c58cb41de' | ||
const publicKey_x = '14c58e581c7656ba153195669fe4ce53ff78dd5ede60a4039771a90c58cb41de' | ||
const publicKey_y = 'ec41869995bd661849414c523c7dff9a96f1c8dbc2e5e78172118f91c7199869' | ||
// construct did:key for secp256r1 (unlike did for secp256k1 which is for an Ethereum Address) | ||
// const multicodecName = 'p256-pub'; | ||
// const did = encodeDIDfromHexString(multicodecName,publicKey) | ||
const did = 'did:key:zDnaej4NHntda4rNW4FBUJgFzdcgEAXKGRVGE8LuVfRbuMuc1' | ||
@@ -485,3 +459,3 @@ | ||
const resolver = { | ||
resolve: jest.fn().mockImplementation((didUrl: string) => { | ||
resolve: jest.fn(async (didUrl: string) => { | ||
if (didUrl.includes(did)) { | ||
@@ -504,3 +478,3 @@ return { | ||
}), | ||
} | ||
} as Resolvable | ||
@@ -562,3 +536,3 @@ describe('pregenerated JWT', () => { | ||
expect.assertions(1) | ||
await expect(() => verifyJWT(incomingJwt, { resolver, proofPurpose: 'impossible' })).rejects.toThrowError( | ||
await expect(() => verifyJWT(incomingJwt, { resolver, proofPurpose: 'impossible' as any })).rejects.toThrowError( | ||
`DID document for ${did} does not have public keys suitable for ES256 with impossible purpose` | ||
@@ -572,3 +546,3 @@ ) | ||
const resolver = { | ||
resolve: jest.fn().mockImplementation((didUrl: string) => { | ||
resolve: jest.fn(async (didUrl: string) => { | ||
if (didUrl.includes(did)) { | ||
@@ -599,3 +573,3 @@ return { | ||
}), | ||
} | ||
} as Resolvable | ||
@@ -657,3 +631,3 @@ describe('pregenerated JWT', () => { | ||
expect.assertions(1) | ||
await expect(() => verifyJWT(incomingJwt, { resolver, proofPurpose: 'impossible' })).rejects.toThrowError( | ||
await expect(() => verifyJWT(incomingJwt, { resolver, proofPurpose: 'impossible' as any })).rejects.toThrowError( | ||
`DID document for ${did} does not have public keys suitable for ES256K with impossible purpose` | ||
@@ -667,3 +641,3 @@ ) | ||
'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJpYXQiOjE0ODUzMjExMzMsImlzcyI6ImRpZDpldGhyOjB4OTBlNDVkNzViZDEyNDZlMDkyNDg3MjAxODY0N2RiYTk5NmE4ZTdiOSIsInJlcXVlc3RlZCI6WyJuYW1lIiwicGhvbmUiXX0.KIG2zUO8Quf3ucb9jIncZ1CmH0v-fAZlsKvesfsd9x4RzU0qrvinVd9d30DOeZOwdwEdXkET_wuPoOECwU0IKA' | ||
const jwkResolver = { resolve: jest.fn().mockReturnValue(didDocJwk) } | ||
const jwkResolver = { resolve: jest.fn().mockReturnValue(didDocJwk) } as Resolvable | ||
@@ -694,3 +668,3 @@ it('verifies the JWT and return correct payload', async () => { | ||
'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJpYXQiOjE0ODUzMjExMzMsImlzcyI6ImRpZDpldGhyOjB4OTBlNDVkNzViZDEyNDZlMDkyNDg3MjAxODY0N2RiYTk5NmE4ZTdiOSIsInJlcXVlc3RlZCI6WyJuYW1lIiwicGhvbmUiXX0.KIG2zUO8Quf3ucb9jIncZ1CmH0v-fAZlsKvesfsd9x4RzU0qrvinVd9d30DOeZOwdwEdXkET_wuPoOECwU0IKA' | ||
const legacyResolver = { resolve: jest.fn().mockReturnValue(didDocLegacy) } | ||
const legacyResolver = { resolve: jest.fn().mockReturnValue(didDocLegacy) } as Resolvable | ||
@@ -873,3 +847,3 @@ it('verifies the JWT and return correct payload', async () => { | ||
}), | ||
} | ||
} as Resolvable | ||
const jwt = await createJWT({ hello: 'world' }, { issuer: aud, signer, alg: 'ES256K' }) | ||
@@ -896,3 +870,3 @@ const { payload } = await verifyJWT(jwt, { resolver: ethResolver }) | ||
}), | ||
} | ||
} as Resolvable | ||
const jwt = await createJWT({ hello: 'world' }, { issuer: aud, signer, alg: 'ES256K' }) | ||
@@ -918,3 +892,3 @@ const { payload } = await verifyJWT(jwt, { resolver: ethResolver }) | ||
}), | ||
} | ||
} as Resolvable | ||
const jwt = await createJWT({ hello: 'world' }, { issuer: aud, signer: recoverySigner, alg: 'ES256K-R' }) | ||
@@ -1118,3 +1092,3 @@ const result = await verifyJWT(jwt, { resolver: ethResolver }) | ||
// use the hex public key as an arbitrary payload | ||
const encodedPayload = bytesToBase64url(fromString(publicKey, 'base16')) | ||
const encodedPayload = bytesToBase64url(hexToBytes(publicKey)) | ||
const jws = await createJWS(encodedPayload, signer) | ||
@@ -1134,3 +1108,3 @@ expect(jws).toMatchSnapshot() | ||
expect.assertions(1) | ||
const encodedPayload = bytesToBase64url(fromString(publicKey, 'base16')) | ||
const encodedPayload = bytesToBase64url(hexToBytes(publicKey)) | ||
const jws = await createJWS(encodedPayload, signer) | ||
@@ -1273,3 +1247,7 @@ expect(() => verifyJWS(jws, { publicKeyHex: publicKey } as VerificationMethod)).not.toThrow() | ||
expect.assertions(1) | ||
const authenticators = await resolveAuthenticator({ resolve: jest.fn().mockReturnValue(singleKey) }, alg, did) | ||
const authenticators = await resolveAuthenticator( | ||
{ resolve: jest.fn().mockReturnValue(singleKey) } as Resolvable, | ||
alg, | ||
did | ||
) | ||
return expect(authenticators).toEqual({ | ||
@@ -1285,3 +1263,3 @@ authenticators: [ecKey1], | ||
const authenticators = await resolveAuthenticator( | ||
{ resolve: jest.fn().mockReturnValue(multipleKeysLegacy) }, | ||
{ resolve: jest.fn().mockReturnValue(multipleKeysLegacy) } as Resolvable, | ||
alg, | ||
@@ -1300,3 +1278,3 @@ did | ||
const authenticators = await resolveAuthenticator( | ||
{ resolve: jest.fn().mockReturnValue(multipleKeysLegacy) }, | ||
{ resolve: jest.fn().mockReturnValue(multipleKeysLegacy) } as Resolvable, | ||
alg, | ||
@@ -1316,3 +1294,3 @@ did, | ||
const authenticators = await resolveAuthenticator( | ||
{ resolve: jest.fn().mockReturnValue(multipleAuthTypes) }, | ||
{ resolve: jest.fn().mockReturnValue(multipleAuthTypes) } as Resolvable, | ||
alg, | ||
@@ -1332,3 +1310,3 @@ did, | ||
return await expect( | ||
resolveAuthenticator({ resolve: jest.fn().mockReturnValue(unsupportedFormat) }, alg, did) | ||
resolveAuthenticator({ resolve: jest.fn().mockReturnValue(unsupportedFormat) } as Resolvable, alg, did) | ||
).rejects.toThrowError(`DID document for ${did} does not have public keys for ${alg}`) | ||
@@ -1343,3 +1321,3 @@ }) | ||
const authenticators = await resolveAuthenticator( | ||
{ resolve: jest.fn().mockReturnValue(multipleKeysLegacy) }, | ||
{ resolve: jest.fn().mockReturnValue(multipleKeysLegacy) } as Resolvable, | ||
alg, | ||
@@ -1358,3 +1336,3 @@ did | ||
const authenticators = await resolveAuthenticator( | ||
{ resolve: jest.fn().mockReturnValue(multipleKeysLegacy) }, | ||
{ resolve: jest.fn().mockReturnValue(multipleKeysLegacy) } as Resolvable, | ||
alg, | ||
@@ -1374,3 +1352,3 @@ did, | ||
const authenticators = await resolveAuthenticator( | ||
{ resolve: jest.fn().mockReturnValue(multipleAuthTypes) }, | ||
{ resolve: jest.fn().mockReturnValue(multipleAuthTypes) } as Resolvable, | ||
alg, | ||
@@ -1390,3 +1368,3 @@ did, | ||
return await expect( | ||
resolveAuthenticator({ resolve: jest.fn().mockReturnValue(unsupportedFormat) }, alg, did) | ||
resolveAuthenticator({ resolve: jest.fn().mockReturnValue(unsupportedFormat) } as Resolvable, alg, did) | ||
).rejects.toThrowError(`DID document for ${did} does not have public keys for ${alg}`) | ||
@@ -1399,3 +1377,8 @@ }) | ||
return await expect( | ||
resolveAuthenticator({ resolve: jest.fn().mockReturnValue(singleKey) }, alg, did, 'authentication') | ||
resolveAuthenticator( | ||
{ resolve: jest.fn().mockReturnValue(singleKey) } as Resolvable, | ||
alg, | ||
did, | ||
'authentication' | ||
) | ||
).rejects.toThrowError( | ||
@@ -1409,3 +1392,3 @@ `DID document for ${did} does not have public keys suitable for ES256K with authentication purpose` | ||
return await expect( | ||
resolveAuthenticator({ resolve: jest.fn().mockReturnValue(noPublicKey) }, alg, did) | ||
resolveAuthenticator({ resolve: jest.fn().mockReturnValue(noPublicKey) } as Resolvable, alg, did) | ||
).rejects.toThrowError(`DID document for ${did} does not have public keys for ${alg}`) | ||
@@ -1423,3 +1406,3 @@ }) | ||
}), | ||
}, | ||
} as Resolvable, | ||
alg, | ||
@@ -1434,3 +1417,3 @@ did | ||
return await expect( | ||
resolveAuthenticator({ resolve: jest.fn().mockReturnValue(singleKey) }, 'ESBAD', did) | ||
resolveAuthenticator({ resolve: jest.fn().mockReturnValue(singleKey) } as Resolvable, 'ESBAD', did) | ||
).rejects.toThrowError('No supported signature types for algorithm ESBAD') | ||
@@ -1437,0 +1420,0 @@ }) |
@@ -1,2 +0,2 @@ | ||
import NaclSigner from '../signers/NaclSigner' | ||
import NaclSigner from '../signers/NaclSigner.js' | ||
@@ -3,0 +3,0 @@ const privateKey = 'nlXR4aofRVuLqtn9+XVQNlX4s1nVQvp+TOhBBtYls1IG+sHyIkDP/WN+rWZHGIQp+v2pyct+rkM4asF/YRFQdQ==' |
@@ -1,11 +0,11 @@ | ||
import SignerAlgorithm from '../SignerAlgorithm' | ||
import { toSignatureObject, toSignatureObject2 } from '../VerifierAlgorithm' | ||
import SimpleSigner from '../signers/SimpleSigner' | ||
import EllipticSigner from '../signers/EllipticSigner' | ||
import NaclSigner from '../signers/NaclSigner' | ||
import SignerAlgorithm from '../SignerAlgorithm.js' | ||
import { toSignatureObject, toSignatureObject2 } from '../VerifierAlgorithm.js' | ||
import SimpleSigner from '../signers/SimpleSigner.js' | ||
import EllipticSigner from '../signers/EllipticSigner.js' | ||
import NaclSigner from '../signers/NaclSigner.js' | ||
// @ts-ignore | ||
import nacl from 'tweetnacl' | ||
import { base64ToBytes, stringToBytes } from '../util' | ||
import { sha256 } from '../Digest' | ||
import { ES256Signer } from '../signers/ES256Signer' | ||
import { hexToBytes } from '../util' | ||
import { base64ToBytes, hexToBytes, stringToBytes } from '../util.js' | ||
import { sha256 } from '../Digest.js' | ||
import { ES256Signer } from '../signers/ES256Signer.js' | ||
import { p256 } from '@noble/curves/p256' | ||
@@ -12,0 +12,0 @@ import { secp256k1 } from '@noble/curves/secp256k1' |
@@ -1,2 +0,2 @@ | ||
import SimpleSigner from '../signers/SimpleSigner' | ||
import SimpleSigner from '../signers/SimpleSigner.js' | ||
@@ -3,0 +3,0 @@ const privateKey = '278a5de700e29faae8e40e366ec5012b5ec63d36ec77e8a2417154cc1d25383f' |
@@ -1,23 +0,24 @@ | ||
import VerifierAlgorithm from '../VerifierAlgorithm' | ||
import { createJWT } from '../JWT' | ||
// @ts-ignore | ||
import nacl from 'tweetnacl' | ||
import { | ||
base64ToBytes, | ||
bigintToBytes, | ||
bytesToBase58, | ||
bytesToBase64, | ||
hexToBytes, | ||
bytesToBase64url, | ||
bytesToHex, | ||
bytesToMultibase, | ||
bigintToBytes, | ||
} from '../util' | ||
import * as u8a from 'uint8arrays' | ||
import { EdDSASigner } from '../signers/EdDSASigner' | ||
import { ES256KSigner } from '../signers/ES256KSigner' | ||
import { toEthereumAddress } from '../Digest' | ||
import { publicKeyToAddress as toBip122Address } from '../blockchains/bip122' | ||
import { publicKeyToAddress as toCosmosAddressWithoutPrefix } from '../blockchains/cosmos' | ||
hexToBytes, | ||
} from '../util.js' | ||
import { EdDSASigner } from '../signers/EdDSASigner.js' | ||
import { ES256KSigner } from '../signers/ES256KSigner.js' | ||
import { toEthereumAddress } from '../Digest.js' | ||
import { publicKeyToAddress as toBip122Address } from '../blockchains/bip122.js' | ||
import { publicKeyToAddress as toCosmosAddressWithoutPrefix } from '../blockchains/cosmos.js' | ||
import { p256 } from '@noble/curves/p256' | ||
import { secp256k1 } from '@noble/curves/secp256k1' | ||
import { ES256Signer } from '../signers/ES256Signer' | ||
import { ES256Signer } from '../signers/ES256Signer.js' | ||
import VerifierAlgorithm from '../VerifierAlgorithm.js' | ||
import { createJWT } from '../JWT.js' | ||
@@ -116,2 +117,3 @@ describe('VerifierAlgorithm', () => { | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [ecKey1, ecKey2])).toEqual(ecKey2) | ||
@@ -125,3 +127,5 @@ }) | ||
const pubkey = Object.assign({ publicKeyBase58 }, ecKey2) | ||
// @ts-ignore | ||
delete pubkey.publicKeyHex | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [pubkey])).toEqual(pubkey) | ||
@@ -135,3 +139,5 @@ }) | ||
const pubkey = Object.assign({ publicKeyBase64 }, ecKey2) | ||
// @ts-ignore | ||
delete pubkey.publicKeyHex | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [pubkey])).toEqual(pubkey) | ||
@@ -145,3 +151,5 @@ }) | ||
const pubkey = Object.assign({ publicKeyJwk }, ecKey2) | ||
// @ts-ignore | ||
delete pubkey.publicKeyHex | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [pubkey])).toEqual(pubkey) | ||
@@ -155,3 +163,5 @@ }) | ||
const pubkey = Object.assign({ publicKeyMultibase }, ecKey2) | ||
// @ts-ignore | ||
delete pubkey.publicKeyHex | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [pubkey])).toEqual(pubkey) | ||
@@ -164,2 +174,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [ecKey1, compressedKey])).toEqual(compressedKey) | ||
@@ -172,2 +183,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(() => verifier(parts[1], parts[2], [ecKey1])).toThrowError( | ||
@@ -182,2 +194,3 @@ new Error('invalid_signature: Signature invalid for JWT') | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(() => verifier(parts[1], parts[2], [ecKey1])).toThrowError(new Error('wrong signature length')) | ||
@@ -189,2 +202,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [malformedKey1, malformedKey2, malformedKey3, compressedKey])).toEqual( | ||
@@ -201,5 +215,5 @@ compressedKey | ||
const publicKeyPoint = secp256k1.ProjectivePoint.fromHex(publicKeyBytes) | ||
const publicKeyHex = u8a.toString(publicKeyBytes, 'base16') | ||
const publicKeyHex = bytesToHex(publicKeyBytes) | ||
const compressedPublicKeyBytes = secp256k1.getPublicKey(privateKey, true) | ||
const compressedPublicKey = u8a.toString(compressedPublicKeyBytes, 'base16') | ||
const compressedPublicKey = bytesToHex(compressedPublicKeyBytes) | ||
const publicKeyBase64 = bytesToBase64(publicKeyBytes) | ||
@@ -215,3 +229,3 @@ const publicKeyBase58 = bytesToBase58(publicKeyBytes) | ||
const eip155 = toEthereumAddress(publicKeyHex) | ||
const bip122 = toBip122Address(publicKeyHex) | ||
const bip122 = toBip122Address(publicKeyHex, 'undefined') | ||
const cosmosPrefix = 'example' | ||
@@ -336,2 +350,3 @@ const cosmos = toCosmosAddressWithoutPrefix(publicKeyHex, cosmosPrefix) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [ecKey1, ecKey2])).toEqual(ecKey2) | ||
@@ -345,3 +360,5 @@ }) | ||
const pubkey = Object.assign({ publicKeyBase58 }, ecKey2) | ||
// @ts-ignore | ||
delete pubkey.publicKeyHex | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [pubkey])).toEqual(pubkey) | ||
@@ -355,3 +372,5 @@ }) | ||
const pubkey = Object.assign({ publicKeyBase64 }, ecKey2) | ||
// @ts-ignore | ||
delete pubkey.publicKeyHex | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [pubkey])).toEqual(pubkey) | ||
@@ -365,3 +384,5 @@ }) | ||
const pubkey = Object.assign({ publicKeyJwk }, ecKey2) | ||
// @ts-ignore | ||
delete pubkey.publicKeyHex | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [pubkey])).toEqual(pubkey) | ||
@@ -375,3 +396,5 @@ }) | ||
const pubkey = Object.assign({ publicKeyMultibase }, ecKey2) | ||
// @ts-ignore | ||
delete pubkey.publicKeyHex | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [pubkey])).toEqual(pubkey) | ||
@@ -384,2 +407,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [ecKey1, compressedKey])).toEqual(compressedKey) | ||
@@ -392,2 +416,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(() => verifier(parts[1], parts[2], [ecKey1])).toThrowError( | ||
@@ -402,3 +427,3 @@ new Error('invalid_signature: Signature invalid for JWT') | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
return expect(() => verifier(parts[1], parts[2], [ecKey1])).toThrowError( | ||
return expect(() => verifier(parts!![1], parts!![2], [ecKey1])).toThrowError( | ||
new Error('compactSignature expected 64 bytes, got 66') | ||
@@ -411,2 +436,3 @@ ) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [malformedKey1, malformedKey2, malformedKey3, compressedKey])).toEqual( | ||
@@ -421,2 +447,3 @@ compressedKey | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [ethAddress])).toEqual(ethAddress) | ||
@@ -429,2 +456,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [blockchainAddress])).toEqual(blockchainAddress) | ||
@@ -437,2 +465,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [blockchainAddressCaip10])).toEqual(blockchainAddressCaip10) | ||
@@ -445,2 +474,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [blockchainAddressBip122])).toEqual(blockchainAddressBip122) | ||
@@ -453,2 +483,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [blockchainAddressCosmos])).toEqual(blockchainAddressCosmos) | ||
@@ -461,2 +492,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [recoveryMethod2020Key])).toEqual(recoveryMethod2020Key) | ||
@@ -473,2 +505,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [ecKey1, ecKey2])).toEqual(ecKey2) | ||
@@ -481,2 +514,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [ecKey1, compressedKey])).toEqual(compressedKey) | ||
@@ -489,2 +523,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [ecKey1, ethAddress])).toEqual(ethAddress) | ||
@@ -497,2 +532,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [ecKey1, blockchainAddress])).toEqual(blockchainAddress) | ||
@@ -505,2 +541,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [ecKey1, blockchainAddressCaip10])).toEqual(blockchainAddressCaip10) | ||
@@ -513,2 +550,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [ecKey1, blockchainAddressBip122])).toEqual(blockchainAddressBip122) | ||
@@ -521,2 +559,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [ecKey1, blockchainAddressCosmos])).toEqual(blockchainAddressCosmos) | ||
@@ -529,2 +568,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [ecKey1, recoveryMethod2020Key])).toEqual(recoveryMethod2020Key) | ||
@@ -538,3 +578,5 @@ }) | ||
const pubkey = Object.assign({ publicKeyBase58 }, ecKey2) | ||
// @ts-ignore | ||
delete pubkey.publicKeyHex | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [pubkey])).toEqual(pubkey) | ||
@@ -548,3 +590,5 @@ }) | ||
const pubkey = Object.assign({ publicKeyBase64 }, ecKey2) | ||
// @ts-ignore | ||
delete pubkey.publicKeyHex | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [pubkey])).toEqual(pubkey) | ||
@@ -558,3 +602,5 @@ }) | ||
const pubkey = Object.assign({ publicKeyJwk }, ecKey2) | ||
// @ts-ignore | ||
delete pubkey.publicKeyHex | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [pubkey])).toEqual(pubkey) | ||
@@ -568,3 +614,5 @@ }) | ||
const pubkey = Object.assign({ publicKeyMultibase }, ecKey2) | ||
// @ts-ignore | ||
delete pubkey.publicKeyHex | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [pubkey])).toEqual(pubkey) | ||
@@ -577,2 +625,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(() => verifier(parts[1], parts[2], [ecKey1])).toThrowError( | ||
@@ -590,2 +639,3 @@ new Error('invalid_signature: Signature invalid for JWT') | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [edKey, edKey2])).toEqual(edKey) | ||
@@ -598,5 +648,7 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
const publicKeyBase58 = u8a.toString(u8a.fromString(edKey.publicKeyBase64, 'base64pad'), 'base58btc') | ||
const publicKeyBase58 = bytesToBase58(base64ToBytes(edKey.publicKeyBase64)) | ||
const pubkey = Object.assign({ publicKeyBase58 }, edKey) | ||
// @ts-ignore | ||
delete pubkey.publicKeyBase64 | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [pubkey])).toEqual(pubkey) | ||
@@ -612,6 +664,8 @@ }) | ||
kty: 'OKP', | ||
x: u8a.toString(u8a.fromString(edKey.publicKeyBase64, 'base64pad'), 'base64url'), | ||
x: bytesToBase64url(base64ToBytes(edKey.publicKeyBase64)), | ||
} | ||
const pubkey = Object.assign({ publicKeyJwk }, edKey) | ||
// @ts-ignore | ||
delete pubkey.publicKeyBase64 | ||
// @ts-ignore | ||
return expect(verifier(parts[1], parts[2], [pubkey])).toEqual(pubkey) | ||
@@ -624,2 +678,3 @@ }) | ||
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/) | ||
// @ts-ignore | ||
return expect(() => verifier(parts[1], parts[2], [edKey2])).toThrowError( | ||
@@ -626,0 +681,0 @@ new Error('invalid_signature: Signature invalid for JWT') |
@@ -1,9 +0,10 @@ | ||
import { jest, beforeEach, expect, it } from '@jest/globals' | ||
import { x25519Decrypter, resolveX25519Encrypters } from '../xc20pEncryption' | ||
import { decryptJWE, createJWE } from '../JWE' | ||
import * as u8a from 'uint8arrays' | ||
import { DIDResolutionResult, Resolvable } from 'did-resolver' | ||
import { resolveX25519Encrypters, x25519Decrypter } from '../encryption/xc20pEncryption.js' | ||
import { createJWE, Decrypter, decryptJWE } from '../encryption/JWE.js' | ||
import { createX25519ECDH } from '../encryption/ECDH.js' | ||
import { bytesToBase58, generateKeyPair } from '../util.js' | ||
import { randomBytes } from '@noble/hashes/utils' | ||
import { generateKeyPair } from '../util' | ||
import { createX25519ECDH } from '../ECDH' | ||
import { jest } from '@jest/globals' | ||
describe('xc20pEncryption', () => { | ||
@@ -21,15 +22,15 @@ describe('resolveX25519Encrypters', () => { | ||
let resolver | ||
let decrypter1, decrypter2 | ||
let decrypter1remote, decrypter2remote | ||
let resolver: Resolvable | ||
let decrypter1: Decrypter, decrypter2: Decrypter | ||
let decrypter1remote: Decrypter, decrypter2remote: Decrypter | ||
let didDocumentResult1, | ||
didDocumentResult2, | ||
didDocumentResult3, | ||
didDocumentResult4, | ||
didDocumentResult5, | ||
didDocumentResult6, | ||
didDocumentResult7, | ||
didDocumentResult8, | ||
didDocumentResult9 | ||
let didDocumentResult1: DIDResolutionResult, | ||
didDocumentResult2: DIDResolutionResult, | ||
didDocumentResult3: DIDResolutionResult, | ||
didDocumentResult4: DIDResolutionResult, | ||
didDocumentResult5: DIDResolutionResult, | ||
didDocumentResult6: DIDResolutionResult, | ||
didDocumentResult7: DIDResolutionResult, | ||
didDocumentResult8: DIDResolutionResult, | ||
didDocumentResult9: DIDResolutionResult | ||
@@ -52,3 +53,3 @@ beforeEach(() => { | ||
controller: did1, | ||
publicKeyBase58: u8a.toString(kp1.publicKey, 'base58btc'), | ||
publicKeyBase58: bytesToBase58(kp1.publicKey), | ||
}, | ||
@@ -63,3 +64,3 @@ ], | ||
}, | ||
} | ||
} as DIDResolutionResult | ||
@@ -74,10 +75,15 @@ didDocumentResult2 = { | ||
controller: did2, | ||
publicKeyBase58: u8a.toString(kp2.publicKey, 'base58btc'), | ||
publicKeyBase58: bytesToBase58(kp2.publicKey), | ||
}, | ||
], | ||
}, | ||
} | ||
} as unknown as DIDResolutionResult | ||
didDocumentResult3 = { didResolutionMetadata: { error: 'notFound' }, didDocument: null } | ||
didDocumentResult4 = { didDocument: { publicKey: [], keyAgreement: [{ type: 'wrong type' }] } } | ||
didDocumentResult3 = { didResolutionMetadata: { error: 'notFound' }, didDocument: null } as DIDResolutionResult | ||
didDocumentResult4 = { | ||
didDocument: { | ||
publicKey: [], | ||
keyAgreement: [{ type: 'wrong type' }], | ||
}, | ||
} as unknown as DIDResolutionResult | ||
@@ -96,3 +102,3 @@ didDocumentResult5 = { | ||
}, | ||
} | ||
} as DIDResolutionResult | ||
@@ -111,3 +117,3 @@ didDocumentResult6 = { | ||
}, | ||
} | ||
} as DIDResolutionResult | ||
@@ -126,3 +132,3 @@ didDocumentResult7 = { | ||
}, | ||
} | ||
} as DIDResolutionResult | ||
@@ -141,3 +147,3 @@ didDocumentResult8 = { | ||
}, | ||
} | ||
} as DIDResolutionResult | ||
@@ -156,6 +162,6 @@ didDocumentResult9 = { | ||
}, | ||
} | ||
} as DIDResolutionResult | ||
resolver = { | ||
resolve: jest.fn((did) => { | ||
resolve: jest.fn(async (did) => { | ||
switch (did) { | ||
@@ -182,3 +188,3 @@ case did1: | ||
}), | ||
} | ||
} as Resolvable | ||
}) | ||
@@ -191,4 +197,4 @@ | ||
const jwe = await createJWE(cleartext, encrypters) | ||
expect(jwe.recipients[0].header.kid).toEqual(did1 + '#abc') | ||
expect(jwe.recipients[1].header.kid).toEqual(did2 + '#abc') | ||
expect(jwe.recipients!![0].header.kid).toEqual(did1 + '#abc') | ||
expect(jwe.recipients!![1].header.kid).toEqual(did2 + '#abc') | ||
expect(await decryptJWE(jwe, decrypter1)).toEqual(cleartext) | ||
@@ -224,15 +230,15 @@ expect(await decryptJWE(jwe, decrypter2)).toEqual(cleartext) | ||
didDocumentResult1.didDocument.verificationMethod.push({ | ||
didDocumentResult1.didDocument?.verificationMethod?.push({ | ||
id: did1 + '#def', | ||
type: 'X25519KeyAgreementKey2019', | ||
controller: did1, | ||
publicKeyBase58: u8a.toString(secondKp1.publicKey, 'base58btc'), | ||
publicKeyBase58: bytesToBase58(secondKp1.publicKey), | ||
}) | ||
didDocumentResult1.didDocument.keyAgreement.push(did1 + '#def') | ||
didDocumentResult1.didDocument?.keyAgreement?.push(did1 + '#def') | ||
didDocumentResult2.didDocument.keyAgreement.push({ | ||
didDocumentResult2.didDocument?.keyAgreement?.push({ | ||
id: did2 + '#def', | ||
type: 'X25519KeyAgreementKey2019', | ||
controller: did2, | ||
publicKeyBase58: u8a.toString(secondKp2.publicKey, 'base58btc'), | ||
publicKeyBase58: bytesToBase58(secondKp2.publicKey), | ||
}) | ||
@@ -244,6 +250,6 @@ | ||
expect(jwe.recipients[0].header.kid).toEqual(did1 + '#abc') | ||
expect(jwe.recipients[1].header.kid).toEqual(did1 + '#def') | ||
expect(jwe.recipients[2].header.kid).toEqual(did2 + '#abc') | ||
expect(jwe.recipients[3].header.kid).toEqual(did2 + '#def') | ||
expect(jwe.recipients!![0].header.kid).toEqual(did1 + '#abc') | ||
expect(jwe.recipients!![1].header.kid).toEqual(did1 + '#def') | ||
expect(jwe.recipients!![2].header.kid).toEqual(did2 + '#abc') | ||
expect(jwe.recipients!![3].header.kid).toEqual(did2 + '#def') | ||
expect(await decryptJWE(jwe, newDecrypter1)).toEqual(cleartext) | ||
@@ -260,3 +266,3 @@ expect(await decryptJWE(jwe, newDecrypter2)).toEqual(cleartext) | ||
const jwe = await createJWE(cleartext, encrypters) | ||
expect(jwe.recipients[0].header.kid).toEqual(did1 + '#abc') | ||
expect(jwe.recipients!![0].header.kid).toEqual(did1 + '#abc') | ||
expect(await decryptJWE(jwe, decrypter1)).toEqual(cleartext) | ||
@@ -271,3 +277,3 @@ expect(await decryptJWE(jwe, decrypter1remote)).toEqual(cleartext) | ||
const jwe = await createJWE(cleartext, encrypters) | ||
expect(jwe.recipients[0].header.kid).toEqual(did1 + '#abc') | ||
expect(jwe.recipients!![0].header.kid).toEqual(did1 + '#abc') | ||
expect(await decryptJWE(jwe, decrypter1)).toEqual(cleartext) | ||
@@ -282,4 +288,4 @@ expect(await decryptJWE(jwe, decrypter1remote)).toEqual(cleartext) | ||
const jwe = await createJWE(cleartext, encrypters) | ||
expect(jwe.recipients[0].header.kid).toEqual(did2 + '#abc') | ||
expect(jwe.recipients.length).toEqual(1) | ||
expect(jwe.recipients!![0].header.kid).toEqual(did2 + '#abc') | ||
expect(jwe.recipients!!.length).toEqual(1) | ||
expect(await decryptJWE(jwe, decrypter2)).toEqual(cleartext) | ||
@@ -286,0 +292,0 @@ expect(await decryptJWE(jwe, decrypter2remote)).toEqual(cleartext) |
@@ -1,17 +0,15 @@ | ||
import { fromString } from 'uint8arrays/from-string' | ||
import { toString } from 'uint8arrays/to-string' | ||
import { bytesToBase58, base58ToBytes } from '../util' | ||
import { sha256, ripemd160 } from '../Digest' | ||
import { base58ToBytes, bytesToBase58, bytesToHex, hexToBytes } from '../util.js' | ||
import { ripemd160, sha256 } from '../Digest.js' | ||
export function publicKeyToAddress(publicKey: string, otherAddress: string): string { | ||
// Use the same version/prefix byte as the given address. | ||
const version = toString(base58ToBytes(otherAddress).slice(0, 1), 'hex') | ||
const publicKeyBuffer = fromString(publicKey, 'hex') | ||
const version = bytesToHex(base58ToBytes(otherAddress).slice(0, 1)) | ||
const publicKeyBuffer = hexToBytes(publicKey) | ||
const publicKeyHash = ripemd160(sha256(publicKeyBuffer)) | ||
const step1 = version + toString(publicKeyHash, 'hex') | ||
const step2 = sha256(fromString(step1, 'hex')) | ||
const step1 = version + bytesToHex(publicKeyHash) | ||
const step2 = sha256(hexToBytes(step1)) | ||
const step3 = sha256(step2) | ||
const checksum = toString(step3, 'hex').substring(0, 8) | ||
const checksum = bytesToHex(step3).substring(0, 8) | ||
const step4 = step1 + checksum | ||
return bytesToBase58(fromString(step4, 'hex')) | ||
return bytesToBase58(hexToBytes(step4)) | ||
} |
import { secp256k1 } from '@noble/curves/secp256k1' | ||
import { bech32 } from 'bech32' | ||
import { sha256, ripemd160 } from '../Digest' | ||
import { sha256, ripemd160 } from '../Digest.js' | ||
@@ -5,0 +5,0 @@ export function publicKeyToAddress(publicKey: string, prefix: string): string { |
@@ -1,4 +0,4 @@ | ||
import { publicKeyToAddress as bip122 } from './bip122' | ||
import { publicKeyToAddress as cosmos } from './cosmos' | ||
import { toEthereumAddress } from '../Digest' | ||
import { publicKeyToAddress as bip122 } from './bip122.js' | ||
import { publicKeyToAddress as cosmos } from './cosmos.js' | ||
import { toEthereumAddress } from '../Digest.js' | ||
@@ -5,0 +5,0 @@ export function verifyBlockchainAccountId(publicKey: string, blockchainAccountId: string | undefined): boolean { |
@@ -1,7 +0,7 @@ | ||
import SimpleSigner from './signers/SimpleSigner' | ||
import EllipticSigner from './signers/EllipticSigner' | ||
import NaclSigner from './signers/NaclSigner' | ||
import { ES256KSigner } from './signers/ES256KSigner' | ||
import { ES256Signer } from './signers/ES256Signer' | ||
import { EdDSASigner } from './signers/EdDSASigner' | ||
import SimpleSigner from './signers/SimpleSigner.js' | ||
import EllipticSigner from './signers/EllipticSigner.js' | ||
import NaclSigner from './signers/NaclSigner.js' | ||
import { ES256KSigner } from './signers/ES256KSigner.js' | ||
import { ES256Signer } from './signers/ES256Signer.js' | ||
import { EdDSASigner } from './signers/EdDSASigner.js' | ||
import { | ||
@@ -11,16 +11,23 @@ createJWS, | ||
decodeJWT, | ||
JWTHeader, | ||
JWTPayload, | ||
JWTVerified, | ||
Signer, | ||
type JWTHeader, | ||
type JWTPayload, | ||
type JWTVerified, | ||
type Signer, | ||
verifyJWS, | ||
verifyJWT, | ||
} from './JWT' | ||
import { toEthereumAddress } from './Digest' | ||
} from './JWT.js' | ||
import { toEthereumAddress } from './Digest.js' | ||
export { JWE, createJWE, decryptJWE, Encrypter, Decrypter, ProtectedHeader, Recipient, RecipientHeader } from './JWE' | ||
export { ECDH, createX25519ECDH } from './ECDH' | ||
export { | ||
xc20pDirEncrypter, | ||
xc20pDirDecrypter, | ||
type JWE, | ||
createJWE, | ||
decryptJWE, | ||
type Encrypter, | ||
type Decrypter, | ||
type ProtectedHeader, | ||
type Recipient, | ||
type RecipientHeader, | ||
} from './encryption/JWE.js' | ||
export { type ECDH, createX25519ECDH } from './encryption/ECDH.js' | ||
export { | ||
x25519Encrypter, | ||
@@ -35,3 +42,3 @@ x25519Decrypter, | ||
xc20pAuthDecrypterEcdh1PuV3x25519WithXc20PkwV2, | ||
} from './xc20pEncryption' | ||
} from './encryption/xc20pEncryption.js' | ||
@@ -51,12 +58,14 @@ export { | ||
toEthereumAddress, | ||
Signer, | ||
JWTHeader, | ||
JWTPayload, | ||
JWTVerified, | ||
type Signer, | ||
type JWTHeader, | ||
type JWTPayload, | ||
type JWTVerified, | ||
} | ||
export { JWTOptions, JWTVerifyOptions } from './JWT' | ||
export { type JWTOptions, type JWTVerifyOptions } from './JWT.js' | ||
export { base64ToBytes, base58ToBytes, hexToBytes } from './util' | ||
export { base64ToBytes, base58ToBytes, hexToBytes } from './util.js' | ||
export * from './Errors' | ||
export * from './Errors.js' | ||
export { xc20pDirDecrypter, xc20pDirEncrypter } from './encryption/xc20pDir.js' | ||
export * from './encryption/aesEncryption.js' |
import canonicalizeData from 'canonicalize' | ||
import type { DIDDocument, DIDResolutionResult, Resolvable, VerificationMethod } from 'did-resolver' | ||
import SignerAlg from './SignerAlgorithm' | ||
import { decodeBase64url, EcdsaSignature, encodeBase64url } from './util' | ||
import VerifierAlgorithm from './VerifierAlgorithm' | ||
import { JWT_ERROR } from './Errors' | ||
import SignerAlg from './SignerAlgorithm.js' | ||
import { decodeBase64url, EcdsaSignature, encodeBase64url } from './util.js' | ||
import VerifierAlgorithm from './VerifierAlgorithm.js' | ||
import { JWT_ERROR } from './Errors.js' | ||
@@ -8,0 +8,0 @@ export type Signer = (data: string | Uint8Array) => Promise<EcdsaSignature | string> |
@@ -1,3 +0,3 @@ | ||
import { Signer, SignerAlgorithm } from './JWT' | ||
import { EcdsaSignature, fromJose, toJose } from './util' | ||
import type { Signer, SignerAlgorithm } from './JWT.js' | ||
import { type EcdsaSignature, fromJose, toJose } from './util.js' | ||
@@ -4,0 +4,0 @@ // eslint-disable-next-line @typescript-eslint/no-explicit-any |
import { ed25519 } from '@noble/curves/ed25519' | ||
import type { Signer } from '../JWT' | ||
import { bytesToBase64url, stringToBytes } from '../util' | ||
import type { Signer } from '../JWT.js' | ||
import { bytesToBase64url, stringToBytes } from '../util.js' | ||
@@ -5,0 +5,0 @@ /** |
@@ -1,4 +0,4 @@ | ||
import { hexToBytes } from '../util' | ||
import { Signer } from '../JWT' | ||
import { ES256KSigner } from './ES256KSigner' | ||
import type { Signer } from '../JWT.js' | ||
import { hexToBytes } from '../util.js' | ||
import { ES256KSigner } from './ES256KSigner.js' | ||
@@ -5,0 +5,0 @@ /** |
@@ -1,5 +0,4 @@ | ||
import { leftpad } from '../util' | ||
import { toJose } from '../util' | ||
import { Signer } from '../JWT' | ||
import { sha256 } from '../Digest' | ||
import { leftpad, toJose } from '../util.js' | ||
import { Signer } from '../JWT.js' | ||
import { sha256 } from '../Digest.js' | ||
import { secp256k1 } from '@noble/curves/secp256k1' | ||
@@ -6,0 +5,0 @@ |
@@ -1,5 +0,4 @@ | ||
import { leftpad } from '../util' | ||
import { toJose } from '../util' | ||
import { Signer } from '../JWT' | ||
import { sha256 } from '../Digest' | ||
import { leftpad, toJose } from '../util.js' | ||
import { Signer } from '../JWT.js' | ||
import { sha256 } from '../Digest.js' | ||
import { p256 } from '@noble/curves/p256' | ||
@@ -6,0 +5,0 @@ |
@@ -1,4 +0,4 @@ | ||
import { EdDSASigner as EdDSASigner } from './EdDSASigner' | ||
import { Signer } from '../JWT' | ||
import { base64ToBytes } from '../util' | ||
import { EdDSASigner as EdDSASigner } from './EdDSASigner.js' | ||
import type { Signer } from '../JWT.js' | ||
import { base64ToBytes } from '../util.js' | ||
@@ -10,3 +10,4 @@ /** | ||
* | ||
* The signing function itself takes the data as a `string` or `Uint8Array` parameter and returns a `base64Url`-encoded signature. | ||
* The signing function itself takes the data as a `string` or `Uint8Array` parameter and returns a | ||
* `base64Url`-encoded signature. | ||
* | ||
@@ -13,0 +14,0 @@ * @example |
@@ -1,4 +0,4 @@ | ||
import { fromJose, hexToBytes } from '../util' | ||
import { Signer } from '../JWT' | ||
import { ES256KSigner } from './ES256KSigner' | ||
import { fromJose, hexToBytes } from '../util.js' | ||
import type { Signer } from '../JWT.js' | ||
import { ES256KSigner } from './ES256KSigner.js' | ||
@@ -5,0 +5,0 @@ /** |
@@ -1,5 +0,7 @@ | ||
import * as u8a from 'uint8arrays' | ||
import { concat, fromString, toString } from 'uint8arrays' | ||
import { bases } from 'multiformats/basics' | ||
import { x25519 } from '@noble/curves/ed25519' | ||
const u8a = { toString, fromString, concat } | ||
/** | ||
@@ -11,3 +13,3 @@ * @deprecated Signers will be expected to return base64url `string` signatures. | ||
s: string | ||
recoveryParam?: number | null | ||
recoveryParam?: number | ||
} | ||
@@ -101,4 +103,4 @@ | ||
export function toSealed(ciphertext: string, tag: string): Uint8Array { | ||
return u8a.concat([base64ToBytes(ciphertext), base64ToBytes(tag)]) | ||
export function toSealed(ciphertext: string, tag?: string): Uint8Array { | ||
return u8a.concat([base64ToBytes(ciphertext), tag ? base64ToBytes(tag) : new Uint8Array(0)]) | ||
} | ||
@@ -105,0 +107,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { sha256, toEthereumAddress } from './Digest' | ||
import { sha256, toEthereumAddress } from './Digest.js' | ||
import type { VerificationMethod } from 'did-resolver' | ||
@@ -13,4 +13,4 @@ import { bases } from 'multiformats/basics' | ||
ECDSASignature, | ||
} from './util' | ||
import { verifyBlockchainAccountId } from './blockchains' | ||
} from './util.js' | ||
import { verifyBlockchainAccountId } from './blockchains/index.js' | ||
import { secp256k1 } from '@noble/curves/secp256k1' | ||
@@ -46,3 +46,3 @@ import { p256 } from '@noble/curves/p256' | ||
function extractPublicKeyBytes(pk: VerificationMethod): Uint8Array { | ||
export function extractPublicKeyBytes(pk: VerificationMethod): Uint8Array { | ||
if (pk.publicKeyBase58) { | ||
@@ -67,3 +67,3 @@ return base58ToBytes(pk.publicKeyBase58) | ||
pk.publicKeyJwk.kty === 'OKP' && | ||
pk.publicKeyJwk.crv === 'Ed25519' && | ||
['Ed25519', 'X25519'].includes(pk.publicKeyJwk.crv ?? '') && | ||
pk.publicKeyJwk.x | ||
@@ -70,0 +70,0 @@ ) { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
141
0
659969
11
33
9622
2
+ Added@stablelib/aes@^1.0.1
+ Added@stablelib/aes-kw@^1.0.1
+ Added@stablelib/gcm@^1.0.2
+ Added@stablelib/aes@1.0.1(transitive)
+ Added@stablelib/aes-kw@1.0.1(transitive)
+ Added@stablelib/blockcipher@1.0.1(transitive)
+ Added@stablelib/ctr@1.0.2(transitive)
+ Added@stablelib/gcm@1.0.2(transitive)
+ Addedmultiformats@11.0.212.1.3(transitive)
+ Addeduint8arrays@4.0.10(transitive)
- Removedmultiformats@9.9.0(transitive)
- Removeduint8arrays@3.1.1(transitive)
Updateddid-resolver@^4.1.0
Updatedmultiformats@^11.0.2
Updateduint8arrays@^4.0.3