diff --git a/Crypto/ECC.hs b/Crypto/ECC.hs index 40092a0..d152006 100644 --- a/Crypto/ECC.hs +++ b/Crypto/ECC.hs @@ -15,6 +15,7 @@ module Crypto.ECC , Curve_P384R1(..) , Curve_P521R1(..) , Curve_X25519(..) + , Curve_X448(..) , EllipticCurve(..) , EllipticCurveDH(..) , EllipticCurveArith(..) @@ -33,6 +34,7 @@ import Crypto.Internal.ByteArray (ByteArray, ByteArrayAccess, Scrubbed import qualified Crypto.Internal.ByteArray as B import Crypto.Number.Serialize (i2ospOf_, os2ip) import qualified Crypto.PubKey.Curve25519 as X25519 +import qualified Crypto.PubKey.Ed448 as X448 import Data.Function (on) import Data.ByteArray (convert) @@ -183,6 +185,23 @@ instance EllipticCurveDH Curve_X25519 where ecdh _ s p = SharedSecret $ convert secret where secret = X25519.dh p s +data Curve_X448 = Curve_X448 + +instance EllipticCurve Curve_X448 where + type Point Curve_X448 = X448.PublicKey + type Scalar Curve_X448 = X448.SecretKey + curveSizeBits _ = 448 + curveGenerateScalar _ = X448.generateSecretKey + curveGenerateKeyPair _ = do + s <- X448.generateSecretKey + return $ KeyPair (X448.toPublic s) s + encodePoint _ p = B.convert p + decodePoint _ bs = X448.publicKey bs + +instance EllipticCurveDH Curve_X448 where + ecdh _ s p = SharedSecret $ convert secret + where secret = X448.dh p s + encodeECPoint :: forall curve bs . (Simple.Curve curve, ByteArray bs) => Simple.Point curve -> bs encodeECPoint Simple.PointO = error "encodeECPoint: cannot serialize point at infinity" encodeECPoint (Simple.Point x y) = B.concat [uncompressed,xb,yb] diff --git a/Crypto/PubKey/Ed448.hs b/Crypto/PubKey/Ed448.hs index af22176..33c969a 100644 --- a/Crypto/PubKey/Ed448.hs +++ b/Crypto/PubKey/Ed448.hs @@ -20,6 +20,7 @@ module Crypto.PubKey.Ed448 -- * methods , dh , toPublic + , generateSecretKey ) where import Data.Word @@ -27,6 +28,7 @@ import Foreign.Ptr import GHC.Ptr import Crypto.Error +import Crypto.Random import Crypto.Internal.Compat import Crypto.Internal.Imports import Crypto.Internal.ByteArray (ByteArrayAccess, ScrubbedBytes, Bytes, withByteArray) @@ -92,6 +94,10 @@ toPublic (SecretKey sec) = PublicKey <$> basePoint = Ptr "\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# {-# NOINLINE toPublic #-} +-- | Generate a secret key. +generateSecretKey :: MonadRandom m => m SecretKey +generateSecretKey = SecretKey <$> getRandomBytes x448_bytes + x448_bytes :: Int x448_bytes = 448 `quot` 8