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
@@ -1,144 +0,0 @@
1
- require 'btcruby'
2
- require 'arkecosystem/crypto/enums/types'
3
-
4
- module ArkEcosystem
5
- module Crypto
6
- # The shared cryptography methods.
7
- class Crypto
8
- def self.get_id(transaction)
9
- Digest::SHA256.digest(get_bytes(transaction, false, false)).unpack('H*').first
10
- end
11
-
12
- def self.get_bytes(transaction, skip_signature = true, skip_second_signature = true)
13
- bytes = ''
14
- bytes << [transaction[:type]].pack('c')
15
- bytes << [transaction[:timestamp]].pack('V')
16
- bytes << [transaction[:sender_public_key]].pack('H*')
17
-
18
- bytes << if transaction[:recipient_id]
19
- BTC::Base58.data_from_base58check(transaction[:recipient_id])
20
- else
21
- [].pack('x21')
22
- end
23
-
24
- if transaction[:vendor_field]
25
- bytes << transaction[:vendor_field]
26
-
27
- if transaction[:vendor_field].size < 64
28
- bytes << [].pack("x#{64 - transaction[:vendor_field].size}")
29
- end
30
- else
31
- bytes << [].pack('x64')
32
- end
33
-
34
- bytes << [transaction[:amount]].pack('Q<')
35
- bytes << [transaction[:fee]].pack('Q<')
36
-
37
- case transaction[:type]
38
- when ArkEcosystem::Crypto::Enums::Types::SECOND_SIGNATURE_REGISTRATION
39
- asset_signature_public_key = transaction[:asset][:signature][:public_key]
40
-
41
- bytes << [asset_signature_public_key].pack('H*')
42
- when ArkEcosystem::Crypto::Enums::Types::DELEGATE_REGISTRATION
43
- bytes << transaction[:asset][:delegate][:username]
44
- when ArkEcosystem::Crypto::Enums::Types::VOTE
45
- bytes << transaction[:asset][:votes].join('')
46
- when ArkEcosystem::Crypto::Enums::Types::MULTI_SIGNATURE_REGISTRATION
47
- ms_asset = transaction[:asset][:multisignature]
48
-
49
- bytes << [ms_asset[:min]].pack('C')
50
- bytes << [ms_asset[:lifetime]].pack('C')
51
- bytes << ms_asset[:keysgroup].join('')
52
- end
53
-
54
- if !skip_signature && transaction[:signature]
55
- bytes << [transaction[:signature]].pack('H*')
56
- end
57
-
58
- if !skip_second_signature && transaction[:sign_signature]
59
- bytes << [transaction[:sign_signature]].pack('H*')
60
- end
61
-
62
- bytes
63
- end
64
-
65
- def self.verify(transaction)
66
- public_only_key = BTC::Key.new(public_key: [transaction.sender_public_key].pack('H*'))
67
-
68
- bytes = ArkEcosystem::Crypto::Crypto.get_bytes(transaction.to_hash)
69
-
70
- public_only_key.verify_ecdsa_signature([transaction.signature].pack('H*'), Digest::SHA256.digest(bytes))
71
- end
72
-
73
- def self.second_verify(transaction, second_public_key_hex)
74
- public_only_key = BTC::Key.new(public_key: [second_public_key_hex].pack('H*'))
75
-
76
- bytes = ArkEcosystem::Crypto::Crypto.get_bytes(transaction.to_hash, false)
77
-
78
- public_only_key.verify_ecdsa_signature([transaction.sign_signature].pack('H*'), Digest::SHA256.digest(bytes))
79
- end
80
-
81
- def self.parse_signatures(serialized, transaction, start_offset)
82
- signature = serialized[start_offset..-1]
83
-
84
- multi_signature_offset = 0
85
-
86
- if !signature.length
87
- transaction.delete(:signature)
88
- else
89
- # First Signature
90
- signature_length = signature[2, 2].to_i(16) + 2
91
- transaction[:signature] = serialized[start_offset, signature_length * 2]
92
-
93
- # Multi Signature
94
- multi_signature_offset += signature_length * 2
95
-
96
- # Second Signature
97
- transaction[:second_signature] = serialized[(start_offset + signature_length * 2)..-1]
98
-
99
- if transaction[:second_signature].empty?
100
- transaction.delete(:second_signature)
101
- elsif transaction[:second_signature][0, 2] == 'ff'
102
- transaction.delete(:second_signature)
103
- else
104
- # Second Signature
105
- second_signature_length = signature[2, 2].to_i(16) + 2
106
- transaction[:second_signature] = transaction[:second_signature][0, second_signature_length * 2]
107
-
108
- # Multi Signature
109
- multi_signature_offset += second_signature_length * 2
110
- end
111
-
112
- # All Signatures
113
- signatures = serialized[(start_offset + multi_signature_offset)..-1]
114
-
115
- return transaction if signatures.empty?
116
-
117
- return transaction if signatures[0, 2] != 'ff'
118
-
119
- # Parse Multi Signatures
120
- signatures = signatures[2..-1]
121
- transaction[:signatures] = []
122
-
123
- more_signatures = true
124
-
125
- while more_signatures
126
- break if signatures.empty?
127
-
128
- multi_signature_length = signatures[2, 2].to_i(16) + 2
129
-
130
- if multi_signature_length > 0
131
- transaction[:signatures].push(signatures[0, multi_signature_length * 2])
132
- else
133
- more_signatures = false
134
- end
135
-
136
- signatures = signatures[(multi_signature_length * 2)..-1]
137
- end
138
-
139
- transaction
140
- end
141
- end
142
- end
143
- end
144
- end
@@ -1,94 +0,0 @@
1
- require 'arkecosystem/crypto/identity/address'
2
-
3
- module ArkEcosystem
4
- module Crypto
5
- # The base deserialiser for transactions.
6
- class Deserialiser
7
- def initialize(serialised)
8
- @serialised = serialised
9
- @binary = BTC::Data.data_from_hex(@serialised)
10
-
11
- @handlers = %w[
12
- Transfer
13
- SecondSignatureRegistration
14
- DelegateRegistration
15
- Vote
16
- MultiSignatureRegistration
17
- Ipfs
18
- TimelockTransfer
19
- MultiPayment
20
- DelegateResignation
21
- ]
22
- end
23
-
24
- def deserialise
25
- transaction = {}
26
- transaction[:version] = @binary.unpack('C2').last
27
- transaction[:network] = @binary.unpack('C3').last
28
- transaction[:type] = @binary.unpack('C4').last
29
- transaction[:timestamp] = @binary.unpack('V2').last
30
- transaction[:sender_public_key] = @binary.unpack('H16H66').last
31
- transaction[:fee] = @binary.unpack('C41Q<').last
32
-
33
- vendor_field_length = @binary.unpack('C49C1').last
34
-
35
- if vendor_field_length > 0
36
- vendor_field_offset = (41 + 8 + 1) * 2
37
- vendor_field_take = vendor_field_length * 2
38
-
39
- transaction[:vendor_field_hex] = @binary.unpack("H#{vendor_field_offset}H#{vendor_field_take}").last
40
- end
41
-
42
- asset_offset = (41 + 8 + 1) * 2 + vendor_field_length * 2
43
-
44
- transaction = handle_type(asset_offset, transaction)
45
-
46
- transaction[:amount] = 0 unless transaction[:amount]
47
-
48
- if transaction[:version] == 1 || transaction[:version].empty?
49
- transaction = handle_version_one(transaction)
50
- end
51
-
52
- transaction
53
- end
54
-
55
- private
56
-
57
- def handle_type(asset_offset, transaction)
58
- deserialiser = @handlers[transaction[:type]]
59
- deserialiser = Object.const_get("ArkEcosystem::Crypto::Deserialisers::#{deserialiser}")
60
- deserialiser.new(@serialised, @binary, asset_offset, transaction).deserialise
61
- end
62
-
63
- def handle_version_one(transaction)
64
- if transaction[:second_signature]
65
- transaction[:sign_signature] = transaction[:second_signature]
66
- end
67
-
68
- if transaction[:type] == ArkEcosystem::Crypto::Enums::Types::SECOND_SIGNATURE_REGISTRATION
69
- transaction[:recipient_id] = ArkEcosystem::Crypto::Identity::Address.from_public_key(transaction[:sender_public_key])
70
- end
71
-
72
- if transaction[:type] == ArkEcosystem::Crypto::Enums::Types::VOTE
73
- transaction[:recipient_id] = ArkEcosystem::Crypto::Identity::Address.from_public_key(transaction[:sender_public_key])
74
- end
75
-
76
- if transaction[:type] == ArkEcosystem::Crypto::Enums::Types::MULTI_SIGNATURE_REGISTRATION
77
- # The "recipientId" doesn't exist on v1 multi signature registrations
78
- # transaction[:recipient_id] = ArkEcosystem::Crypto::Identity::Address::from_public_key(transaction[:sender_public_key]);
79
- transaction[:asset][:multisignature][:keysgroup] = transaction[:asset][:multisignature][:keysgroup].map! { |key| '+' + key }
80
- end
81
-
82
- if transaction[:vendor_field_hex]
83
- transaction[:vendor_field] = BTC::Data.data_from_hex(transaction[:vendor_field_hex])
84
- end
85
-
86
- unless transaction[:id]
87
- transaction[:id] = ArkEcosystem::Crypto::Crypto.get_id(transaction)
88
- end
89
-
90
- transaction
91
- end
92
- end
93
- end
94
- end
@@ -1,15 +0,0 @@
1
- module ArkEcosystem
2
- module Crypto
3
- module Deserialisers
4
- # The base deserialiser for transactions.
5
- class Base
6
- def initialize(serialised, binary, asset_offset, transaction)
7
- @serialised = serialised
8
- @binary = binary
9
- @asset_offset = asset_offset
10
- @transaction = transaction
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,22 +0,0 @@
1
- module ArkEcosystem
2
- module Crypto
3
- module Deserialisers
4
- # The deserialiser for delegate registration transactions.
5
- class DelegateRegistration < Base
6
- def deserialise
7
- @transaction[:asset] = {
8
- delegate: {}
9
- }
10
-
11
- username_length = @binary.unpack("C#{@asset_offset / 2}Q<").last & 0xff
12
-
13
- username = @serialised[@asset_offset + 2, username_length * 2]
14
-
15
- @transaction[:asset][:delegate][:username] = BTC::Data.data_from_hex(username)
16
-
17
- ArkEcosystem::Crypto::Crypto.parse_signatures(@serialised, @transaction, @asset_offset + (username_length + 1) * 2)
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,12 +0,0 @@
1
- module ArkEcosystem
2
- module Crypto
3
- module Deserialisers
4
- # The deserialiser for delegate resignation transactions.
5
- class DelegateResignation < Base
6
- def deserialise
7
- ArkEcosystem::Crypto::Crypto.parse_signatures(@serialised, @transaction, @asset_offset)
8
- end
9
- end
10
- end
11
- end
12
- end
@@ -1,18 +0,0 @@
1
- module ArkEcosystem
2
- module Crypto
3
- module Deserialisers
4
- # The deserialiser for IPFS transactions.
5
- class IPFS < Base
6
- def deserialise
7
- @transaction[:asset] = {}
8
-
9
- dag_length = @binary.unpack("C#{@asset_offset / 2}Q<").last & 0xff
10
-
11
- @transaction[:asset][:dag] = @serialised[@asset_offset + 2, dag_length * 2]
12
-
13
- ArkEcosystem::Crypto::Crypto.parse_signatures(@serialised, @transaction, @asset_offset + 2 + length * 2)
14
- end
15
- end
16
- end
17
- end
18
- end
@@ -1,38 +0,0 @@
1
- module ArkEcosystem
2
- module Crypto
3
- module Deserialisers
4
- # The deserialiser for multi payment transactions.
5
- class MultiPayment < Base
6
- def deserialise
7
- @transaction[:asset] = {
8
- amount: 0,
9
- payments: []
10
- }
11
-
12
- total = @binary.unpack("C#{@asset_offset / 2}Q<").last & 0xff
13
- offset = @asset_offset / 2 + 1
14
-
15
- i = 0
16
- while i < total
17
- recipient_id = @binary.unpack("H#{(offset + 1) * 2}H42").last
18
-
19
- payment = {
20
- amount: @binary.unpack("C#{@asset_offset / 2}Q<").last,
21
- recipient_id: BTC::Base58.base58check_from_data([recipient_id].pack('H*'))
22
- }
23
-
24
- @transaction[:asset][:payments].push(payment)
25
-
26
- offset += 22
27
-
28
- i += 1
29
- end
30
-
31
- products.each { |item| @transaction[:amount] += item[:amount] }
32
-
33
- ArkEcosystem::Crypto::Crypto.parse_signatures(@serialised, @transaction, offset * 2)
34
- end
35
- end
36
- end
37
- end
38
- end
@@ -1,32 +0,0 @@
1
- module ArkEcosystem
2
- module Crypto
3
- module Deserialisers
4
- # The deserialiser for multi signature registrations transactions.
5
- class MultiSignatureRegistration < Base
6
- def deserialise
7
- @transaction[:asset] = {
8
- multisignature: {
9
- keysgroup: []
10
- }
11
- }
12
-
13
- @transaction[:asset][:multisignature][:min] = @binary.unpack("C#{@asset_offset / 2}Q<").last & 0xff
14
- @transaction[:asset][:multisignature][:lifetime] = @binary.unpack("C#{@asset_offset / 2 + 2}Q<").last & 0xff
15
-
16
- count = @binary.unpack("C#{@asset_offset / 2 + 1}Q<").last & 0xff
17
-
18
- i = 0
19
- while i < count
20
- index_start = @asset_offset + 6 + i * 66
21
-
22
- @transaction[:asset][:multisignature][:keysgroup].push(@serialised[index_start, 66])
23
-
24
- i += 1
25
- end
26
-
27
- ArkEcosystem::Crypto::Crypto.parse_signatures(@serialised, @transaction, @asset_offset + 6 + count * 66)
28
- end
29
- end
30
- end
31
- end
32
- end
@@ -1,18 +0,0 @@
1
- module ArkEcosystem
2
- module Crypto
3
- module Deserialisers
4
- # The deserialiser for second signature registrations transactions.
5
- class SecondSignatureRegistration < Base
6
- def deserialise
7
- @transaction[:asset] = {
8
- signature: {}
9
- }
10
-
11
- @transaction[:asset][:signature][:public_key] = @serialised[@asset_offset, 66]
12
-
13
- ArkEcosystem::Crypto::Crypto.parse_signatures(@serialised, @transaction, @asset_offset + 66)
14
- end
15
- end
16
- end
17
- end
18
- end
@@ -1,19 +0,0 @@
1
- module ArkEcosystem
2
- module Crypto
3
- module Deserialisers
4
- # The deserialiser for timelock transfer transactions.
5
- class TimelockTransfer < Base
6
- def deserialise
7
- @transaction[:amount] = @binary.unpack("C#{@asset_offset / 2}Q<").last
8
- @transaction[:timelocktype] = @binary.unpack("C#{@asset_offset / 2 + 8}").last & 0xff
9
- @transaction[:timelock] = @binary.unpack("C#{@asset_offset / 2 + 9}Q<").last
10
-
11
- recipient_id = @binary.unpack("H#{(@asset_offset / 2 + 13) * 2}H42").last
12
- @transaction[:recipient_id] = BTC::Base58.base58check_from_data([recipient_id].pack('H*'))
13
-
14
- ArkEcosystem::Crypto::Crypto.parse_signatures(@serialised, @transaction, @asset_offset + (21 + 13) * 2)
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,18 +0,0 @@
1
- module ArkEcosystem
2
- module Crypto
3
- module Deserialisers
4
- # The deserialiser for transfer transactions.
5
- class Transfer < Base
6
- def deserialise
7
- @transaction[:amount] = @binary.unpack("C#{@asset_offset / 2}Q<").last
8
- @transaction[:expiration] = @binary.unpack("C#{@asset_offset / 2 + 8}").last
9
-
10
- recipient_id = @binary.unpack("H#{(@asset_offset / 2 + 12) * 2}H42").last
11
- @transaction[:recipient_id] = BTC::Base58.base58check_from_data([recipient_id].pack('H*'))
12
-
13
- ArkEcosystem::Crypto::Crypto.parse_signatures(@serialised, @transaction, @asset_offset + (21 + 12) * 2)
14
- end
15
- end
16
- end
17
- end
18
- end
@@ -1,31 +0,0 @@
1
- module ArkEcosystem
2
- module Crypto
3
- module Deserialisers
4
- # The deserialiser for vote transactions.
5
- class Vote < Base
6
- def deserialise
7
- @transaction[:asset] = {
8
- votes: []
9
- }
10
-
11
- vote_length = @binary.unpack("C#{@asset_offset / 2}Q<").last & 0xff
12
-
13
- i = 0
14
- while i < vote_length
15
- index_start = @asset_offset + 2 + i * 2 * 34
16
- index_end = 2 * 34
17
-
18
- vote = @serialised[index_start, index_end]
19
- vote = (vote[1] == '1' ? '+' : '-') + vote[2..-1]
20
-
21
- @transaction[:asset][:votes].push(vote)
22
-
23
- i += 1
24
- end
25
-
26
- ArkEcosystem::Crypto::Crypto.parse_signatures(@serialised, @transaction, @asset_offset + 2 + vote_length * 34 * 2)
27
- end
28
- end
29
- end
30
- end
31
- end