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.



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

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.



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

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



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

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.



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

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.



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

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



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

def handshake_hash
  @h
end

#mix_hash(data) ⇒ Object

Parameters:

  • data (String)

    binary string to be hashed



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

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

#mix_key(input_key_meterial) ⇒ Object



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

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.



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

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:



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

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