CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-sodium-native

Low level bindings for libsodium cryptographic library

Pending
Overview
Eval results
Files

box.mddocs/

Public Key Encryption

Asymmetric authenticated encryption using Curve25519 elliptic curve cryptography for secure communication between parties with public/private key pairs.

Capabilities

Key Pair Generation

Generates a random Curve25519 key pair for public key encryption.

/**
 * Generate random Curve25519 key pair
 * @param pk - Output buffer for public key (must be PUBLICKEYBYTES long)
 * @param sk - Output buffer for secret key (must be SECRETKEYBYTES long)
 * @throws Error if buffer sizes are incorrect or generation fails
 */
function crypto_box_keypair(pk: Buffer, sk: Buffer): void;

Seed-based Key Pair Generation

Generates a deterministic Curve25519 key pair from a seed.

/**
 * Generate Curve25519 key pair from seed
 * @param pk - Output buffer for public key (must be PUBLICKEYBYTES long)
 * @param sk - Output buffer for secret key (must be SECRETKEYBYTES long)
 * @param seed - Seed buffer (must be SEEDBYTES long)
 * @throws Error if buffer sizes are incorrect or generation fails
 */
function crypto_box_seed_keypair(pk: Buffer, sk: Buffer, seed: Buffer): void;

Usage Example:

const sodium = require('sodium-native');

// Generate Alice's key pair
const alicePk = Buffer.alloc(sodium.crypto_box_PUBLICKEYBYTES);
const aliceSk = Buffer.alloc(sodium.crypto_box_SECRETKEYBYTES);
sodium.crypto_box_keypair(alicePk, aliceSk);

// Generate Bob's key pair  
const bobPk = Buffer.alloc(sodium.crypto_box_PUBLICKEYBYTES);
const bobSk = Buffer.alloc(sodium.crypto_box_SECRETKEYBYTES);
sodium.crypto_box_keypair(bobPk, bobSk);

Easy Mode Encryption

Encrypts a message from sender to recipient using their public key and sender's secret key.

/**
 * Encrypt message using recipient's public key and sender's secret key
 * @param c - Output buffer for ciphertext (must be m.length + MACBYTES)
 * @param m - Message buffer to encrypt
 * @param n - Nonce buffer (must be NONCEBYTES long)
 * @param pk - Recipient's public key (must be PUBLICKEYBYTES long)
 * @param sk - Sender's secret key (must be SECRETKEYBYTES long)
 * @throws Error if buffer sizes are incorrect or encryption fails
 */
function crypto_box_easy(c: Buffer, m: Buffer, n: Buffer, pk: Buffer, sk: Buffer): void;

Easy Mode Decryption

Decrypts and verifies a message using recipient's secret key and sender's public key.

/**
 * Decrypt and verify message using recipient's secret key and sender's public key
 * @param m - Output buffer for plaintext (must be c.length - MACBYTES)
 * @param c - Ciphertext buffer to decrypt
 * @param n - Nonce buffer (must be NONCEBYTES long)
 * @param pk - Sender's public key (must be PUBLICKEYBYTES long)
 * @param sk - Recipient's secret key (must be SECRETKEYBYTES long)
 * @returns true if decryption successful, false if verification fails
 * @throws Error if buffer sizes are incorrect
 */
function crypto_box_open_easy(m: Buffer, c: Buffer, n: Buffer, pk: Buffer, sk: Buffer): boolean;

Usage Example:

const sodium = require('sodium-native');

// Alice wants to send a message to Bob
const message = Buffer.from('Hello Bob!');
const nonce = Buffer.alloc(sodium.crypto_box_NONCEBYTES);
sodium.randombytes_buf(nonce);

// Alice encrypts using Bob's public key and her secret key
const ciphertext = Buffer.alloc(message.length + sodium.crypto_box_MACBYTES);
sodium.crypto_box_easy(ciphertext, message, nonce, bobPk, aliceSk);

// Bob decrypts using Alice's public key and his secret key
const plaintext = Buffer.alloc(ciphertext.length - sodium.crypto_box_MACBYTES);
if (sodium.crypto_box_open_easy(plaintext, ciphertext, nonce, alicePk, bobSk)) {
  console.log('Bob received:', plaintext.toString());
}

Detached Mode Encryption

Encrypts a message with the authentication tag stored separately.

/**
 * Encrypt message with detached authentication tag
 * @param c - Output buffer for ciphertext (must be same length as message)
 * @param mac - Output buffer for authentication tag (must be MACBYTES long)
 * @param m - Message buffer to encrypt
 * @param n - Nonce buffer (must be NONCEBYTES long)
 * @param pk - Recipient's public key (must be PUBLICKEYBYTES long)
 * @param sk - Sender's secret key (must be SECRETKEYBYTES long)
 * @throws Error if buffer sizes are incorrect or encryption fails
 */
function crypto_box_detached(c: Buffer, mac: Buffer, m: Buffer, n: Buffer, pk: Buffer, sk: Buffer): void;

Detached Mode Decryption

Decrypts a message using a separate authentication tag.

/**
 * Decrypt message with detached authentication tag
 * @param m - Output buffer for plaintext (must be same length as ciphertext)
 * @param c - Ciphertext buffer to decrypt
 * @param mac - Authentication tag buffer (must be MACBYTES long)
 * @param n - Nonce buffer (must be NONCEBYTES long)
 * @param pk - Sender's public key (must be PUBLICKEYBYTES long)
 * @param sk - Recipient's secret key (must be SECRETKEYBYTES long)
 * @returns true if decryption successful, false if verification fails
 * @throws Error if buffer sizes are incorrect
 */
function crypto_box_open_detached(m: Buffer, c: Buffer, mac: Buffer, n: Buffer, pk: Buffer, sk: Buffer): boolean;

Anonymous Encryption (Sealed Box)

Encrypts a message to a recipient using only their public key (anonymous sender).

/**
 * Encrypt message anonymously using only recipient's public key
 * @param c - Output buffer for sealed ciphertext (must be m.length + SEALBYTES)
 * @param m - Message buffer to encrypt
 * @param pk - Recipient's public key (must be PUBLICKEYBYTES long)
 * @throws Error if buffer sizes are incorrect or encryption fails
 */
function crypto_box_seal(c: Buffer, m: Buffer, pk: Buffer): void;

Anonymous Decryption (Sealed Box)

Decrypts an anonymously encrypted message using the recipient's key pair.

/**
 * Decrypt anonymously encrypted message
 * @param m - Output buffer for plaintext (must be c.length - SEALBYTES)
 * @param c - Sealed ciphertext buffer to decrypt
 * @param pk - Recipient's public key (must be PUBLICKEYBYTES long)
 * @param sk - Recipient's secret key (must be SECRETKEYBYTES long)
 * @returns true if decryption successful, false if verification fails
 */
function crypto_box_seal_open(m: Buffer, c: Buffer, pk: Buffer, sk: Buffer): boolean;

Usage Example:

const sodium = require('sodium-native');

// Anonymous encryption to Bob
const message = Buffer.from('Anonymous message');
const sealedBox = Buffer.alloc(message.length + sodium.crypto_box_SEALBYTES);
sodium.crypto_box_seal(sealedBox, message, bobPk);

// Bob can decrypt without knowing sender
const plaintext = Buffer.alloc(sealedBox.length - sodium.crypto_box_SEALBYTES);
if (sodium.crypto_box_seal_open(plaintext, sealedBox, bobPk, bobSk)) {
  console.log('Anonymous message:', plaintext.toString());
}

Constants

// Seed size for deterministic key generation
const crypto_box_SEEDBYTES: number;

// Public key size in bytes
const crypto_box_PUBLICKEYBYTES: number;

// Secret key size in bytes  
const crypto_box_SECRETKEYBYTES: number;

// Nonce size in bytes
const crypto_box_NONCEBYTES: number;

// Authentication tag size in bytes
const crypto_box_MACBYTES: number;

// Additional bytes for sealed box encryption
const crypto_box_SEALBYTES: number;

Security Considerations

  • Key Reuse: Public keys can be safely reused, but each message must use a unique nonce.
  • Nonce Management: Never reuse nonces between the same key pairs.
  • Sealed Boxes: Provide anonymity but prevent reply without additional key exchange.
  • Forward Secrecy: Consider ephemeral key pairs for forward secrecy in long-term communications.

Common Patterns

Secure Messaging

const sodium = require('sodium-native');

class SecureMessaging {
  constructor() {
    this.publicKey = Buffer.alloc(sodium.crypto_box_PUBLICKEYBYTES);
    this.secretKey = Buffer.alloc(sodium.crypto_box_SECRETKEYBYTES);
    sodium.crypto_box_keypair(this.publicKey, this.secretKey);
  }
  
  encryptTo(message, recipientPublicKey) {
    const nonce = Buffer.alloc(sodium.crypto_box_NONCEBYTES);
    sodium.randombytes_buf(nonce);
    
    const ciphertext = Buffer.alloc(message.length + sodium.crypto_box_MACBYTES);
    sodium.crypto_box_easy(ciphertext, message, nonce, recipientPublicKey, this.secretKey);
    
    return { ciphertext, nonce };
  }
  
  decryptFrom(ciphertext, nonce, senderPublicKey) {
    const plaintext = Buffer.alloc(ciphertext.length - sodium.crypto_box_MACBYTES);
    if (sodium.crypto_box_open_easy(plaintext, ciphertext, nonce, senderPublicKey, this.secretKey)) {
      return plaintext;
    }
    return null;
  }
  
  encryptAnonymous(message, recipientPublicKey) {
    const sealedBox = Buffer.alloc(message.length + sodium.crypto_box_SEALBYTES);
    sodium.crypto_box_seal(sealedBox, message, recipientPublicKey);
    return sealedBox;
  }
  
  decryptAnonymous(sealedBox) {
    const plaintext = Buffer.alloc(sealedBox.length - sodium.crypto_box_SEALBYTES);
    if (sodium.crypto_box_seal_open(plaintext, sealedBox, this.publicKey, this.secretKey)) {
      return plaintext;
    }
    return null;
  }
}

Install with Tessl CLI

npx tessl i tessl/npm-sodium-native

docs

aead.md

auth.md

box.md

ed25519.md

hash.md

index.md

kdf.md

kx.md

memory.md

pwhash.md

random.md

secretbox.md

secretstream.md

shorthash.md

sign.md

stream.md

tile.json