Add P256 functions to implement ECDSA

This commit is contained in:
Olivier Chéron 2017-10-08 15:28:14 +02:00
parent 19b7ab375a
commit 977e75f478
2 changed files with 29 additions and 1 deletions

View File

@ -8,7 +8,6 @@
-- P256 support -- P256 support
-- --
{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE EmptyDataDecls #-}
{-# OPTIONS_GHC -fno-warn-unused-binds #-} {-# OPTIONS_GHC -fno-warn-unused-binds #-}
module Crypto.PubKey.ECC.P256 module Crypto.PubKey.ECC.P256
@ -22,7 +21,9 @@ module Crypto.PubKey.ECC.P256
, pointDh , pointDh
, pointsMulVarTime , pointsMulVarTime
, pointIsValid , pointIsValid
, pointIsAtInfinity
, toPoint , toPoint
, pointX
, pointToIntegers , pointToIntegers
, pointFromIntegers , pointFromIntegers
, pointToBinary , pointToBinary
@ -31,6 +32,7 @@ module Crypto.PubKey.ECC.P256
-- * Scalar arithmetic -- * Scalar arithmetic
, scalarGenerate , scalarGenerate
, scalarZero , scalarZero
, scalarN
, scalarIsZero , scalarIsZero
, scalarAdd , scalarAdd
, scalarSub , scalarSub
@ -77,6 +79,9 @@ data P256Scalar
data P256Y data P256Y
data P256X data P256X
order :: Integer
order = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551
------------------------------------------------------------------------ ------------------------------------------------------------------------
-- Point methods -- Point methods
------------------------------------------------------------------------ ------------------------------------------------------------------------
@ -146,6 +151,19 @@ pointIsValid p = unsafeDoIO $ withPoint p $ \px py -> do
r <- ccryptonite_p256_is_valid_point px py r <- ccryptonite_p256_is_valid_point px py
return (r /= 0) return (r /= 0)
-- | Check if a 'Point' is the point at infinity
pointIsAtInfinity :: Point -> Bool
pointIsAtInfinity (Point b) = constAllZero b
-- | Return the x coordinate as a 'Scalar' if the point is not at infinity
pointX :: Point -> Maybe Scalar
pointX p
| pointIsAtInfinity p = Nothing
| otherwise = Just $
withNewScalarFreeze $ \d ->
withPoint p $ \px _ ->
ccryptonite_p256_mod ccryptonite_SECP256r1_n (castPtr px) (castPtr d)
-- | Convert a point to (x,y) Integers -- | Convert a point to (x,y) Integers
pointToIntegers :: Point -> (Integer, Integer) pointToIntegers :: Point -> (Integer, Integer)
pointToIntegers p = unsafeDoIO $ withPoint p $ \px py -> pointToIntegers p = unsafeDoIO $ withPoint p $ \px py ->
@ -216,6 +234,10 @@ scalarGenerate = unwrap . scalarFromBinary . witness <$> getRandomBytes 32
scalarZero :: Scalar scalarZero :: Scalar
scalarZero = withNewScalarFreeze $ \d -> ccryptonite_p256_init d scalarZero = withNewScalarFreeze $ \d -> ccryptonite_p256_init d
-- | The scalar representing the curve order
scalarN :: Scalar
scalarN = throwCryptoError (scalarFromInteger order)
-- | Check if the scalar is 0 -- | Check if the scalar is 0
scalarIsZero :: Scalar -> Bool scalarIsZero :: Scalar -> Bool
scalarIsZero s = unsafeDoIO $ withScalar s $ \d -> do scalarIsZero s = unsafeDoIO $ withScalar s $ \d -> do

View File

@ -126,6 +126,12 @@ tests = testGroup "P256"
, testProperty "point-add" propertyPointAdd , testProperty "point-add" propertyPointAdd
, testProperty "point-negate" propertyPointNegate , testProperty "point-negate" propertyPointNegate
, testProperty "point-mul" propertyPointMul , testProperty "point-mul" propertyPointMul
, testProperty "infinity" $
let gN = P256.toPoint P256.scalarN
g1 = P256.pointBase
in propertyHold [ eqTest "zero" True (P256.pointIsAtInfinity gN)
, eqTest "base" False (P256.pointIsAtInfinity g1)
]
] ]
] ]
where where