ttcrypt 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,67 @@
1
+ //
2
+ // sha256.h
3
+ // iGlomp
4
+ //
5
+ // Created by Sergey Chernov on 28.10.11.
6
+ // Copyright (c) 2011 Thrift. All rights reserved.
7
+ //
8
+
9
+ #ifndef iGlomp_sha256_h
10
+ #define iGlomp_sha256_h
11
+
12
+ /* Declarations of functions and data types used for SHA256 and SHA224 sum
13
+ library functions.
14
+ Copyright (C) 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
15
+
16
+ This program is free software: you can redistribute it and/or modify
17
+ it under the terms of the GNU General Public License as published by
18
+ the Free Software Foundation, either version 3 of the License, or
19
+ (at your option) any later version.
20
+
21
+ This program is distributed in the hope that it will be useful,
22
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
23
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
+ GNU General Public License for more details.
25
+
26
+ You should have received a copy of the GNU General Public License
27
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
28
+
29
+ typedef unsigned char uint8;
30
+ typedef unsigned int uint32;
31
+
32
+ #ifndef SHA256_H
33
+ # define SHA256_H 1
34
+
35
+ # include <stdio.h>
36
+ # include <stdint.h>
37
+
38
+ # ifdef __cplusplus
39
+ extern "C" {
40
+ # endif
41
+
42
+ /* Structure to save state of computation between the single steps. */
43
+ typedef struct sha256_ctx
44
+ {
45
+ uint32_t state[8];
46
+
47
+ uint32_t total[2];
48
+ size_t buflen;
49
+ uint8 buffer[64];
50
+ } sha256_context;
51
+
52
+ enum { SHA224_DIGEST_SIZE = 224 / 8 };
53
+ enum { SHA256_DIGEST_SIZE = 256 / 8 };
54
+
55
+ void sha256_starts( sha256_context *ctx );
56
+ void sha256_update( sha256_context *ctx, uint8 *input, uint32 length );
57
+ void sha256_finish( sha256_context *ctx, uint8 digest[32] );
58
+
59
+
60
+
61
+ # ifdef __cplusplus
62
+ }
63
+ # endif
64
+
65
+
66
+ #endif
67
+ #endif
@@ -0,0 +1,63 @@
1
+ //
2
+ // text_utils.cpp
3
+ //
4
+ // Created by Sergey Chernov on 01.06.14.
5
+ // Copyright (c) 2014 thrift. All rights reserved.
6
+ //
7
+
8
+ /*
9
+ This program is free software: you can redistribute it and/or modify
10
+ it under the terms of the GNU General Public License as published by
11
+ the Free Software Foundation, either version 3 of the License, or
12
+ (at your option) any later version.
13
+
14
+ This program is distributed in the hope that it will be useful,
15
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ GNU General Public License for more details.
18
+
19
+ You should have received a copy of the GNU General Public License
20
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
21
+ */
22
+
23
+ #include "text_utils.h"
24
+
25
+
26
+ std::string sformat(const std::string fmt_str, ...) {
27
+ int final_n, n = ((int)fmt_str.size()) * 2; /* reserve 2 times as much as the length of the fmt_str */
28
+ std::string str;
29
+ std::unique_ptr<char[]> formatted;
30
+ va_list ap;
31
+ while(1) {
32
+ formatted.reset(new char[n]); /* wrap the plain char array into the unique_ptr */
33
+ // strcpy(&formatted[0], fmt_str.c_str());
34
+ va_start(ap, fmt_str);
35
+ final_n = vsnprintf(&formatted[0], n, fmt_str.c_str(), ap);
36
+ va_end(ap);
37
+ if (final_n < 0 || final_n >= n)
38
+ n += abs(final_n - n + 1);
39
+ else
40
+ break;
41
+ }
42
+ return std::string(formatted.get());
43
+ }
44
+
45
+ std::string vsformat(const std::string fmt_str, va_list args) {
46
+ int final_n, n = ((int)fmt_str.size()) * 2; /* reserve 2 times as much as the length of the fmt_str */
47
+ std::string str;
48
+ std::unique_ptr<char[]> formatted;
49
+ while(1) {
50
+ formatted.reset(new char[n]); /* wrap the plain char array into the unique_ptr */
51
+ // strcpy(&formatted[0], fmt_str.c_str());
52
+ va_list c;
53
+ va_copy(c, args);
54
+ final_n = vsnprintf(&formatted[0], n-1, fmt_str.c_str(), c);
55
+ va_end(c);
56
+ if (final_n < 0 || final_n >= n)
57
+ n += abs(final_n - n + 1);
58
+ else
59
+ break;
60
+ }
61
+ return std::string(formatted.get());
62
+ }
63
+
@@ -0,0 +1,64 @@
1
+ //
2
+ // text_utils.h
3
+ // zcoin
4
+ //
5
+ // Created by Sergey Chernov on 01.06.14.
6
+ // Copyright (c) 2014 thrift. All rights reserved.
7
+ //
8
+
9
+ /*
10
+ This program is free software: you can redistribute it and/or modify
11
+ it under the terms of the GNU General Public License as published by
12
+ the Free Software Foundation, either version 3 of the License, or
13
+ (at your option) any later version.
14
+
15
+ This program is distributed in the hope that it will be useful,
16
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ GNU General Public License for more details.
19
+
20
+ You should have received a copy of the GNU General Public License
21
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
22
+ */
23
+
24
+ #ifndef __zcoin__text_utils__
25
+ #define __zcoin__text_utils__
26
+
27
+ #include <iostream>
28
+
29
+ std::string sformat(const std::string fmt_str, ...);
30
+ std::string vsformat(const std::string fmt_str, va_list args);
31
+
32
+ #ifdef DEBUG
33
+
34
+ template <class T> void log_d(const T& object,const std::string& msg) {
35
+ std::cout << (object.to_string() + ": " + msg) << std::endl;
36
+ }
37
+
38
+ template <class T> void log_d(T *const object,const std::string& msg) {
39
+ log_d(*object, msg);
40
+ }
41
+
42
+ inline void log_d(const std::string format, ...) {
43
+ va_list ap;
44
+ va_start(ap, format);
45
+ std::cout << vsformat(format, ap) << std::endl;
46
+ va_end(ap);
47
+ }
48
+
49
+ #else
50
+
51
+ #define log_d(...)
52
+
53
+ #endif
54
+
55
+ template <class T>
56
+ void stopwatch(T text, std::function<void(void)> block) {
57
+ std::cout << "Starting " << text << "...";
58
+ std::cout.flush();
59
+ clock_t start = clock();
60
+ block();
61
+ std::cout << " done, " << (clock() - start)/1000.0 << "ms " << std::endl;
62
+ }
63
+
64
+ #endif /* defined(__zcoin__text_utils__) */
@@ -0,0 +1,51 @@
1
+ /*
2
+ ttcrypt.cpp
3
+
4
+ Created by Sergey Chernov on 03.06.14.
5
+ Copyright (c) 2014 thrift. All rights reserved.
6
+
7
+
8
+ This program is free software: you can redistribute it and/or modify
9
+ it under the terms of the GNU General Public License as published by
10
+ the Free Software Foundation, either version 3 of the License, or
11
+ (at your option) any later version.
12
+
13
+ This program is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+
18
+ You should have received a copy of the GNU General Public License
19
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ */
21
+
22
+ #include "ttcrypt.h"
23
+ #include "sha1.h"
24
+ #include "sha256.h"
25
+
26
+ using namespace thrift;
27
+
28
+ byte_buffer ttcrypt::sha1(const byte_buffer& data) noexcept {
29
+ byte_buffer res(20);
30
+ sha1::calc(data.data().get(), (int)data.size(), res.data().get() );
31
+ return res;
32
+ }
33
+
34
+ byte_buffer ttcrypt::sha256(const thrift::byte_buffer &data) noexcept {
35
+ byte_buffer res(32);
36
+ sha256_ctx ctx;
37
+ sha256_starts(&ctx);
38
+ sha256_update(&ctx, data.data().get(), (uint32) data.size());
39
+ sha256_finish(&ctx, res.data().get());
40
+ return res;
41
+ }
42
+
43
+ byte_buffer ttcrypt::i2osp(const big_integer& i, size_t block_size) noexcept {
44
+ byte_buffer res = i.to_byte_buffer();
45
+ if( block_size > 0 && res.size() != block_size ) {
46
+ size_t pad_length = block_size - res.size() % block_size;
47
+ if( pad_length > 0 )
48
+ return byte_buffer('\0', pad_length) + res;
49
+ }
50
+ return res;
51
+ }
@@ -0,0 +1,45 @@
1
+ /*
2
+ ttcrypt.h
3
+ zcoin
4
+
5
+ Created by Sergey Chernov on 03.06.14.
6
+ Copyright (c) 2014 thrift. All rights reserved.
7
+
8
+ This program is free software: you can redistribute it and/or modify
9
+ it under the terms of the GNU General Public License as published by
10
+ the Free Software Foundation, either version 3 of the License, or
11
+ (at your option) any later version.
12
+
13
+ This program is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+
18
+ You should have received a copy of the GNU General Public License
19
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ */
21
+
22
+ #ifndef __zcoin__ttcrypt__
23
+ #define __zcoin__ttcrypt__
24
+
25
+ #include <iostream>
26
+ #include "byte_buffer.h"
27
+ #include "big_integer.h"
28
+
29
+ using namespace thrift;
30
+
31
+ namespace ttcrypt {
32
+
33
+ byte_buffer sha1(const byte_buffer& data) noexcept;
34
+ byte_buffer sha256(const byte_buffer& data) noexcept;
35
+
36
+ byte_buffer i2osp(const big_integer& i, size_t block_size=0) noexcept;
37
+
38
+ inline big_integer os2ip(const byte_buffer& buffer) noexcept {
39
+ return big_integer(buffer);
40
+ }
41
+
42
+ }
43
+
44
+
45
+ #endif /* defined(__zcoin__ttcrypt__) */
@@ -0,0 +1,234 @@
1
+ /*
2
+ * TTCrypt ruby bindings
3
+ *
4
+ * Copyright (C) 2014 Thrift, Sergey S. Chernov
5
+
6
+ This program is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+ #include <iostream>
20
+ #include <stdlib.h>
21
+
22
+ #include "ruby_cpp_tools.h"
23
+
24
+ #include "byte_buffer.h"
25
+ #include "pollard_rho.h"
26
+ #include "rsa_key.h"
27
+
28
+ extern "C" {
29
+ #include <ruby.h>
30
+ #include <ruby/thread.h>
31
+
32
+ void Init_ttcrypt(void);
33
+ }
34
+
35
+ using namespace thrift;
36
+ using namespace ttcrypt;
37
+
38
+ using namespace std;
39
+
40
+ static VALUE rsa_exception;
41
+ static VALUE rsa_class;
42
+
43
+ VALUE wrap_exceptions(const std::function<VALUE()>& block) {
44
+ try {
45
+ return block();
46
+ } catch (const rsa_key::error& e) {
47
+ rb_raise(rsa_exception, "%s", e.what());
48
+ } catch (const std::exception& e) {
49
+ rb_raise(rb_eStandardError, "%s", e.what());
50
+ } catch (...) {
51
+ rb_raise(rsa_exception, "unknown exception");
52
+ }
53
+ return Qnil;
54
+ }
55
+
56
+ rsa_key* rsa_ptr(VALUE self) {
57
+ rsa_key *pkey;
58
+ Data_Get_Struct(self, rsa_key, pkey);
59
+ return pkey;
60
+ }
61
+
62
+ rsa_key& rsa(VALUE self) {
63
+ return *rsa_ptr(self);
64
+ }
65
+
66
+ extern "C" {
67
+
68
+ static VALUE rsa_generate(VALUE self, VALUE length) {
69
+ return wrap_exceptions([=] {
70
+ unsigned l = NUM2UINT(length);
71
+ rsa_key *pkey = rsa_ptr(self);
72
+ ruby_unblock([=] {*pkey = rsa_key::generate(l);});
73
+ return self;
74
+ });
75
+ }
76
+
77
+ static VALUE rsa_bits(VALUE self) {
78
+ return INT2NUM(rsa(self).size_in_bits());
79
+ }
80
+
81
+ static VALUE rsa_encrypt(VALUE self, VALUE rb_data) {
82
+ return wrap_exceptions([=] {
83
+ byte_buffer res;
84
+ auto data = value_to_byte_buffer(rb_data);
85
+ ruby_unblock([&] {
86
+ res = rsa(self).encrypt(data);
87
+ });
88
+ return to_rb_string(res);
89
+ });
90
+ }
91
+
92
+ static VALUE rsa_decrypt(VALUE self, VALUE rb_data) {
93
+ return wrap_exceptions([=] {
94
+ byte_buffer res;
95
+ rsa_key& key = rsa(self);
96
+ auto data = value_to_byte_buffer(rb_data);
97
+ ruby_unblock([&res,&data,&key] {
98
+ res = key.decrypt(data);
99
+ });
100
+ return to_rb_string(res);
101
+ });
102
+ }
103
+
104
+ static VALUE factorize(VALUE self, VALUE composite) {
105
+ return wrap_exceptions([=] {
106
+ string s = value_to_string(composite);
107
+
108
+ vector<big_integer> factors;
109
+ ruby_unblock([s,&factors] {
110
+ factors = pollard_rho::factorize(decode_hex(s));
111
+ });
112
+
113
+ VALUE result = rb_ary_new();
114
+ for (auto factor : factors) {
115
+ rb_ary_push(result, to_hex_value(factor));
116
+ }
117
+ return result;
118
+ });
119
+ }
120
+
121
+ typedef byte_buffer (*hash_t)(const byte_buffer &);
122
+
123
+ static hash_t hash_provider(VALUE name) {
124
+ string n = value_to_string(name);
125
+ if (n == "sha256")
126
+ return sha256;
127
+ else if (n == "sha1")
128
+ return sha1;
129
+ else
130
+ throw invalid_argument("not supported hash: " + n);
131
+ }
132
+
133
+ static VALUE rsa_sign(VALUE self, VALUE message, VALUE signature_method) {
134
+ return wrap_exceptions([=] {
135
+ byte_buffer m = value_to_byte_buffer(message);
136
+ byte_buffer res;
137
+ hash_t hash = hash_provider(signature_method);
138
+
139
+ ruby_unblock([&] {
140
+ res = rsa(self).sign(m, hash);
141
+ });
142
+
143
+ return to_value(res);
144
+ });
145
+ }
146
+
147
+ static VALUE rsa_verify(VALUE self, VALUE message, VALUE signature,
148
+ VALUE signature_method) {
149
+ return wrap_exceptions([=] {
150
+ byte_buffer m = value_to_byte_buffer(message);
151
+ byte_buffer s = value_to_byte_buffer(signature);
152
+ bool res;
153
+ hash_t hash = hash_provider(signature_method);
154
+
155
+ ruby_unblock([&] {
156
+ res = rsa(self).verify(m, s, hash);
157
+ });
158
+
159
+ return res ? Qtrue : Qfalse;
160
+ });
161
+ }
162
+
163
+ static VALUE rsa_extract_public(VALUE self) {
164
+ return wrap_exceptions([=] {
165
+ rsa_key &me = rsa(self);
166
+ VALUE res = rb_class_new_instance(0,NULL,rsa_class);
167
+ rsa_key &pub = rsa(res);
168
+ pub = me.public_key();
169
+ return res;
170
+ });
171
+ }
172
+
173
+ static VALUE rsa_components(VALUE self) {
174
+ return wrap_exceptions([=] {
175
+ rsa_key& key = rsa(self);
176
+ VALUE hash = rb_hash_new();
177
+ for(auto x: key.get_params()) {
178
+ rb_hash_aset(hash,to_rb_sym(x.first),to_rb_string(x.second.to_byte_buffer()));
179
+ }
180
+ return hash;
181
+ });
182
+ }
183
+
184
+ static int do_set_param(VALUE key,VALUE data,VALUE obj) {
185
+ rsa(obj).set(value_to_string(key), value_to_byte_buffer(data));
186
+ return ST_CONTINUE;
187
+ }
188
+
189
+ static VALUE rsa_set_params(VALUE self,VALUE hash) {
190
+ return wrap_exceptions([=]{
191
+ rb_hash_foreach(hash, (int (*)(...)) do_set_param, self);
192
+ rsa(self).normalize_key();
193
+ return Qnil;
194
+ });
195
+ }
196
+
197
+ static VALUE rsa_is_private(VALUE self) {
198
+ return rsa(self).is_private() ? Qtrue : Qfalse;
199
+ }
200
+
201
+ static void rsa_free(void* ptr) {
202
+ delete (ttcrypt::rsa_key*) ptr;
203
+ }
204
+
205
+ static VALUE rsa_alloc(VALUE klass) {
206
+ return Data_Wrap_Struct(klass, 0, rsa_free, new ttcrypt::rsa_key);
207
+ }
208
+
209
+ }
210
+
211
+ void Init_ttcrypt(void) {
212
+
213
+ VALUE ttcrypt_module = rb_define_module("TTCrypt");
214
+
215
+ rb_define_method(ttcrypt_module, "_factorize", (ruby_method) factorize, 1);
216
+
217
+ rsa_class = rb_define_class_under(ttcrypt_module, "RsaKey", rb_cObject);
218
+ rb_define_alloc_func(rsa_class, rsa_alloc);
219
+ rb_define_method(rsa_class, "_generate", (ruby_method) rsa_generate, 1);
220
+ rb_define_method(rsa_class, "_bits", (ruby_method) rsa_bits, 0);
221
+ rb_define_method(rsa_class, "_encrypt", (ruby_method) rsa_encrypt, 1);
222
+ rb_define_method(rsa_class, "_decrypt", (ruby_method) rsa_decrypt, 1);
223
+ rb_define_method(rsa_class, "_sign", (ruby_method) rsa_sign, 2);
224
+ rb_define_method(rsa_class, "_verify", (ruby_method) rsa_verify, 3);
225
+ rb_define_method(rsa_class, "extract_public",
226
+ (ruby_method) rsa_extract_public, 0);
227
+ rb_define_method(rsa_class, "_is_private", (ruby_method) rsa_is_private, 0);
228
+ rb_define_method(rsa_class, "_components", (ruby_method) rsa_components, 0);
229
+ rb_define_method(rsa_class, "_set_params", (ruby_method) rsa_set_params, 1);
230
+
231
+ rsa_exception = rb_define_class_under(rsa_class, "Error",
232
+ rb_eStandardError);
233
+ }
234
+
@@ -0,0 +1,5 @@
1
+ module TTCrypt
2
+
3
+ VERSION = '0.0.2'
4
+
5
+ end
data/lib/ttcrypt.rb ADDED
@@ -0,0 +1,142 @@
1
+ # Thrift cryptographics primitives: fast c++ implementation, only strong schemes,
2
+ # releases GVL on long operations so other threads can be executed in parallel.
3
+ module TTCrypt
4
+ # Your code goes here...
5
+
6
+ # Pollard 'rho' prime factorization. Allows execution of other ruby
7
+ # threads in parallel (releases GVL)
8
+ #
9
+ # @return [int] array of prime factors
10
+ def factorize composite
11
+ hex = composite.to_i.to_s(16)
12
+ hex = '0' + hex if (hex.length & 1) == 1
13
+ _factorize(hex).map { |x| x.to_i(16) }
14
+ end
15
+
16
+ # Implementation of RSAES-OAEP encryption and RSASSA-PSS signing
17
+ # accroding to pkcs#1 v2.2 specification. Does NOT implement any previous cryptographically
18
+ # weak shcemes (like 1.5 signature) - go use openssl for itm but it does compromise private
19
+ # key.
20
+ #
21
+ # All time consuming operations are executed releasing GVL so other threads can run in parallel
22
+ # in the multicore hardware.
23
+ #
24
+ class RsaKey
25
+
26
+ # raised when some parameters of RSAES are invalid, e.g.
27
+ # message/representation is too long, encrypted message or representation
28
+ # is not properly padded
29
+ class Error < StandardError
30
+ end
31
+
32
+ ACCEPTED_PARAMS = %i|n e p q d|
33
+
34
+ def initialize ** params
35
+ set_params(params)
36
+ end
37
+
38
+ def set_params ** params
39
+ res = {}
40
+ params.each { |k, v|
41
+ ACCEPTED_PARAMS.include?(k) or raise ArgumentError, "unknown key component"
42
+ res[k.to_s] = v.to_s.force_encoding(Encoding::BINARY)
43
+ }
44
+ _set_params res
45
+ end
46
+
47
+ # Generate private key (that contains public key too) of the desired bit
48
+ # length (recommended at least 2048).
49
+ def self.generate bits_strength
50
+ k = RsaKey.new
51
+ k._generate(bits_strength)
52
+ end
53
+
54
+ # Get key size in bits
55
+ def bits
56
+ _bits
57
+ end
58
+
59
+ # Encrypt message with public key using RSAES-OAEP scheme
60
+ # (pkcs#1 v.2.2).
61
+ def encrypt message
62
+ message.force_encoding Encoding::BINARY
63
+ _encrypt message
64
+ end
65
+
66
+ # Decrypt message with private key using RSAES-OAEP scheme
67
+ # (pkcs#1 v.2.2). Requires private key
68
+ #
69
+ def decrypt message
70
+ message.force_encoding Encoding::BINARY
71
+ _decrypt message
72
+ end
73
+
74
+ # Sign the message using pkcs#1 v2.2 RSASSA-PSS
75
+ # process. Requires private key.
76
+ #
77
+ #@param [String] message to sign
78
+ #@param [Symbol|String] hash function used (:sha1 or :sha256)
79
+ #@return [bool] true if the signature is consistent
80
+ def sign message, hash_name
81
+ message.force_encoding Encoding::BINARY
82
+ _sign message, hash_name.to_s.downcase
83
+ end
84
+
85
+ # Check message signature signed with pkcs#1 v2.2 RSASSA-PSS
86
+ # process
87
+ #
88
+ #@param [String] message to verify
89
+ #@param [String] signature
90
+ #@param [Symbol|String] hash function used (:sha1 or :sha256)
91
+ #@return [bool] true if the signature is consistent
92
+ def verify message, signature, hash_name=:sha1
93
+ message.force_encoding Encoding::BINARY
94
+ signature.force_encoding Encoding::BINARY
95
+ _verify message, signature, hash_name.to_s.downcase
96
+ end
97
+
98
+ # Extract public key from a private (or public) key
99
+ # @return [RsaKey] public key instance
100
+ def extract_public
101
+ # native implementation: this is for indexing only
102
+ end
103
+
104
+ # true if self contains private key
105
+ def private?
106
+ _is_private
107
+ end
108
+
109
+ # Get key components as hash. Components are binary strings, indexes are symbols
110
+ # e.g. :n, :e
111
+ def components
112
+ @components ||= _components
113
+ end
114
+
115
+ # @return [String] P component or nil
116
+ def p
117
+ components[:p]
118
+ end
119
+
120
+ def q
121
+ components[:q]
122
+ end
123
+
124
+ def n
125
+ components[:n]
126
+ end
127
+
128
+ def e
129
+ components[:e]
130
+ end
131
+
132
+ end
133
+ end
134
+
135
+ # it should require native lib after module definition above
136
+ # otherwise won't work!
137
+ require 'ttcrypt/ttcrypt'
138
+
139
+ module TTCrypt
140
+ module_function :factorize, :_factorize
141
+ end
142
+
@@ -0,0 +1,17 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ RSpec.configure do |config|
8
+ config.treat_symbols_as_metadata_keys_with_true_values = true
9
+ config.run_all_when_everything_filtered = true
10
+ config.filter_run :focus
11
+
12
+ # Run specs in random order to surface order dependencies. If you find an
13
+ # order dependency and want to debug it, you can fix the order by providing
14
+ # the seed, which is printed after each run.
15
+ # --seed 1234
16
+ config.order = 'random'
17
+ end