-- | 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