crypto_gost3410 0.3.2

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
+ SHA1:
3
+ metadata.gz: '082f164444c12a227f4a3ec508997456f21875b3'
4
+ data.tar.gz: 2bc4bbb47e4454b232eac0802873c07986ca9634
5
+ SHA512:
6
+ metadata.gz: 1fca1493e6ca23449c622ce1e9c108185e472373ad51e6825e50805ff1601ff5c4e189cd626496617cde7d819c5b6df7d6b159008999dea84bf7b6c706f933c0
7
+ data.tar.gz: a55b720dd19db1df32dbdd90ab039e505b8d6075c51c268756ddb862a4fce7034c86b94e7601ee6b96955dab4e5bff3efc9f8d6f2b88b7e890521b73fdd0a22c
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /spec/crypto_gost/digital_signature_gost_12/digital_signature_spec.rb
11
+ /.byebug_history
12
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
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
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.12.5
@@ -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
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in crypto_gost.gemspec
4
+ gemspec
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
@@ -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 '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,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,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
@@ -0,0 +1,3 @@
1
+ module CryptoGost3410
2
+ VERSION = '0.3.2'.freeze
3
+ 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: []