crypto_gost3410 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.rubocop.yml +17 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.rdoc +173 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/crypto_gost3410.gemspec +30 -0
- data/lib/crypto_gost3410.rb +13 -0
- data/lib/crypto_gost3410/converter.rb +24 -0
- data/lib/crypto_gost3410/generator.rb +37 -0
- data/lib/crypto_gost3410/group.rb +102 -0
- data/lib/crypto_gost3410/group/gost256tc26a.rb +18 -0
- data/lib/crypto_gost3410/group/gost256tc26b.rb +21 -0
- data/lib/crypto_gost3410/group/gost256tc26c.rb +21 -0
- data/lib/crypto_gost3410/group/gost256tc26d.rb +21 -0
- data/lib/crypto_gost3410/group/gost256tc26test.rb +21 -0
- data/lib/crypto_gost3410/group/gost512tc26a.rb +18 -0
- data/lib/crypto_gost3410/group/gost512tc26b.rb +18 -0
- data/lib/crypto_gost3410/group/gost512tc26c.rb +18 -0
- data/lib/crypto_gost3410/group/gost512tc26test.rb +18 -0
- data/lib/crypto_gost3410/modular_arithmetic.rb +43 -0
- data/lib/crypto_gost3410/point.rb +64 -0
- data/lib/crypto_gost3410/verifier.rb +42 -0
- data/lib/crypto_gost3410/version.rb +3 -0
- metadata +171 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: '082f164444c12a227f4a3ec508997456f21875b3'
|
4
|
+
data.tar.gz: 2bc4bbb47e4454b232eac0802873c07986ca9634
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1fca1493e6ca23449c622ce1e9c108185e472373ad51e6825e50805ff1601ff5c4e189cd626496617cde7d819c5b6df7d6b159008999dea84bf7b6c706f933c0
|
7
|
+
data.tar.gz: a55b720dd19db1df32dbdd90ab039e505b8d6075c51c268756ddb862a4fce7034c86b94e7601ee6b96955dab4e5bff3efc9f8d6f2b88b7e890521b73fdd0a22c
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- crypto_gost.gemspec
|
4
|
+
- Rakefile
|
5
|
+
- bin/test.rb
|
6
|
+
- lib/crypto_gost/digital_signature_gost_12/modular_arithmetic.rb
|
7
|
+
- lib/crypto_gost/digital_signature_gost_12/group/**/*
|
8
|
+
- spec/**/*
|
9
|
+
|
10
|
+
Metrics/LineLength:
|
11
|
+
Max: 100
|
12
|
+
|
13
|
+
Metrics/MethodLength:
|
14
|
+
Max: 13
|
15
|
+
|
16
|
+
Metrics/AbcSize:
|
17
|
+
Max: 20
|
data/.travis.yml
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, and in the interest of
|
4
|
+
fostering an open and welcoming community, we pledge to respect all people who
|
5
|
+
contribute through reporting issues, posting feature requests, updating
|
6
|
+
documentation, submitting pull requests or patches, and other activities.
|
7
|
+
|
8
|
+
We are committed to making participation in this project a harassment-free
|
9
|
+
experience for everyone, regardless of level of experience, gender, gender
|
10
|
+
identity and expression, sexual orientation, disability, personal appearance,
|
11
|
+
body size, race, ethnicity, age, religion, or nationality.
|
12
|
+
|
13
|
+
Examples of unacceptable behavior by participants include:
|
14
|
+
|
15
|
+
* The use of sexualized language or imagery
|
16
|
+
* Personal attacks
|
17
|
+
* Trolling or insulting/derogatory comments
|
18
|
+
* Public or private harassment
|
19
|
+
* Publishing other's private information, such as physical or electronic
|
20
|
+
addresses, without explicit permission
|
21
|
+
* Other unethical or unprofessional conduct
|
22
|
+
|
23
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
24
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
25
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
26
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
27
|
+
threatening, offensive, or harmful.
|
28
|
+
|
29
|
+
By adopting this Code of Conduct, project maintainers commit themselves to
|
30
|
+
fairly and consistently applying these principles to every aspect of managing
|
31
|
+
this project. Project maintainers who do not follow or enforce the Code of
|
32
|
+
Conduct may be permanently removed from the project team.
|
33
|
+
|
34
|
+
This code of conduct applies both within project spaces and in public spaces
|
35
|
+
when an individual is representing the project or its community.
|
36
|
+
|
37
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
38
|
+
reported by contacting a project maintainer at dtopornin@gmail.com. All
|
39
|
+
complaints will be reviewed and investigated and will result in a response that
|
40
|
+
is deemed necessary and appropriate to the circumstances. Maintainers are
|
41
|
+
obligated to maintain confidentiality with regard to the reporter of an
|
42
|
+
incident.
|
43
|
+
|
44
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
45
|
+
version 1.3.0, available at
|
46
|
+
[http://contributor-covenant.org/version/1/3/0/][version]
|
47
|
+
|
48
|
+
[homepage]: http://contributor-covenant.org
|
49
|
+
[version]: http://contributor-covenant.org/version/1/3/0/
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2019 vblazhnovgit
|
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.rdoc
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
== CryptoGost3410
|
2
|
+
|
3
|
+
Ruby library implementing GOST 34.10-2012 ECC signature and VKO algorithms.
|
4
|
+
Forked from https://github.com/wilddima/crypto_gost.
|
5
|
+
|
6
|
+
=== Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
gem 'crypto_gost3410'
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install crypto_gost3410
|
19
|
+
|
20
|
+
Or install it locally from source crypto_gost3410 project directory
|
21
|
+
|
22
|
+
$ bundle exec rake install
|
23
|
+
|
24
|
+
=== Usage
|
25
|
+
|
26
|
+
# All input and output data for CryptoGost3410 are big numbers only, not byte arrays nor strings.
|
27
|
+
# As so, input CryptoGost3411 message digest should be converted to big number too.
|
28
|
+
# We removed SecureRandom random number generations out of module to use any external generator.
|
29
|
+
# In version 0.2.1 tests we use crypto_gost3411 gem instead of stribog gem for digest generation.
|
30
|
+
|
31
|
+
require 'securerandom'
|
32
|
+
require 'crypto_gost3411'
|
33
|
+
require 'crypto_gost3410'
|
34
|
+
|
35
|
+
group = CryptoGost3410::Group::Gost256tc26a
|
36
|
+
puts group.opts[:name]
|
37
|
+
puts group.opts[:id]
|
38
|
+
puts group.opts[:oid]
|
39
|
+
|
40
|
+
coord_size = group.opts[:coord_size] # in bytes
|
41
|
+
|
42
|
+
generator = CryptoGost3410::Generator.new(group) # for sign and for vko
|
43
|
+
verifier = CryptoGost3410::Verifier.new(group) # for verify
|
44
|
+
|
45
|
+
# private_key is random number 0<n<group.order
|
46
|
+
# you can use fixed number for debugging
|
47
|
+
private_key = SecureRandom.random_number(1..group.order-1)
|
48
|
+
puts "private_key: #{private_key.to_s(16)}"
|
49
|
+
|
50
|
+
public_key = group.generate_public_key private_key
|
51
|
+
puts "public_key.x: #{public_key.x.to_s(16)}"
|
52
|
+
puts "public_key.y: #{public_key.y.to_s(16)}"
|
53
|
+
|
54
|
+
# Signature:
|
55
|
+
|
56
|
+
message = 'ruby'
|
57
|
+
digest = CryptoGost3411::Gost3411.new(coord_size).update(message).final
|
58
|
+
CryptoGost3410::Converter.printBytes(digest, coord_size * 2)
|
59
|
+
digest_num = CryptoGost3410::Converter.bytesToBignum(digest.reverse)
|
60
|
+
puts "digest_num: #{digest_num.to_s(16)}"
|
61
|
+
|
62
|
+
# rnd_val is random number 0<n<group.order so as private_key
|
63
|
+
# you can use fixed number for debugging
|
64
|
+
rand_val = SecureRandom.random_number(1..group.order-1)
|
65
|
+
puts "rand_val: #{rand_val.to_s(16)}"
|
66
|
+
|
67
|
+
signature = generator.sign(digest_num, private_key, rand_val)
|
68
|
+
puts "signature.x: #{signature.x.to_s(16)}" # x stands for r
|
69
|
+
puts "signature.y: #{signature.y.to_s(16)}" # y stands for s
|
70
|
+
|
71
|
+
signature_ok = verifier.verify(digest_num, public_key, signature)
|
72
|
+
puts "signature_ok: #{signature_ok}"
|
73
|
+
|
74
|
+
# VKO:
|
75
|
+
|
76
|
+
receiver_private_key = SecureRandom.random_number(1..group.order-1)
|
77
|
+
puts "receiver_private_key: #{receiver_private_key.to_s(16)}"
|
78
|
+
|
79
|
+
receiver_public_key = group.generate_public_key receiver_private_key
|
80
|
+
puts "receiver_public_key.x: #{receiver_public_key.x.to_s(16)}"
|
81
|
+
puts "receiver_public_key.y: #{receiver_public_key.y.to_s(16)}"
|
82
|
+
|
83
|
+
# ukm is random number 2**(coord_size*2)<=ukm<2**(coord_size*8)
|
84
|
+
ukm = SecureRandom.random_number(2**(coord_size*2)..2**(coord_size*8)-1)
|
85
|
+
puts "ukm: #{ukm.to_s(16)}"
|
86
|
+
|
87
|
+
sender_vko = generator.vko(ukm, private_key, receiver_public_key)
|
88
|
+
puts "sender_vko.x: #{sender_vko.x.to_s(16)}"
|
89
|
+
puts "sender_vko.y: #{sender_vko.y.to_s(16)}"
|
90
|
+
|
91
|
+
receiver_vko = generator.vko(ukm, receiver_private_key, public_key)
|
92
|
+
puts "receiver_vko.x: #{receiver_vko.x.to_s(16)}"
|
93
|
+
puts "receiver_vko.y: #{receiver_vko.y.to_s(16)}"
|
94
|
+
|
95
|
+
puts "vko_ok: #{(sender_vko.x == receiver_vko.x) && (sender_vko.y == receiver_vko.y)}"
|
96
|
+
|
97
|
+
=== Converting GOST digest, public_key and signature strings to big numbers and vise versa
|
98
|
+
|
99
|
+
require 'crypto_gost3411'
|
100
|
+
require 'crypto_gost3410'
|
101
|
+
|
102
|
+
group = CryptoGost3410::Group::Gost256tc26test
|
103
|
+
coord_size = group.opts[:coord_size] # in bytes
|
104
|
+
|
105
|
+
# get tbs, signer public_key and signature byte strings from x509 certificate
|
106
|
+
# ...
|
107
|
+
# generate digest
|
108
|
+
digest32 = CryptoGost3411::Gost3411.new(coord_size).update(tbs).final
|
109
|
+
# little-endian digest32 -> reverse -> big-endian -> BigNum
|
110
|
+
digest32_num = CryptoGost3410::Converter.bytesToBignum(digest32.reverse)
|
111
|
+
# public key x||y little-endian -> reverse -> big-endian -> Point(x_num, y_num)
|
112
|
+
public_key_x_num = CryptoGost3410::Converter.bytesToBignum(public_key[0...coord_size].reverse)
|
113
|
+
public_key_y_num = CryptoGost3410::Converter.bytesToBignum(public_key[coord_size..-1].reverse)
|
114
|
+
public_key_point = CryptoGost3410::Point.new(group, [public_key_x_num, public_key_y_num])
|
115
|
+
# signature s||r big-endian -> Point(r_num, s_num)
|
116
|
+
signature_s_num = CryptoGost3410::Converter.bytesToBignum(signature[0...coord_size])
|
117
|
+
signature_r_num = CryptoGost3410::Converter.bytesToBignum(signature[coord_size..-1])
|
118
|
+
signature_point = CryptoGost3410::Point.new(group, [sig_r_num, sig_s_num])
|
119
|
+
|
120
|
+
signature_point_ok = CryptoGost3410::Verifier.new(group).verify(digest32_num, public_key_point, signature_point)
|
121
|
+
puts "signature_point_ok: #{signature_point_ok}"
|
122
|
+
|
123
|
+
# Converting signature point to byte string ( s||r, big-endian):
|
124
|
+
signature_bytes_s = CryptoGost3410::Converter.bignumToBytes(signature_point.x, coord_size)
|
125
|
+
signature_bytes_r = CryptoGost3410::Converter.bignumToBytes(signature_point.y, coord_size)
|
126
|
+
signature_bytes = signature_bytes_s + signature_bytes_r
|
127
|
+
# Print signature bytes in hex (64 symbols in line)
|
128
|
+
CryptoGost3410::Converter.printBytes(signature_bytes, coord_size * 2)
|
129
|
+
|
130
|
+
=== List of TC 26 GOST 34.10-2012 elliptic curves:
|
131
|
+
|
132
|
+
Gost256tc26test - id-tc26-gost-3410-2012-256-paramSetTest (former id-GostR3410-2001-TestParamSet). Use for testing only!
|
133
|
+
Gost256tc26a - id-tc26-gost-3410-2012-256-paramSetA (Edwards twisted curve)
|
134
|
+
Gost256tc26b - id-tc26-gost-3410-2012-256-paramSetB (former id-GostR3410-2001-CryptoPro-A-ParamSet)
|
135
|
+
Gost256tc26c - id-tc26-gost-3410-2012-256-paramSetC (former id-GostR3410-2001-CryptoPro-B-ParamSet)
|
136
|
+
Gost256tc26d - id-tc26-gost-3410-2012-256-paramSetD (former id-GostR3410-2001-CryptoPro-C-ParamSet)
|
137
|
+
Gost512test - id-tc26-gost-3410-2012-512-paramSetTest. Use for testing only!
|
138
|
+
Gost512tc26a - id-tc26-gost-3410-2012-512-paramSetA
|
139
|
+
Gost512tc26b - id-tc26-gost-3410-2012-512-paramSetB
|
140
|
+
Gost512tc26c - id-tc26-gost-3410-2012-512-paramSetC (Edwards twisted curve)
|
141
|
+
|
142
|
+
You can find group by name, by id, by oid and by der_oid:
|
143
|
+
|
144
|
+
name = 'Gost256tc26test'
|
145
|
+
group = CryptoGost3410::Group.findByName(name)
|
146
|
+
|
147
|
+
id = 'id-tc26-gost-3410-2012-256-paramSetTest'
|
148
|
+
group = CryptoGost3410::Group.findById(id)
|
149
|
+
|
150
|
+
oid = '1.2.643.7.1.2.1.1.0'
|
151
|
+
group = CryptoGost3410::Group.findByOid(oid)
|
152
|
+
|
153
|
+
der_oid = "\x06\x09\x2a\x85\x03\x07\x01\x02\x01\x01\x00"
|
154
|
+
group = CryptoGost3410::Group.findByDerOid(der_oid)
|
155
|
+
|
156
|
+
=== Testing
|
157
|
+
|
158
|
+
Run spec test from crypto_gost3410 source project directory:
|
159
|
+
|
160
|
+
$ bundle exec rake spec
|
161
|
+
|
162
|
+
=== Thanks
|
163
|
+
|
164
|
+
Thanks to WildDima for root crypto_gost project on GitHub at https://github.com/wilddima/crypto_gost.
|
165
|
+
|
166
|
+
=== Contributing
|
167
|
+
|
168
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/vblazhnovgit/crypto_gost3410. 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.
|
169
|
+
|
170
|
+
|
171
|
+
=== License
|
172
|
+
|
173
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'crypto_gost'
|
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
|
data/bin/setup
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'crypto_gost3410/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'crypto_gost3410'
|
9
|
+
spec.version = CryptoGost3410::VERSION
|
10
|
+
spec.authors = ['vblazhnovgit']
|
11
|
+
spec.email = ['vblazhnov@yandex.ru']
|
12
|
+
|
13
|
+
spec.summary = 'Write a short summary, because Rubygems requires one.'
|
14
|
+
spec.description = 'Write a longer description or delete this line.'
|
15
|
+
spec.homepage = 'http://github.com/vblazhnovgit/crypto_gost3410'
|
16
|
+
spec.license = 'MIT'
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
19
|
+
spec.bindir = 'exe'
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ['lib']
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler'
|
24
|
+
spec.add_development_dependency 'byebug'
|
25
|
+
spec.add_development_dependency 'faker'
|
26
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
27
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
28
|
+
spec.add_development_dependency 'rubocop'
|
29
|
+
spec.add_dependency 'crypto_gost3411'
|
30
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# Gost cryptography
|
2
|
+
#
|
3
|
+
# @author vblazhnovgit
|
4
|
+
module CryptoGost3410
|
5
|
+
require 'securerandom'
|
6
|
+
require 'crypto_gost3410/version'
|
7
|
+
require 'crypto_gost3410/generator'
|
8
|
+
require 'crypto_gost3410/verifier'
|
9
|
+
require 'crypto_gost3410/point'
|
10
|
+
require 'crypto_gost3410/group'
|
11
|
+
require 'crypto_gost3410/modular_arithmetic'
|
12
|
+
require 'crypto_gost3410/converter'
|
13
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module CryptoGost3410
|
2
|
+
class Converter
|
3
|
+
# Big number -> byte string (big-endian) of given size
|
4
|
+
def self.bignumToBytes(bn, size)
|
5
|
+
s = bn.to_s(16)
|
6
|
+
s = ('0' * (size * 2 - s.length)) + s
|
7
|
+
sa = s.scan(/../)
|
8
|
+
ba = []
|
9
|
+
sa.each{|c| ba << c.to_i(16).chr}
|
10
|
+
bytes = ba.join
|
11
|
+
end
|
12
|
+
|
13
|
+
# Byte string (big-endian) to big number
|
14
|
+
def self.bytesToBignum(bytes)
|
15
|
+
bytes.unpack('H*')[0].hex
|
16
|
+
end
|
17
|
+
|
18
|
+
# Byte string hex printer
|
19
|
+
def self.printBytes(bytes, line_size = 16)
|
20
|
+
bytes.unpack('H*')[0].scan(/.{1,#{line_size}}/).each{|s| puts(s)}
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module CryptoGost3410
|
2
|
+
# DigitalSignature
|
3
|
+
#
|
4
|
+
# @author vblazhnovgit
|
5
|
+
class Generator
|
6
|
+
attr_reader :group
|
7
|
+
|
8
|
+
def initialize(group)
|
9
|
+
@group = group
|
10
|
+
end
|
11
|
+
|
12
|
+
def sign(hash, private_key, rand_val)
|
13
|
+
@hash = hash
|
14
|
+
@private_key = private_key
|
15
|
+
@rnd = rand_val
|
16
|
+
@r = r_func
|
17
|
+
s = s_func
|
18
|
+
CryptoGost3410::Point.new self, [@r, s]
|
19
|
+
end
|
20
|
+
|
21
|
+
def vko(ukm, private_key, other_public_key)
|
22
|
+
n = (group.opts[:h] * private_key * ukm) % group.order
|
23
|
+
other_public_key * n
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def r_func
|
29
|
+
(group.generator * @rnd).x % group.order
|
30
|
+
end
|
31
|
+
|
32
|
+
def s_func
|
33
|
+
(@r * @private_key + @rnd * @hash) % group.order
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module CryptoGost3410
|
2
|
+
# Group
|
3
|
+
#
|
4
|
+
# @author vblazhnovgit
|
5
|
+
class Group
|
6
|
+
attr_reader :opts, :generator, :a, :b, :gx, :gy, :order, :p
|
7
|
+
|
8
|
+
def initialize(opts)
|
9
|
+
@opts = opts
|
10
|
+
@name = opts.fetch(:name)
|
11
|
+
@p = opts[:p]
|
12
|
+
@a = opts[:a]
|
13
|
+
@b = opts[:b]
|
14
|
+
@gx = opts[:gx]
|
15
|
+
@gy = opts[:gy]
|
16
|
+
@order = opts[:n]
|
17
|
+
@cofactor = opts[:h]
|
18
|
+
@generator = CryptoGost3410::Point.new self, [gx, gy]
|
19
|
+
end
|
20
|
+
|
21
|
+
NAMES = %w[
|
22
|
+
Gost256tc26test
|
23
|
+
Gost256tc26a
|
24
|
+
Gost256tc26b
|
25
|
+
Gost256tc26c
|
26
|
+
Gost256tc26d
|
27
|
+
Gost512tc26test
|
28
|
+
Gost512tc26a
|
29
|
+
Gost512tc26b
|
30
|
+
Gost512tc26c
|
31
|
+
].freeze
|
32
|
+
|
33
|
+
NAMES.each do |name|
|
34
|
+
require_relative "./group/#{name.downcase}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.findByOid(oid)
|
38
|
+
group = nil
|
39
|
+
NAMES.each do |n|
|
40
|
+
g = Object.const_get("CryptoGost3410::Group::#{n}")
|
41
|
+
if g.opts[:oid] == oid then
|
42
|
+
group = g
|
43
|
+
break
|
44
|
+
end
|
45
|
+
if (g.opts[:cp_oid] != nil) && (g.opts[:cp_oid] == oid) then
|
46
|
+
group = g
|
47
|
+
break
|
48
|
+
end
|
49
|
+
end
|
50
|
+
group
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.findByDerOid(der_oid)
|
54
|
+
group = nil
|
55
|
+
NAMES.each do |n|
|
56
|
+
g = Object.const_get("CryptoGost3410::Group::#{n}")
|
57
|
+
if g.opts[:der_oid] == der_oid then
|
58
|
+
group = g
|
59
|
+
break
|
60
|
+
end
|
61
|
+
if (g.opts[:cp_der_oid] != nil) && (g.opts[:cp_der_oid] == der_oid) then
|
62
|
+
group = g
|
63
|
+
break
|
64
|
+
end
|
65
|
+
end
|
66
|
+
group
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.findById(id)
|
70
|
+
group = nil
|
71
|
+
NAMES.each do |n|
|
72
|
+
g = Object.const_get("CryptoGost3410::Group::#{n}")
|
73
|
+
if g.opts[:id] == id then
|
74
|
+
group = g
|
75
|
+
break
|
76
|
+
end
|
77
|
+
if (g.opts[:cp_id] != nil) && (g.opts[:cp_id] == id) then
|
78
|
+
group = g
|
79
|
+
break
|
80
|
+
end
|
81
|
+
end
|
82
|
+
group
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.findByName(name)
|
86
|
+
group = nil
|
87
|
+
NAMES.each do |n|
|
88
|
+
g = Object.const_get("CryptoGost3410::Group::#{n}")
|
89
|
+
if g.opts[:name] == name then
|
90
|
+
group = g
|
91
|
+
break
|
92
|
+
end
|
93
|
+
end
|
94
|
+
group
|
95
|
+
end
|
96
|
+
|
97
|
+
def generate_public_key(private_key)
|
98
|
+
generator * private_key
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module CryptoGost3410
|
2
|
+
class Group
|
3
|
+
Gost256tc26a = new(
|
4
|
+
name: 'gost256tc26a',
|
5
|
+
id: 'id-tc26-gost-3410-2012-256-paramSetA',
|
6
|
+
oid: '1.2.643.7.1.2.1.1.1',
|
7
|
+
der_oid: "\x06\x09\x2a\x85\x03\x07\x01\x02\x01\x01\x01",
|
8
|
+
coord_size: 32,
|
9
|
+
p: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97,
|
10
|
+
a: 0xC2173F1513981673AF4892C23035A27CE25E2013BF95AA33B22C656F277E7335,
|
11
|
+
b: 0x295F9BAE7428ED9CCC20E7C359A9D41A22FCCD9108E17BF7BA9337A6F8AE9513,
|
12
|
+
gx: 0x91E38443A5E82C0D880923425712B2BB658B9196932E02C78B2582FE742DAA28,
|
13
|
+
gy: 0x32879423AB1A0375895786C4BB46E9565FDE0B5344766740AF268ADB32322E5C,
|
14
|
+
n: 0x400000000000000000000000000000000FD8CDDFC87B6635C115AF556C360C67,
|
15
|
+
h: 0x4
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module CryptoGost3410
|
2
|
+
class Group
|
3
|
+
Gost256tc26b = new(
|
4
|
+
name: 'gost256tc26b',
|
5
|
+
id: 'id-tc26-gost-3410-2012-256-paramSetB', # former id-GostR3410-2001-CryptoPro-A-ParamSet
|
6
|
+
oid: '1.2.643.7.1.2.1.1.2', # former 1.2.643.2.2.35.1
|
7
|
+
der_oid: "\x06\x09\x2a\x85\x03\x07\x01\x02\x01\x01\x02",
|
8
|
+
cp_id: 'id-GostR3410-2001-CryptoPro-A-ParamSet',
|
9
|
+
cp_oid: '1.2.643.2.2.35.1',
|
10
|
+
cp_der_oid: "\x06\x07\x2a\x85\x03\x02\x02\x23\x01",
|
11
|
+
coord_size: 32,
|
12
|
+
p: 115792089237316195423570985008687907853269984665640564039457584007913129639319,
|
13
|
+
a: 115792089237316195423570985008687907853269984665640564039457584007913129639316,
|
14
|
+
b: 166,
|
15
|
+
gx: 1,
|
16
|
+
gy: 64033881142927202683649881450433473985931760268884941288852745803908878638612,
|
17
|
+
n: 115792089237316195423570985008687907853073762908499243225378155805079068850323,
|
18
|
+
h: 1
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module CryptoGost3410
|
2
|
+
class Group
|
3
|
+
Gost256tc26c = new(
|
4
|
+
name: 'gost256tc26c',
|
5
|
+
id: 'id-tc26-gost-3410-2012-256-paramSetC', # former id-GostR3410-2001-CryptoPro-B-ParamSet
|
6
|
+
oid: '1.2.643.7.1.2.1.1.3', # former 1.2.643.2.2.35.2
|
7
|
+
der_oid: "\x06\x09\x2a\x85\x03\x07\x01\x02\x01\x01\x03",
|
8
|
+
cp_id: 'id-GostR3410-2001-CryptoPro-B-ParamSet',
|
9
|
+
cp_oid: '1.2.643.2.2.35.2',
|
10
|
+
cp_der_oid: "\x06\x07\x2a\x85\x03\x02\x02\x23\x02",
|
11
|
+
coord_size: 32,
|
12
|
+
p: 57896044618658097711785492504343953926634992332820282019728792003956564823193,
|
13
|
+
a: 57896044618658097711785492504343953926634992332820282019728792003956564823190,
|
14
|
+
b: 28091019353058090096996979000309560759124368558014865957655842872397301267595,
|
15
|
+
gx: 1,
|
16
|
+
gy: 28792665814854611296992347458380284135028636778229113005756334730996303888124,
|
17
|
+
n: 57896044618658097711785492504343953927102133160255826820068844496087732066703,
|
18
|
+
h: 1
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module CryptoGost3410
|
2
|
+
class Group
|
3
|
+
Gost256tc26d = new(
|
4
|
+
name: 'gost256tc26d',
|
5
|
+
id: 'id-tc26-gost-3410-2012-256-paramSetD', # former id-GostR3410-2001-CryptoPro-C-ParamSet
|
6
|
+
oid: '1.2.643.7.1.2.1.1.4', # former 1.2.643.2.2.35.3
|
7
|
+
der_oid: "\x06\x09\x2a\x85\x03\x07\x01\x02\x01\x01\x04",
|
8
|
+
cp_id: 'id-GostR3410-2001-CryptoPro-C-ParamSet',
|
9
|
+
cp_oid: '1.2.643.2.2.35.3',
|
10
|
+
cp_der_oid: "\x06\x07\x2a\x85\x03\x02\x02\x23\x03",
|
11
|
+
coord_size: 32,
|
12
|
+
p: 70390085352083305199547718019018437841079516630045180471284346843705633502619,
|
13
|
+
a: 70390085352083305199547718019018437841079516630045180471284346843705633502616,
|
14
|
+
b: 32858,
|
15
|
+
gx: 0,
|
16
|
+
gy: 29818893917731240733471273240314769927240550812383695689146495261604565990247,
|
17
|
+
n: 70390085352083305199547718019018437840920882647164081035322601458352298396601,
|
18
|
+
h: 1
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module CryptoGost3410
|
2
|
+
class Group
|
3
|
+
Gost256tc26test = new(
|
4
|
+
name: 'gost256tc26test',
|
5
|
+
id: 'id-tc26-gost-3410-2012-256-paramSetTest', # former id-GostR3410-2001-TestParamSet
|
6
|
+
oid: '1.2.643.7.1.2.1.1.0', # former 1.2.643.2.2.35.0
|
7
|
+
der_oid: "\x06\x09\x2a\x85\x03\x07\x01\x02\x01\x01\x00",
|
8
|
+
cp_id: 'id-GostR3410-2001-TestParamSet',
|
9
|
+
cp_oid: '1.2.643.2.2.35.0',
|
10
|
+
cp_der_oid: "\x06\x07\x2a\x85\x03\x02\x02\x23\x00",
|
11
|
+
coord_size: 32,
|
12
|
+
p: 0x8000000000000000000000000000000000000000000000000000000000000431,
|
13
|
+
a: 0x7,
|
14
|
+
b: 0x5FBFF498AA938CE739B8E022FBAFEF40563F6E6A3472FC2A514C0CE9DAE23B7E,
|
15
|
+
gx: 0x2,
|
16
|
+
gy: 0x8E2A8A0E65147D4BD6316030E16D19C85C97F0A9CA267122B96ABBCEA7E8FC8,
|
17
|
+
n: 0x8000000000000000000000000000000150FE8A1892976154C59CFC193ACCF5B3,
|
18
|
+
h: 1
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module CryptoGost3410
|
2
|
+
class Group
|
3
|
+
Gost512tc26a = new(
|
4
|
+
name: 'gost512tc26a',
|
5
|
+
id: 'id-tc26-gost-3410-2012-512-paramSetA',
|
6
|
+
oid: '1.2.643.7.1.2.1.2.1',
|
7
|
+
der_oid: "\x06\x09\x2a\x85\x03\x07\x01\x02\x01\x02\x01",
|
8
|
+
coord_size: 64,
|
9
|
+
p: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7,
|
10
|
+
a: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC4,
|
11
|
+
b: 0xE8C2505DEDFC86DDC1BD0B2B6667F1DA34B82574761CB0E879BD081CFD0B6265EE3CB090F30D27614CB4574010DA90DD862EF9D4EBEE4761503190785A71C760,
|
12
|
+
gx: 0x3,
|
13
|
+
gy: 0x7503CFE87A836AE3A61B8816E25450E6CE5E1C93ACF1ABC1778064FDCBEFA921DF1626BE4FD036E93D75E6A50E3A41E98028FE5FC235F5B889A589CB5215F2A4,
|
14
|
+
n: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27E69532F48D89116FF22B8D4E0560609B4B38ABFAD2B85DCACDB1411F10B275,
|
15
|
+
h: 1
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module CryptoGost3410
|
2
|
+
class Group
|
3
|
+
Gost512tc26b = new(
|
4
|
+
name: 'gost512tc26b',
|
5
|
+
id: 'id-tc26-gost-3410-2012-512-paramSetB',
|
6
|
+
oid: '1.2.643.7.1.2.1.2.2',
|
7
|
+
der_oid: "\x06\x09\x2a\x85\x03\x07\x01\x02\x01\x02\x02",
|
8
|
+
coord_size: 64,
|
9
|
+
p: 0x8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006F,
|
10
|
+
a: 0x8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006C,
|
11
|
+
b: 0x687D1B459DC841457E3E06CF6F5E2517B97C7D614AF138BCBF85DC806C4B289F3E965D2DB1416D217F8B276FAD1AB69C50F78BEE1FA3106EFB8CCBC7C5140116,
|
12
|
+
gx: 0x2,
|
13
|
+
gy: 0x1A8F7EDA389B094C2C071E3647A8940F3C123B697578C213BE6DD9E6C8EC7335DCB228FD1EDF4A39152CBCAAF8C0398828041055F94CEEEC7E21340780FE41BD,
|
14
|
+
n: 0x800000000000000000000000000000000000000000000000000000000000000149A1EC142565A545ACFDB77BD9D40CFA8B996712101BEA0EC6346C54374F25BD,
|
15
|
+
h: 1
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module CryptoGost3410
|
2
|
+
class Group
|
3
|
+
Gost512tc26c = new(
|
4
|
+
name: 'gost512tc26c',
|
5
|
+
id: 'id-tc26-gost-3410-2012-512-paramSetC',
|
6
|
+
oid: '1.2.643.7.1.2.1.2.3',
|
7
|
+
der_oid: "\x06\x09\x2a\x85\x03\x07\x01\x02\x01\x02\x03",
|
8
|
+
coord_size: 64,
|
9
|
+
p: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7,
|
10
|
+
a: 0xDC9203E514A721875485A529D2C722FB187BC8980EB866644DE41C68E143064546E861C0E2C9EDD92ADE71F46FCF50FF2AD97F951FDA9F2A2EB6546F39689BD3,
|
11
|
+
b: 0xB4C4EE28CEBC6C2C8AC12952CF37F16AC7EFB6A9F69F4B57FFDA2E4F0DE5ADE038CBC2FFF719D2C18DE0284B8BFEF3B52B8CC7A5F5BF0A3C8D2319A5312557E1,
|
12
|
+
gx: 0xE2E31EDFC23DE7BDEBE241CE593EF5DE2295B7A9CBAEF021D385F7074CEA043AA27272A7AE602BF2A7B9033DB9ED3610C6FB85487EAE97AAC5BC7928C1950148,
|
13
|
+
gy: 0xF5CE40D95B5EB899ABBCCFF5911CB8577939804D6527378B8C108C3D2090FF9BE18E2D33E3021ED2EF32D85822423B6304F726AA854BAE07D0396E9A9ADDC40F,
|
14
|
+
n: 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC98CDBA46506AB004C33A9FF5147502CC8EDA9E7A769A12694623CEF47F023ED,
|
15
|
+
h: 0x4
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module CryptoGost3410
|
2
|
+
class Group
|
3
|
+
Gost512tc26test = new(
|
4
|
+
name: 'gost512tc26test',
|
5
|
+
id: 'id-tc26-gost-3410-2012-512-paramSetTest',
|
6
|
+
oid: '1.2.643.7.1.2.1.2.0',
|
7
|
+
der_oid: "\x06\x09\x2a\x85\x03\x07\x01\x02\x01\x02\x00",
|
8
|
+
coord_size: 64,
|
9
|
+
p: 0x4531ACD1FE0023C7550D267B6B2FEE80922B14B2FFB90F04D4EB7C09B5D2D15DF1D852741AF4704A0458047E80E4546D35B8336FAC224DD81664BBF528BE6373,
|
10
|
+
a: 0x7,
|
11
|
+
b: 0x1CFF0806A31116DA29D8CFA54E57EB748BC5F377E49400FDD788B649ECA1AC4361834013B2AD7322480A89CA58E0CF74BC9E540C2ADD6897FAD0A3084F302ADC,
|
12
|
+
gx: 0x24D19CC64572EE30F396BF6EBBFD7A6C5213B3B3D7057CC825F91093A68CD762FD60611262CD838DC6B60AA7EEE804E28BC849977FAC33B4B530F1B120248A9A,
|
13
|
+
gy: 0x2BB312A43BD2CE6E0D020613C857ACDDCFBF061E91E5F2C3F32447C259F39B2C83AB156D77F1496BF7EB3351E1EE4E43DC1A18B91B24640B6DBB92CB1ADD371E,
|
14
|
+
n: 0x4531ACD1FE0023C7550D267B6B2FEE80922B14B2FFB90F04D4EB7C09B5D2D15DA82F2D7ECB1DBAC719905C5EECC423F1D86E25EDBE23C595D644AAF187E6E6DF,
|
15
|
+
h: 1
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module CryptoGost3410
|
2
|
+
# ModularArithmetic
|
3
|
+
#
|
4
|
+
# Take this code from here: https://gist.github.com/jingoro/2388745
|
5
|
+
# @author jingoro
|
6
|
+
module ModularArithmetic
|
7
|
+
|
8
|
+
module_function
|
9
|
+
|
10
|
+
def gcd(x, y)
|
11
|
+
gcdext(x, y).first
|
12
|
+
end
|
13
|
+
|
14
|
+
def gcdext(x, y)
|
15
|
+
if x < 0
|
16
|
+
g, a, b = gcdext(-x, y)
|
17
|
+
return [g, -a, b]
|
18
|
+
end
|
19
|
+
if y < 0
|
20
|
+
g, a, b = gcdext(x, -y)
|
21
|
+
return [g, a, -b]
|
22
|
+
end
|
23
|
+
r0, r1 = x, y
|
24
|
+
a0 = b1 = 1
|
25
|
+
a1 = b0 = 0
|
26
|
+
until r1.zero?
|
27
|
+
q = r0 / r1
|
28
|
+
r0, r1 = r1, r0 - q*r1
|
29
|
+
a0, a1 = a1, a0 - q*a1
|
30
|
+
b0, b1 = b1, b0 - q*b1
|
31
|
+
end
|
32
|
+
[r0, a0, b0]
|
33
|
+
end
|
34
|
+
|
35
|
+
def invert(num, mod)
|
36
|
+
g, a, b = gcdext(num, mod)
|
37
|
+
unless g == 1
|
38
|
+
raise ZeroDivisionError.new("#{num} has no inverse modulo #{mod}")
|
39
|
+
end
|
40
|
+
a % mod
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module CryptoGost3410
|
2
|
+
# EllipticCurvePoint
|
3
|
+
#
|
4
|
+
# author WildDima
|
5
|
+
class Point
|
6
|
+
attr_accessor :x, :y, :group
|
7
|
+
|
8
|
+
def initialize(group, coords)
|
9
|
+
@group = group
|
10
|
+
@x, @y = coords
|
11
|
+
end
|
12
|
+
|
13
|
+
def coords
|
14
|
+
[x, y]
|
15
|
+
end
|
16
|
+
|
17
|
+
# rubocop:disable Metrics/AbcSize
|
18
|
+
def +(other)
|
19
|
+
unless other.is_a? Point
|
20
|
+
raise ArgumentError, "Invalid other: #{other.inspect}"
|
21
|
+
end
|
22
|
+
|
23
|
+
new_x = add_ec_module(other.x - x)
|
24
|
+
new_y = add_ec_module(other.y - y)
|
25
|
+
|
26
|
+
s = add_ec_module(
|
27
|
+
(new_y * ModularArithmetic.invert(new_x, group.p)) % group.p
|
28
|
+
)
|
29
|
+
|
30
|
+
new_x = add_ec_module((s**2 - x - other.x) % group.p)
|
31
|
+
new_y = add_ec_module((s * (x - new_x) - y) % group.p)
|
32
|
+
|
33
|
+
self.class.new group, [new_x, new_y]
|
34
|
+
end
|
35
|
+
|
36
|
+
def double
|
37
|
+
new_x = add_ec_module(2 * y)
|
38
|
+
new_y = add_ec_module(3 * x**2 + group.a)
|
39
|
+
|
40
|
+
s = (new_y * ModularArithmetic.invert(new_x, group.p)) % group.p
|
41
|
+
|
42
|
+
new_x = add_ec_module(s**2 - 2 * x) % group.p
|
43
|
+
new_y = add_ec_module(s * (x - new_x) - y) % group.p
|
44
|
+
|
45
|
+
self.class.new group, [new_x, new_y]
|
46
|
+
end
|
47
|
+
# rubocop:enable Metrics/AbcSize
|
48
|
+
|
49
|
+
def *(other)
|
50
|
+
return unless other.is_a? Numeric
|
51
|
+
if other == 1
|
52
|
+
self
|
53
|
+
elsif (other % 2).odd?
|
54
|
+
self + (self * (other - 1))
|
55
|
+
else
|
56
|
+
double * (other / 2)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def add_ec_module(coord)
|
61
|
+
coord < 0 ? coord + group.p : coord
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module CryptoGost3410
|
2
|
+
# DigitalSignature
|
3
|
+
#
|
4
|
+
# @author vblazhnovgit
|
5
|
+
class Verifier
|
6
|
+
attr_reader :group
|
7
|
+
|
8
|
+
def initialize(group)
|
9
|
+
@group = group
|
10
|
+
end
|
11
|
+
|
12
|
+
def verify(hash, public_key, signature)
|
13
|
+
@public_key = public_key
|
14
|
+
r = signature.x
|
15
|
+
s = signature.y
|
16
|
+
return false if invalid_vector?(r) || invalid_vector?(s)
|
17
|
+
(c_param(hash, public_key, r, s).x % group.order) == r
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def mod_inv(opt, mod)
|
23
|
+
ModularArithmetic.invert(opt, mod)
|
24
|
+
end
|
25
|
+
|
26
|
+
def valid_vector?(vector)
|
27
|
+
(1...group.order).cover? vector
|
28
|
+
end
|
29
|
+
|
30
|
+
def invalid_vector?(vector)
|
31
|
+
!valid_vector?(vector)
|
32
|
+
end
|
33
|
+
|
34
|
+
def z_param(hash, param)
|
35
|
+
(param * mod_inv(hash, group.order)) % group.order
|
36
|
+
end
|
37
|
+
|
38
|
+
def c_param(hash, public_key, r, s)
|
39
|
+
group.generator * z_param(hash, s) + public_key * z_param(hash, -r)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
metadata
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: crypto_gost3410
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- vblazhnovgit
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-04-24 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: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: byebug
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: faker
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: crypto_gost3411
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: Write a longer description or delete this line.
|
112
|
+
email:
|
113
|
+
- vblazhnov@yandex.ru
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- ".gitignore"
|
119
|
+
- ".rspec"
|
120
|
+
- ".rubocop.yml"
|
121
|
+
- ".travis.yml"
|
122
|
+
- CODE_OF_CONDUCT.md
|
123
|
+
- Gemfile
|
124
|
+
- LICENSE.txt
|
125
|
+
- README.rdoc
|
126
|
+
- Rakefile
|
127
|
+
- bin/console
|
128
|
+
- bin/setup
|
129
|
+
- crypto_gost3410.gemspec
|
130
|
+
- lib/crypto_gost3410.rb
|
131
|
+
- lib/crypto_gost3410/converter.rb
|
132
|
+
- lib/crypto_gost3410/generator.rb
|
133
|
+
- lib/crypto_gost3410/group.rb
|
134
|
+
- lib/crypto_gost3410/group/gost256tc26a.rb
|
135
|
+
- lib/crypto_gost3410/group/gost256tc26b.rb
|
136
|
+
- lib/crypto_gost3410/group/gost256tc26c.rb
|
137
|
+
- lib/crypto_gost3410/group/gost256tc26d.rb
|
138
|
+
- lib/crypto_gost3410/group/gost256tc26test.rb
|
139
|
+
- lib/crypto_gost3410/group/gost512tc26a.rb
|
140
|
+
- lib/crypto_gost3410/group/gost512tc26b.rb
|
141
|
+
- lib/crypto_gost3410/group/gost512tc26c.rb
|
142
|
+
- lib/crypto_gost3410/group/gost512tc26test.rb
|
143
|
+
- lib/crypto_gost3410/modular_arithmetic.rb
|
144
|
+
- lib/crypto_gost3410/point.rb
|
145
|
+
- lib/crypto_gost3410/verifier.rb
|
146
|
+
- lib/crypto_gost3410/version.rb
|
147
|
+
homepage: http://github.com/vblazhnovgit/crypto_gost3410
|
148
|
+
licenses:
|
149
|
+
- MIT
|
150
|
+
metadata: {}
|
151
|
+
post_install_message:
|
152
|
+
rdoc_options: []
|
153
|
+
require_paths:
|
154
|
+
- lib
|
155
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - ">="
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0'
|
165
|
+
requirements: []
|
166
|
+
rubyforge_project:
|
167
|
+
rubygems_version: 2.6.14.3
|
168
|
+
signing_key:
|
169
|
+
specification_version: 4
|
170
|
+
summary: Write a short summary, because Rubygems requires one.
|
171
|
+
test_files: []
|