{-# LANGUAGE CApiFFI #-}
{-# LANGUAGE CPP #-}
module Cardano.Wasm.Internal.Api.Random (getRandomBytes) where
#if !defined(wasm32_HOST_ARCH)
import Data.ByteString (ByteString)
import Crypto.Random.Entropy (getEntropy)
getRandomBytes :: Word -> IO ByteString
getRandomBytes :: Word -> IO ByteString
getRandomBytes Word
n = Int -> IO ByteString
forall byteArray. ByteArray byteArray => Int -> IO byteArray
getEntropy (Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
n)
#else
import Control.Exception (throwIO)
import Data.ByteString (ByteString, packCStringLen)
import Data.Word (Word8)
import System.IO.Error (mkIOError, userErrorType)
import Foreign.C.Types (CInt (..), CSize (..))
import Foreign.Marshal.Alloc (allocaBytes)
import Foreign.Ptr (Ptr, castPtr)
foreign import ccall "__wasi_random_get"
wasi_random_get
:: Ptr Word8
-> CSize
-> IO CInt
getRandomBytes :: Word -> IO ByteString
getRandomBytes n =
allocaBytes (fromIntegral n) $ \ptr -> do
errno <- wasi_random_get ptr (fromIntegral n)
if errno == 0
then packCStringLen (castPtr ptr, fromIntegral n)
else
throwIO $
mkIOError
userErrorType
("wasi_random_get failed with errno: " ++ show errno)
Nothing
Nothing
#endif