synta 0.1.2

ASN.1 parser, decoder, and encoder library with DER/BER support and C FFI
Documentation
//! Profiling harness for certificate parsing
//!
//! Run with: cargo build --release --example profile_cert_parse
//! Then: perf record -F 999 -g ./target/release/examples/profile_cert_parse
//! Generate flamegraph: perf script | inferno-flamegraph > flamegraph.svg

use std::hint::black_box;
use synta::{Decoder, Encoding};
use synta_certificate::Certificate;

// Embedded test certificate (simple test certificate for profiling)
const TEST_CERT: &[u8] = &[
    0x30, 0x82, 0x01, 0x0D, // SEQUENCE (certificate)
    0x30, 0x81, 0xBE, // SEQUENCE (tbsCertificate)
    0xA0, 0x03, 0x02, 0x01, 0x02, // [0] EXPLICIT version (v3)
    0x02, 0x01, 0x01, // INTEGER (serial = 1)
    0x30, 0x0D, // SEQUENCE (signature algorithm)
    0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01,
    0x0B, // OID sha256WithRSAEncryption
    0x05, 0x00, // NULL
    0x30, 0x0F, // SEQUENCE (issuer)
    0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x04, 0x54, 0x65, 0x73,
    0x74, // CN=Test
    0x30, 0x1E, // SEQUENCE (validity)
    0x17, 0x0D, 0x32, 0x33, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
    0x5A, // UTCTime
    0x17, 0x0D, 0x32, 0x34, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
    0x5A, // UTCTime
    0x30, 0x0F, // SEQUENCE (subject)
    0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x04, 0x54, 0x65, 0x73,
    0x74, // CN=Test
    0x30, 0x5C, // SEQUENCE (subjectPublicKeyInfo)
    0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05,
    0x00, // RSA NULL
    0x03, 0x4B, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, // BIT STRING + SEQUENCE
    0xC4, 0x8B, 0xE7, 0xD9, 0x7D, 0x45, 0xF8, 0x7E, 0x93, 0x5A, 0x4B, 0xF0, 0x8D, 0x6F, 0x5E, 0x9E,
    0x1F, 0x95, 0xA7, 0x3E, 0x7F, 0xF4, 0x8E, 0x3B, 0x8F, 0x5C, 0x7E, 0x3B, 0x8E, 0x5D, 0x7E, 0x3C,
    0x8F, 0x5E, 0x7D, 0x3B, 0x8E, 0x5F, 0x7C, 0x3A, 0x8F, 0x5D, 0x7B, 0x39, 0x8E, 0x5C, 0x7A, 0x38,
    0x8F, 0x5B, 0x79, 0x37, 0x8E, 0x5A, 0x78, 0x36, 0x8F, 0x59, 0x77, 0x35, 0x8E, 0x58, 0x76, 0x34,
    0x03, // modulus
    0x02, 0x03, 0x01, 0x00, 0x01, // exponent 65537
    0x30, 0x0D, // SEQUENCE (signatureAlgorithm)
    0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05,
    0x00, // sha256WithRSAEncryption NULL
    0x03, 0x41, 0x00, // BIT STRING (signature)
    0x30, 0x3E, 0x02, 0x1D, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55,
    0x66, 0x77, 0x88, 0x99, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB,
    0xCC, 0xDD, 0x02, 0x1D, 0x00, 0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
    0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
];

fn main() {
    // Parse the test certificate to verify it works
    let mut decoder = Decoder::new(TEST_CERT, Encoding::Der);
    let cert: Certificate = decoder.decode().expect("Failed to parse test certificate");
    println!("Test certificate parsed successfully");
    println!("Serial number: {:?}", cert.tbs_certificate.serial_number);

    // Run many iterations for profiling
    const ITERATIONS: usize = 1_000_000;

    println!("Running {} iterations for profiling...", ITERATIONS);
    let start = std::time::Instant::now();

    for _ in 0..ITERATIONS {
        let mut decoder = Decoder::new(black_box(TEST_CERT), Encoding::Der);
        let cert: Certificate = black_box(decoder.decode().expect("Decode failed"));
        black_box(cert);
    }

    let elapsed = start.elapsed();
    println!("Completed in {:?}", elapsed);
    println!("Average per parse: {:?}", elapsed / ITERATIONS as u32);
    println!(
        "Throughput: {:.0} parses/sec",
        ITERATIONS as f64 / elapsed.as_secs_f64()
    );
}