+
Skip to content

zk-evm/bls12-381

BLS12-381 Signature Library

Crypto  Zig support  Ethereum  Platform  Build Status

A high-performance, memory-safe implementation of BLS12-381 digital signatures in Zig, providing both native Zig APIs and C ABI bindings for maximum interoperability.

🚀 Features

Core Cryptographic Operations

  • BLS12-381 Digital Signatures - Complete implementation of pairing-based signatures
  • Signature Aggregation - Efficient batch verification of multiple signatures
  • Key Aggregation - Combine multiple public keys into a single aggregate key
  • Min-PK and Min-Sig Variants - Support for both signature size and public key size optimizations
  • Ethereum 2.0 Compatible - Fully compliant with Ethereum consensus specifications

Performance & Safety

  • Memory Safe - Written in Zig with compile-time memory safety guarantees
  • Zero-Copy Operations - Optimized for minimal memory allocations
  • Thread-Safe - Built-in concurrency support with thread pooling
  • Memory Pooling - Intelligent buffer reuse for high-throughput scenarios
  • SIMD Optimizations - Leverages BLST's assembly optimizations (x86_64 ADX support)

Developer Experience

  • Native Zig API - Idiomatic Zig interfaces with error handling
  • C ABI Bindings - Full C-compatible API for language interoperability
  • Async Support - Non-blocking signature operations with callbacks
  • Comprehensive Testing - Extensive test suite with benchmarks
  • Cross-Platform - Supports Linux, macOS, and Windows

📦 Installation

Prerequisites

Building from Source

# Clone the repository
git clone https://github.com/zk-evm/bls12-381.git
cd bls12-381

# Build the library (static and shared)
zig build

# Build with optimizations
zig build -Doptimize=ReleaseFast

# Build portable version (no CPU-specific optimizations)
zig build -Dportable=true

# Force ADX optimizations on x86_64
zig build -Dforce-adx=true

Build Artifacts

After building, you'll find:

  • Static Library: zig-out/lib/libbls12-381.a
  • Shared Library: zig-out/lib/libbls12-381-min-pk.so (Linux) / .dylib (macOS) / .dll (Windows)
  • Executable: zig-out/bin/bls12-381

🔧 Usage

Quick Start (Zig)

const std = @import("std");
const bls = @import("bls12-381");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    // Initialize the library
    try bls.init();
    defer bls.deinit();

    // Generate a secret key
    var secret_key = bls.SecretKey.generate();
    
    // Derive public key
    var public_key = secret_key.getPublicKey();
    
    // Sign a message
    const message = "Hello, BLS12-381!";
    var signature = secret_key.sign(message);
    
    // Verify signature
    const is_valid = public_key.verify(signature, message);
    std.debug.print("Signature valid: {}\n", .{is_valid});
}

Signature Aggregation

const signatures = [_]*bls.Signature{ &sig1, &sig2, &sig3 };
const public_keys = [_]*bls.PublicKey{ &pk1, &pk2, &pk3 };
const messages = [_][]const u8{ "msg1", "msg2", "msg3" };

// Aggregate signatures
var agg_sig = bls.AggregateSignature.aggregate(&signatures);

// Batch verify
const is_valid = agg_sig.fastAggregateVerify(&public_keys, &messages);

C API Usage

#include "bls12-381.h"

int main() {
    // Initialize library
    if (init() != 0) {
        return 1;
    }
    
    // Create signature set
    SignatureSet set = {
        .message = "Hello World",
        .message_len = 11,
        .public_key = pk_bytes,
        .signature = sig_bytes
    };
    
    // Verify signature
    uint32_t result = verify_signature(&set, 1, true, true);
    
    deinit();
    return result == 0 ? 0 : 1;
}

🏗️ API Reference

Core Types

Type Description Size
SecretKey Private key for signing 32 bytes
PublicKey Public key for verification 48 bytes (min-pk) / 96 bytes (min-sig)
Signature Digital signature 96 bytes (min-pk) / 48 bytes (min-sig)
AggregatePublicKey Aggregated public keys 48/96 bytes
AggregateSignature Aggregated signatures 96/48 bytes

Key Operations

Signature Generation

// Single signature
const signature = secret_key.sign(message);

// Sign with domain separation
const sig_with_dst = secret_key.signWithDst(message, dst);

Signature Verification

// Single verification
const valid = public_key.verify(signature, message);

// Batch verification (faster for multiple sigs)
const valid = bls.fastAggregateVerify(public_keys, signatures, messages);

Key Management

// Key generation from seed
var secret_key = SecretKey.fromSeed(seed_bytes);

// Key derivation
var child_key = secret_key.derive(derivation_path);

// Key serialization
var pk_bytes = public_key.toBytes();
var sk_bytes = secret_key.toBytes();

⚡ Performance

Benchmarks

Operation Throughput Latency Notes
Key Generation 1,265,227 ops/sec 0.8 μs Secret key creation from random material
Public Key Derivation 8,072 ops/sec 123.9 μs SK→PK conversion
Signing 2,261 ops/sec 442.3 μs Message signing with BLS12-381
Verification 660 ops/sec 1,516.1 μs Single signature verification
Signature Aggregation 68,836 ops/sec 14.5 μs Combining 10 signatures
Aggregate Verification 660 agg/sec 1.51 ms Batch verify 100 signatures
Effective Batch Throughput 66,030 sigs/sec - Individual sigs in batch mode

Serialization Performance

Operation Throughput Latency
Public Key Compression 13,057,728 ops/sec 0.1 μs
Signature Compression 6,603,057 ops/sec 0.2 μs
Public Key Decompression 55,413 ops/sec 18.0 μs

Benchmarks run on x86_64 Linux with Zig 0.15.1 ReleaseFast optimization and ADX support

Performance Analysis

🔑 Key Insights:

  • Signature Aggregation is 100x faster than individual operations - use batch verification for high throughput
  • Key generation is extremely fast due to efficient random number generation
  • Verification is the bottleneck - consider caching verified signatures when possible
  • Serialization is negligible cost - network/storage will be the limiting factor

Memory Usage

  • Signature Context: ~3KB
  • Memory Pool Buffer: Configurable (default: 64KB)
  • Thread Pool: ~8 threads (configurable)

🧪 Testing

# Run all tests
zig build test

# Run with coverage
zig build test --summary all

# Run specific test suite
zig build test --test-filter "signature_tests"

# Performance benchmarks
zig build bench                          # Debug benchmarks
zig build bench -Doptimize=ReleaseFast   # Production benchmarks

# Individual benchmark categories  
zig build bench --test-filter "benchmark_key_generation"
zig build bench --test-filter "benchmark_signing"
zig build bench --test-filter "benchmark_verification"
zig build bench --test-filter "benchmark_aggregation"
zig build bench --test-filter "benchmark_serialization"

Test Coverage

  • ✅ Core cryptographic operations
  • ✅ Edge cases and error conditions
  • ✅ Cross-platform compatibility
  • ✅ Thread safety and concurrency
  • ✅ Memory leak detection
  • ✅ Performance regression tests

🏛️ Cryptographic Overview

BLS12-381 Curve

This library implements signatures over the BLS12-381 elliptic curve pairing, which provides:

  • 128-bit security level - Equivalent to 3072-bit RSA
  • Pairing-friendly - Enables signature aggregation
  • Ethereum 2.0 standard - Used in Ethereum's proof-of-stake consensus

Security Features

  • Deterministic signatures (RFC 6979)
  • Side-channel resistance - Constant-time operations where applicable
  • Memory safety - Zig's compile-time guarantees prevent buffer overflows
  • Input validation - All inputs are validated before processing

Compliance

🔧 Configuration

Build Options

# Performance optimizations
zig build -Doptimize=ReleaseFast     # Maximum speed
zig build -Doptimize=ReleaseSmall    # Minimum size
zig build -Doptimize=ReleaseSafe     # Optimized + safety checks

# Platform options
zig build -Dportable=true            # Disable CPU-specific optimizations
zig build -Dforce-adx=true           # Force ADX instructions (x86_64)

# Threading
zig build -Dthread-pool-size=16      # Custom thread pool size
zig build -Dsingle-threaded=true     # Disable threading

Runtime Configuration

// Memory pool settings
const config = bls.Config{
    .memory_pool_size = 128 * 1024,    // 128KB pool
    .max_threads = 8,                  // Thread limit
    .enable_batch_verify = true,       // Batch verification
};

try bls.initWithConfig(config);

🌐 Platform Support

Platform Status Notes
Linux x86_64 ✅ Full Includes ADX optimizations
Linux ARM64 ✅ Full NEON optimizations
macOS x86_64 ✅ Full Intel Mac support
macOS ARM64 ✅ Full Apple Silicon (M1/M2)
Windows x86_64 ✅ Full MSVC and MinGW
FreeBSD 🧪 Beta Community maintained

🤝 Contributing

We welcome contributions! Please see our Contributing Guidelines for details.

Development Setup

# Install development dependencies
zig build install-dev

# Run pre-commit hooks
zig build lint
zig build format
zig build test

# Generate documentation
zig build docs

Code Style

  • Follow Zig Style Guide
  • Use zig fmt for formatting
  • Add tests for new features
  • Update documentation as needed

📝 License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Copyright (c) 2025 zk-evm

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

🙏 Acknowledgments

📚 Additional Resources


WebsiteDocumentationIssuesDiscussions

Made with ❤️ by zk-evm

Releases

No releases published

Sponsor this project

Packages

No packages published

Languages

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载