iota-ruby 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d338628f110c60d06b1b639d25dd4773839658bf
4
- data.tar.gz: 7e06e28d669a453fcf59373c099f209519342c17
3
+ metadata.gz: e15da20a0b19ab615e650922f5e5182d0ccae186
4
+ data.tar.gz: a6749e1c32299500485799903b203e9d6688960f
5
5
  SHA512:
6
- metadata.gz: 95ef1fb4978e645b6b6baed2822764ee0e60fa4cfa9f2439073c3a0a35b7ddf2e4bfb854b640123805246a440ec9ca441ba18a8c2a4804ccdd7c10556105332c
7
- data.tar.gz: e12509d8fa7ec4b673aaafbccd7a7fee6888fb70d33943e4ca66a73b986653f6ce857a6f3f837cc2181c955d6397040eac62354b8bd644795c91195380e03541
6
+ metadata.gz: 2e9495318e52b2b1d1c5279a5c572819c59a3408f27794e9aa4f2bf3a24b2cc3acd8e454b0c6e0cf287745b8d0b8d04a6d391b88dd6ba709fbcb9495a7564261
7
+ data.tar.gz: 7185c56ed47281120f6ddba2d39c29d7f6d437b2331b871f97ac678e8c4a45d776b96a7bc2f456416b949a89df0b1620277b19ab1ed7901b3739e3e44f9324a6
data/.gitignore CHANGED
@@ -10,3 +10,6 @@ Gemfile.lock
10
10
  /spec/reports/
11
11
  /tmp/
12
12
  .DS_Store
13
+ Makefile
14
+ *.bundle
15
+ *.o
data/README.md CHANGED
@@ -13,7 +13,7 @@ This gem is a **beta release**. If you find any bug or face issue, please [post
13
13
  Add this line to your application's Gemfile:
14
14
 
15
15
  ```ruby
16
- gem 'iota-ruby', '~> 1.0.1', require: 'iota'
16
+ gem 'iota-ruby', require: 'iota'
17
17
  ```
18
18
 
19
19
  And then execute:
@@ -55,7 +55,7 @@ Overall, there are currently four subclasses that are accessible from the IOTA o
55
55
  - **`api`**: Core API functionality for interacting with the IOTA core.
56
56
  - **`utils`**: Utility related functions for conversions, validation and so on
57
57
  - **`validator`**: Validator functions that can help with determining whether the inputs or results that you get are valid.
58
- - **`multisig`**: *In progress*
58
+ - **`multisig`**: Functions for creating and signing multi-signature addresses and transactions.
59
59
 
60
60
 
61
61
  ## How to use the Library
data/Rakefile CHANGED
@@ -1,5 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
+ require "rake/extensiontask"
3
4
 
4
5
  Rake::TestTask.new(:test) do |t|
5
6
  t.libs << "test"
@@ -7,4 +8,17 @@ Rake::TestTask.new(:test) do |t|
7
8
  t.test_files = FileList["test/**/*_test.rb"]
8
9
  end
9
10
 
10
- task :default => :test
11
+ Rake::ExtensionTask.new "ccurl" do |ext|
12
+ ext.lib_dir = "lib"
13
+ end
14
+
15
+ def can_compile_extensions
16
+ return false if RUBY_DESCRIPTION =~ /jruby/
17
+ return true
18
+ end
19
+
20
+ if can_compile_extensions
21
+ task :default => [:compile, :test]
22
+ else
23
+ task :default => [:test]
24
+ end
data/examples/multisig.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require "bundler/setup"
2
2
  require "iota"
3
3
 
4
- iota = IOTA::Client.new(provider: 'http://node.lukaseder.de:14265')
4
+ iota = IOTA::Client.new(provider: 'http://localhost:14265')
5
5
 
6
6
  # First co-signer uses index 0 and security level 3
7
7
  digestOne = iota.multisig.getDigest('ABCDFG', 0, 3)
@@ -55,3 +55,15 @@ firstSignedBundle = iota.multisig.addSignature(initiatedBundle, finalAddress, io
55
55
  finalBundle = iota.multisig.addSignature(firstSignedBundle, finalAddress, iota.multisig.getKey('FDSAG', 0, 3))
56
56
 
57
57
  puts "IS VALID SIGNATURE: #{iota.utils.validateSignatures(finalBundle, finalAddress)}"
58
+
59
+ # Send signed transction
60
+ # Uncomment following lines if you want to send transaction
61
+ # trytes = finalBundle.map do |tx|
62
+ # iota.utils.transactionTrytes(tx)
63
+ # end
64
+
65
+ # iota.api.sendTrytes(trytes.reverse, 10, 14) do |st1, transactions|
66
+ # if st1
67
+ # puts data
68
+ # end
69
+ # end
data/ext/ccurl/ccurl.c ADDED
@@ -0,0 +1,125 @@
1
+ #include <ruby.h>
2
+ #include <stdint.h>
3
+
4
+ #define HASH_LENGTH 243
5
+ #define NUMBER_OF_ROUNDS 81
6
+ #define STATE_LENGTH 3 * HASH_LENGTH
7
+
8
+ typedef int64_t trit_t;
9
+
10
+ #define __TRUTH_TABLE 1, 0, -1, 1, -1, 0, -1, 1, 0
11
+
12
+ static const trit_t TRUTH_TABLE[9] = {__TRUTH_TABLE};
13
+
14
+ typedef struct {
15
+ int rounds;
16
+ trit_t state[STATE_LENGTH];
17
+ } Curl;
18
+
19
+ static VALUE ccurl_transform(VALUE self);
20
+
21
+ static VALUE ccurl_alloc(VALUE klass) {
22
+ Curl *ctx = ALLOC(Curl);
23
+ return Data_Wrap_Struct(klass, 0, RUBY_DEFAULT_FREE, ctx);
24
+ }
25
+
26
+ static VALUE ccurl_init(VALUE self, VALUE rounds) {
27
+ Curl *ctx;
28
+ int requested = NUMBER_OF_ROUNDS;
29
+
30
+ if (TYPE(rounds) != T_NIL) {
31
+ requested = NUM2INT(rounds);
32
+ }
33
+
34
+ Data_Get_Struct(self, Curl, ctx);
35
+
36
+ ctx->rounds = requested;
37
+ memset(ctx->state, (trit_t)0, STATE_LENGTH * sizeof(trit_t));
38
+
39
+ return self;
40
+ }
41
+
42
+ static VALUE ccurl_absorb(VALUE self, VALUE data) {
43
+ Curl *ctx;
44
+ Data_Get_Struct(self, Curl, ctx);
45
+
46
+ trit_t *trits;
47
+
48
+ int offset = 0;
49
+ int length = NUM2INT(rb_funcall(data, rb_intern("length"), 0, 0));
50
+
51
+ trits = (trit_t*)malloc(length * sizeof(trit_t));
52
+
53
+ for (int i = 0; i < length; ++i) {
54
+ trits[i] = (trit_t)(NUM2LONG(rb_ary_entry(data, i)));
55
+ }
56
+
57
+ do {
58
+ memcpy(ctx->state, trits + offset, (length < HASH_LENGTH ? length : HASH_LENGTH) * sizeof(trit_t));
59
+ ccurl_transform(self);
60
+ offset += HASH_LENGTH;
61
+ } while ((length -= HASH_LENGTH) > 0);
62
+
63
+ free(trits);
64
+
65
+ return Qnil;
66
+ }
67
+
68
+ static VALUE ccurl_squeeze(VALUE self, VALUE data) {
69
+ Curl *ctx;
70
+ Data_Get_Struct(self, Curl, ctx);
71
+
72
+ int incoming_count, length = NUM2INT(rb_funcall(data, rb_intern("length"), 0, 0));
73
+
74
+ for(incoming_count = length; length < HASH_LENGTH; length++) {
75
+ rb_ary_push(data, LONG2NUM(0));
76
+ }
77
+
78
+ for (int i = 0; i < HASH_LENGTH; i++) {
79
+ rb_ary_store(data, i, LONG2NUM(ctx->state[i]));
80
+ }
81
+
82
+ ccurl_transform(self);
83
+
84
+ return Qnil;
85
+ }
86
+
87
+ static VALUE ccurl_transform(VALUE self) {
88
+ Curl *ctx;
89
+ Data_Get_Struct(self, Curl, ctx);
90
+
91
+ trit_t scratchpad[STATE_LENGTH];
92
+ int round, scratchpadIndex=0, scratchpadIndexSave, stateIndex;
93
+
94
+ for (round = 0; round < NUMBER_OF_ROUNDS; round++) {
95
+ memcpy(scratchpad, ctx->state, STATE_LENGTH * sizeof(trit_t));
96
+
97
+ for (stateIndex = 0; stateIndex < STATE_LENGTH; stateIndex++) {
98
+ scratchpadIndexSave = scratchpadIndex;
99
+ scratchpadIndex += (scratchpadIndex < 365 ? 364 : -365);
100
+ ctx->state[stateIndex] = TRUTH_TABLE[scratchpad[scratchpadIndexSave ] + scratchpad[scratchpadIndex ] * 3 + 4];
101
+ }
102
+ }
103
+
104
+ return Qnil;
105
+ }
106
+
107
+ static VALUE ccurl_reset(VALUE self) {
108
+ Curl *ctx;
109
+ Data_Get_Struct(self, Curl, ctx);
110
+ memset(ctx->state, 0, STATE_LENGTH * sizeof(char));
111
+ return Qnil;
112
+ }
113
+
114
+ void Init_ccurl(void) {
115
+ VALUE iota = rb_define_module("IOTA");
116
+ VALUE iotaCrypto = rb_define_module_under(iota, "Crypto");
117
+ VALUE cCurl = rb_define_class_under(iotaCrypto, "CCurl", rb_cObject);
118
+
119
+ rb_define_alloc_func(cCurl, ccurl_alloc);
120
+ rb_define_method(cCurl, "initialize", ccurl_init, 1);
121
+ rb_define_method(cCurl, "absorb", ccurl_absorb, 1);
122
+ rb_define_method(cCurl, "squeeze", ccurl_squeeze, 1);
123
+ rb_define_method(cCurl, "transform", ccurl_transform, 0);
124
+ rb_define_method(cCurl, "reset", ccurl_reset, 0);
125
+ }
@@ -0,0 +1,23 @@
1
+ can_compile_extensions = false
2
+ want_extensions = true
3
+
4
+ begin
5
+ require 'mkmf'
6
+ can_compile_extensions = true
7
+ rescue Exception
8
+ # This will appear only in verbose mode.
9
+ $stderr.puts "Could not require 'mkmf'. Not fatal, the extensions are optional."
10
+ end
11
+
12
+ if can_compile_extensions && want_extensions
13
+ extension_name = 'ccurl'
14
+ dir_config(extension_name) # The destination
15
+ create_makefile(extension_name) # Create Makefile
16
+ else
17
+ # Create a dummy Makefile, to satisfy Gem::Installer#install
18
+ mfile = open("Makefile", "wb")
19
+ mfile.puts '.PHONY: install'
20
+ mfile.puts 'install:'
21
+ mfile.puts "\t" + '@echo "Extensions not installed, falling back to pure Ruby version."'
22
+ mfile.close
23
+ end
data/iota-ruby.gemspec CHANGED
@@ -17,9 +17,11 @@ Gem::Specification.new do |spec|
17
17
  spec.test_files = `git ls-files -- test/*`.split("\n")
18
18
  spec.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
19
19
  spec.require_paths = ["lib"]
20
+ spec.extensions = ["ext/ccurl/extconf.rb"]
20
21
 
21
22
  spec.add_development_dependency "bundler", "~> 1.15"
22
23
  spec.add_development_dependency "rake", "~> 10.0"
23
24
  spec.add_development_dependency "minitest", "~> 5.0"
25
+ spec.add_development_dependency "rake-compiler", "~> 1.0.4"
24
26
  spec.add_dependency "digest-sha3", "~> 1.1"
25
27
  end
@@ -10,7 +10,7 @@ module IOTA
10
10
  ret_status = false
11
11
  ret_data = nil
12
12
  # get the trytes of the transaction hashes
13
- getTrytes(hashes) do |status, trytes|
13
+ getTrytesInBatches(hashes) do |status, trytes|
14
14
  ret_status = status
15
15
  if status
16
16
  transactionObjects = []
@@ -397,6 +397,25 @@ module IOTA
397
397
  end
398
398
  end
399
399
  end
400
+
401
+ def getTrytesInBatches(hashes, batchSize = 500, &callback)
402
+ if !@validator.isArrayOfHashes(hashes)
403
+ return sendData(false, "Invalid Trytes provided", &callback)
404
+ end
405
+
406
+ data = []
407
+
408
+ hashes.in_groups_of(batchSize, false) do |group|
409
+ getTrytes(group) do |status, trytes|
410
+ if !status
411
+ return sendData(false, trytes, &callback)
412
+ end
413
+ data += trytes
414
+ end
415
+ end
416
+
417
+ sendData(true, data, &callback)
418
+ end
400
419
  end
401
420
  end
402
421
  end
@@ -6,7 +6,7 @@ module IOTA
6
6
  MAX_TRIT_VALUE = 1
7
7
  MIN_TRIT_VALUE = -1
8
8
  BYTE_HASH_LENGTH = 48
9
- HASH_LENGTH = IOTA::Crypto::Curl::HASH_LENGTH
9
+ HASH_LENGTH = Curl::HASH_LENGTH
10
10
 
11
11
  # All possible tryte values
12
12
  TRYTES_ALPHABET = "9ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -1,73 +1,17 @@
1
+ if !Dir.glob(File.join(File.dirname(__FILE__), '../../ccurl.*')).empty?
2
+ require "iota/crypto/curl_c"
3
+ BaseCurl = IOTA::Crypto::CCurl
4
+ else
5
+ require "iota/crypto/curl_ruby"
6
+ BaseCurl = IOTA::Crypto::RubyCurl
7
+ end
8
+
1
9
  module IOTA
2
10
  module Crypto
3
- class Curl
4
- NUMBER_OF_ROUNDS = 81
5
- HASH_LENGTH = 243
6
- STATE_LENGTH = 3 * HASH_LENGTH
7
-
11
+ class Curl < BaseCurl
8
12
  def initialize(rounds = nil)
9
- @rounds = rounds || NUMBER_OF_ROUNDS
10
- @truthTable = [1, 0, -1, 2, 1, -1, 0, 2, -1, 1, 0]
11
- end
12
-
13
- def setup(state = nil)
14
- if state
15
- @state = state
16
- else
17
- @state = []
18
- STATE_LENGTH.times {|a| @state << 0}
19
- end
20
- end
21
-
22
- def reset
23
- setup
24
- end
25
-
26
- def absorb(trits, offset, length)
27
- loop do
28
- i = 0
29
- limit = length < HASH_LENGTH ? length : HASH_LENGTH
30
-
31
- while i < limit
32
- @state[i] = trits[offset]
33
- i += 1
34
- offset += 1
35
- end
36
-
37
- transform
38
- length -= HASH_LENGTH
39
-
40
- break if length <= 0
41
- end
42
- end
43
-
44
- def squeeze(trits, offset, length)
45
- loop do
46
- i = 0
47
- limit = length < HASH_LENGTH ? length : HASH_LENGTH
48
- while i < limit
49
- trits[offset] = @state[i]
50
- i += 1
51
- offset += 1
52
- end
53
-
54
- transform
55
- length -= HASH_LENGTH
56
-
57
- break if length <= 0
58
- end
59
- end
60
-
61
- def transform
62
- stateCopy = []
63
- index = 0
64
-
65
- (0...@rounds).step(1) do |_|
66
- stateCopy = @state.slice(0, @state.length)
67
- (0...STATE_LENGTH).step(1) do |i|
68
- @state[i] = @truthTable[stateCopy[index].to_i + (stateCopy[index += (index < 365 ? 364 : -365)].to_i << 2) + 5]
69
- end
70
- end
13
+ rounds ||= NUMBER_OF_ROUNDS
14
+ super(rounds)
71
15
  end
72
16
  end
73
17
  end
@@ -0,0 +1,15 @@
1
+ module IOTA
2
+ module Crypto
3
+ class CCurl
4
+ NUMBER_OF_ROUNDS = 81
5
+ HASH_LENGTH = 243
6
+ STATE_LENGTH = 3 * HASH_LENGTH
7
+
8
+ def version
9
+ "C"
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ require "ccurl"
@@ -0,0 +1,70 @@
1
+ module IOTA
2
+ module Crypto
3
+ class RubyCurl
4
+ NUMBER_OF_ROUNDS = 81
5
+ HASH_LENGTH = 243
6
+ STATE_LENGTH = 3 * HASH_LENGTH
7
+ TRUTH_TABLE = [1, 0, -1, 1, -1, 0, -1, 1, 0]
8
+
9
+ def initialize(rounds = nil)
10
+ @rounds = rounds || NUMBER_OF_ROUNDS
11
+ reset
12
+ end
13
+
14
+ def reset
15
+ @state = [0] * STATE_LENGTH
16
+ end
17
+
18
+ def absorb(trits)
19
+ length = trits.length
20
+ offset = 0
21
+
22
+ while offset < length
23
+ start = offset
24
+ stop = [start + HASH_LENGTH, length].min
25
+
26
+ @state[0...stop-start] = trits.slice(start, stop-start)
27
+ transform
28
+
29
+ offset += HASH_LENGTH
30
+ end
31
+ end
32
+
33
+ def squeeze(trits)
34
+ trits[0...HASH_LENGTH] = @state.slice(0, HASH_LENGTH)
35
+ transform
36
+ end
37
+
38
+ def transform
39
+ previousState = @state.slice(0, @state.length)
40
+ newState = @state.slice(0, @state.length)
41
+
42
+ index = 0
43
+ round = 0
44
+ while round < @rounds
45
+ previousTrit = previousState[index].to_i
46
+
47
+ pos = 0
48
+ while true
49
+ index += (index < 365) ? 364 : -365
50
+ newTrit = previousState[index].to_i
51
+ newState[pos] = TRUTH_TABLE[previousTrit + (3 * newTrit) + 4]
52
+ previousTrit = newTrit
53
+ pos += 1
54
+ break if pos >= STATE_LENGTH
55
+ end
56
+
57
+ previousState = newState
58
+ newState = newState.slice(0, newState.length)
59
+ round += 1
60
+ end
61
+
62
+ @state = newState
63
+ end
64
+
65
+ def version
66
+ "Ruby"
67
+ end
68
+ end
69
+ end
70
+ end
@@ -62,23 +62,21 @@ module IOTA
62
62
  end
63
63
 
64
64
  def transactionObject(trytes)
65
- return if !trytes
65
+ return nil if !trytes
66
66
 
67
67
  # validity check
68
68
  (2279...2295).step(1) do |i|
69
- raise ArgumentError, "Invalid trytes provided" if trytes[i] != "9"
69
+ return nil if trytes[i] != "9"
70
70
  end
71
71
 
72
72
  trx = {}
73
73
  transactionTrits = IOTA::Crypto::Converter.trits(trytes)
74
74
  hash = []
75
75
 
76
- curl = IOTA::Crypto::Curl.new
77
-
78
76
  # generate the correct transaction hash
79
- curl.setup()
80
- curl.absorb(transactionTrits, 0, transactionTrits.length)
81
- curl.squeeze(hash, 0, 243)
77
+ curl = IOTA::Crypto::Curl.new
78
+ curl.absorb(transactionTrits)
79
+ curl.squeeze(hash)
82
80
 
83
81
  trx['hash'] = IOTA::Crypto::Converter.trytes(hash)
84
82
  trx['signatureMessageFragment'] = trytes.slice(0, 2187)
data/lib/iota/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module IOTA
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -0,0 +1,31 @@
1
+ require "test_helper"
2
+ if !Dir.glob(File.join(File.dirname(__FILE__), '../lib/ccurl.*')).empty?
3
+ require "iota/crypto/curl_c"
4
+
5
+ class CcurlTest < Minitest::Test
6
+ def setup
7
+ @converter = IOTA::Crypto::Converter
8
+ @curl = IOTA::Crypto::CCurl.new(81)
9
+ end
10
+
11
+ def test_that_hash_works
12
+ trytes = "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999G9AIBZPUUIXPRDTUJNGAUSWPJMLJOCSJSPVGP9KDCABPQIWXYOAXJVMDYSCPAAIJNWOHUIUNKKOVJJASCHJYTXA999999999999999999999FOINFALCON99999999999999999RJFYLXD99999999999D99999999WCKBQGFJRFIYVJAZDYLNQZIUQGG9EKZKNUOBEEASPPJXUGCTAGHGWLQSWJKC9DRVEKKHDOUJLNEQCGYK9HKFPGUUIXFOZBXZIJAFPWBYUTIAZMYHGAC9QMRDJCGOW9VXVLVQKTKRLQFITNLDHPDXHDWIVRZQGZ9999OEMEOVATRLZWXXDXIX9AVNDCHRLC9WHB9IAUUYKHUGIFBKCCYN9LRGTTQISBQYPDHTXRTOYVZTLU99999COINFALCON99999999999999999Z9PSAGQJE999999999L99999999IQXMVTRNAQVADDX9ET9IAMVJDZV"
13
+ expected_hash = "QLMNETEZDOYSBQLRPRJIZNRRDZ9EKY9LCOLNIDQEZNUFWOVYR9SJLBCVIJWIOKGNPMPGWYTNFMOW99999"
14
+
15
+ transactionTrits = @converter.trits(trytes)
16
+ hash = []
17
+
18
+ start = Time.now
19
+ # generate the correct transaction hash
20
+ @curl.reset
21
+ @curl.absorb(transactionTrits)
22
+ @curl.squeeze(hash)
23
+ hash = @converter.trytes(hash)
24
+ puts "C Curl time: #{(Time.now - start) * 1000.0}ms"
25
+
26
+ assert expected_hash == hash
27
+ end
28
+ end
29
+ else
30
+ puts "C extension is not available. Skipping tests for it."
31
+ end
@@ -0,0 +1,27 @@
1
+ require "test_helper"
2
+ require "iota/crypto/curl_ruby"
3
+
4
+ class RubyCurlTest < Minitest::Test
5
+ def setup
6
+ @converter = IOTA::Crypto::Converter
7
+ @curl = IOTA::Crypto::RubyCurl.new
8
+ end
9
+
10
+ def test_that_hash_works
11
+ trytes = "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999G9AIBZPUUIXPRDTUJNGAUSWPJMLJOCSJSPVGP9KDCABPQIWXYOAXJVMDYSCPAAIJNWOHUIUNKKOVJJASCHJYTXA999999999999999999999FOINFALCON99999999999999999RJFYLXD99999999999D99999999WCKBQGFJRFIYVJAZDYLNQZIUQGG9EKZKNUOBEEASPPJXUGCTAGHGWLQSWJKC9DRVEKKHDOUJLNEQCGYK9HKFPGUUIXFOZBXZIJAFPWBYUTIAZMYHGAC9QMRDJCGOW9VXVLVQKTKRLQFITNLDHPDXHDWIVRZQGZ9999OEMEOVATRLZWXXDXIX9AVNDCHRLC9WHB9IAUUYKHUGIFBKCCYN9LRGTTQISBQYPDHTXRTOYVZTLU99999COINFALCON99999999999999999Z9PSAGQJE999999999L99999999IQXMVTRNAQVADDX9ET9IAMVJDZV"
12
+ expected_hash = "QLMNETEZDOYSBQLRPRJIZNRRDZ9EKY9LCOLNIDQEZNUFWOVYR9SJLBCVIJWIOKGNPMPGWYTNFMOW99999"
13
+
14
+ transactionTrits = @converter.trits(trytes)
15
+ hash = []
16
+
17
+ start = Time.now
18
+ # generate the correct transaction hash
19
+ @curl.reset
20
+ @curl.absorb(transactionTrits)
21
+ @curl.squeeze(hash)
22
+ hash = @converter.trytes(hash)
23
+ puts "Ruby Curl time: #{(Time.now - start) * 1000.0}ms"
24
+
25
+ assert expected_hash == hash
26
+ end
27
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iota-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vivek Marakana
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-03 00:00:00.000000000 Z
11
+ date: 2017-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake-compiler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.0.4
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.0.4
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: digest-sha3
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -71,7 +85,8 @@ email:
71
85
  - vivek.marakana@gmail.com
72
86
  executables:
73
87
  - iota-console
74
- extensions: []
88
+ extensions:
89
+ - ext/ccurl/extconf.rb
75
90
  extra_rdoc_files: []
76
91
  files:
77
92
  - ".editorconfig"
@@ -83,6 +98,8 @@ files:
83
98
  - Rakefile
84
99
  - bin/iota-console
85
100
  - examples/multisig.rb
101
+ - ext/ccurl/ccurl.c
102
+ - ext/ccurl/extconf.rb
86
103
  - iota-ruby.gemspec
87
104
  - lib/iota.rb
88
105
  - lib/iota/api/api.rb
@@ -91,6 +108,8 @@ files:
91
108
  - lib/iota/crypto/bundle.rb
92
109
  - lib/iota/crypto/converter.rb
93
110
  - lib/iota/crypto/curl.rb
111
+ - lib/iota/crypto/curl_c.rb
112
+ - lib/iota/crypto/curl_ruby.rb
94
113
  - lib/iota/crypto/hmac.rb
95
114
  - lib/iota/crypto/kerl.rb
96
115
  - lib/iota/crypto/private_key.rb
@@ -111,6 +130,8 @@ files:
111
130
  - lib/iota/utils/utils.rb
112
131
  - lib/iota/version.rb
113
132
  - test/ascii_test.rb
133
+ - test/curl_c_test.rb
134
+ - test/curl_ruby_test.rb
114
135
  - test/kerl_test.rb
115
136
  - test/test_helper.rb
116
137
  - test/utils_test.rb
@@ -133,12 +154,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
154
  version: '0'
134
155
  requirements: []
135
156
  rubyforge_project:
136
- rubygems_version: 2.6.12
157
+ rubygems_version: 2.6.14
137
158
  signing_key:
138
159
  specification_version: 4
139
160
  summary: IOTA API wrapper for Ruby
140
161
  test_files:
141
162
  - test/ascii_test.rb
163
+ - test/curl_c_test.rb
164
+ - test/curl_ruby_test.rb
142
165
  - test/kerl_test.rb
143
166
  - test/test_helper.rb
144
167
  - test/utils_test.rb