Class: Noise::State::SymmetricState

Inherits:
Object
  • Object
show all
Defined in:
lib/noise/state/symmetric_state.rb

Overview

A SymmetricState object contains a CipherState plus the following variables:

  • ck: A chaining key of HASHLEN bytes.
  • h: A hash output of HASHLEN bytes.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(protocol, connection) ⇒ SymmetricState

Returns a new instance of SymmetricState.



13
14
15
16
17
18
19
20
# File 'lib/noise/state/symmetric_state.rb', line 13

def initialize(protocol, connection)
  @protocol = protocol
  @connection = connection
  @ck = @h = initialize_h(protocol)

  @cipher_state = CipherState.new(cipher: @protocol.cipher_fn)
  @cipher_state.initialize_key(nil)
end

Instance Attribute Details

#cipher_stateObject (readonly)

Returns the value of attribute cipher_state.



11
12
13
# File 'lib/noise/state/symmetric_state.rb', line 11

def cipher_state
  @cipher_state
end

#ckObject (readonly)

Returns the value of attribute ck.



11
12
13
# File 'lib/noise/state/symmetric_state.rb', line 11

def ck
  @ck
end

#hObject (readonly)

Returns the value of attribute h.



11
12
13
# File 'lib/noise/state/symmetric_state.rb', line 11

def h
  @h
end

Class Method Details

.initialize_symmetric(protocol, connection, prologue: nil) ⇒ Object



22
23
24
# File 'lib/noise/state/symmetric_state.rb', line 22

def self.initialize_symmetric(protocol, connection, prologue: nil)
  new(protocol, connection).tap { |s| s.mix_hash(prologue) if prologue }
end

Instance Method Details

#decrypt_and_hash(ciphertext) ⇒ Object

Note that if k is empty, the DecryptWithAd() call will set plaintext equal to ciphertext.



61
62
63
64
65
# File 'lib/noise/state/symmetric_state.rb', line 61

def decrypt_and_hash(ciphertext)
  plaintext = @cipher_state.decrypt_with_ad(@h, ciphertext)
  mix_hash(ciphertext)
  plaintext
end

#encrypt_and_hash(plaintext) ⇒ Object

Note that if k is empty, the EncryptWithAd() call will set ciphertext equal to plaintext.



54
55
56
57
58
# File 'lib/noise/state/symmetric_state.rb', line 54

def encrypt_and_hash(plaintext)
  ciphertext = @cipher_state.encrypt_with_ad(@h, plaintext)
  mix_hash(ciphertext)
  ciphertext
end

#handshake_hashObject

Returns h. This function should only be called at the end of a handshake, i.e. after the Split() function has been called. This function is used for channel binding



49
50
51
# File 'lib/noise/state/symmetric_state.rb', line 49

def handshake_hash
  @h
end

#mix_hash(data) ⇒ Object

Parameters:

  • data (String)

    binary string to be hashed



33
34
35
# File 'lib/noise/state/symmetric_state.rb', line 33

def mix_hash(data)
  @h = @protocol.hash_fn.hash(@h + data)
end

#mix_key(input_key_meterial) ⇒ Object



26
27
28
29
30
# File 'lib/noise/state/symmetric_state.rb', line 26

def mix_key(input_key_meterial)
  @ck, temp_k = @protocol.hkdf_fn.call(@ck, input_key_meterial, 2)
  temp_k = truncate(temp_k)
  @cipher_state.initialize_key(temp_k)
end

#mix_key_and_hash(input_key_meterial) ⇒ Object

This function is used for handling pre-shared symmetric keys.



38
39
40
41
42
43
# File 'lib/noise/state/symmetric_state.rb', line 38

def mix_key_and_hash(input_key_meterial)
  @ck, temp_h, temp_k = @protocol.hkdf_fn.call(@ck, input_key_meterial, 3)
  mix_hash(temp_h)
  temp_k = truncate(temp_k)
  @cipher_state.initialize_key(temp_k)
end

#splitCipherState

Returns a pair of CipherState objects for encrypting transport messages.

Returns:



68
69
70
71
72
73
74
# File 'lib/noise/state/symmetric_state.rb', line 68

def split
  temp_k1, temp_k2 = @protocol.hkdf_fn.call(@ck, '', 2)
  c1 = create_cipher_state(temp_k1)
  c2 = create_cipher_state(temp_k2)
  @connection.handshake_done(c1, c2)
  [c1, c2]
end