synor/sdk/cpp/examples/zk_example.cpp
Gulshan Yadav cf5130d9e4 feat(sdk): Add comprehensive examples for C, C++, C#, and Ruby SDKs
Add example code demonstrating all SDK services (Crypto, DEX, ZK, IBC,
Compiler) for the remaining languages:

- C SDK (5 examples): Using synor_* C API with explicit memory management
- C++ SDK (5 examples): Modern C++17 with RAII and designated initializers
- C# SDK (5 examples): Async/await patterns with .NET conventions
- Ruby SDK (5 examples): Ruby idioms with blocks and symbols

Each example covers:
- Crypto: Hybrid signatures, mnemonics, Falcon, SPHINCS+, KDF, hashing
- DEX: Markets, spot trading, perpetuals, liquidity, portfolio
- ZK: Circuits, Groth16, PLONK, STARK, recursive proofs, ceremonies
- IBC: Chains, channels, transfers, packets, relayer, monitoring
- Compiler: Compilation, optimization, ABI, analysis, validation, security
2026-01-28 14:44:04 +05:30

359 lines
13 KiB
C++

/**
* Synor ZK SDK Examples for C++
*
* Demonstrates zero-knowledge proof operations:
* - Circuit compilation (Circom)
* - Proof generation and verification
* - Multiple proving systems (Groth16, PLONK, STARK)
* - Recursive proof composition
* - Trusted setup ceremonies
*/
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <random>
#include <synor/zk.hpp>
using namespace synor::zk;
void circuit_example(SynorZk& zk) {
std::cout << "=== Circuit Compilation ===" << std::endl;
// Simple Circom circuit: prove knowledge of factors
std::string circom_code = R"(
pragma circom 2.1.0;
template Multiplier() {
signal input a;
signal input b;
signal output c;
c <== a * b;
}
component main = Multiplier();
)";
// Compile the circuit
std::cout << "Compiling circuit..." << std::endl;
auto circuit = zk.circuits().compile({
.code = circom_code,
.language = CircuitLanguage::Circom
});
std::cout << "Circuit compiled:" << std::endl;
std::cout << " Circuit ID: " << circuit.circuit_id() << std::endl;
std::cout << " Constraints: " << circuit.constraints() << std::endl;
std::cout << " Public inputs: " << circuit.public_inputs() << std::endl;
std::cout << " Private inputs: " << circuit.private_inputs() << std::endl;
std::cout << " Outputs: " << circuit.outputs() << std::endl;
// Get circuit info
auto info = zk.circuits().get(circuit.circuit_id());
std::cout << "\nCircuit info:" << std::endl;
std::cout << " Name: " << info.name() << std::endl;
std::cout << " Version: " << info.version() << std::endl;
std::cout << " Wires: " << info.wire_count() << std::endl;
std::cout << " Labels: " << info.label_count() << std::endl;
// List available circuits
auto circuits = zk.circuits().list();
std::cout << "\nAvailable circuits: " << circuits.size() << std::endl;
for (size_t i = 0; i < std::min(circuits.size(), size_t(3)); ++i) {
const auto& c = circuits[i];
std::cout << " " << c.circuit_id() << ": " << c.name()
<< " (" << c.constraints() << " constraints)" << std::endl;
}
std::cout << std::endl;
}
void groth16_example(SynorZk& zk) {
std::cout << "=== Groth16 Proving System ===" << std::endl;
std::string circuit_id = "multiplier-v1";
// Generate proving/verification keys (trusted setup)
std::cout << "Generating keys..." << std::endl;
auto keys = zk.groth16().setup(circuit_id);
std::cout << "Keys generated:" << std::endl;
std::cout << " Proving key size: " << keys.proving_key().size() << " bytes" << std::endl;
std::cout << " Verification key size: " << keys.verification_key().size() << " bytes" << std::endl;
// Prepare witness (private inputs)
std::map<std::string, std::string> witness = {
{"a", "3"},
{"b", "7"}
};
// Generate proof
std::cout << "\nGenerating proof..." << std::endl;
auto proof = zk.groth16().prove({
.circuit_id = circuit_id,
.witness = witness,
.proving_key = keys.proving_key()
});
std::cout << "Proof generated:" << std::endl;
std::cout << " Proof size: " << proof.proof_bytes().size() << " bytes" << std::endl;
std::cout << " Public signals: " << proof.public_signals().size() << std::endl;
std::cout << " Proving time: " << proof.proving_time_ms() << "ms" << std::endl;
// Verify proof
std::cout << "\nVerifying proof..." << std::endl;
bool verified = zk.groth16().verify({
.proof = proof.proof_bytes(),
.public_signals = proof.public_signals(),
.verification_key = keys.verification_key()
});
std::cout << "Verification result: " << (verified ? "true" : "false") << std::endl;
// Export proof for on-chain verification
auto solidity_calldata = zk.groth16().export_calldata(proof);
std::cout << "\nSolidity calldata: " << solidity_calldata.substr(0, 100) << "..." << std::endl;
std::cout << std::endl;
}
void plonk_example(SynorZk& zk) {
std::cout << "=== PLONK Proving System ===" << std::endl;
std::string circuit_id = "multiplier-v1";
// PLONK uses universal trusted setup
std::cout << "Getting universal setup..." << std::endl;
auto srs = zk.plonk().get_universal_setup(14); // 2^14 constraints
std::cout << "SRS loaded: " << srs.size() << " bytes" << std::endl;
// Generate circuit-specific keys
std::cout << "\nGenerating circuit keys..." << std::endl;
auto keys = zk.plonk().setup(circuit_id, srs);
std::cout << "Keys generated" << std::endl;
// Generate proof
std::map<std::string, std::string> witness = {{"a", "5"}, {"b", "9"}};
std::cout << "\nGenerating PLONK proof..." << std::endl;
auto proof = zk.plonk().prove({
.circuit_id = circuit_id,
.witness = witness,
.proving_key = keys.proving_key()
});
std::cout << "Proof generated:" << std::endl;
std::cout << " Proof size: " << proof.proof_bytes().size() << " bytes" << std::endl;
std::cout << " Proving time: " << proof.proving_time_ms() << "ms" << std::endl;
// Verify proof
bool verified = zk.plonk().verify({
.proof = proof.proof_bytes(),
.public_signals = proof.public_signals(),
.verification_key = keys.verification_key()
});
std::cout << "Verification result: " << (verified ? "true" : "false") << std::endl;
// Compare with Groth16
std::cout << "\nPLONK advantages:" << std::endl;
std::cout << " - Universal trusted setup" << std::endl;
std::cout << " - Larger proofs (~2.5 KB vs ~200 bytes)" << std::endl;
std::cout << " - Faster proving for some circuits" << std::endl;
std::cout << std::endl;
}
void stark_example(SynorZk& zk) {
std::cout << "=== STARK Proving System ===" << std::endl;
std::string circuit_id = "multiplier-v1";
// STARKs don't need trusted setup
std::cout << "Configuring STARK parameters..." << std::endl;
StarkConfig config{
.field_size = 256,
.hash_function = HashFunction::Poseidon,
.blowup_factor = 8,
.num_queries = 30,
.folding_factor = 8
};
// Generate proof
std::map<std::string, std::string> witness = {{"a", "11"}, {"b", "13"}};
std::cout << "\nGenerating STARK proof..." << std::endl;
auto proof = zk.stark().prove({
.circuit_id = circuit_id,
.witness = witness,
.config = config
});
std::cout << "Proof generated:" << std::endl;
std::cout << " Proof size: " << proof.proof_bytes().size() << " bytes" << std::endl;
std::cout << " Proving time: " << proof.proving_time_ms() << "ms" << std::endl;
std::cout << " FRI layers: " << proof.fri_layers() << std::endl;
// Verify proof
std::cout << "\nVerifying STARK proof..." << std::endl;
bool verified = zk.stark().verify({
.proof = proof.proof_bytes(),
.public_signals = proof.public_signals(),
.config = config
});
std::cout << "Verification result: " << (verified ? "true" : "false") << std::endl;
// Compare with SNARKs
std::cout << "\nSTARK advantages:" << std::endl;
std::cout << " - No trusted setup needed" << std::endl;
std::cout << " - Post-quantum secure" << std::endl;
std::cout << " - Larger proofs (~100 KB)" << std::endl;
std::cout << " - Faster proving for complex computations" << std::endl;
std::cout << std::endl;
}
void recursive_example(SynorZk& zk) {
std::cout << "=== Recursive Proof Composition ===" << std::endl;
// Create inner proofs
std::cout << "Generating inner proofs..." << std::endl;
std::vector<RecursiveProof> inner_proofs;
for (int i = 1; i <= 3; ++i) {
std::map<std::string, std::string> witness = {
{"a", std::to_string(i)},
{"b", std::to_string(i + 1)}
};
auto proof = zk.recursive().prove_inner({
.circuit_id = "multiplier-v1",
.witness = witness,
.level = 0
});
inner_proofs.push_back(proof);
std::cout << " Inner proof " << i << " generated" << std::endl;
}
// Aggregate proofs recursively
std::cout << "\nAggregating proofs..." << std::endl;
auto aggregated_proof = zk.recursive().aggregate({
.proofs = inner_proofs,
.aggregation_circuit = "recursive-aggregator-v1"
});
std::cout << "Aggregated proof:" << std::endl;
std::cout << " Proof size: " << aggregated_proof.proof_bytes().size() << " bytes" << std::endl;
std::cout << " Proofs aggregated: " << aggregated_proof.proofs_aggregated() << std::endl;
std::cout << " Recursion depth: " << aggregated_proof.recursion_depth() << std::endl;
// Verify aggregated proof (verifies all inner proofs at once)
std::cout << "\nVerifying aggregated proof..." << std::endl;
bool verified = zk.recursive().verify_aggregated(aggregated_proof);
std::cout << "Verification result: " << (verified ? "true" : "false") << std::endl;
// Use cases
std::cout << "\nRecursive proof use cases:" << std::endl;
std::cout << " - Rollup batch verification" << std::endl;
std::cout << " - Incremental computation proofs" << std::endl;
std::cout << " - Cross-chain state proofs" << std::endl;
std::cout << std::endl;
}
void ceremony_example(SynorZk& zk) {
std::cout << "=== Trusted Setup Ceremony ===" << std::endl;
// List active ceremonies
auto ceremonies = zk.ceremony().list(CeremonyStatus::Active);
std::cout << "Active ceremonies: " << ceremonies.size() << std::endl;
for (size_t i = 0; i < std::min(ceremonies.size(), size_t(3)); ++i) {
const auto& ceremony = ceremonies[i];
std::cout << "\n " << ceremony.ceremony_id() << ":" << std::endl;
std::cout << " Circuit: " << ceremony.circuit_id() << std::endl;
std::cout << " Participants: " << ceremony.participant_count() << std::endl;
std::cout << " Current round: " << ceremony.current_round() << std::endl;
std::cout << " Status: " << ceremony.status() << std::endl;
}
// Create a new ceremony
std::cout << "\nCreating new ceremony..." << std::endl;
auto new_ceremony = zk.ceremony().create({
.circuit_id = "new-circuit-v1",
.min_participants = 10,
.max_participants = 100,
.round_duration = 3600, // 1 hour per round
.verify_contributions = true
});
std::cout << "Ceremony created:" << std::endl;
std::cout << " Ceremony ID: " << new_ceremony.ceremony_id() << std::endl;
std::cout << " Join URL: " << new_ceremony.join_url() << std::endl;
// Participate in a ceremony
std::cout << "\nParticipating in ceremony..." << std::endl;
// Generate entropy
std::vector<uint8_t> entropy(32);
std::random_device rd;
std::generate(entropy.begin(), entropy.end(), std::ref(rd));
auto contribution = zk.ceremony().contribute({
.ceremony_id = new_ceremony.ceremony_id(),
.entropy = entropy
});
std::cout << "Contribution made:" << std::endl;
std::cout << " Contribution ID: " << contribution.contribution_id() << std::endl;
std::cout << " Position: " << contribution.position() << std::endl;
std::cout << " Hash: " << contribution.hash() << std::endl;
// Verify a contribution
std::cout << "\nVerifying contribution..." << std::endl;
bool valid = zk.ceremony().verify_contribution(contribution.contribution_id());
std::cout << "Contribution valid: " << (valid ? "true" : "false") << std::endl;
// Get ceremony transcript (for auditability)
auto transcript = zk.ceremony().get_transcript(new_ceremony.ceremony_id());
std::cout << "\nCeremony transcript:" << std::endl;
std::cout << " Total contributions: " << transcript.contributions().size() << std::endl;
std::cout << " Start time: " << transcript.start_time() << std::endl;
std::cout << " Final hash: " << (transcript.final_hash().empty() ? "pending" : transcript.final_hash()) << std::endl;
std::cout << std::endl;
}
int main(int argc, char** argv) {
// Initialize client
const char* api_key = std::getenv("SYNOR_API_KEY");
ZkConfig config{
.api_key = api_key ? api_key : "your-api-key",
.endpoint = "https://zk.synor.io/v1",
.timeout = std::chrono::seconds(120), // ZK operations can be slow
.retries = 3,
.debug = false,
.default_proving_system = ProvingSystem::Groth16,
.prove_timeout = std::chrono::seconds(300),
.verify_timeout = std::chrono::seconds(30)
};
SynorZk zk(config);
try {
// Check service health
bool healthy = zk.health_check();
std::cout << "Service healthy: " << (healthy ? "true" : "false") << std::endl << std::endl;
// Run examples
circuit_example(zk);
groth16_example(zk);
plonk_example(zk);
stark_example(zk);
recursive_example(zk);
ceremony_example(zk);
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}