Class: Miscreant::AEAD

Inherits:
Object
  • Object
show all
Defined in:
lib/miscreant/aead.rb

Overview

The AEAD class provides Authenticated Encryption with Associated Data

If you're looking for the API to encrypt something, congratulations! This is the one you probably want to use. This class provides a high-level interface to Miscreant's misuse-resistant encryption.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(alg, key) ⇒ AEAD

Create a new AEAD encryptor instance.

You will need to select an algorithm to use, passed as a string:

  • “AES-SIV” (RFC 5297): the original AES-SIV function, based on CMAC

  • “AES-PMAC-SIV”: a parallelizable AES-SIV alternative

Choose AES-PMAC-SIV if you'd like better performance. Choose AES-SIV if you'd like wider compatibility: AES-PMAC-SIV is presently implemented in the Miscreant libraries.

Parameters:

  • alg ("AES-SIV", "AES-PMAC-SIV")

    cryptographic algorithm to use

  • key (String)

    32-byte or 64-byte random Encoding::BINARY secret key


43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/miscreant/aead.rb', line 43

def initialize(alg, key)
  Internals::Util.validate_bytestring("key", key, length: [32, 64])

  case alg
  when "AES-SIV", "AES-CMAC-SIV"
    mac = :CMAC
  when "AES-PMAC-SIV"
    mac = :PMAC
  else raise ArgumentError, "unsupported algorithm: #{alg.inspect}"
  end

  @siv = AES::SIV.new(key, mac)
end

Class Method Details

.generate_key(size = 32) ⇒ String

Generate a new random AES-SIV key of the given size

Parameters:

  • size (Integer) (defaults to: 32)

    size of key in bytes (32 or 64)

Returns:

  • (String)

    newly generated AES-SIV key

Raises:

  • (ArgumentError)

16
17
18
19
# File 'lib/miscreant/aead.rb', line 16

def self.generate_key(size = 32)
  raise ArgumentError, "key size must be 32 or 64 bytes" unless [32, 64].include?(size)
  AES::SIV.generate_key(size)
end

.generate_nonce(size = 16) ⇒ String

Generate a random “nonce” (i.e. number used once) value

Parameters:

  • size (Integer) (defaults to: 16)

    size of nonce in bytes (default 16)

Returns:

  • (String)

    newly generated nonce value


26
27
28
# File 'lib/miscreant/aead.rb', line 26

def self.generate_nonce(size = 16)
  SecureRandom.random_bytes(size)
end

Instance Method Details

#inspectString

Inspect this AES-SIV instance

Returns:

  • (String)

    description of this instance


60
61
62
# File 'lib/miscreant/aead.rb', line 60

def inspect
  to_s
end

#open(ciphertext, nonce:, ad: "") ⇒ String

Verify and decrypt a ciphertext, authenticating it along with the associated data

Parameters:

  • ciphertext (String)

    an Encoding::BINARY string to decrypt

  • nonce (String)

    a unique-per-message value

  • associated_data (String)

    optional data to authenticate along with the message

Returns:

  • (String)

    decrypted plaintext

Raises:


86
87
88
89
90
91
# File 'lib/miscreant/aead.rb', line 86

def open(ciphertext, nonce:, ad: "")
  raise TypeError, "expected nonce to be String, got #{nonce.class}" unless nonce.is_a?(String)
  raise TypeError, "expected ad to be String, got #{ad.class}" unless ad.is_a?(String)

  @siv.open(ciphertext, [ad, nonce])
end

#seal(plaintext, nonce:, ad: "") ⇒ String

Encrypt a message, authenticating it along with the associated data

Parameters:

  • plaintext (String)

    an Encoding::BINARY string to encrypt

  • nonce (String)

    a unique-per-message value

  • ad (String) (defaults to: "")

    optional data to authenticate along with the message

Returns:

  • (String)

    encrypted ciphertext

Raises:

  • (TypeError)

71
72
73
74
75
76
# File 'lib/miscreant/aead.rb', line 71

def seal(plaintext, nonce:, ad: "")
  raise TypeError, "expected String, got #{nonce.class}" unless nonce.is_a?(String)
  raise TypeError, "expected String, got #{ad.class}" unless ad.is_a?(String)

  @siv.seal(plaintext, [ad, nonce])
end