properly check for point validity before making a point

This commit is contained in:
Vincent Hanquez 2016-12-02 15:28:03 +00:00
parent 922bed5ac5
commit 052417e5b1
3 changed files with 16 additions and 6 deletions

View File

@ -200,7 +200,7 @@ decodeECPoint mxy = case B.uncons mxy of
(xb,yb) = B.splitAt siz xy (xb,yb) = B.splitAt siz xy
x = os2ip xb x = os2ip xb
y = os2ip yb y = os2ip yb
in CryptoPassed $ Simple.Point x y in Simple.pointFromIntegers (x,y)
| otherwise -> CryptoFailed $ CryptoError_PointFormatInvalid | otherwise -> CryptoFailed $ CryptoError_PointFormatInvalid
curveSizeBytes :: EllipticCurve c => Proxy c -> Int curveSizeBytes :: EllipticCurve c => Proxy c -> Int

View File

@ -10,6 +10,7 @@ module Crypto.ECC.Simple.Prim
, pointBaseMul , pointBaseMul
, pointMul , pointMul
, pointAddTwoMuls , pointAddTwoMuls
, pointFromIntegers
, isPointAtInfinity , isPointAtInfinity
, isPointValid , isPointValid
) where ) where
@ -159,6 +160,15 @@ isPointAtInfinity :: Point curve -> Bool
isPointAtInfinity PointO = True isPointAtInfinity PointO = True
isPointAtInfinity _ = False 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 -- | check if a point is on specific curve
-- --
-- This perform three checks: -- This perform three checks:
@ -166,9 +176,8 @@ isPointAtInfinity _ = False
-- * x is not out of range -- * x is not out of range
-- * y is not out of range -- * y is not out of range
-- * the equation @y^2 = x^3 + a*x + b (mod p)@ holds -- * the equation @y^2 = x^3 + a*x + b (mod p)@ holds
isPointValid :: Curve curve => Point curve -> Bool isPointValid :: Curve curve => proxy curve -> Integer -> Integer -> Bool
isPointValid PointO = True isPointValid proxy x y =
isPointValid point@(Point x y) =
case ty of case ty of
CurvePrime (CurvePrimeParam p) -> CurvePrime (CurvePrimeParam p) ->
let a = curveEccA cc 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 , ((((x `add` a) `mul` x `add` y) `mul` x) `add` b `add` (squareF2m fx y)) == 0
] ]
where where
ty = curveType point ty = curveType proxy
cc = curveParameters point cc = curveParameters proxy
-- | div and mod -- | div and mod
divmod :: Integer -> Integer -> Integer -> Maybe Integer divmod :: Integer -> Integer -> Integer -> Maybe Integer

View File

@ -39,6 +39,7 @@ data CryptoError =
| CryptoError_PointSizeInvalid | CryptoError_PointSizeInvalid
| CryptoError_PointFormatInvalid | CryptoError_PointFormatInvalid
| CryptoError_PointFormatUnsupported | CryptoError_PointFormatUnsupported
| CryptoError_PointCoordinatesInvalid
-- Message authentification error -- Message authentification error
| CryptoError_MacKeyInvalid | CryptoError_MacKeyInvalid
| CryptoError_AuthenticationTagSizeInvalid | CryptoError_AuthenticationTagSizeInvalid