diff --git a/cbits/sntrup761.c b/cbits/sntrup761.c index 7d64eeb08..ebdb7fbe5 100644 --- a/cbits/sntrup761.c +++ b/cbits/sntrup761.c @@ -6,9 +6,9 @@ * - Christine van Vredendaal */ -#include "sntrup761.h" - #include "sha512.h" +#include "sntrup761.h" +#include "sxcrandom.h" /* from supercop-20201130/crypto_sort/int32/portable4/int32_minmax.inc */ #define int32_MINMAX(a,b) \ @@ -684,7 +684,7 @@ Hash_prefix (unsigned char *out, int b, const unsigned char *in, int inlen) /* ----- higher-level randomness */ static uint32_t -urandom32 (void *random_ctx, sntrup761_random_func * random) +urandom32 (void *random_ctx, random_func * random) { unsigned char c[4]; uint32_t out[4]; @@ -698,7 +698,7 @@ urandom32 (void *random_ctx, sntrup761_random_func * random) } static void -Short_random (small * out, void *random_ctx, sntrup761_random_func * random) +Short_random (small * out, void *random_ctx, random_func * random) { uint32_t L[p]; int i; @@ -709,7 +709,7 @@ Short_random (small * out, void *random_ctx, sntrup761_random_func * random) } static void -Small_random (small * out, void *random_ctx, sntrup761_random_func * random) +Small_random (small * out, void *random_ctx, random_func * random) { int i; @@ -722,7 +722,7 @@ Small_random (small * out, void *random_ctx, sntrup761_random_func * random) /* h,(f,ginv) = KeyGen() */ static void KeyGen (Fq * h, small * f, small * ginv, void *random_ctx, - sntrup761_random_func * random) + random_func * random) { small g[p]; Fq finv[p]; @@ -886,7 +886,7 @@ typedef small Inputs[p]; /* passed by reference */ /* pk,sk = ZKeyGen() */ static void ZKeyGen (unsigned char *pk, unsigned char *sk, void *random_ctx, - sntrup761_random_func * random) + random_func * random) { Fq h[p]; small f[p], v[p]; @@ -962,7 +962,7 @@ HashSession (unsigned char *k, int b, const unsigned char *y, /* pk,sk = KEM_KeyGen() */ void sntrup761_keypair (unsigned char *pk, unsigned char *sk, void *random_ctx, - sntrup761_random_func * random) + random_func * random) { int i; @@ -989,7 +989,7 @@ Hide (unsigned char *c, unsigned char *r_enc, const Inputs r, /* c,k = Encap(pk) */ void sntrup761_enc (unsigned char *c, unsigned char *k, const unsigned char *pk, - void *random_ctx, sntrup761_random_func * random) + void *random_ctx, random_func * random) { Inputs r; unsigned char r_enc[Inputs_bytes]; diff --git a/cbits/sntrup761.h b/cbits/sntrup761.h index 14bfebba7..81d056e9d 100644 --- a/cbits/sntrup761.h +++ b/cbits/sntrup761.h @@ -11,21 +11,20 @@ #include #include +#include "sxcrandom.h" #define SNTRUP761_SECRETKEY_SIZE 1763 #define SNTRUP761_PUBLICKEY_SIZE 1158 #define SNTRUP761_CIPHERTEXT_SIZE 1039 #define SNTRUP761_SIZE 32 -typedef void sntrup761_random_func (void *ctx, size_t length, uint8_t *dst); - void sntrup761_keypair (uint8_t *pk, uint8_t *sk, - void *random_ctx, sntrup761_random_func *random); + void *random_ctx, random_func *random); void sntrup761_enc (uint8_t *c, uint8_t *k, const uint8_t *pk, - void *random_ctx, sntrup761_random_func *random); + void *random_ctx, random_func *random); void sntrup761_dec (uint8_t *k, const uint8_t *c, const uint8_t *sk); diff --git a/cbits/sxcrandom.c b/cbits/sxcrandom.c new file mode 100644 index 000000000..75859b9a3 --- /dev/null +++ b/cbits/sxcrandom.c @@ -0,0 +1,6 @@ +#include +#include "sxcrandom.h" + +void sxcrandom_dummy (void *ctx, size_t length, uint8_t *dst) { + memset(dst, 0x00, length); +} diff --git a/cbits/sxcrandom.h b/cbits/sxcrandom.h new file mode 100644 index 000000000..273dcb2ba --- /dev/null +++ b/cbits/sxcrandom.h @@ -0,0 +1,10 @@ +#ifndef SXCRANDOM_H +#define SXCRANDOM_H + +#include + +typedef void random_func (void *ctx, size_t length, uint8_t *dst); + +void sxcrandom_dummy (void *ctx, size_t length, uint8_t *dst); + +#endif diff --git a/package.yaml b/package.yaml index 24c5996eb..c2de94cbb 100644 --- a/package.yaml +++ b/package.yaml @@ -20,9 +20,9 @@ category: Chat, Network, Web, System, Cryptography extra-source-files: - README.md - CHANGELOG.md - # - cbits/sntrup761.c - - cbits/sntrup761.h - cbits/sha512.h + - cbits/sntrup761.h + - cbits/sxcrandom.h dependencies: - aeson == 2.2.* @@ -93,8 +93,9 @@ when: library: source-dirs: src c-sources: - - cbits/sntrup761.c - cbits/sha512.c + - cbits/sntrup761.c + - cbits/sxcrandom.c include-dirs: cbits extra-libraries: crypto diff --git a/simplexmq.cabal b/simplexmq.cabal index ce9564194..2b98e10c2 100644 --- a/simplexmq.cabal +++ b/simplexmq.cabal @@ -1,6 +1,6 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.35.2. +-- This file has been generated from package.yaml by hpack version 0.36.0. -- -- see: https://github.com/sol/hpack @@ -26,8 +26,9 @@ build-type: Simple extra-source-files: README.md CHANGELOG.md - cbits/sntrup761.h cbits/sha512.h + cbits/sntrup761.h + cbits/sxcrandom.h flag swift description: Enable swift JSON format @@ -102,7 +103,9 @@ library Simplex.Messaging.Crypto.Lazy Simplex.Messaging.Crypto.Ratchet Simplex.Messaging.Crypto.SNTRUP761.Bindings - Simplex.Messaging.Crypto.SNTRUP761.Bindings.Types + Simplex.Messaging.Crypto.SNTRUP761.Bindings.Defines + Simplex.Messaging.Crypto.SNTRUP761.Bindings.FFI + Simplex.Messaging.Crypto.SNTRUP761.Bindings.RNG Simplex.Messaging.Encoding Simplex.Messaging.Encoding.String Simplex.Messaging.Notifications.Client @@ -151,8 +154,9 @@ library include-dirs: cbits c-sources: - cbits/sntrup761.c cbits/sha512.c + cbits/sntrup761.c + cbits/sxcrandom.c extra-libraries: crypto build-depends: diff --git a/src/Simplex/Messaging/Crypto/SNTRUP761/Bindings.hs b/src/Simplex/Messaging/Crypto/SNTRUP761/Bindings.hs index 4d5525ca2..c86b438ef 100644 --- a/src/Simplex/Messaging/Crypto/SNTRUP761/Bindings.hs +++ b/src/Simplex/Messaging/Crypto/SNTRUP761/Bindings.hs @@ -1,30 +1,38 @@ -{-# LANGUAGE ForeignFunctionInterface #-} +{-# LANGUAGE NamedFieldPuns #-} -module Simplex.Messaging.Crypto.SNTRUP761.Bindings ( - sntrup761_keypair, - sntrup761_enc, - sntrup761_dec, - module Simplex.Messaging.Crypto.SNTRUP761.Bindings.Types -) where +module Simplex.Messaging.Crypto.SNTRUP761.Bindings where -import Data.Void -import Foreign -import Foreign.C -import Simplex.Messaging.Crypto.SNTRUP761.Bindings.Types +import Data.ByteArray (ScrubbedBytes) +import qualified Data.ByteArray as BA +import Data.ByteString (ByteString) +import Simplex.Messaging.Crypto.SNTRUP761.Bindings.Defines +import Simplex.Messaging.Crypto.SNTRUP761.Bindings.FFI +import Simplex.Messaging.Crypto.SNTRUP761.Bindings.RNG (RNG (..)) -type RandomCtx = Void +type PublicKey = ByteString --- typedef void sntrup761_random_func (void *ctx, size_t length, uint8_t *dst); -type RandomFunc = Ptr RandomCtx -> CSize -> Ptr Word8 -> IO () +type SecretKey = ScrubbedBytes --- void sntrup761_keypair (uint8_t *pk, uint8_t *sk, void *random_ctx, sntrup761_random_func *random); -foreign import ccall "sntrup761_keypair" - sntrup761_keypair :: Ptr Word8 -> Ptr Word8 -> Ptr RandomCtx -> Ptr RandomFunc -> IO () +type Ciphertext = ByteString --- void sntrup761_enc (uint8_t *c, uint8_t *k, const uint8_t *pk, void *random_ctx, sntrup761_random_func *random); -foreign import ccall "sntrup761_enc" - sntrup761_enc :: Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> Ptr RandomCtx -> Ptr RandomFunc -> IO () +type Key = ScrubbedBytes --- void sntrup761_dec (uint8_t *k, const uint8_t *c, const uint8_t *sk); -foreign import ccall "sntrup761_dec" - sntrup761_dec :: Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO () +sntrup761KeypairWith :: RNG -> IO (PublicKey, SecretKey) +sntrup761KeypairWith RNG{rngContext, rngFunc} = do + BA.allocRet c_SNTRUP761_SECRETKEY_SIZE $ \skPtr -> + BA.alloc c_SNTRUP761_PUBLICKEY_SIZE $ \pkPtr -> + sntrup761_keypair pkPtr skPtr rngContext rngFunc + +sntrup761EncWith :: RNG -> PublicKey -> IO (Ciphertext, Key) +sntrup761EncWith RNG {rngContext, rngFunc} pk = + BA.withByteArray pk $ \pkPtr -> + BA.allocRet c_SNTRUP761_SIZE $ \kPtr -> + BA.alloc c_SNTRUP761_CIPHERTEXT_SIZE $ \cPtr -> + sntrup761_enc cPtr kPtr pkPtr rngContext rngFunc + +sntrup761Dec :: Ciphertext -> SecretKey -> IO Key +sntrup761Dec c sk = + BA.withByteArray sk $ \skPtr -> + BA.withByteArray c $ \cPtr -> + BA.alloc c_SNTRUP761_SIZE $ \kPtr -> + sntrup761_dec kPtr cPtr skPtr diff --git a/src/Simplex/Messaging/Crypto/SNTRUP761/Bindings/Defines.hsc b/src/Simplex/Messaging/Crypto/SNTRUP761/Bindings/Defines.hsc new file mode 100644 index 000000000..06a4ea9c2 --- /dev/null +++ b/src/Simplex/Messaging/Crypto/SNTRUP761/Bindings/Defines.hsc @@ -0,0 +1,18 @@ +module Simplex.Messaging.Crypto.SNTRUP761.Bindings.Defines where + +import Foreign.C + +#include "sntrup761.h" +#include "sxcrandom.h" + +c_SNTRUP761_SECRETKEY_SIZE :: Int +c_SNTRUP761_SECRETKEY_SIZE = #{const SNTRUP761_SECRETKEY_SIZE} + +c_SNTRUP761_PUBLICKEY_SIZE :: Int +c_SNTRUP761_PUBLICKEY_SIZE = #{const SNTRUP761_PUBLICKEY_SIZE} + +c_SNTRUP761_CIPHERTEXT_SIZE :: Int +c_SNTRUP761_CIPHERTEXT_SIZE = #{const SNTRUP761_CIPHERTEXT_SIZE} + +c_SNTRUP761_SIZE :: Int +c_SNTRUP761_SIZE = #{const SNTRUP761_SIZE} diff --git a/src/Simplex/Messaging/Crypto/SNTRUP761/Bindings/FFI.hs b/src/Simplex/Messaging/Crypto/SNTRUP761/Bindings/FFI.hs new file mode 100644 index 000000000..77d17c5bf --- /dev/null +++ b/src/Simplex/Messaging/Crypto/SNTRUP761/Bindings/FFI.hs @@ -0,0 +1,23 @@ +{-# LANGUAGE ForeignFunctionInterface #-} + +module Simplex.Messaging.Crypto.SNTRUP761.Bindings.FFI ( + sntrup761_keypair, + sntrup761_enc, + sntrup761_dec, +) where + +import Foreign +import Foreign.C +import Simplex.Messaging.Crypto.SNTRUP761.Bindings.RNG (RNGContext, RNGFunc) + +-- void sntrup761_keypair (uint8_t *pk, uint8_t *sk, void *random_ctx, sntrup761_random_func *random); +foreign import ccall "sntrup761_keypair" + sntrup761_keypair :: Ptr Word8 -> Ptr Word8 -> RNGContext -> RNGFunc -> IO () + +-- void sntrup761_enc (uint8_t *c, uint8_t *k, const uint8_t *pk, void *random_ctx, sntrup761_random_func *random); +foreign import ccall "sntrup761_enc" + sntrup761_enc :: Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> RNGContext -> RNGFunc -> IO () + +-- void sntrup761_dec (uint8_t *k, const uint8_t *c, const uint8_t *sk); +foreign import ccall "sntrup761_dec" + sntrup761_dec :: Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO () diff --git a/src/Simplex/Messaging/Crypto/SNTRUP761/Bindings/RNG.hs b/src/Simplex/Messaging/Crypto/SNTRUP761/Bindings/RNG.hs new file mode 100644 index 000000000..cdc47472c --- /dev/null +++ b/src/Simplex/Messaging/Crypto/SNTRUP761/Bindings/RNG.hs @@ -0,0 +1,25 @@ +module Simplex.Messaging.Crypto.SNTRUP761.Bindings.RNG + ( RNG (..) + , dummyRNG + , RNGContext + , RNGFunc + ) where + +import Foreign +import Foreign.C + +data RNG = RNG + { rngContext :: RNGContext + , rngFunc :: RNGFunc + } + +dummyRNG :: RNG +dummyRNG = RNG {rngContext = nullPtr, rngFunc = randomDummy} + +type RNGContext = Ptr RNG + +-- typedef void random_func (void *ctx, size_t length, uint8_t *dst); +type RNGFunc = FunPtr (Ptr RNGContext -> CSize -> Ptr Word8 -> IO ()) + +foreign import ccall "&sxcrandom_dummy" + randomDummy :: RNGFunc diff --git a/src/Simplex/Messaging/Crypto/SNTRUP761/Bindings/Types.hsc b/src/Simplex/Messaging/Crypto/SNTRUP761/Bindings/Types.hsc deleted file mode 100644 index 14d95493f..000000000 --- a/src/Simplex/Messaging/Crypto/SNTRUP761/Bindings/Types.hsc +++ /dev/null @@ -1,12 +0,0 @@ --- {-# LANGUAGE CApiFFI #-} - -module Simplex.Messaging.Crypto.SNTRUP761.Bindings.Types where - -import Foreign.C - -#include "sntrup761.h" - -c_SNTRUP761_SECRETKEY_SIZE :: CInt -c_SNTRUP761_SECRETKEY_SIZE = #{const SNTRUP761_SECRETKEY_SIZE} - --- foreign import capi "sntrup761.h value SNTRUP761_SECRETKEY_SIZE" c_SNTRUP761_SECRETKEY_SIZE :: CInt diff --git a/tests/CoreTests/CryptoTests.hs b/tests/CoreTests/CryptoTests.hs index b380963a3..0f47d395f 100644 --- a/tests/CoreTests/CryptoTests.hs +++ b/tests/CoreTests/CryptoTests.hs @@ -16,6 +16,7 @@ import qualified Data.Text.Lazy.Encoding as LE import qualified Simplex.Messaging.Crypto as C import qualified Simplex.Messaging.Crypto.Lazy as LC import Simplex.Messaging.Crypto.SNTRUP761.Bindings +import Simplex.Messaging.Crypto.SNTRUP761.Bindings.RNG (dummyRNG) import Test.Hspec import Test.Hspec.QuickCheck (modifyMaxSuccess) import Test.QuickCheck @@ -203,4 +204,7 @@ testEncoding alg = it "should encode / decode key" . ioProperty $ do testSNTRUP761 :: IO () testSNTRUP761 = do - print c_SNTRUP761_SECRETKEY_SIZE + let rng = dummyRNG + (pk, sk) <- sntrup761KeypairWith rng + (c, k) <- sntrup761EncWith rng pk + sntrup761Dec c sk `shouldReturn` k