To make things fast, while keeping them simple, I redefined the function in C, and made it available as a gem .
The source is on GitHub ( https://github.com/daxtens/fast_secure_compare ), but its essence is the following very simple C.
int secure_compare_bytes(const unsigned char * secret, unsigned int secret_len, const unsigned char * input, unsigned int input_len) { int input_pos; int secret_pos = 0; int result = secret_len - input_len;
`` ``
There's also a bit of FFI glue to make him talk to Ruby.
This is much faster than the original pure Ruby, and somewhat faster (and much easier) than hashing. I edited the rehearsals for short. This is on a 2008 MacBook. You can replicate this using timing.rb in the demo directory.
==== Long text ==== user system total real ==, early fail 0.000000 0.000000 0.000000 ( 0.000028) ==, late fail 0.000000 0.000000 0.000000 ( 0.000710) Pure Ruby secure_compare, 'early' 1.730000 0.040000 1.770000 ( 1.777258) Pure Ruby secure_compare, 'late' 1.730000 0.050000 1.780000 ( 1.774144) C-based FastSecureCompare, 'early' 0.040000 0.000000 0.040000 ( 0.047612) C-based FastSecureCompare, 'late' 0.040000 0.000000 0.040000 ( 0.045767) SHA512-then-==, 'early' 0.050000 0.000000 0.050000 ( 0.048569) SHA512-then-==, 'late' 0.050000 0.000000 0.050000 ( 0.046100) ==== Short text ==== user system total real ==, early fail 0.000000 0.000000 0.000000 ( 0.000028) ==, late fail 0.000000 0.000000 0.000000 ( 0.000031) Pure Ruby secure_compare, 'early' 0.010000 0.000000 0.010000 ( 0.010552) Pure Ruby secure_compare, 'late' 0.010000 0.000000 0.010000 ( 0.010805) C-based FastSecureCompare, 'early' 0.000000 0.000000 0.000000 ( 0.000556) C-based FastSecureCompare, 'late' 0.000000 0.000000 0.000000 ( 0.000516) SHA512-then-==, 'early' 0.000000 0.000000 0.000000 ( 0.000780) SHA512-then-==, 'late' 0.000000 0.000000 0.000000 ( 0.000812)
source share