crypto_gost 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -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 +69 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/crypto_gost.gemspec +29 -0
- data/lib/crypto_gost/create.rb +57 -0
- data/lib/crypto_gost/group/nistp192.rb +16 -0
- data/lib/crypto_gost/group/nistp224.rb +16 -0
- data/lib/crypto_gost/group/nistp256.rb +16 -0
- data/lib/crypto_gost/group/nistp384.rb +16 -0
- data/lib/crypto_gost/group/nistp521.rb +16 -0
- data/lib/crypto_gost/group/secp112r1.rb +16 -0
- data/lib/crypto_gost/group/secp112r2.rb +16 -0
- data/lib/crypto_gost/group/secp128r1.rb +16 -0
- data/lib/crypto_gost/group/secp128r2.rb +16 -0
- data/lib/crypto_gost/group/secp160k1.rb +16 -0
- data/lib/crypto_gost/group/secp160r1.rb +16 -0
- data/lib/crypto_gost/group/secp160r2.rb +16 -0
- data/lib/crypto_gost/group/secp192k1.rb +16 -0
- data/lib/crypto_gost/group/secp192r1.rb +16 -0
- data/lib/crypto_gost/group/secp224k1.rb +16 -0
- data/lib/crypto_gost/group/secp224r1.rb +16 -0
- data/lib/crypto_gost/group/secp256k1.rb +16 -0
- data/lib/crypto_gost/group/secp256r1.rb +16 -0
- data/lib/crypto_gost/group/secp384r1.rb +16 -0
- data/lib/crypto_gost/group/secp521r1.rb +16 -0
- data/lib/crypto_gost/group.rb +59 -0
- data/lib/crypto_gost/modular_arithmetic.rb +43 -0
- data/lib/crypto_gost/point.rb +64 -0
- data/lib/crypto_gost/signature.rb +32 -0
- data/lib/crypto_gost/verify.rb +58 -0
- data/lib/crypto_gost/version.rb +3 -0
- data/lib/crypto_gost.rb +12 -0
- metadata +182 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 680142f87c12169079be42ec1667be220ef7bf52
|
4
|
+
data.tar.gz: 64e105f871b4732ae06bf46c1524c197a660e118
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9e17b576b65621fe29559e6df7eb4838eedb4684fd1c424a4eb7857e2ef925409967aa40e473e2062f4daaddc532c8a0f7c93709306a8a53c131a8b9e3297849
|
7
|
+
data.tar.gz: a56c12d16a240b644668fe134c6ffc9cfcdc07ed2868ae1518a41dacb1ffbceeb323b03b245287d1e1cc6681c9f1bef7ff0df2be7ad4af49312ed5107d760b93
|
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) 2016 WildDima
|
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,69 @@
|
|
1
|
+
== CryptoGost
|
2
|
+
|
3
|
+
{<img src="https://travis-ci.org/WildDima/crypto_gost.svg?branch=master"
|
4
|
+
alt="Build Status" />}[https://travis-ci.org/WildDima/crypto_gost]
|
5
|
+
|
6
|
+
Ruby library implementing GOST 34.10-12 ECC (not production ready)
|
7
|
+
|
8
|
+
=== Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
gem 'crypto_gost'
|
13
|
+
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install crypto_gost
|
22
|
+
|
23
|
+
=== Usage
|
24
|
+
|
25
|
+
group = CryptoGost::Group::Nistp192
|
26
|
+
private_key = group.generate_private_key
|
27
|
+
public_key = group.generate_public_key private_key
|
28
|
+
message = 'ruby'
|
29
|
+
|
30
|
+
signature = CryptoGost::Create.new(message, group).(private_key) #=> #<CryptoGost::Signature:0x007fbf1a128e38 @r=797072555870978995277638382002810748614228757069663574432, @s=3005972168119503640451023541340174801109033211348956501476>
|
31
|
+
|
32
|
+
# signature = CryptoGost::Create.new(message, group).call(private_key)
|
33
|
+
|
34
|
+
CryptoGost::Verify.new(message, group).(public_key, signature) # => true
|
35
|
+
|
36
|
+
# CryptoGost::Verify.new(message, group).call(public_key, signature)
|
37
|
+
|
38
|
+
List of added elliptic curves:
|
39
|
+
|
40
|
+
Nistp192
|
41
|
+
Nistp224
|
42
|
+
Nistp256
|
43
|
+
Nistp384
|
44
|
+
Nistp521
|
45
|
+
Secp112r1
|
46
|
+
Secp112r2
|
47
|
+
Secp128r1
|
48
|
+
Secp128r2
|
49
|
+
Secp160k1
|
50
|
+
Secp160r1
|
51
|
+
Secp160r2
|
52
|
+
Secp192k1
|
53
|
+
Secp192r1
|
54
|
+
Secp224k1
|
55
|
+
Secp224r1
|
56
|
+
Secp256k1
|
57
|
+
Secp256r1
|
58
|
+
Secp384r1
|
59
|
+
Secp521r1
|
60
|
+
|
61
|
+
=== Contributing
|
62
|
+
|
63
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/wilddima/crypto_gost. 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.
|
64
|
+
|
65
|
+
|
66
|
+
=== License
|
67
|
+
|
68
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
69
|
+
|
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
data/crypto_gost.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'crypto_gost/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "crypto_gost"
|
8
|
+
spec.version = CryptoGost::VERSION
|
9
|
+
spec.authors = ["WildDima"]
|
10
|
+
spec.email = ["dtopornin@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Write a short summary, because Rubygems requires one.}
|
13
|
+
spec.description = %q{Write a longer description or delete this line.}
|
14
|
+
spec.homepage = "http://github.com/WildDima/crypto_gost"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_dependency 'stribog', "~> 0.2.0"
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.12"
|
24
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
26
|
+
spec.add_development_dependency 'rubocop'
|
27
|
+
spec.add_development_dependency 'byebug'
|
28
|
+
spec.add_development_dependency 'faker'
|
29
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'stribog'
|
2
|
+
require 'securerandom'
|
3
|
+
|
4
|
+
module CryptoGost
|
5
|
+
# DigitalSignature
|
6
|
+
#
|
7
|
+
# @author WildDima
|
8
|
+
class Create
|
9
|
+
attr_reader :group, :public_key, :signature_adapter, :create_hash
|
10
|
+
|
11
|
+
def initialize(message, group, signature_adapter: Signature,
|
12
|
+
create_hash: Stribog::CreateHash)
|
13
|
+
@signature_adapter = signature_adapter
|
14
|
+
@create_hash = create_hash
|
15
|
+
@message = message
|
16
|
+
@group = group
|
17
|
+
end
|
18
|
+
|
19
|
+
def call(private_key)
|
20
|
+
@private_key = private_key
|
21
|
+
loop do
|
22
|
+
rand_val = SecureRandom.random_number(1..group.order)
|
23
|
+
r = r_func(rand_val)
|
24
|
+
s = s_func(rand_val, private_key)
|
25
|
+
break new_signature(r: r, s: s) if !r.zero? || !s.zero?
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def hash_message(message, size: 256)
|
32
|
+
new_hash(message, size: size)
|
33
|
+
end
|
34
|
+
|
35
|
+
def r_func(rand_val)
|
36
|
+
(group.generator * rand_val).x % group.order
|
37
|
+
end
|
38
|
+
|
39
|
+
def s_func(rand_val, private_key)
|
40
|
+
(r_func(rand_val) * private_key + rand_val * hash_mod_ecn) %
|
41
|
+
group.order
|
42
|
+
end
|
43
|
+
|
44
|
+
def hash_mod_ecn
|
45
|
+
hashed = hash_message(@message, size: 256).dec
|
46
|
+
hashed.zero? ? 1 : hashed
|
47
|
+
end
|
48
|
+
|
49
|
+
def new_signature(keys)
|
50
|
+
signature_adapter.new(r: keys[:r], s: keys[:s])
|
51
|
+
end
|
52
|
+
|
53
|
+
def new_hash(message, size: 256)
|
54
|
+
create_hash.new(message).(size)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Nistp192 = new(
|
6
|
+
name: 'nistp192',
|
7
|
+
p: 62771017353866807638357894232076664160839087_00390324961279,
|
8
|
+
a: -3,
|
9
|
+
b: 0x64210519_e59c80e7_0fa7e9ab_72243049_feb8deec_c146b9b1,
|
10
|
+
gx: 0x188da80e_b03090f6_7cbf20eb_43a18800_f4ff0afd_82ff1012,
|
11
|
+
gy: 0x07192b95_ffc8da78_631011ed_6b24cdd5_73f977a1_1e794811,
|
12
|
+
n: 62771017353866807638357894231760590137671947_73182842284081,
|
13
|
+
h: nil, # cofactor not given in NIST document
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Nistp224 = new(
|
6
|
+
name: 'nistp224',
|
7
|
+
p: 26959946667150639794667015087019630673557916_260026308143510066298881,
|
8
|
+
a: -3,
|
9
|
+
b: 0xb4050a85_0c04b3ab_f5413256_5044b0b7_d7bfd8ba_270b3943_2355ffb4,
|
10
|
+
gx: 0xb70e0cbd_6bb4bf7f_321390b9_4a03c1d3_56c21122_343280d6_115c1d21,
|
11
|
+
gy: 0xbd376388_b5f723fb_4c22dfe6_cd4375a0_5a074764_44d58199_85007e34,
|
12
|
+
n: 26959946667150639794667015087019625940457807_714424391721682722368061,
|
13
|
+
h: nil, # cofactor not given in NIST document
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Nistp256 = new(
|
6
|
+
name: 'nistp256',
|
7
|
+
p: 11579208921035624876269744694940757353008614_3415290314195533631308867097853951,
|
8
|
+
a: -3,
|
9
|
+
b: 0x5ac635d8_aa3a93e7_b3ebbd55_769886bc_651d06b0_cc53b0f6_3bce3c3e_27d2604b,
|
10
|
+
gx: 0x6b17d1f2_e12c4247_f8bce6e5_63a440f2_77037d81_2deb33a0_f4a13945_d898c296,
|
11
|
+
gy: 0x4fe342e2_fe1a7f9b_8ee7eb4a_7c0f9e16_2bce3357_6b315ece_cbb64068_37bf51f5,
|
12
|
+
n: 11579208921035624876269744694940757352999695_5224135760342422259061068512044369,
|
13
|
+
h: nil, # cofactor not given in NIST document
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Nistp384 = new(
|
6
|
+
name: 'nistp384',
|
7
|
+
p: 39402006196394479212279040100143613805079739_27046544666794829340424572177149687032904726_6088258938001861606973112319,
|
8
|
+
a: -3,
|
9
|
+
b: 0xb3312fa7_e23ee7e4_988e056b_e3f82d19_181d9c6e_fe814112_0314088f_5013875a_c656398d_8a2ed19d_2a85c8ed_d3ec2aef,
|
10
|
+
gx: 0xaa87ca22_be8b0537_8eb1c71e_f320ad74_6e1d3b62_8ba79b98_59f741e0_82542a38_5502f25d_bf55296c_3a545e38_72760ab7,
|
11
|
+
gy: 0x3617de4a_96262c6f_5d9e98bf_9292dc29_f8f41dbd_289a147c_e9da3113_b5f0b8c0_0a60b1ce_1d7e819d_7a431d7c_90ea0e5f,
|
12
|
+
n: 39402006196394479212279040100143613805079739_27046544666794690527962765939911326356939895_6308152294913554433653942643,
|
13
|
+
h: nil, # cofactor not given in NIST document
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: "Curve P-256" from http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.doc
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Nistp521 = new(
|
6
|
+
name: 'nistp521',
|
7
|
+
p: 68647976601306097149819007990813932172694353_00143305409394463459185543183397656052122559_64066145455497729631139148085803712198799971_6643812574028291115057151,
|
8
|
+
a: -3,
|
9
|
+
b: 0x051_953eb961_8e1c9a1f_929a21a0_b68540ee_a2da725b_99b315f3_b8b48991_8ef109e1_56193951_ec7e937b_1652c0bd_3bb1bf07_3573df88_3d2c34f1_ef451fd4_6b503f00,
|
10
|
+
gx: 0x00c6_858e06b7_0404e9cd_9e3ecb66_2395b442_9c648139_053fb521_f828af60_6b4d3dba_a14b5e77_efe75928_fe1dc127_a2ffa8de_3348b3c1_856a429b_f97e7e31_c2e5bd66,
|
11
|
+
gy: 0x0118_39296a78_9a3bc004_5c8a5fb4_2c7d1bd9_98f54449_579b4468_17afbd17_273e662c_97ee7299_5ef42640_c550b901_3fad0761_353c7086_a272c240_88be9476_9fd16650,
|
12
|
+
n: 68647976601306097149819007990813932172694353_00143305409394463459185543183397655394245057_74633321719753296399637136332111386476861244_0380340372808892707005449,
|
13
|
+
h: nil, # cofactor not given in NIST document
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: http://www.secg.org/collateral/sec2_final.pdf
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Secp112r1 = new(
|
6
|
+
name: 'secp112r1',
|
7
|
+
p: 0xDB7C_2ABF62E3_5E668076_BEAD208B,
|
8
|
+
a: 0xDB7C_2ABF62E3_5E668076_BEAD2088,
|
9
|
+
b: 0x659E_F8BA0439_16EEDE89_11702B22,
|
10
|
+
gx: 0x0948_7239995A_5EE76B55_F9C2F098,
|
11
|
+
gy: 0xA89C_E5AF8724_C0A23E0E_0FF77500,
|
12
|
+
n: 0xDB7C_2ABF62E3_5E7628DF_AC6561C5,
|
13
|
+
h: 1,
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: http://www.secg.org/collateral/sec2_final.pdf
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Secp112r2 = new(
|
6
|
+
name: 'secp112r2',
|
7
|
+
p: 0xDB7C_2ABF62E3_5E668076_BEAD208B,
|
8
|
+
a: 0x6127_C24C05F3_8A0AAAF6_5C0EF02C,
|
9
|
+
b: 0x51DE_F1815DB5_ED74FCC3_4C85D709,
|
10
|
+
gx: 0x4BA3_0AB5E892_B4E1649D_D0928643,
|
11
|
+
gy: 0xADCD_46F5882E_3747DEF3_6E956E97,
|
12
|
+
n: 0x36DF_0AAFD8B8_D7597CA1_0520D04B,
|
13
|
+
h: 4,
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: http://www.secg.org/collateral/sec2_final.pdf
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Secp128r1 = new(
|
6
|
+
name: 'secp128r1',
|
7
|
+
p: 0xFFFFFFFD_FFFFFFFF_FFFFFFFF_FFFFFFFF,
|
8
|
+
a: 0xFFFFFFFD_FFFFFFFF_FFFFFFFF_FFFFFFFC,
|
9
|
+
b: 0xE87579C1_1079F43D_D824993C_2CEE5ED3,
|
10
|
+
gx: 0x161FF752_8B899B2D_0C28607C_A52C5B86,
|
11
|
+
gy: 0xCF5AC839_5BAFEB13_C02DA292_DDED7A83,
|
12
|
+
n: 0xFFFFFFFE_00000000_75A30D1B_9038A115,
|
13
|
+
h: 1,
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: http://www.secg.org/collateral/sec2_final.pdf
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Secp128r2 = new(
|
6
|
+
name: 'secp128r2',
|
7
|
+
p: 0xFFFFFFFD_FFFFFFFF_FFFFFFFF_FFFFFFFF,
|
8
|
+
a: 0xD6031998_D1B3BBFE_BF59CC9B_BFF9AEE1,
|
9
|
+
b: 0x5EEEFCA3_80D02919_DC2C6558_BB6D8A5D,
|
10
|
+
gx: 0x7B6AA5D8_5E572983_E6FB32A7_CDEBC140,
|
11
|
+
gy: 0x27B6916A_894D3AEE_7106FE80_5FC34B44,
|
12
|
+
n: 0x3FFFFFFF_7FFFFFFF_BE002472_0613B5A3,
|
13
|
+
h: 4,
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: http://www.secg.org/collateral/sec2_final.pdf
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Secp160k1 = new(
|
6
|
+
name: 'secp160k1',
|
7
|
+
p: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFAC73,
|
8
|
+
a: 0,
|
9
|
+
b: 7,
|
10
|
+
gx: 0x3B4C382C_E37AA192_A4019E76_3036F4F5_DD4D7EBB,
|
11
|
+
gy: 0x938CF935_318FDCED_6BC28286_531733C3_F03C4FEE,
|
12
|
+
n: 0x01_00000000_00000000_0001B8FA_16DFAB9A_CA16B6B3,
|
13
|
+
h: 1,
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: http://www.secg.org/collateral/sec2_final.pdf
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Secp160r1 = new(
|
6
|
+
name: 'secp160r1',
|
7
|
+
p: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_7FFFFFFF,
|
8
|
+
a: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_7FFFFFFC,
|
9
|
+
b: 0x1C97BEFC_54BD7A8B_65ACF89F_81D4D4AD_C565FA45,
|
10
|
+
gx: 0x4A96B568_8EF57328_46646989_68C38BB9_13CBFC82,
|
11
|
+
gy: 0x23A62855_3168947D_59DCC912_04235137_7AC5FB32,
|
12
|
+
n: 0x01_00000000_00000000_0001F4C8_F927AED3_CA752257,
|
13
|
+
h: 1,
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: http://www.secg.org/collateral/sec2_final.pdf
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Secp160r2 = new(
|
6
|
+
name: 'secp160r2',
|
7
|
+
p: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFAC73,
|
8
|
+
a: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFAC70,
|
9
|
+
b: 0xB4E134D3_FB59EB8B_AB572749_04664D5A_F50388BA,
|
10
|
+
gx: 0x52DCB034_293A117E_1F4FF11B_30F7199D_3144CE6D,
|
11
|
+
gy: 0xFEAFFEF2_E331F296_E071FA0D_F9982CFE_A7D43F2E,
|
12
|
+
n: 0x01_00000000_00000000_0000351E_E786A818_F3A1A16B,
|
13
|
+
h: 1,
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: http://www.secg.org/collateral/sec2_final.pdf
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Secp192k1 = new(
|
6
|
+
name: 'secp192k1',
|
7
|
+
p: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFEE37,
|
8
|
+
a: 0,
|
9
|
+
b: 3,
|
10
|
+
gx: 0xDB4FF10E_C057E9AE_26B07D02_80B7F434_1DA5D1B1_EAE06C7D,
|
11
|
+
gy: 0x9B2F2F6D_9C5628A7_844163D0_15BE8634_4082AA88_D95E2F9D,
|
12
|
+
n: 0xFFFFFFFF_FFFFFFFF_FFFFFFFE_26F2FC17_0F69466A_74DEFD8D,
|
13
|
+
h: 1,
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: http://www.secg.org/collateral/sec2_final.pdf
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Secp192r1 = new(
|
6
|
+
name: 'secp192r1',
|
7
|
+
p: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFFFF_FFFFFFFF,
|
8
|
+
a: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFFFF_FFFFFFFC,
|
9
|
+
b: 0x64210519_E59C80E7_0FA7E9AB_72243049_FEB8DEEC_C146B9B1,
|
10
|
+
gx: 0x188DA80E_B03090F6_7CBF20EB_43A18800_F4FF0AFD_82FF1012,
|
11
|
+
gy: 0x07192B95_FFC8DA78_631011ED_6B24CDD5_73F977A1_1E794811,
|
12
|
+
n: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_99DEF836_146BC9B1_B4D22831,
|
13
|
+
h: 1,
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: http://www.secg.org/collateral/sec2_final.pdf
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Secp224k1 = new(
|
6
|
+
name: 'secp224k1',
|
7
|
+
p: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFE56D,
|
8
|
+
a: 0,
|
9
|
+
b: 5,
|
10
|
+
gx: 0xA1455B33_4DF099DF_30FC28A1_69A467E9_E47075A9_0F7E650E_B6B7A45C,
|
11
|
+
gy: 0x7E089FED_7FBA3442_82CAFBD6_F7E319F7_C0B0BD59_E2CA4BDB_556D61A5,
|
12
|
+
n: 0x01_00000000_00000000_00000000_0001DCE8_D2EC6184_CAF0A971_769FB1F7,
|
13
|
+
h: 1,
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: http://www.secg.org/collateral/sec2_final.pdf
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Secp224r1 = new(
|
6
|
+
name: 'secp224r1',
|
7
|
+
p: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_00000000_00000000_00000001,
|
8
|
+
a: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFFFF_FFFFFFFF_FFFFFFFE,
|
9
|
+
b: 0xB4050A85_0C04B3AB_F5413256_5044B0B7_D7BFD8BA_270B3943_2355FFB4,
|
10
|
+
gx: 0xB70E0CBD_6BB4BF7F_321390B9_4A03C1D3_56C21122_343280D6_115C1D21,
|
11
|
+
gy: 0xBD376388_B5F723FB_4C22DFE6_CD4375A0_5A074764_44D58199_85007E34,
|
12
|
+
n: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFF16A2_E0B8F03E_13DD2945_5C5C2A3D,
|
13
|
+
h: 1,
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: http://www.secg.org/collateral/sec2_final.pdf
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Secp256k1 = new(
|
6
|
+
name: 'secp256k1',
|
7
|
+
p: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFC2F,
|
8
|
+
a: 0,
|
9
|
+
b: 7,
|
10
|
+
gx: 0x79BE667E_F9DCBBAC_55A06295_CE870B07_029BFCDB_2DCE28D9_59F2815B_16F81798,
|
11
|
+
gy: 0x483ADA77_26A3C465_5DA4FBFC_0E1108A8_FD17B448_A6855419_9C47D08F_FB10D4B8,
|
12
|
+
n: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_BAAEDCE6_AF48A03B_BFD25E8C_D0364141,
|
13
|
+
h: 1,
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: http://www.secg.org/collateral/sec2_final.pdf
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Secp256r1 = new(
|
6
|
+
name: 'secp256r1',
|
7
|
+
p: 0xFFFFFFFF_00000001_00000000_00000000_00000000_FFFFFFFF_FFFFFFFF_FFFFFFFF,
|
8
|
+
a: 0xFFFFFFFF_00000001_00000000_00000000_00000000_FFFFFFFF_FFFFFFFF_FFFFFFFC,
|
9
|
+
b: 0x5AC635D8_AA3A93E7_B3EBBD55_769886BC_651D06B0_CC53B0F6_3BCE3C3E_27D2604B,
|
10
|
+
gx: 0x6B17D1F2_E12C4247_F8BCE6E5_63A440F2_77037D81_2DEB33A0_F4A13945_D898C296,
|
11
|
+
gy: 0x4FE342E2_FE1A7F9B_8EE7EB4A_7C0F9E16_2BCE3357_6B315ECE_CBB64068_37BF51F5,
|
12
|
+
n: 0xFFFFFFFF_00000000_FFFFFFFF_FFFFFFFF_BCE6FAAD_A7179E84_F3B9CAC2_FC632551,
|
13
|
+
h: 1,
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: http://www.secg.org/collateral/sec2_final.pdf
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Secp384r1 = new(
|
6
|
+
name: 'secp384r1',
|
7
|
+
p: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFFFF_00000000_00000000_FFFFFFFF,
|
8
|
+
a: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFFFF_00000000_00000000_FFFFFFFC,
|
9
|
+
b: 0xB3312FA7_E23EE7E4_988E056B_E3F82D19_181D9C6E_FE814112_0314088F_5013875A_C656398D_8A2ED19D_2A85C8ED_D3EC2AEF,
|
10
|
+
gx: 0xAA87CA22_BE8B0537_8EB1C71E_F320AD74_6E1D3B62_8BA79B98_59F741E0_82542A38_5502F25D_BF55296C_3A545E38_72760AB7,
|
11
|
+
gy: 0x3617DE4A_96262C6F_5D9E98BF_9292DC29_F8F41DBD_289A147C_E9DA3113_B5F0B8C0_0A60B1CE_1D7E819D_7A431D7C_90EA0E5F,
|
12
|
+
n: 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_C7634D81_F4372DDF_581A0DB2_48B0A77A_ECEC196A_CCC52973,
|
13
|
+
h: 1,
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Source: http://www.secg.org/collateral/sec2_final.pdf
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
class Group
|
5
|
+
Secp521r1 = new(
|
6
|
+
name: 'secp521r1',
|
7
|
+
p: 0x01FF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF,
|
8
|
+
a: 0x01FF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFC,
|
9
|
+
b: 0x0051_953EB961_8E1C9A1F_929A21A0_B68540EE_A2DA725B_99B315F3_B8B48991_8EF109E1_56193951_EC7E937B_1652C0BD_3BB1BF07_3573DF88_3D2C34F1_EF451FD4_6B503F00,
|
10
|
+
gx: 0x00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66,
|
11
|
+
gy: 0x011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650,
|
12
|
+
n: 0x01FF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFA_51868783_BF2F966B_7FCC0148_F709A5D0_3BB5C9B8_899C47AE_BB6FB71E_91386409,
|
13
|
+
h: 1,
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require_relative './point'
|
3
|
+
|
4
|
+
module CryptoGost
|
5
|
+
# Group
|
6
|
+
#
|
7
|
+
# @author WildDima
|
8
|
+
class Group
|
9
|
+
attr_reader :opts, :generator, :a, :b, :gx, :gy, :order, :p
|
10
|
+
|
11
|
+
def initialize(opts)
|
12
|
+
@opts = opts
|
13
|
+
@name = opts.fetch(:name)
|
14
|
+
@p = opts[:p]
|
15
|
+
@a = opts[:a]
|
16
|
+
@b = opts[:b]
|
17
|
+
@gx = opts[:gx]
|
18
|
+
@gy = opts[:gy]
|
19
|
+
@order = opts[:n]
|
20
|
+
@cofactor = opts[:h]
|
21
|
+
@generator = CryptoGost::Point.new self, [gx, gy]
|
22
|
+
end
|
23
|
+
|
24
|
+
NAMES = %w(
|
25
|
+
Nistp192
|
26
|
+
Nistp224
|
27
|
+
Nistp256
|
28
|
+
Nistp384
|
29
|
+
Nistp521
|
30
|
+
Secp112r1
|
31
|
+
Secp112r2
|
32
|
+
Secp128r1
|
33
|
+
Secp128r2
|
34
|
+
Secp160k1
|
35
|
+
Secp160r1
|
36
|
+
Secp160r2
|
37
|
+
Secp192k1
|
38
|
+
Secp192r1
|
39
|
+
Secp224k1
|
40
|
+
Secp224r1
|
41
|
+
Secp256k1
|
42
|
+
Secp256r1
|
43
|
+
Secp384r1
|
44
|
+
Secp521r1
|
45
|
+
).freeze
|
46
|
+
|
47
|
+
NAMES.each do |name|
|
48
|
+
require_relative "./group/#{name.downcase}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def generate_public_key(private_key)
|
52
|
+
generator * private_key
|
53
|
+
end
|
54
|
+
|
55
|
+
def generate_private_key
|
56
|
+
1 + SecureRandom.random_number(order - 1)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module CryptoGost
|
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 CryptoGost
|
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,32 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
# DigitalSignature
|
5
|
+
#
|
6
|
+
# @author WildDima
|
7
|
+
class Signature
|
8
|
+
attr_reader :r, :s
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def decode(sign)
|
12
|
+
asn1 = OpenSSL::ASN1.decode(sign)
|
13
|
+
r = asn1.value[0].value.to_i
|
14
|
+
s = asn1.value[1].value.to_i
|
15
|
+
new(r, s)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(r:, s:)
|
20
|
+
@r = r
|
21
|
+
@s = s
|
22
|
+
end
|
23
|
+
|
24
|
+
def encode
|
25
|
+
asn1 = OpenSSL::ASN1::Sequence.new [
|
26
|
+
OpenSSL::ASN1::Integer.new(r),
|
27
|
+
OpenSSL::ASN1::Integer.new(s),
|
28
|
+
]
|
29
|
+
asn1.to_der
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'stribog'
|
2
|
+
|
3
|
+
module CryptoGost
|
4
|
+
# DigitalSignature
|
5
|
+
#
|
6
|
+
# @author WildDima
|
7
|
+
class Verify
|
8
|
+
attr_reader :group, :public_key, :create_hash, :message
|
9
|
+
|
10
|
+
def initialize(message, group, create_hash = Stribog::CreateHash)
|
11
|
+
@message = message
|
12
|
+
@group = group
|
13
|
+
@create_hash = create_hash
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(public_key, sign)
|
17
|
+
@public_key = public_key
|
18
|
+
@sign = sign
|
19
|
+
@hashed_message = hash_message(@message, size: 256)
|
20
|
+
r = sign.r
|
21
|
+
s = sign.s
|
22
|
+
return false if invalid_vector?(r) || invalid_vector?(s)
|
23
|
+
(c_param(r, s).x % group.order) == r
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def hash_message(message, size: 256)
|
29
|
+
create_hash.new(message).(size)
|
30
|
+
end
|
31
|
+
|
32
|
+
def hash_mod_ecn
|
33
|
+
hashed = hash_message(message, size: 256).dec
|
34
|
+
hashed.zero? ? 1 : hashed
|
35
|
+
end
|
36
|
+
|
37
|
+
def mod_inv(opt, mod)
|
38
|
+
ModularArithmetic.invert(opt, mod)
|
39
|
+
end
|
40
|
+
|
41
|
+
def valid_vector?(vector)
|
42
|
+
(1...group.order).cover? vector
|
43
|
+
end
|
44
|
+
|
45
|
+
def invalid_vector?(vector)
|
46
|
+
!valid_vector?(vector)
|
47
|
+
end
|
48
|
+
|
49
|
+
def z_param(param)
|
50
|
+
param * mod_inv(hash_mod_ecn, group.order) %
|
51
|
+
group.order
|
52
|
+
end
|
53
|
+
|
54
|
+
def c_param(r, s)
|
55
|
+
group.generator * z_param(s) + public_key * z_param(-r)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/crypto_gost.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# Gost cryptography
|
2
|
+
#
|
3
|
+
# @author WildDima
|
4
|
+
module CryptoGost
|
5
|
+
require_relative './crypto_gost/version'
|
6
|
+
require_relative './crypto_gost/create'
|
7
|
+
require_relative './crypto_gost/verify'
|
8
|
+
require_relative './crypto_gost/signature'
|
9
|
+
require_relative './crypto_gost/group'
|
10
|
+
require_relative './crypto_gost/point'
|
11
|
+
require_relative './crypto_gost/modular_arithmetic'
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: crypto_gost
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- WildDima
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-04-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: stribog
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.2.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.2.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.12'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.12'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: byebug
|
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: faker
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
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
|
+
- dtopornin@gmail.com
|
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_gost.gemspec
|
130
|
+
- lib/crypto_gost.rb
|
131
|
+
- lib/crypto_gost/create.rb
|
132
|
+
- lib/crypto_gost/group.rb
|
133
|
+
- lib/crypto_gost/group/nistp192.rb
|
134
|
+
- lib/crypto_gost/group/nistp224.rb
|
135
|
+
- lib/crypto_gost/group/nistp256.rb
|
136
|
+
- lib/crypto_gost/group/nistp384.rb
|
137
|
+
- lib/crypto_gost/group/nistp521.rb
|
138
|
+
- lib/crypto_gost/group/secp112r1.rb
|
139
|
+
- lib/crypto_gost/group/secp112r2.rb
|
140
|
+
- lib/crypto_gost/group/secp128r1.rb
|
141
|
+
- lib/crypto_gost/group/secp128r2.rb
|
142
|
+
- lib/crypto_gost/group/secp160k1.rb
|
143
|
+
- lib/crypto_gost/group/secp160r1.rb
|
144
|
+
- lib/crypto_gost/group/secp160r2.rb
|
145
|
+
- lib/crypto_gost/group/secp192k1.rb
|
146
|
+
- lib/crypto_gost/group/secp192r1.rb
|
147
|
+
- lib/crypto_gost/group/secp224k1.rb
|
148
|
+
- lib/crypto_gost/group/secp224r1.rb
|
149
|
+
- lib/crypto_gost/group/secp256k1.rb
|
150
|
+
- lib/crypto_gost/group/secp256r1.rb
|
151
|
+
- lib/crypto_gost/group/secp384r1.rb
|
152
|
+
- lib/crypto_gost/group/secp521r1.rb
|
153
|
+
- lib/crypto_gost/modular_arithmetic.rb
|
154
|
+
- lib/crypto_gost/point.rb
|
155
|
+
- lib/crypto_gost/signature.rb
|
156
|
+
- lib/crypto_gost/verify.rb
|
157
|
+
- lib/crypto_gost/version.rb
|
158
|
+
homepage: http://github.com/WildDima/crypto_gost
|
159
|
+
licenses:
|
160
|
+
- MIT
|
161
|
+
metadata: {}
|
162
|
+
post_install_message:
|
163
|
+
rdoc_options: []
|
164
|
+
require_paths:
|
165
|
+
- lib
|
166
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
167
|
+
requirements:
|
168
|
+
- - ">="
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: '0'
|
171
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
172
|
+
requirements:
|
173
|
+
- - ">="
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: '0'
|
176
|
+
requirements: []
|
177
|
+
rubyforge_project:
|
178
|
+
rubygems_version: 2.6.8
|
179
|
+
signing_key:
|
180
|
+
specification_version: 4
|
181
|
+
summary: Write a short summary, because Rubygems requires one.
|
182
|
+
test_files: []
|