CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-libsodium-wrappers

The Sodium cryptographic library compiled to pure JavaScript providing comprehensive cryptographic operations including encryption, digital signatures, key exchange, password hashing, and random number generation for web browsers and Node.js environments.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

public-key-encryption.mddocs/

Public-Key Encryption

Public-key encryption enables secure communication between parties without prior key exchange. libsodium-wrappers provides Curve25519-based key exchange with ChaCha20-Poly1305 encryption and anonymous encryption (sealing) capabilities.

Capabilities

Standard Box Encryption

Curve25519-XSalsa20-Poly1305 encryption between two parties with known keys.

/**
 * Generates a new key pair for public-key encryption
 * @returns Object with publicKey, privateKey, and keyType properties
 */
function crypto_box_keypair();

/**
 * Encrypts a message for a recipient
 * @param message - The plaintext message to encrypt
 * @param nonce - 24-byte nonce (must be unique for each message with the same key pair)
 * @param publicKey - Recipient's 32-byte public key  
 * @param privateKey - Sender's 32-byte private key
 * @returns Encrypted ciphertext with authentication tag
 */
function crypto_box_easy(message, nonce, publicKey, privateKey);

/**
 * Decrypts a message
 * @param ciphertext - The encrypted message to decrypt
 * @param nonce - 24-byte nonce used during encryption
 * @param publicKey - Sender's 32-byte public key
 * @param privateKey - Recipient's 32-byte private key
 * @returns Decrypted plaintext message
 * @throws Error if decryption fails or authentication is invalid
 */
function crypto_box_open_easy(ciphertext, nonce, publicKey, privateKey);

/**
 * Generates a deterministic key pair from a seed
 * @param seed - 32-byte seed for key generation
 * @returns Object with publicKey, privateKey, and keyType properties
 */
function crypto_box_seed_keypair(seed);

/**
 * Encrypts a message with detached authentication tag
 * @param message - The plaintext message to encrypt
 * @param nonce - 24-byte nonce
 * @param publicKey - Recipient's 32-byte public key
 * @param privateKey - Sender's 32-byte private key
 * @returns Object with ciphertext and mac properties
 */
function crypto_box_detached(message, nonce, publicKey, privateKey);

/**
 * Decrypts a message with detached authentication tag
 * @param ciphertext - The encrypted message
 * @param mac - The detached authentication tag
 * @param nonce - 24-byte nonce used during encryption
 * @param publicKey - Sender's 32-byte public key
 * @param privateKey - Recipient's 32-byte private key
 * @returns Decrypted plaintext message
 */
function crypto_box_open_detached(ciphertext, mac, nonce, publicKey, privateKey);

Usage Example:

// Generate key pairs for Alice and Bob
const alice = sodium.crypto_box_keypair();
const bob = sodium.crypto_box_keypair();

// Alice encrypts a message for Bob
const message = sodium.from_string("Hello Bob!");
const nonce = sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES);
const ciphertext = sodium.crypto_box_easy(message, nonce, bob.publicKey, alice.privateKey);

// Bob decrypts the message from Alice
const decrypted = sodium.crypto_box_open_easy(ciphertext, nonce, alice.publicKey, bob.privateKey);
console.log(sodium.to_string(decrypted)); // "Hello Bob!"

Optimized Operations with Shared Secret

For multiple messages between the same parties, compute the shared secret once for better performance.

/**
 * Computes a shared secret between two parties
 * @param publicKey - Other party's 32-byte public key
 * @param privateKey - Own 32-byte private key
 * @returns 32-byte shared secret for use with afternm functions
 */
function crypto_box_beforenm(publicKey, privateKey);

/**
 * Encrypts a message using a precomputed shared secret
 * @param message - The plaintext message to encrypt
 * @param nonce - 24-byte nonce
 * @param sharedKey - 32-byte shared secret from crypto_box_beforenm
 * @returns Encrypted ciphertext with authentication tag
 */
function crypto_box_easy_afternm(message, nonce, sharedKey);

/**
 * Decrypts a message using a precomputed shared secret
 * @param ciphertext - The encrypted message to decrypt
 * @param nonce - 24-byte nonce used during encryption
 * @param sharedKey - 32-byte shared secret from crypto_box_beforenm
 * @returns Decrypted plaintext message
 */
function crypto_box_open_easy_afternm(ciphertext, nonce, sharedKey);

Anonymous Encryption (Sealing)

Encrypt messages for a recipient without revealing the sender's identity.

/**
 * Encrypts a message anonymously for a recipient
 * @param message - The plaintext message to encrypt
 * @param publicKey - Recipient's 32-byte public key
 * @returns Encrypted ciphertext (larger than regular box due to ephemeral key)
 */
function crypto_box_seal(message, publicKey);

/**
 * Decrypts an anonymously encrypted message
 * @param ciphertext - The sealed ciphertext to decrypt
 * @param publicKey - Recipient's 32-byte public key
 * @param secretKey - Recipient's 32-byte secret key
 * @returns Decrypted plaintext message
 * @throws Error if decryption fails
 */
function crypto_box_seal_open(ciphertext, publicKey, secretKey);

Usage Example:

// Bob's key pair
const bob = sodium.crypto_box_keypair();

// Anonymous sender encrypts a message for Bob
const message = sodium.from_string("Anonymous message");
const sealedBox = sodium.crypto_box_seal(message, bob.publicKey);

// Bob decrypts the anonymous message
const decrypted = sodium.crypto_box_seal_open(sealedBox, bob.publicKey, bob.privateKey);
console.log(sodium.to_string(decrypted)); // "Anonymous message"

Curve25519-XChaCha20-Poly1305 (Modern Variant)

Modern variant with extended nonces for better security properties.

function crypto_box_curve25519xchacha20poly1305_keypair();
function crypto_box_curve25519xchacha20poly1305_easy(message, nonce, publicKey, privateKey);
function crypto_box_curve25519xchacha20poly1305_open_easy(ciphertext, nonce, publicKey, privateKey);
function crypto_box_curve25519xchacha20poly1305_seal(message, publicKey);
function crypto_box_curve25519xchacha20poly1305_seal_open(ciphertext, publicKey, secretKey);
function crypto_box_curve25519xchacha20poly1305_beforenm(publicKey, privateKey);
function crypto_box_curve25519xchacha20poly1305_easy_afternm(message, nonce, sharedKey);
function crypto_box_curve25519xchacha20poly1305_open_easy_afternm(ciphertext, nonce, sharedKey);
function crypto_box_curve25519xchacha20poly1305_detached(message, nonce, publicKey, privateKey);
function crypto_box_curve25519xchacha20poly1305_open_detached(ciphertext, mac, nonce, publicKey, privateKey);
function crypto_box_curve25519xchacha20poly1305_seed_keypair(seed);

Key Pair Structure

interface KeyPair {
  publicKey: Uint8Array;  // 32 bytes - share with others
  privateKey: Uint8Array; // 32 bytes - keep secret
  keyType: string;        // "x25519" or "curve25519"
}

Constants

// Standard Box
const crypto_box_PUBLICKEYBYTES = 32;
const crypto_box_SECRETKEYBYTES = 32;
const crypto_box_NONCEBYTES = 24;
const crypto_box_MACBYTES = 16;
const crypto_box_SEEDBYTES = 32;
const crypto_box_BEFORENMBYTES = 32;
const crypto_box_SEALBYTES = 48; // Additional bytes for sealed boxes

// Modern Variant
const crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES = 32;
const crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES = 32;
const crypto_box_curve25519xchacha20poly1305_NONCEBYTES = 24;
const crypto_box_curve25519xchacha20poly1305_MACBYTES = 16;
const crypto_box_curve25519xchacha20poly1305_SEEDBYTES = 32;
const crypto_box_curve25519xchacha20poly1305_SEALBYTES = 48;

Security Considerations

  • Nonce Management: Never reuse nonces with the same key pair. Use random nonces or counters.
  • Key Generation: Always use crypto_box_keypair() or crypto_box_seed_keypair() for key generation.
  • Private Key Security: Private keys must be kept secret and securely stored.
  • Public Key Verification: Verify public keys are received from trusted sources to prevent man-in-the-middle attacks.
  • Sealed Boxes: Anonymous encryption provides no sender authentication - use regular boxes when sender identity matters.

docs

advanced-cryptography.md

aead.md

authentication.md

digital-signatures.md

hashing.md

index.md

key-exchange.md

password-hashing.md

public-key-encryption.md

random.md

secret-key-encryption.md

stream-ciphers.md

utilities.md

tile.json