argon2 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +35 -8
- data/lib/argon2/profiles.rb +50 -0
- data/lib/argon2/version.rb +1 -1
- data/lib/argon2.rb +27 -7
- data/sig/argon2.rbs +29 -9
- data/sig/engine.rbs +9 -0
- data/sig/errors.rbs +6 -0
- data/sig/ffi.rbs +3 -3
- data/sig/hash_format.rbs +31 -0
- metadata +10 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77cb6034627eab11765cd70555304c694e3f3f20febe4fed4fa986f7c77bc8b1
|
4
|
+
data.tar.gz: 80f8821f1a3f14f45947644f7e2c538ce3287c2c42a32f6d62f12b34c9e16d9c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 72fa1e22c23e7c7e47fd03270a90af60e95d7891493d877eb961c6b4087999557ca2accb9b5ed1a7bc94fd2e5f05d98688360f941069a946f37bf20f1b0c9506
|
7
|
+
data.tar.gz: dfff839d55b2f7ca06183d1cd6006aa45a79bf249081f039cdd486d53100dc2ea293f789d9a8ffa87aa69fb6d2d4413c35c296e214fb527ee172789d5f7b74cb
|
data/README.md
CHANGED
@@ -27,26 +27,50 @@ Require this in your Gemfile like a typical Ruby gem:
|
|
27
27
|
require 'argon2'
|
28
28
|
```
|
29
29
|
|
30
|
-
To
|
30
|
+
To utilise default costs ([RFC 9106](https://www.rfc-editor.org/rfc/rfc9106#name-parameter-choice)'s lower-memory, second recommended parameters):
|
31
31
|
|
32
32
|
```ruby
|
33
|
-
hasher = Argon2::Password.new
|
33
|
+
hasher = Argon2::Password.new
|
34
34
|
hasher.create("password")
|
35
|
-
=> "$argon2i$v=19$m=65536,t=2,p=1$jL7lLEAjDN+pY2cG1N8D2g$iwj1ueduCvm6B9YVjBSnAHu+6mKzqGmDW745ALR38Uo"
|
36
35
|
```
|
37
36
|
|
38
|
-
|
37
|
+
Alternatively, use this shortcut:
|
39
38
|
|
40
39
|
```ruby
|
41
|
-
|
40
|
+
Argon2::Password.create("password")
|
41
|
+
=> "$argon2i$v=19$m=65536,t=2,p=1$61qkSyYNbUgf3kZH3GtHRw$4CQff9AZ0lWd7uF24RKMzqEiGpzhte1Hp8SO7X8bAew"
|
42
|
+
```
|
43
|
+
|
44
|
+
If your use case can afford the higher memory consumption/cost, you can/should specify to use RFC 9106's first recommended parameters:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
hasher = Argon2::Password.new(profile: :rfc_9106_high_memory)
|
42
48
|
hasher.create("password")
|
49
|
+
=> "$argon2id$v=19$m=2097152,t=1,p=4$LvHa74Yax7uCWPN7P6/oQQ$V1dMt4dfuYSmLpwUTpKUzg+RrXjWzWHlE6NLowBzsAg"
|
43
50
|
```
|
44
51
|
|
45
|
-
|
52
|
+
To generate a hash using one of the other `Argon::Profiles` names:
|
46
53
|
|
47
54
|
```ruby
|
48
|
-
|
49
|
-
|
55
|
+
# Only use this profile in testing env, it's unsafe!
|
56
|
+
hasher = Argon2::Password.new(profile: :unsafe_cheapest)
|
57
|
+
hasher.create("password")
|
58
|
+
=> "$argon2id$v=19$m=8,t=1,p=1$HZZHG3oTqptqgrxWxFic5g$EUokHMU6m6w2AVIEk1MpZBhVwW9Nj+ESRjPwTBVtWpY"
|
59
|
+
```
|
60
|
+
|
61
|
+
The list of named cost profiles are:
|
62
|
+
|
63
|
+
* `:rfc_9106_high_memory`: the first recommended option but is expensive
|
64
|
+
* `:rfc_9106_low_memory`: the second recommended option (default)
|
65
|
+
* `:pre_rfc_9106`: the previous default costs for `ruby-argon2` <= v2.2.0, before offering RFC 9106 named profiles
|
66
|
+
* `:unsafe_cheapest`: Strictly for testing, the minimum costs allowed by Argon2 for the fastest hashing speed
|
67
|
+
|
68
|
+
To generate a hash using specific time and memory cost:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
hasher = Argon2::Password.new(t_cost: 2, m_cost: 16, p_cost: 1)
|
72
|
+
hasher.create("password")
|
73
|
+
=> "$argon2i$v=19$m=65536,t=2,p=1$jL7lLEAjDN+pY2cG1N8D2g$iwj1ueduCvm6B9YVjBSnAHu+6mKzqGmDW745ALR38Uo"
|
50
74
|
```
|
51
75
|
|
52
76
|
You can then use this function to verify a password against a given hash. Will return either true or false.
|
@@ -81,6 +105,9 @@ steep check
|
|
81
105
|
```
|
82
106
|
These tools will need to be installed manually at this time and will be added to Gemfiles after much further testing.
|
83
107
|
|
108
|
+
## Version 2.2.0
|
109
|
+
This version changed the way the build system works to deal with a new version of Rubygems. See https://github.com/technion/ruby-argon2/issues/56.
|
110
|
+
|
84
111
|
## Version 2.0 - Argon 2id
|
85
112
|
Version 2.x upwards will now default to the Argon2id hash format. This is consistent with current recommendations regarding Argon2 usage. It remains capable of verifying existing hashes.
|
86
113
|
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Argon2
|
4
|
+
# Contains named profiles of different common cost parameter sets
|
5
|
+
class Profiles
|
6
|
+
def self.[](name)
|
7
|
+
name = name.upcase.to_sym
|
8
|
+
raise NotImplementedError unless const_defined?(name)
|
9
|
+
|
10
|
+
const_get(name)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.to_a
|
14
|
+
constants.map(&:downcase)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.to_h
|
18
|
+
to_a.reduce({}) { |h, name| h.update(name => self[name]) }
|
19
|
+
end
|
20
|
+
|
21
|
+
# https://datatracker.ietf.org/doc/html/rfc9106#name-argon2-algorithm
|
22
|
+
# FIRST RECOMMENDED option per RFC 9106.
|
23
|
+
RFC_9106_HIGH_MEMORY = {
|
24
|
+
t_cost: 1,
|
25
|
+
m_cost: 21, # 2 GiB
|
26
|
+
p_cost: 4
|
27
|
+
}.freeze
|
28
|
+
|
29
|
+
# SECOND RECOMMENDED option per RFC 9106.
|
30
|
+
RFC_9106_LOW_MEMORY = {
|
31
|
+
t_cost: 3,
|
32
|
+
m_cost: 16, # 64 MiB
|
33
|
+
p_cost: 4
|
34
|
+
}.freeze
|
35
|
+
|
36
|
+
# The default values ruby-argon2 had before using RFC 9106 recommendations
|
37
|
+
PRE_RFC_9106 = {
|
38
|
+
t_cost: 2,
|
39
|
+
m_cost: 16, # 64 MiB
|
40
|
+
p_cost: 1
|
41
|
+
}.freeze
|
42
|
+
|
43
|
+
# Only use for fast testing. Insecure otherwise!
|
44
|
+
UNSAFE_CHEAPEST = {
|
45
|
+
t_cost: 1,
|
46
|
+
m_cost: 3, # 8 KiB
|
47
|
+
p_cost: 1
|
48
|
+
}.freeze
|
49
|
+
end
|
50
|
+
end
|
data/lib/argon2/version.rb
CHANGED
data/lib/argon2.rb
CHANGED
@@ -6,19 +6,26 @@ require 'argon2/version'
|
|
6
6
|
require 'argon2/errors'
|
7
7
|
require 'argon2/engine'
|
8
8
|
require 'argon2/hash_format'
|
9
|
+
require 'argon2/profiles'
|
9
10
|
|
10
11
|
module Argon2
|
11
12
|
# Front-end API for the Argon2 module.
|
12
13
|
class Password
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
# Expose constants for the options supported and default used for passwords.
|
15
|
+
DEFAULT_T_COST = Argon2::Profiles::RFC_9106_LOW_MEMORY[:t_cost]
|
16
|
+
DEFAULT_M_COST = Argon2::Profiles::RFC_9106_LOW_MEMORY[:m_cost]
|
17
|
+
DEFAULT_P_COST = Argon2::Profiles::RFC_9106_LOW_MEMORY[:p_cost]
|
18
|
+
MIN_T_COST = 1
|
19
|
+
MAX_T_COST = 750
|
20
|
+
MIN_M_COST = 3
|
21
|
+
MAX_M_COST = 31
|
22
|
+
MIN_P_COST = 1
|
23
|
+
MAX_P_COST = 8
|
16
24
|
|
17
|
-
|
18
|
-
|
25
|
+
def initialize(options = {})
|
26
|
+
options.update(Profiles[options[:profile]]) if options.key?(:profile)
|
19
27
|
|
20
|
-
|
21
|
-
raise ArgonHashFail, "Invalid p_cost" if @p_cost < 1 || @p_cost > 8
|
28
|
+
init_costs(options)
|
22
29
|
|
23
30
|
@salt_do_not_supply = options[:salt_do_not_supply]
|
24
31
|
@secret = options[:secret]
|
@@ -50,5 +57,18 @@ module Argon2
|
|
50
57
|
|
51
58
|
Argon2::Engine.argon2_verify(pass, hash, secret)
|
52
59
|
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
|
63
|
+
def init_costs(options = {})
|
64
|
+
@t_cost = options[:t_cost] || DEFAULT_T_COST
|
65
|
+
raise ArgonHashFail, "Invalid t_cost" if @t_cost < MIN_T_COST || @t_cost > MAX_T_COST
|
66
|
+
|
67
|
+
@m_cost = options[:m_cost] || DEFAULT_M_COST
|
68
|
+
raise ArgonHashFail, "Invalid m_cost" if @m_cost < MIN_M_COST || @m_cost > MAX_M_COST
|
69
|
+
|
70
|
+
@p_cost = options[:p_cost] || DEFAULT_P_COST
|
71
|
+
raise ArgonHashFail, "Invalid p_cost" if @p_cost < MIN_P_COST || @p_cost > MAX_P_COST
|
72
|
+
end
|
53
73
|
end
|
54
74
|
end
|
data/sig/argon2.rbs
CHANGED
@@ -1,21 +1,41 @@
|
|
1
|
-
# Classes
|
2
1
|
module Argon2
|
2
|
+
# Front-end API for the Argon2 module.
|
3
3
|
class Password
|
4
4
|
@t_cost: Integer
|
5
5
|
@m_cost: Integer
|
6
6
|
@p_cost: Integer
|
7
7
|
@salt: nil | String
|
8
8
|
@secret: nil | String
|
9
|
+
@salt_do_not_supply: nil | String
|
10
|
+
|
11
|
+
# Expose constants for the options supported and default used for passwords.
|
12
|
+
DEFAULT_T_COST: 2
|
13
|
+
|
14
|
+
DEFAULT_M_COST: 16
|
15
|
+
|
16
|
+
DEFAULT_P_COST: 1
|
17
|
+
|
18
|
+
MIN_T_COST: 1
|
19
|
+
|
20
|
+
MAX_T_COST: 750
|
21
|
+
|
22
|
+
MIN_M_COST: 1
|
23
|
+
|
24
|
+
MAX_M_COST: 31
|
25
|
+
|
26
|
+
MIN_P_COST: 1
|
27
|
+
|
28
|
+
MAX_P_COST: 8
|
9
29
|
|
10
30
|
def initialize: (?::Hash[untyped, untyped] options) -> void
|
31
|
+
|
11
32
|
def create: (String pass) -> untyped
|
12
|
-
|
13
|
-
|
14
|
-
def self.
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
class ArgonHashFail < StandardError
|
33
|
+
|
34
|
+
# Helper class, just creates defaults and calls hash()
|
35
|
+
def self.create: (String pass, ?::Hash[untyped, untyped] options) -> String
|
36
|
+
|
37
|
+
def self.valid_hash?: (String hash) -> bool
|
38
|
+
|
39
|
+
def self.verify_password: (String pass, String hash, ?String|nil secret) -> bool
|
20
40
|
end
|
21
41
|
end
|
data/sig/engine.rbs
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
module Argon2
|
2
|
+
# SecureRandom is a Ruby module. I have no idea why steep now thinks it's an unknown constant, nor why rbs
|
3
|
+
# prototype has no interest in outputting this.
|
4
|
+
SecureRandom: untyped
|
5
|
+
# Generates a random, binary string for use as a salt.
|
6
|
+
class Engine
|
7
|
+
def self.saltgen: () -> untyped
|
8
|
+
end
|
9
|
+
end
|
data/sig/errors.rbs
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
module Argon2
|
2
|
+
class ArgonHashFail < StandardError
|
3
|
+
end
|
4
|
+
|
5
|
+
ERRORS: ::Array["ARGON2_OK" | "ARGON2_OUTPUT_PTR_NULL" | "ARGON2_OUTPUT_TOO_SHORT" | "ARGON2_OUTPUT_TOO_LONG" | "ARGON2_PWD_TOO_SHORT" | "ARGON2_PWD_TOO_LONG" | "ARGON2_SALT_TOO_SHORT" | "ARGON2_SALT_TOO_LONG" | "ARGON2_AD_TOO_SHORT" | "ARGON2_AD_TOO_LONG" | "ARGON2_SECRET_TOO_SHORT" | "ARGON2_SECRET_TOO_LONG" | "ARGON2_TIME_TOO_SMALL" | "ARGON2_TIME_TOO_LARGE" | "ARGON2_MEMORY_TOO_LITTLE" | "ARGON2_MEMORY_TOO_MUCH" | "ARGON2_LANES_TOO_FEW" | "ARGON2_LANES_TOO_MANY" | "ARGON2_PWD_PTR_MISMATCH" | "ARGON2_SALT_PTR_MISMATCH" | "ARGON2_SECRET_PTR_MISMATCH" | "ARGON2_AD_PTR_MISMATCH" | "ARGON2_MEMORY_ALLOCATION_ERROR" | "ARGON2_FREE_MEMORY_CBK_NULL" | "ARGON2_ALLOCATE_MEMORY_CBK_NULL" | "ARGON2_INCORRECT_PARAMETER" | "ARGON2_INCORRECT_TYPE" | "ARGON2_OUT_PTR_MISMATCH" | "ARGON2_THREADS_TOO_FEW" | "ARGON2_THREADS_TOO_MANY" | "ARGON2_MISSING_ARGS" | "ARGON2_ENCODING_FAIL" | "ARGON2_DECODING_FAIL" | "ARGON2_THREAD_FAIL"]
|
6
|
+
end
|
data/sig/ffi.rbs
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module Argon2
|
2
2
|
# Direct external bindings. Call these methods via the Engine class to ensure points are dealt with
|
3
|
-
module Ext
|
4
|
-
extend FFI::Library
|
5
|
-
end
|
3
|
+
# module Ext
|
4
|
+
# extend FFI::Library
|
5
|
+
# end
|
6
6
|
|
7
7
|
# The engine class shields users from the FFI interface.
|
8
8
|
# It is generally not advised to directly use this class.
|
data/sig/hash_format.rbs
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Argon2
|
2
|
+
#
|
3
|
+
# Get the values from an Argon2 compatible string.
|
4
|
+
#
|
5
|
+
class HashFormat
|
6
|
+
attr_reader variant: untyped
|
7
|
+
|
8
|
+
attr_reader version: untyped
|
9
|
+
|
10
|
+
attr_reader t_cost: untyped
|
11
|
+
|
12
|
+
attr_reader m_cost: untyped
|
13
|
+
|
14
|
+
attr_reader p_cost: untyped
|
15
|
+
|
16
|
+
attr_reader salt: untyped
|
17
|
+
|
18
|
+
attr_reader checksum: untyped
|
19
|
+
|
20
|
+
# FIXME: Reduce complexity/AbcSize
|
21
|
+
# rubocop:disable Metrics/AbcSize
|
22
|
+
def initialize: (untyped digest) -> void
|
23
|
+
|
24
|
+
#
|
25
|
+
# Checks whether a given digest is a valid Argon2 hash.
|
26
|
+
#
|
27
|
+
# Supports 1 and argon2id formats.
|
28
|
+
#
|
29
|
+
def self.valid_hash?: (untyped digest) -> untyped
|
30
|
+
end
|
31
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: argon2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Technion
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -250,17 +250,21 @@ files:
|
|
250
250
|
- lib/argon2/errors.rb
|
251
251
|
- lib/argon2/ffi_engine.rb
|
252
252
|
- lib/argon2/hash_format.rb
|
253
|
+
- lib/argon2/profiles.rb
|
253
254
|
- lib/argon2/version.rb
|
254
255
|
- sig/argon2.rbs
|
255
256
|
- sig/constants.rbs
|
257
|
+
- sig/engine.rbs
|
258
|
+
- sig/errors.rbs
|
256
259
|
- sig/ffi.rbs
|
260
|
+
- sig/hash_format.rbs
|
257
261
|
- sig/version.rbs
|
258
262
|
homepage: https://github.com/technion/ruby-argon2
|
259
263
|
licenses:
|
260
264
|
- MIT
|
261
265
|
metadata:
|
262
266
|
rubygems_mfa_required: 'true'
|
263
|
-
post_install_message:
|
267
|
+
post_install_message:
|
264
268
|
rdoc_options: []
|
265
269
|
require_paths:
|
266
270
|
- lib
|
@@ -275,8 +279,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
275
279
|
- !ruby/object:Gem::Version
|
276
280
|
version: '0'
|
277
281
|
requirements: []
|
278
|
-
rubygems_version: 3.3.
|
279
|
-
signing_key:
|
282
|
+
rubygems_version: 3.3.15
|
283
|
+
signing_key:
|
280
284
|
specification_version: 4
|
281
285
|
summary: Argon2 Password hashing binding
|
282
286
|
test_files: []
|