arkecosystem-crypto 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.
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