@fruitsjs/crypto
Version:
Cryptographic functions for building Fruits Eco-Blockchain apps.
63 lines (50 loc) • 2.09 kB
text/typescript
import * as CryptoJS from 'crypto-js';
import {gzip} from 'pako/lib/deflate';
import {ECKCDSA} from './ec-kcdsa';
import {Converter} from './converter';
import {EncryptedData} from './typings/encryptedData';
const IV_LENGTH = 16;
const SHARED_KEY_SIZE = 32;
function encrypt(plaintext: Uint8Array, nonce: Uint8Array, sharedKeyOrig: any[]) {
const sharedKey = sharedKeyOrig.slice(0);
for (let i = 0; i < SHARED_KEY_SIZE; i++) {
// tslint:disable:no-bitwise
sharedKey[i] ^= nonce[i];
}
const key = CryptoJS.SHA256(Converter.convertByteArrayToWordArray(sharedKey));
const data = Converter.convertByteArrayToWordArray(plaintext);
const encrypted = CryptoJS.AES.encrypt(data, key, {
iv: CryptoJS.lib.WordArray.random(IV_LENGTH)
});
const ivOut = Converter.convertWordArrayToByteArray(encrypted.iv);
const ciphertextOut = Converter.convertWordArrayToByteArray(encrypted.ciphertext);
return ivOut.concat(ciphertextOut);
}
/**
* Encrypts arbitrary data for P2P message/data exchange using asymmetric encryption
*
* @see [[decryptData]]
* @param plaintext Data to be encrypted
* @param recipientPublicKeyHex The recipients public key in hexadecimal format
* @param senderPrivateKeyHex The senders private (agreement) key hexadecimal format
* @return The encrypted Data
* @module crypto
*/
export function encryptData(
plaintext: Uint8Array,
recipientPublicKeyHex: string,
senderPrivateKeyHex: string): EncryptedData {
const sharedKey =
ECKCDSA.sharedkey(
Converter.convertHexStringToByteArray(senderPrivateKeyHex),
Converter.convertHexStringToByteArray(recipientPublicKeyHex)
);
const compressedData = gzip(plaintext);
const randomBytes = CryptoJS.lib.WordArray.random(SHARED_KEY_SIZE);
const nonce = Converter.convertWordArrayToUint8Array(randomBytes);
const data = Uint8Array.from(encrypt(compressedData, nonce, sharedKey));
return {
nonce,
data
};
}