ntc-rcrypto 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 97cbd390dc90ba8f2b7dbe0c0b9c62b2c98be41eb8dfa95bcb0755f537a06727
4
+ data.tar.gz: 860aa0358088f78f5b872629f13dd2e764d5c4c3b38f7b20a50b316a95594cac
5
+ SHA512:
6
+ metadata.gz: e7af25f256f43b6fcc6e3d0cccdd5e6bfaf19bf5a99a2b01056257595b2a239df08e9258133eacb3ae475248189e46742cdbeff608c0cfdc9a984dcefbc8d28e
7
+ data.tar.gz: 7d4e992779c28b52a66075daba8f2e7426c34df9205b41e38ab1b1ea7d374d47165c7f21a36134468fa48a3f2082b3c59a36f66500d0e129e520560cb1e41d65
@@ -0,0 +1,65 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ *.gem
11
+ *.rbc
12
+ /.config
13
+ /coverage/
14
+ /InstalledFiles
15
+ /pkg/
16
+ /spec/reports/
17
+ /spec/examples.txt
18
+ /test/tmp/
19
+ /test/version_tmp/
20
+ /tmp/
21
+
22
+ # Used by dotenv library to load environment variables.
23
+ # .env
24
+
25
+ # Ignore Byebug command history file.
26
+ .byebug_history
27
+
28
+ ## Specific to RubyMotion:
29
+ .dat*
30
+ .repl_history
31
+ build/
32
+ *.bridgesupport
33
+ build-iPhoneOS/
34
+ build-iPhoneSimulator/
35
+
36
+ ## Specific to RubyMotion (use of CocoaPods):
37
+ #
38
+ # We recommend against adding the Pods directory to your .gitignore. However
39
+ # you should judge for yourself, the pros and cons are mentioned at:
40
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
41
+ #
42
+ # vendor/Pods/
43
+
44
+ ## Documentation cache and generated files:
45
+ /.yardoc/
46
+ /_yardoc/
47
+ /doc/
48
+ /rdoc/
49
+
50
+ ## Environment normalization:
51
+ /.bundle/
52
+ /vendor/bundle
53
+ /lib/bundler/man/
54
+
55
+ # for a library or gem, you might want to ignore these files since the code is
56
+ # intended to run in multiple environments; otherwise, check them in:
57
+ # Gemfile.lock
58
+ # .ruby-version
59
+ # .ruby-gemset
60
+
61
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
62
+ .rvmrc
63
+
64
+ # Used by RuboCop. Remote config files pulled in from inherit_from directive.
65
+ # .rubocop-https?--*
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.7.0
6
+ before_install: gem install bundler -v 2.1.4
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at congnghia0609@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [https://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: https://contributor-covenant.org
74
+ [version]: https://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in rcrypto.gemspec
4
+ gemspec
5
+
6
+ gem "rake", "~> 12.1"
7
+ gem "minitest", "~> 5.10"
@@ -0,0 +1,21 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ntc-rcrypto (0.0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ minitest (5.13.0)
10
+ rake (12.3.3)
11
+
12
+ PLATFORMS
13
+ ruby
14
+
15
+ DEPENDENCIES
16
+ minitest (~> 5.10)
17
+ ntc-rcrypto!
18
+ rake (~> 12.1)
19
+
20
+ BUNDLED WITH
21
+ 2.1.4
data/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright 2020 nghiatc
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
@@ -0,0 +1,51 @@
1
+ # ntc-rcrypto
2
+ ntc-rcrypto is module ruby cryptography.
3
+
4
+ ## Installation
5
+
6
+ Add this line to your application's Gemfile:
7
+
8
+ ```ruby
9
+ gem 'ntc-rcrypto'
10
+ ```
11
+
12
+ And then execute:
13
+ ```ruby
14
+ bundle install
15
+ ```
16
+
17
+ Or install it yourself as:
18
+ ```ruby
19
+ gem install ntc-rcrypto
20
+ ```
21
+
22
+ ## Usage
23
+ **Use encode/decode Hex**
24
+ ```ruby
25
+ require './rcrypto'
26
+
27
+ sss = Rcrypto::SSS.new
28
+
29
+ s = "nghiatcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
30
+ puts s
31
+ puts s.length
32
+ # creates a set of shares
33
+ arr = sss.create(3, 6, s)
34
+ # puts arr
35
+
36
+ # combines shares into secret
37
+ s1 = sss.combine(arr[0...3])
38
+ puts s1
39
+ puts s1.length
40
+
41
+ s2 = sss.combine(arr[3...6])
42
+ puts s2
43
+ puts s2.length
44
+
45
+ s3 = sss.combine(arr[1...5])
46
+ puts s3
47
+ puts s3.length
48
+ ```
49
+
50
+ ## License
51
+ This code is under the [Apache Licence v2](https://www.apache.org/licenses/LICENSE-2.0).
@@ -0,0 +1,10 @@
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
+ task :default => :test
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rcrypto"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,91 @@
1
+ require './rcrypto'
2
+
3
+ sss = Rcrypto::SSS.new
4
+
5
+ # # Dev1: random_number
6
+ # for i in 0...10
7
+ # puts sss.random_number
8
+ # end
9
+
10
+ # # Dev2: extended gcd
11
+ # puts sss.modinv(67356225285819719212258382314594931188352598651646313425411610888829358649431, 115792089237316195423570985008687907853269984665640564039457584007913129639747)
12
+ # #=> 66304286696287781344919781629879750902445808730247479812988635671630372079315
13
+
14
+ # # Dev3: hexlify
15
+ # puts sss.hexlify('nghiatc')
16
+
17
+ # # Dev4: encode & decode
18
+ # number = 67356225285819719212258382314594931188352598651646313425411610888829358649431
19
+ # puts number
20
+ # b64data = sss.to_base64(number)
21
+ # puts b64data.length
22
+ # puts b64data
23
+ # hexdata = sss.to_hex(number)
24
+ # puts hexdata.length
25
+ # puts hexdata
26
+ # numb64decode = sss.from_base64(b64data)
27
+ # puts numb64decode
28
+ # numhexdecode = sss.from_hex(hexdata)
29
+ # puts numhexdecode
30
+
31
+ # # Dev5: split & merge
32
+ # s = "nghiatcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
33
+ # puts s
34
+ # puts s.length
35
+ # arr = sss.split_secret_to_int(s)
36
+ # puts(arr)
37
+ # puts(sss.in_numbers(arr, 49937119214509114343548691117920141602615245118674498473442528546336026425464))
38
+ # rs = sss.merge_int_to_string(arr)
39
+ # puts(rs)
40
+ # puts(rs.length)
41
+
42
+ # Test1
43
+ s = "nghiatcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
44
+ puts s
45
+ puts s.length
46
+ # creates a set of shares
47
+ arr = sss.create(3, 6, s)
48
+ # puts "================== arr"
49
+ # puts arr
50
+ # puts "=================="
51
+ # combines shares into secret
52
+ s1 = sss.combine(arr[0...3])
53
+ puts s1
54
+ puts s1.length
55
+
56
+ s2 = sss.combine(arr[3...6])
57
+ puts s2
58
+ puts s2.length
59
+
60
+ s3 = sss.combine(arr[1...5])
61
+ puts s3
62
+ puts s3.length
63
+
64
+ # # Test2
65
+ # s = "nghiatcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
66
+ # puts s
67
+ # puts s.length
68
+ # # creates a set of shares
69
+ # arr = [
70
+ # "cac78fd8a2491872833bf9049cb91f706ae7c6619c8dcd11d2b93db1a42610c8d16221744779f7d1df1152d128f1c4e665fcc7d5f9c5da8c5a3954795d14e7fa882ede5e95cc86c133369f0069086a84e7dfa36a8004f6365eebc798ac467f988c5063932ea32066270dc4c18da124f7593ef71491c9e6d7b838f33524449f47c64902a4bd32d020691044daa01dbbfdc7b3a5e8fb20d546e3eac08986e50449ef4340426e494113245e49f672151e86b9da58e122673665a807cc1c04dbe7bc0151a94de40f618b470d73f90b93ede1b7d1611b6f6cb020d9ec12cd7d7bfd471f108d6caa60e3e4c933c78863ed9b8672a37270909ceca95f16e6d3f3dde55f",
71
+ # "173a962eac9997a9cbd24fa9f664c7a4e90134985344d80332d52b099fa7dfb16ada3209a95af9732b197b1b9bd9067b5f8a0053635a4bc538d60d626576fb1d2ceb4145d68125447c7716a72db869abbe56d649f53e47316bcf9ce165008a93c03ca42840f92ff5c35433375ddf3bbcbf2a8cdffdd475c9c20733b278121adec6d35a0bc80bee9311f814bea1d9783981e042f210d459e8818df76f8b541a72825274df2d5ac29e0074396e7922849d663acdd84919e113dad867a8257d571d3f8e3644dfe790f6f0192fcad5c8735ee4658de1ae03285d721d92119aafc77ffcd9bc7e80da7b47c12ae8cfc730f397cd8533889d4fc96e7f0d4d5fc49d3db9",
72
+ # "d64848bb07b603d7f882017750c260b4c9fc067dbe97bc49903e7e9a80314dd5d77398b0adcc2e6dbba02e166f93cc15f5b0cdf982abe0879ba1f530d70c9aae0e2fd6764b88616a92c5a3e1b470c19ae94b34284343a106482c15a19381a164bdd3952c55576ad95687100c59dc857b78dfc436ce7f8525420ae273ca58619df6f952772b2e0a785a10c24b77791208bcb6d0ab8c874e7b3f53e522b50855d01566b9f20d4a69136afd25f6cbf127c34650552bf1e1b2885b83fc8fe42bbbc5c3be42dec0b98b4d72a6ff118ca4c49a3055b4bdf7b1e251f7ee61d94fc04bd6d7562dd210d806911ba055ff1f5100808cf350922d4d527058112ac36ea098a2",
73
+ # "18ad9f41e1a4076fa139da699624686a32b9388cd8931c0f9278ae705ef6693c072d1d4885034672127061f2ce28e3af65c0bcd45024420adaa9df15f6ecee61cf586adcdc7a18981d85ca0ffbd58ad4b82ab15dabf0729aa7d99ce0b4013f3b7318d191cd1450fbea27488e0c4043ba2dfcfc484bdab19cb72b389bcc947c38a1d8cabe59f8f6ce7e878a4c250996835806a354fb4a177510f6a5f2a603686f3e3e9b6c82a8073ad96f49ea5ca470ef6e560a55e74699221df3953ce8747ea461ec0d9d7435eb9526a9a73e5181873c8a05b6711314902af4cf0a9bc69336e818684510273d27752ff0b2b2977f46573033a95b77fe99e004f726633070d1b8",
74
+ # "188fd844683b4f1f3b65f03ae4624166a7f7378129c946ed9bbcb5cc23c6b77e5325340b89656394711c25c5500bcc789105ee4bbc9f1c8a3a90d261d8c29feda7647cdf1f88c918a4a4afe5af0e8820c779b3b98540571a2f8603996a0dfb8c1bce6440a7f07288fedc9fa66f86548b8ca521efd3df208fe8a3118b929ebed88db91d5a85d54974742764b7a3709699aad5c3933b9b769bc02f8d27f25ea2df5d73c4607dad720b57e07454f58327e6bf55a833fa5f012a6b7012ef5d0cd4ab7ca9871107ac2a17235d925dd7fd767aa0115d4c5c7b73fe165718895401cf58ec830f95dd4af709064a1c5737b9378775f95c41d078aca3701d50296df1a0af",
75
+ # "5d486655b69532b179d825639fe8648cfe468719211f52d35fc9facd8c8572b33e6206aeb819dd96b22f6ade3533f502e1015ca765a236e7ddedf8b5a95bb7f4fa5b1fce132f7ca624a4d4f2adf14e7c31487a35a4685552e2ab149510c4c11a8c6bb5fa21b058b7de597abbe9ddbb178f293ddd07ee15304618b4855696e180e1afae690e15b623941bf719289ea5e72fa597aeb77b133ce409c5cca4e2a5125f1d7e8f085eb5341ba5eab68f80e7382d52a3145dd3c357ddcf2f883e4acf3324a5ab08ad2fb76d22500581d2aa496938ef650f52af5fbb7aae4779f436101a950953cf77433cb6fafa8c0346c716d456e988b4e05861a239bf643860a7340a",
76
+ # ]
77
+ # # puts "================== arr"
78
+ # # puts arr
79
+ # # puts "=================="
80
+ # # combines shares into secret
81
+ # s1 = sss.combine(arr[0...3])
82
+ # puts s1
83
+ # puts s1.length
84
+ #
85
+ # s2 = sss.combine(arr[3...6])
86
+ # puts s2
87
+ # puts s2.length
88
+ #
89
+ # s3 = sss.combine(arr[1...5])
90
+ # puts s3
91
+ # puts s3.length
@@ -0,0 +1,9 @@
1
+ require "./rcrypto/version"
2
+ require 'awesome_print' if ENV['USE_AWESOME_PRINT'] == 'true'
3
+
4
+ module Rcrypto
5
+ require './rcrypto/sss'
6
+ require './rcrypto/base_error'
7
+ extend self
8
+ end
9
+
@@ -0,0 +1,16 @@
1
+ module Rcrypto
2
+ class BaseError < StandardError
3
+ def initialize(error, cause = nil)
4
+ @error = error
5
+ @cause = cause
6
+ end
7
+
8
+ def to_s
9
+ if !!@cause
10
+ JSON[error: @error, cause: @cause] rescue {error: @error, cause: @cause}.to_s
11
+ else
12
+ JSON[@error] rescue @error
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,364 @@
1
+ require 'base64'
2
+
3
+ module Rcrypto
4
+ class SSS
5
+ # The largest PRIME 256-bit big.Int
6
+ # https://primes.utm.edu/lists/2small/200bit.html
7
+ # PRIME = 2^n - k = 2^256 - 189
8
+ @@prime = 115792089237316195423570985008687907853269984665640564039457584007913129639747
9
+
10
+ # Returns a random number from the range (0, PRIME-1) inclusive
11
+ def random_number
12
+ rand(1...@@prime)
13
+ end
14
+
15
+ # extended gcd
16
+ def egcd(a, b)
17
+ if a == 0
18
+ return b, 0, 1
19
+ else
20
+ g, y, x = egcd(b % a, a)
21
+ return g, x - (b / a) * y, y
22
+ end
23
+ end
24
+
25
+ # Computes the multiplicative inverse of the number on the field PRIME.
26
+ def modinv(a, m)
27
+ g, x, y = egcd(a, m)
28
+ if g != 1
29
+ raise Exception('modular inverse does not exist')
30
+ else
31
+ return x % m
32
+ end
33
+ end
34
+
35
+ # Convert string to hex.
36
+ def hexlify(s)
37
+ a = []
38
+ if s.respond_to? :each_byte
39
+ s.each_byte { |b| a << sprintf('%02X', b) }
40
+ else
41
+ s.each { |b| a << sprintf('%02X', b) }
42
+ end
43
+ a.join.downcase
44
+ end
45
+
46
+ # Convert hex to string.
47
+ def unhexlify(s)
48
+ s.split.pack('H*')
49
+ end
50
+
51
+ # Returns the Int number base10 in base64 representation; note: this is
52
+ # not a string representation; the base64 output is exactly 256 bits long.
53
+ def to_base64(number)
54
+ hexdata = number.to_s(16)
55
+ n = 64 - hexdata.length
56
+ i = 0
57
+ while i < n
58
+ hexdata = '0' + hexdata
59
+ i += 1
60
+ end
61
+ b64data = Base64.urlsafe_encode64(hexdata)
62
+ b64data
63
+ end
64
+
65
+ # Returns the number base64 in base 10 Int representation; note: this is
66
+ # not coming from a string representation; the base64 input is exactly 256
67
+ # bits long, and the output is an arbitrary size base 10 integer.
68
+ def from_base64(number)
69
+ hexdata = Base64.urlsafe_decode64(number)
70
+ rs = hexdata.to_i(16)
71
+ rs
72
+ end
73
+
74
+ # Returns the Int number base10 in Hex representation; note: this is
75
+ # not a string representation; the Hex output is exactly 256 bits long.
76
+ def to_hex(number)
77
+ hexdata = number.to_s(16)
78
+ # puts hexdata
79
+ n = 64 - hexdata.length
80
+ i = 0
81
+ while i < n
82
+ hexdata = '0' + hexdata
83
+ i += 1
84
+ end
85
+ hexdata
86
+ end
87
+
88
+ # Returns the number Hex in base 10 Int representation; note: this is
89
+ # not coming from a string representation; the Hex input is exactly 256
90
+ # bits long, and the output is an arbitrary size base 10 integer.
91
+ def from_hex(number)
92
+ rs = number.to_i(16)
93
+ rs
94
+ end
95
+
96
+ # Evaluates a polynomial with coefficients specified in reverse order:
97
+ # evaluatePolynomial([a, b, c, d], x):
98
+ # return a + bx + cx^2 + dx^3
99
+ # Horner's method: ((dx + c)x + b)x + a
100
+ def evaluate_polynomial(polynomial, part, value)
101
+ last = polynomial[part].length - 1
102
+ result = polynomial[part][last]
103
+ s = last - 1
104
+ while s >= 0
105
+ result = (result * value + polynomial[part][s]) % @@prime
106
+ s -= 1
107
+ end
108
+ result
109
+ end
110
+
111
+ # Converts a byte array into an a 256-bit Int, array based upon size of
112
+ # the input byte; all values are right-padded to length 256, even if the most
113
+ # significant bit is zero.
114
+ def split_secret_to_int(secret)
115
+ result = []
116
+ hex_data = hexlify(secret)
117
+ count = (hex_data.length / 64.0).ceil
118
+ i = 0
119
+ while i < count
120
+ if (i + 1) * 64 < hex_data.length
121
+ subs = hex_data[i * 64...(i + 1) * 64]
122
+ result.append(subs.to_i(16))
123
+ else
124
+ last = hex_data[i * 64...hex_data.length]
125
+ n = 64 - last.length
126
+ j = 0
127
+ while j < n
128
+ last += '0'
129
+ j += 1
130
+ end
131
+ result.append(last.to_i(16))
132
+ end
133
+ i += 1
134
+ end
135
+ result
136
+ end
137
+
138
+ def trim_right(s)
139
+ i = s.length - 1
140
+ while i >= 0 && s[i] == '0'
141
+ i -= 1
142
+ end
143
+ rs = s[0..i]
144
+ rs
145
+ end
146
+
147
+ # Converts an array of Ints to the original byte array, removing any
148
+ # least significant nulls.
149
+ def merge_int_to_string(secrets)
150
+ hex_data = ""
151
+ for s in secrets
152
+ tmp = to_hex(s)
153
+ hex_data += tmp
154
+ end
155
+ hex_data = unhexlify(trim_right(hex_data))
156
+ hex_data
157
+ end
158
+
159
+ # in_numbers(numbers, value) returns boolean whether or not value is in array
160
+ def in_numbers(numbers, value)
161
+ for n in numbers
162
+ if n == value
163
+ return true
164
+ end
165
+ end
166
+ return false
167
+ end
168
+
169
+ # Returns a new array of secret shares (encoding x,y pairs as Base64 or Hex strings)
170
+ # created by Shamir's Secret Sharing Algorithm requiring a minimum number of
171
+ # share to recreate, of length shares, from the input secret raw as a string.
172
+ def create(minimum, shares, secret)
173
+ result = []
174
+
175
+ # Verify minimum isn't greater than shares; there is no way to recreate
176
+ # the original polynomial in our current setup, therefore it doesn't make
177
+ # sense to generate fewer shares than are needed to reconstruct the secrets.
178
+ if minimum > shares
179
+ raise Exception('cannot require more shares then existing')
180
+ end
181
+
182
+ # Convert the secrets to its respective 256-bit Int representation.
183
+ secrets = split_secret_to_int(secret)
184
+
185
+ # List of currently used numbers in the polynomial
186
+ numbers = [0]
187
+
188
+ # Create the polynomial of degree (minimum - 1); that is, the highest
189
+ # order term is (minimum-1), though as there is a constant term with
190
+ # order 0, there are (minimum) number of coefficients.
191
+ #
192
+ # However, the polynomial object is a 2d array, because we are constructing
193
+ # a different polynomial for each part of the secrets.
194
+ #
195
+ # polynomial[parts][minimum]
196
+ polynomial = []
197
+ for i in 0...secrets.length
198
+ subpoly = []
199
+ subpoly.push(secrets[i])
200
+ j = 1
201
+ while j < minimum
202
+ # Each coefficient should be unique
203
+ number = random_number()
204
+ while in_numbers(numbers, number)
205
+ number = random_number()
206
+ end
207
+
208
+ numbers.append(number)
209
+ subpoly.push(number)
210
+ j += 1
211
+ end
212
+ polynomial.push(subpoly)
213
+ end
214
+
215
+ # Create the points object; this holds the (x, y) points of each share.
216
+ # Again, because secrets is an array, each share could have multiple parts
217
+ # over which we are computing Shamir's Algorithm. The last dimension is
218
+ # always two, as it is storing an x, y pair of points.
219
+ #
220
+ # Note: this array is technically unnecessary due to creating result
221
+ # in the inner loop. Can disappear later if desired.
222
+ #
223
+ # points[shares][parts][2]
224
+ points = []
225
+ for i in 0...shares
226
+ s = ''
227
+ arrsh = []
228
+ for j in 0...secrets.length
229
+ arrxy = []
230
+ # generate a new x-coordinate.
231
+ number = random_number()
232
+ while in_numbers(numbers, number)
233
+ number = random_number()
234
+ end
235
+ x = number
236
+ y = evaluate_polynomial(polynomial, j, number)
237
+ arrxy.push(x)
238
+ arrxy.push(y)
239
+ s += to_hex(x)
240
+ s += to_hex(y)
241
+ arrsh.push(arrxy)
242
+ end
243
+ points.push(arrsh)
244
+ result.push(s)
245
+ end
246
+ result
247
+ end
248
+
249
+ # akes a string array of shares encoded in Hex created via Shamir's
250
+ # Algorithm; each string must be of equal length of a multiple of 128 characters
251
+ # as a single 128 character share is a pair of 256-bit numbers (x, y).
252
+ def decode_share_hex(shares)
253
+ # Recreate the original object of x, y points, based upon number of shares
254
+ # and size of each share (number of parts in the secret).
255
+ secrets = []
256
+
257
+ # For each share...
258
+ for i in 0...shares.length
259
+ # ensure that it is valid.
260
+ unless is_valid_share_hex(shares[i])
261
+ raise Exception('one of the shares is invalid')
262
+ end
263
+
264
+ # find the number of parts it represents.
265
+ share = shares[i]
266
+ count = share.length / 128
267
+ arrsh = []
268
+ # and for each part, find the x,y pair...
269
+ for j in 0...count
270
+ cshare = share[j * 128...(j + 1) * 128]
271
+ arrxy = []
272
+ # decoding from Base64.
273
+ x = from_hex(cshare[0...64])
274
+ y = from_hex(cshare[64...128])
275
+ arrxy.push(x)
276
+ arrxy.push(y)
277
+ arrsh.push(arrxy)
278
+ end
279
+ secrets.push(arrsh)
280
+ end
281
+ secrets
282
+ end
283
+
284
+ # Takes in a given string to check if it is a valid secret
285
+ #
286
+ # Requirements:
287
+ # Length multiple of 128
288
+ # Can decode each 64 character block as Hex
289
+ #
290
+ # Returns only success/failure (bool)
291
+ def is_valid_share_hex(candidate)
292
+ if candidate.length == 0 || candidate.length % 128 != 0
293
+ return false
294
+ end
295
+ count = candidate.length / 64
296
+ j = 0
297
+ while j < count
298
+ part = candidate[j * 64...(j + 1) * 64]
299
+ decode = from_hex(part)
300
+ if decode < 0 || decode == @@prime
301
+ return false
302
+ end
303
+ j += 1
304
+ end
305
+ return true
306
+ end
307
+
308
+ # Takes a string array of shares encoded in Base64 or Hex created via Shamir's Algorithm
309
+ # Note: the polynomial will converge if the specified minimum number of shares
310
+ # or more are passed to this function. Passing thus does not affect it
311
+ # Passing fewer however, simply means that the returned secret is wrong.
312
+ def combine(shares)
313
+ if shares.empty?
314
+ raise Exception('shares is NULL or empty')
315
+ end
316
+
317
+ # Recreate the original object of x, y points, based upon number of shares
318
+ # and size of each share (number of parts in the secret).
319
+ #
320
+ # points[shares][parts][2]
321
+ points = decode_share_hex(shares)
322
+ # puts points
323
+
324
+ # Use Lagrange Polynomial Interpolation (LPI) to reconstruct the secrets.
325
+ # For each part of the secrets (clearest to iterate over)...
326
+ secrets = []
327
+ for j in 0...(points[0]).length
328
+ secrets.append(0)
329
+ # and every share...
330
+ for i in 0...shares.length # LPI sum loop
331
+ # remember the current x and y values.
332
+ ax = points[i][j][0] # ax
333
+ ay = points[i][j][1] # ay
334
+ numerator = 1 # LPI numerator
335
+ denominator = 1 # LPI denominator
336
+ # and for every other point...
337
+ for k in 0...shares.length # LPI product loop
338
+ if k != i
339
+ # combine them via half products.
340
+ # x=0 ==> [(0-bx)/(ax-bx)] * ...
341
+ bx = points[k][j][0] # bx
342
+ negbx = -bx # (0 - bx)
343
+ axbx = ax - bx # (ax - bx)
344
+
345
+ numerator = (numerator * negbx) % @@prime # (0 - bx) * ...
346
+ denominator = (denominator * axbx) % @@prime # (ax - bx) * ...
347
+ end
348
+ end
349
+ # LPI product: x=0, y = ay * [(x-bx)/(ax-bx)] * ...
350
+ # multiply together the points (ay)(numerator)(denominator)^-1 ...
351
+ fx = ay
352
+ fx = (fx * numerator) % @@prime
353
+ fx = (fx * modinv(denominator, @@prime)) % @@prime
354
+
355
+ # LPI sum: s = fx + fx + ...
356
+ secrets[j] = (secrets[j] + fx) % @@prime
357
+ end
358
+ end
359
+ rs = merge_int_to_string(secrets)
360
+ rs
361
+ end
362
+
363
+ end
364
+ end
@@ -0,0 +1,4 @@
1
+ module Rcrypto
2
+ VERSION = "0.0.1"
3
+ end
4
+
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rcrypto/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ntc-rcrypto"
8
+ spec.version = Rcrypto::VERSION
9
+ spec.authors = ["nghiatc"]
10
+ spec.email = ["congnghia0609@gmail.com"]
11
+
12
+ spec.summary = %q{ntc-rcrypto ruby cryptography.}
13
+ spec.description = %q{ntc-rcrypto is module ruby cryptography.}
14
+ spec.homepage = "https://github.com/congnghia0609/ntc-rcrypto"
15
+ spec.license = 'Apache-2.0'
16
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
17
+
18
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
19
+
20
+ spec.metadata["homepage_uri"] = spec.homepage
21
+ spec.metadata["source_code_uri"] = "https://github.com/congnghia0609/ntc-rcrypto"
22
+ spec.metadata["changelog_uri"] = "https://github.com/congnghia0609/ntc-rcrypto"
23
+
24
+ # Specify which files should be added to the gem when it is released.
25
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
26
+ # spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
27
+ # `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
28
+ # end
29
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
30
+ spec.bindir = "exe"
31
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
+ spec.require_paths = ["lib"]
33
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ntc-rcrypto
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - nghiatc
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-03-17 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: ntc-rcrypto is module ruby cryptography.
14
+ email:
15
+ - congnghia0609@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".gitignore"
21
+ - ".travis.yml"
22
+ - CODE_OF_CONDUCT.md
23
+ - Gemfile
24
+ - Gemfile.lock
25
+ - LICENSE
26
+ - README.md
27
+ - Rakefile
28
+ - bin/console
29
+ - bin/setup
30
+ - lib/main.rb
31
+ - lib/rcrypto.rb
32
+ - lib/rcrypto/base_error.rb
33
+ - lib/rcrypto/sss.rb
34
+ - lib/rcrypto/version.rb
35
+ - rcrypto.gemspec
36
+ homepage: https://github.com/congnghia0609/ntc-rcrypto
37
+ licenses:
38
+ - Apache-2.0
39
+ metadata:
40
+ homepage_uri: https://github.com/congnghia0609/ntc-rcrypto
41
+ source_code_uri: https://github.com/congnghia0609/ntc-rcrypto
42
+ changelog_uri: https://github.com/congnghia0609/ntc-rcrypto
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: 2.3.0
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubygems_version: 3.1.2
59
+ signing_key:
60
+ specification_version: 4
61
+ summary: ntc-rcrypto ruby cryptography.
62
+ test_files: []