or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

core-bitcoin.mdcryptography.mdencryption.mdhd-wallets.mdindex.mdtransaction-building.mdutilities.md
tile.json

cryptography.mddocs/

Cryptography

Low-level cryptographic operations for digital signatures, hashing, and key management.

Imports

// ES6 imports
import { Hash, ECDSA, Sig, KeyPair, Point, Random } from 'bsv'

// CommonJS imports  
const { Hash, ECDSA, Sig, KeyPair, Point, Random } = require('bsv')

Hash Functions

Comprehensive cryptographic hash functions used throughout Bitcoin protocols.

Class Definition

class Hash {
  // SHA family hash functions
  static sha1(buf: Buffer): Buffer
  static sha256(buf: Buffer): Buffer
  static sha256Sha256(buf: Buffer): Buffer    // Double SHA-256 (Bitcoin standard)
  static sha512(buf: Buffer): Buffer

  // RIPEMD hash functions
  static ripemd160(buf: Buffer): Buffer
  static sha256Ripemd160(buf: Buffer): Buffer // SHA-256 + RIPEMD-160 (address hash)

  // HMAC functions
  static hmac(
    hashFStr: string,       // Hash function name ('sha1', 'sha256', 'sha512')
    data: Buffer,          // Data to authenticate
    key: Buffer            // HMAC key
  ): Buffer

  static sha1Hmac(data: Buffer, key: Buffer): Buffer
  static sha256Hmac(data: Buffer, key: Buffer): Buffer
  static sha512Hmac(data: Buffer, key: Buffer): Buffer

  // Async variants for non-blocking computation
  static asyncSha1(buf: Buffer): Promise<Buffer>
  static asyncSha256(buf: Buffer): Promise<Buffer>
  static asyncSha256Sha256(buf: Buffer): Promise<Buffer>
  static asyncSha512(buf: Buffer): Promise<Buffer>
  static asyncRipemd160(buf: Buffer): Promise<Buffer>
  static asyncSha256Ripemd160(buf: Buffer): Promise<Buffer>

  // Block size constants
  static sha1.blockSize: number     // 512 bits
  static sha256.blockSize: number   // 512 bits  
  static sha512.blockSize: number   // 1024 bits
}

Usage Examples

// Standard hash functions
const data = Buffer.from('Hello, BSV!', 'utf8')

// SHA-256 (most common in Bitcoin)
const sha256Hash = Hash.sha256(data)

// Double SHA-256 (Bitcoin block and transaction hashes)
const doubleHash = Hash.sha256Sha256(data)

// Bitcoin address hash (SHA-256 + RIPEMD-160)
const pubKeyBuf = pubKey.toBuffer()
const addressHash = Hash.sha256Ripemd160(pubKeyBuf)

// RIPEMD-160 (used in Bitcoin addresses)
const ripemd = Hash.ripemd160(data)

// HMAC authentication
const key = Buffer.from('secret-key', 'utf8')
const hmac = Hash.sha256Hmac(data, key)

// Async operations for large data
const hash = await Hash.asyncSha256(largeBuffer)
const doubleHash = await Hash.asyncSha256Sha256(largeBuffer)

// Block size information
console.log('SHA-256 block size:', Hash.sha256.blockSize) // 512

ECDSA (Elliptic Curve Digital Signature Algorithm)

Digital signature creation and verification using secp256k1 elliptic curve.

Class Definition

class Ecdsa {
  constructor(
    sig?: Sig,              // Signature object
    keyPair?: KeyPair,      // Key pair for signing/verification  
    hashBuf?: Buffer,       // Hash to sign/verify
    k?: Bn,                // Nonce value (should be random)
    endian?: string,        // Byte order ('big' or 'little')
    verified?: boolean      // Verification result cache
  )

  // Core properties
  sig: Sig                // Signature
  keyPair: KeyPair       // Key pair
  hashBuf: Buffer        // Message hash
  k: Bn                  // Nonce
  endian: string         // Byte order
  verified: boolean      // Verification result

  // Signing operations
  sign(): Ecdsa          // Create signature
  randomK(): Ecdsa       // Generate random nonce
  deterministicK(badrs?: Bn[]): Ecdsa  // Generate deterministic nonce (RFC 6979)

  // Verification operations  
  verify(enforceLowS?: boolean): Ecdsa  // Verify signature
  
  // Public key recovery
  calcrecovery(): Ecdsa  // Calculate recovery parameter
  sig2PubKey(): PubKey   // Recover public key from signature

  // Static methods for direct operations
  static sign(
    hashBuf: Buffer,
    keyPair: KeyPair,
    endian?: string
  ): Sig

  static verify(
    hashBuf: Buffer,
    sig: Sig, 
    pubKey: PubKey,
    endian?: string,
    enforceLowS?: boolean
  ): boolean

  static calcrecovery(
    sig: Sig,
    pubKey: PubKey,  
    hashBuf: Buffer
  ): number

  // Async variants
  asyncSign(): Promise<Ecdsa>
  asyncVerify(enforceLowS?: boolean): Promise<Ecdsa>
  asyncCalcrecovery(): Promise<Ecdsa>
  asyncSig2PubKey(): Promise<PubKey>
}

Usage Examples

// Create ECDSA signature
const keyPair = KeyPair.fromPrivKey(privKey)
const hashBuf = Hash.sha256(messageBuf)

// Method 1: Using static methods (recommended)
const sig = Ecdsa.sign(hashBuf, keyPair)
const isValid = Ecdsa.verify(hashBuf, sig, pubKey)

// Method 2: Using instance methods
const ecdsa = new Ecdsa()
ecdsa.hashBuf = hashBuf
ecdsa.keyPair = keyPair
ecdsa.randomK()  // Generate random nonce
ecdsa.sign()
const signature = ecdsa.sig

// Verify signature
const ecdsa2 = new Ecdsa()
ecdsa2.hashBuf = hashBuf
ecdsa2.sig = signature
ecdsa2.keyPair = KeyPair.fromPubKey(pubKey)
ecdsa2.verify()
console.log('Valid:', ecdsa2.verified)

// Deterministic nonce generation (RFC 6979)
ecdsa.deterministicK()
ecdsa.sign()

// Public key recovery
const recoveredPubKey = ecdsa.sig2PubKey()

// Recovery parameter calculation
const recoveryParam = Ecdsa.calcrecovery(sig, pubKey, hashBuf)

// Async operations
const sig = await ecdsa.asyncSign()
const isValid = await ecdsa.asyncVerify(true) // Enforce low-S

Signature (Sig)

Digital signature representation with multiple encoding formats.

Class Definition

class Sig {
  constructor(
    r?: Bn,                 // R component
    s?: Bn,                 // S component
    nHashType?: number,     // Hash type for transactions
    recovery?: number,      // Public key recovery value
    compressed?: boolean    // Whether pubkey is compressed
  )

  // Core properties
  r: Bn                   // R component
  s: Bn                   // S component
  nHashType: number       // Hash type
  recovery: number        // Recovery parameter
  compressed: boolean     // Pubkey compression flag

  // Creation methods
  static fromDer(buf: Buffer, strict?: boolean): Sig
  static fromTxFormat(buf: Buffer): Sig      // DER + nHashType
  static fromCompact(buf: Buffer): Sig       // Recovery format
  static fromProperties(obj: object): Sig

  // Serialization methods
  toDer(): Buffer                           // DER encoding
  toTxFormat(): Buffer                      // Transaction format
  toCompact(): Buffer                       // Compact format with recovery
  
  // Validation
  hasLowS(): boolean                        // Check BIP 62 low-S constraint
  static IsTxDer(buf: Buffer): boolean      // Check transaction DER format

  // Hash type constants
  static SIGHASH_ALL: number               // Sign all inputs and outputs
  static SIGHASH_NONE: number              // Sign all inputs, no outputs
  static SIGHASH_SINGLE: number            // Sign all inputs, one output
  static SIGHASH_ANYONECANPAY: number      // Modifier: sign only this input
  static SIGHASH_FORKID: number            // Bitcoin SV fork ID
}

Usage Examples

// Create signature from components
const r = Bn.fromHex('...')
const s = Bn.fromHex('...')
const sig = new Sig(r, s, Sig.SIGHASH_ALL)

// Parse DER format signature
const derBuf = Buffer.from('30440220...', 'hex')
const sig = Sig.fromDer(derBuf)

// Transaction format (DER + hash type)
const txSig = Sig.fromTxFormat(txSigBuf)
console.log('Hash type:', txSig.nHashType)

// Compact format with recovery
const compactSig = Sig.fromCompact(compactBuf)
console.log('Recovery param:', compactSig.recovery)

// Serialization
const derBuf = sig.toDer()
const txFormatBuf = sig.toTxFormat()  
const compactBuf = sig.toCompact()

// BIP 62 low-S validation
const hasLowS = sig.hasLowS()
if (!hasLowS) {
  // Convert to low-S if needed
  sig.s = sig.s.neg().mod(Point.getN())
}

// Hash type usage
const allSig = new Sig(r, s, Sig.SIGHASH_ALL)
const noneSig = new Sig(r, s, Sig.SIGHASH_NONE) 
const singleSig = new Sig(r, s, Sig.SIGHASH_SINGLE)
const anyoneCanPay = new Sig(r, s, Sig.SIGHASH_ALL | Sig.SIGHASH_ANYONECANPAY)

// Bitcoin SV signatures include FORKID
const bsvSig = new Sig(r, s, Sig.SIGHASH_ALL | Sig.SIGHASH_FORKID)

KeyPair

Public/private key pair management for cryptographic operations.

Class Definition

class KeyPair {
  constructor(
    privKey?: PrivKey,      // Private key
    pubKey?: PubKey         // Public key
  )

  // Core properties
  privKey: PrivKey        // Private key component
  pubKey: PubKey          // Public key component

  // Creation methods
  static fromRandom(): KeyPair
  static fromPrivKey(privKey: PrivKey): KeyPair
  static fromString(str: string): KeyPair
  static fromJSON(json: object): KeyPair

  // Serialization methods
  toString(): string
  toJSON(): object

  // Network variants
  static Mainnet: typeof KeyPair
  static Testnet: typeof KeyPair
}

Usage Examples

// Generate random key pair
const keyPair = KeyPair.fromRandom()
console.log('Private key WIF:', keyPair.privKey.toWif())
console.log('Public key hex:', keyPair.pubKey.toHex())

// Create from existing private key
const privKey = PrivKey.fromWif('L1aW4aubDFB7yfras2S1mN3bqg9nwySY8nkoLmJebSLD5BWv3ENZ')
const keyPair = KeyPair.fromPrivKey(privKey)

// Network-specific key pairs
const mainnetPair = KeyPair.Mainnet.fromRandom()
const testnetPair = KeyPair.Testnet.fromRandom()

// Use for signing
const message = Buffer.from('Hello, BSV!', 'utf8')
const hashBuf = Hash.sha256(message)
const sig = Ecdsa.sign(hashBuf, keyPair)

// Serialization
const keyPairStr = keyPair.toString()
const keyPair2 = KeyPair.fromString(keyPairStr)

Point (Elliptic Curve Points)

Elliptic curve point operations for secp256k1 curve.

Class Definition

class Point {
  constructor(
    x?: Bn,                 // X coordinate
    y?: Bn                  // Y coordinate  
  )

  // Core properties
  x: Bn                   // X coordinate
  y: Bn                   // Y coordinate

  // Creation methods
  static fromX(odd: boolean, x: Bn): Point
  static getG(): Point             // Get generator point
  static getN(): Bn               // Get curve order

  // Coordinate access
  getX(): Bn              // Get X coordinate
  getY(): Bn              // Get Y coordinate

  // Point operations
  add(p: Point): Point    // Point addition
  mul(d: Bn): Point      // Scalar multiplication

  // Validation
  validate(): Point       // Validate point is on curve
  isValid(): boolean
}

Usage Examples

// Get secp256k1 generator point
const G = Point.getG()
const n = Point.getN() // Curve order

// Create point from coordinates
const x = Bn.fromHex('...')
const y = Bn.fromHex('...')
const point = new Point(x, y)

// Create from X coordinate (compressed format)
const point = Point.fromX(true, x) // odd=true

// Point operations
const privKeyBn = Bn.fromRandom()
const pubKeyPoint = G.mul(privKeyBn) // Public key = privKey * G

// Point addition
const sum = point1.add(point2)

// Validation
const isValid = point.isValid()
point.validate() // Throws if invalid

// Use with PubKey
const pubKey = new PubKey(pubKeyPoint, true) // compressed=true

Random Number Generation

Cryptographically secure random number generation for keys and nonces.

Class Definition

class Random {
  // Generate cryptographically secure random bytes
  static getRandomBuffer(size: number): Buffer
}

Usage Examples

// Generate random bytes for keys
const randomBytes = Random.getRandomBuffer(32) // 256 bits
const privKey = PrivKey.fromBn(Bn.fromBuffer(randomBytes))

// Generate random nonces
const nonce = Random.getRandomBuffer(32)
const k = Bn.fromBuffer(nonce)

// Random initialization vectors
const iv = Random.getRandomBuffer(16) // 128 bits for AES

// Random salts
const salt = Random.getRandomBuffer(16)

Advanced Cryptographic Operations

Message Signing and Verification

// Complete message signing workflow
const message = 'Hello, BSV blockchain!'
const messageBuf = Buffer.from(message, 'utf8')

// Create message hash (Bitcoin message signing uses double SHA-256)
const hashBuf = Hash.sha256Sha256(messageBuf)

// Sign with private key
const keyPair = KeyPair.fromPrivKey(privKey)
const sig = Ecdsa.sign(hashBuf, keyPair)

// Verify signature
const pubKey = PubKey.fromPrivKey(privKey)
const isValid = Ecdsa.verify(hashBuf, sig, pubKey, 'big', true)
console.log('Signature valid:', isValid)

// Recover public key from signature
const ecdsa = new Ecdsa(sig, null, hashBuf)
const recoveredPubKey = ecdsa.sig2PubKey()

Deterministic Signatures (RFC 6979)

// Create deterministic signature (same message + key = same signature)
const ecdsa = new Ecdsa()
ecdsa.hashBuf = hashBuf
ecdsa.keyPair = keyPair
ecdsa.deterministicK() // Generate deterministic nonce
ecdsa.sign()

const sig1 = ecdsa.sig
// Signing again will produce identical signature
ecdsa.deterministicK()
ecdsa.sign()
const sig2 = ecdsa.sig
// sig1 equals sig2

Low-Level Hash Operations

// HMAC-based key derivation
const password = Buffer.from('password', 'utf8')
const salt = Random.getRandomBuffer(16)
const iterations = 10000

// PBKDF2 (available via deps)
const derivedKey = bsv.deps.pbkdf2(password, salt, iterations, 32, 'sha256')

// Custom HMAC operations
const key = derivedKey.slice(0, 16)
const data = Buffer.from('authenticate this', 'utf8')
const hmac = Hash.sha256Hmac(data, key)

Error Handling

Cryptographic operations include comprehensive validation:

// Hash validation
try {
  const hash = Hash.sha256(null) // Will throw
} catch (error) {
  console.error('Hash error:', error.message)
}

// Signature validation
try {
  const sig = Sig.fromDer(invalidBuffer)
} catch (error) {
  console.error('Invalid signature format:', error.message)
}

// Point validation
try {
  const point = new Point(invalidX, invalidY)
  point.validate() // Will throw if not on curve
} catch (error) {
  console.error('Invalid curve point:', error.message)
}

// ECDSA verification
try {
  const ecdsa = new Ecdsa()
  ecdsa.verify() // May throw on invalid signature
} catch (error) {
  console.error('Signature verification failed:', error.message)
}