Class: Miscreant::AES::SIV

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

Overview

The AES-SIV misuse resistant authenticated encryption cipher

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(key) ⇒ Miscreant::AES::SIV

Create a new AES-SIV instance

Parameters:

  • key (String)

    32-byte or 64-byte Encoding::BINARY cryptographic key

Raises:

  • (TypeError)


23
24
25
26
27
28
29
30
31
32
# File 'lib/miscreant/aes/siv.rb', line 23

def initialize(key)
  raise TypeError, "expected String, got #{key.class}" unless key.is_a?(String)
  raise ArgumentError, "key must be Encoding::BINARY" unless key.encoding == Encoding::BINARY
  raise ArgumentError, "key must be 32 or 64 bytes" unless [32, 64].include?(key.length)

  length = key.length / 2

  @mac_key = key.slice(0, length)
  @enc_key = key.slice(length..-1)
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)


13
14
15
16
# File 'lib/miscreant/aes/siv.rb', line 13

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

Instance Method Details

#inspectString

Inspect this AES-SIV instance

Returns:

  • (String)

    description of this instance



37
38
39
# File 'lib/miscreant/aes/siv.rb', line 37

def inspect
  to_s
end

#open(ciphertext, associated_data = []) ⇒ String

Verify and decrypt an AES-SIV ciphertext, authenticating it along with the associated data

Parameters:

  • ciphertext (String)

    an Encoding::BINARY string to decrypt

  • associated_data (Array<String>) (defaults to: [])

    optional array of message headers to authenticate

Returns:

  • (String)

    decrypted plaintext

Raises:



63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/miscreant/aes/siv.rb', line 63

def open(ciphertext, associated_data = [])
  raise TypeError, "expected String, got #{ciphertext.class}" unless ciphertext.is_a?(String)
  raise ArgumentError, "ciphertext must be Encoding::BINARY" unless ciphertext.encoding == Encoding::BINARY

  v = ciphertext.slice(0, AES::BLOCK_SIZE)
  ciphertext = ciphertext.slice(AES::BLOCK_SIZE..-1)
  plaintext = _transform(v, ciphertext)

  t = _s2v(associated_data, plaintext)
  raise IntegrityError, "ciphertext verification failure!" unless Util.ct_equal(t, v)

  plaintext
end

#seal(plaintext, associated_data = []) ⇒ String

Encrypt a message using AES-SIV, authenticating it along with the associated data

Parameters:

  • plaintext (String)

    an Encoding::BINARY string to encrypt

  • associated_data (Array<String>) (defaults to: [])

    optional array of message headers to authenticate

Returns:

  • (String)

    encrypted ciphertext

Raises:

  • (TypeError)


47
48
49
50
51
52
53
54
# File 'lib/miscreant/aes/siv.rb', line 47

def seal(plaintext, associated_data = [])
  raise TypeError, "expected String, got #{plaintext.class}" unless plaintext.is_a?(String)
  raise ArgumentError, "plaintext must be Encoding::BINARY" unless plaintext.encoding == Encoding::BINARY

  v = _s2v(associated_data, plaintext)
  ciphertext = _transform(v, plaintext)
  v + ciphertext
end