Class: Nuckle::Chacha20Blake3::Cipher

Inherits:
Object
  • Object
show all
Defined in:
lib/nuckle/chacha20_blake3.rb

Overview

Authenticated encryption cipher.

Instance Method Summary collapse

Constructor Details

#initialize(key) ⇒ Cipher

Returns a new instance of Cipher.

Parameters:

  • key (String)

    32-byte master key

Raises:

  • (ArgumentError)


26
27
28
29
30
31
# File 'lib/nuckle/chacha20_blake3.rb', line 26

def initialize(key)
  key = key.b
  raise ArgumentError, "key must be #{KEYBYTES} bytes (got #{key.bytesize})" unless key.bytesize == KEYBYTES

  @key = key
end

Instance Method Details

#decrypt(nonce, ciphertext, aad: "") ⇒ String

Decrypt a ciphertext||tag blob with the given 24-byte nonce.

Parameters:

  • nonce (String)

    24-byte nonce

  • ciphertext (String)

    ciphertext || 32-byte tag

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

Returns:

  • (String)

    plaintext

Raises:



55
56
57
58
59
60
61
62
# File 'lib/nuckle/chacha20_blake3.rb', line 55

def decrypt(nonce, ciphertext, aad: "")
  ciphertext = ciphertext.b
  raise CryptoError, "ciphertext too short" if ciphertext.bytesize < TAGBYTES

  tag = ciphertext.byteslice(ciphertext.bytesize - TAGBYTES, TAGBYTES)
  ct  = ciphertext.byteslice(0, ciphertext.bytesize - TAGBYTES)
  decrypt_detached(nonce, ct, tag, aad: aad)
end

#decrypt_detached(nonce, ciphertext, tag, aad: "") ⇒ Object

Decrypt from a detached ciphertext + tag.

Raises:



77
78
79
80
81
82
83
84
85
86
87
# File 'lib/nuckle/chacha20_blake3.rb', line 77

def decrypt_detached(nonce, ciphertext, tag, aad: "")
  tag = tag.b
  raise ArgumentError, "tag must be #{TAGBYTES} bytes" unless tag.bytesize == TAGBYTES

  ciphertext = ciphertext.b
  enc_key, auth_key, enc_nonce = derive_subkeys(nonce)
  expected = compute_tag(auth_key, aad, ciphertext)
  raise CryptoError, "decryption failed" unless Util.verify32(tag, expected)

  Internals::Chacha20.xor(enc_key, enc_nonce, ciphertext)
end

#encrypt(nonce, plaintext, aad: "") ⇒ String

Encrypt plaintext with the given 24-byte nonce.

Parameters:

  • nonce (String)

    24-byte nonce

  • plaintext (String)
  • aad (String) (defaults to: "")

    associated data (authenticated but not encrypted)

Returns:

  • (String)

    ciphertext || 32-byte tag



40
41
42
43
44
45
# File 'lib/nuckle/chacha20_blake3.rb', line 40

def encrypt(nonce, plaintext, aad: "")
  enc_key, auth_key, enc_nonce = derive_subkeys(nonce)
  ct  = Internals::Chacha20.xor(enc_key, enc_nonce, plaintext)
  tag = compute_tag(auth_key, aad, ct)
  ct + tag
end

#encrypt_detached(nonce, plaintext, aad: "") ⇒ Array(String, String)

Encrypt, returning ciphertext and tag separately.

Returns:

  • (Array(String, String))
    ciphertext, tag


67
68
69
70
71
72
# File 'lib/nuckle/chacha20_blake3.rb', line 67

def encrypt_detached(nonce, plaintext, aad: "")
  enc_key, auth_key, enc_nonce = derive_subkeys(nonce)
  ct  = Internals::Chacha20.xor(enc_key, enc_nonce, plaintext)
  tag = compute_tag(auth_key, aad, ct)
  [ct, tag]
end