Low level bindings for libsodium cryptographic library
—
High-performance stream ciphers including ChaCha20, XChaCha20, and Salsa20 for fast symmetric encryption with XOR operations.
High-speed stream cipher suitable for bulk encryption.
/**
* Generate ChaCha20 keystream
* @param c - Output buffer for keystream
* @param n - Nonce buffer (must be NONCEBYTES long)
* @param k - Key buffer (must be KEYBYTES long)
* @throws Error if buffer sizes are incorrect or generation fails
*/
function crypto_stream_chacha20(c: Buffer, n: Buffer, k: Buffer): void;
/**
* Encrypt/decrypt data with ChaCha20 (XOR operation)
* @param c - Output buffer for ciphertext/plaintext (same length as message)
* @param m - Message buffer to encrypt/decrypt
* @param n - Nonce buffer (must be NONCEBYTES long)
* @param k - Key buffer (must be KEYBYTES long)
* @throws Error if buffer sizes are incorrect or operation fails
*/
function crypto_stream_chacha20_xor(c: Buffer, m: Buffer, n: Buffer, k: Buffer): void;
/**
* Encrypt/decrypt with ChaCha20 and initial counter
* @param c - Output buffer for ciphertext/plaintext (same length as message)
* @param m - Message buffer to encrypt/decrypt
* @param n - Nonce buffer (must be NONCEBYTES long)
* @param ic - Initial counter value
* @param k - Key buffer (must be KEYBYTES long)
* @throws Error if buffer sizes are incorrect or operation fails
*/
function crypto_stream_chacha20_xor_ic(c: Buffer, m: Buffer, n: Buffer, ic: number, k: Buffer): void;Usage Example:
const sodium = require('sodium-native');
// ChaCha20 encryption/decryption
const key = Buffer.alloc(sodium.crypto_stream_chacha20_KEYBYTES);
const nonce = Buffer.alloc(sodium.crypto_stream_chacha20_NONCEBYTES);
sodium.randombytes_buf(key);
sodium.randombytes_buf(nonce);
const message = Buffer.from('Hello, ChaCha20!');
const ciphertext = Buffer.alloc(message.length);
const plaintext = Buffer.alloc(message.length);
// Encrypt
sodium.crypto_stream_chacha20_xor(ciphertext, message, nonce, key);
// Decrypt (same operation)
sodium.crypto_stream_chacha20_xor(plaintext, ciphertext, nonce, key);
console.log(plaintext.toString()); // "Hello, ChaCha20!"IETF-standardized variant of ChaCha20 with different nonce size.
/**
* Generate ChaCha20-IETF keystream
* @param c - Output buffer for keystream
* @param n - Nonce buffer (must be NONCEBYTES long)
* @param k - Key buffer (must be KEYBYTES long)
* @throws Error if buffer sizes are incorrect or generation fails
*/
function crypto_stream_chacha20_ietf(c: Buffer, n: Buffer, k: Buffer): void;
/**
* Encrypt/decrypt data with ChaCha20-IETF
* @param c - Output buffer for ciphertext/plaintext (same length as message)
* @param m - Message buffer to encrypt/decrypt
* @param n - Nonce buffer (must be NONCEBYTES long)
* @param k - Key buffer (must be KEYBYTES long)
* @throws Error if buffer sizes are incorrect or operation fails
*/
function crypto_stream_chacha20_ietf_xor(c: Buffer, m: Buffer, n: Buffer, k: Buffer): void;
/**
* Encrypt/decrypt with ChaCha20-IETF and initial counter
* @param c - Output buffer for ciphertext/plaintext (same length as message)
* @param m - Message buffer to encrypt/decrypt
* @param n - Nonce buffer (must be NONCEBYTES long)
* @param ic - Initial counter value
* @param k - Key buffer (must be KEYBYTES long)
* @throws Error if buffer sizes are incorrect or operation fails
*/
function crypto_stream_chacha20_ietf_xor_ic(c: Buffer, m: Buffer, n: Buffer, ic: number, k: Buffer): void;Extended nonce variant of ChaCha20 for better nonce management.
/**
* Generate XChaCha20 keystream
* @param c - Output buffer for keystream
* @param n - Nonce buffer (must be NONCEBYTES long)
* @param k - Key buffer (must be KEYBYTES long)
* @throws Error if buffer sizes are incorrect or generation fails
*/
function crypto_stream_xchacha20(c: Buffer, n: Buffer, k: Buffer): void;
/**
* Encrypt/decrypt data with XChaCha20
* @param c - Output buffer for ciphertext/plaintext (same length as message)
* @param m - Message buffer to encrypt/decrypt
* @param n - Nonce buffer (must be NONCEBYTES long)
* @param k - Key buffer (must be KEYBYTES long)
* @throws Error if buffer sizes are incorrect or operation fails
*/
function crypto_stream_xchacha20_xor(c: Buffer, m: Buffer, n: Buffer, k: Buffer): void;
/**
* Encrypt/decrypt with XChaCha20 and initial counter
* @param c - Output buffer for ciphertext/plaintext (same length as message)
* @param m - Message buffer to encrypt/decrypt
* @param n - Nonce buffer (must be NONCEBYTES long)
* @param ic - Initial counter value
* @param k - Key buffer (must be KEYBYTES long)
* @throws Error if buffer sizes are incorrect or operation fails
*/
function crypto_stream_xchacha20_xor_ic(c: Buffer, m: Buffer, n: Buffer, ic: number, k: Buffer): void;High-performance stream cipher, predecessor to ChaCha20.
/**
* Generate Salsa20 keystream
* @param c - Output buffer for keystream
* @param n - Nonce buffer (must be NONCEBYTES long)
* @param k - Key buffer (must be KEYBYTES long)
* @throws Error if buffer sizes are incorrect or generation fails
*/
function crypto_stream_salsa20(c: Buffer, n: Buffer, k: Buffer): void;
/**
* Encrypt/decrypt data with Salsa20
* @param c - Output buffer for ciphertext/plaintext (same length as message)
* @param m - Message buffer to encrypt/decrypt
* @param n - Nonce buffer (must be NONCEBYTES long)
* @param k - Key buffer (must be KEYBYTES long)
* @throws Error if buffer sizes are incorrect or operation fails
*/
function crypto_stream_salsa20_xor(c: Buffer, m: Buffer, n: Buffer, k: Buffer): void;
/**
* Encrypt/decrypt with Salsa20 and initial counter
* @param c - Output buffer for ciphertext/plaintext (same length as message)
* @param m - Message buffer to encrypt/decrypt
* @param n - Nonce buffer (must be NONCEBYTES long)
* @param ic - Initial counter value
* @param k - Key buffer (must be KEYBYTES long)
* @throws Error if buffer sizes are incorrect or operation fails
*/
function crypto_stream_salsa20_xor_ic(c: Buffer, m: Buffer, n: Buffer, ic: number, k: Buffer): void;Sodium-native specific wrappers for streaming encryption with state management.
/**
* Initialize ChaCha20 streaming encryption state
* @param state - State buffer (must be STATEBYTES long)
* @param n - Nonce buffer (must be NONCEBYTES long)
* @param k - Key buffer (must be KEYBYTES long)
*/
function crypto_stream_chacha20_xor_wrap_init(state: Buffer, n: Buffer, k: Buffer): void;
/**
* Update ChaCha20 streaming encryption with more data
* @param state - State buffer from init
* @param c - Output buffer for ciphertext/plaintext (same length as message)
* @param m - Message buffer to encrypt/decrypt
*/
function crypto_stream_chacha20_xor_wrap_update(state: Buffer, c: Buffer, m: Buffer): void;
/**
* Finalize ChaCha20 streaming encryption
* @param state - State buffer from init/update
*/
function crypto_stream_chacha20_xor_wrap_final(state: Buffer): void;Usage Example:
const sodium = require('sodium-native');
// Streaming encryption for large data
const key = Buffer.alloc(sodium.crypto_stream_chacha20_KEYBYTES);
const nonce = Buffer.alloc(sodium.crypto_stream_chacha20_NONCEBYTES);
sodium.randombytes_buf(key);
sodium.randombytes_buf(nonce);
const state = Buffer.alloc(sodium.crypto_stream_chacha20_xor_STATEBYTES);
sodium.crypto_stream_chacha20_xor_wrap_init(state, nonce, key);
// Process data in chunks
const chunk1 = Buffer.from('First chunk of data');
const chunk2 = Buffer.from('Second chunk of data');
const encrypted1 = Buffer.alloc(chunk1.length);
const encrypted2 = Buffer.alloc(chunk2.length);
sodium.crypto_stream_chacha20_xor_wrap_update(state, encrypted1, chunk1);
sodium.crypto_stream_chacha20_xor_wrap_update(state, encrypted2, chunk2);
sodium.crypto_stream_chacha20_xor_wrap_final(state);// Generic stream cipher constants
const crypto_stream_KEYBYTES: number;
const crypto_stream_NONCEBYTES: number;
// ChaCha20 constants
const crypto_stream_chacha20_KEYBYTES: number;
const crypto_stream_chacha20_NONCEBYTES: number;
const crypto_stream_chacha20_MESSAGEBYTES_MAX: number;
const crypto_stream_chacha20_xor_STATEBYTES: number;
// ChaCha20-IETF constants
const crypto_stream_chacha20_ietf_KEYBYTES: number;
const crypto_stream_chacha20_ietf_NONCEBYTES: number;
const crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX: number;
const crypto_stream_chacha20_ietf_xor_STATEBYTES: number;
// XChaCha20 constants
const crypto_stream_xchacha20_KEYBYTES: number;
const crypto_stream_xchacha20_NONCEBYTES: number;
const crypto_stream_xchacha20_MESSAGEBYTES_MAX: number;
const crypto_stream_xchacha20_xor_STATEBYTES: number;
// Salsa20 constants
const crypto_stream_salsa20_KEYBYTES: number;
const crypto_stream_salsa20_NONCEBYTES: number;
const crypto_stream_salsa20_MESSAGEBYTES_MAX: number;
const crypto_stream_salsa20_xor_STATEBYTES: number;
// Sodium-native specific
const sn_crypto_stream_xor_STATEBYTES: number;const sodium = require('sodium-native');
const fs = require('fs');
class StreamFileEncryption {
constructor(cipher = 'xchacha20') {
this.cipher = cipher;
this.keyBytes = sodium[`crypto_stream_${cipher}_KEYBYTES`];
this.nonceBytes = sodium[`crypto_stream_${cipher}_NONCEBYTES`];
}
encryptFile(inputFile, outputFile, key) {
const nonce = Buffer.alloc(this.nonceBytes);
sodium.randombytes_buf(nonce);
const input = fs.readFileSync(inputFile);
const output = Buffer.alloc(input.length);
sodium[`crypto_stream_${this.cipher}_xor`](output, input, nonce, key);
// Prepend nonce to encrypted data
const encrypted = Buffer.concat([nonce, output]);
fs.writeFileSync(outputFile, encrypted);
}
decryptFile(inputFile, outputFile, key) {
const encrypted = fs.readFileSync(inputFile);
const nonce = encrypted.subarray(0, this.nonceBytes);
const ciphertext = encrypted.subarray(this.nonceBytes);
const output = Buffer.alloc(ciphertext.length);
sodium[`crypto_stream_${this.cipher}_xor`](output, ciphertext, nonce, key);
fs.writeFileSync(outputFile, output);
}
}const sodium = require('sodium-native');
class StreamCipher {
constructor(key, nonce, cipher = 'chacha20') {
this.cipher = cipher;
this.state = Buffer.alloc(sodium[`crypto_stream_${cipher}_xor_STATEBYTES`]);
sodium[`crypto_stream_${cipher}_xor_wrap_init`](this.state, nonce, key);
}
process(data) {
const output = Buffer.alloc(data.length);
sodium[`crypto_stream_${this.cipher}_xor_wrap_update`](this.state, output, data);
return output;
}
finalize() {
sodium[`crypto_stream_${this.cipher}_xor_wrap_final`](this.state);
}
}
// Usage
const key = Buffer.alloc(sodium.crypto_stream_chacha20_KEYBYTES);
const nonce = Buffer.alloc(sodium.crypto_stream_chacha20_NONCEBYTES);
sodium.randombytes_buf(key);
sodium.randombytes_buf(nonce);
const cipher = new StreamCipher(key, nonce);
// Process data in chunks
const encrypted1 = cipher.process(Buffer.from('First chunk'));
const encrypted2 = cipher.process(Buffer.from('Second chunk'));
cipher.finalize();const sodium = require('sodium-native');
function encryptAtPosition(data, key, nonce, position) {
// Calculate initial counter based on position
const blockSize = 64; // ChaCha20 block size
const initialCounter = Math.floor(position / blockSize);
const output = Buffer.alloc(data.length);
sodium.crypto_stream_chacha20_xor_ic(output, data, nonce, initialCounter, key);
return output;
}
// Useful for random access in encrypted files
const key = Buffer.alloc(sodium.crypto_stream_chacha20_KEYBYTES);
const nonce = Buffer.alloc(sodium.crypto_stream_chacha20_NONCEBYTES);
sodium.randombytes_buf(key);
sodium.randombytes_buf(nonce);
// Encrypt data at specific file position
const position = 1024; // Start encryption at byte 1024
const data = Buffer.from('Data to encrypt at position');
const encrypted = encryptAtPosition(data, key, nonce, position);Install with Tessl CLI
npx tessl i tessl/npm-sodium-native