Skip to content

Instantly share code, notes, and snippets.

@Freaky
Created August 25, 2023 03:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Freaky/062d1210f377455b83b075ab3570fdd8 to your computer and use it in GitHub Desktop.
Save Freaky/062d1210f377455b83b075ab3570fdd8 to your computer and use it in GitHub Desktop.
A faster pure Ruby constant-time secure compare
def fixed_length_secure_compare(a, b)
raise ArgumentError, 'length mismatch' unless a.bytesize == b.bytesize
res = 0
if a.bytesize >= 4 && a.bytesize % 4 == 0
ai = a.unpack "L*"
bi = b.unpack "L*"
ai.each { |int| res |= int ^ bi.shift }
else
ab = a.bytes
b.each_byte { |byte| res |= byte ^ ab.shift }
end
res == 0
end
@Freaky
Copy link
Author

Freaky commented Aug 25, 2023

Against a SHA256 hexdigest:

       rails compare    157.661k (± 0.1%) i/s -    803.505k in   5.096422s
        fast compare    447.140k (± 6.1%) i/s -      2.236M in   5.016808s
     OpenSSL compare     13.818M (± 9.0%) i/s -     69.452M in   5.067903s

Might have been useful prior to OpenSSL.fixed_length_secure_compare - now it's just a bit of fun.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment