How did i missed it?
well then we can replace 'all?' with reducing here:

if computed_mac.length == presented_mac.length then
  computed_mac.chars.zip(presented_mac.chars).map {|x,y| x == y}.reduce(:&)
end

But as everyone mentioned here, simply comparing hashes is better option,
because good hashes (like SHA) changes significantly when original value
changes slightly.

2012/5/29 Martin Bolet <martin.bosslet / googlemail.com>

> 2012/5/29 Dmitry S. Kravtsov <idkravitz / gmail.com>:
> > Ok, now I get it,
> > well I may only suggest to use high order functions, and write it like
> this:
> >
> > if computed_mac.length == presented_mac.length then
> >   computed_mac.chars.zip(presented_mac.chars).map {|x,y| x == y}.all?
> > end
> >
>
> all? will be most likely short-circuiting, too, so this has the same
> problem as using ==.
>
> There's two ways I know that security folks have approved of:
>
> 1. As it is done in eql_time_cmp in [1].
>
> 2. sha = OpenSSL::Digest::SHA256.new
>    if sha.digest(computed_mac) == sha.digest(presented_mac)
>      ..
>    end
>
> Although some say that there is even a problem with the first method:
> An extremely
> optimized (byte code) compiler could figure out what we're trying to
> do there and "help"
> us in short-circuiting again. This won't apply to the second method,
> though.
>
>
> [1]
> http://www.ruby-doc.org/stdlib-2.0/libdoc/openssl/rdoc/OpenSSL/PKCS5.html
>
>


-- 
Dmitry S. Kravtsov