Arm.hs (2662B)
1 {-# OPTIONS_HADDOCK hide #-} 2 {-# LANGUAGE BangPatterns #-} 3 4 -- | 5 -- Module: Crypto.Cipher.ChaCha20.Arm 6 -- Copyright: (c) 2025 Jared Tobin 7 -- License: MIT 8 -- Maintainer: Jared Tobin <jared@ppad.tech> 9 -- 10 -- ARM NEON support for the ChaCha20 stream cipher. 11 12 module Crypto.Cipher.ChaCha20.Arm ( 13 chacha20_arm_available 14 , block 15 , cipher 16 ) where 17 18 import qualified Data.ByteString as BS 19 import qualified Data.ByteString.Internal as BI 20 import Data.Word (Word8, Word32) 21 import Foreign.C.Types (CInt(..), CSize(..)) 22 import Foreign.ForeignPtr (withForeignPtr) 23 import Foreign.Ptr (Ptr, plusPtr) 24 import System.IO.Unsafe (unsafeDupablePerformIO) 25 26 -- ffi ------------------------------------------------------------------------ 27 28 foreign import ccall unsafe "chacha20_block_arm" 29 c_chacha20_block 30 :: Ptr Word8 -> Word32 -> Ptr Word8 -> Ptr Word8 -> IO () 31 32 foreign import ccall unsafe "chacha20_cipher_arm" 33 c_chacha20_cipher 34 :: Ptr Word8 -> Word32 -> Ptr Word8 35 -> Ptr Word8 -> Ptr Word8 -> CSize -> IO () 36 37 foreign import ccall unsafe "chacha20_arm_available" 38 c_chacha20_arm_available :: IO CInt 39 40 -- utilities ------------------------------------------------------------------ 41 42 fi :: (Integral a, Num b) => a -> b 43 fi = fromIntegral 44 {-# INLINE fi #-} 45 46 -- api ------------------------------------------------------------------------ 47 48 -- | Are ARM NEON extensions available? 49 chacha20_arm_available :: Bool 50 chacha20_arm_available = 51 unsafeDupablePerformIO c_chacha20_arm_available /= 0 52 {-# NOINLINE chacha20_arm_available #-} 53 54 -- | One 64-byte ChaCha20 keystream block for the given (already- 55 -- validated) key, counter, and nonce. 56 block :: BS.ByteString -> Word32 -> BS.ByteString -> BS.ByteString 57 block (BI.PS kfp koff _) counter (BI.PS nfp noff _) = 58 BI.unsafeCreate 64 $ \dst -> 59 withForeignPtr kfp $ \kp0 -> 60 withForeignPtr nfp $ \np0 -> 61 c_chacha20_block (kp0 `plusPtr` koff) 62 counter 63 (np0 `plusPtr` noff) 64 dst 65 66 -- | XOR the plaintext with the ChaCha20 keystream derived from the 67 -- given (already-validated) key, counter, and nonce. 68 cipher 69 :: BS.ByteString -> Word32 -> BS.ByteString -> BS.ByteString 70 -> BS.ByteString 71 cipher (BI.PS kfp koff _) counter (BI.PS nfp noff _) 72 (BI.PS pfp poff plen) = 73 BI.unsafeCreate plen $ \dst -> 74 withForeignPtr kfp $ \kp0 -> 75 withForeignPtr nfp $ \np0 -> 76 withForeignPtr pfp $ \pp0 -> 77 c_chacha20_cipher (kp0 `plusPtr` koff) 78 counter 79 (np0 `plusPtr` noff) 80 (pp0 `plusPtr` poff) 81 dst 82 (fi plen)