diff --git a/package.json b/package.json index 53f1ded4..49b86182 100644 --- a/package.json +++ b/package.json @@ -94,8 +94,9 @@ "@scure/base": "^1.1.3", "canonicalize": "^2.0.0", "did-resolver": "^4.1.0", - "multiformats": "^12.0.0", - "uint8arrays": "^4.0.3" + "multibase": "^4.0.6", + "multiformats": "^9.6.2", + "uint8arrays": "3.1.1" }, "eslintIgnore": [ "*.test.ts" diff --git a/renovate.json b/renovate.json index 33b1b8b8..e7550ef6 100644 --- a/renovate.json +++ b/renovate.json @@ -30,6 +30,13 @@ "extends": [ "schedule:earlyMondays" ] + }, + { + "matchPackagePatterns": [ + "multiformats", + "uint8arrays" + ], + "enabled": false } ] } diff --git a/src/Digest.ts b/src/Digest.ts index 0ebbd292..69f665fe 100644 --- a/src/Digest.ts +++ b/src/Digest.ts @@ -1,9 +1,7 @@ import { sha256 as sha256Hash } from '@noble/hashes/sha256' export { ripemd160 } from '@noble/hashes/ripemd160' import { keccak_256 } from '@noble/hashes/sha3' -import { fromString } from 'uint8arrays/from-string' -import { toString } from 'uint8arrays/to-string' -import { concat } from 'uint8arrays/concat' +import { fromString, toString, concat } from 'uint8arrays' export function sha256(payload: string | Uint8Array): Uint8Array { const data = typeof payload === 'string' ? fromString(payload) : payload diff --git a/src/dependency.types.d.ts b/src/dependency.types.d.ts new file mode 100644 index 00000000..f8da82bc --- /dev/null +++ b/src/dependency.types.d.ts @@ -0,0 +1,26 @@ +declare module 'uint8arrays' { + export function compare(a: Uint8Array, b: Uint8Array): 0 | 1 | -1 + export function concat(arrays: Array>, length?: number | undefined): Uint8Array + export type SupportedEncodings = + | 'utf8' + | 'utf-8' + | 'hex' + | 'ascii' + | 'base10' + | 'base16' + | 'base16upper' + | 'base58btc' + | 'base64' + | 'base64url' + | 'base64pad' + export function fromString(string: string, encoding?: SupportedEncodings | undefined): Uint8Array + export function toString(array: Uint8Array, encoding?: SupportedEncodings | undefined): string +} + +declare module 'multiformats' { + declare namespace varint { + export function decode(data: Uint8Array, offset?: number | undefined): [number, number] + export function encodeTo(int: number, target: Uint8Array, offset?: number | undefined): Uint8Array + export function encodingLength(int: number): number + } +} diff --git a/src/encryption/JWE.ts b/src/encryption/JWE.ts index 3a6ac5ce..3bf91ec1 100644 --- a/src/encryption/JWE.ts +++ b/src/encryption/JWE.ts @@ -1,5 +1,4 @@ -import { fromString } from 'uint8arrays/from-string' -import { base64ToBytes, bytesToBase64url, decodeBase64url, toSealed } from '../util.js' +import { base64ToBytes, bytesToBase64url, decodeBase64url, stringToBytes, toSealed } from '../util.js' import type { Decrypter, Encrypter, EncryptionResult, EphemeralKeyPair, JWE, ProtectedHeader } from './types.js' function validateJWE(jwe: JWE) { @@ -74,7 +73,7 @@ export async function decryptJWE(jwe: JWE, decrypter: Decrypter): Promise { const protHeader = encodeBase64url(JSON.stringify(Object.assign({ alg }, protectedHeader, { enc }))) - const encodedAad = fromString(aad ? `${protHeader}.${bytesToBase64url(aad)}` : protHeader, 'utf-8') + const encodedAad = stringToBytes(aad ? `${protHeader}.${bytesToBase64url(aad)}` : protHeader) return { ...xc20pEncrypt(cleartext, encodedAad), protectedHeader: protHeader, diff --git a/src/util.ts b/src/util.ts index 65456aba..2648a383 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,8 +1,8 @@ import { concat, fromString, toString } from 'uint8arrays' -import { bases } from 'multiformats/basics' import { x25519 } from '@noble/curves/ed25519' import type { EphemeralKeyPair } from './encryption/types.js' import { varint } from 'multiformats' +import { BaseName, decode, encode } from 'multibase' const u8a = { toString, fromString, concat } @@ -77,18 +77,18 @@ export const supportedCodecs = { */ export function bytesToMultibase( b: Uint8Array, - base: keyof typeof bases = 'base58btc', + base: BaseName = 'base58btc', codec?: keyof typeof supportedCodecs | number ): string { if (!codec) { - return bases[base].encode(b) + return u8a.toString(encode(base, b), 'utf-8') } else { const codecCode = typeof codec === 'string' ? supportedCodecs[codec] : codec const prefixLength = varint.encodingLength(codecCode) const multicodecEncoding = new Uint8Array(prefixLength + b.length) varint.encodeTo(codecCode, multicodecEncoding) // set prefix multicodecEncoding.set(b, prefixLength) // add the original bytes - return bases[base].encode(multicodecEncoding) + return u8a.toString(encode(base, multicodecEncoding), 'utf-8') } } @@ -103,15 +103,7 @@ export function bytesToMultibase( * @public */ export function multibaseToBytes(s: string): Uint8Array { - const { base10, base16, base16upper, base58btc, base64, base64url } = bases - - const baseDecoder = base58btc.decoder - .or(base10.decoder) - .or(base16.decoder) - .or(base16upper.decoder) - .or(base64.decoder) - .or(base64url.decoder) - const bytes = baseDecoder.decode(s) + const bytes = decode(s) // look for known key lengths first // Ed25519/X25519, secp256k1/P256 compressed or not, BLS12-381 G1/G2 compressed @@ -166,7 +158,7 @@ export function bigintToBytes(n: bigint, minLength?: number): Uint8Array { } export function stringToBytes(s: string): Uint8Array { - return u8a.fromString(s) + return u8a.fromString(s, 'utf-8') } export function toJose({ r, s, recoveryParam }: EcdsaSignature, recoverable?: boolean): string { diff --git a/yarn.lock b/yarn.lock index 3479f276..9f81e8a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2461,6 +2461,11 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@multiformats/base-x@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@multiformats/base-x/-/base-x-4.0.1.tgz#95ff0fa58711789d53aefb2590a8b7a4e715d121" + integrity sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw== + "@noble/ciphers@^0.4.0": version "0.4.0" resolved "https://registry.yarnpkg.com/@noble/ciphers/-/ciphers-0.4.0.tgz#e3f69e3ce935683dd8dadb636652a5cb5cd5958c" @@ -8205,10 +8210,17 @@ ms@^2.0.0, ms@^2.1.2: resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -multiformats@^12.0.0, multiformats@^12.0.1: - version "12.1.3" - resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-12.1.3.tgz#cbf7a9861e11e74f8228b21376088cb43ba8754e" - integrity sha512-eajQ/ZH7qXZQR2AgtfpmSMizQzmyYVmCql7pdhldPuYQi4atACekbJaQplk6dWyIi10jCaFnd6pqvcEFXjbaJw== +multibase@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/multibase/-/multibase-4.0.6.tgz#6e624341483d6123ca1ede956208cb821b440559" + integrity sha512-x23pDe5+svdLz/k5JPGCVdfn7Q5mZVMBETiC+ORfO+sor9Sgs0smJzAjfTbM5tckeCqnaUuMYoz+k3RXMmJClQ== + dependencies: + "@multiformats/base-x" "^4.0.1" + +multiformats@^9.4.2, multiformats@^9.6.2: + version "9.9.0" + resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.9.0.tgz#c68354e7d21037a8f1f8833c8ccd68618e8f1d37" + integrity sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg== mute-stream@~1.0.0: version "1.0.0" @@ -10624,12 +10636,12 @@ uglify-js@^3.1.4: resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.0.tgz" integrity sha512-aTeNPVmgIMPpm1cxXr2Q/nEbvkmV8yq66F3om7X3P/cvOXQ0TMQ64Wk63iyT1gPlmdmGzjGpyLh1f3y8MZWXGg== -uint8arrays@^4.0.3: - version "4.0.6" - resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-4.0.6.tgz#bae68b536c2e87147045b95d73d29e503e45ecab" - integrity sha512-4ZesjQhqOU2Ip6GPReIwN60wRxIupavL8T0Iy36BBHr2qyMrNxsPJvr7vpS4eFt8F8kSguWUPad6ZM9izs/vyw== +uint8arrays@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-3.1.1.tgz#2d8762acce159ccd9936057572dade9459f65ae0" + integrity sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg== dependencies: - multiformats "^12.0.1" + multiformats "^9.4.2" unbox-primitive@^1.0.1: version "1.0.1"