| License | BSD-style |
|---|---|
| Maintainer | Vincent Hanquez <vincent@snarc.org> |
| Stability | experimental |
| Portability | Good |
| Safe Haskell | None |
| Language | Haskell2010 |
Crypto.PubKey.ElGamal
Description
ElGamal encryption and signature over the multiplicative group of integers modulo a prime, reusing the parameters of Crypto.PubKey.DH.
These are raw primitives, not a scheme. The encryption here is textbook
ElGamal: it applies no padding, so it is malleable by construction --
multiplying a ciphertext's second component by t multiplies the plaintext
by t -- and it is not IND-CCA secure. A message is an Integer below the
modulus rather than a byte string, and nothing here maps one to the other.
Use it to build a scheme that adds those, or prefer
Crypto.PubKey.RSA.OAEP or Crypto.PubKey.ECIES where a scheme is what is
wanted.
The signature primitive is likewise raw, and an ephemeral value must never
be reused between signatures: two signatures under the same k reveal the
private key.
What is kept from the clock, and what is not
Every exponentiation with a secret exponent is
expSafe. Decryption inverts the shared
secret by Fermat's little theorem rather than by the extended Euclidean
algorithm, whose steps follow the bits it is given. sign cannot do that
-- k is inverted modulo p-1, which is even -- so it blinds instead: the
algorithm is handed k times a fresh random unit, and the blinder is
divided out afterwards. signWith, having no randomness of its own, hands
it k.
What is left is the Integer arithmetic around all of that, whose cost
follows the size of the numbers. See Crypto.PubKey.DSA for the same note
at more length.
Synopsis
- data Params
- data PublicNumber
- data PrivateNumber
- newtype EphemeralKey = EphemeralKey Integer
- data SharedKey
- data Signature = Signature {}
- generatePrivate :: MonadRandom m => Integer -> m PrivateNumber
- generatePublic :: Params -> PrivateNumber -> PublicNumber
- encryptWith :: EphemeralKey -> Params -> PublicNumber -> Integer -> CryptoFailable (Integer, Integer)
- encrypt :: MonadRandom m => Params -> PublicNumber -> Integer -> m (CryptoFailable (Integer, Integer))
- decrypt :: Params -> PrivateNumber -> (Integer, Integer) -> CryptoFailable Integer
- signWith :: (ByteArrayAccess msg, HashAlgorithm hash) => Integer -> Params -> PrivateNumber -> hash -> msg -> Maybe Signature
- signDigestWith :: HashAlgorithm hash => Integer -> Params -> PrivateNumber -> Digest hash -> Maybe Signature
- sign :: (ByteArrayAccess msg, HashAlgorithm hash, MonadRandom m) => Params -> PrivateNumber -> hash -> msg -> m Signature
- signDigest :: (HashAlgorithm hash, MonadRandom m) => Params -> PrivateNumber -> Digest hash -> m Signature
- verify :: (ByteArrayAccess msg, HashAlgorithm hash) => Params -> PublicNumber -> hash -> msg -> Signature -> Bool
- verifyDigest :: HashAlgorithm hash => Params -> PublicNumber -> Digest hash -> Signature -> Bool
Documentation
Represent Diffie Hellman parameters namely P (prime), and G (generator).
Instances
| Data Params Source # | |
Defined in Crypto.PubKey.DH Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Params -> c Params # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Params # toConstr :: Params -> Constr # dataTypeOf :: Params -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Params) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Params) # gmapT :: (forall b. Data b => b -> b) -> Params -> Params # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Params -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Params -> r # gmapQ :: (forall d. Data d => d -> u) -> Params -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Params -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Params -> m Params # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Params -> m Params # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Params -> m Params # | |
| Read Params Source # | |
| Show Params Source # | |
| NFData Params Source # | |
Defined in Crypto.PubKey.DH | |
| Eq Params Source # | |
data PublicNumber Source #
Represent Diffie Hellman public number Y.
Instances
data PrivateNumber Source #
Represent Diffie Hellman private number X.
Instances
newtype EphemeralKey Source #
ElGamal Ephemeral key. also called Temporary key.
Constructors
| EphemeralKey Integer |
Instances
| NFData EphemeralKey Source # | |
Defined in Crypto.PubKey.ElGamal Methods rnf :: EphemeralKey -> () # | |
ElGamal Signature
Instances
| Data Signature Source # | |
Defined in Crypto.PubKey.ElGamal Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Signature -> c Signature # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Signature # toConstr :: Signature -> Constr # dataTypeOf :: Signature -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Signature) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Signature) # gmapT :: (forall b. Data b => b -> b) -> Signature -> Signature # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Signature -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Signature -> r # gmapQ :: (forall d. Data d => d -> u) -> Signature -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Signature -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Signature -> m Signature # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Signature -> m Signature # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Signature -> m Signature # | |
| Read Signature Source # | |
| Show Signature Source # | |
| NFData Signature Source # | |
Defined in Crypto.PubKey.ElGamal | |
| Eq Signature Source # | |
Generation
generatePrivate :: MonadRandom m => Integer -> m PrivateNumber Source #
generate a private number, in [1, q-1] where q is the order of the
group. Zero is excluded: it would make the public number 1 and the shared
value constant.
generatePublic :: Params -> PrivateNumber -> PublicNumber Source #
generate a public number that is for the other party benefits. this number is usually called h=g^a
Encryption and decryption with no scheme
encryptWith :: EphemeralKey -> Params -> PublicNumber -> Integer -> CryptoFailable (Integer, Integer) Source #
encrypt with a specified ephemeral key
The ephemeral key must lie in [1, p-2] and must never be reused: zero
would leave the message unmasked, and a repeat lets anyone who learns one
plaintext recover the other. A message must be below the modulus, or
decryption would return it reduced.
encrypt :: MonadRandom m => Params -> PublicNumber -> Integer -> m (CryptoFailable (Integer, Integer)) Source #
encrypt a message using params and public keys will generate b (called the ephemeral key)
decrypt :: Params -> PrivateNumber -> (Integer, Integer) -> CryptoFailable Integer Source #
decrypt message
c1 must be a unit modulo p; a ciphertext whose first component is zero
or out of range is rejected rather than raising.
Signature primitives
Arguments
| :: (ByteArrayAccess msg, HashAlgorithm hash) | |
| => Integer | ephemeral value k, in [1, p-2] and coprime with p-1 |
| -> Params | DH params (p,g) |
| -> PrivateNumber | DH private key |
| -> hash | collision resistant hash algorithm |
| -> msg | message to sign |
| -> Maybe Signature |
sign a message with an explicit ephemeral value
k has to lie in [1, p-2] and be coprime with p-1. Nothing says the
value handed in cannot be used: either it fails one of those two conditions,
or it is one of the few that produce a second component of zero. Either way
the answer is to draw another k, which is what sign does.
k is an ephemeral private key. It has to be drawn uniformly at random,
kept secret, and used for one signature only: the private number follows
from a signature and its k, and equally from two signatures made with the
same k. None of that is visible to this function, which is why it takes
k from the caller and checks only what it can.
Arguments
| :: HashAlgorithm hash | |
| => Integer | ephemeral value k, in [1, p-2] and coprime with p-1 |
| -> Params | DH params (p,g) |
| -> PrivateNumber | DH private key |
| -> Digest hash | digest of the message to sign |
| -> Maybe Signature |
Sign a digest with an explicit ephemeral value.
The digest's type says which algorithm made it, so this needs nothing else
to name one. signWith takes a hash value and never reads it -- it is
there to fix the type -- which leaves a caller that is itself polymorphic
in the algorithm with nothing to pass.
Arguments
| :: (ByteArrayAccess msg, HashAlgorithm hash, MonadRandom m) | |
| => Params | DH params (p,g) |
| -> PrivateNumber | DH private key |
| -> hash | collision resistant hash algorithm |
| -> msg | message to sign |
| -> m Signature |
signDigest :: (HashAlgorithm hash, MonadRandom m) => Params -> PrivateNumber -> Digest hash -> m Signature Source #
Sign a digest, drawing the ephemeral value. See signDigestWith for
why a digest rather than a hash value.
Verification primitives
verify :: (ByteArrayAccess msg, HashAlgorithm hash) => Params -> PublicNumber -> hash -> msg -> Signature -> Bool Source #
verify a signature
verifyDigest :: HashAlgorithm hash => Params -> PublicNumber -> Digest hash -> Signature -> Bool Source #
Verify a signature over a digest. See signDigestWith for why a digest
rather than a hash value.