iota-ruby 1.1.8-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +8 -0
  3. data/.gitignore +15 -0
  4. data/.travis.yml +24 -0
  5. data/.yardopts +7 -0
  6. data/CHANGELOG.md +18 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE +21 -0
  9. data/README.md +121 -0
  10. data/Rakefile +36 -0
  11. data/bin/iota-console +15 -0
  12. data/examples/multisig.rb +69 -0
  13. data/ext/ccurl/ccurl.c +134 -0
  14. data/ext/ccurl/extconf.rb +22 -0
  15. data/ext/jcurl/JCurl.java +126 -0
  16. data/ext/jcurl/JCurlService.java +36 -0
  17. data/ext/pow/ccurl-0.3.0.dll +0 -0
  18. data/ext/pow/libccurl-0.3.0.dylib +0 -0
  19. data/ext/pow/libccurl-0.3.0.so +0 -0
  20. data/iota-ruby.gemspec +37 -0
  21. data/lib/iota.rb +76 -0
  22. data/lib/iota/api/api.rb +251 -0
  23. data/lib/iota/api/commands.rb +113 -0
  24. data/lib/iota/api/transport.rb +43 -0
  25. data/lib/iota/api/wrappers.rb +429 -0
  26. data/lib/iota/crypto/bundle.rb +163 -0
  27. data/lib/iota/crypto/converter.rb +244 -0
  28. data/lib/iota/crypto/curl.rb +18 -0
  29. data/lib/iota/crypto/curl_c.rb +17 -0
  30. data/lib/iota/crypto/curl_java.rb +18 -0
  31. data/lib/iota/crypto/curl_ruby.rb +70 -0
  32. data/lib/iota/crypto/hmac.rb +27 -0
  33. data/lib/iota/crypto/kerl.rb +82 -0
  34. data/lib/iota/crypto/pow_provider.rb +27 -0
  35. data/lib/iota/crypto/private_key.rb +80 -0
  36. data/lib/iota/crypto/sha3_ruby.rb +122 -0
  37. data/lib/iota/crypto/signing.rb +97 -0
  38. data/lib/iota/models/account.rb +489 -0
  39. data/lib/iota/models/base.rb +13 -0
  40. data/lib/iota/models/bundle.rb +87 -0
  41. data/lib/iota/models/input.rb +38 -0
  42. data/lib/iota/models/seed.rb +33 -0
  43. data/lib/iota/models/transaction.rb +52 -0
  44. data/lib/iota/models/transfer.rb +44 -0
  45. data/lib/iota/multisig/address.rb +41 -0
  46. data/lib/iota/multisig/multisig.rb +244 -0
  47. data/lib/iota/utils/ascii.rb +50 -0
  48. data/lib/iota/utils/broker.rb +124 -0
  49. data/lib/iota/utils/input_validator.rb +149 -0
  50. data/lib/iota/utils/object_validator.rb +34 -0
  51. data/lib/iota/utils/utils.rb +324 -0
  52. data/lib/iota/version.rb +3 -0
  53. data/lib/jcurl.jar +0 -0
  54. data/lib/patch.rb +17 -0
  55. data/test/ascii_test.rb +114 -0
  56. data/test/curl_c_test.rb +31 -0
  57. data/test/curl_java_test.rb +31 -0
  58. data/test/curl_ruby_test.rb +27 -0
  59. data/test/kerl_test.rb +52 -0
  60. data/test/pow_provider_test.rb +36 -0
  61. data/test/sha3_test.rb +71 -0
  62. data/test/test_helper.rb +4 -0
  63. data/test/utils_test.rb +179 -0
  64. 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
@@ -0,0 +1,8 @@
1
+ root=true
2
+
3
+ [*]
4
+ end_of_line=lf
5
+ insert_final_newline=true
6
+ indent_style=space
7
+ indent_size=2
8
+ trim_trailing_whitespace=true
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ *.gem
2
+ Gemfile.lock
3
+ /.bundle/
4
+ /.yardoc
5
+ /Gemfile.lock
6
+ /_yardoc/
7
+ /coverage/
8
+ /doc/
9
+ /pkg/
10
+ /spec/reports/
11
+ /tmp/
12
+ .DS_Store
13
+ Makefile
14
+ *.bundle
15
+ *.o
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
@@ -0,0 +1,7 @@
1
+ --protected
2
+ --no-private
3
+ --embed-mixin ClassMethods
4
+ -
5
+ README.md
6
+ CHANGELOG.md
7
+ LICENSE
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
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
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
+ [![Build Status](https://travis-ci.org/vivekmarakana/iota.lib.rb.svg?branch=master)](https://travis-ci.org/vivekmarakana/iota.lib.rb) [![Gem Version](https://badge.fury.io/rb/iota-ruby.svg)](https://badge.fury.io/rb/iota-ruby) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](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
+ }