Module: Linzer::MLDSA
- Defined in:
- lib/linzer/ml_dsa.rb,
lib/linzer/ml_dsa/gem_key.rb,
lib/linzer/ml_dsa/openssl_key.rb
Overview
ML-DSA support for HTTP Message Signatures as specified by https://c2sp.org/httpsig-pq
Two independent backends live under this namespace, both supporting all three FIPS 204 parameter sets (ML-DSA-44/65/87):
- OpenSSLKey -- backed directly by OpenSSL 3.5+, no extra gem dependency.
- GemKey -- backed by the
ml_dsagem.
require "linzer" alone already gets you OpenSSLKey for free when the
running OpenSSL build supports it, that's the safe default, and this
file plays no part in it (lib/linzer.rb requires ml_dsa/openssl_key
directly). require "linzer/ml_dsa" is the explicit opt-in for
everything else: it also loads GemKey, which in turn requires the
ml_dsa gem to be installed. Reach for it when your OpenSSL build is
too old for ML-DSA, or you specifically want the gem-backed
implementation.
Linzer.generate_ml_dsa_*_key/Linzer.new_ml_dsa_*_key dispatch
between them via a backend: keyword (:auto, :openssl, or :ml_dsa),
preferring OpenSSL when this build actually supports it.
Defined Under Namespace
Classes: GemKey, OpenSSLKey
Constant Summary collapse
- ALGORITHMS =
{ "ml-dsa-44" => MlDsa::ML_DSA_44, "ml-dsa-65" => MlDsa::ML_DSA_65, "ml-dsa-87" => MlDsa::ML_DSA_87 }.freeze
Class Method Summary collapse
-
.openssl_supported?(algorithm) ⇒ Boolean
Checks whether this OpenSSL build can actually perform ML-DSA signing/verification for the given algorithm.
Class Method Details
.openssl_supported?(algorithm) ⇒ Boolean
Checks whether this OpenSSL build can actually perform ML-DSA signing/verification for the given algorithm.
Returns true only when the algorithm is both something this
OpenSSL-backed implementation has actually implemented (see
IMPLEMENTED_ALGORITHMS) and something the underlying OpenSSL
library itself supports. This is needed mostly because a
version-number check alone isn't reliable and some distributions ship
OpenSSL 3.5+ with ML-DSA disabled by crypto policy (see
https://github.com/ruby/openssl/issues/1075), so this actually
attempts a throwaway key generation rather than inspecting
OpenSSL::OPENSSL_VERSION.
Memoized per algorithm after the first check, so repeated calls are
free. Unknown or not-yet-implemented algorithm identifiers return
false rather than raising.
Kept at the Linzer::MLDSA module level, not under OpenSSLKey, since it's a backend-selection capability probe used to decide whether to construct an OpenSSLKey at all, not a detail of an already-chosen OpenSSL backend.
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
# File 'lib/linzer/ml_dsa/openssl_key.rb', line 319 def openssl_supported?(algorithm) cache = (@openssl_supported ||= {}) return cache[algorithm] if cache.key?(algorithm) cache[algorithm] = if IMPLEMENTED_ALGORITHMS.include?(algorithm) begin OpenSSL::PKey.generate_key(algorithm.upcase) true rescue OpenSSL::PKey::PKeyError false end else false end end |