module Network.LibP2P.Crypto.Ed25519
( generateKeyPair
, keyPairFromSeed
) where
import qualified Crypto.Error as CE
import qualified Crypto.PubKey.Ed25519 as Ed
import Crypto.Random (getRandomBytes)
import Data.ByteArray (convert)
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import Network.LibP2P.Crypto.Key
generateKeyPair :: IO (Either String KeyPair)
generateKeyPair :: IO (Either String KeyPair)
generateKeyPair = do
seed <- Int -> IO ByteString
forall byteArray. ByteArray byteArray => Int -> IO byteArray
forall (m :: * -> *) byteArray.
(MonadRandom m, ByteArray byteArray) =>
Int -> m byteArray
getRandomBytes Int
32 :: IO ByteString
pure (keyPairFromSeed seed)
keyPairFromSeed :: ByteString -> Either String KeyPair
keyPairFromSeed :: ByteString -> Either String KeyPair
keyPairFromSeed ByteString
seed
| ByteString -> Int
BS.length ByteString
seed Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
32 = String -> Either String KeyPair
forall a b. a -> Either a b
Left String
"keyPairFromSeed: seed must be 32 bytes"
| Bool
otherwise =
case CryptoFailable SecretKey -> Either CryptoError SecretKey
forall a. CryptoFailable a -> Either CryptoError a
CE.eitherCryptoError (ByteString -> CryptoFailable SecretKey
forall ba. ByteArrayAccess ba => ba -> CryptoFailable SecretKey
Ed.secretKey ByteString
seed) of
Left CryptoError
err -> String -> Either String KeyPair
forall a b. a -> Either a b
Left (String -> Either String KeyPair)
-> String -> Either String KeyPair
forall a b. (a -> b) -> a -> b
$ String
"keyPairFromSeed: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> CryptoError -> String
forall a. Show a => a -> String
show CryptoError
err
Right SecretKey
sk ->
let pk :: PublicKey
pk = SecretKey -> PublicKey
Ed.toPublic SecretKey
sk
in KeyPair -> Either String KeyPair
forall a b. b -> Either a b
Right (KeyPair -> Either String KeyPair)
-> KeyPair -> Either String KeyPair
forall a b. (a -> b) -> a -> b
$
KeyPair
{ kpPublic :: PublicKey
kpPublic = KeyType -> ByteString -> PublicKey
PublicKey KeyType
Ed25519 (PublicKey -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
convert PublicKey
pk)
, kpPrivate :: PrivateKey
kpPrivate = KeyType -> ByteString -> PrivateKey
PrivateKey KeyType
Ed25519 (SecretKey -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
convert SecretKey
sk)
}