pq_crypto 0.6.0 → 0.6.1
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/CHANGELOG.md +7 -0
- data/ext/pqcrypto/extconf.rb +2 -0
- data/ext/pqcrypto/pqcrypto_ruby_secure.c +139 -0
- data/ext/pqcrypto/pqcrypto_secure.c +532 -0
- data/ext/pqcrypto/pqcrypto_secure.h +20 -0
- data/ext/pqcrypto/pqcrypto_version.h +1 -1
- data/lib/pq_crypto/hybrid_kem.rb +1 -1
- data/lib/pq_crypto/internal.rb +23 -0
- data/lib/pq_crypto/kem.rb +27 -34
- data/lib/pq_crypto/pkcs8/der.rb +68 -0
- data/lib/pq_crypto/pkcs8/private_key_choice.rb +186 -0
- data/lib/pq_crypto/pkcs8.rb +51 -468
- data/lib/pq_crypto/serialization.rb +19 -29
- data/lib/pq_crypto/signature.rb +28 -35
- data/lib/pq_crypto/version.rb +1 -1
- data/lib/pq_crypto.rb +10 -0
- metadata +4 -1
data/lib/pq_crypto/signature.rb
CHANGED
|
@@ -189,7 +189,7 @@ module PQCrypto
|
|
|
189
189
|
builder = PQCrypto.__send__(:_native_mldsa_mu_builder_new, tr, context)
|
|
190
190
|
builder_consumed = false
|
|
191
191
|
mu = nil
|
|
192
|
-
sig_bytes =
|
|
192
|
+
sig_bytes = Internal.binary_string(signature)
|
|
193
193
|
begin
|
|
194
194
|
_drain_io_into_builder(io, builder, chunk_size)
|
|
195
195
|
mu = PQCrypto.__send__(:_native_mldsa_mu_builder_finalize, builder)
|
|
@@ -230,7 +230,7 @@ module PQCrypto
|
|
|
230
230
|
end
|
|
231
231
|
|
|
232
232
|
def validate_context!(context)
|
|
233
|
-
ctx =
|
|
233
|
+
ctx = Internal.binary_string(context)
|
|
234
234
|
if ctx.bytesize > 255
|
|
235
235
|
raise ArgumentError, "context must be at most 255 bytes (FIPS 204)"
|
|
236
236
|
end
|
|
@@ -264,7 +264,7 @@ module PQCrypto
|
|
|
264
264
|
|
|
265
265
|
def initialize(algorithm, bytes)
|
|
266
266
|
@algorithm = algorithm
|
|
267
|
-
@bytes =
|
|
267
|
+
@bytes = Internal.binary_string(bytes)
|
|
268
268
|
validate_length!
|
|
269
269
|
end
|
|
270
270
|
|
|
@@ -291,7 +291,7 @@ module PQCrypto
|
|
|
291
291
|
def verify(message, signature, context: "".b)
|
|
292
292
|
context = Signature.send(:validate_context!, context)
|
|
293
293
|
begin
|
|
294
|
-
PQCrypto.__send__(Signature.send(:native_method_for, @algorithm, :verify),
|
|
294
|
+
PQCrypto.__send__(Signature.send(:native_method_for, @algorithm, :verify), Internal.binary_string(message), Internal.binary_string(signature), @bytes, context)
|
|
295
295
|
rescue ArgumentError => e
|
|
296
296
|
raise InvalidKeyError, e.message
|
|
297
297
|
end
|
|
@@ -315,7 +315,7 @@ module PQCrypto
|
|
|
315
315
|
|
|
316
316
|
def ==(other)
|
|
317
317
|
return false unless other.is_a?(PublicKey) && other.algorithm == algorithm
|
|
318
|
-
|
|
318
|
+
Internal.constant_time_equal?(other.send(:bytes_for_native), @bytes)
|
|
319
319
|
end
|
|
320
320
|
|
|
321
321
|
alias eql? ==
|
|
@@ -345,14 +345,14 @@ module PQCrypto
|
|
|
345
345
|
|
|
346
346
|
def initialize(algorithm, bytes, seed: nil)
|
|
347
347
|
@algorithm = algorithm
|
|
348
|
-
@bytes =
|
|
349
|
-
@seed = seed.nil? ? nil :
|
|
348
|
+
@bytes = Internal.binary_string(bytes)
|
|
349
|
+
@seed = seed.nil? ? nil : Internal.binary_string(seed)
|
|
350
350
|
validate_length!
|
|
351
351
|
validate_seed_length! if @seed
|
|
352
352
|
end
|
|
353
353
|
|
|
354
354
|
def self.from_seed(algorithm, seed)
|
|
355
|
-
seed_bytes =
|
|
355
|
+
seed_bytes = Internal.binary_string(seed)
|
|
356
356
|
_public_key, expanded = PQCrypto.__send__(Signature.send(:native_method_for, algorithm, :keypair_from_seed), seed_bytes)
|
|
357
357
|
new(algorithm, expanded, seed: seed_bytes)
|
|
358
358
|
rescue ArgumentError => e
|
|
@@ -372,39 +372,17 @@ module PQCrypto
|
|
|
372
372
|
end
|
|
373
373
|
|
|
374
374
|
def to_pkcs8_der(format: :expanded, passphrase: nil, iterations: PKCS8::ENCRYPTED_PKCS8_DEFAULT_ITERATIONS)
|
|
375
|
-
|
|
376
|
-
when :expanded
|
|
377
|
-
PKCS8.encode_der(@algorithm, @bytes, format: :expanded, passphrase: passphrase, iterations: iterations)
|
|
378
|
-
when :seed
|
|
379
|
-
ensure_seed_available!(format)
|
|
380
|
-
PKCS8.encode_der(@algorithm, @seed, format: :seed, passphrase: passphrase, iterations: iterations)
|
|
381
|
-
when :both
|
|
382
|
-
ensure_seed_available!(format)
|
|
383
|
-
PKCS8.encode_der(@algorithm, [@seed, @bytes], format: :both, passphrase: passphrase, iterations: iterations)
|
|
384
|
-
else
|
|
385
|
-
raise SerializationError, "Unsupported PKCS#8 private key format: #{format.inspect}"
|
|
386
|
-
end
|
|
375
|
+
PKCS8.encode_der(@algorithm, pkcs8_material(format), format: format, passphrase: passphrase, iterations: iterations)
|
|
387
376
|
end
|
|
388
377
|
|
|
389
378
|
def to_pkcs8_pem(format: :expanded, passphrase: nil, iterations: PKCS8::ENCRYPTED_PKCS8_DEFAULT_ITERATIONS)
|
|
390
|
-
|
|
391
|
-
when :expanded
|
|
392
|
-
PKCS8.encode_pem(@algorithm, @bytes, format: :expanded, passphrase: passphrase, iterations: iterations)
|
|
393
|
-
when :seed
|
|
394
|
-
ensure_seed_available!(format)
|
|
395
|
-
PKCS8.encode_pem(@algorithm, @seed, format: :seed, passphrase: passphrase, iterations: iterations)
|
|
396
|
-
when :both
|
|
397
|
-
ensure_seed_available!(format)
|
|
398
|
-
PKCS8.encode_pem(@algorithm, [@seed, @bytes], format: :both, passphrase: passphrase, iterations: iterations)
|
|
399
|
-
else
|
|
400
|
-
raise SerializationError, "Unsupported PKCS#8 private key format: #{format.inspect}"
|
|
401
|
-
end
|
|
379
|
+
PKCS8.encode_pem(@algorithm, pkcs8_material(format), format: format, passphrase: passphrase, iterations: iterations)
|
|
402
380
|
end
|
|
403
381
|
|
|
404
382
|
def sign(message, context: "".b)
|
|
405
383
|
context = Signature.send(:validate_context!, context)
|
|
406
384
|
begin
|
|
407
|
-
PQCrypto.__send__(Signature.send(:native_method_for, @algorithm, :sign),
|
|
385
|
+
PQCrypto.__send__(Signature.send(:native_method_for, @algorithm, :sign), Internal.binary_string(message), @bytes, context)
|
|
408
386
|
rescue ArgumentError => e
|
|
409
387
|
raise InvalidKeyError, e.message
|
|
410
388
|
end
|
|
@@ -422,7 +400,7 @@ module PQCrypto
|
|
|
422
400
|
|
|
423
401
|
def ==(other)
|
|
424
402
|
return false unless other.is_a?(SecretKey) && other.algorithm == algorithm
|
|
425
|
-
|
|
403
|
+
Internal.constant_time_equal?(other.send(:bytes_for_native), @bytes)
|
|
426
404
|
end
|
|
427
405
|
|
|
428
406
|
alias eql? ==
|
|
@@ -446,8 +424,23 @@ module PQCrypto
|
|
|
446
424
|
raise InvalidKeyError, "Invalid signature secret key length" unless @bytes.bytesize == expected
|
|
447
425
|
end
|
|
448
426
|
|
|
427
|
+
def pkcs8_material(format)
|
|
428
|
+
case format
|
|
429
|
+
when :expanded
|
|
430
|
+
@bytes
|
|
431
|
+
when :seed
|
|
432
|
+
ensure_seed_available!(format)
|
|
433
|
+
@seed
|
|
434
|
+
when :both
|
|
435
|
+
ensure_seed_available!(format)
|
|
436
|
+
[@seed, @bytes]
|
|
437
|
+
else
|
|
438
|
+
raise SerializationError, "Unsupported PKCS#8 private key format: #{format.inspect}"
|
|
439
|
+
end
|
|
440
|
+
end
|
|
441
|
+
|
|
449
442
|
def validate_seed_length!
|
|
450
|
-
expected = PKCS8::
|
|
443
|
+
expected = PKCS8::PrivateKeyChoice.seed_bytes(@algorithm)
|
|
451
444
|
raise InvalidKeyError, "Invalid signature seed length" unless @seed.bytesize == expected
|
|
452
445
|
end
|
|
453
446
|
|
data/lib/pq_crypto/version.rb
CHANGED
data/lib/pq_crypto.rb
CHANGED
|
@@ -30,9 +30,12 @@ end
|
|
|
30
30
|
|
|
31
31
|
require_relative "pq_crypto/errors"
|
|
32
32
|
require_relative "pq_crypto/version"
|
|
33
|
+
require_relative "pq_crypto/internal"
|
|
33
34
|
require_relative "pq_crypto/algorithm_registry"
|
|
34
35
|
require_relative "pq_crypto/serialization"
|
|
35
36
|
require_relative "pq_crypto/spki"
|
|
37
|
+
require_relative "pq_crypto/pkcs8/der"
|
|
38
|
+
require_relative "pq_crypto/pkcs8/private_key_choice"
|
|
36
39
|
require_relative "pq_crypto/pkcs8"
|
|
37
40
|
require_relative "pq_crypto/kem"
|
|
38
41
|
require_relative "pq_crypto/signature"
|
|
@@ -93,6 +96,13 @@ module PQCrypto
|
|
|
93
96
|
public_key_from_pqc_container_pem
|
|
94
97
|
secret_key_from_pqc_container_der
|
|
95
98
|
secret_key_from_pqc_container_pem
|
|
99
|
+
pkcs8_private_key_info_to_der
|
|
100
|
+
pkcs8_private_key_info_from_der
|
|
101
|
+
pkcs8_encrypt_der
|
|
102
|
+
pkcs8_decrypt_der
|
|
103
|
+
pkcs8_encrypted_der?
|
|
104
|
+
pkcs8_der_to_pem
|
|
105
|
+
pkcs8_pem_to_der
|
|
96
106
|
__test_ml_kem_keypair_from_seed
|
|
97
107
|
__test_ml_kem_encapsulate_from_seed
|
|
98
108
|
__test_ml_kem_512_encapsulate_from_seed
|
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.6.
|
|
4
|
+
version: 0.6.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Roman Haydarov
|
|
@@ -314,9 +314,12 @@ files:
|
|
|
314
314
|
- lib/pq_crypto/algorithm_registry.rb
|
|
315
315
|
- lib/pq_crypto/errors.rb
|
|
316
316
|
- lib/pq_crypto/hybrid_kem.rb
|
|
317
|
+
- lib/pq_crypto/internal.rb
|
|
317
318
|
- lib/pq_crypto/kem.rb
|
|
318
319
|
- lib/pq_crypto/key.rb
|
|
319
320
|
- lib/pq_crypto/pkcs8.rb
|
|
321
|
+
- lib/pq_crypto/pkcs8/der.rb
|
|
322
|
+
- lib/pq_crypto/pkcs8/private_key_choice.rb
|
|
320
323
|
- lib/pq_crypto/serialization.rb
|
|
321
324
|
- lib/pq_crypto/signature.rb
|
|
322
325
|
- lib/pq_crypto/spki.rb
|