arkecosystem-crypto 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/lib/arkecosystem/crypto.rb +35 -42
  3. data/lib/arkecosystem/crypto/{identity → identities}/address.rb +10 -4
  4. data/lib/arkecosystem/crypto/identities/private_key.rb +18 -0
  5. data/lib/arkecosystem/crypto/identities/public_key.rb +18 -0
  6. data/lib/arkecosystem/crypto/{identity → identities}/wif.rb +4 -4
  7. data/lib/arkecosystem/crypto/networks/devnet.rb +1 -5
  8. data/lib/arkecosystem/crypto/networks/mainnet.rb +1 -5
  9. data/lib/arkecosystem/crypto/networks/testnet.rb +1 -5
  10. data/lib/arkecosystem/crypto/transactions/builder/base.rb +52 -0
  11. data/lib/arkecosystem/crypto/transactions/builder/delegate_registration.rb +34 -0
  12. data/lib/arkecosystem/crypto/transactions/builder/multi_signature_registration.rb +43 -0
  13. data/lib/arkecosystem/crypto/transactions/builder/second_signature_registration.rb +28 -0
  14. data/lib/arkecosystem/crypto/transactions/builder/transfer.rb +33 -0
  15. data/lib/arkecosystem/crypto/transactions/builder/vote.rb +29 -0
  16. data/lib/arkecosystem/crypto/transactions/deserializer.rb +98 -0
  17. data/lib/arkecosystem/crypto/transactions/deserializers/base.rb +17 -0
  18. data/lib/arkecosystem/crypto/transactions/deserializers/delegate_registration.rb +24 -0
  19. data/lib/arkecosystem/crypto/transactions/deserializers/delegate_resignation.rb +14 -0
  20. data/lib/arkecosystem/crypto/transactions/deserializers/ipfs.rb +20 -0
  21. data/lib/arkecosystem/crypto/transactions/deserializers/multi_payment.rb +40 -0
  22. data/lib/arkecosystem/crypto/transactions/deserializers/multi_signature_registration.rb +34 -0
  23. data/lib/arkecosystem/crypto/transactions/deserializers/second_signature_registration.rb +20 -0
  24. data/lib/arkecosystem/crypto/transactions/deserializers/timelock_transfer.rb +21 -0
  25. data/lib/arkecosystem/crypto/transactions/deserializers/transfer.rb +21 -0
  26. data/lib/arkecosystem/crypto/transactions/deserializers/vote.rb +33 -0
  27. data/lib/arkecosystem/crypto/transactions/serializer.rb +86 -0
  28. data/lib/arkecosystem/crypto/transactions/serializers/base.rb +15 -0
  29. data/lib/arkecosystem/crypto/transactions/serializers/delegate_registration.rb +19 -0
  30. data/lib/arkecosystem/crypto/transactions/serializers/delegate_resignation.rb +14 -0
  31. data/lib/arkecosystem/crypto/transactions/serializers/ipfs.rb +19 -0
  32. data/lib/arkecosystem/crypto/transactions/serializers/multi_payment.rb +25 -0
  33. data/lib/arkecosystem/crypto/transactions/serializers/multi_signature_registration.rb +33 -0
  34. data/lib/arkecosystem/crypto/transactions/serializers/second_signature_registration.rb +16 -0
  35. data/lib/arkecosystem/crypto/transactions/serializers/timelock_transfer.rb +23 -0
  36. data/lib/arkecosystem/crypto/transactions/serializers/transfer.rb +22 -0
  37. data/lib/arkecosystem/crypto/transactions/serializers/vote.rb +25 -0
  38. data/lib/arkecosystem/crypto/transactions/transaction.rb +198 -0
  39. data/lib/arkecosystem/crypto/utils/message.rb +42 -0
  40. data/lib/arkecosystem/crypto/utils/slot.rb +23 -0
  41. data/lib/arkecosystem/crypto/version.rb +1 -1
  42. metadata +67 -39
  43. data/lib/arkecosystem/crypto/builder/delegate_registration.rb +0 -33
  44. data/lib/arkecosystem/crypto/builder/multi_signature_registration.rb +0 -45
  45. data/lib/arkecosystem/crypto/builder/second_signature_registration.rb +0 -27
  46. data/lib/arkecosystem/crypto/builder/transaction.rb +0 -109
  47. data/lib/arkecosystem/crypto/builder/transfer.rb +0 -32
  48. data/lib/arkecosystem/crypto/builder/vote.rb +0 -28
  49. data/lib/arkecosystem/crypto/crypto.rb +0 -144
  50. data/lib/arkecosystem/crypto/deserialiser.rb +0 -94
  51. data/lib/arkecosystem/crypto/deserialisers/base.rb +0 -15
  52. data/lib/arkecosystem/crypto/deserialisers/delegate_registration.rb +0 -22
  53. data/lib/arkecosystem/crypto/deserialisers/delegate_resignation.rb +0 -12
  54. data/lib/arkecosystem/crypto/deserialisers/ipfs.rb +0 -18
  55. data/lib/arkecosystem/crypto/deserialisers/multi_payment.rb +0 -38
  56. data/lib/arkecosystem/crypto/deserialisers/multi_signature_registration.rb +0 -32
  57. data/lib/arkecosystem/crypto/deserialisers/second_signature_registration.rb +0 -18
  58. data/lib/arkecosystem/crypto/deserialisers/timelock_transfer.rb +0 -19
  59. data/lib/arkecosystem/crypto/deserialisers/transfer.rb +0 -18
  60. data/lib/arkecosystem/crypto/deserialisers/vote.rb +0 -31
  61. data/lib/arkecosystem/crypto/identity/private_key.rb +0 -14
  62. data/lib/arkecosystem/crypto/identity/public_key.rb +0 -18
  63. data/lib/arkecosystem/crypto/message.rb +0 -42
  64. data/lib/arkecosystem/crypto/models/transaction.rb +0 -16
  65. data/lib/arkecosystem/crypto/serialiser.rb +0 -84
  66. data/lib/arkecosystem/crypto/serialisers/base.rb +0 -13
  67. data/lib/arkecosystem/crypto/serialisers/delegate_registration.rb +0 -17
  68. data/lib/arkecosystem/crypto/serialisers/delegate_resignation.rb +0 -12
  69. data/lib/arkecosystem/crypto/serialisers/ipfs.rb +0 -17
  70. data/lib/arkecosystem/crypto/serialisers/multi_payment.rb +0 -23
  71. data/lib/arkecosystem/crypto/serialisers/multi_signature_registration.rb +0 -31
  72. data/lib/arkecosystem/crypto/serialisers/second_signature_registration.rb +0 -14
  73. data/lib/arkecosystem/crypto/serialisers/timelock_transfer.rb +0 -21
  74. data/lib/arkecosystem/crypto/serialisers/transfer.rb +0 -20
  75. data/lib/arkecosystem/crypto/serialisers/vote.rb +0 -23
@@ -0,0 +1,19 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Transactions
4
+ module Serializers
5
+ # The serializer for delegate registration transactions.
6
+ class DelegateRegistration < Base
7
+ def serialize
8
+ delegate_bytes = BTC::Data.hex_from_data(@transaction[:asset][:delegate][:username])
9
+
10
+ @bytes << [delegate_bytes.length / 2].pack('C')
11
+ @bytes << BTC::Data.data_from_hex(delegate_bytes)
12
+
13
+ @bytes
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Transactions
4
+ module Serializers
5
+ # The serializer for delegate resignation transactions.
6
+ class DelegateResignation < Base
7
+ def serialize
8
+ @bytes
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Transactions
4
+ module Serializers
5
+ # The serializer for IPFS transactions.
6
+ class IPFS < Base
7
+ def serialize
8
+ dag = @transaction[:asset][:ipfs][:dag]
9
+
10
+ @bytes << [dag.length / 2].pack('C')
11
+ @bytes << BTC::Data.data_from_hex(dag)
12
+
13
+ @bytes
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,25 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Transactions
4
+ module Serializers
5
+ # The serializer for multi payment transactions.
6
+ class MultiPayment < Base
7
+ def serialize
8
+ @bytes << [@transaction[:asset][:payments].count].pack('Q<')
9
+
10
+ @transaction[:asset][:payments].each do |_item|
11
+ @bytes << [@item[:amount]].pack('Q<')
12
+
13
+ recipient_id = BTC::Base58.data_from_base58check(@item[:recipientId])
14
+ recipient_id = BTC::Data.hex_from_data(recipient_id)
15
+
16
+ @bytes << [recipient_id].pack('H*')
17
+ end
18
+
19
+ @bytes
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,33 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Transactions
4
+ module Serializers
5
+ # The serializer for multi signature registrations transactions.
6
+ class MultiSignatureRegistration < Base
7
+ def serialize
8
+ keysgroup = []
9
+
10
+ if @transaction[:version] == 1 || @transaction[:version].empty?
11
+ @transaction[:asset][:multisignature][:keysgroup].each do |item|
12
+ if item.start_with?('+')
13
+ keysgroup.push(item[1..-1])
14
+ else
15
+ keysgroup.push(item)
16
+ end
17
+ end
18
+ else
19
+ keysgroup = @transaction[:asset][:multisignature][:keysgroup]
20
+ end
21
+
22
+ @bytes << [@transaction[:asset][:multisignature][:min]].pack('C')
23
+ @bytes << [@transaction[:asset][:multisignature][:keysgroup].count].pack('C')
24
+ @bytes << [@transaction[:asset][:multisignature][:lifetime]].pack('C')
25
+ @bytes << BTC::Data.data_from_hex(keysgroup.join(''))
26
+
27
+ @bytes
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,16 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Transactions
4
+ module Serializers
5
+ # The serializer for second signature registrations transactions.
6
+ class SecondSignatureRegistration < Base
7
+ def serialize
8
+ @bytes << BTC::Data.data_from_hex(@transaction[:asset][:signature][:publicKey])
9
+
10
+ @bytes
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Transactions
4
+ module Serializers
5
+ # The serializer for timelock transfer transactions.
6
+ class TimelockTransfer < Base
7
+ def serialize
8
+ @bytes << [@transaction[:amount]].pack('Q<')
9
+ @bytes << [@transaction[:timelocktype]].pack('h*')
10
+ @bytes << [@transaction[:timelock]].pack('V')
11
+
12
+ recipient_id = BTC::Base58.data_from_base58check(@transaction[:recipientId])
13
+ recipient_id = BTC::Data.hex_from_data(recipient_id)
14
+
15
+ @bytes << [recipient_id].pack('H*')
16
+
17
+ @bytes
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Transactions
4
+ module Serializers
5
+ # The serializer for transfer transactions.
6
+ class Transfer < Base
7
+ def serialize
8
+ @bytes << [@transaction[:amount]].pack('Q<')
9
+ @bytes << [@transaction[:expiration] || 0].pack('V')
10
+
11
+ recipient_id = BTC::Base58.data_from_base58check(@transaction[:recipientId])
12
+ recipient_id = BTC::Data.hex_from_data(recipient_id)
13
+
14
+ @bytes << [recipient_id].pack('H*')
15
+
16
+ @bytes
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,25 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Transactions
4
+ module Serializers
5
+ # The serializer for vote transactions.
6
+ class Vote < Base
7
+ def serialize
8
+ vote_bytes = []
9
+
10
+ @transaction[:asset][:votes].each do |item|
11
+ prefix = item.start_with?('+') ? '01' : '00'
12
+
13
+ vote_bytes.push(prefix + item[1..-1])
14
+ end
15
+
16
+ @bytes << [@transaction[:asset][:votes].count].pack('C')
17
+ @bytes << BTC::Data.data_from_hex(vote_bytes.join(''))
18
+
19
+ @bytes
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,198 @@
1
+ require 'json'
2
+ require 'btcruby'
3
+ require 'arkecosystem/crypto/enums/types'
4
+
5
+ module ArkEcosystem
6
+ module Crypto
7
+ module Transactions
8
+ # The model of a transaction.
9
+ class Transaction
10
+ attr_accessor :amount, :asset, :fee, :id, :recipient_id, :sender_public_key, :sign_signature, :second_signature, :signature, :signatures, :timestamp, :type, :vendor_field, :vendor_field_hex, :version, :network, :expiration, :timelocktype, :timelock
11
+
12
+ def initialize
13
+ @asset = {}
14
+ end
15
+
16
+ def get_id
17
+ Digest::SHA256.digest(to_bytes(false, false)).unpack('H*').first
18
+ end
19
+
20
+ def sign(passphrase)
21
+ private_key = ArkEcosystem::Crypto::Identities::PrivateKey.from_passphrase(passphrase)
22
+ @sender_public_key = private_key.public_key.unpack('H*').first
23
+ @signature = private_key.ecdsa_signature(Digest::SHA256.digest(to_bytes)).unpack('H*').first
24
+ self
25
+ end
26
+
27
+ def second_sign(second_passphrase)
28
+ second_key = ArkEcosystem::Crypto::Identities::PrivateKey.from_passphrase(second_passphrase)
29
+
30
+ @sign_signature = second_key.ecdsa_signature(Digest::SHA256.digest(to_bytes(false))).unpack('H*').first
31
+ self
32
+ end
33
+
34
+ def verify
35
+ public_only_key = BTC::Key.new(public_key: [@sender_public_key].pack('H*'))
36
+ public_only_key.verify_ecdsa_signature([@signature].pack('H*'), Digest::SHA256.digest(to_bytes))
37
+ end
38
+
39
+ def second_verify(second_public_key)
40
+ public_only_key = BTC::Key.new(public_key: [second_public_key].pack('H*'))
41
+ public_only_key.verify_ecdsa_signature([@sign_signature].pack('H*'), Digest::SHA256.digest(to_bytes(false)))
42
+ end
43
+
44
+ def to_bytes(skip_signature = true, skip_second_signature = true)
45
+ bytes = ''
46
+ bytes << [@type].pack('c')
47
+ bytes << [@timestamp].pack('V')
48
+ bytes << [@sender_public_key].pack('H*')
49
+
50
+ bytes << if @recipient_id
51
+ BTC::Base58.data_from_base58check(@recipient_id)
52
+ else
53
+ [].pack('x21')
54
+ end
55
+
56
+ if @vendor_field
57
+ bytes << @vendor_field
58
+
59
+ if @vendor_field.size < 64
60
+ bytes << [].pack("x#{64 - @vendor_field.size}")
61
+ end
62
+ else
63
+ bytes << [].pack('x64')
64
+ end
65
+
66
+ bytes << [@amount].pack('Q<')
67
+ bytes << [@fee].pack('Q<')
68
+
69
+ case @type
70
+ when ArkEcosystem::Crypto::Enums::Types::SECOND_SIGNATURE_REGISTRATION
71
+ asset_signature_public_key = @asset[:signature][:public_key]
72
+
73
+ bytes << [asset_signature_public_key].pack('H*')
74
+ when ArkEcosystem::Crypto::Enums::Types::DELEGATE_REGISTRATION
75
+ bytes << @asset[:delegate][:username]
76
+ when ArkEcosystem::Crypto::Enums::Types::VOTE
77
+ bytes << @asset[:votes].join('')
78
+ when ArkEcosystem::Crypto::Enums::Types::MULTI_SIGNATURE_REGISTRATION
79
+ ms_asset = @asset[:multisignature]
80
+
81
+ bytes << [ms_asset[:min]].pack('C')
82
+ bytes << [ms_asset[:lifetime]].pack('C')
83
+ bytes << ms_asset[:keysgroup].join('')
84
+ end
85
+
86
+ if !skip_signature && @signature
87
+ bytes << [@signature].pack('H*')
88
+ end
89
+
90
+ if !skip_second_signature && @sign_signature
91
+ bytes << [@sign_signature].pack('H*')
92
+ end
93
+
94
+ bytes
95
+ end
96
+
97
+ def parse_signatures(serialized, start_offset)
98
+ signature = serialized[start_offset..-1]
99
+
100
+ multi_signature_offset = 0
101
+
102
+ if !signature.length
103
+ @signature = nil
104
+ else
105
+ # First Signature
106
+ signature_length = signature[2, 2].to_i(16) + 2
107
+ @signature = serialized[start_offset, signature_length * 2]
108
+
109
+ # Multi Signature
110
+ multi_signature_offset += signature_length * 2
111
+
112
+ # Second Signature
113
+ @second_signature = serialized[(start_offset + signature_length * 2)..-1]
114
+
115
+ if @second_signature.empty?
116
+ @second_signature = nil
117
+ elsif @second_signature[0, 2] == 'ff'
118
+ @second_signature = nil
119
+ else
120
+ # Second Signature
121
+ second_signature_length = @second_signature[2, 2].to_i(16) + 2
122
+ @second_signature = @second_signature[0, second_signature_length * 2]
123
+
124
+ # Multi Signature
125
+ multi_signature_offset += second_signature_length * 2
126
+ end
127
+
128
+ # All Signatures
129
+ signatures = serialized[(start_offset + multi_signature_offset)..-1]
130
+
131
+ return self if signatures.empty?
132
+
133
+ return self if signatures[0, 2] != 'ff'
134
+
135
+ # Parse Multi Signatures
136
+ signatures = signatures[2..-1]
137
+ @signatures = []
138
+
139
+ more_signatures = true
140
+
141
+ while more_signatures
142
+ break if signatures.empty?
143
+
144
+ multi_signature_length = signatures[2, 2].to_i(16) + 2
145
+
146
+ if multi_signature_length > 0
147
+ @signatures.push(signatures[0, multi_signature_length * 2])
148
+ else
149
+ more_signatures = false
150
+ end
151
+
152
+ signatures = signatures[(multi_signature_length * 2)..-1]
153
+ end
154
+
155
+ self
156
+ end
157
+ end
158
+
159
+ def serialize(transaction)
160
+ ArkEcosystem::Crypto::Serialiser.new(transaction).serialize
161
+ end
162
+
163
+ def deserialize(serialized)
164
+ ArkEcosystem::Crypto::Transactions::Deserializer.new(serialized).deserialize
165
+ end
166
+
167
+ def to_params
168
+ {
169
+ type: type,
170
+ amount: amount,
171
+ fee: fee,
172
+ vendorField: vendor_field,
173
+ timestamp: timestamp,
174
+ recipientId: recipient_id,
175
+ senderPublicKey: sender_public_key,
176
+ signature: signature,
177
+ id: id
178
+ }.tap do |h|
179
+ h[:asset] = asset.deep_transform_keys { |key| snake_case_to_camel_case(key) } if asset.any?
180
+ h[:signSignature] = sign_signature if sign_signature
181
+ end
182
+ end
183
+
184
+ def to_json
185
+ to_params.to_json
186
+ end
187
+
188
+ private
189
+
190
+ def snake_case_to_camel_case(string)
191
+ string.to_s.split('_').enum_for(:each_with_index).collect do |s, index|
192
+ index.zero? ? s : s.capitalize
193
+ end.join
194
+ end
195
+ end
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,42 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Utils
4
+ # The builder to work with signed messages.
5
+ class Message
6
+ def initialize(message)
7
+ @public_key = message[:publickey]
8
+ @signature = message[:signature]
9
+ @message = message[:message]
10
+ end
11
+
12
+ def self.sign(message, passphrase)
13
+ key = ArkEcosystem::Crypto::Identities::PrivateKey.from_passphrase(passphrase)
14
+
15
+ hash = Digest::SHA256.digest(message)
16
+
17
+ Message.new(publickey: BTC.to_hex(key.public_key),
18
+ signature: BTC.to_hex(key.ecdsa_signature(hash)),
19
+ message: message)
20
+ end
21
+
22
+ def verify
23
+ key = BTC::Key.new(public_key: BTC.from_hex(@public_key))
24
+
25
+ hash = Digest::SHA256.digest(@message)
26
+
27
+ key.verify_ecdsa_signature(BTC.from_hex(@signature), hash)
28
+ end
29
+
30
+ def to_params
31
+ { publickey: @public_key,
32
+ signature: @signature,
33
+ message: @message }
34
+ end
35
+
36
+ def to_json
37
+ to_params.to_json
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end