    -- | Signature generation.
    module Crypto.PubKey.ECC.Generate where

    import Crypto.Number.Generate
    import Crypto.PubKey.ECC.ECDSA
    import Crypto.PubKey.ECC.Prim
    import Crypto.PubKey.ECC.Types
    import Crypto.Random.Types

    -- | Generate Q given d.
    --
    -- /WARNING:/ Vulnerable to timing attacks.
    generateQ
        :: Curve
        -> Integer
        -> Point
    generateQ :: Curve -> Integer -> Point
    generateQ Curve
    curve Integer
    d = Curve -> Integer -> Point -> Point
    pointMul Curve
    curve Integer
    d Point
    g
      where
        g :: Point
    g = CurveCommon -> Point
    ecc_g (CurveCommon -> Point) -> CurveCommon -> Point
    forall a b. (a -> b) -> a -> b
    $ Curve -> CurveCommon
    common_curve Curve
    curve

    -- | Generate a pair of (private, public) key.
    --
    -- /WARNING:/ Vulnerable to timing attacks.
    generate
        :: MonadRandom m
        => Curve
        -- ^ Elliptic Curve
        -> m (PublicKey, PrivateKey)
    generate :: forall (m :: * -> *).
    MonadRandom m =>
    Curve -> m (PublicKey, PrivateKey)
    generate Curve
    curve = do
        d <- Integer -> Integer -> m Integer
    forall (m :: * -> *).
    MonadRandom m =>
    Integer -> Integer -> m Integer
    generateBetween Integer
    1 (Integer
    n Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    - Integer
    1)
        let q = Curve -> Integer -> Point
    generateQ Curve
    curve Integer
    d
        return (PublicKey curve q, PrivateKey curve d)
      where
        n :: Integer
    n = CurveCommon -> Integer
    ecc_n (CurveCommon -> Integer) -> CurveCommon -> Integer
    forall a b. (a -> b) -> a -> b
    $ Curve -> CurveCommon
    common_curve Curve
    curve