Method: ECIES::Crypt#decrypt

Defined in:
lib/ecies/crypt.rb

#decrypt(key, encrypted_message) ⇒ String

Decrypts a message with a private key using ECIES.

Parameters:

  • key (OpenSSL::EC:PKey)

    The private key.

  • encrypted_message (String)

    Octet string of the encrypted message.

Returns:

  • (String)

    The plain-text message.


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/ecies/crypt.rb', line 87

def decrypt(key, encrypted_message)
  key.private_key? or raise "Must have private key to decrypt"
  @cipher.reset

  ephemeral_public_key_length = key.group.generator.to_octet_string(:compressed).bytesize
  ciphertext_length = encrypted_message.bytesize - ephemeral_public_key_length - @mac_length
  ciphertext_length > 0 or raise OpenSSL::PKey::ECError, "Encrypted message too short"

  ephemeral_public_key_octet = encrypted_message.byteslice(0, ephemeral_public_key_length)
  ciphertext = encrypted_message.byteslice(ephemeral_public_key_length, ciphertext_length)
  mac = encrypted_message.byteslice(-@mac_length, @mac_length)

  ephemeral_public_key = OpenSSL::PKey::EC::Point.new(key.group, OpenSSL::BN.new(ephemeral_public_key_octet, 2))

  shared_secret = key.dh_compute_key(ephemeral_public_key)

  key_pair = kdf(shared_secret, @cipher.key_len + @mac_length, ephemeral_public_key_octet)
  cipher_key = key_pair.byteslice(0, @cipher.key_len)
  hmac_key = key_pair.byteslice(-@mac_length, @mac_length)

  computed_mac = OpenSSL::HMAC.digest(@mac_digest, hmac_key, ciphertext + @mac_shared_info).byteslice(0, @mac_length)
  computed_mac == mac or raise OpenSSL::PKey::ECError, "Invalid Message Authenticaton Code"

  @cipher.decrypt
  @cipher.iv = IV
  @cipher.key = cipher_key

  @cipher.update(ciphertext) + @cipher.final
end