noise-ruby 0.10.0 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +30 -0
- data/.rubocop.yml +3 -0
- data/.ruby-version +1 -1
- data/lib/noise/connection/base.rb +1 -6
- data/lib/noise/functions/cipher/aes_gcm.rb +2 -2
- data/lib/noise/functions/cipher/cha_cha_poly.rb +2 -2
- data/lib/noise/functions/dh/ed448.rb +1 -5
- data/lib/noise/functions/dh/secp256k1.rb +1 -4
- data/lib/noise/functions/hash/blake3.rb +1 -4
- data/lib/noise/pattern.rb +102 -13
- data/lib/noise/protocol.rb +3 -6
- data/lib/noise/state/handshake_state.rb +82 -66
- data/lib/noise/state/symmetric_state.rb +5 -1
- data/lib/noise/version.rb +1 -1
- data/lib/noise.rb +12 -0
- data/noise.gemspec +3 -3
- metadata +10 -11
- data/.travis.yml +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cffe6f7ffc789455f6b27bf3246cce8870cf57600e551d8f8edf91437ccd7afd
|
4
|
+
data.tar.gz: f9c83042c8aa626a7a6e81ad62dd64ccf6c5515c33f1f64e12904b2ffcaa5fa9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1c2fe0e62f0939b48052d348511a97cedcf222316491d43f1d6128d146108587eedeb972d1fbce732a15aa7b73684f76e013e7a57c2f27fe85a3f7331a140bd
|
7
|
+
data.tar.gz: fa9aea76917642726a8688fbc7b3d0f5fb9b32d1fe058ba7fbf81757d9754da92c1809633378b518753cf105e25e452f65975cfbef0f9b679ec12c68c5198d80
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: Ruby
|
9
|
+
|
10
|
+
on:
|
11
|
+
push:
|
12
|
+
branches: [ master ]
|
13
|
+
pull_request:
|
14
|
+
branches: [ master ]
|
15
|
+
|
16
|
+
jobs:
|
17
|
+
test:
|
18
|
+
|
19
|
+
runs-on: ubuntu-latest
|
20
|
+
|
21
|
+
steps:
|
22
|
+
- uses: actions/checkout@v2
|
23
|
+
- name: Set up Ruby
|
24
|
+
uses: ruby/setup-ruby@v1
|
25
|
+
with:
|
26
|
+
ruby-version: 2.6
|
27
|
+
- name: Install dependencies
|
28
|
+
run: bundle install
|
29
|
+
- name: Run tests
|
30
|
+
run: bundle exec rake
|
data/.rubocop.yml
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.7.6
|
@@ -40,7 +40,6 @@ module Noise
|
|
40
40
|
def initialise_handshake_state
|
41
41
|
@handshake_state = Noise::State::HandshakeState.new(
|
42
42
|
self,
|
43
|
-
protocol,
|
44
43
|
initiator?,
|
45
44
|
@prologue,
|
46
45
|
@local_keypairs,
|
@@ -100,17 +99,13 @@ module Noise
|
|
100
99
|
end
|
101
100
|
|
102
101
|
def validate
|
103
|
-
validate_psk! if
|
102
|
+
validate_psk! if @protocol.psk?
|
104
103
|
|
105
104
|
raise Noise::Exceptions::NoiseValidationError if valid_keypairs?
|
106
105
|
|
107
106
|
true
|
108
107
|
end
|
109
108
|
|
110
|
-
def psk_handshake?
|
111
|
-
@protocol.is_psk_handshake
|
112
|
-
end
|
113
|
-
|
114
109
|
def handshake_done(_c1, _c2)
|
115
110
|
@handshake_hash = @symmetric_state.handshake_hash
|
116
111
|
@s = @handshake_state.s
|
@@ -13,7 +13,7 @@ module Noise
|
|
13
13
|
cipher.auth_data = ad
|
14
14
|
cipher.update(plaintext) + cipher.final + cipher.auth_tag
|
15
15
|
rescue OpenSSL::Cipher::CipherError => e
|
16
|
-
raise Noise::Exceptions::EncryptError.
|
16
|
+
raise Noise::Exceptions::EncryptError, "Encrypt failed. #{e.message}", e.backtrace
|
17
17
|
end
|
18
18
|
|
19
19
|
def decrypt(k, n, ad, ciphertext)
|
@@ -24,7 +24,7 @@ module Noise
|
|
24
24
|
cipher.auth_tag = ciphertext[-16..-1]
|
25
25
|
cipher.update(ciphertext[0...-16]) + cipher.final
|
26
26
|
rescue OpenSSL::Cipher::CipherError => e
|
27
|
-
raise Noise::Exceptions::DecryptError.
|
27
|
+
raise Noise::Exceptions::DecryptError, "Decrpyt failed. #{e.message}", e.backtrace
|
28
28
|
end
|
29
29
|
|
30
30
|
def nonce_to_bytes(n)
|
@@ -10,14 +10,14 @@ module Noise
|
|
10
10
|
cipher = RbNaCl::AEAD::ChaCha20Poly1305IETF.new(String.new(k).force_encoding('ASCII-8BIT'))
|
11
11
|
cipher.encrypt(nonce_to_bytes(n), plaintext, ad)
|
12
12
|
rescue ::RbNaCl::CryptoError => e
|
13
|
-
raise Noise::Exceptions::EncryptError.
|
13
|
+
raise Noise::Exceptions::EncryptError, "Encrypt failed. #{e.message}", e.backtrace
|
14
14
|
end
|
15
15
|
|
16
16
|
def decrypt(k, n, ad, ciphertext)
|
17
17
|
cipher = RbNaCl::AEAD::ChaCha20Poly1305IETF.new(String.new(k).force_encoding('ASCII-8BIT'))
|
18
18
|
cipher.decrypt(nonce_to_bytes(n), ciphertext, ad)
|
19
19
|
rescue ::RbNaCl::CryptoError => e
|
20
|
-
raise Noise::Exceptions::DecryptError.
|
20
|
+
raise Noise::Exceptions::DecryptError, "Decrpyt failed. #{e.message}", e.backtrace
|
21
21
|
end
|
22
22
|
|
23
23
|
def nonce_to_bytes(n)
|
data/lib/noise/pattern.rb
CHANGED
@@ -2,13 +2,99 @@
|
|
2
2
|
|
3
3
|
module Noise
|
4
4
|
module Token
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
class TokenE
|
6
|
+
def to_s
|
7
|
+
'e'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class TokenS
|
12
|
+
def to_s
|
13
|
+
's'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class TokenDH
|
18
|
+
def mix(symmetric_state, dh_fn, initiator, keypair)
|
19
|
+
private_key, public_key = get_key(keypair, initiator)
|
20
|
+
symmetric_state.mix_key(dh_fn.dh(private_key, public_key))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class TokenEE < TokenDH
|
25
|
+
def get_key(keypair, _initiator)
|
26
|
+
[keypair.e.private_key, keypair.re]
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
'ee'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class TokenES < TokenDH
|
35
|
+
def get_key(keypair, initiator)
|
36
|
+
initiator ? [keypair.e.private_key, keypair.rs] : [keypair.s.private_key, keypair.re]
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_s
|
40
|
+
'es'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class TokenSE < TokenDH
|
45
|
+
def get_key(keypair, initiator)
|
46
|
+
initiator ? [keypair.s.private_key, keypair.re] : [keypair.e.private_key, keypair.rs]
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_s
|
50
|
+
'se'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
class TokenSS < TokenDH
|
54
|
+
def get_key(keypair, _initiator)
|
55
|
+
[keypair.s.private_key, keypair.rs]
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_s
|
59
|
+
'ss'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
class TokenPSK
|
63
|
+
def to_s
|
64
|
+
'psk'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
E = TokenE.new
|
69
|
+
S = TokenS.new
|
70
|
+
EE = TokenEE.new
|
71
|
+
ES = TokenES.new
|
72
|
+
SE = TokenSE.new
|
73
|
+
SS = TokenSS.new
|
74
|
+
PSK = TokenPSK.new
|
75
|
+
end
|
76
|
+
|
77
|
+
module Modifier
|
78
|
+
class Psk
|
79
|
+
attr_reader :index
|
80
|
+
def initialize(index)
|
81
|
+
@index = index
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
class Fallback
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.parse(s)
|
89
|
+
if s.start_with?('psk')
|
90
|
+
index = s.gsub(/psk/, '').to_i
|
91
|
+
Modifier::Psk.new(index)
|
92
|
+
elsif s == 'fallback'
|
93
|
+
Modifier::Fallback.new
|
94
|
+
else
|
95
|
+
raise Noise::Exceptions::UnsupportedModifierError
|
96
|
+
end
|
97
|
+
end
|
12
98
|
end
|
13
99
|
|
14
100
|
class Pattern
|
@@ -17,7 +103,7 @@ module Noise
|
|
17
103
|
def self.create(name)
|
18
104
|
pattern_set = name.scan(/([A-Z1]+)([^A-Z]*)/)&.first
|
19
105
|
pattern = pattern_set&.first
|
20
|
-
modifiers = pattern_set[1].split('+')
|
106
|
+
modifiers = pattern_set[1].split('+').map { |s| Modifier.parse(s) }
|
21
107
|
class_name = "Noise::Pattern#{pattern}"
|
22
108
|
klass = Object.const_get(class_name)
|
23
109
|
klass.new(modifiers)
|
@@ -31,10 +117,15 @@ module Noise
|
|
31
117
|
@modifiers = modifiers
|
32
118
|
end
|
33
119
|
|
120
|
+
def psk?
|
121
|
+
modifiers.any? { |m| m.is_a? Modifier::Psk }
|
122
|
+
end
|
123
|
+
|
34
124
|
def apply_pattern_modifiers
|
35
125
|
@modifiers.each do |modifier|
|
36
|
-
|
37
|
-
|
126
|
+
case modifier
|
127
|
+
when Modifier::Psk
|
128
|
+
index = modifier.index
|
38
129
|
raise Noise::Exceptions::PSKValueError if index / 2 > @tokens.size
|
39
130
|
|
40
131
|
if index.zero?
|
@@ -43,10 +134,8 @@ module Noise
|
|
43
134
|
@tokens[index - 1] << Token::PSK
|
44
135
|
end
|
45
136
|
@psk_count += 1
|
46
|
-
|
137
|
+
when Modifier::Fallback
|
47
138
|
@fallback = true
|
48
|
-
else
|
49
|
-
raise Noise::Exceptions::UnsupportedModifierError
|
50
139
|
end
|
51
140
|
end
|
52
141
|
end
|
data/lib/noise/protocol.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
module Noise
|
4
4
|
class Protocol
|
5
|
-
attr_accessor :is_psk_handshake
|
6
5
|
attr_accessor :cipher_fn, :hash_fn, :dh_fn, :hkdf_fn
|
7
6
|
attr_reader :name, :pattern
|
8
7
|
|
@@ -22,7 +21,7 @@ module Noise
|
|
22
21
|
'BLAKE2s': Noise::Functions::Hash::Blake2s,
|
23
22
|
'SHA256': Noise::Functions::Hash::Sha256,
|
24
23
|
'SHA512': Noise::Functions::Hash::Sha512,
|
25
|
-
'BLAKE3': Noise::Functions::Hash::Blake3
|
24
|
+
'BLAKE3': Noise::Functions::Hash::Blake3
|
26
25
|
}.stringify_keys.freeze
|
27
26
|
|
28
27
|
def self.create(name)
|
@@ -35,8 +34,6 @@ module Noise
|
|
35
34
|
@name = name
|
36
35
|
@pattern = Noise::Pattern.create(pattern_name)
|
37
36
|
@hkdf_fn = Noise::Functions::Hash.create_hkdf_fn(hash_name)
|
38
|
-
@is_psk_handshake = @pattern.modifiers.any? { |m| m.start_with?('psk') }
|
39
|
-
|
40
37
|
@pattern.apply_pattern_modifiers
|
41
38
|
|
42
39
|
initialize_fn!(cipher_name, hash_name, dh_name)
|
@@ -49,8 +46,8 @@ module Noise
|
|
49
46
|
raise Noise::Exceptions::ProtocolNameError unless @cipher_fn && @hash_fn && @dh_fn
|
50
47
|
end
|
51
48
|
|
52
|
-
def
|
53
|
-
@
|
49
|
+
def psk?
|
50
|
+
@pattern.psk?
|
54
51
|
end
|
55
52
|
end
|
56
53
|
end
|
@@ -20,45 +20,60 @@ module Noise
|
|
20
20
|
attr_reader :message_patterns, :symmetric_state
|
21
21
|
attr_reader :s, :rs, :e, :re
|
22
22
|
|
23
|
-
def initialize(connection,
|
23
|
+
def initialize(connection, initiator, prologue, local_keypairs, remote_keys)
|
24
24
|
@connection = connection
|
25
|
-
@protocol = protocol
|
26
|
-
@symmetric_state = SymmetricState.
|
27
|
-
@symmetric_state.initialize_symmetric(@protocol, connection)
|
28
|
-
@symmetric_state.mix_hash(prologue)
|
25
|
+
@protocol = connection.protocol
|
26
|
+
@symmetric_state = SymmetricState.initialize_symmetric(@protocol, connection, prologue: prologue)
|
29
27
|
@initiator = initiator
|
30
28
|
@s = local_keypairs[:s]
|
31
29
|
@e = local_keypairs[:e]
|
32
30
|
@rs = remote_keys[:rs]
|
33
31
|
@re = remote_keys[:re]
|
34
32
|
|
35
|
-
|
36
|
-
get_remote_keypair = ->(token) { instance_variable_get('@r' + token) }
|
33
|
+
initiator_keypair_getter, responder_keypair_getter = get_keypair_getter(initiator)
|
37
34
|
|
35
|
+
# Sets message_patterns to the message patterns from handshake_pattern
|
36
|
+
@message_patterns = @protocol.pattern.tokens.dup
|
37
|
+
|
38
|
+
process_initiator_pre_messages(initiator_keypair_getter)
|
39
|
+
process_fallback(initiator_keypair_getter)
|
40
|
+
process_responder_pre_messages(responder_keypair_getter)
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_keypair_getter(initiator)
|
38
44
|
if initiator
|
39
|
-
|
40
|
-
responder_keypair_getter = get_remote_keypair
|
45
|
+
[local_keypair_getter, remote_keypair_getter]
|
41
46
|
else
|
42
|
-
|
43
|
-
responder_keypair_getter = get_local_keypair
|
47
|
+
[remote_keypair_getter, local_keypair_getter]
|
44
48
|
end
|
49
|
+
end
|
45
50
|
|
46
|
-
|
47
|
-
@
|
51
|
+
def local_keypair_getter
|
52
|
+
->(token) { instance_variable_get('@' + token.to_s).public_key }
|
53
|
+
end
|
48
54
|
|
55
|
+
def remote_keypair_getter
|
56
|
+
->(token) { instance_variable_get('@r' + token.to_s) }
|
57
|
+
end
|
58
|
+
|
59
|
+
def process_initiator_pre_messages(keypair_getter)
|
49
60
|
@protocol.pattern.initiator_pre_messages&.map do |token|
|
50
|
-
keypair =
|
61
|
+
keypair = keypair_getter.call(token)
|
51
62
|
@symmetric_state.mix_hash(keypair)
|
52
63
|
end
|
64
|
+
end
|
53
65
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
66
|
+
def process_fallback(initiator_keypair_getter)
|
67
|
+
return unless @protocol.pattern.fallback
|
68
|
+
|
69
|
+
message = @message_patterns.delete_at(0).first
|
70
|
+
public_key = initiator_keypair_getter.call(message)
|
71
|
+
@symmetric_state.mix_hash(public_key)
|
72
|
+
end
|
59
73
|
|
74
|
+
def process_responder_pre_messages(keypair_getter)
|
60
75
|
@protocol.pattern.responder_pre_messages&.map do |token|
|
61
|
-
keypair =
|
76
|
+
keypair = keypair_getter.call(token)
|
62
77
|
@symmetric_state.mix_hash(keypair)
|
63
78
|
end
|
64
79
|
end
|
@@ -68,13 +83,13 @@ module Noise
|
|
68
83
|
pattern = @message_patterns.first
|
69
84
|
len = pattern.inject(0) do |l, token|
|
70
85
|
case token
|
71
|
-
when
|
86
|
+
when Noise::Token::E
|
72
87
|
l += @protocol.dh_fn.dhlen
|
73
|
-
has_key = true if @protocol.
|
74
|
-
when
|
88
|
+
has_key = true if @protocol.psk?
|
89
|
+
when Noise::Token::S
|
75
90
|
l += @protocol.dh_fn.dhlen
|
76
91
|
l += 16 if has_key
|
77
|
-
|
92
|
+
else
|
78
93
|
has_key = true
|
79
94
|
end
|
80
95
|
l
|
@@ -87,29 +102,19 @@ module Noise
|
|
87
102
|
# Takes a payload byte sequence which may be zero-length, and a message_buffer to write the output into
|
88
103
|
def write_message(payload, message_buffer)
|
89
104
|
pattern = @message_patterns.shift
|
90
|
-
dh_fn = @protocol.dh_fn
|
91
105
|
|
92
106
|
pattern.each do |token|
|
93
107
|
case token
|
94
|
-
when
|
95
|
-
@e
|
108
|
+
when Noise::Token::E
|
109
|
+
@e ||= @protocol.dh_fn.generate_keypair
|
96
110
|
message_buffer << @e.public_key
|
97
|
-
|
98
|
-
|
99
|
-
when 's'
|
111
|
+
mix_e(@e.public_key)
|
112
|
+
when Noise::Token::S
|
100
113
|
message_buffer << @symmetric_state.encrypt_and_hash(@s.public_key)
|
101
|
-
when
|
102
|
-
@symmetric_state.
|
103
|
-
when
|
104
|
-
|
105
|
-
@symmetric_state.mix_key(dh_fn.dh(private_key, public_key))
|
106
|
-
when 'se'
|
107
|
-
private_key, public_key = @initiator ? [@s.private_key, @re] : [@e.private_key, @rs]
|
108
|
-
@symmetric_state.mix_key(dh_fn.dh(private_key, public_key))
|
109
|
-
when 'ss'
|
110
|
-
@symmetric_state.mix_key(dh_fn.dh(@s.private_key, @rs))
|
111
|
-
when 'psk'
|
112
|
-
@symmetric_state.mix_key_and_hash(@connection.psks.shift)
|
114
|
+
when Noise::Token::EE, Noise::Token::ES, Noise::Token::SE, Noise::Token::SS
|
115
|
+
token.mix(@symmetric_state, @protocol.dh_fn, @initiator, self)
|
116
|
+
when Noise::Token::PSK
|
117
|
+
mix_psk
|
113
118
|
end
|
114
119
|
end
|
115
120
|
message_buffer << @symmetric_state.encrypt_and_hash(payload)
|
@@ -120,37 +125,48 @@ module Noise
|
|
120
125
|
# and a payload_buffer to write the message's plaintext payload into
|
121
126
|
def read_message(message, payload_buffer)
|
122
127
|
pattern = @message_patterns.shift
|
123
|
-
dh_fn = @protocol.dh_fn
|
124
|
-
len = dh_fn.dhlen
|
125
128
|
pattern.each do |token|
|
126
129
|
case token
|
127
|
-
when
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
when 'ee'
|
138
|
-
@symmetric_state.mix_key(dh_fn.dh(@e.private_key, @re))
|
139
|
-
when 'es'
|
140
|
-
private_key, public_key = @initiator ? [@e.private_key, @rs] : [@s.private_key, @re]
|
141
|
-
@symmetric_state.mix_key(dh_fn.dh(private_key, public_key))
|
142
|
-
when 'se'
|
143
|
-
private_key, public_key = @initiator ? [@s.private_key, @re] : [@e.private_key, @rs]
|
144
|
-
@symmetric_state.mix_key(dh_fn.dh(private_key, public_key))
|
145
|
-
when 'ss'
|
146
|
-
@symmetric_state.mix_key(dh_fn.dh(@s.private_key, @rs))
|
147
|
-
when 'psk'
|
148
|
-
@symmetric_state.mix_key_and_hash(@connection.psks.shift)
|
130
|
+
when Noise::Token::E
|
131
|
+
message, re = extract_key(message, false)
|
132
|
+
@re ||= re
|
133
|
+
mix_e(@re)
|
134
|
+
when Noise::Token::S
|
135
|
+
message, @rs = extract_key(message, true)
|
136
|
+
when Noise::Token::EE, Noise::Token::ES, Noise::Token::SE, Noise::Token::SS
|
137
|
+
token.mix(@symmetric_state, @protocol.dh_fn, @initiator, self)
|
138
|
+
when Noise::Token::PSK
|
139
|
+
mix_psk
|
149
140
|
end
|
150
141
|
end
|
151
142
|
payload_buffer << @symmetric_state.decrypt_and_hash(message)
|
152
143
|
@symmetric_state.split if @message_patterns.empty?
|
153
144
|
end
|
145
|
+
|
146
|
+
private
|
147
|
+
|
148
|
+
def extract_key(message, is_encrypted)
|
149
|
+
len = @protocol.dh_fn.dhlen
|
150
|
+
offset =
|
151
|
+
if is_encrypted && @connection.cipher_state_handshake.key?
|
152
|
+
16
|
153
|
+
else
|
154
|
+
0
|
155
|
+
end
|
156
|
+
key = message[0...len + offset]
|
157
|
+
message = message[(len + offset)..-1]
|
158
|
+
key = @symmetric_state.decrypt_and_hash(key) if is_encrypted
|
159
|
+
[message, key]
|
160
|
+
end
|
161
|
+
|
162
|
+
def mix_e(public_key)
|
163
|
+
@symmetric_state.mix_hash(public_key)
|
164
|
+
@symmetric_state.mix_key(public_key) if @protocol.psk?
|
165
|
+
end
|
166
|
+
|
167
|
+
def mix_psk
|
168
|
+
@symmetric_state.mix_key_and_hash(@connection.psks.shift)
|
169
|
+
end
|
154
170
|
end
|
155
171
|
end
|
156
172
|
end
|
@@ -11,7 +11,7 @@ module Noise
|
|
11
11
|
attr_reader :h, :ck
|
12
12
|
attr_reader :cipher_state
|
13
13
|
|
14
|
-
def
|
14
|
+
def initialize(protocol, connection)
|
15
15
|
@protocol = protocol
|
16
16
|
@connection = connection
|
17
17
|
@ck = @h = initialize_h(protocol)
|
@@ -20,6 +20,10 @@ module Noise
|
|
20
20
|
@cipher_state.initialize_key(nil)
|
21
21
|
end
|
22
22
|
|
23
|
+
def self.initialize_symmetric(protocol, connection, prologue: nil)
|
24
|
+
new(protocol, connection).tap { |s| s.mix_hash(prologue) if prologue }
|
25
|
+
end
|
26
|
+
|
23
27
|
def mix_key(input_key_meterial)
|
24
28
|
@ck, temp_k = @protocol.hkdf_fn.call(@ck, input_key_meterial, 2)
|
25
29
|
temp_k = truncate(temp_k)
|
data/lib/noise/version.rb
CHANGED
data/lib/noise.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'noise/version'
|
4
4
|
|
5
5
|
require 'ecdsa'
|
6
|
+
require 'logger'
|
6
7
|
require 'rbnacl'
|
7
8
|
require 'ruby_hmac'
|
8
9
|
require 'securerandom'
|
@@ -19,4 +20,15 @@ module Noise
|
|
19
20
|
autoload :Exceptions, 'noise/exceptions'
|
20
21
|
autoload :Functions, 'noise/functions'
|
21
22
|
autoload :State, 'noise/state'
|
23
|
+
|
24
|
+
def self.logger
|
25
|
+
@logger ||= Logger.new(STDOUT)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def require_force(name)
|
30
|
+
require name
|
31
|
+
yield if block_given?
|
32
|
+
rescue LoadError => e
|
33
|
+
Noise.logger.warn(e.message)
|
22
34
|
end
|
data/noise.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
lib = File.expand_path('
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
5
|
require 'noise/version'
|
6
6
|
|
@@ -22,8 +22,8 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.require_paths = ['lib']
|
23
23
|
|
24
24
|
spec.add_development_dependency 'blake3'
|
25
|
-
spec.add_development_dependency 'bundler', '~>
|
26
|
-
spec.add_development_dependency 'rake', '
|
25
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
26
|
+
spec.add_development_dependency 'rake', '>= 12.3.3'
|
27
27
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
28
28
|
spec.add_development_dependency 'secp256k1-ruby'
|
29
29
|
|
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.10.
|
4
|
+
version: 0.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hajime Yamaguchi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-08-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: blake3
|
@@ -30,28 +30,28 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '2.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '2.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 12.3.3
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 12.3.3
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -143,11 +143,11 @@ executables: []
|
|
143
143
|
extensions: []
|
144
144
|
extra_rdoc_files: []
|
145
145
|
files:
|
146
|
+
- ".github/workflows/ruby.yml"
|
146
147
|
- ".gitignore"
|
147
148
|
- ".rspec"
|
148
149
|
- ".rubocop.yml"
|
149
150
|
- ".ruby-version"
|
150
|
-
- ".travis.yml"
|
151
151
|
- CODE_OF_CONDUCT.md
|
152
152
|
- Gemfile
|
153
153
|
- README.md
|
@@ -214,8 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
214
214
|
- !ruby/object:Gem::Version
|
215
215
|
version: '0'
|
216
216
|
requirements: []
|
217
|
-
|
218
|
-
rubygems_version: 2.7.6
|
217
|
+
rubygems_version: 3.1.6
|
219
218
|
signing_key:
|
220
219
|
specification_version: 4
|
221
220
|
summary: A Ruby implementation of the Noise Protocol framework
|