noise-ruby 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b0c3d02c47e652a285fbe31fcc7b5ff4c3d7cc05
4
- data.tar.gz: '0930939cdcee4d1215b35eb89351f12f1faf6538'
3
+ metadata.gz: c16d9319142dc02bcf5e1524c141aaa99a923942
4
+ data.tar.gz: b926ad7e994d5387fe48fab254b8f5c0ccb124fe
5
5
  SHA512:
6
- metadata.gz: e3a80f068ff0e387d2bca7cb0df4ecd19edb2728a6ee6d4c5b54a5487f1a7f0cc470d2e8d0ec173257d3efb25c1f121659b3cf61029dfba072faa39e4e5f6d5b
7
- data.tar.gz: 1359c45f4a39ea567809dff276c6e91da4711b4d45a89909a6f7682e627986ab37f2ab14cba7d89c96fe71752e7db2c045ab9a6e3315d01b749a0304037d95e7
6
+ metadata.gz: d1cafc8d1343cba342d73451a6817001faf4e3298fbc239e6e4efb8d1454087f0826602a73c3c503c9d498eafcfe0aca79fd91bfe3eb2ba401bec13d1b12e9fd
7
+ data.tar.gz: 40dfacc90d63bb5807dc8ce7b13d01beac299f2a62ef405f98971bf5381e6ff6bf9a2c637eedab26a9d451c95c1715c19991c8ed5014aee0ce28cc426944c3f0
@@ -10,6 +10,12 @@ Style/Documentation:
10
10
  Style/LambdaCall:
11
11
  Enabled: false
12
12
 
13
+ Style/SymbolArray:
14
+ MinSize: 100
15
+
16
+ Style/WordArray:
17
+ MinSize: 100
18
+
13
19
  AllCops:
14
20
  TargetRubyVersion: 2.4.1
15
21
 
data/Gemfile CHANGED
@@ -4,3 +4,5 @@ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Specify your gem's dependencies in noise.gemspec
6
6
  gemspec
7
+
8
+ gem 'aead', git: 'https://github.com/FredericHeihoff/aead.git', branch: :master
data/README.md CHANGED
@@ -1,15 +1,23 @@
1
1
  # Noise
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/noise`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ A Ruby implementation of the Noise Protocol framework(http://noiseprotocol.org/).
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ ## Future Works
6
+
7
+ The followings are not supported yet.
8
+
9
+ - DH Functions
10
+ - Curve448
11
+ - Hash Functions
12
+ - Blake2s
13
+ - PSK Mode
6
14
 
7
15
  ## Installation
8
16
 
9
17
  Add this line to your application's Gemfile:
10
18
 
11
- ```ruby
12
- gem 'noise'
19
+ ```
20
+ gem 'noise-ruby'
13
21
  ```
14
22
 
15
23
  And then execute:
@@ -18,7 +26,7 @@ And then execute:
18
26
 
19
27
  Or install it yourself as:
20
28
 
21
- $ gem install noise
29
+ $ gem install noise-ruby
22
30
 
23
31
  ## Usage
24
32
 
@@ -4,6 +4,7 @@ require 'noise/version'
4
4
 
5
5
  require 'ecdsa'
6
6
  require 'rbnacl'
7
+ require 'ruby_hmac'
7
8
  require 'securerandom'
8
9
 
9
10
  require 'noise/utils/hash'
@@ -22,8 +22,8 @@ module Noise
22
22
  @handshake_started = false
23
23
  @handshake_finished = false
24
24
  @fn = nil
25
- @write_message_proc = lambda {|payload| write_message(payload)}
26
- @read_message_proc = lambda {|payload| read_message(payload)}
25
+ @write_message_proc = ->(payload) { write_message(payload) }
26
+ @read_message_proc = ->(payload) { read_message(payload) }
27
27
  end
28
28
 
29
29
  def prologue=(prologue)
@@ -1,19 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'aead'
4
+
3
5
  module Noise
4
6
  module Functions
5
7
  module Cipher
6
8
  class AesGcm
7
9
  def encrypt(k, n, ad, plaintext)
8
- throw NotImplementedError
10
+ mode = AEAD::Cipher.new('AES-256-GCM')
11
+ cipher = mode.new(k)
12
+ cipher.encrypt(nonce_to_bytes(n), ad, plaintext)
9
13
  end
10
14
 
11
15
  def decrypt(k, n, ad, ciphertext)
12
- throw NotImplementedError
16
+ mode = AEAD::Cipher.new('AES-256-GCM')
17
+ cipher = mode.new(k)
18
+ cipher.decrypt(nonce_to_bytes(n), ad, ciphertext)
13
19
  end
14
20
 
15
21
  def nonce_to_bytes(n)
16
- "\00" * 4 + sprintf('%16x', n).htb
22
+ "\00" * 4 + format('%16x', n).htb
17
23
  end
18
24
  end
19
25
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Noise
2
4
  module Functions
3
5
  module DH
@@ -10,13 +10,17 @@ module Noise
10
10
 
11
11
  def self.hmac_hash(key, data, digest)
12
12
  # TODO: support for blake2b, blake2s
13
- OpenSSL::HMAC.digest(OpenSSL::Digest.new(digest), key, data)
13
+ if digest.include?('SHA')
14
+ OpenSSL::HMAC.digest(OpenSSL::Digest.new(digest), key, data)
15
+ elsif digest.include?('BLAKE2b')
16
+ Noise::Functions::Hash::Blake2bHMAC.new(key).update(data).digest
17
+ end
14
18
  end
15
19
 
16
20
  def self.create_hkdf_fn(digest)
17
- ->(chaining_key, input_key_material, num_output) {
21
+ lambda do |chaining_key, input_key_material, num_output|
18
22
  hkdf(chaining_key, input_key_material, num_output, digest)
19
- }
23
+ end
20
24
  end
21
25
 
22
26
  def self.hkdf(chaining_key, input_key_material, num_outputs, digest)
@@ -18,6 +18,13 @@ module Noise
18
18
  BLOCKLEN
19
19
  end
20
20
  end
21
+
22
+ class Blake2bHMAC < HMAC::Base
23
+ def initialize(key = nil)
24
+ super(RbNaCl::Hash::Blake2b, 128, 64, key)
25
+ end
26
+ public_class_method :new, :digest, :hexdigest
27
+ end
21
28
  end
22
29
  end
23
30
  end
@@ -30,14 +30,20 @@ module Noise
30
30
 
31
31
  # initiator [Boolean]
32
32
  def required_keypairs(initiator)
33
+ initiator ? required_keypairs_of_initiator : required_keypairs_of_responder
34
+ end
35
+
36
+ def required_keypairs_of_initiator
37
+ required = []
38
+ required << :s if %w[K X I].include?(@name[0])
39
+ required << :rs if @one_way || @name[1] == 'K'
40
+ required
41
+ end
42
+
43
+ def required_keypairs_of_responder
33
44
  required = []
34
- if initiator
35
- required << :s if ['K', 'X', 'I'].include?(@name[0])
36
- required << :rs if @one_way || @name[1] == 'K'
37
- else
38
- required << :rs if @name[0] == 'K'
39
- required << :s if @one_way || ['K', 'X'].include?(@name[1])
40
- end
45
+ required << :rs if @name[0] == 'K'
46
+ required << :s if @one_way || %w[K X].include?(@name[1])
41
47
  required
42
48
  end
43
49
 
@@ -187,37 +193,3 @@ module Noise
187
193
  end
188
194
  end
189
195
  end
190
- #
191
- # def has_pre_messages(self):
192
- # return any(map(lambda x: len(x) > 0, self.pre_messages))
193
- #
194
- # def get_initiator_pre_messages(self) -> list:
195
- # return self.pre_messages[0].copy()
196
- #
197
- # def get_responder_pre_messages(self) -> list:
198
- # return self.pre_messages[1].copy()
199
- #
200
- # def apply_pattern_modifiers(self, modifiers: List[str]) -> None:
201
- # # Applies given pattern modifiers to self.tokens of the Pattern instance.
202
- # for modifier in modifiers:
203
- # if modifier.startswith('psk'):
204
- # try:
205
- # index = int(modifier.replace('psk', '', 1))
206
- # except ValueError:
207
- # raise ValueError('Improper psk modifier {}'.format(modifier))
208
- #
209
- # if index // 2 > len(self.tokens):
210
- # raise ValueError('Modifier {} cannot be applied - pattern has not enough messages'.format(modifier))
211
- #
212
- # # Add TOKEN_PSK in the correct place in the correct message
213
- # if index == 0: # if 0, insert at the beginning of first message
214
- # self.tokens[0].insert(0, TOKEN_PSK)
215
- # else: # if bigger than zero, append at the end of first, second etc.
216
- # self.tokens[index - 1].append(TOKEN_PSK)
217
- # self.psk_count += 1
218
- #
219
- # elif modifier == 'fallback':
220
- # raise NotImplementedError # TODO implement
221
- #
222
- # else:
223
- # raise ValueError('Unknown pattern modifier {}'.format(modifier))
@@ -109,7 +109,6 @@ module Noise
109
109
  temp = message[0...len + offset]
110
110
  message = message[(len + offset)..-1]
111
111
  @rs = @protocol.dh_fn.class.from_public(@symmetric_state.decrypt_and_hash(temp))
112
- # @protocol.keypair.load(@symmetric_state.decrypt_and_hash(temp))
113
112
  next
114
113
  when 'ee'
115
114
  @symmetric_state.mix_key(dh_fn.dh(@e[0], @re[1]))
@@ -67,13 +67,8 @@ module Noise
67
67
  c2 = CipherState.new(cipher: @protocol.cipher_fn)
68
68
  c1.initialize_key(temp_k1)
69
69
  c2.initialize_key(temp_k2)
70
- if @protocol.initiator
71
- @protocol.cipher_state_encrypt = c1
72
- @protocol.cipher_state_decrypt = c2
73
- else
74
- @protocol.cipher_state_encrypt = c2
75
- @protocol.cipher_state_decrypt = c1
76
- end
70
+ @protocol.cipher_state_encrypt = @protocol.initiator ? c1 : c2
71
+ @protocol.cipher_state_decrypt = @protocol.initiator ? c2 : c1
77
72
  @protocol.handshake_done
78
73
  [c1, c2]
79
74
  end
@@ -2,9 +2,10 @@
2
2
 
3
3
  class String
4
4
  def htb
5
- [self].pack("H*")
5
+ [self].pack('H*')
6
6
  end
7
+
7
8
  def bth
8
- self.unpack("H*").first
9
+ unpack('H*').first
9
10
  end
10
11
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Noise
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
@@ -23,7 +23,8 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency 'rake', '~> 10.0'
24
24
  spec.add_development_dependency 'rspec', '~> 3.0'
25
25
 
26
+ spec.add_runtime_dependency 'aead'
26
27
  spec.add_runtime_dependency 'ecdsa'
27
28
  spec.add_runtime_dependency 'rbnacl'
28
- spec.add_runtime_dependency 'rb-pure25519'
29
+ spec.add_runtime_dependency 'ruby-hmac'
29
30
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: noise-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hajime Yamaguchi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-12-05 00:00:00.000000000 Z
11
+ date: 2017-12-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: aead
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: ecdsa
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -81,7 +95,7 @@ dependencies:
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
- name: rb-pure25519
98
+ name: ruby-hmac
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - ">="