Class: Noise::Pattern

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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(modifiers) ⇒ Pattern

Returns a new instance of Pattern.



127
128
129
130
131
132
133
# File 'lib/noise/pattern.rb', line 127

def initialize(modifiers)
  @pre_messages = [[], []]
  @tokens = []
  @name = ''
  @psk_count = 0
  @modifiers = modifiers
end

Instance Attribute Details

#fallbackObject (readonly)

Returns the value of attribute fallback.



103
104
105
# File 'lib/noise/pattern.rb', line 103

def fallback
  @fallback
end

#modifiersObject (readonly)

Returns the value of attribute modifiers.



103
104
105
# File 'lib/noise/pattern.rb', line 103

def modifiers
  @modifiers
end

#nameObject (readonly)

Returns the value of attribute name.



103
104
105
# File 'lib/noise/pattern.rb', line 103

def name
  @name
end

#psk_countObject (readonly)

Returns the value of attribute psk_count.



103
104
105
# File 'lib/noise/pattern.rb', line 103

def psk_count
  @psk_count
end

#tokensObject (readonly)

Returns the value of attribute tokens.



103
104
105
# File 'lib/noise/pattern.rb', line 103

def tokens
  @tokens
end

Class Method Details

.create(name, modifiers = []) ⇒ Noise::Pattern

Noise::ProtocolName tells a pattern name from the modifiers written after it, so both arrive here already separated.

Parameters:

  • name (String)

    the handshake pattern name on its own, for example 'XX'.

  • modifiers (Array<Noise::Modifier::Psk, Noise::Modifier::Fallback>) (defaults to: [])

    the modifiers to apply to it. Call #apply_pattern_modifiers to have them rewrite the token list.

Returns:

Raises:



113
114
115
# File 'lib/noise/pattern.rb', line 113

def self.create(name, modifiers = [])
  pattern_class(name).new(modifiers)
end

Instance Method Details

#apply_pattern_modifiersObject



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/noise/pattern.rb', line 139

def apply_pattern_modifiers
  @modifiers.each do |modifier|
    case modifier
    when Modifier::Psk
      index = modifier.index
      # psk0 prepends to the first message, pskN appends to the Nth one.
      raise Noise::Exceptions::PSKValueError if index > @tokens.size

      if index.zero?
        @tokens[0].insert(0, Token::PSK)
      else
        @tokens[index - 1] << Token::PSK
      end
      @psk_count += 1
    when Modifier::Fallback
      @fallback = true
    end
  end
end

#initiator_pre_messagesObject



178
179
180
# File 'lib/noise/pattern.rb', line 178

def initiator_pre_messages
  (@pre_messages[0] || []).dup
end

#initiator_static?Boolean

A party needs a static keypair when its static public key is either pre-shared with the peer or transmitted during the handshake. Deriving this from the pattern itself keeps deferred patterns (whose names carry a '1', e.g. X1K) working, unlike inspecting single characters of the name.

Returns:

  • (Boolean)


189
190
191
# File 'lib/noise/pattern.rb', line 189

def initiator_static?
  initiator_static_pre_shared? || sends_static?(0)
end

#initiator_static_pre_shared?Boolean

Returns:

  • (Boolean)


197
198
199
# File 'lib/noise/pattern.rb', line 197

def initiator_static_pre_shared?
  initiator_pre_messages.include?(Token::S)
end

#one_way?Boolean

Returns:

  • (Boolean)


210
211
212
# File 'lib/noise/pattern.rb', line 210

def one_way?
  false
end

#psk?Boolean

Returns:

  • (Boolean)


135
136
137
# File 'lib/noise/pattern.rb', line 135

def psk?
  modifiers.any? { |m| m.is_a? Modifier::Psk }
end

#required_keypairs(initiator) ⇒ Object

initiator [Boolean]



160
161
162
# File 'lib/noise/pattern.rb', line 160

def required_keypairs(initiator)
  initiator ? required_keypairs_of_initiator : required_keypairs_of_responder
end

#required_keypairs_of_initiatorObject



164
165
166
167
168
169
# File 'lib/noise/pattern.rb', line 164

def required_keypairs_of_initiator
  required = []
  required << :s if initiator_static?
  required << :rs if responder_static_pre_shared?
  required
end

#required_keypairs_of_responderObject



171
172
173
174
175
176
# File 'lib/noise/pattern.rb', line 171

def required_keypairs_of_responder
  required = []
  required << :rs if initiator_static_pre_shared?
  required << :s if responder_static?
  required
end

#responder_pre_messagesObject



182
183
184
# File 'lib/noise/pattern.rb', line 182

def responder_pre_messages
  (@pre_messages[1] || []).dup
end

#responder_static?Boolean

Returns:

  • (Boolean)


193
194
195
# File 'lib/noise/pattern.rb', line 193

def responder_static?
  responder_static_pre_shared? || sends_static?(1)
end

#responder_static_pre_shared?Boolean

Returns:

  • (Boolean)


201
202
203
# File 'lib/noise/pattern.rb', line 201

def responder_static_pre_shared?
  responder_pre_messages.include?(Token::S)
end

#sends_static?(offset) ⇒ Boolean

The initiator writes the messages at even indexes, the responder the ones at odd indexes.

Returns:

  • (Boolean)


206
207
208
# File 'lib/noise/pattern.rb', line 206

def sends_static?(offset)
  offset.step(@tokens.size - 1, 2).any? { |i| @tokens[i].include?(Token::S) }
end