From 6dcba8d8cd3a626cc702f666476ebde7c1a87296 Mon Sep 17 00:00:00 2001 From: Vincent Hanquez Date: Sat, 11 Apr 2015 08:23:52 +0100 Subject: [PATCH] [Internal] properly handle big endian architecture add a CompatPrim module to handle all the primitive compatibility needed, instead of putting all in Compat. --- Crypto/Internal/CompatPrim.hs | 40 +++++++++++++++++++++++++++++++++++ Crypto/Internal/WordArray.hs | 4 ++-- cryptonite.cabal | 1 + 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 Crypto/Internal/CompatPrim.hs diff --git a/Crypto/Internal/CompatPrim.hs b/Crypto/Internal/CompatPrim.hs new file mode 100644 index 0000000..16ab8f3 --- /dev/null +++ b/Crypto/Internal/CompatPrim.hs @@ -0,0 +1,40 @@ +-- | +-- Module : Crypto.Internal.CompatPrim +-- License : BSD-style +-- Maintainer : Vincent Hanquez +-- Stability : stable +-- Portability : Compat +-- +-- This module try to keep all the difference between versions of ghc primitive +-- or other needed packages, so that modules don't need to use CPP. +-- +-- Note that MagicHash and CPP conflicts in places, making it "more interesting" +-- to write compat code for primitives +-- +{-# LANGUAGE CPP #-} +{-# LANGUAGE MagicHash #-} +module Crypto.Internal.CompatPrim + ( be32Prim + , byteswap32Prim + ) where + +import GHC.Prim + +#ifdef ARCH_IS_LITTLE_ENDIAN +be32Prim :: Word# -> Word# +be32Prim = byteswap32Prim +#else +be32Prim w = w +#endif + +byteswap32Prim :: Word# -> Word# +#if __GLASGOW_HASKELL__ >= 708 +byteswap32Prim w = byteSwap32# w +#else +byteswap32Prim w = + let a = uncheckedShiftL# w 24# + b = and# (uncheckedShiftL# w 8#) 0x00ff0000## + c = and# (uncheckedShiftRL# w 8#) 0x0000ff00## + d = and# (uncheckedShiftRL# w 24#) 0x000000ff## + in or# a (or# b (or# c d)) +#endif diff --git a/Crypto/Internal/WordArray.hs b/Crypto/Internal/WordArray.hs index f7a1729..52d3896 100644 --- a/Crypto/Internal/WordArray.hs +++ b/Crypto/Internal/WordArray.hs @@ -35,6 +35,7 @@ module Crypto.Internal.WordArray import Data.Word import Data.Bits (xor) import Crypto.Internal.Compat +import Crypto.Internal.CompatPrim import GHC.Prim import GHC.Types import GHC.Word @@ -102,9 +103,8 @@ mutableArray32FromAddrBE (I# n) a = IO $ \s -> loop i st mb | booleanPrim (i ==# n) = (# st, MutableArray32 mb #) | otherwise = - let st' = writeWord32Array# mb i (be (indexWord32OffAddr# a i)) st + let st' = writeWord32Array# mb i (be32Prim (indexWord32OffAddr# a i)) st in loop (i +# 1#) st' mb - be = byteSwap32# mutableArray32Freeze :: MutableArray32 -> IO Array32 mutableArray32Freeze (MutableArray32 mb) = IO $ \st -> diff --git a/cryptonite.cabal b/cryptonite.cabal index 6fe02ab..f0c2c83 100644 --- a/cryptonite.cabal +++ b/cryptonite.cabal @@ -126,6 +126,7 @@ Library Crypto.PubKey.Internal Crypto.PubKey.ElGamal Crypto.Internal.Compat + Crypto.Internal.CompatPrim Crypto.Internal.Bytes Crypto.Internal.Endian Crypto.Internal.Imports