packages feed

cryptocipher 0.2.11 → 0.2.12

raw patch · 3 files changed

+52/−13 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Crypto.Cipher.DH: generateParams :: CryptoRandomGen g => g -> Int -> Integer -> Either GenError (Params, g)
+ Crypto.Cipher.DH: generatePrivate :: CryptoRandomGen g => g -> Int -> Either GenError (PrivateNumber, g)

Files

Crypto/Cipher/DH.hs view
@@ -12,13 +12,17 @@ 	, PublicNumber 	, PrivateNumber 	, SharedKey+	, generateParams+	, generatePrivate 	, generatePublic 	, getShared 	) where  import Number.ModArithmetic (exponantiation_rtl_binary)-import Number.Prime+import Number.Prime (generateSafePrime)+import Number.Generate (generateOfSize) import Crypto.Random+import Control.Arrow (first)  type Params = (Integer,Integer) {- P prime, G generator -} @@ -31,14 +35,22 @@ newtype SharedKey = SharedKey Integer {- S -} 	deriving (Show,Read,Eq,Enum,Real,Num,Ord) -generateParams :: CryptoRandomGen g => g -> Params-generateParams = undefined+-- | generate params from a specific generator (2 or 5 are common values)+-- we generate a safe prime (a prime number of the form 2p+1 where p is also prime)+generateParams :: CryptoRandomGen g => g -> Int -> Integer -> Either GenError (Params, g)+generateParams rng bits generator =+	either Left (Right . first (\p -> (p, generator))) $ generateSafePrime rng bits -generatePrivate :: CryptoRandomGen g => g -> PrivateNumber-generatePrivate rng = undefined+-- | generate a private number with no specific property+-- this number is usually called X in DH text.+generatePrivate :: CryptoRandomGen g => g -> Int -> Either GenError (PrivateNumber, g)+generatePrivate rng bits = either Left (Right . first PrivateNumber) $ generateOfSize rng bits +-- | generate a public number that is for the other party benefits.+-- this number is usually called Y in DH text. generatePublic :: Params -> PrivateNumber -> PublicNumber generatePublic (p,g) (PrivateNumber x) = PublicNumber $ exponantiation_rtl_binary g x p +-- | generate a shared key using our private number and the other party public number getShared :: Params -> PrivateNumber -> PublicNumber -> SharedKey getShared (p,_) (PrivateNumber x) (PublicNumber y) = SharedKey $ exponantiation_rtl_binary y x p
Number/Prime.hs view
@@ -1,6 +1,9 @@ module Number.Prime 	( generatePrime+	, generateSafePrime 	, isProbablyPrime+	, findPrimeFrom+	, findPrimeFromWith 	, primalityTestNaive 	-- , primalityTestAKS 	, primalityTestMillerRabin@@ -21,18 +24,41 @@ 	| any (\p -> p `divides` n) (filter (< n) smallPrimes) = Right (False, rng) 	| otherwise                                            = primalityTestMillerRabin rng 30 n +-- | generate a prime number of the required bitsize generatePrime :: CryptoRandomGen g => g -> Int -> Either GenError (Integer, g) generatePrime rng bits = case generateOfSize rng bits of 	Left err         -> Left err 	Right (sp, rng') -> findPrimeFrom rng' sp -findPrimeFrom :: CryptoRandomGen g => g -> Integer -> Either GenError (Integer, g)-findPrimeFrom rng n-	| even n        = findPrimeFrom rng (n+1)+-- | generate a prime number of the form 2p+1 where p is also prime.+-- it is also know as a Sophie Germaine prime or safe prime.+--+-- The number of safe prime is significantly smaller to the number of prime,+-- as such it shouldn't be used if this number is supposed to be kept safe.+generateSafePrime :: CryptoRandomGen g => g -> Int -> Either GenError (Integer, g)+generateSafePrime rng bits = case generateOfSize rng bits of+	Left err         -> Left err+	Right (sp, rng') -> case findPrimeFromWith rng' (\g i -> isProbablyPrime g (2*i+1)) (sp `div` 2) of+		Left err         -> Left err+		Right (p, rng'') -> Right (2*p+1, rng'')++-- | find a prime from a starting point where the property hold.+findPrimeFromWith :: CryptoRandomGen g => g -> (g -> Integer -> Either GenError (Bool,g)) -> Integer -> Either GenError (Integer, g)+findPrimeFromWith rng prop n+	| even n        = findPrimeFromWith rng prop (n+1) 	| otherwise     = case isProbablyPrime rng n of 		Left err               -> Left err-		Right (isPPrime, rng') -> if isPPrime then Right (n, rng') else findPrimeFrom rng' (n+2)+		Right (False, rng')    -> findPrimeFromWith rng' prop (n+2)+		Right (True, rng')     ->+			case prop rng' n of+				Left err             -> Left err+				Right (False, rng'') -> findPrimeFromWith rng'' prop (n+2)+				Right (True, rng'')  -> Right (n, rng'') +-- | find a prime from a starting point with no specific property.+findPrimeFrom :: CryptoRandomGen g => g -> Integer -> Either GenError (Integer, g)+findPrimeFrom rng n = findPrimeFromWith rng (\g _ -> Right (True, g)) n+ -- | Miller Rabin algorithm return if the number is probably prime or composite. -- the tries parameter is the number of recursion, that determines the accuracy of the test. primalityTestMillerRabin :: CryptoRandomGen g => g -> Int -> Integer -> Either GenError (Bool, g)@@ -79,9 +105,9 @@ 		-- for p prime, the euler totient (# of coprime to n) is clearly n -1 		totient = n-1 		ubound = (fst $ sqrti totient) * (logi n)-		logi n-			| n == 0    = 0-			| otherwise = 1 + logi (n `shiftR` 1)+		logi z+			| z == 0    = 0+			| otherwise = 1 + logi (z `shiftR` 1)  -- | Test naively is integer is prime. -- while naive, we skip even number and stop iteration at i > sqrt(n)@@ -149,4 +175,5 @@ 	]  {-# INLINE divides #-}+divides :: Integer -> Integer -> Bool divides i n = n `mod` i == 0
cryptocipher.cabal view
@@ -1,5 +1,5 @@ Name:                cryptocipher-Version:             0.2.11+Version:             0.2.12 Description:         Symmetrical Block, Stream and PubKey Ciphers License:             BSD3 License-file:        LICENSE