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
@@ -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