nis-ruby 0.0.15 → 0.0.16
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 +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
|