Skip to content

Latest commit

 

History

186 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bsvz

bsvz

BSV foundation library for Zig.

Table of Contents

Status

Crypto, keys, script, transactions, SPV, BEEF, and broadcast. 27 BRC standards covered.

Details

Implemented:

  • primitives: hex, varint, base58, base58check, network/version-byte helpers, chainhash (display-order hash type), EC curve wrapper with ECDH and Type-42 key derivation, ECDSA signatures with low-S normalization, Schnorr proofs, AES-CBC, AES-GCM, symmetric key encryption, Shamir secret sharing (key shares, backup format), HMAC-DRBG, BIP32 HD keys (xpriv/xpub, child derivation), BIP39 mnemonics (English wordlist, PBKDF2 seed), BRC-43 invoice strings
  • crypto: sha256, sha512, hash256, ripemd160, hash160, hmacSha256, hmacSha512, secp256k1 private/public keys, secp256k1 point API, DER signatures, compact signatures with recovery, ECIES (Electrum + Bitcore), tx-signature helpers
  • compat: P2PKH address, WIF encode/decode, Bitcoin Signed Message (sign/verify/recover), ECIES
  • transaction: parse/serialize (standard + extended format), txid, sighash/preimage, P2PKH spend helpers, BEEF V1/V2/Atomic, transaction builder (addInput/addOutput/payToAddress/sign), fee calculation with pluggable models, change distribution
  • script: ScriptNum, parser/chunks, full modern BSV opcode surface plus legacy/reference semantics, execution engine, transaction-aware CHECKSIG/CHECKMULTISIG, configurable policy enforcement, ASM encode/decode, script builder (appendPushData/appendOpcodes), type detection (isP2PKH/isP2PK/isData/isMultiSigOut), templates (P2PKH, OP_RETURN, PushDrop, R-puzzle, OP_TRUE, Push TX), script clone/ownership
  • spv: MerklePath parse/serialize/computeRoot/combine/verify, MerkleTreeParent, ancestor traversal, BEEF verification, pluggable chain tracker interface
  • message: BRC-77 signed messages (sign/verify) and BRC-78 encrypted messages (encrypt/decrypt)
  • broadcast: WhatsOnChain, TAAL, and Arc HTTP broadcast clients

Script interpreter test corpus:

  • 1,499 test vectors from the BSV script corpus
  • 1,435 executable rows passing
  • 64 rows tracked as meta/non-executable

Getting Started

Requirements: Zig 0.15.2

Fetch the dependency:

zig fetch --save git+https://github.com/b-open-io/bsvz.git

Then expose the module in your build.zig:

const bsvz = b.dependency("bsvz", .{ .target = target, .optimize = optimize });
exe.root_module.addImport("bsvz", bsvz.module("bsvz"));

Module Layout

Module Description
bsvz.primitives Hex, varint, base58, base58check, version-byte helpers
bsvz.primitives.chainhash Display-order (reverse hex) hash type, single/double hash helpers
bsvz.primitives.ec EC curve wrapper, PrivateKey, PublicKey, key generation, ECDH, Type-42 derivation
bsvz.primitives.ecdsa ECDSA signature type with DER encoding and low-S normalization
bsvz.primitives.schnorr Schnorr DLEQ proof generation and verification
bsvz.primitives.keyshares Shamir secret sharing: polynomial, key shares, backup format
bsvz.primitives.aescbc AES-CBC encrypt/decrypt with PKCS7 padding (128/256-bit keys)
bsvz.primitives.aesgcm AES-GCM encrypt/decrypt with authentication tags (128/256-bit keys)
bsvz.primitives.symmetric Symmetric key wrapper with encrypt/decrypt
bsvz.primitives.drbg HMAC-DRBG deterministic random bit generator
bsvz.primitives.bip32 HD key derivation: ExtendedKey, xpriv/xpub, child paths, mainnet/testnet, masterFromMnemonic
bsvz.primitives.bip39 Mnemonic generation, English wordlist, entropy, PBKDF2 seed derivation
bsvz.primitives.brc43 BRC-43 protocol ID normalization and <level>-<protocol>-<key> invoice strings
bsvz.crypto SHA256, SHA512, RIPEMD160, HASH160, HASH256, HMAC-SHA256, HMAC-SHA512, secp256k1 keys and point API, DER and compact signatures, ECIES
bsvz.script Script parser, opcode set, execution engine, policy flags, ASM encode/decode, script builder, type detection
bsvz.transaction Parse, serialize (standard + extended format), sighash, P2PKH spend helpers
bsvz.transaction.builder Transaction builder: addInput, addOutput, payToAddress, sign, applyFee
bsvz.transaction.beef BEEF V1/V2/Atomic parse, serialize, and transaction extraction
bsvz.transaction.fees Fee calculation, change distribution, total input/output satoshis
bsvz.transaction.fee_model Pluggable fee models (satoshis-per-kilobyte)
bsvz.message BRC-77 portable signed messages (signed); BRC-78 portable encrypted messages (encrypted)
bsvz.compat P2PKH address, WIF encode/decode, Bitcoin Signed Message, ECIES
bsvz.spv MerklePath, MerkleTreeParent, BlockHeader, SPV and BEEF verification
bsvz.broadcast WhatsOnChain, TAAL, Arc HTTP broadcast clients

Documentation

Standards Coverage

27 BRC standards covered — full spec index at bsv.brc.dev
Standard Title Module
BRC‑2 Data Encryption and Decryption primitives.aescbc, primitives.aesgcm, primitives.symmetric
BRC‑3 Digital Signature Creation and Verification primitives.ec, primitives.ecdsa, crypto.secp256k1
BRC‑8 Everett-style Transaction Envelopes transaction
BRC‑9 Simplified Payment Verification spv.verify, spv.verifyBeef
BRC‑12 Raw Transaction Format transaction
BRC‑14 Script Binary, Hex, and ASM Formats script, script.asm
BRC‑16 Pay to Public Key Hash script.templates.p2pkh, compat.address
BRC‑17 Pay to R Puzzle Hash script.templates.r_puzzle
BRC‑18 Pay to False Return script.templates.op_return
BRC‑19 Pay to True Return script.templates.op_true
BRC‑30 Transaction Extended Format (EF) transaction
BRC‑32 BIP32 Key Derivation primitives.bip32
BRC‑36 Format for Bitcoin Outpoints transaction.OutPoint
BRC‑42 BSV Key Derivation Scheme (Type‑42) primitives.ec (deriveChild, deriveSharedSecret)
BRC‑43 Security Levels, Protocol IDs, Key IDs primitives.brc43, primitives.ec (deriveChild)
BRC‑47 Bare Multi-Signature script
BRC‑48 Pay to Push Drop script.templates.pushdrop
BRC‑61 Compound Merkle Path Format spv.MerklePath
BRC‑62 BEEF Transactions transaction.beef
BRC‑67 Simplified Payment Verification spv
BRC‑74 BSV Unified Merkle Path (BUMP) spv.MerklePath
BRC‑75 Mnemonic for Master Private Key primitives.bip39
BRC‑77 Message Signature Creation and Verification message.signed (portable wire); legacy BSM: compat.bsm, crypto.compact
BRC‑78 Portable Encrypted Messages message.encrypted (BRC-78 wire); Electrum/Bitcore ECIES: crypto.ecies, compat.ecies
BRC‑94 Schnorr Shared Secret Revelation primitives.schnorr
BRC‑95 Atomic BEEF Transactions transaction.beef
BRC‑96 BEEF V2 Txid Only Extension transaction.beef

Script Verification APIs

The verification surface covers plain script pairs, full prevout spends, detailed results, and step traces.

API reference and examples

Entry points

Function Description
bsvz.script.thread.verifyScripts(...) Verify a plain unlocking/locking script pair
bsvz.script.thread.ScriptThread.verifyPair(...) Same, on a reusable thread
bsvz.script.thread.verifyExecutableScripts(...) Verify an executable/full-locking-script pair
bsvz.script.thread.verifyPrevoutSpend(...) Verify a spend against a previous output
bsvz.script.thread.verifyPrevoutSpendDetailed(...) Same, with structured result
bsvz.script.thread.verifyPrevoutSpendTraced(...) Same, with step trace
bsvz.script.interpreter.verify(...) Small wrapper for simple verification
bsvz.script.interpreter.verifyPrevout(...) Small wrapper for prevout verification
bsvz.script.interpreter.verifyDetailed(...) Detailed result variant
bsvz.script.interpreter.verifyTraced(...) Traced variant

Return shapes:

  • true / false: script evaluated cleanly, result is the final truthiness
  • error.*: policy, parsing, encoding, or transaction-context failure; result.terminal gives .success, .false_result, or .script_error

Detailed result fields: result.phase, result.script_error

Trace step fields: phase, opcode offset, opcode byte, pre-step stack/altstack/condition-stack snapshots, ops_executed, last_code_separator

Both VerificationResult and traced results have writeDebug(...) helpers.

Minimal pair verification

var thread = bsvz.script.thread.ScriptThread.init(.{ .allocator = allocator });
defer thread.deinit();

const ok = try thread.verifyPair(
    bsvz.script.Script.init(unlocking_bytes),
    bsvz.script.Script.init(locking_bytes),
);

Prevout spend verification

const previous_output = previous_tx.outputs[previous_output_index];

var result = bsvz.script.interpreter.verifyPrevoutDetailed(.{
    .allocator = allocator,
    .tx = &spend_tx,
    .input_index = spend_input_index,
    .previous_output = previous_output,
    .unlocking_script = spend_tx.inputs[spend_input_index].unlocking_script,
});
defer result.deinit(allocator);

if (result.terminal == .script_error) return result.script_error.?;
const ok = result.success;

Step trace

var traced = bsvz.script.thread.verifyScriptsTraced(.{
    .allocator = allocator,
}, bsvz.script.Script.init(&[_]u8{}), bsvz.script.Script.init(&[_]u8{
    @intFromEnum(bsvz.script.opcode.Opcode.OP_1),
    @intFromEnum(bsvz.script.opcode.Opcode.OP_FROMALTSTACK),
}));
defer traced.deinit(allocator);

try traced.writeDebug(std.io.getStdOut().writer());

Output serialization

const output = bsvz.transaction.Output{
    .satoshis = 42,
    .locking_script = bsvz.script.Script.init(&[_]u8{0x6a}),
};

var raw = try allocator.alloc(u8, output.serializedLen());
defer allocator.free(raw);
_ = output.writeInto(raw);

const parsed = try bsvz.transaction.Output.parse(raw);
const hash_all = try bsvz.transaction.Output.hashAll(allocator, &[_]bsvz.transaction.Output{output});

Examples

secp256k1 point API

bsvz.crypto.Point: fromCompressedSec1, fromRaw64, toCompressedSec1, toRaw64, xBytes32, yBytes32, add, mul, negate

Interpreter Coverage

Coverage map
Area Notes
Script bytes, chunks, parser, serializer direct pushes, PUSHDATA1/2/4, chunk roundtrip, malformed pushdata rejection
Script thread / seam orchestration separates seam behavior from the opcode loop; owns the "full previous locking script for sighash, executable prefix for execution" split
Push-only and script inspection helpers isPushOnly, hasCodeSeparator, top-level OP_RETURN tail handling
Execution core stack, altstack, condition stack, truthiness, op counting, stack limits
Control flow IF, NOTIF, ELSE, ENDIF, VERIFY, legacy vs post-Genesis multi-ELSE, post-Genesis OP_RETURN, CODESEPARATOR
Stack ops DUP, DROP, SWAP, ROT, ROLL, PICK, 2DUP, 2DROP, 2OVER, 2ROT, 2SWAP, 3DUP, IFDUP, TOALTSTACK, FROMALTSTACK, TUCK
Byte/splice ops CAT, SPLIT, NUM2BIN, BIN2NUM, SIZE
Bitwise ops INVERT, AND, OR, XOR, LSHIFT, RSHIFT
Numeric and boolean ops ADD, SUB, MUL, DIV, MOD, comparisons, min/max, within, boolean logic
Hash ops RIPEMD160, SHA1, SHA256, HASH160, HASH256
ScriptNum small-or-big numeric core using Zig stdlib bigint for promoted values
CHECKSIG transaction-aware, legacy and ForkID paths, CODESEPARATOR handling, scriptCode normalization
CHECKMULTISIG transaction-aware, post-Genesis behavior, early-exit, NULLDUMMY/NULLFAIL/ForkID policy
Policy flags strict_encoding, der_signatures, low_s, strict_pubkey_encoding, null_dummy, null_fail, sig_push_only, clean_stack, minimal_data, minimal_if, discourage_upgradable_nops, verify_check_locktime, verify_check_sequence
CLTV / CSV / upgradable NOPs tx-aware legacy/reference verify semantics behind explicit flags; post-Genesis BSV profile treats them as NOP-family ops unless policy discourages them
Numeric minimal-encoding parity minimal push and minimal numeric decoding enforced where Go applies MINIMALDATA
CODESEPARATOR parity legacy and ForkID scriptCode behavior, chained separator tests, parser/scanner coverage
BSV script test vectors all 1,499 Go corpus rows are accounted for across exact, filtered, reference, and specialized suites; all 1,435 executable rows pass; 64 meta/non-executable rows are audited

Scope:

  • Modern post-Genesis BSV script execution by default, plus legacy-reference semantics and opt-in legacy P2SH for compatibility and corpus parity

Benchmarks

Harnesses and results (Apple M3 Max)

Harnesses:

# bsvz interpreter
zig build bench

# Go SDK comparison
cd benchmarks/go_sdk && GOCACHE=/tmp/go-build-bsvz go test -run '^$' -bench . -benchmem

# Live corpus pipeline (requires sibling bsvz-autotrainer repo)
cd ../bsvz-autotrainer && bun bench:pipe

Source: ./benchmarks/script_engine.zig, ./benchmarks/go_sdk/script_engine_bench_test.go

Benchmarks use prebuilt fixtures. Key generation and per-iteration signing are excluded from the hot loop.

Script engine (Apple M3 Max):

Workload bsvz go-sdk
arithmetic verify ~0.11 us/op ~3.7 us/op
branching verify ~0.10 us/op ~4.6 us/op
SHA256 verify ~0.11 us/op ~3.9 us/op
HASH160 verify ~0.28 us/op ~4.0 us/op
stack ops verify ~0.30 us/op ~12.7 us/op
P2PKH verify (Go reference tx) ~476.1 us/op ~227.4 us/op

bsvz diagnostics:

Workload bsvz
P2PKH sighash only ~0.35 us/op
P2PKH secp verify only ~433.8 us/op
P2PKH verify (synthetic fixture) ~456.5 us/op

Live corpus pipeline (JungleBus-style, via bsvz-autotrainer):

Workload bsvz go-sdk
wall clock ~1720 ms ~1851 ms
tx throughput ~1907 tx/s ~1772 tx/s
parse+spend throughput ~13121 ops/s ~12194 ops/s

Phase split:

Phase bsvz go-sdk
JSON DOM ~492 ms ~517 ms
tx hex decode ~38 ms ~59 ms
spend verify ~1146 ms ~1224 ms

The remaining cost sits in secp verification. bsvz now uses Zig stdlib prehashed verification directly rather than a custom secp256k1 fast path.

These numbers are a local baseline on one machine; your results will vary with allocator configuration, CPU microarchitecture, and corpus mix.

Related SDKs

Language Repository
TypeScript bsv-blockchain/ts-sdk
Go bsv-blockchain/go-sdk
Python bsv-blockchain/py-sdk
Rust b1narydt/bsv-rust-sdk

About

No description, website, or topics provided.

Resources

Stars

5 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages