argon2 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f926025634562667dbc1575383b09a6d3178248f1551325726f1dc194472b0e5
4
- data.tar.gz: a4876cbbaf99df1062ac39f668e3af254c5b45b1d431bf5e7180e3076fd20d3d
3
+ metadata.gz: 77cb6034627eab11765cd70555304c694e3f3f20febe4fed4fa986f7c77bc8b1
4
+ data.tar.gz: 80f8821f1a3f14f45947644f7e2c538ce3287c2c42a32f6d62f12b34c9e16d9c
5
5
  SHA512:
6
- metadata.gz: e5c592dc870390af4ad6fbce1ea4b3b4b5be6fa25574f18ac44d0509dab1adef3bb21e1e1c5a84b01d364e335f4b4b01460a0a4207c96734ae67f0b4ff12289a
7
- data.tar.gz: c59f5baeea0c7ff436f77a4dadc267c5619ceccf2749ee25a428173abbf4842606a48bbd90f74a89cbd6347cc31dc643447b926cb6caccdcbcf04d7eabfb19a8
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 generate a hash using specific time and memory cost:
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(t_cost: 2, m_cost: 16, p_cost: 1)
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
- To utilise default costs:
37
+ Alternatively, use this shortcut:
39
38
 
40
39
  ```ruby
41
- hasher = Argon2::Password.new
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
- Alternatively, use this shortcut:
52
+ To generate a hash using one of the other `Argon::Profiles` names:
46
53
 
47
54
  ```ruby
48
- Argon2::Password.create("password")
49
- => "$argon2i$v=19$m=65536,t=2,p=1$61qkSyYNbUgf3kZH3GtHRw$4CQff9AZ0lWd7uF24RKMzqEiGpzhte1Hp8SO7X8bAew"
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
@@ -3,5 +3,5 @@
3
3
  # Standard Gem version constant.
4
4
 
5
5
  module Argon2
6
- VERSION = "2.2.0"
6
+ VERSION = "2.3.0"
7
7
  end
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
- def initialize(options = {})
14
- @t_cost = options[:t_cost] || 2
15
- raise ArgonHashFail, "Invalid t_cost" if @t_cost < 1 || @t_cost > 750
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
- @m_cost = options[:m_cost] || 16
18
- raise ArgonHashFail, "Invalid m_cost" if @m_cost < 1 || @m_cost > 31
25
+ def initialize(options = {})
26
+ options.update(Profiles[options[:profile]]) if options.key?(:profile)
19
27
 
20
- @p_cost = options[:p_cost] || 1
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
- def self.create: (String pass) -> untyped
13
- def self.valid_hash?: (string hash) -> Integer?
14
- def self.verify_password: (untyped pass, untyped hash, ?nil secret) -> untyped
15
- end
16
- class Engine
17
- def self.saltgen: () -> String
18
- end
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.
@@ -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.2.0
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: 2022-12-27 00:00:00.000000000 Z
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.5
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: []