tweetsodium
Version:
libsodium sealed cryptobox using tweetnacl
54 lines (46 loc) • 1.93 kB
JavaScript
;
var tweetSodium = module.exports;
import nacl from 'tweetnacl';
import { blake2bInit, blake2bUpdate, blake2bFinal } from 'blakejs'; // Authenticated sealing only prepends the nonce to the ciphertext. Anonymous
// sealing also prepends a random public key.
tweetSodium.overheadLength = nacl.box.overheadLength + nacl.box.publicKeyLength; // Generates a 24 byte nonce that is a blake2b digest of the ephemeral
// public key and the reipient's public key.
//
// Returns a 24-byte Uint8Array
//
// Parameters:
// - epk - ephemeral public key Uint8Array
// - publicKey - recipient's public key Uint8Array
function sealNonce(epk, publicKey) {
var hash = blake2bInit(nacl.box.nonceLength, false);
blake2bUpdate(hash, epk);
blake2bUpdate(hash, publicKey);
return blake2bFinal(hash);
} // Encrypt a message for a recipient.
//
// Returns a Uint8Array whose length is 48 bytes greater than the message's.
//
// Parameters:
// - message - message Uint8Array to encrypt.
// - publicKey - recipient's public key Uint8Array.
tweetSodium.seal = function (message, publicKey) {
var ekp = nacl.box.keyPair();
var out = new Uint8Array(message.length + tweetSodium.overheadLength);
out.set(ekp.publicKey, 0);
var nonce = sealNonce(ekp.publicKey, publicKey);
var ct = nacl.box(message, nonce, publicKey, ekp.secretKey);
out.set(ct, nacl.box.publicKeyLength);
return out;
}; // Decrypt the ciphertext message using the secret key.
//
// Returns a Uint8Array whose length is 48 bytes less than the ciphertext's.
//
// Parameters:
// - ciphertext - encrypted message Uint8Array.
// - secretKey - secret key Uint8Array.
tweetSodium.sealOpen = function (ciphertext, publicKey, secretKey) {
var epk = ciphertext.slice(0, nacl.box.publicKeyLength);
var nonce = sealNonce(epk, publicKey);
ciphertext = ciphertext.slice(nacl.box.publicKeyLength);
return nacl.box.open(ciphertext, nonce, epk, secretKey);
};