cryptonite-openssl 0.2 → 0.3
raw patch · 7 files changed
+168/−12 lines, 7 filesdep +cryptonite-opensslPVP ok
version bump matches the API change (PVP)
Dependencies added: cryptonite-openssl
API changes (from Hackage documentation)
+ Crypto.OpenSSL.ECC: ecPointsMulAndSum :: EcGroup -> [(EcPoint, Integer)] -> EcPoint
+ Crypto.OpenSSL.ECC: ecPointsMulOfPowerAndSum :: EcGroup -> [EcPoint] -> Integer -> EcPoint
+ Crypto.OpenSSL.ECC: ecPointsSum :: EcGroup -> [EcPoint] -> EcPoint
Files
- Crypto/OpenSSL/BN.hs +2/−8
- Crypto/OpenSSL/BN/Foreign.hs +61/−1
- Crypto/OpenSSL/ECC.hs +66/−1
- Crypto/OpenSSL/Misc.hs +1/−0
- cryptonite-openssl.cabal +4/−1
- tests/Imports.hs +21/−0
- tests/Tests.hs +13/−1
Crypto/OpenSSL/BN.hs view
@@ -5,9 +5,8 @@ import Crypto.OpenSSL.Misc import Foreign.Ptr import Foreign.ForeignPtr+import Crypto.Number.Serialize -import Data.Bits-import qualified Data.ByteString as B import qualified Data.ByteString.Internal as B withIntegerAsBN :: Integer -> (Ptr BIGNUM -> IO a) -> IO a@@ -17,11 +16,7 @@ foreignBn <- newForeignPtr ssl_bn_free bn withForeignPtr foreignBn f where (fptr, o, len) = B.toForeignPtr bs- bs = B.reverse $ B.unfoldr fdivMod256 i- fdivMod256 0 = Nothing- fdivMod256 n = Just (fromIntegral a,b) where (b,a) = divMod256 n- divMod256 :: Integer -> (Integer, Integer)- divMod256 n = (n `shiftR` 8, n .&. 0xff)+ bs = i2osp i bnToInt :: Ptr BIGNUM -> IO Integer bnToInt bn = do@@ -29,7 +24,6 @@ bs <- B.create (fromIntegral bytes) $ \bufPtr -> check $ ssl_bn_2bin bn (castPtr bufPtr) return $ os2ip bs- where os2ip = B.foldl' (\a b -> (256 * a) .|. (fromIntegral b)) 0 withBnCtxNew :: (Ptr BN_CTX -> IO a) -> IO a withBnCtxNew f = do
Crypto/OpenSSL/BN/Foreign.hs view
@@ -28,7 +28,67 @@ foreign import ccall unsafe "BN_bin2bn" ssl_bn_bin2 :: Ptr CUChar -> CInt -> Ptr BIGNUM -> IO (Ptr BIGNUM) --- bn_num_bytes is a macro, +-- setter++foreign import ccall unsafe "BN_set_word"+ ssl_bn_set_word :: Ptr BIGNUM -> CULong -> IO CInt++ssl_bn_zero :: Ptr BIGNUM -> IO CInt+ssl_bn_zero p = ssl_bn_set_word p 0++ssl_bn_one :: Ptr BIGNUM -> IO CInt+ssl_bn_one p = ssl_bn_set_word p 1++-- arithmetic operations++foreign import ccall unsafe "BN_add" -- r = a + b+ ssl_bn_add :: Ptr BIGNUM -> Ptr BIGNUM -> Ptr BIGNUM -> IO CInt++foreign import ccall unsafe "BN_sub" -- r = a - b+ ssl_bn_sub :: Ptr BIGNUM -> Ptr BIGNUM -> Ptr BIGNUM -> IO CInt++foreign import ccall unsafe "BN_mul" -- r = a * b+ ssl_bn_mul :: Ptr BIGNUM -> Ptr BIGNUM -> Ptr BIGNUM -> Ptr BN_CTX -> IO CInt++foreign import ccall unsafe "BN_sqr" -- r = sqrt(a)+ ssl_bn_sqr :: Ptr BIGNUM -> Ptr BIGNUM -> Ptr BN_CTX -> IO CInt++foreign import ccall unsafe "BN_div" -- div,rem = a / b+ ssl_bn_div :: Ptr BIGNUM -> Ptr BIGNUM -> Ptr BIGNUM -> Ptr BIGNUM -> Ptr BN_CTX -> IO CInt++--foreign import ccall unsafe "BN_mod" -- r = a % b+-- ssl_bn_mod :: Ptr BIGNUM -> Ptr BIGNUM -> Ptr BIGNUM -> Ptr BN_CTX -> IO CInt++foreign import ccall unsafe "BN_nnmod" -- r = a % b+ ssl_bn_nnmod :: Ptr BIGNUM -> Ptr BIGNUM -> Ptr BIGNUM -> Ptr BN_CTX -> IO CInt++-- arithmetic modular operations++foreign import ccall unsafe "BN_mod_add" -- r = a + b [m]+ ssl_bn_mod_add :: Ptr BIGNUM -> Ptr BIGNUM -> Ptr BIGNUM -> Ptr BIGNUM -> Ptr BN_CTX -> IO CInt++foreign import ccall unsafe "BN_mod_sub" -- r = a - b [m]+ ssl_bn_mod_sub :: Ptr BIGNUM -> Ptr BIGNUM -> Ptr BIGNUM -> Ptr BIGNUM -> Ptr BN_CTX -> IO CInt++foreign import ccall unsafe "BN_mod_mul" -- r = a * b [m]+ ssl_bn_mod_mul :: Ptr BIGNUM -> Ptr BIGNUM -> Ptr BIGNUM -> Ptr BIGNUM -> Ptr BN_CTX -> IO CInt++foreign import ccall unsafe "BN_mod_sqr" -- r = sqrt a [m]+ ssl_bn_mod_sqr :: Ptr BIGNUM -> Ptr BIGNUM -> Ptr BIGNUM -> Ptr BN_CTX -> IO CInt++-- exponantiations++foreign import ccall unsafe "BN_exp" -- r = a^p+ ssl_bn_exp :: Ptr BIGNUM -> Ptr BIGNUM -> Ptr BIGNUM -> Ptr BN_CTX -> IO CInt++foreign import ccall unsafe "BN_mod_exp" -- r = a^p [m]+ ssl_bn_mod_exp :: Ptr BIGNUM -> Ptr BIGNUM -> Ptr BIGNUM -> Ptr BIGNUM -> Ptr BN_CTX -> IO CInt++foreign import ccall unsafe "BN_gcd" -- r = gcd(a,b)+ ssl_bn_gcd :: Ptr BIGNUM -> Ptr BIGNUM -> Ptr BIGNUM -> Ptr BN_CTX -> IO CInt+++-- bn_num_bytes is a macro, ssl_bn_num_bytes :: Ptr BIGNUM -> IO CInt ssl_bn_num_bytes ptr = do bits <- ssl_bn_num_bits ptr
Crypto/OpenSSL/ECC.hs view
@@ -20,9 +20,12 @@ , ecGroupGetCurveGF2m -- * EcPoint arithmetic , ecPointAdd+ , ecPointsSum , ecPointDbl , ecPointMul , ecPointMulWithGenerator+ , ecPointsMulAndSum+ , ecPointsMulOfPowerAndSum , ecPointGeneratorMul , ecPointInvert , ecPointInfinity@@ -45,11 +48,13 @@ , ecKeyToPair ) where -import Control.Monad (void)+import Control.Monad (void, forM_) import Control.Applicative+import Control.Exception (bracket) import Crypto.OpenSSL.ECC.Foreign import Crypto.OpenSSL.ASN1 import Crypto.OpenSSL.BN+import Crypto.OpenSSL.BN.Foreign import Crypto.OpenSSL.Misc import Foreign.ForeignPtr import Foreign.Ptr@@ -94,6 +99,10 @@ f ptr EcPoint <$> newForeignPtr ssl_point_free_funptr ptr +withPointTemp :: Ptr EC_GROUP -> (Ptr EC_POINT -> IO a) -> IO a+withPointTemp grp f = bracket (ssl_point_new grp) (ssl_point_free) f++ -- | try to get a curve group from an ASN1 description string (OID) -- -- e.g.@@ -248,6 +257,17 @@ withPointNew gptr $ \r -> check $ ssl_point_add gptr r p1ptr p2ptr bnCtx {-# NOINLINE ecPointAdd #-} +-- | Add many points together+ecPointsSum :: EcGroup -> [EcPoint] -> EcPoint+ecPointsSum g [] = ecPointInfinity g+ecPointsSum (EcGroup g) ((EcPoint x):xs) = doIO $+ withForeignPtr g $ \gptr ->+ withForeignPtr x $ \xptr ->+ withBnCtxNew $ \bnCtx ->+ withPointDup gptr xptr $ \rptr ->+ forM_ xs $ \(EcPoint p) -> withForeignPtr p $ \pptr -> do+ check $ ssl_point_add gptr rptr rptr pptr bnCtx+ -- | compute the doubling of the point p, r = p^2 ecPointDbl :: EcGroup -> EcPoint -> EcPoint ecPointDbl (EcGroup g) (EcPoint p) = doIO $@@ -270,6 +290,47 @@ withPointNew gptr $ \r -> check $ ssl_point_mul gptr r nullPtr qptr bnM bnCtx {-# NOINLINE ecPointMul #-} +-- | compute sum (\(q,m) -> q * m) l+ecPointsMulAndSum :: EcGroup -> [(EcPoint, Integer)] -> EcPoint+ecPointsMulAndSum g [] = ecPointInfinity g+ecPointsMulAndSum (EcGroup g) l = doIO $+ withForeignPtr g $ \gptr ->+ withBnCtxNew $ \bnCtx ->+ withPointNew gptr $ \rptr ->+ withPointTemp gptr $ \tptr -> do+ check $ ssl_point_set_to_infinity gptr rptr+ forM_ l $ \(EcPoint p,m) -> do+ withForeignPtr p $ \pptr -> withIntegerAsBN m $ \bnM -> check $ ssl_point_mul gptr tptr nullPtr pptr bnM bnCtx+ check $ ssl_point_add gptr rptr rptr tptr bnCtx++-- | Compute the sum of the point to the nth power+--+-- > f [p1,p2,..,pi] n = p1 * (n ^ 0) + p2 * (n ^ 1) + .. + pi * (n ^ i-1)+ecPointsMulOfPowerAndSum :: EcGroup -> [EcPoint] -> Integer -> EcPoint+ecPointsMulOfPowerAndSum g [] _ = ecPointInfinity g+ecPointsMulOfPowerAndSum (EcGroup g) l startn = doIO $+ withForeignPtr g $ \gptr ->+ withBnCtxNew $ \bnCtx ->+ withIntegerAsBN startn $ \n ->+ withBnNew $ \nIter ->+ withBnNew $ \gMod ->+ withPointNew gptr $ \rptr ->+ withPointTemp gptr $ \tptr -> do+ check $ ssl_group_get_order gptr gMod bnCtx+ check $ ssl_bn_one nIter+ start gptr gMod bnCtx n nIter rptr tptr+ where+ start gptr gMod bnCtx n nIter rptr tptr = loop l+ where+ loop [] = return ()+ loop (EcPoint x:xs) = do+ -- r += x * current-n+ withForeignPtr x $ \xptr -> check $ ssl_point_mul gptr tptr nullPtr xptr nIter bnCtx+ check $ ssl_point_add gptr rptr rptr tptr bnCtx+ -- nIter = nIter * n+ check $ ssl_bn_mod_mul nIter nIter n gMod bnCtx+ loop xs+ -- | compute generator * n + q * m ecPointMulWithGenerator :: EcGroup -> Integer -- ^ n@@ -328,6 +389,7 @@ ((==) 1 <$> ssl_point_is_on_curve gptr pptr bnCtx) {-# NOINLINE ecPointIsOnCurve #-} +-- | Create a binary represention of a point using the specific format ecPointToOct :: B.ByteArray outBytes => EcGroup -> EcPoint -> PointConversionForm -> outBytes ecPointToOct (EcGroup g) (EcPoint p) pconv = doIO $ withForeignPtr g $ \gptr ->@@ -339,6 +401,7 @@ where form = ecPointConversionToC pconv {-# NOINLINE ecPointToOct #-} +-- | Try to parse a binary representation to a point ecPointFromOct :: B.ByteArrayAccess inBytes => EcGroup -> inBytes -> Either String EcPoint ecPointFromOct (EcGroup g) bs = doIO $ do (opensslRet,point) <- withForeignPtr g $ \gptr ->@@ -372,6 +435,7 @@ (,,) <$> bnToInt bnX <*> bnToInt bnY <*> bnToInt bnZ {-# NOINLINE ecPointToJProjectiveGFp #-} +-- | Convert a (x,y) to a point representation on a prime curve. ecPointFromAffineGFp :: EcGroup -> (Integer, Integer) -> EcPoint ecPointFromAffineGFp (EcGroup g) (x,y) = doIO $ withForeignPtr g $ \gptr ->@@ -382,6 +446,7 @@ check $ ssl_point_set_affine_coordinates_GFp gptr r bnX bnY bnCtx {-# NOINLINE ecPointFromAffineGFp #-} +-- | Convert a point of a prime curve to affine representation (x,y) ecPointToAffineGFp :: EcGroup -> EcPoint -> (Integer, Integer) ecPointToAffineGFp (EcGroup g) (EcPoint p) = doIO $ withForeignPtr g $ \gptr ->
Crypto/OpenSSL/Misc.hs view
@@ -28,6 +28,7 @@ if r == 0 then throwIO $ OpenSSLError (fromIntegral r) else return ()+{-# INLINE check #-} checkCtx :: Exception e => (String -> e) -> String -> IO CInt -> IO () checkCtx exnConstr n f = do
cryptonite-openssl.cabal view
@@ -1,5 +1,5 @@ Name: cryptonite-openssl-Version: 0.2+Version: 0.3 Synopsis: Crypto stuff using OpenSSL cryptographic library Description: cryptography License: BSD3@@ -32,6 +32,7 @@ Build-depends: base >= 4.3 && < 5 , bytestring , memory+ , cryptonite ghc-options: -Wall -fwarn-tabs -optc-O3 default-language: Haskell2010 if os(mingw32) || os(windows)@@ -47,6 +48,7 @@ type: exitcode-stdio-1.0 hs-source-dirs: tests Main-is: Tests.hs+ Other-modules: Imports Build-Depends: base >= 3 && < 5 , bytestring , tasty@@ -54,5 +56,6 @@ , tasty-hunit , tasty-kat , cryptonite+ , cryptonite-openssl ghc-options: -Wall -fno-warn-orphans -fno-warn-missing-signatures -rtsopts default-language: Haskell2010
+ tests/Imports.hs view
@@ -0,0 +1,21 @@+module Imports+ (+ -- * Individual Types+ Word16, Word32, Word64+ , ByteString+ -- * Modules+ , module X+ ) where++import Data.Word (Word16, Word32, Word64)+import Data.ByteString (ByteString)++import Control.Applicative as X+import Control.Monad as X+import Data.Foldable as X (foldl')+import Data.Monoid as X+import Data.ByteString.Char8 as X ()++import Test.Tasty as X+import Test.Tasty.HUnit as X+import Test.Tasty.QuickCheck as X hiding (vector)
tests/Tests.hs view
@@ -1,10 +1,22 @@ {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ViewPatterns #-} module Main where import Imports+import Crypto.OpenSSL.ECC +p256 = maybe (error "p256 not available") id+ $ ecGroupFromCurveOID "1.2.840.10045.3.1.7"++intToInteger :: Int -> Integer+intToInteger i = toInteger i+ tests = testGroup "cryptonite-openssl"- [+ [ testProperty "ring" $ \(Positive (intToInteger -> a)) (Positive (intToInteger -> b)) ->+ let pa = ecPointGeneratorMul p256 a+ pb = ecPointGeneratorMul p256 b+ pc = ecPointGeneratorMul p256 (a+b)+ in ecPointEq p256 (ecPointAdd p256 pa pb) pc ] main = defaultMain tests