Fix generate(Safe)Prime to guarantee prime size
Add check for size in generatePrime Add size test in generateSafePrime Require only that top bit is set, instead of top 2 This is the general standard, see e.g. OpenSSL Add an error for too few bits being supplied to prime generator, and add documentation Add some documentation and require highest two bits set Simplify return syntax in generatePrime and generateSafePrime Switch exponent to bit-shift for small performance boost
This commit is contained in:
parent
16fc2a3104
commit
0cec622ddf
2
.gitignore
vendored
2
.gitignore
vendored
@ -10,3 +10,5 @@ QA
|
||||
benchs/Bench
|
||||
benchs/Hash
|
||||
*.sublime-workspace
|
||||
.cabal-sandbox/
|
||||
cabal.sandbox.config
|
||||
|
||||
@ -43,6 +43,8 @@ data CryptoError =
|
||||
-- Message authentification error
|
||||
| CryptoError_MacKeyInvalid
|
||||
| CryptoError_AuthenticationTagSizeInvalid
|
||||
-- Prime generation error
|
||||
| CryptoError_PrimeSizeInvalid
|
||||
deriving (Show,Eq,Enum,Data,Typeable)
|
||||
|
||||
instance E.Exception CryptoError
|
||||
|
||||
@ -27,6 +27,7 @@ import Crypto.Number.Basic (sqrti, gcde)
|
||||
import Crypto.Number.ModArithmetic (expSafe)
|
||||
import Crypto.Random.Types
|
||||
import Crypto.Random.Probabilistic
|
||||
import Crypto.Error
|
||||
|
||||
import Data.Bits
|
||||
|
||||
@ -40,22 +41,44 @@ isProbablyPrime !n
|
||||
| primalityTestFermat 50 (n`div`2) n = primalityTestMillerRabin 30 n
|
||||
| otherwise = False
|
||||
|
||||
-- | generate a prime number of the required bitsize
|
||||
-- | generate a prime number of the required bitsize (i.e. in the range
|
||||
-- [2^(b-1)+2^(b-2), 2^b)).
|
||||
--
|
||||
-- May throw a CryptoError_PrimeSizeInvalid if the requested size is less
|
||||
-- than 5 bits, as the smallest prime meeting these conditions is 29.
|
||||
-- This function requires that the two highest bits are set, so that when
|
||||
-- multiplied with another prime to create a key, it is guaranteed to be of
|
||||
-- the proper size.
|
||||
generatePrime :: MonadRandom m => Int -> m Integer
|
||||
generatePrime bits = do
|
||||
sp <- generateParams bits (Just SetTwoHighest) True
|
||||
return $ findPrimeFrom sp
|
||||
if bits < 5 then
|
||||
throwCryptoError $ CryptoFailed $ CryptoError_PrimeSizeInvalid
|
||||
else do
|
||||
sp <- generateParams bits (Just SetTwoHighest) True
|
||||
let prime = findPrimeFrom sp
|
||||
if prime < 1 `shiftL` bits then
|
||||
return $ prime
|
||||
else generatePrime bits
|
||||
|
||||
-- | generate a prime number of the form 2p+1 where p is also prime.
|
||||
-- it is also knowed 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.
|
||||
--
|
||||
-- May throw a CryptoError_PrimeSizeInvalid if the requested size is less than
|
||||
-- 6 bits, as the smallest safe prime with the two highest bits set is 59.
|
||||
generateSafePrime :: MonadRandom m => Int -> m Integer
|
||||
generateSafePrime bits = do
|
||||
sp <- generateParams bits (Just SetTwoHighest) True
|
||||
let p = findPrimeFromWith (\i -> isProbablyPrime (2*i+1)) (sp `div` 2)
|
||||
return (2*p+1)
|
||||
if bits < 6 then
|
||||
throwCryptoError $ CryptoFailed $ CryptoError_PrimeSizeInvalid
|
||||
else do
|
||||
sp <- generateParams bits (Just SetTwoHighest) True
|
||||
let p = findPrimeFromWith (\i -> isProbablyPrime (2*i+1)) (sp `div` 2)
|
||||
let val = 2 * p + 1
|
||||
if val < 1 `shiftL` bits then
|
||||
return $ val
|
||||
else generateSafePrime bits
|
||||
|
||||
-- | find a prime from a starting point where the property hold.
|
||||
findPrimeFromWith :: (Integer -> Bool) -> Integer -> Integer
|
||||
|
||||
@ -205,7 +205,7 @@ Library
|
||||
, bytestring
|
||||
, memory >= 0.8
|
||||
, ghc-prim
|
||||
ghc-options: -Wall -fwarn-tabs -optc-O3 -fno-warn-unused-imports
|
||||
ghc-options: -Wall -fwarn-tabs -optc-O3 -fno-warn-unused-imports -fobject-code
|
||||
default-language: Haskell2010
|
||||
cc-options: -std=gnu99
|
||||
if flag(old_toolchain_inliner)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user