@tiny-utils/crypto
Version:
Tiny utils for crypto: asymmetric/symmetric encryption, ed25519, sha256, etc.
69 lines (61 loc) • 1.95 kB
text/typescript
import { randomBytes, box as naclbox } from 'tweetnacl';
import { SmartBuffer } from '@tiny-utils/bytes';
/**
* @category Crypto
* @description Method to symmetrically encrypt the data using *xsalsa20-poly1305* algorithm.
*
* @param data Data to encrypt
* @param key Symmetric key to encrypt the data
* @returns Encrypted data
*/
export const symmetricEncrypt = (data: Uint8Array, key: Uint8Array) => {
const nonce = randomBytes(24);
const encData = naclbox.after(data, nonce, key);
return packSymmetricalyEncryptedData(encData, nonce);
};
/**
* Method to pack data and nonce into one readable bytes array
*
* @param encData Encrypted data raw bytes
* @param nonce Nonce raw bytes
* @returns Container buffer
*/
export const packSymmetricalyEncryptedData = (encData: Uint8Array, nonce: Uint8Array) => {
const buf = SmartBuffer.ofSize(1 + 1 + nonce.length + 4 + encData.length);
buf.writeUint8(1);
buf.writeBytes8Length(nonce);
buf.writeBytes32Length(encData);
return buf.bytes;
};
/**
* @category Crypto
* @description Method to symmetrically decrypt the data using *xsalsa20-poly1305* algorithm.
*
* @param data Data to decrypt
* @param key Symmetric key to decrypt the data
* @returns Decrypted data
*/
export const symmetricDecrypt = (data: Uint8Array, key: Uint8Array) => {
const { nonce, encData } = unpackSymmetricalyEncryptedData(data);
const decData = naclbox.open.after(encData, nonce, key);
if (!decData) {
throw new Error(`symmetricDecrypt: Invalid box or key`);
}
return decData;
};
/**
* Method to unpack data and nonce from one readable bytes array
*
* @param data Bytes with encrypted data and nonce
* @returns Data and nonce
*/
export const unpackSymmetricalyEncryptedData = (data: Uint8Array) => {
const buf = new SmartBuffer(data);
const version = buf.readUint8();
const nonce = buf.readBytes8Length();
const encData = buf.readBytes32Length();
return {
nonce,
encData,
};
};