iota-ruby 1.1.8-java
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.
- checksums.yaml +7 -0
- data/.editorconfig +8 -0
- data/.gitignore +15 -0
- data/.travis.yml +24 -0
- data/.yardopts +7 -0
- data/CHANGELOG.md +18 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +121 -0
- data/Rakefile +36 -0
- data/bin/iota-console +15 -0
- data/examples/multisig.rb +69 -0
- data/ext/ccurl/ccurl.c +134 -0
- data/ext/ccurl/extconf.rb +22 -0
- data/ext/jcurl/JCurl.java +126 -0
- data/ext/jcurl/JCurlService.java +36 -0
- data/ext/pow/ccurl-0.3.0.dll +0 -0
- data/ext/pow/libccurl-0.3.0.dylib +0 -0
- data/ext/pow/libccurl-0.3.0.so +0 -0
- data/iota-ruby.gemspec +37 -0
- data/lib/iota.rb +76 -0
- data/lib/iota/api/api.rb +251 -0
- data/lib/iota/api/commands.rb +113 -0
- data/lib/iota/api/transport.rb +43 -0
- data/lib/iota/api/wrappers.rb +429 -0
- data/lib/iota/crypto/bundle.rb +163 -0
- data/lib/iota/crypto/converter.rb +244 -0
- data/lib/iota/crypto/curl.rb +18 -0
- data/lib/iota/crypto/curl_c.rb +17 -0
- data/lib/iota/crypto/curl_java.rb +18 -0
- data/lib/iota/crypto/curl_ruby.rb +70 -0
- data/lib/iota/crypto/hmac.rb +27 -0
- data/lib/iota/crypto/kerl.rb +82 -0
- data/lib/iota/crypto/pow_provider.rb +27 -0
- data/lib/iota/crypto/private_key.rb +80 -0
- data/lib/iota/crypto/sha3_ruby.rb +122 -0
- data/lib/iota/crypto/signing.rb +97 -0
- data/lib/iota/models/account.rb +489 -0
- data/lib/iota/models/base.rb +13 -0
- data/lib/iota/models/bundle.rb +87 -0
- data/lib/iota/models/input.rb +38 -0
- data/lib/iota/models/seed.rb +33 -0
- data/lib/iota/models/transaction.rb +52 -0
- data/lib/iota/models/transfer.rb +44 -0
- data/lib/iota/multisig/address.rb +41 -0
- data/lib/iota/multisig/multisig.rb +244 -0
- data/lib/iota/utils/ascii.rb +50 -0
- data/lib/iota/utils/broker.rb +124 -0
- data/lib/iota/utils/input_validator.rb +149 -0
- data/lib/iota/utils/object_validator.rb +34 -0
- data/lib/iota/utils/utils.rb +324 -0
- data/lib/iota/version.rb +3 -0
- data/lib/jcurl.jar +0 -0
- data/lib/patch.rb +17 -0
- data/test/ascii_test.rb +114 -0
- data/test/curl_c_test.rb +31 -0
- data/test/curl_java_test.rb +31 -0
- data/test/curl_ruby_test.rb +27 -0
- data/test/kerl_test.rb +52 -0
- data/test/pow_provider_test.rb +36 -0
- data/test/sha3_test.rb +71 -0
- data/test/test_helper.rb +4 -0
- data/test/utils_test.rb +179 -0
- metadata +183 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b762aee06e150e37e0998b97106204794c256078df463f5ca81a68abe77df44e
|
4
|
+
data.tar.gz: c0efd60e7d56ce9636b37d1e2e12e1ca71bd1baa9e2965d4ccce27708d28c4a0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9d62b2da39b068fbbb78d03189dcfc83af26df4da42713e6f7cb6d00ce919903b3955c9ba3a3b52c2c8aa12c345a9771d4b5dff46a802fc0dc1546624af784a2
|
7
|
+
data.tar.gz: 371522bd00bebb25c36e12aa66b141afc0e560f4cd4fe4019e3402b7f80f2e1a7547468ac692ac203ae72a337a11fa3675748911105ee3424054d582023d4d58
|
data/.editorconfig
ADDED
data/.gitignore
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
sudo: false
|
2
|
+
language: ruby
|
3
|
+
dist: trusty
|
4
|
+
osx_image: xcode9.3
|
5
|
+
os:
|
6
|
+
- linux
|
7
|
+
- osx
|
8
|
+
rvm:
|
9
|
+
- ruby-head
|
10
|
+
- 2.5.1
|
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
|
24
|
+
before_install: gem install bundler -v 1.15.0
|
data/.yardopts
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,18 @@
|
|
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
|
+
|
7
|
+
## [1.1.7] - 2018-12-02
|
8
|
+
- adding `user` & `password` options to client
|
9
|
+
- [Local PoW Support](https://github.com/vivekmarakana/iota.lib.rb#local-pow-support)
|
10
|
+
|
11
|
+
## [1.1.6] - 2018-07-22
|
12
|
+
### Added
|
13
|
+
- `wasAddressSpentFrom` API
|
14
|
+
- Inbuilt batching for following apis: `getTrytes`, `getBalances`, `wereAddressesSpentFrom`, `getInclusionStates` & `findTransactions`
|
15
|
+
- adding changelog file to keep track of future changes
|
16
|
+
|
17
|
+
### Old major changes
|
18
|
+
- Only returning balance array as reponse for `getBalances` api call
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2017 Vivek Marakana
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
# IOTA Ruby Gem
|
2
|
+
|
3
|
+
[](https://travis-ci.org/vivekmarakana/iota.lib.rb) [](https://badge.fury.io/rb/iota-ruby) [](https://raw.githubusercontent.com/vivekmarakana/iota.lib.rb/master/LICENSE)
|
4
|
+
|
5
|
+
This is the **unofficial** Ruby gem for the IOTA Core. It implements both the [official API](https://iota.readme.io/), as well as newly proposed functionality (such as signing, bundles, utilities, conversion, multi signature support and reattch/promote).
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'iota-ruby'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install iota-ruby
|
22
|
+
|
23
|
+
|
24
|
+
# Documentation
|
25
|
+
|
26
|
+
You can find basic documentation at: [https://vivekmarakana.gitbooks.io/iota-ruby](https://vivekmarakana.gitbooks.io/iota-ruby/)
|
27
|
+
|
28
|
+
|
29
|
+
## Getting Started
|
30
|
+
|
31
|
+
After you've successfully installed the library, it is fairly easy to get started by simply launching a new instance of the IOTA object with an optional settings object. When instantiating the object you have the option to decide the API provider that is used to send the requests to and you can also connect directly to the Sandbox environment.
|
32
|
+
|
33
|
+
The optional settings object can have the following values:
|
34
|
+
|
35
|
+
1. **`host`**: `String` Host you want to connect to. Can be DNS, IPv4 or IPv6. Defaults to `localhost `
|
36
|
+
2. **`port`**: `Integer` port of the host you want to connect to. Defaults to 14265.
|
37
|
+
2. **`user`**: `String` username for host if required.
|
38
|
+
2. **`password`**: `String` password for host if required.
|
39
|
+
3. **`provider`**: `String` If you don't provide host and port, you can supply the full provider value to connect to
|
40
|
+
4. **`sandbox`**: `Boolean` Optional value to determine if your provider is the IOTA Sandbox or not.
|
41
|
+
5. **`token`**: `String` Token string in case you are using sandbox.
|
42
|
+
5. **`timeout`**: `Integer` Timeout in seconds for api requests to full node. Defaults to 120.
|
43
|
+
5. **`batch_size`**: `Integer` Batch size for apis like `getTrytes`, `getBalances` etc. Defaults to 500.
|
44
|
+
5. **`local_pow`**: `Boolean` Should PoW be done local machine or not. Defaults to `false` i.e. remote PoW.
|
45
|
+
|
46
|
+
You can either supply the remote node directly via the `provider` option, or individually with `host` and `port`, as can be seen in the example below:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
require 'iota'
|
50
|
+
|
51
|
+
# Create client with host and port as provider
|
52
|
+
client = IOTA::Client.new(host: 'http://localhost', port: 14265)
|
53
|
+
|
54
|
+
# Create client directly with provider
|
55
|
+
client = IOTA::Client.new(provider: 'http://localhost:14265')
|
56
|
+
|
57
|
+
# now you can start using all of the functions
|
58
|
+
status, data = client.api.getNodeInfo
|
59
|
+
```
|
60
|
+
|
61
|
+
Overall, there are currently four subclasses that are accessible from the IOTA object:
|
62
|
+
- **`api`**: Core API functionality for interacting with the IOTA core.
|
63
|
+
- **`utils`**: Utility related functions for conversions, validation and so on
|
64
|
+
- **`validator`**: Validator functions that can help with determining whether the inputs or results that you get are valid.
|
65
|
+
- **`multisig`**: Functions for creating and signing multi-signature addresses and transactions.
|
66
|
+
|
67
|
+
|
68
|
+
## How to use the Library
|
69
|
+
|
70
|
+
All API calls are executed **synchronously** and returns array with 2 entries. First entry is `status` and second is `data`. However, you can use it by passing block to it as well.
|
71
|
+
|
72
|
+
Here is a simple example of how to access the `getNodeInfo` function:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
# Method 1
|
76
|
+
client.api.getNodeInfo do |status, data|
|
77
|
+
if !status
|
78
|
+
# If status is `false`, `data` contains error message...
|
79
|
+
puts data
|
80
|
+
else
|
81
|
+
# If status is `true`, `data` contains response...
|
82
|
+
puts data.inspect
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Method 2
|
87
|
+
status, data = client.api.getNodeInfo
|
88
|
+
if !status
|
89
|
+
puts data
|
90
|
+
else
|
91
|
+
puts data.inspect
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
## Local PoW Support
|
96
|
+
|
97
|
+
If you want to use this gem with public full node which does not support remote PoW on host, you can set `local_pow` to `true` when initialising the client.
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
require 'iota'
|
101
|
+
|
102
|
+
# With remote PoW
|
103
|
+
client = IOTA::Client.new(provider: 'https://node.iota-tangle.io:14265')
|
104
|
+
# If you use `client.api.attachToTangle` api here, you'll get error saying that attachToTangle command is not allowed
|
105
|
+
|
106
|
+
# With local pow
|
107
|
+
client = IOTA::Client.new(provider: 'https://node.iota-tangle.io:14265', local_pow: true)
|
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
|
+
```
|
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
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rake/testtask"
|
3
|
+
|
4
|
+
Rake::TestTask.new(:test) do |t|
|
5
|
+
t.libs << "test"
|
6
|
+
t.libs << "lib"
|
7
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
8
|
+
end
|
9
|
+
|
10
|
+
tasks = []
|
11
|
+
|
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
|
20
|
+
|
21
|
+
tasks << :compile
|
22
|
+
else
|
23
|
+
puts "Not building jar for travis"
|
24
|
+
end
|
25
|
+
else
|
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
|
34
|
+
end
|
35
|
+
|
36
|
+
task :default => tasks + [:test]
|
data/bin/iota-console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "iota"
|
5
|
+
|
6
|
+
require "irb"
|
7
|
+
require "irb/completion"
|
8
|
+
|
9
|
+
# Config IRB to enable --simple-prompt and auto indent
|
10
|
+
IRB.conf[:PROMPT_MODE] = :SIMPLE
|
11
|
+
IRB.conf[:AUTO_INDENT] = true
|
12
|
+
|
13
|
+
puts "Gem loaded..."
|
14
|
+
IRB.start
|
15
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
require "iota"
|
3
|
+
|
4
|
+
iota = IOTA::Client.new(provider: 'http://localhost:14265')
|
5
|
+
|
6
|
+
# First co-signer uses index 0 and security level 3
|
7
|
+
digestOne = iota.multisig.getDigest('ABCDFG', 0, 3)
|
8
|
+
|
9
|
+
# Second cosigner also uses index 0 and security level 3 for the private key
|
10
|
+
digestTwo = iota.multisig.getDigest('FDSAG', 0, 3)
|
11
|
+
|
12
|
+
# Initiate the multisig address generation
|
13
|
+
address = IOTA::Multisig::Address.new
|
14
|
+
|
15
|
+
# Absorb the first cosigners key digest
|
16
|
+
address.absorb(digestOne)
|
17
|
+
|
18
|
+
# Absorb the second cosigners key digest
|
19
|
+
address.absorb(digestTwo)
|
20
|
+
|
21
|
+
# and finally we finalize the address itself
|
22
|
+
finalAddress = address.finalize()
|
23
|
+
|
24
|
+
puts "MULTISIG ADDRESS: #{finalAddress}"
|
25
|
+
|
26
|
+
# Simple validation if the multisig was created correctly
|
27
|
+
# Can be called by each cosigner independently
|
28
|
+
isValid = iota.multisig.validateAddress(finalAddress, [digestOne, digestTwo])
|
29
|
+
|
30
|
+
puts "IS VALID MULTISIG ADDRESS: #{isValid}"
|
31
|
+
|
32
|
+
|
33
|
+
# Transfers object
|
34
|
+
multisigTransfer = [
|
35
|
+
{
|
36
|
+
address: 'ZGHXPZYDKXPEOSQTAQOIXEEI9K9YKFKCWKYYTYAUWXK9QZAVMJXWAIZABOXHHNNBJIEBEUQRTBWGLYMTX',
|
37
|
+
value: 999,
|
38
|
+
message: '',
|
39
|
+
tag: '999999999999999999999999999'
|
40
|
+
}
|
41
|
+
]
|
42
|
+
|
43
|
+
# Multisig address object, used as input
|
44
|
+
input = {
|
45
|
+
address: finalAddress,
|
46
|
+
security: 6,
|
47
|
+
balance: 1000
|
48
|
+
}
|
49
|
+
|
50
|
+
# Define remainder address
|
51
|
+
remainderAddress = 'NZRALDYNVGJWUVLKDWFKJVNYLWQGCWYCURJIIZRLJIKSAIVZSGEYKTZRDBGJLOA9AWYJQB9IPWRAKUC9FBDRZJZXZG'
|
52
|
+
|
53
|
+
initiatedBundle = iota.multisig.initiateTransfer(input, remainderAddress, multisigTransfer)
|
54
|
+
firstSignedBundle = iota.multisig.addSignature(initiatedBundle, finalAddress, iota.multisig.getKey('ABCDFG', 0, 3))
|
55
|
+
finalBundle = iota.multisig.addSignature(firstSignedBundle, finalAddress, iota.multisig.getKey('FDSAG', 0, 3))
|
56
|
+
|
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,134 @@
|
|
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
|
+
#ifndef RARRAY_LEN
|
9
|
+
# define RARRAY_LEN(x) return (long)NUM2INT(rb_funcall(x, rb_intern("length"), 0));
|
10
|
+
#endif
|
11
|
+
|
12
|
+
typedef int64_t trit_t;
|
13
|
+
|
14
|
+
#define __TRUTH_TABLE 1, 0, -1, 1, -1, 0, -1, 1, 0
|
15
|
+
|
16
|
+
static const trit_t TRUTH_TABLE[9] = {__TRUTH_TABLE};
|
17
|
+
|
18
|
+
typedef struct {
|
19
|
+
int rounds;
|
20
|
+
trit_t state[STATE_LENGTH];
|
21
|
+
} Curl;
|
22
|
+
|
23
|
+
static VALUE ccurl_transform(VALUE self);
|
24
|
+
|
25
|
+
static VALUE ccurl_alloc(VALUE klass) {
|
26
|
+
Curl *ctx = ALLOC(Curl);
|
27
|
+
return Data_Wrap_Struct(klass, 0, RUBY_DEFAULT_FREE, ctx);
|
28
|
+
}
|
29
|
+
|
30
|
+
static VALUE ccurl_init(VALUE self, VALUE rounds) {
|
31
|
+
Curl *ctx;
|
32
|
+
int requested = NUMBER_OF_ROUNDS;
|
33
|
+
|
34
|
+
if (TYPE(rounds) != T_NIL) {
|
35
|
+
requested = NUM2INT(rounds);
|
36
|
+
}
|
37
|
+
|
38
|
+
Data_Get_Struct(self, Curl, ctx);
|
39
|
+
|
40
|
+
ctx->rounds = requested;
|
41
|
+
memset(ctx->state, (trit_t)0, STATE_LENGTH * sizeof(trit_t));
|
42
|
+
|
43
|
+
return self;
|
44
|
+
}
|
45
|
+
|
46
|
+
static VALUE ccurl_absorb(VALUE self, VALUE data) {
|
47
|
+
trit_t *trits;
|
48
|
+
int offset = 0;
|
49
|
+
int i;
|
50
|
+
int length = (int)RARRAY_LEN(data);
|
51
|
+
|
52
|
+
Curl *ctx;
|
53
|
+
Data_Get_Struct(self, Curl, ctx);
|
54
|
+
|
55
|
+
trits = (trit_t*)malloc(length * sizeof(trit_t));
|
56
|
+
|
57
|
+
for (i = 0; i < length; ++i) {
|
58
|
+
trits[i] = (trit_t)(NUM2LONG(rb_ary_entry(data, i)));
|
59
|
+
}
|
60
|
+
|
61
|
+
do {
|
62
|
+
memcpy(ctx->state, trits + offset, (length < HASH_LENGTH ? length : HASH_LENGTH) * sizeof(trit_t));
|
63
|
+
ccurl_transform(self);
|
64
|
+
offset += HASH_LENGTH;
|
65
|
+
} while ((length -= HASH_LENGTH) > 0);
|
66
|
+
|
67
|
+
free(trits);
|
68
|
+
|
69
|
+
return Qnil;
|
70
|
+
}
|
71
|
+
|
72
|
+
static VALUE ccurl_squeeze(VALUE self, VALUE data) {
|
73
|
+
int offset = 0;
|
74
|
+
int i;
|
75
|
+
int length = (int)RARRAY_LEN(data);
|
76
|
+
|
77
|
+
Curl *ctx;
|
78
|
+
Data_Get_Struct(self, Curl, ctx);
|
79
|
+
|
80
|
+
do {
|
81
|
+
for(; length < HASH_LENGTH; length++) {
|
82
|
+
rb_ary_push(data, LONG2NUM(0));
|
83
|
+
}
|
84
|
+
|
85
|
+
for (i = 0; i < HASH_LENGTH; i++) {
|
86
|
+
rb_ary_store(data, i, LONG2NUM(ctx->state[i]));
|
87
|
+
}
|
88
|
+
|
89
|
+
ccurl_transform(self);
|
90
|
+
offset += HASH_LENGTH;
|
91
|
+
} while ((length -= HASH_LENGTH) > 0);
|
92
|
+
|
93
|
+
return Qnil;
|
94
|
+
}
|
95
|
+
|
96
|
+
static VALUE ccurl_transform(VALUE self) {
|
97
|
+
trit_t scratchpad[STATE_LENGTH];
|
98
|
+
int round, scratchpadIndex=0, scratchpadIndexSave, stateIndex;
|
99
|
+
|
100
|
+
Curl *ctx;
|
101
|
+
Data_Get_Struct(self, Curl, ctx);
|
102
|
+
|
103
|
+
for (round = 0; round < NUMBER_OF_ROUNDS; round++) {
|
104
|
+
memcpy(scratchpad, ctx->state, STATE_LENGTH * sizeof(trit_t));
|
105
|
+
|
106
|
+
for (stateIndex = 0; stateIndex < STATE_LENGTH; stateIndex++) {
|
107
|
+
scratchpadIndexSave = scratchpadIndex;
|
108
|
+
scratchpadIndex += (scratchpadIndex < 365 ? 364 : -365);
|
109
|
+
ctx->state[stateIndex] = TRUTH_TABLE[scratchpad[scratchpadIndexSave ] + scratchpad[scratchpadIndex ] * 3 + 4];
|
110
|
+
}
|
111
|
+
}
|
112
|
+
|
113
|
+
return Qnil;
|
114
|
+
}
|
115
|
+
|
116
|
+
static VALUE ccurl_reset(VALUE self) {
|
117
|
+
Curl *ctx;
|
118
|
+
Data_Get_Struct(self, Curl, ctx);
|
119
|
+
memset(ctx->state, 0, STATE_LENGTH * sizeof(char));
|
120
|
+
return Qnil;
|
121
|
+
}
|
122
|
+
|
123
|
+
void Init_ccurl(void) {
|
124
|
+
VALUE iota = rb_define_module("IOTA");
|
125
|
+
VALUE iotaCrypto = rb_define_module_under(iota, "Crypto");
|
126
|
+
VALUE cCurl = rb_define_class_under(iotaCrypto, "CCurl", rb_cObject);
|
127
|
+
|
128
|
+
rb_define_alloc_func(cCurl, ccurl_alloc);
|
129
|
+
rb_define_method(cCurl, "initialize", ccurl_init, 1);
|
130
|
+
rb_define_method(cCurl, "absorb", ccurl_absorb, 1);
|
131
|
+
rb_define_method(cCurl, "squeeze", ccurl_squeeze, 1);
|
132
|
+
rb_define_method(cCurl, "transform", ccurl_transform, 0);
|
133
|
+
rb_define_method(cCurl, "reset", ccurl_reset, 0);
|
134
|
+
}
|