OverviewFilesCommitsIssuesDocsReleasesPeers

P2P-Hiverelay / packages / blind-client / runtime / node.js

35 lines · javascript ref:
import crypto from 'node:crypto'
import b4a from 'b4a'
import { asBytes } from '../bytes.js'

export function createNodeCryptoRuntime () {
  return Object.freeze({
    randomBytes (length) {
      return crypto.randomBytes(length)
    },
    async aes256GcmEncrypt ({ key, nonce, aad, plaintext }) {
      key = asBytes(key, 'key', 32)
      nonce = asBytes(nonce, 'nonce', 12)
      aad = asBytes(aad, 'aad')
      plaintext = asBytes(plaintext, 'plaintext')
      const cipher = crypto.createCipheriv('aes-256-gcm', key, nonce, { authTagLength: 16 })
      cipher.setAAD(aad, { plaintextLength: plaintext.byteLength })
      const ciphertext = b4a.concat([cipher.update(plaintext), cipher.final()])
      return b4a.concat([ciphertext, cipher.getAuthTag()])
    },
    async aes256GcmDecrypt ({ key, nonce, aad, sealed }) {
      key = asBytes(key, 'key', 32)
      nonce = asBytes(nonce, 'nonce', 12)
      aad = asBytes(aad, 'aad')
      sealed = asBytes(sealed, 'sealed')
      if (sealed.byteLength < 16) throw new Error('sealed AES-GCM value is truncated')
      const ciphertext = sealed.subarray(0, sealed.byteLength - 16)
      const tag = sealed.subarray(sealed.byteLength - 16)
      const decipher = crypto.createDecipheriv('aes-256-gcm', key, nonce, { authTagLength: 16 })
      decipher.setAAD(aad, { plaintextLength: ciphertext.byteLength })
      decipher.setAuthTag(tag)
      return b4a.concat([decipher.update(ciphertext), decipher.final()])
    }
  })
}