CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-sodium-native

Low level bindings for libsodium cryptographic library

Pending
Overview
Eval results
Files

sign.mddocs/

Digital Signatures

Ed25519 digital signatures for message authentication, integrity verification, and non-repudiation.

Capabilities

Key Pair Generation

Generates a random Ed25519 key pair for digital signatures.

/**
 * Generate random Ed25519 signing 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_sign_keypair(pk: Buffer, sk: Buffer): void;

Seed-based Key Pair Generation

Generates a deterministic Ed25519 key pair from a seed.

/**
 * Generate Ed25519 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_sign_seed_keypair(pk: Buffer, sk: Buffer, seed: Buffer): void;

Usage Example:

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

// Generate signing key pair
const publicKey = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES);
const secretKey = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES);
sodium.crypto_sign_keypair(publicKey, secretKey);

// Or generate from seed for reproducible keys
const seed = Buffer.alloc(sodium.crypto_sign_SEEDBYTES);
sodium.randombytes_buf(seed);
sodium.crypto_sign_seed_keypair(publicKey, secretKey, seed);

Combined Mode Signing

Signs a message and combines it with the signature.

/**
 * Sign message and combine with signature
 * @param sm - Output buffer for signed message (must be m.length + BYTES)
 * @param m - Message buffer to sign
 * @param sk - Secret key buffer (must be SECRETKEYBYTES long)
 * @throws Error if buffer sizes are incorrect or signing fails
 */
function crypto_sign(sm: Buffer, m: Buffer, sk: Buffer): void;

Combined Mode Verification

Verifies a signed message and extracts the original message.

/**
 * Verify signed message and extract original message
 * @param m - Output buffer for original message (must be sm.length - BYTES)
 * @param sm - Signed message buffer to verify
 * @param pk - Public key buffer (must be PUBLICKEYBYTES long)
 * @returns true if verification successful, false if signature invalid
 * @throws Error if buffer sizes are incorrect
 */
function crypto_sign_open(m: Buffer, sm: Buffer, pk: Buffer): boolean;

Usage Example:

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

// Sign a message (combined mode)
const message = Buffer.from('Important message');
const signedMessage = Buffer.alloc(message.length + sodium.crypto_sign_BYTES);
sodium.crypto_sign(signedMessage, message, secretKey);

// Verify and extract message
const extractedMessage = Buffer.alloc(signedMessage.length - sodium.crypto_sign_BYTES);
if (sodium.crypto_sign_open(extractedMessage, signedMessage, publicKey)) {
  console.log('Verified message:', extractedMessage.toString());
} else {
  console.log('Invalid signature');
}

Detached Mode Signing

Creates a signature that is stored separately from the message.

/**
 * Create detached signature for message
 * @param sig - Output buffer for signature (must be BYTES long)
 * @param m - Message buffer to sign
 * @param sk - Secret key buffer (must be SECRETKEYBYTES long)
 * @throws Error if buffer sizes are incorrect or signing fails
 */
function crypto_sign_detached(sig: Buffer, m: Buffer, sk: Buffer): void;

Detached Mode Verification

Verifies a detached signature against a message.

/**
 * Verify detached signature against message
 * @param sig - Signature buffer to verify (must be BYTES long)
 * @param m - Message buffer that was signed
 * @param pk - Public key buffer (must be PUBLICKEYBYTES long)
 * @returns true if signature is valid, false otherwise
 */
function crypto_sign_verify_detached(sig: Buffer, m: Buffer, pk: Buffer): boolean;

Usage Example:

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

// Create detached signature
const message = Buffer.from('Document to sign');
const signature = Buffer.alloc(sodium.crypto_sign_BYTES);
sodium.crypto_sign_detached(signature, message, secretKey);

// Verify detached signature
if (sodium.crypto_sign_verify_detached(signature, message, publicKey)) {
  console.log('Signature is valid');
} else {
  console.log('Invalid signature');
}

Key Conversion Functions

Extract public key from secret key and convert between Ed25519 and Curve25519 keys.

/**
 * Extract public key from Ed25519 secret key
 * @param pk - Output buffer for public key (must be PUBLICKEYBYTES long)
 * @param sk - Secret key buffer (must be SECRETKEYBYTES long)
 * @throws Error if buffer sizes are incorrect or extraction fails
 */
function crypto_sign_ed25519_sk_to_pk(pk: Buffer, sk: Buffer): void;

/**
 * Convert Ed25519 public key to Curve25519 public key
 * @param x25519pk - Output buffer for Curve25519 public key
 * @param ed25519pk - Ed25519 public key to convert
 * @throws Error if conversion fails or buffer sizes incorrect
 */
function crypto_sign_ed25519_pk_to_curve25519(x25519pk: Buffer, ed25519pk: Buffer): void;

/**
 * Convert Ed25519 secret key to Curve25519 secret key
 * @param x25519sk - Output buffer for Curve25519 secret key
 * @param ed25519sk - Ed25519 secret key to convert
 * @throws Error if conversion fails or buffer sizes incorrect
 */
function crypto_sign_ed25519_sk_to_curve25519(x25519sk: Buffer, ed25519sk: Buffer): void;

Usage Example:

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

// Extract public key from secret key
const derivedPublicKey = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES);
sodium.crypto_sign_ed25519_sk_to_pk(derivedPublicKey, secretKey);

// Convert Ed25519 keys to Curve25519 for encryption
const curve25519PublicKey = Buffer.alloc(sodium.crypto_box_PUBLICKEYBYTES);
const curve25519SecretKey = Buffer.alloc(sodium.crypto_box_SECRETKEYBYTES);

sodium.crypto_sign_ed25519_pk_to_curve25519(curve25519PublicKey, publicKey);
sodium.crypto_sign_ed25519_sk_to_curve25519(curve25519SecretKey, secretKey);

Constants

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

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

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

// Signature size in bytes
const crypto_sign_BYTES: number;

Security Considerations

  • Key Security: Keep secret keys secure and use sodium_malloc() for storage.
  • Message Integrity: Signatures provide both authentication and integrity verification.
  • Non-repudiation: Valid signatures prove the signer possessed the secret key.
  • Deterministic: Ed25519 signatures are deterministic - same message and key produce same signature.

Common Patterns

Document Signing Service

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

class DocumentSigner {
  constructor() {
    this.publicKey = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES);
    this.secretKey = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES);
    sodium.crypto_sign_keypair(this.publicKey, this.secretKey);
  }
  
  signDocument(document) {
    const signature = Buffer.alloc(sodium.crypto_sign_BYTES);
    sodium.crypto_sign_detached(signature, document, this.secretKey);
    
    return {
      document: document,
      signature: signature,
      publicKey: this.publicKey
    };
  }
  
  static verifyDocument(signedDoc) {
    return sodium.crypto_sign_verify_detached(
      signedDoc.signature,
      signedDoc.document, 
      signedDoc.publicKey
    );
  }
}

// Usage
const signer = new DocumentSigner();
const document = Buffer.from('Important contract text');
const signed = signer.signDocument(document);

if (DocumentSigner.verifyDocument(signed)) {
  console.log('Document signature is valid');
}

Multi-signature Verification

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

class MultiSigVerifier {
  constructor() {
    this.signers = new Map();
  }
  
  addSigner(name, publicKey) {
    this.signers.set(name, publicKey);
  }
  
  verifySignatures(document, signatures) {
    const results = new Map();
    
    for (const [signerName, signature] of signatures) {
      const publicKey = this.signers.get(signerName);
      if (publicKey) {
        const isValid = sodium.crypto_sign_verify_detached(
          signature, 
          document, 
          publicKey
        );
        results.set(signerName, isValid);
      }
    }
    
    return results;
  }
  
  requireMinimumSignatures(document, signatures, minRequired) {
    const results = this.verifySignatures(document, signatures);
    const validCount = Array.from(results.values()).filter(valid => valid).length;
    return validCount >= minRequired;
  }
}

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