From 052417e5b124d488b411b43b414bb2a705a50d12 Mon Sep 17 00:00:00 2001 From: Vincent Hanquez Date: Fri, 2 Dec 2016 15:28:03 +0000 Subject: [PATCH] properly check for point validity before making a point --- Crypto/ECC.hs | 2 +- Crypto/ECC/Simple/Prim.hs | 19 ++++++++++++++----- Crypto/Error/Types.hs | 1 + 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Crypto/ECC.hs b/Crypto/ECC.hs index df2864a..adecae8 100644 --- a/Crypto/ECC.hs +++ b/Crypto/ECC.hs @@ -200,7 +200,7 @@ decodeECPoint mxy = case B.uncons mxy of (xb,yb) = B.splitAt siz xy x = os2ip xb y = os2ip yb - in CryptoPassed $ Simple.Point x y + in Simple.pointFromIntegers (x,y) | otherwise -> CryptoFailed $ CryptoError_PointFormatInvalid curveSizeBytes :: EllipticCurve c => Proxy c -> Int diff --git a/Crypto/ECC/Simple/Prim.hs b/Crypto/ECC/Simple/Prim.hs index cf2f7bd..872e77e 100644 --- a/Crypto/ECC/Simple/Prim.hs +++ b/Crypto/ECC/Simple/Prim.hs @@ -10,6 +10,7 @@ module Crypto.ECC.Simple.Prim , pointBaseMul , pointMul , pointAddTwoMuls + , pointFromIntegers , isPointAtInfinity , isPointValid ) where @@ -159,6 +160,15 @@ isPointAtInfinity :: Point curve -> Bool isPointAtInfinity PointO = True isPointAtInfinity _ = False +-- | Make a point on a curve from integer (x,y) coordinate +-- +-- if the point is not valid related to the curve then an error is +-- returned instead of a point +pointFromIntegers :: forall curve . Curve curve => (Integer, Integer) -> CryptoFailable (Point curve) +pointFromIntegers (x,y) + | isPointValid (Proxy :: Proxy curve) x y = CryptoPassed $ Point x y + | otherwise = CryptoFailed $ CryptoError_PointCoordinatesInvalid + -- | check if a point is on specific curve -- -- This perform three checks: @@ -166,9 +176,8 @@ isPointAtInfinity _ = False -- * x is not out of range -- * y is not out of range -- * the equation @y^2 = x^3 + a*x + b (mod p)@ holds -isPointValid :: Curve curve => Point curve -> Bool -isPointValid PointO = True -isPointValid point@(Point x y) = +isPointValid :: Curve curve => proxy curve -> Integer -> Integer -> Bool +isPointValid proxy x y = case ty of CurvePrime (CurvePrimeParam p) -> let a = curveEccA cc @@ -187,8 +196,8 @@ isPointValid point@(Point x y) = , ((((x `add` a) `mul` x `add` y) `mul` x) `add` b `add` (squareF2m fx y)) == 0 ] where - ty = curveType point - cc = curveParameters point + ty = curveType proxy + cc = curveParameters proxy -- | div and mod divmod :: Integer -> Integer -> Integer -> Maybe Integer diff --git a/Crypto/Error/Types.hs b/Crypto/Error/Types.hs index 7363763..4aaf4e0 100644 --- a/Crypto/Error/Types.hs +++ b/Crypto/Error/Types.hs @@ -39,6 +39,7 @@ data CryptoError = | CryptoError_PointSizeInvalid | CryptoError_PointFormatInvalid | CryptoError_PointFormatUnsupported + | CryptoError_PointCoordinatesInvalid -- Message authentification error | CryptoError_MacKeyInvalid | CryptoError_AuthenticationTagSizeInvalid