CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-uint8arrays

Utility functions to make dealing with Uint8Arrays easier

Pending
Overview
Eval results
Files

xor-operations.mddocs/

XOR Operations

Bitwise XOR operations and distance comparison functions for cryptographic applications, DHT (Distributed Hash Table) implementations, and Kademlia-style routing. These functions are essential for peer-to-peer networking and cryptographic protocols.

Capabilities

XOR Calculation

Performs bitwise XOR operation on two equal-length Uint8Arrays, returning a new array with the XOR result.

/**
 * Returns the xor distance between two Uint8Arrays
 * @param a - First array for XOR operation
 * @param b - Second array for XOR operation  
 * @returns New Uint8Array containing XOR result
 * @throws Error if arrays have different lengths
 */
function xor(a: Uint8Array, b: Uint8Array): Uint8Array;

Usage Examples:

import { xor } from "uint8arrays/xor";

// Basic XOR operation
const array1 = new Uint8Array([1, 0, 1, 0]);
const array2 = new Uint8Array([0, 1, 1, 1]);
const result = xor(array1, array2);
console.log(result); // Uint8Array(4) [1, 1, 0, 1]

// Cryptographic XOR (one-time pad)
const message = new Uint8Array([72, 101, 108, 108, 111]); // "Hello"
const key = new Uint8Array([31, 42, 17, 5, 89]);
const encrypted = xor(message, key);
const decrypted = xor(encrypted, key); // XOR with same key to decrypt
console.log(decrypted); // [72, 101, 108, 108, 111] - original message

// DHT node distance calculation
const nodeId1 = new Uint8Array([0x12, 0x34, 0x56, 0x78]);
const nodeId2 = new Uint8Array([0x9A, 0xBC, 0xDE, 0xF0]);
const distance = xor(nodeId1, nodeId2);
console.log(distance); // Uint8Array showing XOR distance

// Binary operations
const bits1 = new Uint8Array([0b10101010]);
const bits2 = new Uint8Array([0b11110000]);
const xorBits = xor(bits1, bits2);
console.log(xorBits[0].toString(2)); // "1011010" (binary result)

XOR Distance Comparison

Compares XOR distances for DHT and Kademlia applications. Determines which of two XOR results represents a smaller distance.

/**
 * Compares two Uint8Arrays representing two xor distances. Returns -1 if a
 * is a lower distance, 1 if b is a lower distance or 0 if the distances
 * are equal.
 * @param a - First XOR distance to compare
 * @param b - Second XOR distance to compare
 * @returns -1 if a is closer, 1 if b is closer, 0 if equal
 * @throws Error if arrays have different lengths
 */
function xorCompare(a: Uint8Array, b: Uint8Array): -1 | 0 | 1;

Usage Examples:

import { xor, xorCompare } from "uint8arrays";

// DHT routing example
const target = new Uint8Array([0xFF, 0xFF, 0x00, 0x00]);
const node1 = new Uint8Array([0xFF, 0xFE, 0x01, 0x23]);
const node2 = new Uint8Array([0xFF, 0xFC, 0x45, 0x67]);

// Calculate distances to target
const distance1 = xor(target, node1);
const distance2 = xor(target, node2);

// Compare which node is closer to target
const comparison = xorCompare(distance1, distance2);
console.log(comparison); // -1 (node1 is closer), 1 (node2 is closer), or 0 (equal)

// Kademlia k-bucket sorting
const targetKey = new Uint8Array([0x12, 0x34, 0x56, 0x78]);
const peers = [
  new Uint8Array([0x11, 0x22, 0x33, 0x44]),
  new Uint8Array([0x99, 0xAA, 0xBB, 0xCC]),
  new Uint8Array([0x13, 0x35, 0x57, 0x79])
];

// Sort peers by distance to target
const sortedPeers = peers.sort((a, b) => {
  const distanceA = xor(targetKey, a);
  const distanceB = xor(targetKey, b);
  return xorCompare(distanceA, distanceB);
});

console.log("Peers sorted by distance to target:", sortedPeers);

// Equal distance detection
const equalDist1 = new Uint8Array([0x01, 0x02, 0x03]);
const equalDist2 = new Uint8Array([0x01, 0x02, 0x03]);
console.log(xorCompare(equalDist1, equalDist2)); // 0 (equal distances)

DHT and P2P Applications

Kademlia Routing Table

import { xor, xorCompare } from "uint8arrays";

class KademliaNode {
  constructor(public id: Uint8Array) {}
  
  findClosestPeers(targetId: Uint8Array, peers: Uint8Array[], k: number = 20): Uint8Array[] {
    return peers
      .map(peerId => ({
        id: peerId,
        distance: xor(targetId, peerId)
      }))
      .sort((a, b) => xorCompare(a.distance, b.distance))
      .slice(0, k)
      .map(peer => peer.id);
  }
  
  shouldReplaceInBucket(targetId: Uint8Array, currentPeer: Uint8Array, candidatePeer: Uint8Array): boolean {
    const currentDistance = xor(targetId, currentPeer);
    const candidateDistance = xor(targetId, candidatePeer);
    return xorCompare(candidateDistance, currentDistance) === -1; // candidate is closer
  }
}

Content Addressing

import { xor, xorCompare, fromString } from "uint8arrays";

// Find nodes responsible for storing content
function findStorageNodes(contentHash: string, availableNodes: string[]): string[] {
  const contentId = fromString(contentHash, "hex");
  const nodeDistances = availableNodes.map(nodeIdHex => {
    const nodeId = fromString(nodeIdHex, "hex");
    return {
      nodeId: nodeIdHex,
      distance: xor(contentId, nodeId)
    };
  });
  
  // Sort by XOR distance and take closest nodes
  return nodeDistances
    .sort((a, b) => xorCompare(a.distance, b.distance))
    .slice(0, 3) // Store on 3 closest nodes
    .map(node => node.nodeId);
}

Cryptographic Applications

One-Time Pad Encryption

import { xor, fromString, toString } from "uint8arrays";

function encryptMessage(message: string, key: Uint8Array): Uint8Array {
  const messageBytes = fromString(message, "utf8");
  if (messageBytes.length > key.length) {
    throw new Error("Key must be at least as long as message");
  }
  return xor(messageBytes, key.slice(0, messageBytes.length));
}

function decryptMessage(encrypted: Uint8Array, key: Uint8Array): string {
  const decrypted = xor(encrypted, key.slice(0, encrypted.length));
  return toString(decrypted, "utf8");
}

// Usage
const key = new Uint8Array(256).map(() => Math.floor(Math.random() * 256));
const message = "Secret message";
const encrypted = encryptMessage(message, key);
const decrypted = decryptMessage(encrypted, key);
console.log(decrypted); // "Secret message"

Stream Cipher Operations

import { xor } from "uint8arrays/xor";

function streamCipherXOR(data: Uint8Array, keystream: Uint8Array): Uint8Array {
  if (data.length !== keystream.length) {
    throw new Error("Data and keystream must be same length");
  }
  return xor(data, keystream);
}

// Generate keystream (simplified example)
function generateKeystream(length: number, seed: number): Uint8Array {
  const keystream = new Uint8Array(length);
  let state = seed;
  for (let i = 0; i < length; i++) {
    state = (state * 1103515245 + 12345) & 0x7FFFFFFF;
    keystream[i] = (state >> 16) & 0xFF;
  }
  return keystream;
}

Performance Characteristics

xor()

  • Time Complexity: O(n) where n is array length
  • Space Complexity: O(n) for result array
  • Memory Access: Sequential, cache-friendly
  • Optimization: Uses native bitwise operations

xorCompare()

  • Time Complexity: O(n) worst case, O(1) best case
  • Early Termination: Stops at first differing byte
  • Byte Order: Compares from most significant to least significant byte
  • Deterministic: Always returns consistent ordering

Error Handling

Both functions validate input parameters:

// Length mismatch errors
try {
  xor(new Uint8Array([1, 2]), new Uint8Array([1, 2, 3]));
} catch (error) {
  console.log(error.message); // "Inputs should have the same length"
}

try {
  xorCompare(new Uint8Array([1]), new Uint8Array([1, 2]));
} catch (error) {
  console.log(error.message); // "Inputs should have the same length"  
}

Security Considerations

  • XOR Properties: A ⊕ A = 0, A ⊕ 0 = A, A ⊕ B = B ⊕ A
  • Key Reuse: Never reuse keys in cryptographic XOR operations
  • Perfect Secrecy: XOR with truly random key provides perfect secrecy
  • Distance Metrics: XOR distance satisfies triangle inequality for DHT applications

Install with Tessl CLI

npx tessl i tessl/npm-uint8arrays

docs

array-operations.md

index.md

memory-allocation.md

string-encoding.md

xor-operations.md

tile.json