Class: JWT::PQ::Algorithms::HybridEdDsa
- Inherits:
-
Object
- Object
- JWT::PQ::Algorithms::HybridEdDsa
- Includes:
- JWA::SigningAlgorithm
- Defined in:
- lib/jwt/pq/algorithms/hybrid_eddsa.rb
Overview
JWT signing algorithm for hybrid EdDSA + ML-DSA signatures.
The signature is a simple concatenation: ed25519_sig (64 bytes) || ml_dsa_sig. This allows PQ-aware verifiers to validate both, while the fixed 64-byte Ed25519 prefix makes it possible to split the signatures deterministically.
Constant Summary collapse
- ED25519_SIG_SIZE =
64
Instance Method Summary collapse
- #header ⇒ Object
-
#initialize(alg) ⇒ HybridEdDsa
constructor
A new instance of HybridEdDsa.
- #sign(data:, signing_key:) ⇒ Object
- #verify(data:, signature:, verification_key:) ⇒ Object
Constructor Details
#initialize(alg) ⇒ HybridEdDsa
Returns a new instance of HybridEdDsa.
18 19 20 21 22 |
# File 'lib/jwt/pq/algorithms/hybrid_eddsa.rb', line 18 def initialize(alg) @alg = alg @ml_dsa_algorithm = alg.sub("EdDSA+", "") @header = { "alg" => alg, "pq_alg" => @ml_dsa_algorithm }.freeze end |
Instance Method Details
#header ⇒ Object
24 25 26 |
# File 'lib/jwt/pq/algorithms/hybrid_eddsa.rb', line 24 def header(*) @header end |
#sign(data:, signing_key:) ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/jwt/pq/algorithms/hybrid_eddsa.rb', line 28 def sign(data:, signing_key:) unless signing_key.is_a?(JWT::PQ::HybridKey) raise_sign_error!( "Expected a JWT::PQ::HybridKey, got #{signing_key.class}. " \ "Use JWT::PQ::HybridKey.generate to create a hybrid key." ) end raise_sign_error!("Both Ed25519 and ML-DSA private keys required") unless signing_key.private? ed_sig = signing_key.ed25519_signing_key.sign(data) ml_sig = signing_key.ml_dsa_key.sign(data) # Concatenate: Ed25519 (64 bytes) || ML-DSA (variable) ed_sig + ml_sig end |
#verify(data:, signature:, verification_key:) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/jwt/pq/algorithms/hybrid_eddsa.rb', line 44 def verify(data:, signature:, verification_key:) unless verification_key.is_a?(JWT::PQ::HybridKey) raise_verify_error!( "Expected a JWT::PQ::HybridKey, got #{verification_key.class}." ) end return false if signature.bytesize <= ED25519_SIG_SIZE ed_sig = signature.byteslice(0, ED25519_SIG_SIZE) ml_sig = signature.byteslice(ED25519_SIG_SIZE..) ed_valid = begin verification_key.ed25519_verify_key.verify(ed_sig, data) true rescue Ed25519::VerifyError false end ml_valid = verification_key.ml_dsa_key.verify(data, ml_sig) ed_valid && ml_valid rescue JWT::PQ::Error false end |