Class: PqcRails::Kem
- Inherits:
-
Object
- Object
- PqcRails::Kem
- Includes:
- LengthValidation
- Defined in:
- lib/pqc_rails/kem.rb
Overview
liboqsのGeneric KEM APIをRubyらしく包んだクラス。
使い方:
kem = PqcRails::Kem.new(:ml_kem_512) # またはliboqsの生の名前 "ML-KEM-512"
keypair = kem.generate_keypair
encap = kem.encapsulate(keypair.public_key)
shared = kem.decapsulate(encap.ciphertext, keypair.secret_key)
shared == encap.shared_secret # => true
kem.free を呼ぶか、ブロック形式(PqcRails::Kem.open)を使うことで Cレベルのメモリを確実に解放できる。
Defined Under Namespace
Classes: Encapsulation, Keypair
Instance Attribute Summary collapse
-
#alg_name ⇒ Object
readonly
Returns the value of attribute alg_name.
Class Method Summary collapse
Instance Method Summary collapse
- #decapsulate(ciphertext, secret_key) ⇒ Object
- #encapsulate(public_key) ⇒ Object
- #free ⇒ Object
- #generate_keypair ⇒ Object
-
#initialize(alg_name) ⇒ Kem
constructor
A new instance of Kem.
- #length_ciphertext ⇒ Object
- #length_public_key ⇒ Object
- #length_secret_key ⇒ Object
- #length_shared_secret ⇒ Object
Constructor Details
#initialize(alg_name) ⇒ Kem
Returns a new instance of Kem.
27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/pqc_rails/kem.rb', line 27 def initialize(alg_name) @alg_name = alg_name liboqs_alg_name = Algorithms.resolve_kem_name(alg_name) @kem_ptr = Ffi::Kem.OQS_KEM_new(liboqs_alg_name) if @kem_ptr.null? raise PqcRails::Error, "OQS_KEM_new failed for '#{liboqs_alg_name}'. " \ "liboqsがこのアルゴリズムを有効にしてビルドされているか確認してください。" end @kem = Ffi::Kem::Struct.new(@kem_ptr) @freed = false end |
Instance Attribute Details
#alg_name ⇒ Object (readonly)
Returns the value of attribute alg_name.
25 26 27 |
# File 'lib/pqc_rails/kem.rb', line 25 def alg_name @alg_name end |
Class Method Details
.open(alg_name) ⇒ Object
103 104 105 106 107 108 |
# File 'lib/pqc_rails/kem.rb', line 103 def self.open(alg_name) kem = new(alg_name) yield kem ensure kem&.free end |
Instance Method Details
#decapsulate(ciphertext, secret_key) ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/pqc_rails/kem.rb', line 79 def decapsulate(ciphertext, secret_key) ensure_not_freed! validate_length!(ciphertext, length_ciphertext, "ciphertext") validate_length!(secret_key, length_secret_key, "secret_key") shared_secret = FFI::MemoryPointer.new(:uint8, length_shared_secret) ct_ptr = FFI::MemoryPointer.new(:uint8, ciphertext.bytesize) ct_ptr.put_bytes(0, ciphertext) sk_ptr = FFI::MemoryPointer.new(:uint8, secret_key.bytesize) sk_ptr.put_bytes(0, secret_key) status = Ffi::Kem.OQS_KEM_decaps(@kem_ptr, shared_secret, ct_ptr, sk_ptr) raise PqcRails::Error, "OQS_KEM_decaps failed (status=#{status})" unless status.zero? shared_secret.read_bytes(length_shared_secret) end |
#encapsulate(public_key) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/pqc_rails/kem.rb', line 61 def encapsulate(public_key) ensure_not_freed! validate_length!(public_key, length_public_key, "public_key") ciphertext = FFI::MemoryPointer.new(:uint8, length_ciphertext) shared_secret = FFI::MemoryPointer.new(:uint8, length_shared_secret) pk_ptr = FFI::MemoryPointer.new(:uint8, public_key.bytesize) pk_ptr.put_bytes(0, public_key) status = Ffi::Kem.OQS_KEM_encaps(@kem_ptr, ciphertext, shared_secret, pk_ptr) raise PqcRails::Error, "OQS_KEM_encaps failed (status=#{status})" unless status.zero? Encapsulation.new( ciphertext.read_bytes(length_ciphertext), shared_secret.read_bytes(length_shared_secret) ) end |
#free ⇒ Object
96 97 98 99 100 101 |
# File 'lib/pqc_rails/kem.rb', line 96 def free return if @freed Ffi::Kem.OQS_KEM_free(@kem_ptr) @freed = true end |
#generate_keypair ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/pqc_rails/kem.rb', line 46 def generate_keypair ensure_not_freed! public_key = FFI::MemoryPointer.new(:uint8, length_public_key) secret_key = FFI::MemoryPointer.new(:uint8, length_secret_key) status = Ffi::Kem.OQS_KEM_keypair(@kem_ptr, public_key, secret_key) raise PqcRails::Error, "OQS_KEM_keypair failed (status=#{status})" unless status.zero? Keypair.new( public_key.read_bytes(length_public_key), secret_key.read_bytes(length_secret_key) ) end |
#length_ciphertext ⇒ Object
43 |
# File 'lib/pqc_rails/kem.rb', line 43 def length_ciphertext = @kem[:length_ciphertext] |
#length_public_key ⇒ Object
41 |
# File 'lib/pqc_rails/kem.rb', line 41 def length_public_key = @kem[:length_public_key] |
#length_secret_key ⇒ Object
42 |
# File 'lib/pqc_rails/kem.rb', line 42 def length_secret_key = @kem[:length_secret_key] |
#length_shared_secret ⇒ Object
44 |
# File 'lib/pqc_rails/kem.rb', line 44 def length_shared_secret = @kem[:length_shared_secret] |