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

    import Crypto.Random (CPRG)
    import Crypto.Types.PubKey.ECC
    import Crypto.Types.PubKey.ECDSA
    import Crypto.Number.Generate
    import Crypto.PubKey.ECC.Prim

    -- | Generate Q given d.
    --
    -- /WARNING:/ Vulnerable to timing attacks.
    generateQ :: Curve
              -> Integer
              -> Point
    generateQ :: Curve -> Integer -> Point
    generateQ curve :: Curve
    curve d :: 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 :: CPRG g
             => g     -- ^ CPRG
             -> Curve -- ^ Elliptic Curve
             -> ((PublicKey, PrivateKey), g)
    generate :: g -> Curve -> ((PublicKey, PrivateKey), g)
    generate rng :: g
    rng curve :: Curve
    curve = ((Curve -> Point -> PublicKey
    PublicKey Curve
    curve Point
    q, Curve -> Integer -> PrivateKey
    PrivateKey Curve
    curve Integer
    d), g
    rng')
      where (d :: Integer
    d, rng' :: g
    rng') = g -> Integer -> Integer -> (Integer, g)
    forall g. CPRG g => g -> Integer -> Integer -> (Integer, g)
    generateBetween g
    rng 1 (Integer
    n Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    - 1)
            q :: Point
    q = Curve -> Integer -> Point
    generateQ Curve
    curve Integer
    d
            n :: Integer
    n = CurveCommon -> Integer
    ecc_n (CurveCommon -> Integer) -> CurveCommon -> Integer
    forall a b. (a -> b) -> a -> b
    $ Curve -> CurveCommon
    common_curve Curve
    curve