ed25519_keccak 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: cdf41b928a7a1cabbc5fe971f10780d30a5c34bcbb897888228ff358378e2c45
4
+ data.tar.gz: 0b51e3684ce71200530d33bef85a401ba53d59d00b97a994b60fc9ec11fb6049
5
+ SHA512:
6
+ metadata.gz: a0fa6396ec42ac850d31e5bd1c069560cfb949056fb191b0bc439b959fe43cf06cea1deef13bc6fe344c92eaf544c7bb4a780f15b52187b1374ef2773546189c
7
+ data.tar.gz: 167fa9dbe0133dd213cc9fb31fb04468ab0b715b04f2fc7711e42b939adab34127ce55a92ce6955149113f31c06592551b3c955518af5de7d8eff9751e8b16bd
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.4.0
7
+ before_install: gem install bundler -v 1.16.6
@@ -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 mijinco1024@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 [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in ed25519_keccak.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,39 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ed25519_keccak (0.1.0)
5
+ digest-sha3-patched (~> 1.1.1)
6
+ sha3 (~> 1.0.1)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ diff-lcs (1.3)
12
+ digest-sha3-patched (1.1.1)
13
+ rake (10.5.0)
14
+ rspec (3.8.0)
15
+ rspec-core (~> 3.8.0)
16
+ rspec-expectations (~> 3.8.0)
17
+ rspec-mocks (~> 3.8.0)
18
+ rspec-core (3.8.0)
19
+ rspec-support (~> 3.8.0)
20
+ rspec-expectations (3.8.2)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.8.0)
23
+ rspec-mocks (3.8.0)
24
+ diff-lcs (>= 1.2.0, < 2.0)
25
+ rspec-support (~> 3.8.0)
26
+ rspec-support (3.8.0)
27
+ sha3 (1.0.1)
28
+
29
+ PLATFORMS
30
+ ruby
31
+
32
+ DEPENDENCIES
33
+ bundler (~> 1.16)
34
+ ed25519_keccak!
35
+ rake (~> 10.0)
36
+ rspec (~> 3.0)
37
+
38
+ BUNDLED WITH
39
+ 1.16.6
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 mijinc0
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
13
+ all 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
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,246 @@
1
+ # Ed25519Keccak
2
+
3
+ ![draft1](images/README_draft1.png)
4
+
5
+ If you want to view full diagram of ed25519, please see to "/images/ed25519_algorithm.png".
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'ed25519_keccak'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install ed25519_keccak
22
+
23
+ ## Usage
24
+
25
+ You can sign with a `32`byte private key and verify the signature.
26
+
27
+ You can choose `Ed25519Keccak::Keccak512` or `Ed25519Keccak::SHA3_512` to sign and verify.
28
+ These signature / validation functions are the same for the signature algorithm. However, the hash function used in the signature algorithm is different.
29
+
30
+ ```
31
+ Keccak512("")
32
+ >> 0x 0eab42de4c3ceb9235fc91ac...
33
+
34
+ SHA3-512("")
35
+ >> 0x a69f73cca23a9ac5c8b567dc...
36
+
37
+ [SHA 3 is based on Keccak, but these outputs are different from each other.]
38
+ ```
39
+
40
+ This implementation is a rewrite of python codes on `RFC8032` as ruby.
41
+ https://tools.ietf.org/html/rfc8032
42
+
43
+ #### Sign
44
+
45
+ `Keccak512`
46
+
47
+ ```ruby
48
+ require "ed25519_keccak"
49
+ require "securerandom"
50
+
51
+ # signed massage data "0x0702"
52
+ message = ["0702"].pack("H*")
53
+
54
+ # secret should be 32byte
55
+ secret = SecureRandom.bytes(32)
56
+
57
+ ed25519_keccak = Ed25519Keccak::Keccak512.new
58
+
59
+ # create a signature as a byte-string
60
+ #
61
+ # first arg : secret (privatekey)
62
+ # second arg : message
63
+ # return : sigunature (byte string)
64
+ sigunature = ed25519_keccak.sign( secret , message )
65
+ ```
66
+
67
+ `SHA3 512`
68
+
69
+ ```ruby
70
+ require "ed25519_keccak"
71
+ require "securerandom"
72
+
73
+ message = ["0702"].pack("H*")
74
+
75
+ secret = SecureRandom.bytes(32)
76
+
77
+ # when you want to use SHA3_512 hash function
78
+ ed25519_sha3 = Ed25519Keccak::SHA3_512.new
79
+
80
+ sigunature = ed25519_sha3.sign( secret , message )
81
+
82
+ puts(sigunature)
83
+ ```
84
+
85
+ And you can use `:hex` format mode.
86
+
87
+ `Keccak512`
88
+
89
+ ```ruby
90
+ require "ed25519_keccak"
91
+ require "securerandom"
92
+
93
+ # massage data "0x0702"
94
+ message = "0702"
95
+
96
+ # secret should be 32byte
97
+ secret = SecureRandom.hex(32)
98
+
99
+ ed25519_keccak = Ed25519Keccak::Keccak512.new
100
+
101
+ # create a signature as a byte-string
102
+ #
103
+ # first arg : secret (privatekey)
104
+ # second arg : message
105
+ # third arg : :hex
106
+ # return : sigunature (byte string)
107
+ sigunature = ed25519_keccak.sign( secret , message, :hex )
108
+
109
+ puts(sigunature)
110
+ # >> "d71a72e7af781b5b85090b9b3a8f9e4052f58f93580e2304fd3d52e09e45ac51"
111
+ # return hex-string of signature
112
+ ```
113
+
114
+ `SHA3 512`
115
+
116
+ ```ruby
117
+ require "ed25519_keccak"
118
+ require "securerandom"
119
+
120
+ message = "0702"
121
+
122
+ secret = SecureRandom.hex(32)
123
+
124
+ ed25519_sha3 = Ed25519Keccak::SHA3_512.new
125
+
126
+ sigunature = ed25519_sha3.sign( secret , message, :hex )
127
+ ```
128
+
129
+ #### Verify
130
+
131
+ `Keccak512`
132
+
133
+ ```ruby
134
+ require "ed25519_keccak"
135
+
136
+ publickey = ["8A558C728C21C126181E5E654B404A45B4F0137CE88177435A69978CC6BEC1F4"].pack("H*")
137
+ message = ["8ce03cd60514233b86789729102ea09e867fc6d964dea8c2018ef7d0a2e0e24bf7e348e917116690b9"].pack("H*")
138
+ signature = ["D9CEC0CC0E3465FAB229F8E1D6DB68AB9CC99A18CB0435F70DEB6100948576CD5C0AA1FEB550BDD8693EF81EB10A556A622DB1F9301986827B96716A7134230C"].pack("H*")
139
+
140
+ ed25519_keccak512 = Ed25519Keccak::Keccak512.new
141
+
142
+ # first arg : publickey
143
+ # second arg : message
144
+ # third arg : sigunature
145
+ # return : success=>true , failed=>false
146
+ is_verify = ed25519_keccak512.verify( publickey , message , signature )
147
+
148
+ puts( is_verify )
149
+ # >> true
150
+ ```
151
+
152
+ `SHA3 512`
153
+
154
+ ```ruby
155
+ require "ed25519_keccak"
156
+
157
+ publickey = ["53C659B47C176A70EB228DE5C0A0FF391282C96640C2A42CD5BBD0982176AB1B"].pack("H*")
158
+ message = ["8ce03cd60514233b86789729102ea09e867fc6d964dea8c2018ef7d0a2e0e24bf7e348e917116690b9"].pack("H*")
159
+ signature = ["C9B1342EAB27E906567586803DA265CC15CCACA411E0AEF44508595ACBC47600D02527F2EED9AB3F28C856D27E30C3808AF7F22F5F243DE698182D373A9ADE03"].pack("H*")
160
+
161
+ ed25519_sha3 = Ed25519Keccak::SHA3_512.new
162
+
163
+ # create a signature as a byte-string
164
+ #
165
+ # first arg : publickey
166
+ # second arg : message
167
+ # third arg : sigunature
168
+ # return : success=>true , failed=>false
169
+ is_verify = ed25519_sha3.verify( publickey , message , signature )
170
+
171
+ puts( is_verify )
172
+ # >> true
173
+ ```
174
+
175
+ You can use `:hex` format mode just as you signed.
176
+
177
+ #### Calculate publickey from secret (privatekey)
178
+
179
+ `Keccak512`
180
+
181
+ ```ruby
182
+ require "ed25519_keccak"
183
+
184
+ secret = ["8D31B712AB28D49591EAF5066E9E967B44507FC19C3D54D742F7B3A255CFF4AB"].pack("H*")
185
+
186
+ ed25519_keccak = Ed25519Keccak::Keccak512.new
187
+
188
+ publickey = ed25519_keccak.secret_to_public( secret )
189
+ ```
190
+
191
+ `SHA3 512`
192
+
193
+ ```ruby
194
+ require "ed25519_keccak"
195
+
196
+ secret = ["8D31B712AB28D49591EAF5066E9E967B44507FC19C3D54D742F7B3A255CFF4AB"].pack("H*")
197
+
198
+ ed25519_sha3 = Ed25519Keccak::SHA3_512.new
199
+
200
+ publickey = ed25519_sha3.secret_to_public( secret )
201
+ ```
202
+
203
+ `:hex` format mode...
204
+
205
+ ```ruby
206
+ require "ed25519_keccak"
207
+
208
+ secret = "8D31B712AB28D49591EAF5066E9E967B44507FC19C3D54D742F7B3A255CFF4AB"
209
+
210
+ ed25519_keccak = Ed25519Keccak::Keccak512.new
211
+
212
+ publickey = ed25519_keccak.secret_to_public( secret, :hex )
213
+
214
+ puts( publickey )
215
+ # >> 8a558c728c21c126181e5e654b404a45b4f0137ce88177435a69978cc6bec1f4
216
+ ```
217
+
218
+ ## Dependencies
219
+
220
+ This gem depends on gems below.
221
+
222
+ **keccak**
223
+ 'digest-sha3-patched', '~> 1.1.1'
224
+
225
+ **sha3(FIPS202)**
226
+ "sha3","~> 1.0.1"
227
+
228
+ ___Thank you for your development.___
229
+
230
+ ## Development
231
+
232
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
233
+
234
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
235
+
236
+ ## Contributing
237
+
238
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/ed25519_keccak. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
239
+
240
+ ## License
241
+
242
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
243
+
244
+ ## Code of Conduct
245
+
246
+ Everyone interacting in the Ed25519Keccak project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/ed25519_keccak/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ed25519_keccak"
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__)
data/bin/setup ADDED
@@ -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,45 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "ed25519_keccak/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ed25519_keccak"
8
+ spec.version = Ed25519Keccak::VERSION
9
+ spec.authors = ["mijinc0"]
10
+ spec.email = ["mijinco1024@gmail.com"]
11
+
12
+ spec.summary = %q{sign/verify ed25519. but use keccak/sha3 as a hash function}
13
+ spec.description = %q{This is a signature and verification library of ed 25519. But instead of SHA2_512, Keccak is adopted as a hash function. This implementation is a rewrite of python codes on RFC8032 as ruby.}
14
+ spec.homepage = "https://github.com/mijinc0"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata["homepage_uri"] = spec.homepage
21
+ spec.metadata["source_code_uri"] = "https://github.com/mijinc0/ed25519_keccak"
22
+ spec.metadata["changelog_uri"] = "https://github.com/mijinc0/ed25519_keccak"
23
+ else
24
+ raise "RubyGems 2.0 or newer is required to protect against " \
25
+ "public gem pushes."
26
+ end
27
+
28
+ # Specify which files should be added to the gem when it is released.
29
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
30
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
31
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
32
+ end
33
+ spec.bindir = "exe"
34
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
35
+ spec.require_paths = ["lib"]
36
+
37
+ spec.add_development_dependency "bundler", "~> 1.16"
38
+ spec.add_development_dependency "rake", "~> 10.0"
39
+ spec.add_development_dependency "rspec", "~> 3.0"
40
+
41
+ # keccak512
42
+ spec.add_dependency 'digest-sha3-patched', '~> 1.1.1'
43
+ # sha3(FIPS202)
44
+ spec.add_dependency "sha3","~> 1.0.1"
45
+ end
Binary file
@@ -0,0 +1 @@
1
+ <mxfile modified="2018-12-02T07:18:09.547Z" host="www.draw.io" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36" etag="ed7a3419-392d-d5d6-28c9-9a87bd26c2c7" version="9.5.1" type="device"><diagram id="f6abf084-93fc-b41f-b3e4-3ea5eded94d1" name="Page-1">7V3dc5s4EP9rMnP34AySEB+PSdqmD72bm6Yzd32UQba5YuQDnI/7608CyXyIJg0Hluw0nY7NIhDS7m93tbvCF+hm+3ibk93mNxbT9AI68eMFencBIQChxz8E5amm4BDUhHWexLJRQ7hL/qWS6EjqPolp0WlYMpaWya5LjFiW0ajs0Eies4dusxVLu73uyJpqhLuIpDr1zyQuNzU1gH5D/0iT9Ub1DLywPrMlqrEcSbEhMXtokdD7C3STM1bW37aPNzQVk6fmpb7uw3fOHh4sp1n5IxcsXeoDFPoLsFrBBQAOWGAcokUMPLT0gONAN1ggeduifFIzQGM+IfKQ5eWGrVlG0vcN9Tpn+yymohuHH23Kbcq/Av6VP1n+9JegX2J1+FU2+5uW5ZPkN9mXjJOau39ibCfvoQ9TPSLb5xF9xdiU+JB8TctXXAfr68Q8tB5ATvItZVvKh8Ub5DQlZXLfFRwi5W99aNewiH+RXPofHJP93JN0L3u+gF7Kx3e9YnzGuMgTOUveP3sha9e3JCdblsUNhX9by8/2lY0QqIbixKKomHbFGwB396jfpaBRTsX1v/D/39Q9+WDr207ZFf8kWy4p19myEB/LRNzs1xf61Mg9iW/kWQjgwyYp6d2unsUHruW6Mr5K0vSGpSyvrkUrLP6JWShz9o22znjVnxxZi17/Ha5QWgY9J/v3NC/p47PSKM8iR6ofqX9defjQKDOgNNSmpciQcyT5RXBKjXN8rQJHahVktVaBM2iVYkey8VD/SIrNh30WlQnLpG6BXLk4HPILti93+z7y6+6Oh/yY0GAVDSI/CuhyNYhwkkdSWrEzDeAhwh3AAwdriIfYKOLxaSMejUW83ZBHGuQF5N6RknAqW4mZaht2Bb4adWdsQYHXtaDA0wHlOiYB5bqnDSh3JKB8q/Hkanj6RFcCLhuSCjTFNbKkkzwPlFbUiwZNUuyHS8eZCzJuFzH873LACBnFDJ7U7WwWup1lbrXqPT6e8Eg8AbsBhTVAfa4E55iIijENYncIUQFcoso4zYOoE4CUe+J+nT8SNoHVqPE11BSVDyd6gU6UUpJXk7WlB8hUzp4wVgsBrEUNK1s9vBlWUF2oITgANNco0AITQKOPSdmK5fKjr5NDMBhrueyO0fq+EYY945SYZ5lC1XQsk5f+wZIqQvXYRaVEsw97KK0fXF7U8P0qz8lTq9lONCh+uBsXuO27vfhUMmvUCF3dfyOChwmZTioDzTLs8uSelMIQFBFJK8NQnXBIP9CuAmrLfJ4ouqGFi98Plg9Ey4dUPwyP5QM72jwbzs8dwywo9f56u+BabRfUuFoQ3O5Fbjt9eksOV9iNWLsDAbbQaKxgUn9riljBUUA3NiwH7XbGgB6Y2+2XaRKJsAF9amze7eHr1bRoDCI6bNyWAXbxbMYNd2GGXV83br7RxNBMOLOi+ORcg3LeLDwD43WjBTybXgOOWpP4YS9zhXsVYi+095CBVQnQw7y/0aIQZXrWukQTKGfP6aXtke4EHWhmok6TlgYaQLM3VgPbHeBV4/pZq3NytTpur7QADVTnma3Vca2LN0yoEMYmfBTibFUIesonYllESppVwT1brej0+PJAL2vqD8TzoEmjipFt+DpKaGF0nie0Gnl+aBs3LeAZnFxbjloMef3YvtTix13c6DmXXqYln9bPMVSugt1eSHcgkRIYDekaqVU5im4Nx+IUWK1b1bjeeK4E9wrB7EuWzGMDrQgIqtqBc6tP8WZa5Z02z+z2NdW4WvrwmhRUeT1VDR+NIcZiHE60z+/pwcm4tVdjTqAiofeyigSh0VXfpPVgdq0TDrv0zSdNpsWbvtE6bzLEn8/DbUc/kCI2WmPunXgSQgn569Fh9+ZBNa6fMUfUsz4edHUMGY05evDEMTR2Ay60uxoQ6jtwfybyTiORB0P/sms6vQAMbdAymszz50k22LE0H12tOPk+hGmVgl6t2GzLPwOXE/mwhxwfDxhMo06nP6nBtGy5NrrGze6qGKiXkb3FcDFQtQrPgMtouDg44wITOLbiDFoeetQrzkgcvyVYebBrswKk5zeNwsq3bsvKhLCypxJhWljpxQHSZCWcKc2ezAlhRgH3+/whmIWej8hsXp96Cewz8BncZ3k0/CgN3OLF3VnMvIe74anQcS6hg4MAIgxDVyUqO++2MsgHdMbbS9DYOJbdYSw0U3LrpFlmd5AB6ZFH+UqlaF++Jb8Owa5hGn7NknKuzCyY9EzLZ3GPoh77IfdfJOuMlPtcT77wuSi7TOoyI2MZ7XFOkkjKb8oPIz7DlNOvxcwm3C25kie2SRxXeB6Sii7GJ+AW7u2ZwsFAoh8PpFr67wCZj1k6sO7eKrN6u/zDoTdRm2WWHmpVKYwNUNmLu2S9V6w6pDea04oYJ/ejMzF4KBPzZSPKdyK2XSa8+zodU4mOAD8RGSDnIFll1bYlU71qoJeyNQMP/8x7XsZLKO8+SrK10N/N0ZfKbIvypmHBZFzkVmn1QwobLsA0m0NYvaDvJOtusYd0WQ2OJqt6ePO1b9SHQVfO9Ozil2RLhTz9Th+EoLFtJS3fSTQuFUEXs+VrM4Jno/Rc2HUnvAFvAqhCw7YgqQqxVwgSP2x+TKTewND8JAt6/x8=</diagram></mxfile>
Binary file
@@ -0,0 +1,4 @@
1
+ require "ed25519_keccak/version.rb"
2
+ require "ed25519_keccak/ed25519base.rb"
3
+ require "ed25519_keccak/keccak512.rb"
4
+ require "ed25519_keccak/sha3_512.rb"
@@ -0,0 +1,304 @@
1
+ ## This implementation is a rewrite of python codes on RFC8032 as ruby.
2
+ ## original : https://tools.ietf.org/html/rfc8032
3
+
4
+ module Ed25519Keccak
5
+ # base class of Ed25519
6
+ class Ed25519Base
7
+ def initialize( hash_function )
8
+ @hash_function = hash_function
9
+ end
10
+
11
+ def sign(secret, message, form=:byte)
12
+ arguments = change_arguments_format( [secret,message], form )
13
+ return change_result_format( p_sign(*arguments), form)
14
+ end
15
+
16
+ def verify(public_key, message, signature, form=:byte)
17
+ arguments = change_arguments_format( [public_key,message,signature], form )
18
+ return p_verify(*arguments)
19
+ end
20
+
21
+ # calculate public key from secret
22
+ def secret_to_public(secret, form=:byte)
23
+ publickey = p_secret_to_public( change_argument_format(secret, form) )
24
+ return change_result_format( publickey, form )
25
+ end
26
+
27
+ private
28
+ ## region arguments/result util ##
29
+
30
+ # Argument is always changed to a byte-string
31
+ # if specified format is unknown, data is not changed.
32
+ # format type is symbol
33
+ def change_argument_format( argument , form )
34
+ case form
35
+ when :hex then
36
+ return hexstr_to_bytes(argument)
37
+ end
38
+ # Other than those above : no change
39
+ return argument
40
+ end
41
+
42
+ def change_arguments_format( arguments, form )
43
+ result = []
44
+ arguments.each{ |argument| result.push( change_argument_format( argument, form) ) }
45
+ return result
46
+ end
47
+
48
+ # result_data is always byte-string
49
+ def change_result_format( result_data, form )
50
+ case form
51
+ when :hex then
52
+ return bytes_to_hexstr(result_data)
53
+ end
54
+ # Other than those above : no change
55
+ return result_data
56
+ end
57
+
58
+
59
+ ## region common util ##
60
+
61
+ def hexstr_to_bytes( hex_str )
62
+ raise ArgumentError , "hex-string length should be even" if hex_str.length.odd?
63
+ return [hex_str].pack("H*")
64
+ end
65
+
66
+ def bytes_to_hexstr( binary )
67
+ return binary.unpack("H*").first
68
+ end
69
+
70
+ # convert int to byte-string (littleEndian)
71
+ # num : unsigned number to convert to bytes
72
+ # length : byte length
73
+ def int_to_bytes( num , length )
74
+ raise ArgumentError , "num :" + num.to_s if num < 0
75
+ raise ArgumentError , "length :" + length.to_s if length < 0
76
+
77
+ hex_str = num.to_s(16)
78
+ hex_str = hex_str.rjust(length*2,"0")
79
+ return hexstr_to_bytes(hex_str).reverse[0,length]
80
+ end
81
+
82
+ # convert byte-string to int (read bytes in little endian)
83
+ def int_form_bytes(b)
84
+ return bytes_to_hexstr(b.reverse).to_i(16)
85
+ end
86
+
87
+
88
+ ## region hash function ##
89
+
90
+ def hash512(s)
91
+ return @hash_function.call(s)
92
+ end
93
+
94
+
95
+ ## region calculate mod ##
96
+
97
+ # calculate base**exponent % modulus
98
+ def pow_mod(base, exponent, modulus)
99
+ raise ArgumentError if exponent<0 || modulus<0
100
+ # result of Nmod1 is always 0
101
+ return 0 if modulus.equal? 1
102
+ result = 1
103
+ base = base % modulus
104
+ while exponent > 0
105
+ result = result*base%modulus if (exponent%2).equal? 1
106
+ exponent = exponent >> 1
107
+ base = base*base%modulus
108
+ end
109
+ return result
110
+ end
111
+
112
+ # calculate 1/x modp
113
+ def modp_inv(x)
114
+ return pow_mod(x , @@p-2 , @@p)
115
+ end
116
+
117
+ # calculate Hash(s) modp
118
+ #
119
+ def hash512_modq(s)
120
+ return int_form_bytes(hash512(s)) % @@q
121
+ end
122
+
123
+
124
+ ## region calculate point of ed25519 curve ##
125
+
126
+ # Points are represented as array [X, Y, Z, T] of extended
127
+ # coordinates, with x = X/Z, y = Y/Z, x*y = T/Z
128
+ #
129
+ # [arguments]
130
+ # pa : point A
131
+ # pb : point B
132
+ def point_add( pa , pb )
133
+ _A = (pa[1]-pa[0]) * (pb[1]-pb[0]) % @@p
134
+ _B = (pa[1]+pa[0]) * (pb[1]+pb[0]) % @@p
135
+ _C = 2 * pa[3] * pb[3] * @@d % @@p
136
+ _D = 2 * pa[2] * pb[2] % @@p
137
+ _E = _B - _A
138
+ _F = _D - _C
139
+ _G = _D + _C
140
+ _H = _B + _A
141
+ return [ _E*_F , _G*_H , _F*_G , _E*_H ]
142
+ end
143
+
144
+ # Computes pointQ = s * pointA
145
+ def point_mul(s, pa)
146
+ pq = [0, 1, 1, 0] # Neutral element
147
+ while s > 0 do
148
+ pq = point_add(pq, pa) unless (s & 1).equal? 0
149
+ pa = point_add(pa, pa)
150
+ s >>= 1
151
+ end
152
+ return pq
153
+ end
154
+
155
+ # return point A == point B
156
+ def point_equal(pa, pb)
157
+ # x1 / z1 == x2 / z2 <==> x1 * z2 == x2 * z1
158
+ return false if (pa[0] * pb[2] - pb[0] * pa[2]) % @@p != 0
159
+ return false if (pa[1] * pb[2] - pb[1] * pa[2]) % @@p != 0
160
+ return true
161
+ end
162
+
163
+
164
+ ## region point manipulation ##
165
+
166
+ # Compute corresponding x-coordinate, with low bit corresponding to
167
+ # sign, or return nil on failure
168
+ def recover_x(y, sign)
169
+ return nil if y >= @@p
170
+ # x2 means x^2
171
+ x2 = (y*y-1) * modp_inv(@@d*y*y+1)
172
+ # when x2==0 and sign!=0, these combination of arguments is illegal
173
+ if x2.equal? 0 then
174
+ unless sign.equal? 0 then
175
+ return nil
176
+ else
177
+ return 0
178
+ end
179
+ end
180
+ # Compute square root of x2
181
+ x = pow_mod(x2 , ((@@p+3) / 8) , @@p)
182
+ x = x * @@modp_sqrt_m1 % @@p unless ((x*x - x2) % @@p).equal? 0
183
+ return nil unless ((x*x - x2) % @@p).equal? 0
184
+ x = @@p - x unless (x & 1).equal? sign
185
+ return x
186
+ end
187
+
188
+ # compress element[point] of ed25519 curve
189
+ #
190
+ # = Compressed format of Point(x,y) =
191
+ # [ y0,y1...y253,y254 | x0 ] ArgumentError ,
192
+ #
193
+ # Change the most significant bit of "y" to the least significant bit of "x"
194
+ # The most significant bit of "y" is always zero because "0 <= y < 2^255-19"
195
+ def point_compress(p)
196
+ zinv = modp_inv(p[2])
197
+ x = p[0] * zinv % @@p
198
+ y = p[1] * zinv % @@p
199
+ # OR can be used to set the least significant bit of x to the most significant bit of y
200
+ # because the most significant bit of "y" is always zero
201
+ c = y | ((x & 1) << 255)
202
+ return int_to_bytes(y | ((x & 1) << 255) , 32)
203
+ end
204
+
205
+ # decompress point that is compressed into 32bytes
206
+ def point_decompress(s)
207
+ # check argument
208
+ raise ArgumentError , "Invalid input length for decompression" unless s.length.equal? 32
209
+
210
+ y = int_form_bytes(s)
211
+ sign = y >> 255
212
+ y &= (1 << 255) - 1
213
+ x = recover_x(y, sign)
214
+ if x.nil? then
215
+ return nil
216
+ else
217
+ return [x, y, 1, x*y % @@p]
218
+ end
219
+ end
220
+
221
+
222
+ ## region key manipulation ##
223
+
224
+ # hash512(secret)
225
+ # => HASH(512bit)
226
+ # => [LH(256bit)] / [RH(256bit)]
227
+ # => LH -> (set some bits) -> a
228
+ # return ( a , RH )
229
+ def secret_expand(secret)
230
+ raise "Bad size of private key" unless secret.length.equal? 32
231
+
232
+ h = hash512(secret)
233
+ a = int_form_bytes(h[0,32])
234
+ a &= (1 << 254) - 8
235
+ a |= (1 << 254)
236
+ return [a, h[32,32]]
237
+ end
238
+
239
+
240
+ ## region sign and verify ##
241
+
242
+ # [ signature format ]
243
+ # | compressed data of _R | s | <- concatnate
244
+ def p_sign(secret, message)
245
+ a, prefix = secret_expand(secret)
246
+ _A = point_compress(point_mul(a, @@G))
247
+ r = hash512_modq(prefix + message)
248
+ _R = point_mul(r, @@G)
249
+ _Rs = point_compress(_R)
250
+ h = hash512_modq(_Rs + _A + message)
251
+ s = (r + h * a) % @@q
252
+ return _Rs + int_to_bytes(s,32)
253
+ end
254
+
255
+ def p_verify(public_key, message, signature)
256
+ # check arguments
257
+ raise ArgumentError , "Bad public_key key length" unless public_key.length.equal? 32
258
+ raise ArgumentError , "Bad signature length" unless signature.length.equal? 64
259
+
260
+ _A = point_decompress(public_key)
261
+ return false if _A.nil? || _A.equal?(0)
262
+
263
+ _Rs = signature[0,32]
264
+ _R = point_decompress(_Rs)
265
+ return false if _R.nil? || _R.equal?(0)
266
+
267
+ s = int_form_bytes(signature[32,32])
268
+ return false if s >= @@q
269
+
270
+ h = hash512_modq(_Rs + public_key + message)
271
+ sB = point_mul(s, @@G)
272
+ hA = point_mul(h, _A)
273
+ return point_equal(sB, point_add(_R, hA))
274
+ end
275
+
276
+ # public_keyKey = aG
277
+ # "a" is generated form a secret
278
+ def p_secret_to_public(secret)
279
+ expanded = secret_expand(secret)
280
+ a = expanded.first
281
+ return point_compress(point_mul(a, @@G))
282
+ end
283
+
284
+
285
+ ## region variable ##
286
+
287
+ # Base field Z_p
288
+ @@p = 2**255 - 19
289
+ # Curve constant
290
+ # d = -121665 * modp_inv(121666) % p
291
+ @@d = 37095705934669439343138083508754565189542113879843219016388785533085940283555
292
+ # Group order
293
+ @@q = 2**252 + 27742317777372353535851937790883648493
294
+ # Square root of -1
295
+ # modp_sqrt_m1 = pow_mod(2 , ((p-1) / 4) , p)
296
+ @@modp_sqrt_m1 = 19681161376707505956807079304988542015446066515923890162744021073123829784752
297
+ # Base point
298
+ # g_y = 4 * modp_inv(5) % p
299
+ # g_x = recover_x(g_y, 0)
300
+ @@g_y = 46316835694926478169428394003475163141307993866256225615783033603165251855960
301
+ @@g_x = 15112221349535400772501151409588531511454012693041857206046113283949847762202
302
+ @@G = [ @@g_x, @@g_y, 1, @@g_x * @@g_y % @@p ]
303
+ end
304
+ end
@@ -0,0 +1,11 @@
1
+ require "digest/sha3"
2
+ require_relative "./ed25519base.rb"
3
+
4
+ module Ed25519Keccak
5
+ # using Keccak(original) as a hash function
6
+ class Keccak512 < Ed25519Base
7
+ def initialize()
8
+ super( ->(s){ return Digest::SHA3.digest( s , 512 ) } )
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require 'sha3'
2
+ require_relative "./ed25519base.rb"
3
+
4
+ module Ed25519Keccak
5
+ # using SHA3(FIPS-202) as a hash function
6
+ class SHA3_512 < Ed25519Base
7
+ def initialize()
8
+ super( ->(s){ return SHA3::Digest.digest( :sha512 , s) } )
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module Ed25519Keccak
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ed25519_keccak
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - mijinc0
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-12-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: digest-sha3-patched
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.1.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.1.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: sha3
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.0.1
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.0.1
83
+ description: This is a signature and verification library of ed 25519. But instead
84
+ of SHA2_512, Keccak is adopted as a hash function. This implementation is a rewrite
85
+ of python codes on RFC8032 as ruby.
86
+ email:
87
+ - mijinco1024@gmail.com
88
+ executables: []
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - ".gitignore"
93
+ - ".rspec"
94
+ - ".travis.yml"
95
+ - CODE_OF_CONDUCT.md
96
+ - Gemfile
97
+ - Gemfile.lock
98
+ - LICENSE.txt
99
+ - README.md
100
+ - Rakefile
101
+ - bin/console
102
+ - bin/setup
103
+ - ed25519_keccak.gemspec
104
+ - images/README_draft1.png
105
+ - images/ed25519-algorithm.xml
106
+ - images/ed25519_algorithm.png
107
+ - lib/ed25519_keccak.rb
108
+ - lib/ed25519_keccak/ed25519base.rb
109
+ - lib/ed25519_keccak/keccak512.rb
110
+ - lib/ed25519_keccak/sha3_512.rb
111
+ - lib/ed25519_keccak/version.rb
112
+ homepage: https://github.com/mijinc0
113
+ licenses:
114
+ - MIT
115
+ metadata:
116
+ homepage_uri: https://github.com/mijinc0
117
+ source_code_uri: https://github.com/mijinc0/ed25519_keccak
118
+ changelog_uri: https://github.com/mijinc0/ed25519_keccak
119
+ post_install_message:
120
+ rdoc_options: []
121
+ require_paths:
122
+ - lib
123
+ required_ruby_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ required_rubygems_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ requirements: []
134
+ rubyforge_project:
135
+ rubygems_version: 2.7.8
136
+ signing_key:
137
+ specification_version: 4
138
+ summary: sign/verify ed25519. but use keccak/sha3 as a hash function
139
+ test_files: []