ed25519 0.0.1.0 → 0.0.2.0
raw patch · 15 files changed
+120/−333 lines, 15 filesdep −containersdep −directorydep −doctestdep ~basesetup-changed
Dependencies removed: containers, directory, doctest, filepath, semigroups, tasty, tasty-hunit, tasty-quickcheck, tasty-th
Dependency ranges changed: base
Files
- .travis.yml +18/−13
- CHANGELOG.md +5/−0
- Setup.hs +3/−0
- Setup.lhs +0/−55
- ed25519.cabal +10/−115
- src/Crypto/Sign/Ed25519.hs +14/−13
- src/cbits/include/ed25519.h +7/−7
- src/cbits/keypair.c +1/−1
- src/cbits/open.c +1/−1
- src/cbits/sign.c +1/−1
- src/cbits/test.c +3/−3
- tests/doctests.hs +0/−73
- tests/hlint.hs +3/−1
- tests/hunit.hs +0/−21
- tests/properties.hs +54/−29
.travis.yml view
@@ -7,23 +7,28 @@ # release of a major GHC version. Setting HPVER implictly sets # GHCVER. Omit lines with versions you don't need/want testing for. env:-# - GHCVER=6.12.3-# - GHCVER=7.0.1-# - GHCVER=7.0.2-# - GHCVER=7.0.3-# - GHCVER=7.0.4-# - GHCVER=7.2.1-# - GHCVER=7.2.2+ - GHCVER=6.12.3+ - GHCVER=7.0.1+ - GHCVER=7.0.2+ - GHCVER=7.0.3+ - GHCVER=7.0.4+ - GHCVER=7.2.1+ - GHCVER=7.2.2 - GHCVER=7.4.1 - GHCVER=7.4.2 - GHCVER=7.6.1 - GHCVER=7.6.2 - GHCVER=7.6.3+ - GHCVER=head - HPVER=2013.2.0.0 - HPVER=2012.4.0.0-# - HPVER=2012.2.0.0-# - HPVER=2011.4.0.0+ - HPVER=2012.2.0.0+#- HPVER=2011.4.0.0 +matrix:+ allow_failures:+ - env: GHCVER=head+ # Note: the distinction between `before_install` and `install` is not # important. before_install:@@ -60,22 +65,22 @@ install: - cabal-1.18 update- - cabal-1.18 install happy alex- - cabal-1.18 install --only-dependencies --enable-tests --enable-benchmarks+ - cabal-1.18 install Cabal-1.18.1.2+ - cabal-1.18 install --only-dependencies --enable-tests -f-test-hlint # Here starts the actual work to be performed for the package under # test; any command which exits with a non-zero exit code causes the # build to fail. script: # -v2 provides useful information for debugging- - cabal-1.18 configure --enable-tests --enable-benchmarks -v2+ - cabal-1.18 configure --enable-tests -f-test-hlint -v2 # this builds all libraries and executables # (including tests/benchmarks) - cabal-1.18 build - cabal-1.18 test-#- cabal-1.18 check+ - cabal-1.18 check # tests that a source-distribution can be generated - cabal-1.18 sdist
CHANGELOG.md view
@@ -1,3 +1,8 @@+0.0.2.0+-------++ * Portability improvements.+ 0.0.1.0 -------
+ Setup.hs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+import Distribution.Simple+main = defaultMain
− Setup.lhs
@@ -1,55 +0,0 @@-#!/usr/bin/runhaskell-\begin{code}-{-# OPTIONS_GHC -Wall #-}-module Main (main) where--import Data.List ( nub )-import Data.Version ( showVersion )-import Distribution.Package ( PackageName(PackageName), Package, PackageId, InstalledPackageId, packageVersion, packageName )-import Distribution.PackageDescription ( PackageDescription(), TestSuite(..) )-import Distribution.Simple ( defaultMainWithHooks, UserHooks(..), simpleUserHooks )-import Distribution.Simple.Utils ( rewriteFile, createDirectoryIfMissingVerbose, copyFiles )-import Distribution.Simple.BuildPaths ( autogenModulesDir )-import Distribution.Simple.Setup ( BuildFlags(buildVerbosity), Flag(..), fromFlag, HaddockFlags(haddockDistPref))-import Distribution.Simple.LocalBuildInfo ( withLibLBI, withTestLBI, LocalBuildInfo(), ComponentLocalBuildInfo(componentPackageDeps) )-import Distribution.Text ( display )-import Distribution.Verbosity ( Verbosity, normal )-import System.FilePath ( (</>) )--main :: IO ()-main = defaultMainWithHooks simpleUserHooks- { buildHook = \pkg lbi hooks flags -> do- generateBuildModule (fromFlag (buildVerbosity flags)) pkg lbi- buildHook simpleUserHooks pkg lbi hooks flags- , postHaddock = \args flags pkg lbi -> do- copyFiles normal (haddockOutputDir flags pkg) []- postHaddock simpleUserHooks args flags pkg lbi- }--haddockOutputDir :: Package p => HaddockFlags -> p -> FilePath-haddockOutputDir flags pkg = destDir where- baseDir = case haddockDistPref flags of- NoFlag -> "."- Flag x -> x- destDir = baseDir </> "doc" </> "html" </> display (packageName pkg)--generateBuildModule :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO ()-generateBuildModule verbosity pkg lbi = do- let dir = autogenModulesDir lbi- createDirectoryIfMissingVerbose verbosity True dir- withLibLBI pkg lbi $ \_ libcfg -> do- withTestLBI pkg lbi $ \suite suitecfg -> do- rewriteFile (dir </> "Build_" ++ testName suite ++ ".hs") $ unlines- [ "module Build_" ++ testName suite ++ " where"- , "deps :: [String]"- , "deps = " ++ (show $ formatdeps (testDeps libcfg suitecfg))- ]- where- formatdeps = map (formatone . snd)- formatone p = case packageName p of- PackageName n -> n ++ "-" ++ showVersion (packageVersion p)--testDeps :: ComponentLocalBuildInfo -> ComponentLocalBuildInfo -> [(InstalledPackageId, PackageId)]-testDeps xs ys = nub $ componentPackageDeps xs ++ componentPackageDeps ys--\end{code}
ed25519.cabal view
@@ -1,5 +1,5 @@ name: ed25519-version: 0.0.1.0+version: 0.0.2.0 category: Cryptography license: MIT synopsis: ed25519 cryptographic signatures@@ -9,10 +9,11 @@ copyright: Copyright (c) Austin Seipp 2013 author: Austin Seipp maintainer: Austin Seipp <aseipp@pobox.com>-build-type: Custom+build-type: Simple cabal-version: >=1.10-tested-with: GHC == 7.4.1, GHC == 7.4.2,- GHC == 7.6.1, GHC == 7.6.2, GHC == 7.6.3+tested-with: GHC == 6.12.3, GHC == 7.0.1, GHC == 7.0.2, GHC == 7.0.3,+ GHC == 7.0.4, GHC == 7.2.1, GHC == 7.2.2, GHC == 7.4.1,+ GHC == 7.4.2, GHC == 7.6.1, GHC == 7.6.2, GHC == 7.6.3 description: This package provides a simple, portable implementation of the@@ -45,32 +46,10 @@ default: True manual: True --- Enable these when/if we need them.-flag test-hunit- default: False- manual: True---- Can't run due to needing C library apparently?-flag test-doctests- default: False- manual: True- flag test-hlint default: True manual: True -flag threaded- default: True- manual: True--flag llvm- default: False- manual: True--flag optimized- default: True- manual: True- ------------------------------------------------------------------------------- -- Build pt 1: main project @@ -82,16 +61,9 @@ exposed-modules: Crypto.Sign.Ed25519 - if flag(optimized)- ghc-options: -O2-- if flag(llvm)- ghc-options: -fllvm- ghc-options: -Wall -fwarn-tabs- default-language: Haskell2010+ default-language: Haskell98 hs-source-dirs: src- cc-options: -O3 -march=native c-sources: src/cbits/ed25519.c include-dirs: src/cbits src/cbits/include @@ -103,13 +75,7 @@ main-is: properties.hs ghc-options: -w hs-source-dirs: tests- default-language: Haskell2010-- if flag(threaded)- ghc-options: -threaded -rtsopts -with-rtsopts=-N-- if flag(llvm)- ghc-options: -fllvm+ default-language: Haskell98 if !flag(test-properties) buildable: False@@ -118,37 +84,7 @@ base, ed25519, bytestring,- deepseq,- QuickCheck >= 2.4,- tasty >= 0.3,- tasty-quickcheck >= 0.3,- tasty-th >= 0.1.1--test-suite hunit- type: exitcode-stdio-1.0- main-is: hunit.hs- ghc-options: -w- hs-source-dirs: tests- default-language: Haskell2010-- if flag(threaded)- ghc-options: -threaded -rtsopts -with-rtsopts=-N-- if flag(llvm)- ghc-options: -fllvm-- if !flag(test-hunit)- buildable: False- else- build-depends:- base,- ed25519,- bytestring,- deepseq,- QuickCheck >= 2.4,- tasty >= 0.3,- tasty-hunit >= 0.2,- tasty-th >= 0.1.1+ QuickCheck >= 2.4 -- -- Style/doc tests below@@ -159,13 +95,7 @@ main-is: hlint.hs ghc-options: -w hs-source-dirs: tests- default-language: Haskell2010-- if flag(threaded)- ghc-options: -threaded -rtsopts -with-rtsopts=-N-- if flag(llvm)- ghc-options: -fllvm+ default-language: Haskell98 if !flag(test-hlint) buildable: False@@ -174,35 +104,6 @@ base, hlint >= 1.7 -test-suite doctests- type: exitcode-stdio-1.0- main-is: doctests.hs- ghc-options: -Wall- hs-source-dirs: tests- default-language: Haskell2010-- if flag(threaded)- ghc-options: -threaded -rtsopts -with-rtsopts=-N-- if flag(llvm)- ghc-options: -fllvm-- if !flag(test-doctests)- buildable: False- else- build-depends:- base,- bytestring,- containers,- directory >= 1.0,- deepseq,- doctest >= 0.9.1,- filepath,- semigroups >= 0.9-- if impl(ghc<7.6.1)- ghc-options: -Werror- ------------------------------------------------------------------------------- -- Build pt 3: benchmarks @@ -215,12 +116,6 @@ deepseq, ed25519 - if flag(optimized)- ghc-options: -O2-- if flag(llvm)- ghc-options: -fllvm-- default-language: Haskell2010+ default-language: Haskell98 hs-source-dirs: benchmarks main-is: bench1.hs
src/Crypto/Sign/Ed25519.hs view
@@ -29,7 +29,6 @@ , sign' -- :: SecretKey -> ByteString -> Signature , verify' -- :: PublicKey -> ByteString -> Signature -> Bool ) where-import Control.Monad (liftM, void) import Foreign.C.Types import Foreign.ForeignPtr (withForeignPtr) import Foreign.Marshal.Alloc (alloca)@@ -61,9 +60,11 @@ pk <- SI.mallocByteString cryptoSignPUBLICKEYBYTES sk <- SI.mallocByteString cryptoSignSECRETKEYBYTES - void . withForeignPtr pk $ \ppk ->- void . withForeignPtr sk $ \psk ->- c_crypto_sign_keypair ppk psk+ _ <- withForeignPtr pk $ \ppk -> do+ _ <- withForeignPtr sk $ \psk -> do+ _ <- c_crypto_sign_keypair ppk psk+ return ()+ return () return (PublicKey $ SI.fromForeignPtr pk 0 cryptoSignPUBLICKEYBYTES, SecretKey $ SI.fromForeignPtr sk 0 cryptoSignSECRETKEYBYTES)@@ -83,9 +84,9 @@ SU.unsafeUseAsCString sk $ \psk -> SI.createAndTrim (mlen+cryptoSignBYTES) $ \out -> alloca $ \smlen -> do- void (c_crypto_sign out smlen mstr (fromIntegral mlen) psk)- fromIntegral `liftM` peek smlen-{-# INLINEABLE sign #-}+ _ <- (c_crypto_sign out smlen mstr (fromIntegral mlen) psk)+ fromIntegral `fmap` peek smlen+{-# INLINE sign #-} -- | Verifies a signed message against a 'PublicKey'. verify :: PublicKey@@ -103,7 +104,7 @@ c_crypto_sign_open pout pmlen smstr (fromIntegral smlen) ppk return (r == 0)-{-# INLINEABLE verify #-}+{-# INLINE verify #-} -------------------------------------------------------------------------------- -- Detached signature support@@ -124,7 +125,7 @@ let sm = sign sk xs l = S.length sm in Signature $! S.take (l - S.length xs) sm-{-# INLINEABLE sign' #-}+{-# INLINE sign' #-} -- | Verify a message with a detached 'Signature', for a given -- 'PublicKey'.@@ -136,7 +137,7 @@ -- ^ Message signature -> Bool verify' pk xs (Signature sig) = verify pk (sig `S.append` xs)-{-# INLINEABLE verify' #-}+{-# INLINE verify' #-} -- -- FFI signature binding@@ -151,13 +152,13 @@ cryptoSignBYTES :: Int cryptoSignBYTES = 64 -foreign import ccall unsafe "crypto_sign_keypair"+foreign import ccall unsafe "ed25519_sign_keypair" c_crypto_sign_keypair :: Ptr Word8 -> Ptr Word8 -> IO CInt -foreign import ccall unsafe "crypto_sign"+foreign import ccall unsafe "ed25519_sign" c_crypto_sign :: Ptr Word8 -> Ptr CULLong -> Ptr CChar -> CULLong -> Ptr CChar -> IO CULLong -foreign import ccall unsafe "crypto_sign_open"+foreign import ccall unsafe "ed25519_sign_open" c_crypto_sign_open :: Ptr Word8 -> Ptr CULLong -> Ptr CChar -> CULLong -> Ptr CChar -> IO CInt
src/cbits/include/ed25519.h view
@@ -8,12 +8,12 @@ #define crypto_sign_IMPLEMENTATION crypto_sign_ed25519_IMPLEMENTATION #define crypto_sign_VERSION crypto_sign_ed25519_VERSION -int crypto_sign_keypair(unsigned char *pk,unsigned char *sk);-int crypto_sign(unsigned char *sm,unsigned long long *smlen,- const unsigned char *m,unsigned long long mlen,- const unsigned char *sk);-int crypto_sign_open(unsigned char *m,unsigned long long *mlen,- const unsigned char *sm,unsigned long long smlen,- const unsigned char *pk);+int ed25519_sign_keypair(unsigned char *pk,unsigned char *sk);+int ed25519_sign(unsigned char *sm,unsigned long long *smlen,+ const unsigned char *m,unsigned long long mlen,+ const unsigned char *sk);+int ed25519_sign_open(unsigned char *m,unsigned long long *mlen,+ const unsigned char *sm,unsigned long long smlen,+ const unsigned char *pk); #endif /* _ED25519_H_ */
src/cbits/keypair.c view
@@ -3,7 +3,7 @@ #include "sha512.h" #include "ge.h" -int crypto_sign_keypair(unsigned char *pk,unsigned char *sk)+int ed25519_sign_keypair(unsigned char *pk,unsigned char *sk) { unsigned char h[64]; ge_p3 A;
src/cbits/open.c view
@@ -4,7 +4,7 @@ #include "ge.h" #include "sc.h" -int crypto_sign_open(+int ed25519_sign_open( unsigned char *m,unsigned long long *mlen, const unsigned char *sm,unsigned long long smlen, const unsigned char *pk
src/cbits/sign.c view
@@ -3,7 +3,7 @@ #include "ge.h" #include "sc.h" -int crypto_sign(+int ed25519_sign( unsigned char *sm,unsigned long long *smlen, const unsigned char *m,unsigned long long mlen, const unsigned char *sk
src/cbits/test.c view
@@ -9,21 +9,21 @@ { int r = 0; - crypto_sign_keypair(pk,sk);+ ed25519_sign_keypair(pk,sk); printf("Keypair generated.\n"); unsigned char *msg = "Hello"; unsigned char sm[5+crypto_sign_BYTES]; unsigned long long smlen; - r = crypto_sign(sm, &smlen, msg, 5, sk);+ r = ed25519_sign(sm, &smlen, msg, 5, sk); assert(r == 0); printf("Signed message (length = %u)\n",smlen); unsigned long long mlen; unsigned char m[5+crypto_sign_BYTES]; - r = crypto_sign_open(m, &mlen, sm, smlen, pk);+ r = ed25519_sign_open(m, &mlen, sm, smlen, pk); assert(r == 0); printf("Verified message (length = %u)\n",mlen);
− tests/doctests.hs
@@ -1,73 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE ForeignFunctionInterface #-}--------------------------------------------------------------------------------- |--- Module : Main (doctests)--- Copyright : (C) 2012-13 Edward Kmett--- License : BSD-style (see the file LICENSE)--- Maintainer : Edward Kmett <ekmett@gmail.com>--- Stability : provisional--- Portability : portable------ This module provides doctests for a project based on the actual versions--- of the packages it was built with. It requires a corresponding Setup.lhs--- to be added to the project-------------------------------------------------------------------------------module Main where--import Build_doctests (deps)-import Control.Applicative-import Control.Monad-import Data.List-import System.Directory-import System.FilePath-import Test.DocTest--#if defined(mingw32_HOST_OS)-#if defined(i386_HOST_ARCH)-#define USE_CP-import Control.Applicative-import Control.Exception-import Foreign.C.Types-foreign import stdcall "windows.h SetConsoleCP" c_SetConsoleCP :: CUInt -> IO Bool-foreign import stdcall "windows.h GetConsoleCP" c_GetConsoleCP :: IO CUInt-#elif defined(x86_64_HOST_ARCH)-#define USE_CP-import Control.Applicative-import Control.Exception-import Foreign.C.Types-foreign import ccall "windows.h SetConsoleCP" c_SetConsoleCP :: CUInt -> IO Bool-foreign import ccall "windows.h GetConsoleCP" c_GetConsoleCP :: IO CUInt-#endif-#endif---- | Run in a modified codepage where we can print UTF-8 values on Windows.-withUnicode :: IO a -> IO a-#ifdef USE_CP-withUnicode m = do- cp <- c_GetConsoleCP- (c_SetConsoleCP 65001 >> m) `finally` c_SetConsoleCP cp-#else-withUnicode m = m-#endif--main :: IO ()-main = withUnicode $ getSources >>= \sources -> doctest $- "-isrc"- : "-idist/build/autogen"- : "-optP-include"- : "-optPdist/build/autogen/cabal_macros.h"- : "-hide-all-packages"- : map ("-package="++) deps ++ sources--getSources :: IO [FilePath]-getSources = filter (isSuffixOf ".hs") <$> go "src"- where- go dir = do- (dirs, files) <- getFilesAndDirectories dir- (files ++) . concat <$> mapM go dirs--getFilesAndDirectories :: FilePath -> IO ([FilePath], [FilePath])-getFilesAndDirectories dir = do- c <- map (dir </>) . filter (`notElem` ["..", "."]) <$> getDirectoryContents dir- (,) <$> filterM doesDirectoryExist c <*> filterM doesFileExist c
tests/hlint.hs view
@@ -1,5 +1,6 @@ module Main where +import Data.Monoid import Control.Monad import Language.Haskell.HLint import System.Environment@@ -8,5 +9,6 @@ main :: IO () main = do args <- getArgs- hints <- hlint $ ["src", "--cpp-define=HLINT"] ++ args+ hints <- hlint $ ["src", "benchmarks", "tests",+ "--cpp-define=HLINT"] `mappend` args unless (null hints) exitFailure
− tests/hunit.hs
@@ -1,21 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}-module Main- ( main -- :: IO ()- ) where-import Prelude as Prelude-import Data.List as List-import Data.Maybe-import Data.Function-import Control.Monad-import Control.DeepSeq-import Debug.Trace--import Test.Tasty-import Test.Tasty.TH-import Test.Tasty.HUnit as HUnit------------------------------------------------------------------------------------- Driver--main :: IO ()-main = $(defaultMainGenerator)
tests/properties.hs view
@@ -1,28 +1,24 @@-{-# LANGUAGE TemplateHaskell #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE CPP #-} module Main ( main -- :: IO () ) where-import Prelude-import Data.List as List-import Data.Maybe-import Data.Function-import Control.Monad-import Control.DeepSeq-import Debug.Trace+import Control.Monad+import Data.ByteString (ByteString)+import qualified Data.ByteString as S -import Test.Tasty-import Test.Tasty.TH-import Test.Tasty.QuickCheck as QC-import Test.QuickCheck.Property+import Crypto.Sign.Ed25519 -import Data.ByteString as S-import Crypto.Sign.Ed25519+import System.Environment (getArgs)+import Test.QuickCheck+import Test.QuickCheck.Property (morallyDubiousIOProperty)+import Text.Printf -------------------------------------------------------------------------------- -- Orphans instance Arbitrary ByteString where- arbitrary = pack `liftM` arbitrary+ arbitrary = S.pack `liftM` arbitrary instance Arbitrary SecretKey where arbitrary = SecretKey `liftM` arbitrary@@ -36,34 +32,63 @@ keypairProp :: ((PublicKey, SecretKey) -> Bool) -> Property keypairProp k = morallyDubiousIOProperty $ k `liftM` createKeypair -prop_sign_verify :: ByteString -> Property-prop_sign_verify xs+roundtrip :: ByteString -> Property+roundtrip xs = keypairProp $ \(pk,sk) -> verify pk (sign sk xs) +roundtrip' :: ByteString -> Property+roundtrip' xs+ = keypairProp $ \(pk,sk) -> verify' pk xs (sign' sk xs)+ -- Generally the signature format is '<signature><original message>' -- and <signature> is of a fixed length (crypto_sign_BYTES), which in -- ed25519's case is 64. sign' drops the message appended at the end, -- so we just make sure we have constant length signatures.-prop_sign'_length :: ByteString -> ByteString -> Property-prop_sign'_length xs xs2- = keypairProp $ \(pk,sk) ->+signLength :: (ByteString,ByteString) -> Property+signLength (xs,xs2)+ = keypairProp $ \(_,sk) -> let s1 = unSignature $ sign' sk xs s2 = unSignature $ sign' sk xs2 in S.length s1 == S.length s2 -- ed25519 has a sig length of 64-prop_sign'_length2 :: ByteString -> Property-prop_sign'_length2 xs- = keypairProp $ \(pk,sk) ->+signLength2 :: ByteString -> Property+signLength2 xs+ = keypairProp $ \(_,sk) -> (64 == S.length (unSignature $ sign' sk xs)) -prop_verify' :: ByteString -> Property-prop_verify' xs- = keypairProp $ \(pk,sk) ->- verify' pk xs (sign' sk xs)- -------------------------------------------------------------------------------- -- Driver main :: IO ()-main = $(defaultMainGenerator)+main = do+ args <- fmap (drop 1) getArgs+ let n = if null args then 100 else read (head args) :: Int+ (results, passed) <- runTests n+ printf "Passed %d tests!\n" (sum passed)+ unless (and results) (fail "Not all tests passed!")++runTests :: Int -> IO ([Bool], [Int])+runTests ntests = fmap unzip . forM (tests ntests) $ \(s, a) ->+ printf "%-40s: " s >> a++tests :: Int -> [(String, IO (Bool,Int))]+tests ntests =+ [ ("Signature roundtrip", wrap roundtrip)+ , ("Detached signature roundtrip", wrap roundtrip')+ , ("Detached signature length", wrap signLength)+ , ("Detached signature length (#2)", wrap signLength2)+ ]+ where+ wrap :: Testable prop => prop -> IO (Bool, Int)+ wrap prop = do+ r <- quickCheckWithResult stdArgs{maxSize=ntests} prop+ case r of+ Success n _ _ -> return (True, n)+ GaveUp n _ _ -> return (True, n)+#if MIN_VERSION_QuickCheck(2,6,0)+ Failure n _ _ _ _ _ _ _ -> return (False, n)+#else+ Failure n _ _ _ _ _ _ -> return (False, n)+#endif+ _ -> return (False, 0)