UNPKG

@veramo/did-comm

Version:

Veramo messaging plugin implementing DIDComm v2.

49 lines (42 loc) 1.45 kB
import type { Decrypter, KeyWrapper, WrappingResult } from 'did-jwt' import { randomBytes } from '@noble/hashes/utils' import { concat } from '@veramo/utils' import { XChaCha20Poly1305 } from '@stablelib/xchacha20poly1305' export const xc20pKeyWrapper: KeyWrapper = { from: (wrappingKey: Uint8Array) => { const cipher = new XChaCha20Poly1305(wrappingKey) const wrap = async (cek: Uint8Array): Promise<WrappingResult> => { const iv = randomBytes(cipher.nonceLength) const sealed = cipher.seal(iv, cek) return { ciphertext: sealed.subarray(0, sealed.length - cipher.tagLength), tag: sealed.subarray(sealed.length - cipher.tagLength), iv, } } return { wrap } }, alg: 'XC20PKW', } export function xc20pDecrypter(key: Uint8Array): Decrypter { const cipher = new XChaCha20Poly1305(key) async function decrypt(sealed: Uint8Array, iv: Uint8Array, aad?: Uint8Array): Promise<Uint8Array | null> { return cipher.open(iv, sealed, aad) } return { alg: 'dir', enc: 'XC20P', decrypt } } export function xc20pKeyUnwrapper(wrappingKey: Uint8Array) { const unwrap = async ( wrappedCek: Uint8Array, iv: Uint8Array, tag: Uint8Array, ): Promise<Uint8Array | null> => { try { const sealed = concat([wrappedCek, tag]) return xc20pDecrypter(wrappingKey).decrypt(sealed, iv) } catch (e) { return null } } return { unwrap, alg: 'XC20PKW' } }