Installation
tacet is available for multiple languages. Choose your platform:
Add tacet as a dev dependency:
cargo add tacet --devcargo add rand --dev # For random input generationOr add to your Cargo.toml:
[dev-dependencies]tacet = "0.1"rand = "0.8"Feature flags
Section titled “Feature flags”Default features (recommended):
parallel- Rayon-based parallel bootstrap (4-8x speedup)kperf(macOS ARM64) - Cycle-accurate timing via kperf (opt-in, requires sudo)perf(Linux) - Cycle-accurate timing via perf_event (opt-in, requires sudo)
Optional features:
macros- Proc macros (timing_test!,timing_test_checked!)
Minimal build:
[dev-dependencies]tacet = { version = "0.1", default-features = false }bun add @tacet/jsnpm i @tacet/jspnpm add @tacet/jsyarn add @tacet/jsNative bindings via NAPI-RS, supporting Node.js and Bun on:
- Linux (x86_64, aarch64)
- macOS (x86_64, aarch64)
- Windows (x86_64)
import { TimingOracle, AttackerModel } from 'tacet';
const outcome = TimingOracle.forAttacker(AttackerModel.AdjacentNetwork) .test( () => new Uint8Array(32).fill(0), // Baseline () => crypto.getRandomValues(new Uint8Array(32)), // Sample (data) => myFunction(data) );Quick Install (Recommended)
Section titled “Quick Install (Recommended)”Install Script (Linux/macOS):
curl -fsSL https://raw.githubusercontent.com/agucova/tacet/main/install.sh | bashInstalls to /usr/local by default. For a custom location:
PREFIX=$HOME/.local bash -c "$(curl -fsSL https://raw.githubusercontent.com/agucova/tacet/main/install.sh)"Homebrew (macOS):
HOMEBREW_DEVELOPER=1 brew install --formula \ https://raw.githubusercontent.com/agucova/tacet/main/homebrew/Formula/tacet-c.rbVerify Installation:
# Add Homebrew's pkgconfig to your path (add to ~/.zshrc or ~/.bashrc)export PKG_CONFIG_PATH="/opt/homebrew/lib/pkgconfig:$PKG_CONFIG_PATH"
pkg-config --modversion tacetpkg-config --cflags --libs tacetUsage in Your Project
Section titled “Usage in Your Project”With pkg-config (recommended):
cc myfile.c $(pkg-config --cflags --libs tacet) -o myappCMake:
find_package(PkgConfig REQUIRED)pkg_check_modules(TACET REQUIRED tacet)
add_executable(my_test test.c)target_include_directories(my_test PRIVATE ${TACET_INCLUDE_DIRS})target_link_libraries(my_test PRIVATE ${TACET_LIBRARIES})Example usage:
#include <tacet/tacet.h>
ToConfig cfg = to_config_adjacent_network();cfg.time_budget_secs = 30.0; // Customize as needed// ToConfig is a value type - no need to freeSee C API for full documentation.
Build from Source (Advanced)
Section titled “Build from Source (Advanced)”If you need to build from source:
git clone https://github.com/agucova/tacetcd tacetcargo build --release -p tacet-c
# Artifacts generated:# - Header: crates/tacet-c/include/tacet.h# - Library: target/release/libtacet_c.a# - pkg-config: target/release/tacet.pcQuick Install (Recommended)
Section titled “Quick Install (Recommended)”Install Script (Linux/macOS):
curl -fsSL https://raw.githubusercontent.com/agucova/tacet/main/install.sh | bashInstalls to /usr/local by default. For a custom location:
PREFIX=$HOME/.local bash -c "$(curl -fsSL https://raw.githubusercontent.com/agucova/tacet/main/install.sh)"Homebrew (macOS):
HOMEBREW_DEVELOPER=1 brew install --formula \ https://raw.githubusercontent.com/agucova/tacet/main/homebrew/Formula/tacet-c.rbVerify Installation:
# Add Homebrew's pkgconfig to your path (add to ~/.zshrc or ~/.bashrc)export PKG_CONFIG_PATH="/opt/homebrew/lib/pkgconfig:$PKG_CONFIG_PATH"
pkg-config --modversion tacetpkg-config --cflags --libs tacetUsage in Your Project
Section titled “Usage in Your Project”With pkg-config (recommended):
c++ -std=c++20 myfile.cpp $(pkg-config --cflags --libs tacet) -o myappCMake (C++20 required):
find_package(PkgConfig REQUIRED)pkg_check_modules(TACET REQUIRED tacet)
# C++20 requiredset(CMAKE_CXX_STANDARD 20)set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(my_test test.cpp)target_include_directories(my_test PRIVATE ${TACET_INCLUDE_DIRS})target_link_libraries(my_test PRIVATE ${TACET_LIBRARIES})Example usage:
#include <tacet/tacet.hpp>using namespace std::chrono_literals;
auto oracle = tacet::Oracle::forAttacker(ToAttackerModel::AdjacentNetwork) .timeBudget(30s);See C++ API for full documentation.
Build from Source (Advanced)
Section titled “Build from Source (Advanced)”If you need to build from source:
git clone https://github.com/agucova/tacetcd tacetcargo build --release -p tacet-c
# Artifacts generated:# - Header: bindings/cpp/tacet.hpp# - Library: target/release/libtacet_c.a# - pkg-config: target/release/tacet.pcInstallation
Section titled “Installation”go get github.com/agucova/tacet/crates/tacet-gogo run github.com/agucova/tacet/crates/tacet-go/cmd/tacet-install@latestThe install command downloads the pre-built native library (~12MB) for your platform and places it in the module cache where CGo can find it. This only needs to be run once.
Requirements: Go 1.22+ with CGo enabled
Supported platforms:
- macOS (ARM64 Apple Silicon, AMD64 Intel)
- Linux (ARM64, AMD64)
Quick Start
Section titled “Quick Start”package main
import ( "fmt" "log" "time"
tacet "github.com/agucova/tacet/crates/tacet-go")
func main() { result, err := tacet.Test( tacet.NewZeroGenerator(0), tacet.FuncOperation(func(input []byte) { myCryptoFunction(input) }), 32, // input size in bytes tacet.WithAttacker(tacet.AdjacentNetwork), tacet.WithTimeBudget(30*time.Second), ) if err != nil { log.Fatal(err) }
switch result.Outcome { case tacet.Pass: fmt.Printf("No leak (P=%.1f%%)\n", result.LeakProbability*100) case tacet.Fail: fmt.Printf("Leak detected: %s\n", result.Exploitability) }}Troubleshooting
Section titled “Troubleshooting”If you see linker errors about missing tacet symbols, run the install command:
go run github.com/agucova/tacet/crates/tacet-go/cmd/tacet-install@latestTo install a specific version:
go run github.com/agucova/tacet/crates/tacet-go/cmd/tacet-install@latest -version=v0.3.0See Go API documentation for complete reference.
Platform support
Section titled “Platform support”| Platform | Timer | Resolution | Notes |
|---|---|---|---|
| Linux x86_64 | rdtsc | ~0.3ns | Best precision |
| Linux aarch64 | cntvct_el0 | 1-10ns | Good precision |
| macOS x86_64 | rdtsc | ~0.3ns | Best precision |
| macOS ARM64 | cntvct_el0 | ~42ns | Uses adaptive batching |
| Windows x86_64 | rdtsc | ~0.3ns | Best precision |
On platforms with coarse timer resolution (macOS ARM64), the library automatically uses adaptive batching to compensate.
Enabling cycle-accurate timers
Section titled “Enabling cycle-accurate timers”For cycle-accurate measurements on ARM64, use TimerSpec::CyclePrecision:
use tacet::{TimingOracle, AttackerModel, TimerSpec};
TimingOracle::for_attacker(AttackerModel::SharedHardware) .timer_spec(TimerSpec::CyclePrecision) // Request cycle-accurate timerThis requires elevated privileges on ARM64:
# kperf requires BOTH sudo AND single-threaded executionsudo -E cargo test --test my_test -- --test-threads=1# Option 1: Run as rootsudo cargo test --test my_test -- --test-threads=1
# Option 2: Grant CAP_PERFMON (persistent)sudo setcap cap_perfmon+ep target/debug/deps/my_test-*cargo test --test my_test -- --test-threads=1Next steps
Section titled “Next steps”- Quick Start: Write your first timing test
- The Two-Class Pattern: Understanding input class selection
- Attacker Models: Choosing the right threat model