Ruby bindings for the Confium open-source framework for multi-stakeholder threshold cryptography.
Confium supports three deployment modes:
-
Mode 1 — Peer-to-peer threshold cryptography: nodes do TC directly (MPC, distributed custody, BFT)
-
Mode 2 — TC PKI replacement: drop-in for existing PKI consumers (PKCS#11 server, OpenSSL 3.0 provider, JCE)
-
Mode 3 — TC Certificate PKI: institutional deployments with custom certificate formats (OIML CNML, BIPM, pharma, accreditation)
This gem wraps the high-value Confium subsystems via a Rust native extension (built at gem install time with rb_sys + magnus). No separate C ABI library to install; everything is statically linked into the extension.
Installation
Add to your Gemfile:
gem "confium", "~> 0.1"
Or install directly:
$ gem install confium
Prerequisites
-
Ruby ≥ 3.1
-
Rust stable toolchain (
rustup default stable) -
C toolchain (clang/gcc/Xcode CLT)
The gem compiles a Rust cdylib at install time and links it into Ruby as a native extension. There is no separate libconfium to install.
Quick start
require "confium"
# Transparency log
tree = Confium::Transparency::MerkleTree.new
seq = tree.append(artifact_hash_bytes_32)
root = tree.root # binary String, 32 bytes
proof = tree.inclusion_proof(seq)
proof.verify(root) # => true
# Composite signature (PQ migration)
kp = Confium::Composite.generate_ed25519_keypair
component = Confium::Composite.sign_ed25519(kp["private_key"], "message")
sig = Confium::Composite::Signature.new([component])
result = sig.verify("message")
result.all_verified? # => true
# Attribute-based threshold policy
pred = Confium::Attributes.parse(%q{and(min_count("role:director", 3), min_distinct("region", 3))})
alice = Confium::Attributes::Signer.new
alice.add("role:director", "yes")
alice.add("region", "europe")
# ... bob, carol similarly
pred.satisfied_by?([alice, bob, carol]) # => true
# X.509 certificate
cert = Confium::PKI::Certificate.from_pem(File.read("cert.pem"))
puts cert.fingerprint_sha256
puts cert.valid_at?(Time.now.utc.iso8601) # => true
# Real threshold cryptography: P-256 Shamir
kp = Confium::TC::FrostP256.generate_keypair
shares = Confium::TC::FrostP256.split_secret(kp["private_key"], 3, 5)
recovered = Confium::TC::FrostP256.recover_secret(shares.first(3).map { |s| { "x" => s.x, "y" => s.y_bytes } })
recovered == kp["private_key"] # => true
API surface (v0.1.0)
Confium::Transparency
-
MerkleTree.new/#append(artifact_hash)/#root/#length/#empty?/#inclusion_proof(seq) -
InclusionProof#sequence/#steps/#verify(root)
Confium::Composite — PQ migration
-
.generate_ed25519_keypair→{ private_key:, public_key: } -
.sign_ed25519(private_key, message)→ component Hash -
Signature.new(components)/#verify(message)/#component_count/#algorithms -
VerificationResult#all_verified?/#per_component
Confium::Attributes — threshold policy DSL
-
.parse(dsl_expr)→Predicate -
Predicate#satisfied_by?(signers) -
Signer.new/#add(key, value)/#has?(key)/#values(key) -
DSL:
min_count("attr", n),min_distinct("attr", n),any("attr"),all("attr"),none("attr"),and(…),or(…),not(p)
Confium::PKI
-
Certificate.from_der(bytes)/.from_pem(str)/#to_der/#to_pem/#fingerprint_sha256/#serial_hex/#not_before/#not_after/#valid_at?(iso8601)/#public_key_bytes -
CSR.from_der/.from_pem/#to_der/#to_pem -
CMS::SignedData.from_json/#to_json/#signer_count/#content_type/#content/#certificate_count/#certificate_at(i) -
CMS::Content#bytes/#length -
XMLDSig.canonicalize(xml)/.canonicalize_exclusive(xml)(Canonical XML RFC 3076 + Exclusive C14N)
Confium::Identity — actor roles
-
.actor_types→["manufacturer", "testing_lab", "issuing_authority_officer", "biml_director", "quorum_coordinator", "verifier"] -
Actor.from_json(json)/#to_json/#actor_id/#actor_type/#quorum_id/#registered_at/#expires_at/#certificate_count
Confium::Config — deployment manifest
-
Manifest.from_toml(toml_str)/#deployment_name/#operator/#manifest_version/#tier_count/#tier_name_at(i)/#quorum_count/#validate/#valid?
Confium::TC::FrostP256 — real P-256 Shamir + ECDSA
-
.generate_keypair→{ private_key: (32 bytes), public_key: (65 bytes SEC1) } -
.split_secret(secret, t, n)→ array ofSharewith#x,#y_bytes -
.recover_secret([{x:, y:}, …])→ secret bytes -
.sign(private_key, message)→{ der:, fixed: }
Confium::TC::ElGamalP256 — threshold ElGamal-P256 KEM
-
.encapsulate(public_key_bytes)→{ ciphertext: { c1:, c2: }, shared_secret: } -
.partial_decrypt(party_index, share_bytes, ciphertext)→{ party_index:, bytes: } -
.aggregate_partials(partials, threshold, ciphertext)→ shared_secret bytes
Development
After checking out the repo:
$ bundle install
$ bundle exec rake compile # build the Rust extension
$ bundle exec rspec # 75+ specs
Architecture
The native extension lives at ext/confium_native/ as a Cargo workspace. It depends on the confium-* crates from crates.io (not on the local Rust workspace). The Ruby-side API is defined entirely in the extension via magnus — lib/confium.rb just requires the compiled .bundle.
License
BSD-2-Clause, same as the rest of the Confium workspace.