iota-ruby 1.1.7 → 1.1.8

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
- SHA1:
3
- metadata.gz: 1e5423f9645a1fceef2e926f77101b6d28a2e837
4
- data.tar.gz: 55d897d2dec4177927a57e90f7e5570c79d95604
2
+ SHA256:
3
+ metadata.gz: 0eddb950ffbc3bf0e3da4e220391718183273cb590bd721edc759fb76b0fd7bf
4
+ data.tar.gz: 53e845e6eacd344ae3237b2547320565cd8323b6fee7d0aa872668f1cb47c507
5
5
  SHA512:
6
- metadata.gz: 16ccbc15b79c844294c81ab21146e6fb848dd1db5d2e3e6b8b56b8096f3aed43d117a607f046b3b7ddd4fcb2e7770284662df7246ea5649c94498f03ceb5e3d9
7
- data.tar.gz: 077a3b55befc66196a5bfa9e2ceab5074d5d42afd856a245a90c4c15d701b7b4f6446973e604c53c748acc1263d549dca8f48df232c826a0b1c42b681c6ba2f1
6
+ metadata.gz: b6873ed591a86864e6ff9ed57179d34bf2f0046dd059eb6849478ffd5ed1209dbc61920c466fae17e0b896a2507b47073ae28ee4b98557d7cd4575db279fdcf4
7
+ data.tar.gz: d13783668a13b9bbf76df9afee95a7a0ef04a081bfaffaaacb4f03b76f3a805f8798727cc0e454dd8b724ebeac64e05171d4d9f92dfaffbedde88005322dac16
data/.travis.yml CHANGED
@@ -1,5 +1,7 @@
1
1
  sudo: false
2
2
  language: ruby
3
+ dist: trusty
4
+ osx_image: xcode9.3
3
5
  os:
4
6
  - linux
5
7
  - osx
@@ -7,4 +9,16 @@ rvm:
7
9
  - ruby-head
8
10
  - 2.5.1
9
11
  - 2.4.1
12
+ - jruby-head
13
+ - jruby-18mode
14
+ - jruby-19mode
15
+ - rbx-3
16
+ matrix:
17
+ exclude:
18
+ - os: osx
19
+ rvm: rbx-3
20
+ - os: osx
21
+ rvm: ruby-head
22
+ - os: osx
23
+ rvm: jruby-head
10
24
  before_install: gem install bundler -v 1.15.0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [1.1.8] - 2019-07-15
2
+ - minor fixes in IOTA::Crypto::Converter.trytes
3
+ - Fixing some stuff in c extenstion to make it compatible with MRI ruby and Rubinius
4
+ - adding support for Rubinius
5
+ - adding support for JRuby platforms with native curl function in Java
6
+
1
7
  ## [1.1.7] - 2018-12-02
2
8
  - adding `user` & `password` options to client
3
9
  - [Local PoW Support](https://github.com/vivekmarakana/iota.lib.rb#local-pow-support)
@@ -8,5 +14,5 @@
8
14
  - Inbuilt batching for following apis: `getTrytes`, `getBalances`, `wereAddressesSpentFrom`, `getInclusionStates` & `findTransactions`
9
15
  - adding changelog file to keep track of future changes
10
16
 
11
- ### Changed
12
- - Only returning balance array as reponse for `getBalances` api call (Major)
17
+ ### Old major changes
18
+ - Only returning balance array as reponse for `getBalances` api call
data/README.md CHANGED
@@ -107,3 +107,15 @@ client = IOTA::Client.new(provider: 'https://node.iota-tangle.io:14265')
107
107
  client = IOTA::Client.new(provider: 'https://node.iota-tangle.io:14265', local_pow: true)
108
108
  # Now you can use `client.api.attachToTangle` api, which will do the proof-of-work on transaction and return the trytes that needs to be broadcasted
109
109
  ```
110
+
111
+ ## Compatibility
112
+
113
+ Tested on [Travis CI](https://travis-ci.org/vivekmarakana/iota.lib.rb) on following environment [configurations](https://github.com/vivekmarakana/iota.lib.rb/blob/master/.travis.yml):
114
+
115
+ - ruby-head (Linux)
116
+ - 2.5.1 (Linux & Mac)
117
+ - 2.4.1 (Linux & Mac)
118
+ - jruby-head (OpenJDK8/Linux)
119
+ - jruby-19mode (OpenJDK8/Linux & OpenJDK8/OSX)
120
+ - jruby-18mode (OpenJDK8/Linux & OpenJDK8/OSX)
121
+ - rbx-3 (Linux)
data/Rakefile CHANGED
@@ -1,6 +1,5 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
- require "rake/extensiontask"
4
3
 
5
4
  Rake::TestTask.new(:test) do |t|
6
5
  t.libs << "test"
@@ -8,17 +7,30 @@ Rake::TestTask.new(:test) do |t|
8
7
  t.test_files = FileList["test/**/*_test.rb"]
9
8
  end
10
9
 
11
- Rake::ExtensionTask.new "ccurl" do |ext|
12
- ext.lib_dir = "lib"
13
- end
10
+ tasks = []
14
11
 
15
- def can_compile_extensions
16
- return false if RUBY_DESCRIPTION =~ /jruby/
17
- return true
18
- end
12
+ if RUBY_PLATFORM =~ /java/
13
+ if ENV['TRAVIS'].to_s.empty?
14
+ puts "Will build JAVA extension"
15
+
16
+ require 'rake/javaextensiontask'
17
+ Rake::JavaExtensionTask.new "jcurl" do |ext|
18
+ ext.lib_dir = "lib"
19
+ end
19
20
 
20
- if can_compile_extensions
21
- task :default => [:compile, :test]
21
+ tasks << :compile
22
+ else
23
+ puts "Not building jar for travis"
24
+ end
22
25
  else
23
- task :default => [:test]
26
+ puts "Will build C extension"
27
+
28
+ require 'rake/extensiontask'
29
+ Rake::ExtensionTask.new "ccurl" do |ext|
30
+ ext.lib_dir = "lib"
31
+ end
32
+
33
+ tasks << :compile
24
34
  end
35
+
36
+ task :default => tasks + [:test]
data/ext/ccurl/ccurl.c CHANGED
@@ -5,6 +5,10 @@
5
5
  #define NUMBER_OF_ROUNDS 81
6
6
  #define STATE_LENGTH 3 * HASH_LENGTH
7
7
 
8
+ #ifndef RARRAY_LEN
9
+ # define RARRAY_LEN(x) return (long)NUM2INT(rb_funcall(x, rb_intern("length"), 0));
10
+ #endif
11
+
8
12
  typedef int64_t trit_t;
9
13
 
10
14
  #define __TRUTH_TABLE 1, 0, -1, 1, -1, 0, -1, 1, 0
@@ -43,7 +47,7 @@ static VALUE ccurl_absorb(VALUE self, VALUE data) {
43
47
  trit_t *trits;
44
48
  int offset = 0;
45
49
  int i;
46
- int length = NUM2INT(rb_funcall(data, rb_intern("length"), 0, 0));
50
+ int length = (int)RARRAY_LEN(data);
47
51
 
48
52
  Curl *ctx;
49
53
  Data_Get_Struct(self, Curl, ctx);
@@ -66,21 +70,25 @@ static VALUE ccurl_absorb(VALUE self, VALUE data) {
66
70
  }
67
71
 
68
72
  static VALUE ccurl_squeeze(VALUE self, VALUE data) {
69
- int length = NUM2INT(rb_funcall(data, rb_intern("length"), 0, 0));
73
+ int offset = 0;
70
74
  int i;
75
+ int length = (int)RARRAY_LEN(data);
71
76
 
72
77
  Curl *ctx;
73
78
  Data_Get_Struct(self, Curl, ctx);
74
79
 
75
- for(; length < HASH_LENGTH; length++) {
76
- rb_ary_push(data, LONG2NUM(0));
77
- }
80
+ do {
81
+ for(; length < HASH_LENGTH; length++) {
82
+ rb_ary_push(data, LONG2NUM(0));
83
+ }
78
84
 
79
- for (i = 0; i < HASH_LENGTH; i++) {
80
- rb_ary_store(data, i, LONG2NUM(ctx->state[i]));
81
- }
85
+ for (i = 0; i < HASH_LENGTH; i++) {
86
+ rb_ary_store(data, i, LONG2NUM(ctx->state[i]));
87
+ }
82
88
 
83
- ccurl_transform(self);
89
+ ccurl_transform(self);
90
+ offset += HASH_LENGTH;
91
+ } while ((length -= HASH_LENGTH) > 0);
84
92
 
85
93
  return Qnil;
86
94
  }
@@ -0,0 +1,126 @@
1
+ package com.vmarakana;
2
+
3
+ import java.util.Arrays;
4
+
5
+ import org.jruby.Ruby;
6
+ import org.jruby.RubyArray;
7
+ import org.jruby.RubyClass;
8
+ import org.jruby.RubyInteger;
9
+ import org.jruby.RubyNil;
10
+ import org.jruby.RubyObject;
11
+ import org.jruby.anno.JRubyMethod;
12
+ import org.jruby.runtime.ThreadContext;
13
+ import org.jruby.runtime.builtin.IRubyObject;
14
+
15
+ public class JCurl extends RubyObject {
16
+ /**
17
+ * The hash length.
18
+ */
19
+ public static final int HASH_LENGTH = 243;
20
+ private static final int STATE_LENGTH = 3 * HASH_LENGTH;
21
+
22
+ public static final int NUMBER_OF_ROUNDS = 81;
23
+ private int numberOfRounds;
24
+
25
+ private static final int[] TRUTH_TABLE = {1, 0, -1, 2, 1, -1, 0, 2, -1, 1, 0};
26
+ private final int[] scratchpad = new int[STATE_LENGTH];
27
+ private int[] state;
28
+
29
+ /**
30
+ * Java constructor
31
+ * @param ruby Ruby
32
+ * @param metaclass RubyClass
33
+ */
34
+ public JCurl(Ruby ruby, RubyClass rubyClass) {
35
+ super(ruby, rubyClass);
36
+ }
37
+
38
+ /**
39
+ *
40
+ * @param context ThreadContext
41
+ * @param klass IRubyObject
42
+ * @param args optional (no args rounds = NUMBER_OF_ROUNDS)
43
+ * @return new Vec3 object (ruby)
44
+ */
45
+ @JRubyMethod(name = "new", meta = true, rest = true)
46
+ public static IRubyObject rbNew(ThreadContext context, IRubyObject klass, IRubyObject... args) {
47
+ JCurl jcurl = (JCurl) ((RubyClass) klass).allocate();
48
+ jcurl.init(context, args);
49
+ return jcurl;
50
+ }
51
+
52
+ // This method is internal and not exposed
53
+ private IRubyObject init(ThreadContext context, IRubyObject... args) {
54
+ state = new int[STATE_LENGTH];
55
+
56
+ // Set rounds
57
+ if (args.length > 0 && args[0] instanceof RubyInteger) {
58
+ numberOfRounds = ((RubyInteger) args[0]).getIntValue();
59
+ } else {
60
+ numberOfRounds = NUMBER_OF_ROUNDS;
61
+ }
62
+
63
+ return new RubyNil(context.runtime);
64
+ }
65
+
66
+ @JRubyMethod
67
+ public IRubyObject transform(ThreadContext context) {
68
+ int scratchpadIndex = 0;
69
+ int prev_scratchpadIndex = 0;
70
+ for (int round = 0; round < numberOfRounds; round++) {
71
+ System.arraycopy(state, 0, scratchpad, 0, STATE_LENGTH);
72
+ for (int stateIndex = 0; stateIndex < STATE_LENGTH; stateIndex++) {
73
+ prev_scratchpadIndex = scratchpadIndex;
74
+ if (scratchpadIndex < 365) {
75
+ scratchpadIndex += 364;
76
+ } else {
77
+ scratchpadIndex += -365;
78
+ }
79
+ state[stateIndex] = TRUTH_TABLE[scratchpad[prev_scratchpadIndex] + (scratchpad[scratchpadIndex] << 2) + 5];
80
+ }
81
+ }
82
+
83
+ return new RubyNil(context.runtime);
84
+ }
85
+
86
+ @JRubyMethod
87
+ public IRubyObject absorb(ThreadContext context, final IRubyObject trits) {
88
+ int offset = 0;
89
+ int length = ((RubyArray) trits).getLength();
90
+
91
+ do {
92
+ System.arraycopy(trits.toJava(int[].class), offset, state, 0, length < HASH_LENGTH ? length : HASH_LENGTH);
93
+ transform(context);
94
+ offset += HASH_LENGTH;
95
+ } while ((length -= HASH_LENGTH) > 0);
96
+
97
+ return new RubyNil(context.runtime);
98
+ }
99
+
100
+ @JRubyMethod
101
+ public RubyNil squeeze(ThreadContext context, final IRubyObject trits) {
102
+ int offset = 0;
103
+ int length = ((RubyArray) trits).getLength();
104
+
105
+ do {
106
+ for(; length < HASH_LENGTH; length++) {
107
+ ((RubyArray) trits).append(context.runtime.newFixnum(0));
108
+ }
109
+
110
+ for (int i = 0; i < HASH_LENGTH; i++) {
111
+ ((RubyArray) trits).store(i, context.runtime.newFixnum(state[i]));
112
+ }
113
+
114
+ transform(context);
115
+ offset += HASH_LENGTH;
116
+ } while ((length -= HASH_LENGTH) > 0);
117
+
118
+ return new RubyNil(context.runtime);
119
+ }
120
+
121
+ @JRubyMethod
122
+ public IRubyObject reset(ThreadContext context) {
123
+ Arrays.fill(state, 0);
124
+ return new RubyNil(context.runtime);
125
+ }
126
+ }
@@ -0,0 +1,36 @@
1
+ package com.vmarakana;
2
+
3
+ import java.io.IOException;
4
+
5
+ import org.jruby.Ruby;
6
+ import org.jruby.RubyClass;
7
+ import org.jruby.RubyModule;
8
+ import org.jruby.runtime.ObjectAllocator;
9
+ import org.jruby.runtime.builtin.IRubyObject;
10
+ import org.jruby.runtime.load.BasicLibraryService;
11
+
12
+ public class JCurlService implements BasicLibraryService {
13
+ private Ruby runtime;
14
+
15
+ /**
16
+ * Basic load method of the BasicLibraryService, this method is
17
+ * invoked when the ruby code does the related require call.
18
+ * @param ruby An instance of the JRuby runtime.
19
+ * @return boolean True if everything was successful, false otherwise.
20
+ * @throws IOException is required to match the BasicLibraryService signature
21
+ */
22
+
23
+ @Override
24
+ public boolean basicLoad(final Ruby ruby) throws IOException {
25
+ RubyModule iota = ruby.defineModule("IOTA");
26
+ RubyModule crypto = iota.defineModuleUnder("Crypto");
27
+ RubyClass jcurl = crypto.defineClassUnder("JCurl", ruby.getObject(), new ObjectAllocator() {
28
+ public IRubyObject allocate(Ruby ruby1, RubyClass rubyClass) {
29
+ return new JCurl(ruby1, rubyClass);
30
+ }
31
+ });
32
+
33
+ jcurl.defineAnnotatedMethods(JCurl.class);
34
+ return true;
35
+ }
36
+ }
data/iota-ruby.gemspec CHANGED
@@ -13,17 +13,25 @@ Gem::Specification.new do |spec|
13
13
  spec.description = "Ruby gem for the IOTA core"
14
14
  spec.homepage = "https://github.com/vivekmarakana/iota.lib.rb"
15
15
 
16
- spec.files = `git ls-files`.split("\n")
16
+ spec.files = `git ls-files`.split("\n") - [ "lib/jcurl.jar"]
17
17
  spec.test_files = `git ls-files -- test/*`.split("\n")
18
- spec.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
19
18
  spec.require_paths = ["lib"]
20
- spec.extensions = ["ext/ccurl/extconf.rb"]
21
19
 
22
- spec.required_ruby_version = '>= 2.4.0'
23
- spec.add_development_dependency "bundler", "~> 1.15"
24
- spec.add_development_dependency "rake", "~> 10.0"
25
- spec.add_development_dependency "minitest", "~> 5.0"
26
- spec.add_development_dependency "rake-compiler", "~> 1.0.4"
27
- spec.add_dependency "digest-sha3", "~> 1.1"
28
- spec.add_dependency "ffi", "~> 1.9.25"
20
+ if RUBY_PLATFORM =~ /java/
21
+ spec.platform = "java"
22
+ spec.files << "lib/jcurl.jar"
23
+ else
24
+ spec.extensions = ["ext/ccurl/extconf.rb"]
25
+ end
26
+
27
+ spec.add_development_dependency "bundler", ">= 1.15"
28
+ spec.add_development_dependency "rake", ">= 10.0"
29
+ spec.add_development_dependency "minitest", ">= 5.0"
30
+ spec.add_development_dependency "rake-compiler", ">= 1.0.4"
31
+
32
+ unless RUBY_PLATFORM =~ /java/
33
+ spec.add_runtime_dependency "digest-sha3", "~> 1.1"
34
+ end
35
+
36
+ spec.add_runtime_dependency "ffi", "~> 1.9.25"
29
37
  end
data/lib/iota.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require "patch"
1
2
  require "iota/version"
2
3
 
3
4
  require "iota/utils/input_validator"
@@ -40,8 +41,6 @@ module IOTA
40
41
  @utils = IOTA::Utils::Utils.new
41
42
  @validator = @utils.validator
42
43
  @multisig = IOTA::Multisig::Multisig.new(self)
43
- # TODO: Implement MAM
44
- # TODO: Implement Flash Channel
45
44
  end
46
45
 
47
46
  def changeNode(settings = {})
@@ -81,7 +81,10 @@ module IOTA
81
81
 
82
82
  (0...trits.length).step(3) do |i|
83
83
  chunk = trits[i...i+3]
84
- trytes += TRYTES_ALPHABET[TRYTE_TRITS.index(chunk)]
84
+ index = TRYTE_TRITS.index(chunk)
85
+ if !index.nil?
86
+ trytes += TRYTES_ALPHABET[index]
87
+ end
85
88
  end
86
89
 
87
90
  trytes
@@ -1,9 +1,9 @@
1
- if !Dir.glob(File.join(File.dirname(__FILE__), '../../ccurl.*')).empty?
1
+ if RUBY_PLATFORM =~ /java/
2
+ require "iota/crypto/curl_java"
3
+ BaseCurl = IOTA::Crypto::JCurl
4
+ else
2
5
  require "iota/crypto/curl_c"
3
6
  BaseCurl = IOTA::Crypto::CCurl
4
- else
5
- require "iota/crypto/curl_ruby"
6
- BaseCurl = IOTA::Crypto::RubyCurl
7
7
  end
8
8
 
9
9
  module IOTA
@@ -5,11 +5,13 @@ module IOTA
5
5
  HASH_LENGTH = 243
6
6
  STATE_LENGTH = 3 * HASH_LENGTH
7
7
 
8
+ unless RUBY_PLATFORM =~ /java/
9
+ require "ccurl"
10
+ end
11
+
8
12
  def version
9
13
  "C"
10
14
  end
11
15
  end
12
16
  end
13
17
  end
14
-
15
- require "ccurl"
@@ -0,0 +1,18 @@
1
+ module IOTA
2
+ module Crypto
3
+ class JCurl
4
+ NUMBER_OF_ROUNDS = 81
5
+ HASH_LENGTH = 243
6
+ STATE_LENGTH = 3 * HASH_LENGTH
7
+
8
+ if RUBY_PLATFORM =~ /java/
9
+ require 'jcurl'
10
+ com.vmarakana.JCurlService.new.basicLoad(JRuby.runtime)
11
+ end
12
+
13
+ def version
14
+ "Java"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,5 +1,3 @@
1
- require 'digest/sha3'
2
-
3
1
  module IOTA
4
2
  module Crypto
5
3
  class Kerl
@@ -11,7 +9,13 @@ module IOTA
11
9
  end
12
10
 
13
11
  def reset
14
- @hasher = Digest::SHA3.new(BIT_HASH_LENGTH)
12
+ unless RUBY_PLATFORM =~ /java/
13
+ require 'digest/sha3'
14
+ @hasher = Digest::SHA3.new(BIT_HASH_LENGTH)
15
+ else
16
+ require "iota/crypto/sha3_ruby"
17
+ @hasher = Digest::RubySHA3.new(BIT_HASH_LENGTH)
18
+ end
15
19
  end
16
20
 
17
21
  def absorb(trits, offset = 0, length = nil)
@@ -0,0 +1,122 @@
1
+ require 'digest'
2
+
3
+ module Digest
4
+ class RubySHA3 < Digest::Class
5
+ PILN = [10, 7, 11, 17, 18, 3, 5, 16,
6
+ 8, 21, 24, 4, 15, 23, 19, 13,
7
+ 12, 2, 20, 14, 22, 9, 6, 1]
8
+
9
+ ROTC = [ 1, 3, 6, 10, 15, 21, 28, 36,
10
+ 45, 55, 2, 14, 27, 41, 56, 8,
11
+ 25, 43, 62, 18, 39, 61, 20, 44]
12
+
13
+ RNDC = [0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
14
+ 0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
15
+ 0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
16
+ 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
17
+ 0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
18
+ 0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
19
+ 0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
20
+ 0x8000000000008080, 0x0000000080000001, 0x8000000080008008]
21
+
22
+ def initialize hash_size = 512
23
+ @size = hash_size / 8
24
+ @buffer = ''
25
+ end
26
+
27
+ def << s
28
+ @buffer << s.unpack('C*').pack('C*')
29
+ self
30
+ end
31
+ alias update <<
32
+
33
+ def reset
34
+ # @buffer.clear # CHANGE: DO NOT CLEAR BUFFER AS WE NEED
35
+ self
36
+ end
37
+
38
+ def digest(data = nil)
39
+ if data
40
+ update(data)
41
+ value = finish
42
+ else
43
+ cloned = dup
44
+ value = cloned.finish
45
+ end
46
+ value
47
+ end
48
+
49
+ def hexdigest(data = nil)
50
+ value = digest(data)
51
+ value.unpack("H*").first
52
+ end
53
+
54
+ def inspect
55
+ "#<#{self.class}: #{hexdigest}>"
56
+ end
57
+
58
+ def finish
59
+ s = Array.new 25, 0
60
+ width = 200 - @size * 2
61
+
62
+ buffer_dup = @buffer.dup
63
+ buffer_dup << "\x01" << "\0" * (width - buffer_dup.size % width)
64
+ buffer_dup[-1] = (buffer_dup[-1].ord | 0x80).chr.unpack('C*').pack('C*')
65
+
66
+ 0.step buffer_dup.size - 1, width do |j|
67
+ quads = buffer_dup[j, width].unpack 'Q*'
68
+ (width / 8).times do |i|
69
+ s[i] ^= quads[i]
70
+ end
71
+
72
+ keccak s
73
+ end
74
+
75
+ s.pack('Q*')[0, @size]
76
+ end
77
+
78
+ private
79
+ def keccak s
80
+ 24.times.each_with_object [] do |round, a|
81
+ # Theta
82
+ 5.times do |i|
83
+ a[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20]
84
+ end
85
+
86
+ 5.times do |i|
87
+ t = a[(i + 4) % 5] ^ rotate(a[(i + 1) % 5], 1)
88
+ 0.step 24, 5 do |j|
89
+ s[j + i] ^= t
90
+ end
91
+ end
92
+
93
+ # Rho Pi
94
+ t = s[1]
95
+ 24.times do |i|
96
+ j = PILN[i]
97
+ a[0] = s[j]
98
+ s[j] = rotate t, ROTC[i]
99
+ t = a[0]
100
+ end
101
+
102
+ # Chi
103
+ 0.step 24, 5 do |j|
104
+ 5.times do |i|
105
+ a[i] = s[j + i]
106
+ end
107
+
108
+ 5.times do |i|
109
+ s[j + i] ^= ~a[(i + 1) % 5] & a[(i + 2) % 5]
110
+ end
111
+ end
112
+
113
+ # Iota
114
+ s[0] ^= RNDC[round]
115
+ end
116
+ end
117
+
118
+ def rotate x, y
119
+ (x << y | x >> 64 - y) & (1 << 64) - 1
120
+ end
121
+ end
122
+ end
@@ -57,7 +57,7 @@ module IOTA
57
57
  # validate remainder address
58
58
  raise StandardError, "Invalid remainder address provided" if remainderAddress && !@validator.isAddress(remainderAddress)
59
59
 
60
- remainderAddress = @utils.noChecksum(remainderAddress) if remainderAddress.length == 90
60
+ remainderAddress = @utils.noChecksum(remainderAddress) if remainderAddress && remainderAddress.length == 90
61
61
 
62
62
  # Create a new bundle
63
63
  bundle = IOTA::Crypto::Bundle.new
data/lib/iota/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module IOTA
2
- VERSION = "1.1.7"
2
+ VERSION = "1.1.8"
3
3
  end
data/lib/patch.rb ADDED
@@ -0,0 +1,17 @@
1
+ # Patching Array#sum method for older rubies, jruby and rubinbius
2
+ if !Array.instance_methods.include?(:sum)
3
+ class Array
4
+ def sum
5
+ inject(0) {|sum, val| sum + val}
6
+ end
7
+ end
8
+ end
9
+
10
+ # Patching Regexp#match? method for older rubies, jruby and rubinbius
11
+ if !Regexp.instance_methods.include?(:match?)
12
+ class Regexp
13
+ def match?(a)
14
+ !match(a).nil?
15
+ end
16
+ end
17
+ end
data/test/curl_c_test.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  require "test_helper"
2
- if !Dir.glob(File.join(File.dirname(__FILE__), '../lib/ccurl.*')).empty?
2
+ unless RUBY_PLATFORM =~ /java/
3
3
  require "iota/crypto/curl_c"
4
4
 
5
- class CcurlTest < Minitest::Test
5
+ class CCurlTest < Minitest::Test
6
6
  def setup
7
7
  @converter = IOTA::Crypto::Converter
8
8
  @curl = IOTA::Crypto::CCurl.new(81)
@@ -0,0 +1,31 @@
1
+ require "test_helper"
2
+ if RUBY_PLATFORM =~ /java/
3
+ require "iota/crypto/curl_java"
4
+
5
+ class JavaCurlTest < Minitest::Test
6
+ def setup
7
+ @converter = IOTA::Crypto::Converter
8
+ @curl = IOTA::Crypto::JCurl.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 "Java Curl time: #{(Time.now - start) * 1000.0}ms"
25
+
26
+ assert expected_hash == hash
27
+ end
28
+ end
29
+ else
30
+ puts "Java extension is not available. Skipping tests for it."
31
+ end
data/test/kerl_test.rb CHANGED
@@ -6,18 +6,6 @@ class KerlTest < Minitest::Test
6
6
  @kerl = IOTA::Crypto::Kerl.new
7
7
  end
8
8
 
9
- def test_that_sha3_works
10
- digest = "\xe0\xef\x02\xd2FD\xa7\xb2\x8b<\x1b\x01\xc4\xfe\x13zI\x86M[\xdefV\xfa\xf49\xe1\xeb\xa6X\x06M\x9e\xcf\x842U\xba\x90=\x1c\xeb\xdcf\xff/\x16\xce".unpack('C*')
11
- hexdigest = "e0ef02d24644a7b28b3c1b01c4fe137a49864d5bde6656faf439e1eba658064d9ecf843255ba903d1cebdc66ff2f16ce"
12
-
13
- a = Digest::SHA3.new(384)
14
- a.update("GYOMKVTSNHVJNCNFBBAH9AAMXLPLLLROQY99QN9DLSJUHDPBLCFFAIQXZA9BKMBJCYSFHFPXAHDWZFEIZ")
15
-
16
- assert a.digest_length == 48
17
- assert a.digest.bytes == digest
18
- assert a.hexdigest == hexdigest
19
- end
20
-
21
9
  def test_that_absorb_squeeze_works
22
10
  input = "GYOMKVTSNHVJNCNFBBAH9AAMXLPLLLROQY99QN9DLSJUHDPBLCFFAIQXZA9BKMBJCYSFHFPXAHDWZFEIZ"
23
11
  expected = "OXJCNFHUNAHWDLKKPELTBFUCVW9KLXKOGWERKTJXQMXTKFKNWNNXYD9DMJJABSEIONOSJTTEVKVDQEWTW"
data/test/sha3_test.rb ADDED
@@ -0,0 +1,71 @@
1
+ require "test_helper"
2
+
3
+ require "iota/crypto/sha3_ruby"
4
+
5
+ class Sha3Test < Minitest::Test
6
+ def setup
7
+ @ruby_sha3_class = Digest::RubySHA3
8
+ unless RUBY_PLATFORM =~ /java/
9
+ require 'digest/sha3'
10
+ @c_sha3_class = Digest::SHA3
11
+ else
12
+ @c_sha3_class = nil
13
+ end
14
+
15
+ @str = "GYOMKVTSNHVJNCNFBBAH9AAMXLPLLLROQY99QN9DLSJUHDPBLCFFAIQXZA9BKMBJCYSFHFPXAHDWZFEIZ"
16
+ @result = "e0ef02d24644a7b28b3c1b01c4fe137a49864d5bde6656faf439e1eba658064d9ecf843255ba903d1cebdc66ff2f16ce"
17
+ end
18
+
19
+ def test_that_c_sha3_update_works
20
+ if @c_sha3_class
21
+ start = Time.now
22
+ a = @c_sha3_class.new(IOTA::Crypto::Kerl::BIT_HASH_LENGTH)
23
+ a.update(@str)
24
+ puts "C SHA3 Update time: #{(Time.now - start) * 1000.0}ms"
25
+
26
+ assert a.digest_length == 48
27
+ assert a.hexdigest == @result
28
+ end
29
+ end
30
+
31
+ def test_that_c_sha3_digest_works
32
+ if @c_sha3_class
33
+ start = Time.now
34
+ a = @c_sha3_class.new(IOTA::Crypto::Kerl::BIT_HASH_LENGTH)
35
+ assert a.hexdigest(@str) == @result
36
+ puts "C SHA3 Digest time: #{(Time.now - start) * 1000.0}ms"
37
+ end
38
+ end
39
+
40
+ def test_that_ruby_sha3_update_works
41
+ if @ruby_sha3_class
42
+ start = Time.now
43
+ a = @ruby_sha3_class.new(IOTA::Crypto::Kerl::BIT_HASH_LENGTH)
44
+ a.update(@str)
45
+ puts "Ruby SHA3 Update time: #{(Time.now - start) * 1000.0}ms"
46
+ assert a.digest_length == 48
47
+ assert a.hexdigest == @result
48
+ end
49
+ end
50
+
51
+ def test_that_ruby_sha3_digest_works
52
+ if @ruby_sha3_class
53
+ start = Time.now
54
+ a = @ruby_sha3_class.new(IOTA::Crypto::Kerl::BIT_HASH_LENGTH)
55
+ assert a.hexdigest(@str) == @result
56
+ puts "Ruby SHA3 Digest time: #{(Time.now - start) * 1000.0}ms"
57
+ end
58
+ end
59
+
60
+ def test_that_c_sha3_and_ruby_sha3_give_same_results
61
+ if @ruby_sha3_class && @c_sha3_class
62
+ a = @ruby_sha3_class.new(IOTA::Crypto::Kerl::BIT_HASH_LENGTH)
63
+ b = @c_sha3_class.new(IOTA::Crypto::Kerl::BIT_HASH_LENGTH)
64
+ assert a.hexdigest(@str) == b.hexdigest(@str)
65
+
66
+ a = @ruby_sha3_class.new(IOTA::Crypto::Kerl::BIT_HASH_LENGTH)
67
+ b = @c_sha3_class.new(IOTA::Crypto::Kerl::BIT_HASH_LENGTH)
68
+ assert a.update(@str).hexdigest == b.update(@str).hexdigest
69
+ end
70
+ end
71
+ end
data/test/utils_test.rb CHANGED
@@ -5,6 +5,12 @@ class UtilsTest < Minitest::Test
5
5
  @utils = IOTA::Utils::Utils.new
6
6
  end
7
7
 
8
+ def test_add_checksum
9
+ addressWithoutChecksum = "UYEEERFQYTPFAHIPXDQAQYWYMSMCLMGBTYAXLWFRFFWPYFOICOVLK9A9VYNCKK9TQUNBTARCEQXJHD9VY"
10
+ addressWithChecksum = "UYEEERFQYTPFAHIPXDQAQYWYMSMCLMGBTYAXLWFRFFWPYFOICOVLK9A9VYNCKK9TQUNBTARCEQXJHD9VYXOEDEOMRC"
11
+ assert_equal @utils.addChecksum(addressWithoutChecksum), addressWithChecksum
12
+ end
13
+
8
14
  def test_checksum_validation
9
15
  addressWithChecksum = "UYEEERFQYTPFAHIPXDQAQYWYMSMCLMGBTYAXLWFRFFWPYFOICOVLK9A9VYNCKK9TQUNBTARCEQXJHD9VYXOEDEOMRC"
10
16
  assert_equal @utils.isValidChecksum(addressWithChecksum), true
metadata CHANGED
@@ -1,69 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iota-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.7
4
+ version: 1.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vivek Marakana
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-02 00:00:00.000000000 Z
11
+ date: 2019-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.15'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.15'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '10.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '5.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '5.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake-compiler
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: 1.0.4
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: 1.0.4
69
69
  - !ruby/object:Gem::Dependency
@@ -97,8 +97,7 @@ dependencies:
97
97
  description: Ruby gem for the IOTA core
98
98
  email:
99
99
  - vivek.marakana@gmail.com
100
- executables:
101
- - iota-console
100
+ executables: []
102
101
  extensions:
103
102
  - ext/ccurl/extconf.rb
104
103
  extra_rdoc_files: []
@@ -116,6 +115,8 @@ files:
116
115
  - examples/multisig.rb
117
116
  - ext/ccurl/ccurl.c
118
117
  - ext/ccurl/extconf.rb
118
+ - ext/jcurl/JCurl.java
119
+ - ext/jcurl/JCurlService.java
119
120
  - ext/pow/ccurl-0.3.0.dll
120
121
  - ext/pow/libccurl-0.3.0.dylib
121
122
  - ext/pow/libccurl-0.3.0.so
@@ -129,11 +130,13 @@ files:
129
130
  - lib/iota/crypto/converter.rb
130
131
  - lib/iota/crypto/curl.rb
131
132
  - lib/iota/crypto/curl_c.rb
133
+ - lib/iota/crypto/curl_java.rb
132
134
  - lib/iota/crypto/curl_ruby.rb
133
135
  - lib/iota/crypto/hmac.rb
134
136
  - lib/iota/crypto/kerl.rb
135
137
  - lib/iota/crypto/pow_provider.rb
136
138
  - lib/iota/crypto/private_key.rb
139
+ - lib/iota/crypto/sha3_ruby.rb
137
140
  - lib/iota/crypto/signing.rb
138
141
  - lib/iota/models/account.rb
139
142
  - lib/iota/models/base.rb
@@ -150,11 +153,14 @@ files:
150
153
  - lib/iota/utils/object_validator.rb
151
154
  - lib/iota/utils/utils.rb
152
155
  - lib/iota/version.rb
156
+ - lib/patch.rb
153
157
  - test/ascii_test.rb
154
158
  - test/curl_c_test.rb
159
+ - test/curl_java_test.rb
155
160
  - test/curl_ruby_test.rb
156
161
  - test/kerl_test.rb
157
162
  - test/pow_provider_test.rb
163
+ - test/sha3_test.rb
158
164
  - test/test_helper.rb
159
165
  - test/utils_test.rb
160
166
  homepage: https://github.com/vivekmarakana/iota.lib.rb
@@ -168,23 +174,24 @@ required_ruby_version: !ruby/object:Gem::Requirement
168
174
  requirements:
169
175
  - - ">="
170
176
  - !ruby/object:Gem::Version
171
- version: 2.4.0
177
+ version: '0'
172
178
  required_rubygems_version: !ruby/object:Gem::Requirement
173
179
  requirements:
174
180
  - - ">="
175
181
  - !ruby/object:Gem::Version
176
182
  version: '0'
177
183
  requirements: []
178
- rubyforge_project:
179
- rubygems_version: 2.6.14
184
+ rubygems_version: 3.0.4
180
185
  signing_key:
181
186
  specification_version: 4
182
187
  summary: IOTA API wrapper for Ruby
183
188
  test_files:
184
189
  - test/ascii_test.rb
185
190
  - test/curl_c_test.rb
191
+ - test/curl_java_test.rb
186
192
  - test/curl_ruby_test.rb
187
193
  - test/kerl_test.rb
188
194
  - test/pow_provider_test.rb
195
+ - test/sha3_test.rb
189
196
  - test/test_helper.rb
190
197
  - test/utils_test.rb