pq_crypto 0.3.2 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +56 -0
- data/CHANGELOG.md +37 -0
- data/GET_STARTED.md +361 -40
- data/README.md +58 -241
- data/SECURITY.md +101 -82
- data/ext/pqcrypto/extconf.rb +40 -7
- data/ext/pqcrypto/mldsa_api.h +71 -1
- data/ext/pqcrypto/mlkem_api.h +24 -0
- data/ext/pqcrypto/pq_externalmu.c +14 -1
- data/ext/pqcrypto/pqcrypto_ruby_secure.c +484 -81
- data/ext/pqcrypto/pqcrypto_secure.c +179 -72
- data/ext/pqcrypto/pqcrypto_secure.h +87 -7
- data/ext/pqcrypto/pqcrypto_version.h +7 -0
- data/ext/pqcrypto/vendor/.vendored +1 -1
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/LICENSE +5 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/Makefile +19 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/Makefile.Microsoft_nmake +23 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/api.h +18 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/cbd.c +83 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/cbd.h +11 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/indcpa.c +327 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/indcpa.h +22 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/kem.c +164 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/kem.h +23 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/ntt.c +146 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/ntt.h +14 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/params.h +36 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/poly.c +311 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/poly.h +37 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/polyvec.c +198 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/polyvec.h +26 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/reduce.c +41 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/reduce.h +13 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/symmetric-shake.c +71 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/symmetric.h +30 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/verify.c +67 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/verify.h +13 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/LICENSE +5 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/Makefile +19 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/Makefile.Microsoft_nmake +23 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/api.h +18 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/cbd.c +108 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/cbd.h +11 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/indcpa.c +327 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/indcpa.h +22 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/kem.c +164 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/kem.h +23 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/ntt.c +146 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/ntt.h +14 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/params.h +36 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/poly.c +299 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/poly.h +37 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/polyvec.c +188 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/polyvec.h +26 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/reduce.c +41 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/reduce.h +13 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/symmetric-shake.c +71 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/symmetric.h +30 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/verify.c +67 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/verify.h +13 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/LICENSE +5 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/Makefile +19 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/Makefile.Microsoft_nmake +23 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/api.h +50 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/ntt.c +98 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/ntt.h +10 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/packing.c +261 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/packing.h +31 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/params.h +44 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/poly.c +848 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/poly.h +52 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/polyvec.c +415 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/polyvec.h +65 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/reduce.c +69 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/reduce.h +17 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/rounding.c +98 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/rounding.h +14 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/sign.c +407 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/sign.h +47 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/symmetric-shake.c +26 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/symmetric.h +34 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/LICENSE +5 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/Makefile +19 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/Makefile.Microsoft_nmake +23 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/api.h +50 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/ntt.c +98 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/ntt.h +10 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/packing.c +261 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/packing.h +31 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/params.h +44 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/poly.c +823 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/poly.h +52 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/polyvec.c +415 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/polyvec.h +65 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/reduce.c +69 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/reduce.h +17 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/rounding.c +92 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/rounding.h +14 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/sign.c +407 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/sign.h +47 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/symmetric-shake.c +26 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/symmetric.h +34 -0
- data/lib/pq_crypto/algorithm_registry.rb +200 -0
- data/lib/pq_crypto/hybrid_kem.rb +1 -12
- data/lib/pq_crypto/kem.rb +104 -13
- data/lib/pq_crypto/pkcs8.rb +387 -0
- data/lib/pq_crypto/serialization.rb +1 -14
- data/lib/pq_crypto/signature.rb +123 -17
- data/lib/pq_crypto/spki.rb +131 -0
- data/lib/pq_crypto/version.rb +1 -1
- data/lib/pq_crypto.rb +78 -19
- data/script/vendor_libs.rb +4 -0
- metadata +95 -3
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "openssl"
|
|
4
|
+
|
|
5
|
+
module PQCrypto
|
|
6
|
+
module SPKI
|
|
7
|
+
PEM_LABEL = "PUBLIC KEY"
|
|
8
|
+
PEM_BEGIN = "-----BEGIN #{PEM_LABEL}-----"
|
|
9
|
+
PEM_END = "-----END #{PEM_LABEL}-----"
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
def encode_der(algorithm_symbol, public_key_bytes)
|
|
13
|
+
entry = AlgorithmRegistry.fetch(algorithm_symbol)
|
|
14
|
+
validate_public_key_algorithm!(algorithm_symbol, entry)
|
|
15
|
+
|
|
16
|
+
bytes = String(public_key_bytes).b
|
|
17
|
+
expected = entry.fetch(:public_key_bytes)
|
|
18
|
+
unless bytes.bytesize == expected
|
|
19
|
+
raise SerializationError,
|
|
20
|
+
"Invalid #{algorithm_symbol.inspect} public key length: expected #{expected}, got #{bytes.bytesize}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
OpenSSL::ASN1::Sequence.new([
|
|
24
|
+
OpenSSL::ASN1::Sequence.new([
|
|
25
|
+
OpenSSL::ASN1::ObjectId.new(AlgorithmRegistry.standard_oid(algorithm_symbol)),
|
|
26
|
+
]),
|
|
27
|
+
OpenSSL::ASN1::BitString.new(bytes),
|
|
28
|
+
]).to_der.b
|
|
29
|
+
rescue OpenSSL::ASN1::ASN1Error => e
|
|
30
|
+
raise SerializationError, e.message
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def encode_pem(algorithm_symbol, public_key_bytes)
|
|
34
|
+
der = encode_der(algorithm_symbol, public_key_bytes)
|
|
35
|
+
body = encode_base64(der).scan(/.{1,64}/).join("\n")
|
|
36
|
+
"#{PEM_BEGIN}\n#{body}\n#{PEM_END}\n"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def decode_der(der)
|
|
40
|
+
input = String(der).b
|
|
41
|
+
outer = decode_asn1(input)
|
|
42
|
+
raise SerializationError, "SPKI DER contains trailing data" unless outer.to_der.b == input
|
|
43
|
+
raise SerializationError, "SPKI must be an ASN.1 SEQUENCE" unless outer.is_a?(OpenSSL::ASN1::Sequence)
|
|
44
|
+
raise SerializationError, "SPKI SEQUENCE must contain exactly 2 elements" unless outer.value.size == 2
|
|
45
|
+
|
|
46
|
+
algorithm_identifier, subject_public_key = outer.value
|
|
47
|
+
algorithm = decode_algorithm_identifier(algorithm_identifier)
|
|
48
|
+
entry = AlgorithmRegistry.fetch(algorithm)
|
|
49
|
+
validate_public_key_algorithm!(algorithm, entry)
|
|
50
|
+
|
|
51
|
+
unless subject_public_key.is_a?(OpenSSL::ASN1::BitString)
|
|
52
|
+
raise SerializationError, "SPKI subjectPublicKey must be a BIT STRING"
|
|
53
|
+
end
|
|
54
|
+
unless subject_public_key.unused_bits.zero?
|
|
55
|
+
raise SerializationError, "SPKI subjectPublicKey must have zero unused bits"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
bytes = String(subject_public_key.value).b
|
|
59
|
+
expected = entry.fetch(:public_key_bytes)
|
|
60
|
+
unless bytes.bytesize == expected
|
|
61
|
+
raise SerializationError,
|
|
62
|
+
"Invalid #{algorithm.inspect} SPKI public key length: expected #{expected}, got #{bytes.bytesize}"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
[algorithm, bytes]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def decode_pem(pem)
|
|
69
|
+
der = der_from_pem(pem)
|
|
70
|
+
decode_der(der)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
def decode_asn1(der)
|
|
76
|
+
OpenSSL::ASN1.decode(der)
|
|
77
|
+
rescue OpenSSL::ASN1::ASN1Error => e
|
|
78
|
+
raise SerializationError, e.message
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def decode_algorithm_identifier(value)
|
|
82
|
+
unless value.is_a?(OpenSSL::ASN1::Sequence)
|
|
83
|
+
raise SerializationError, "SPKI algorithm must be an AlgorithmIdentifier SEQUENCE"
|
|
84
|
+
end
|
|
85
|
+
unless value.value.size == 1
|
|
86
|
+
raise SerializationError, "SPKI AlgorithmIdentifier parameters must be absent"
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
oid = value.value.first
|
|
90
|
+
raise SerializationError, "SPKI AlgorithmIdentifier must contain an OBJECT IDENTIFIER" unless oid.is_a?(OpenSSL::ASN1::ObjectId)
|
|
91
|
+
|
|
92
|
+
algorithm = AlgorithmRegistry.by_standard_oid(oid.oid)
|
|
93
|
+
raise SerializationError, "Unsupported SPKI algorithm OID: #{oid.oid}" if algorithm.nil?
|
|
94
|
+
|
|
95
|
+
algorithm
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def validate_public_key_algorithm!(algorithm_symbol, entry)
|
|
99
|
+
return if %i[ml_kem ml_dsa].include?(entry.fetch(:family))
|
|
100
|
+
|
|
101
|
+
raise SerializationError, "SPKI public key codec is not supported for #{algorithm_symbol.inspect}"
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def encode_base64(bytes)
|
|
105
|
+
[String(bytes).b].pack("m0")
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def decode_base64(body)
|
|
109
|
+
compact = body.gsub(/[\r\n]/, "")
|
|
110
|
+
unless compact.match?(/\A(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?\z/)
|
|
111
|
+
raise SerializationError, "Invalid SPKI PEM: invalid base64"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
compact.unpack1("m0").b
|
|
115
|
+
rescue ArgumentError => e
|
|
116
|
+
raise SerializationError, e.message
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def der_from_pem(pem)
|
|
120
|
+
text = String(pem)
|
|
121
|
+
match = text.match(/\A#{Regexp.escape(PEM_BEGIN)}\r?\n(?<body>[A-Za-z0-9+\/=\r\n]+)\r?\n#{Regexp.escape(PEM_END)}[ \t\r\n]*\z/)
|
|
122
|
+
raise SerializationError, "Invalid SPKI PEM: expected #{PEM_LABEL.inspect} label" unless match
|
|
123
|
+
|
|
124
|
+
body = match[:body]
|
|
125
|
+
raise SerializationError, "Invalid SPKI PEM: embedded NUL in body" if body.include?("\0")
|
|
126
|
+
|
|
127
|
+
decode_base64(body)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
data/lib/pq_crypto/version.rb
CHANGED
data/lib/pq_crypto.rb
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "rbconfig"
|
|
4
|
-
require_relative "pq_crypto/version"
|
|
5
|
-
require_relative "pq_crypto/errors"
|
|
6
|
-
|
|
7
3
|
begin
|
|
8
|
-
require "pqcrypto/pqcrypto_secure"
|
|
4
|
+
require "pqcrypto/pqcrypto_secure" # native extension first
|
|
9
5
|
rescue LoadError => original_error
|
|
6
|
+
require "rbconfig"
|
|
7
|
+
|
|
10
8
|
ext_dir = File.expand_path("pqcrypto", __dir__)
|
|
11
9
|
extensions = [".#{RbConfig::CONFIG.fetch('DLEXT')}", ".bundle", ".so"].uniq
|
|
12
10
|
search_dirs = [ext_dir, File.join(ext_dir, "pqcrypto")].uniq
|
|
@@ -30,13 +28,21 @@ rescue LoadError => original_error
|
|
|
30
28
|
raise original_error unless loaded
|
|
31
29
|
end
|
|
32
30
|
|
|
31
|
+
require_relative "pq_crypto/errors"
|
|
32
|
+
require_relative "pq_crypto/version"
|
|
33
|
+
require_relative "pq_crypto/algorithm_registry"
|
|
33
34
|
require_relative "pq_crypto/serialization"
|
|
35
|
+
require_relative "pq_crypto/spki"
|
|
36
|
+
require_relative "pq_crypto/pkcs8"
|
|
37
|
+
require_relative "pq_crypto/kem"
|
|
38
|
+
require_relative "pq_crypto/signature"
|
|
39
|
+
require_relative "pq_crypto/hybrid_kem"
|
|
34
40
|
|
|
35
41
|
module PQCrypto
|
|
36
42
|
SUITES = {
|
|
37
|
-
kem:
|
|
38
|
-
hybrid_kem:
|
|
39
|
-
signature:
|
|
43
|
+
kem: AlgorithmRegistry.supported_kems,
|
|
44
|
+
hybrid_kem: AlgorithmRegistry.supported_hybrid_kems,
|
|
45
|
+
signature: AlgorithmRegistry.supported_signatures,
|
|
40
46
|
}.freeze
|
|
41
47
|
|
|
42
48
|
NATIVE_EXTENSION_LOADED = true
|
|
@@ -44,14 +50,32 @@ module PQCrypto
|
|
|
44
50
|
module NativeBindings
|
|
45
51
|
NATIVE_METHODS = %i[
|
|
46
52
|
ml_kem_keypair
|
|
53
|
+
ml_kem_keypair_from_seed
|
|
47
54
|
ml_kem_encapsulate
|
|
48
55
|
ml_kem_decapsulate
|
|
56
|
+
ml_kem_512_keypair
|
|
57
|
+
ml_kem_512_keypair_from_seed
|
|
58
|
+
ml_kem_512_encapsulate
|
|
59
|
+
ml_kem_512_decapsulate
|
|
60
|
+
ml_kem_1024_keypair
|
|
61
|
+
ml_kem_1024_keypair_from_seed
|
|
62
|
+
ml_kem_1024_encapsulate
|
|
63
|
+
ml_kem_1024_decapsulate
|
|
49
64
|
hybrid_kem_keypair
|
|
50
65
|
hybrid_kem_encapsulate
|
|
51
66
|
hybrid_kem_decapsulate
|
|
52
67
|
sign_keypair
|
|
53
68
|
sign
|
|
54
69
|
verify
|
|
70
|
+
ml_dsa_44_keypair
|
|
71
|
+
ml_dsa_44_keypair_from_seed
|
|
72
|
+
ml_dsa_keypair_from_seed
|
|
73
|
+
ml_dsa_44_sign
|
|
74
|
+
ml_dsa_44_verify
|
|
75
|
+
ml_dsa_87_keypair
|
|
76
|
+
ml_dsa_87_keypair_from_seed
|
|
77
|
+
ml_dsa_87_sign
|
|
78
|
+
ml_dsa_87_verify
|
|
55
79
|
ct_equals
|
|
56
80
|
secure_wipe
|
|
57
81
|
version
|
|
@@ -65,8 +89,14 @@ module PQCrypto
|
|
|
65
89
|
secret_key_from_pqc_container_pem
|
|
66
90
|
__test_ml_kem_keypair_from_seed
|
|
67
91
|
__test_ml_kem_encapsulate_from_seed
|
|
92
|
+
__test_ml_kem_512_encapsulate_from_seed
|
|
93
|
+
__test_ml_kem_1024_encapsulate_from_seed
|
|
68
94
|
__test_sign_keypair_from_seed
|
|
95
|
+
__test_ml_dsa_44_keypair_from_seed
|
|
96
|
+
__test_ml_dsa_87_keypair_from_seed
|
|
69
97
|
__test_sign_from_seed
|
|
98
|
+
__test_ml_dsa_44_sign_from_seed
|
|
99
|
+
__test_ml_dsa_87_sign_from_seed
|
|
70
100
|
].freeze
|
|
71
101
|
|
|
72
102
|
EXTERNAL_MU_METHODS = %i[
|
|
@@ -127,32 +157,61 @@ module PQCrypto
|
|
|
127
157
|
end
|
|
128
158
|
|
|
129
159
|
module Testing
|
|
130
|
-
|
|
131
|
-
|
|
160
|
+
KEM_KEYPAIR_METHODS = {
|
|
161
|
+
ml_kem_512: :native_ml_kem_512_keypair_from_seed,
|
|
162
|
+
ml_kem_768: :native_ml_kem_keypair_from_seed,
|
|
163
|
+
ml_kem_1024: :native_ml_kem_1024_keypair_from_seed,
|
|
164
|
+
}.freeze
|
|
165
|
+
|
|
166
|
+
KEM_ENCAPSULATE_METHODS = {
|
|
167
|
+
ml_kem_512: :native_test_ml_kem_512_encapsulate_from_seed,
|
|
168
|
+
ml_kem_768: :native_test_ml_kem_encapsulate_from_seed,
|
|
169
|
+
ml_kem_1024: :native_test_ml_kem_1024_encapsulate_from_seed,
|
|
170
|
+
}.freeze
|
|
171
|
+
|
|
172
|
+
MLDSA_KEYPAIR_METHODS = {
|
|
173
|
+
ml_dsa_44: :native_test_ml_dsa_44_keypair_from_seed,
|
|
174
|
+
ml_dsa_65: :native_test_sign_keypair_from_seed,
|
|
175
|
+
ml_dsa_87: :native_test_ml_dsa_87_keypair_from_seed,
|
|
176
|
+
}.freeze
|
|
177
|
+
|
|
178
|
+
MLDSA_SIGN_METHODS = {
|
|
179
|
+
ml_dsa_44: :native_test_ml_dsa_44_sign_from_seed,
|
|
180
|
+
ml_dsa_65: :native_test_sign_from_seed,
|
|
181
|
+
ml_dsa_87: :native_test_ml_dsa_87_sign_from_seed,
|
|
182
|
+
}.freeze
|
|
183
|
+
|
|
184
|
+
def self.ml_kem_keypair_from_seed(seed, algorithm: :ml_kem_768)
|
|
185
|
+
PQCrypto.__send__(KEM_KEYPAIR_METHODS.fetch(algorithm), String(seed).b)
|
|
186
|
+
rescue KeyError
|
|
187
|
+
raise UnsupportedAlgorithmError, "Unsupported ML-KEM KAT algorithm: #{algorithm.inspect}"
|
|
132
188
|
rescue ArgumentError => e
|
|
133
189
|
raise InvalidKeyError, e.message
|
|
134
190
|
end
|
|
135
191
|
|
|
136
|
-
def self.ml_kem_encapsulate_from_seed(public_key, seed)
|
|
137
|
-
PQCrypto.__send__(
|
|
192
|
+
def self.ml_kem_encapsulate_from_seed(public_key, seed, algorithm: :ml_kem_768)
|
|
193
|
+
PQCrypto.__send__(KEM_ENCAPSULATE_METHODS.fetch(algorithm), String(public_key).b, String(seed).b)
|
|
194
|
+
rescue KeyError
|
|
195
|
+
raise UnsupportedAlgorithmError, "Unsupported ML-KEM KAT algorithm: #{algorithm.inspect}"
|
|
138
196
|
rescue ArgumentError => e
|
|
139
197
|
raise InvalidKeyError, e.message
|
|
140
198
|
end
|
|
141
199
|
|
|
142
|
-
def self.ml_dsa_keypair_from_seed(seed)
|
|
143
|
-
PQCrypto.__send__(
|
|
200
|
+
def self.ml_dsa_keypair_from_seed(seed, algorithm: :ml_dsa_65)
|
|
201
|
+
PQCrypto.__send__(MLDSA_KEYPAIR_METHODS.fetch(algorithm), String(seed).b)
|
|
202
|
+
rescue KeyError
|
|
203
|
+
raise UnsupportedAlgorithmError, "Unsupported ML-DSA KAT algorithm: #{algorithm.inspect}"
|
|
144
204
|
rescue ArgumentError => e
|
|
145
205
|
raise InvalidKeyError, e.message
|
|
146
206
|
end
|
|
147
207
|
|
|
148
|
-
def self.ml_dsa_sign_from_seed(message, secret_key, seed)
|
|
149
|
-
PQCrypto.__send__(
|
|
208
|
+
def self.ml_dsa_sign_from_seed(message, secret_key, seed, algorithm: :ml_dsa_65)
|
|
209
|
+
PQCrypto.__send__(MLDSA_SIGN_METHODS.fetch(algorithm), String(message).b, String(secret_key).b, String(seed).b)
|
|
210
|
+
rescue KeyError
|
|
211
|
+
raise UnsupportedAlgorithmError, "Unsupported ML-DSA KAT algorithm: #{algorithm.inspect}"
|
|
150
212
|
rescue ArgumentError => e
|
|
151
213
|
raise InvalidKeyError, e.message
|
|
152
214
|
end
|
|
153
215
|
end
|
|
154
216
|
end
|
|
155
217
|
|
|
156
|
-
require_relative "pq_crypto/kem"
|
|
157
|
-
require_relative "pq_crypto/hybrid_kem"
|
|
158
|
-
require_relative "pq_crypto/signature"
|
data/script/vendor_libs.rb
CHANGED
|
@@ -19,8 +19,12 @@ DEFAULT_PQCLEAN = {
|
|
|
19
19
|
}.freeze
|
|
20
20
|
|
|
21
21
|
KEEP_DIRS = %w[
|
|
22
|
+
crypto_kem/ml-kem-512/clean
|
|
22
23
|
crypto_kem/ml-kem-768/clean
|
|
24
|
+
crypto_kem/ml-kem-1024/clean
|
|
25
|
+
crypto_sign/ml-dsa-44/clean
|
|
23
26
|
crypto_sign/ml-dsa-65/clean
|
|
27
|
+
crypto_sign/ml-dsa-87/clean
|
|
24
28
|
common
|
|
25
29
|
].freeze
|
|
26
30
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pq_crypto
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Roman Haydarov
|
|
@@ -51,8 +51,8 @@ dependencies:
|
|
|
51
51
|
- - "~>"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
53
|
version: '5.0'
|
|
54
|
-
description: Native Ruby wrapper around ML-KEM
|
|
55
|
-
|
|
54
|
+
description: Native Ruby wrapper around ML-KEM, ML-DSA, and an optional hybrid ML-KEM-768+X25519
|
|
55
|
+
KEM, backed by PQClean and OpenSSL.
|
|
56
56
|
email:
|
|
57
57
|
- romanhajdarov@gmail.com
|
|
58
58
|
executables: []
|
|
@@ -74,6 +74,7 @@ files:
|
|
|
74
74
|
- ext/pqcrypto/pqcrypto_ruby_secure.c
|
|
75
75
|
- ext/pqcrypto/pqcrypto_secure.c
|
|
76
76
|
- ext/pqcrypto/pqcrypto_secure.h
|
|
77
|
+
- ext/pqcrypto/pqcrypto_version.h
|
|
77
78
|
- ext/pqcrypto/vendor/.vendored
|
|
78
79
|
- ext/pqcrypto/vendor/pqclean/common/aes.c
|
|
79
80
|
- ext/pqcrypto/vendor/pqclean/common/aes.h
|
|
@@ -100,6 +101,52 @@ files:
|
|
|
100
101
|
- ext/pqcrypto/vendor/pqclean/common/sha2.h
|
|
101
102
|
- ext/pqcrypto/vendor/pqclean/common/sp800-185.c
|
|
102
103
|
- ext/pqcrypto/vendor/pqclean/common/sp800-185.h
|
|
104
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/LICENSE
|
|
105
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/Makefile
|
|
106
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/Makefile.Microsoft_nmake
|
|
107
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/api.h
|
|
108
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/cbd.c
|
|
109
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/cbd.h
|
|
110
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/indcpa.c
|
|
111
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/indcpa.h
|
|
112
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/kem.c
|
|
113
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/kem.h
|
|
114
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/ntt.c
|
|
115
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/ntt.h
|
|
116
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/params.h
|
|
117
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/poly.c
|
|
118
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/poly.h
|
|
119
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/polyvec.c
|
|
120
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/polyvec.h
|
|
121
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/reduce.c
|
|
122
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/reduce.h
|
|
123
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/symmetric-shake.c
|
|
124
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/symmetric.h
|
|
125
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/verify.c
|
|
126
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/verify.h
|
|
127
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/LICENSE
|
|
128
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/Makefile
|
|
129
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/Makefile.Microsoft_nmake
|
|
130
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/api.h
|
|
131
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/cbd.c
|
|
132
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/cbd.h
|
|
133
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/indcpa.c
|
|
134
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/indcpa.h
|
|
135
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/kem.c
|
|
136
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/kem.h
|
|
137
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/ntt.c
|
|
138
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/ntt.h
|
|
139
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/params.h
|
|
140
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/poly.c
|
|
141
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/poly.h
|
|
142
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/polyvec.c
|
|
143
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/polyvec.h
|
|
144
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/reduce.c
|
|
145
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/reduce.h
|
|
146
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/symmetric-shake.c
|
|
147
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/symmetric.h
|
|
148
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/verify.c
|
|
149
|
+
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/verify.h
|
|
103
150
|
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/LICENSE
|
|
104
151
|
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/Makefile
|
|
105
152
|
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/Makefile.Microsoft_nmake
|
|
@@ -123,6 +170,27 @@ files:
|
|
|
123
170
|
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/symmetric.h
|
|
124
171
|
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/verify.c
|
|
125
172
|
- ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/verify.h
|
|
173
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/LICENSE
|
|
174
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/Makefile
|
|
175
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/Makefile.Microsoft_nmake
|
|
176
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/api.h
|
|
177
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/ntt.c
|
|
178
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/ntt.h
|
|
179
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/packing.c
|
|
180
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/packing.h
|
|
181
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/params.h
|
|
182
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/poly.c
|
|
183
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/poly.h
|
|
184
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/polyvec.c
|
|
185
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/polyvec.h
|
|
186
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/reduce.c
|
|
187
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/reduce.h
|
|
188
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/rounding.c
|
|
189
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/rounding.h
|
|
190
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/sign.c
|
|
191
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/sign.h
|
|
192
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/symmetric-shake.c
|
|
193
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/symmetric.h
|
|
126
194
|
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/LICENSE
|
|
127
195
|
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/Makefile
|
|
128
196
|
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/Makefile.Microsoft_nmake
|
|
@@ -144,12 +212,36 @@ files:
|
|
|
144
212
|
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/sign.h
|
|
145
213
|
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/symmetric-shake.c
|
|
146
214
|
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/symmetric.h
|
|
215
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/LICENSE
|
|
216
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/Makefile
|
|
217
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/Makefile.Microsoft_nmake
|
|
218
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/api.h
|
|
219
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/ntt.c
|
|
220
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/ntt.h
|
|
221
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/packing.c
|
|
222
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/packing.h
|
|
223
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/params.h
|
|
224
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/poly.c
|
|
225
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/poly.h
|
|
226
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/polyvec.c
|
|
227
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/polyvec.h
|
|
228
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/reduce.c
|
|
229
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/reduce.h
|
|
230
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/rounding.c
|
|
231
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/rounding.h
|
|
232
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/sign.c
|
|
233
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/sign.h
|
|
234
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/symmetric-shake.c
|
|
235
|
+
- ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/symmetric.h
|
|
147
236
|
- lib/pq_crypto.rb
|
|
237
|
+
- lib/pq_crypto/algorithm_registry.rb
|
|
148
238
|
- lib/pq_crypto/errors.rb
|
|
149
239
|
- lib/pq_crypto/hybrid_kem.rb
|
|
150
240
|
- lib/pq_crypto/kem.rb
|
|
241
|
+
- lib/pq_crypto/pkcs8.rb
|
|
151
242
|
- lib/pq_crypto/serialization.rb
|
|
152
243
|
- lib/pq_crypto/signature.rb
|
|
244
|
+
- lib/pq_crypto/spki.rb
|
|
153
245
|
- lib/pq_crypto/version.rb
|
|
154
246
|
- lib/pqcrypto.rb
|
|
155
247
|
- script/vendor_libs.rb
|