lib/blind_index.rb in blind_index-0.3.3 vs lib/blind_index.rb in blind_index-0.3.4

- old
+ new

@@ -11,11 +11,11 @@ class << self attr_accessor :default_options end self.default_options = { iterations: 10000, - algorithm: :pbkdf2_hmac, + algorithm: :pbkdf2_sha256, insecure_key: false, encode: true, cost: {} } @@ -25,38 +25,56 @@ # apply expression value = options[:expression].call(value) if options[:expression] unless value.nil? algorithm = options[:algorithm].to_sym + algorithm = :pbkdf2_sha256 if algorithm == :pbkdf2_hmac + algorithm = :argon2i if algorithm == :argon2 key = key.call if key.respond_to?(:call) raise BlindIndex::Error, "Missing key for blind index" unless key key = key.to_s - unless options[:insecure_key] && algorithm == :pbkdf2_hmac + unless options[:insecure_key] && algorithm == :pbkdf2_sha256 raise BlindIndex::Error, "Key must use binary encoding" if key.encoding != Encoding::BINARY - # raise BlindIndex::Error, "Key must not be ASCII" if key.bytes.all? { |b| b < 128 } raise BlindIndex::Error, "Key must be 32 bytes" if key.bytesize != 32 end # gist to compare algorithm results # https://gist.github.com/ankane/fe3ac63fbf1c4550ee12554c664d2b8c cost_options = options[:cost] + # check size + size = (options[:size] || 32).to_i + raise BlindIndex::Error, "Size must be between 1 and 32" unless (1..32).include?(size) + + value = value.to_s + value = case algorithm when :scrypt n = cost_options[:n] || 4096 r = cost_options[:r] || 8 cp = cost_options[:p] || 1 - SCrypt::Engine.scrypt(value.to_s, key, n, r, cp, 32) - when :argon2 - t = cost_options[:t] || 3 - m = cost_options[:m] || 12 - [Argon2::Engine.hash_argon2i(value.to_s, key, t, m)].pack("H*") - when :pbkdf2_hmac + SCrypt::Engine.scrypt(value, key, n, r, cp, size) + when :argon2i + t = (cost_options[:t] || 3).to_i + # use same bounds as rbnacl + raise BlindIndex::Error, "t must be between 3 and 10" if t < 3 || t > 10 + + # m is memory in kibibytes (1024 bytes) + m = (cost_options[:m] || 12).to_i + # use same bounds as rbnacl + raise BlindIndex::Error, "m must be between 3 and 22" if m < 3 || m > 22 + + # 32 byte digest size is limitation of argon2 gem + # this is no longer the case on master + # TODO add conditional check when next version of argon2 is released + raise BlindIndex::Error, "Size must be 32" unless size == 32 + [Argon2::Engine.hash_argon2i(value, key, t, m)].pack("H*") + when :pbkdf2_sha256 iterations = cost_options[:iterations] || options[:iterations] - OpenSSL::PKCS5.pbkdf2_hmac(value.to_s, key, iterations, 32, "sha256") + OpenSSL::PKCS5.pbkdf2_hmac(value, key, iterations, size, "sha256") else raise BlindIndex::Error, "Unknown algorithm" end encode = options[:encode]