nis-ruby 0.0.15 → 0.0.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/examples/transactions/transfer.rb +16 -1
- data/lib/nis/struct/message.rb +28 -5
- data/lib/nis/transaction/transfer.rb +3 -1
- data/lib/nis/util/convert.rb +2 -10
- data/lib/nis/util/deserializer.rb +1 -1
- data/lib/nis/util/ed25519.rb +63 -4
- data/lib/nis/util/serializer.rb +3 -3
- data/lib/nis/version.rb +1 -1
- data/nis.gemspec +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 93f3eeb5532cbd0ab950c6813e000a5400f5014c
|
4
|
+
data.tar.gz: bf31058b27c37de8a80a53e152a0e3cc38fbdc84
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c03543c6cfc51d0b46a4077a19cd44a97d87eee619f3ab95b42017a8f7e32911f5cc76a5047fba0e3d24ea11035916529491bd21f9b105a0866ed1c948ab9a9
|
7
|
+
data.tar.gz: 66b59428d40eab12063847cded5fac1ab1bcf27b2cb00f3da1417b9e5e334534267ec32ad8010d606605101fe538a8ff9214dc175a57a764c8be767e96bf26cc
|
@@ -5,9 +5,9 @@ A_PRIVATE_KEY = '4ce5c8f9fce571db0d9ac1adf00b8d3ba0f078ed40835fd3d730a2f24b83421
|
|
5
5
|
|
6
6
|
# recipient
|
7
7
|
B_ADDRESS = 'TA4TX6U5HG2MROAESH2JE5524T4ZOY2EQKQ6ELHF'
|
8
|
+
B_PUBLIC_KEY = '9e7ab2924cd1a3482df784db190614cfc8a33671f5d80a5b15a9c9e8b4d13933'
|
8
9
|
|
9
10
|
kp = Nis::Keypair.new(A_PRIVATE_KEY)
|
10
|
-
|
11
11
|
tx = Nis::Transaction::Transfer.new(B_ADDRESS, 1, 'Good luck!')
|
12
12
|
puts "Fee: #{tx.fee.to_i}"
|
13
13
|
|
@@ -17,3 +17,18 @@ res = nis.transaction_prepare_announce(req)
|
|
17
17
|
|
18
18
|
puts "Message: #{res.message}"
|
19
19
|
puts "TransactionHash: #{res.transaction_hash}"
|
20
|
+
|
21
|
+
# with encrypted message
|
22
|
+
|
23
|
+
message = Nis::Struct::Message.new('Good luck!', type: :encrypted,
|
24
|
+
private_key: kp.private,
|
25
|
+
public_key: B_PUBLIC_KEY
|
26
|
+
)
|
27
|
+
message.encrypt!
|
28
|
+
tx = Nis::Transaction::Transfer.new(B_ADDRESS, 1, message, {})
|
29
|
+
puts "Fee: #{tx.fee.to_i}"
|
30
|
+
|
31
|
+
req = Nis::Request::PrepareAnnounce.new(tx, kp)
|
32
|
+
res = nis.transaction_prepare_announce(req)
|
33
|
+
puts "Message: #{res.message}"
|
34
|
+
puts "TransactionHash: #{res.transaction_hash}"
|
data/lib/nis/struct/message.rb
CHANGED
@@ -2,15 +2,32 @@ class Nis::Struct
|
|
2
2
|
# @attr [String] value
|
3
3
|
# @attr [Integer] type
|
4
4
|
# @attr [String] payload
|
5
|
+
# @attr [String] public_key
|
5
6
|
class Message
|
6
|
-
|
7
|
+
attr_reader :value, :type, :public_key, :private_key
|
7
8
|
|
8
9
|
TYPE_PLAIN = 1
|
9
10
|
TYPE_ENCRYPTED = 2
|
10
11
|
|
11
|
-
def initialize(value = '')
|
12
|
+
def initialize(value = '', type: :plain, private_key: nil, public_key: nil)
|
12
13
|
@value = value
|
13
|
-
@type
|
14
|
+
@type = (type == :encrypted) ? TYPE_ENCRYPTED : TYPE_PLAIN
|
15
|
+
@private_key = private_key
|
16
|
+
@public_key = public_key
|
17
|
+
end
|
18
|
+
|
19
|
+
def encrypt!
|
20
|
+
bin_sk = fix_private_key(@private_key).scan(/../).map(&:hex).reverse.pack('C*')
|
21
|
+
bin_pk = (public_key || @public_key).scan(/../).map(&:hex).pack('C*')
|
22
|
+
@value = Nis::Util::Ed25519.encrypt(bin_sk, bin_pk, value)
|
23
|
+
@type = TYPE_ENCRYPTED
|
24
|
+
end
|
25
|
+
|
26
|
+
def decrypt!
|
27
|
+
bin_sk = fix_private_key(@private_key).scan(/../).map(&:hex).reverse.pack('C*')
|
28
|
+
bin_pk = (public_key || @public_key).scan(/../).map(&:hex).pack('C*')
|
29
|
+
@value = Nis::Util::Ed25519.decrypt(bin_sk, bin_pk, payload)
|
30
|
+
@type = TYPE_PLAIN
|
14
31
|
end
|
15
32
|
|
16
33
|
# @return [Boolean]
|
@@ -40,7 +57,7 @@ class Nis::Struct
|
|
40
57
|
|
41
58
|
# @return [String]
|
42
59
|
def to_s
|
43
|
-
@value
|
60
|
+
@value.to_s
|
44
61
|
end
|
45
62
|
|
46
63
|
# @return [Boolean]
|
@@ -49,7 +66,13 @@ class Nis::Struct
|
|
49
66
|
end
|
50
67
|
|
51
68
|
def payload
|
52
|
-
|
69
|
+
encrypted? ? value : value.unpack('H*').join
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def fix_private_key(key)
|
75
|
+
"#{'0' * 64}#{key.sub(/^00/i, '')}"[-64, 64]
|
53
76
|
end
|
54
77
|
end
|
55
78
|
end
|
@@ -33,7 +33,9 @@ class Nis::Transaction
|
|
33
33
|
|
34
34
|
@recipient = recipient
|
35
35
|
@amount = amount
|
36
|
-
@message = Nis::Struct::Message
|
36
|
+
@message = message.is_a?(Nis::Struct::Message) ?
|
37
|
+
message :
|
38
|
+
Nis::Struct::Message.new(message.to_s)
|
37
39
|
@fee = Nis::Fee::Transfer.new(self)
|
38
40
|
@mosaics = mosaics
|
39
41
|
end
|
data/lib/nis/util/convert.rb
CHANGED
@@ -2,14 +2,6 @@ module Nis::Util
|
|
2
2
|
module Convert
|
3
3
|
HEX_ENCODE_ARRAY = %w[0 1 2 3 4 5 6 7 8 9 a b c d e f]
|
4
4
|
|
5
|
-
def hexlify(obj)
|
6
|
-
obj.unpack('H*').first
|
7
|
-
end
|
8
|
-
|
9
|
-
def unhexlify(obj)
|
10
|
-
obj.scan(/../).map(&:hex).pack('C*')
|
11
|
-
end
|
12
|
-
|
13
5
|
# Reversed convertion of hex to Uint8Array
|
14
6
|
# @param [String] hex
|
15
7
|
# @return [Array]
|
@@ -77,8 +69,8 @@ module Nis::Util
|
|
77
69
|
v += 0x100000000 if v < 0
|
78
70
|
temp[0] = (v >> 24)
|
79
71
|
temp[1] = (v >> 16) & 0xff
|
80
|
-
temp[2] = (v >>
|
81
|
-
temp[3] = (v)
|
72
|
+
temp[2] = (v >> 8) & 0xff
|
73
|
+
temp[3] = (v) & 0xff
|
82
74
|
temp
|
83
75
|
end.flatten
|
84
76
|
end
|
@@ -74,7 +74,7 @@ module Nis::Util
|
|
74
74
|
s = Nis::Util::Convert.hex2ua(serialized)
|
75
75
|
common = deserialize_common(s)
|
76
76
|
tx = {}
|
77
|
-
tx[:otherHash] = {data: deserialize_hex(s[68, 32])}
|
77
|
+
tx[:otherHash] = { data: deserialize_hex(s[68, 32]) }
|
78
78
|
tx[:otherAccount] = deserialize_a(s[104, 40])
|
79
79
|
common.merge(tx)
|
80
80
|
end
|
data/lib/nis/util/ed25519.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'openssl'
|
2
2
|
require 'digest/sha3'
|
3
3
|
require 'base32'
|
4
|
+
require 'securerandom'
|
4
5
|
|
5
6
|
module Nis::Util
|
6
7
|
module Ed25519
|
@@ -52,7 +53,7 @@ module Nis::Util
|
|
52
53
|
|
53
54
|
def xrecover(y)
|
54
55
|
xx = (y * y - 1) * inv(@@d * y * y + 1)
|
55
|
-
x = xx.to_bn.mod_exp((@@q + 3) / 8, @@q)
|
56
|
+
x = xx.to_bn.mod_exp((@@q + 3) / 8, @@q).to_i
|
56
57
|
x = (x * @@I) % @@q if (x * x - xx) % @@q != 0
|
57
58
|
x = @@q - x if x % 2 != 0
|
58
59
|
x
|
@@ -102,10 +103,10 @@ module Nis::Util
|
|
102
103
|
end
|
103
104
|
|
104
105
|
def scalarmult(_P, e)
|
105
|
-
@@ident if e == 0
|
106
|
+
return @@ident if e == 0
|
106
107
|
_Q = scalarmult(_P, e / 2)
|
107
108
|
_Q = edwards_double(_Q)
|
108
|
-
_Q = edwards_add(_Q, _P) if e & 1
|
109
|
+
_Q = edwards_add(_Q, _P) if (e & 1) == 1
|
109
110
|
_Q
|
110
111
|
end
|
111
112
|
|
@@ -161,6 +162,64 @@ module Nis::Util
|
|
161
162
|
encodepoint(_A)
|
162
163
|
end
|
163
164
|
|
165
|
+
def encrypt(sk, pk, data)
|
166
|
+
h = HH(sk)
|
167
|
+
a = 2**(@@b - 2) + (3...@@b - 2).inject(0) { |sum, i| sum + 2**i * bit(h, i) }
|
168
|
+
_A = decodepoint(pk)
|
169
|
+
bin_g = encodepoint(scalarmult(_A, a))
|
170
|
+
|
171
|
+
bin_iv = SecureRandom.random_bytes(16)
|
172
|
+
# bin_iv = [133, 235, 90, 141, 29, 234, 234, 20, 115, 237, 164, 88, 224, 87, 29, 82].pack('C*')
|
173
|
+
hex_iv = bin_iv.unpack('H*').join
|
174
|
+
|
175
|
+
bin_salt = SecureRandom.random_bytes(32)
|
176
|
+
# bin_salt = [35, 150, 208, 176, 6, 179, 135, 220, 197, 253, 164, 147, 164, 177, 228, 43, 143, 146, 245, 255, 226, 71, 44, 94, 218, 169, 117, 88, 98, 241, 115, 79].pack('C*')
|
177
|
+
hex_salt = bin_salt.unpack('H*').join
|
178
|
+
|
179
|
+
ua_salt = Nis::Util::Convert.hex2ua(hex_salt)
|
180
|
+
ua_g = Nis::Util::Convert.hex2ua(bin_g.unpack('H*').join)
|
181
|
+
|
182
|
+
c = []
|
183
|
+
ua_salt.each_with_index { |el, idx| c << (el ^ ua_g[idx]) }
|
184
|
+
bin_key = Digest::SHA3.digest(c.pack('C*'), 256)
|
185
|
+
|
186
|
+
cipher = OpenSSL::Cipher.new('AES-256-CBC')
|
187
|
+
cipher.encrypt
|
188
|
+
cipher.key = bin_key
|
189
|
+
cipher.iv = bin_iv
|
190
|
+
encrypted_data = cipher.update(data.bytes.pack('C*')) + cipher.final
|
191
|
+
hex_salt + hex_iv + encrypted_data.unpack('H*').join
|
192
|
+
end
|
193
|
+
|
194
|
+
def decrypt(sk, pk, data)
|
195
|
+
h = HH(sk)
|
196
|
+
a = 2**(@@b - 2) + (3...@@b - 2).inject(0) { |sum, i| sum + 2**i * bit(h, i) }
|
197
|
+
_A = decodepoint(pk)
|
198
|
+
bin_g = encodepoint(scalarmult(_A, a))
|
199
|
+
|
200
|
+
hex_salt = data[0, 64]
|
201
|
+
hex_iv = data[64, 32]
|
202
|
+
hex_encrypted = data[96, data.size]
|
203
|
+
|
204
|
+
ua_iv = Nis::Util::Convert.hex2ua(hex_iv)
|
205
|
+
bin_iv = ua_iv.pack('C*')
|
206
|
+
|
207
|
+
ua_salt = Nis::Util::Convert.hex2ua(hex_salt)
|
208
|
+
ua_g = Nis::Util::Convert.hex2ua(bin_g.unpack('H*').first)
|
209
|
+
|
210
|
+
c = []
|
211
|
+
ua_salt.each_with_index { |el, idx| c << (el ^ ua_g[idx]) }
|
212
|
+
bin_key = Digest::SHA3.digest(c.pack('C*'), 256)
|
213
|
+
|
214
|
+
bin_encrypted = Nis::Util::Convert.hex2ua(hex_encrypted).pack('C*')
|
215
|
+
|
216
|
+
cipher = OpenSSL::Cipher.new('AES-256-CBC')
|
217
|
+
cipher.decrypt
|
218
|
+
cipher.key = bin_key
|
219
|
+
cipher.iv = bin_iv
|
220
|
+
cipher.update(bin_encrypted) + cipher.final
|
221
|
+
end
|
222
|
+
|
164
223
|
def Hint(m)
|
165
224
|
h = H(m)
|
166
225
|
(0...2 * @@b).inject(0) { |sum, i| sum + 2**i * bit(h, i) }
|
@@ -207,7 +266,7 @@ module Nis::Util
|
|
207
266
|
end
|
208
267
|
|
209
268
|
def decodepoint(s)
|
210
|
-
y = (0...@@b - 1).inject(0) { |sum, i| 2**i * bit(s, i) }
|
269
|
+
y = (0...@@b - 1).inject(0) { |sum, i| sum + 2**i * bit(s, i) }
|
211
270
|
x = xrecover(y)
|
212
271
|
x = @@q - x if x & 1 != bit(s, @@b - 1)
|
213
272
|
_P = [x, y, 1, (x * y) % @@q]
|
data/lib/nis/util/serializer.rb
CHANGED
@@ -90,9 +90,9 @@ module Nis::Util
|
|
90
90
|
a += serialize_common(entity)
|
91
91
|
other_tx = entity[:otherTrans]
|
92
92
|
tx = case other_tx[:type]
|
93
|
-
|
94
|
-
|
95
|
-
|
93
|
+
when 0x0101 then serialize_transfer(other_tx)
|
94
|
+
when 0x0801 then serialize_importance_transfer(other_tx)
|
95
|
+
when 0x1001 then serialize_multisig_aggregate_modification(other_tx)
|
96
96
|
else raise "Unexpected type #{other_tx[:type]}"
|
97
97
|
end
|
98
98
|
a += serialize_int(tx.size)
|
data/lib/nis/version.rb
CHANGED
data/nis.gemspec
CHANGED
@@ -25,13 +25,13 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
26
26
|
spec.require_paths = ['lib']
|
27
27
|
|
28
|
-
spec.post_install_message =
|
28
|
+
spec.post_install_message = '
|
29
29
|
<nis-ruby>
|
30
30
|
Please see https://gitter.im/44uk/nis-ruby for the latest information.
|
31
31
|
The gem is under development. Incompatible changes can be made.
|
32
32
|
Feel free to ask and give feedback to https://twitter.com/44uk_i3
|
33
33
|
Good luck! NEM application development!
|
34
|
-
|
34
|
+
'
|
35
35
|
|
36
36
|
spec.add_development_dependency 'rake', '~> 10.0'
|
37
37
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nis-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yoshiyuki Ieyama
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-09-
|
11
|
+
date: 2017-09-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -372,7 +372,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
372
372
|
version: '0'
|
373
373
|
requirements: []
|
374
374
|
rubyforge_project:
|
375
|
-
rubygems_version: 2.
|
375
|
+
rubygems_version: 2.6.8
|
376
376
|
signing_key:
|
377
377
|
specification_version: 4
|
378
378
|
summary: Ruby client library for the NEM Infrastructure Server API
|