adding Curve_X25519.

This commit is contained in:
Kazu Yamamoto 2016-11-16 13:10:57 +09:00
parent dea0469c61
commit aa33c00855
2 changed files with 45 additions and 0 deletions

View File

@ -13,6 +13,7 @@ module Crypto.ECC
( Curve_P256R1(..) ( Curve_P256R1(..)
, Curve_P384R1(..) , Curve_P384R1(..)
, Curve_P521R1(..) , Curve_P521R1(..)
, Curve_X25519(..)
, EllipticCurve(..) , EllipticCurve(..)
, EllipticCurveDH(..) , EllipticCurveDH(..)
, EllipticCurveArith(..) , EllipticCurveArith(..)
@ -27,7 +28,9 @@ import Crypto.Random
import Crypto.Internal.Imports import Crypto.Internal.Imports
import Crypto.Internal.ByteArray (ByteArrayAccess, ScrubbedBytes) import Crypto.Internal.ByteArray (ByteArrayAccess, ScrubbedBytes)
import Crypto.Number.Serialize (i2ospOf_) import Crypto.Number.Serialize (i2ospOf_)
import qualified Crypto.PubKey.Curve25519 as X25519
import Data.Function (on) import Data.Function (on)
import Data.ByteArray (convert)
-- | An elliptic curve key pair composed of the private part (a scalar), and -- | An elliptic curve key pair composed of the private part (a scalar), and
-- the associated point. -- the associated point.
@ -158,3 +161,27 @@ instance EllipticCurveDH Curve_P521R1 where
H.Point x _ = unP521Point $ pointSmul s p H.Point x _ = unP521Point $ pointSmul s p
len = (521 + 7) `div` 8 len = (521 + 7) `div` 8
shared = SharedSecret $ i2ospOf_ len x shared = SharedSecret $ i2ospOf_ len x
data Curve_X25519 = Curve_X25519
instance EllipticCurve Curve_X25519 where
newtype Point Curve_X25519 = X25519Point X25519.PublicKey
newtype Scalar Curve_X25519 = X25519Scalar X25519.SecretKey
curveGetOrder _ = undefined
curveGetBasePoint = undefined
curveOfScalar _ = Curve_X25519
curveOfPoint _ = Curve_X25519
curveGenerateScalar = X25519Scalar <$> X25519.generateSecretKey
curveGenerateKeyPair = do
s <- X25519.generateSecretKey
let p = X25519.toPublic s
return $ KeyPair (X25519Point p) (X25519Scalar s)
instance EllipticCurveArith Curve_X25519 where
pointAdd = undefined
pointSmul = undefined
instance EllipticCurveDH Curve_X25519 where
ecdh (X25519Scalar s) (X25519Point p) = SharedSecret $ convert secret
where
secret = X25519.dh p s

View File

@ -9,6 +9,7 @@
-- --
{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MagicHash #-} {-# LANGUAGE MagicHash #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Crypto.PubKey.Curve25519 module Crypto.PubKey.Curve25519
( SecretKey ( SecretKey
, PublicKey , PublicKey
@ -20,10 +21,14 @@ module Crypto.PubKey.Curve25519
-- * methods -- * methods
, dh , dh
, toPublic , toPublic
, generateSecretKey
) where ) where
import Data.Bits
import Data.ByteString (ByteString)
import Data.Word import Data.Word
import Foreign.Ptr import Foreign.Ptr
import Foreign.Storable
import GHC.Ptr import GHC.Ptr
import Crypto.Error import Crypto.Error
@ -31,6 +36,8 @@ import Crypto.Internal.Compat
import Crypto.Internal.Imports import Crypto.Internal.Imports
import Crypto.Internal.ByteArray (ByteArrayAccess, ScrubbedBytes, Bytes, withByteArray) import Crypto.Internal.ByteArray (ByteArrayAccess, ScrubbedBytes, Bytes, withByteArray)
import qualified Crypto.Internal.ByteArray as B import qualified Crypto.Internal.ByteArray as B
import Crypto.Error (CryptoFailable(..))
import Crypto.Random
-- | A Curve25519 Secret key -- | A Curve25519 Secret key
newtype SecretKey = SecretKey ScrubbedBytes newtype SecretKey = SecretKey ScrubbedBytes
@ -110,3 +117,14 @@ foreign import ccall "cryptonite_curve25519_donna"
-> Ptr Word8 -- ^ secret -> Ptr Word8 -- ^ secret
-> Ptr Word8 -- ^ basepoint -> Ptr Word8 -- ^ basepoint
-> IO () -> IO ()
generateSecretKey :: MonadRandom m => m SecretKey
generateSecretKey = return $ unsafeDoIO $ do
bs :: ByteString <- getRandomBytes 32
withByteArray bs $ \inp -> do
e0 :: Word8 <- peek inp
poke inp (e0 .&. 0xf8)
e31 :: Word8 <- peekByteOff inp 31
pokeByteOff inp 31 ((e31 .&. 0x7f) .|. 0x40)
let CryptoPassed s = secretKey bs
return s