| License | BSD-style |
|---|---|
| Maintainer | Vincent Hanquez <vincent@snarc.org> |
| Stability | experimental |
| Portability | Good |
| Safe Haskell | None |
| Language | Haskell2010 |
Crypto.PubKey.RSA
Contents
Description
Synopsis
- data Error
- data PublicKey = PublicKey {}
- data PrivateKey = PrivateKey {}
- data Blinder = Blinder !Integer !Integer
- generateWith :: (Integer, Integer) -> Int -> Integer -> Maybe (PublicKey, PrivateKey)
- generate :: MonadRandom m => Int -> Integer -> m (PublicKey, PrivateKey)
- generateBlinder :: MonadRandom m => Integer -> m Blinder
Documentation
error possible during encryption, decryption or signing.
Constructors
| MessageSizeIncorrect | the message to decrypt is not of the correct size (need to be == private_size) |
| MessageTooLong | the message to encrypt is too long |
| MessageNotRecognized | the message decrypted doesn't have a PKCS15 structure (0 2 .. 0 msg) |
| SignatureTooLong | the message's digest is too long |
| InvalidParameters | some parameters lead to breaking assumptions. |
Represent a RSA public key
Constructors
| PublicKey | |
Instances
| Data PublicKey Source # | |||||
Defined in Crypto.PubKey.RSA.Types Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> PublicKey -> c PublicKey # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c PublicKey # toConstr :: PublicKey -> Constr # dataTypeOf :: PublicKey -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c PublicKey) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PublicKey) # gmapT :: (forall b. Data b => b -> b) -> PublicKey -> PublicKey # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> PublicKey -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> PublicKey -> r # gmapQ :: (forall d. Data d => d -> u) -> PublicKey -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> PublicKey -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> PublicKey -> m PublicKey # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> PublicKey -> m PublicKey # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> PublicKey -> m PublicKey # | |||||
| Generic PublicKey Source # | |||||
Defined in Crypto.PubKey.RSA.Types Associated Types
| |||||
| Read PublicKey Source # | |||||
| Show PublicKey Source # | |||||
| NFData PublicKey Source # | |||||
Defined in Crypto.PubKey.RSA.Types | |||||
| Eq PublicKey Source # | |||||
| type Rep PublicKey Source # | |||||
Defined in Crypto.PubKey.RSA.Types type Rep PublicKey = D1 ('MetaData "PublicKey" "Crypto.PubKey.RSA.Types" "crypton-2.2.5-923qx9xmPoRGJz70ZM2O9F" 'False) (C1 ('MetaCons "PublicKey" 'PrefixI 'True) (S1 ('MetaSel ('Just "public_size") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int) :*: (S1 ('MetaSel ('Just "public_n") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Integer) :*: S1 ('MetaSel ('Just "public_e") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Integer)))) | |||||
data PrivateKey Source #
Represent a RSA private key.
Only the pub, d fields are mandatory to fill.
p, q, dP, dQ, qinv are by-product during RSA generation, but are useful to record here to speed up massively the decrypt and sign operation.
implementations can leave optional fields to 0.
Constructors
| PrivateKey | |
Fields
| |
Instances
A blinder, which keeps the timing of the private key operation from saying anything about the number it was given.
The private exponent is not what is at risk. expSafe,
which the exponentiation goes through, keeps the value of an exponent out
of the work it does.
What a blinder covers is the other side. Without one, the operation runs on the ciphertext as it arrived, so how long it takes depends on a number an attacker may have chosen and can vary -- which is what a remote timing attack on RSA needs. With one, the input is multiplied by a random value first and that value divided out afterwards, so the timing carries nothing an attacker can steer.
Every private key operation here takes a . The
Maybe BlinderSafer form of each -- decryptSafer,
signSafer and their kind -- generates one and is
the one to reach for. Pass Nothing only where the input is not attacker
controlled and you have decided that it is not.
A blinder costs one more exponentiation, by the public exponent, which is the cheap direction: measured on an Apple M4, PKCS#1 v1.5 signing goes from about 601 to about 620 microseconds.
Use a blinder once. generateBlinder makes a fresh one;
carrying one across operations is not what it is for.
Instances
Generation function
Arguments
| :: (Integer, Integer) | chosen distinct primes p and q |
| -> Int | size in bytes |
| -> Integer | RSA public exponent |
| -> Maybe (PublicKey, PrivateKey) |
Generate a key pair given p and q.
p and q need to be distinct prime numbers.
e need to be coprime to phi=(p-1)*(q-1). If that's not the case, the function will not return a key pair. A small hamming weight results in better performance.
- e=0x10001 is a popular choice
- e=3 is popular as well, but proven to not be as secure for some cases.
WARNING: Making a key is not constant time, and cannot be: the search for
the two primes takes as long as it takes, and Prime is not
constant time either. What that leaks is about the search rather than
about the primes it settles on. Of the arithmetic that does touch them,
the inverse of one prime modulo the other is worked out without a side
channel, and so is the private exponent, which is the inverse of e modulo
(p-1)*(q-1): e being public lets that be worked out as a remainder, an
inverse modulo e itself, and an exact division, none of which follows the
number being inverted. An e that is not prime keeps the extended
Euclidean algorithm, which for a public e is one division by a small
number and then a few steps on numbers under it.
Arguments
| :: MonadRandom m | |
| => Int | size in bytes |
| -> Integer | RSA public exponent |
| -> m (PublicKey, PrivateKey) |
generate a pair of (private, public) key of size in bytes.
Arguments
| :: MonadRandom m | |
| => Integer | RSA public N parameter. |
| -> m Blinder |
Generate a blinder to use with decryption and signing operation
the unique parameter apart from the random number generator is the public key value N.
The blinder holds a random number and its inverse. N is composite, so Fermat has no answer for the inverse and it goes through the extended Euclidean algorithm, whose steps follow the number handed to it -- which would be the number the blinding rests on. So the algorithm is handed that number multiplied by another random one instead, and its answer multiplied by that number again, which leaves the inverse wanted and shows the algorithm nothing that has anything to do with it.