For developers
Build on Confium in your language
Three bindings ship today: Ruby (full API surface via native extension), Rust (the source of truth), and WASM (browser/Node.js verifier). Each gets you to a working verify in under five minutes.
Pick a binding
| Binding | Use when | Sign | Verify | Install |
|---|---|---|---|---|
| Ruby | Ruby/Rails/Sinatra app; you want a friendly API and don't need bare-metal perf. | Yes | Yes | gem install confium |
| Rust | You need maximum performance, custom integrations, or are building a Confium plugin. | Yes | Yes | cargo add confium-core |
| WASM | Browser / Node.js verifier. Composite sigs, transparency proofs, X.509 / CMS parsing. | No | Yes | npm install @confium/confium-wasm |
The WASM package is verifier-only by design. Signing requires the full Rust or Ruby stack; browsers verify, servers sign.
Install
$ gem install confiumRuby ≥ 3.1 + Rust stable for the native extension.
Five-minute quickstart: verify a composite signature in Ruby
The most common developer task: someone hands you a composite signature and you need to verify it. Here's a complete Sinatra app that does it in ~50 lines.
# app.rb
require "sinatra/base"
require "confium"
class VerifyApp < Sinatra::Base
before { content_type :json }
post "/verify" do
payload = JSON.parse(request.body.read)
message = payload["message"].b
sig = Confium::Composite::Signature.from_json(payload["signature"].to_json)
result = sig.verify(message, {
"Ed25519" => :builtin,
"ECDSA-P256" => :builtin,
"ML-DSA-65" => ->(pk, msg, s) { my_pq_verifier.verify(pk, msg, s) },
})
{
valid: result.all_verified?,
per_component: result.per_component,
}.to_json
rescue Confium::ParseError => e
halt 400, { error: "parse_failed", details: e.details }.to_json
rescue Confium::VerificationError => e
halt 422, { error: "verification_failed", details: e.details }.to_json
end
end
Run it: ruby app.rb. Test it:
curl -X POST http://localhost:4567/verify -d @payload.json.
For the full walkthrough (install, parse cert, validate chain, anchor in transparency log), see the Sinatra verifier quickstart in the Ruby gem docs.
Five-minute quickstart: threshold signing in Rust
The second most common task: split a key across N parties and produce a signature without ever reconstructing the secret.
use confium_tc_frost_p256::FrostP256;
// 1. Generate a keypair.
let kp = FrostP256::generate_keypair()?;
// 2. Split into 5 shares, threshold 3.
let shares = FrostP256::split_secret(&kp.private_key, 3, 5)?;
// 3. Distribute shares[i] to party i. The original secret can
// now be destroyed — it will never be needed again.
// 4. Recover the secret from any 3 shares (demonstration only —
// in production you never reconstruct; you co-sign instead).
let recovered = FrostP256::recover_secret(&[
shares[0].as_ref(),
shares[2].as_ref(),
shares[4].as_ref(),
])?;
assert_eq!(recovered, kp.private_key);
// 5. Sign with the original key (in production, sign with shares).
let sig = FrostP256::sign(&kp.private_key, b"threshold test")?;
println!("der: , fixed: ", sig.der.len(), sig.fixed.len()); The full end-to-end walkthrough lives in the threshold-signing example in the Rust workspace docs.
Five-minute quickstart: WASM verifier in a browser
import init, { CompositeSignature } from "@confium/confium-wasm";
await init();
const sig = CompositeSignature.from_json(jsonString);
const result = sig.verify(messageBytes, {
"Ed25519": "builtin",
"ECDSA-P256": "builtin",
"ML-DSA-65": (pk, msg, sig) => myExternalVerifier(pk, msg, sig),
});
console.log(result.all_verified); // true
console.log(result.per_component); // { Ed25519: true, ... }
The WASM package ships with per-subsystem Cargo features
(verify-composite, verify-transparency,
verify-attributes, verify-pki) so you
can tree-shake down to just what you need.
The typed error model
Every failure mode has a typed error class. There are no bare
RuntimeError raises.
Confium::Error # root — rescue this as catch-all
├── ParseError # malformed PEM / DER / JSON input
├── ValidationError # well-formed but invalid (e.g. expired cert)
├── VerificationError # signature / proof / inclusion check failed
├── ThresholdError # threshold protocol failure (bad share, no quorum)
├── CryptoError # underlying primitive failure
├── NotFoundError # requested signer / cert / share not found
├── IndexError # sequence number out of range
├── UnresolvedSignerError # required signer could not be resolved
└── PolicyViolationError # jurisdictional / FIPS policy violation
Every error carries .details — a Hash with
structured context (which cert, which algorithm, which check
failed). Code that reads .details should treat
the keys as advisory and defensively check for presence.
See the error handling guide for HTTP-status mapping and rescue patterns.
Where to read next
- Ruby API reference — all 11 subsystems documented.
- Rust workspace map — 43-crate layout.
- Sinatra verifier quickstart — the canonical end-to-end Ruby example.
- Threshold signing example — the canonical end-to-end Rust example.
- PQ migration walkthrough — composite signatures deep dive.
- Policy / FIPS mode — jurisdictional algorithm allow-lists.