module Crypto.Ecdsa.Utils where
import Crypto.Number.Serialize (i2osp, os2ip)
import Crypto.PubKey.ECC.ECDSA (PrivateKey (..), PublicKey (..))
import Crypto.PubKey.ECC.Generate (generateQ)
import Crypto.PubKey.ECC.Types (CurveName (SEC_p256k1), Point (..),
getCurveByName)
import Data.ByteArray (ByteArray, ByteArrayAccess,
singleton)
importKey :: ByteArrayAccess privateKey => privateKey -> PrivateKey
{-# INLINE importKey #-}
importKey :: privateKey -> PrivateKey
importKey = Curve -> PrivateNumber -> PrivateKey
PrivateKey (CurveName -> Curve
getCurveByName CurveName
SEC_p256k1) (PrivateNumber -> PrivateKey)
-> (privateKey -> PrivateNumber) -> privateKey -> PrivateKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. privateKey -> PrivateNumber
forall ba. ByteArrayAccess ba => ba -> PrivateNumber
os2ip
exportKey :: ByteArray privateKey => PrivateKey -> privateKey
{-# INLINE exportKey #-}
exportKey :: PrivateKey -> privateKey
exportKey (PrivateKey Curve
_ PrivateNumber
key) = PrivateNumber -> privateKey
forall ba. ByteArray ba => PrivateNumber -> ba
i2osp PrivateNumber
key
derivePubKey :: PrivateKey -> PublicKey
{-# INLINE derivePubKey #-}
derivePubKey :: PrivateKey -> PublicKey
derivePubKey (PrivateKey Curve
curve PrivateNumber
p) = Curve -> PublicPoint -> PublicKey
PublicKey Curve
curve (Curve -> PrivateNumber -> PublicPoint
generateQ Curve
curve PrivateNumber
p)
exportPubKey :: ByteArray publicKey => PublicKey -> publicKey
exportPubKey :: PublicKey -> publicKey
exportPubKey (PublicKey Curve
_ PublicPoint
PointO) = publicKey
forall a. Monoid a => a
mempty
exportPubKey (PublicKey Curve
_ (Point PrivateNumber
x PrivateNumber
y)) = PrivateNumber -> publicKey
forall ba. ByteArray ba => PrivateNumber -> ba
i2osp PrivateNumber
x publicKey -> publicKey -> publicKey
forall a. Semigroup a => a -> a -> a
<> PrivateNumber -> publicKey
forall ba. ByteArray ba => PrivateNumber -> ba
i2osp PrivateNumber
y
exportPubKeyCompress :: ByteArray publicKey => PublicKey -> publicKey
exportPubKeyCompress :: PublicKey -> publicKey
exportPubKeyCompress (PublicKey Curve
_ PublicPoint
PointO) = publicKey
forall a. Monoid a => a
mempty
exportPubKeyCompress (PublicKey Curve
_ (Point PrivateNumber
x PrivateNumber
y)) = publicKey
prefix publicKey -> publicKey -> publicKey
forall a. Semigroup a => a -> a -> a
<> PrivateNumber -> publicKey
forall ba. ByteArray ba => PrivateNumber -> ba
i2osp PrivateNumber
x
where
prefix :: publicKey
prefix | PrivateNumber -> Bool
forall a. Integral a => a -> Bool
even PrivateNumber
y = Word8 -> publicKey
forall a. ByteArray a => Word8 -> a
singleton Word8
0x02
| Bool
otherwise = Word8 -> publicKey
forall a. ByteArray a => Word8 -> a
singleton Word8
0x03