Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Fast C implementation of safeEq #1

Closed
wants to merge 1 commit into from

2 participants

Felipe Lessa Thomas M. DuBuisson
Felipe Lessa

On my computer, the C implementation is 1.6x faster for 32-byte strings and 24x faster for 10-kbyte strings.

Sorry about the whitespace changes, I still don't know how to deal with them in git.

Felipe Lessa meteficha Implement safeEq in C for greater performance.
On my computer, the C implementation is 1.6x faster for 32-byte strings and 24x faster for 10-kbyte strings.
f6e947d
Thomas M. DuBuisson TomMD closed this
Thomas M. DuBuisson
Owner

I merged this manually - thanks!

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

Showing 1 unique commit by 1 author.

Oct 03, 2011
Felipe Lessa meteficha Implement safeEq in C for greater performance.
On my computer, the C implementation is 1.6x faster for 32-byte strings and 24x faster for 10-kbyte strings.
f6e947d
This page is out of date. Refresh to see the latest.
25 Crypto/Classes.hs
@@ -2,9 +2,9 @@
2 2 {-|
3 3 Maintainer: Thomas.DuBuisson@gmail.com
4 4 Stability: beta
5   - Portability: portable
  5 + Portability: portable
6 6
7   -This is the heart of the crypto-api package. By making (or having)
  7 +This is the heart of the crypto-api package. By making (or having)
8 8 an instance of Hash, AsymCipher, BlockCipher or StreamCipher you provide (or obtain)
9 9 access to any infrastructure built on these primitives include block cipher modes
10 10 of operation, hashing, hmac, signing, etc. These classes allow users to build
@@ -13,7 +13,7 @@ as changing a type signature.
13 13 -}
14 14
15 15 module Crypto.Classes
16   - (
  16 + (
17 17 -- * Hash class and helper functions
18 18 Hash(..)
19 19 , hash
@@ -40,12 +40,15 @@ import Data.Serialize
40 40 import qualified Data.ByteString.Lazy as L
41 41 import qualified Data.ByteString as B
42 42 import qualified Data.ByteString.Internal as I
  43 +import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
43 44 import Data.Bits ((.|.), xor)
44 45 import Data.List (foldl')
45 46 import Data.Word (Word64)
46 47 import Data.Tagged
47 48 import Crypto.Types
48 49 import Crypto.Random
  50 +import Foreign (Ptr, unsafePerformIO)
  51 +import Foreign.C (CChar, CInt)
49 52 import System.Entropy
50 53
51 54 -- |The Hash class is intended as the generic interface
@@ -227,9 +230,25 @@ for t _ = unTagged t
227 230 -- otherwise you may leave a significant security hole
228 231 -- (cf. <http://codahale.com/a-lesson-in-timing-attacks/>).
229 232 safeEq :: B.ByteString -> B.ByteString -> Bool
  233 +-- Fast C implementation.
  234 +safeEq s1 s2 =
  235 + unsafePerformIO $
  236 + unsafeUseAsCStringLen s1 $ \(s1_ptr, s1_len) ->
  237 + unsafeUseAsCStringLen s2 $ \(s2_ptr, s2_len) ->
  238 + if s1_len /= s2_len
  239 + then return False
  240 + else (== 0) `fmap` c_safeEq s1_ptr s2_ptr (fromIntegral s1_len)
  241 +
  242 +foreign import ccall unsafe
  243 + c_safeEq :: Ptr CChar -> Ptr CChar -> CInt -> IO CInt
  244 +
  245 +{-
  246 +-- Haskell only implementation.
230 247 safeEq s1 s2 =
231 248 B.length s1 == B.length s2 &&
232 249 foldl' (.|.) 0 (B.zipWith xor s1 s2) == 0
  250 +-}
  251 +
233 252
234 253 -- | Like 'safeEq', safeCompare can be used to compare two
235 254 -- bytestrings in a way that is less suceptible to timing
7 c_impl/misc.c
... ... @@ -0,0 +1,7 @@
  1 +/* Fast C implementation of a safe string equality test. */
  2 +int c_safeEq(char *x, char *y, int length) {
  3 + int ret = 0, i;
  4 + for (i = 0; i < length; i++)
  5 + ret = ret | x[i] ^ y[i];
  6 + return ret;
  7 +}
4 c_impl/misc.h
... ... @@ -0,0 +1,4 @@
  1 +#ifndef CRYPTO_API_MISC_H
  2 +#define CRYPTO_API_MISC_H
  3 +int c_safeEq(char *x, char *y, int length);
  4 +#endif
5 crypto-api.cabal
@@ -24,6 +24,9 @@ stability: stable
24 24 build-type: Simple
25 25 cabal-version: >= 1.6
26 26 tested-with: GHC == 7.0.3
  27 +extra-source-files:
  28 + c_impl/misc.c
  29 + c_impl/misc.h
27 30
28 31
29 32 Library
@@ -36,6 +39,8 @@ Library
36 39 hs-source-dirs:
37 40 exposed-modules: Crypto.Classes, Crypto.Types, Crypto.HMAC, Crypto.Modes, Crypto.Random, Crypto.Padding
38 41 other-modules: Crypto.Util, Crypto.CPoly
  42 + extensions: ForeignFunctionInterface
  43 + c-sources: c_impl/misc.c
39 44
40 45 source-repository head
41 46 type: git

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.