Files
libcrypto/src/private-box.ts
T

60 lines
2.1 KiB
TypeScript

import logger from 'log'
import SecretBox from './secret-box'
import {DHusage, ecdh} from './kdf'
import * as consts from './const'
import * as misc from './misc.ts'
const log = logger('crypto:private-box')
export default class PrivateBox {
private constructor(
private readonly pubkey: CryptoKey,
private readonly box: SecretBox
) {}
public static async gen(extractable: boolean = true): Promise<CryptoKeyPair> {
log.trace('generate keypair')
return await crypto.subtle.generateKey(consts.ECDH, extractable, ['deriveBits']) as CryptoKeyPair
}
public static async encrypt(data: Uint8Array, pubkey: CryptoKey, context?: string): Promise<PrivateBox> {
log.trace('encrypt')
const tmp_pair = await PrivateBox.gen(false)
const key = await ecdh(tmp_pair.privateKey, pubkey, DHusage.box, context) // TODO : null
const box = await SecretBox.encrypt(data, key)
return new this(tmp_pair.publicKey, box)
}
public async decrypt(privkey: CryptoKey, context?: string): Promise<Uint8Array | null> {
log.trace('decrypt')
const key = await ecdh(privkey, this.pubkey, DHusage.box, context) // TODO : null
return await this.box.decrypt(key)
}
public async toString(): Promise<string> {
log.trace('toString')
const pubkey = await PrivateBox.pubkey_toString(this.pubkey)
const box = this.box.toString()
return `${pubkey}.${box}`
}
public static async fromString(data: string): Promise<PrivateBox | null> {
log.trace('fromString')
const parts = data.split('.')
if (parts.length < 2) return null
const pubkey = await PrivateBox.pubkey_fromString(parts[0])
if (pubkey === null) return null
const box = SecretBox.fromString(parts.slice(1).join('.'))
if (box === null) return null
return new PrivateBox(pubkey, box)
}
public static async pubkey_toString(pubkey: CryptoKey): Promise<string> {
return await misc.pubkey_toString(pubkey)
}
public static async pubkey_fromString(pubkey: string): Promise<CryptoKey | null> {
return await misc.pubkey_fromString(pubkey, misc.Usage.ecdh)
}
}