diff --git a/Crypto/ECC.hs b/Crypto/ECC.hs index ea4d153..02e1777 100644 --- a/Crypto/ECC.hs +++ b/Crypto/ECC.hs @@ -118,7 +118,7 @@ instance EllipticCurve Curve_P256R1 where Nothing -> CryptoFailed $ CryptoError_PointSizeInvalid Just (m,xy) -- uncompressed - | m == 4 -> P256.pointFromBinary xy >>= validateP256Point + | m == 4 -> P256.pointFromBinary xy | otherwise -> CryptoFailed $ CryptoError_PointFormatInvalid instance EllipticCurveArith Curve_P256R1 where @@ -210,11 +210,6 @@ instance EllipticCurveDH Curve_X448 where ecdh _ s p = SharedSecret $ convert secret where secret = X448.dh p s -validateP256Point :: P256.Point -> CryptoFailable P256.Point -validateP256Point p - | P256.pointIsValid p = CryptoPassed p - | otherwise = CryptoFailed $ CryptoError_PointCoordinatesInvalid - 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/ECC/P256.hs b/Crypto/PubKey/ECC/P256.hs index 4708985..ba9ac60 100644 --- a/Crypto/PubKey/ECC/P256.hs +++ b/Crypto/PubKey/ECC/P256.hs @@ -26,6 +26,7 @@ module Crypto.PubKey.ECC.P256 , pointFromIntegers , pointToBinary , pointFromBinary + , unsafePointFromBinary -- * scalar arithmetic , scalarGenerate , scalarZero @@ -172,9 +173,18 @@ pointToBinary p = B.unsafeCreate pointSize $ \dst -> withPoint p $ \px py -> do ccryptonite_p256_to_bin (castPtr px) dst ccryptonite_p256_to_bin (castPtr py) (dst `plusPtr` 32) --- | Convert from binary to a point +-- | Convert from binary to a valid point pointFromBinary :: ByteArrayAccess ba => ba -> CryptoFailable Point -pointFromBinary ba +pointFromBinary ba = unsafePointFromBinary ba >>= validatePoint + where + validatePoint :: Point -> CryptoFailable Point + validatePoint p + | pointIsValid p = CryptoPassed p + | otherwise = CryptoFailed $ CryptoError_PointCoordinatesInvalid + +-- | Convert from binary to a point, possibly invalid +unsafePointFromBinary :: ByteArrayAccess ba => ba -> CryptoFailable Point +unsafePointFromBinary ba | B.length ba /= pointSize = CryptoFailed $ CryptoError_PublicKeySizeInvalid | otherwise = CryptoPassed $ withNewPoint $ \px py -> B.withByteArray ba $ \src -> do diff --git a/tests/KAT_PubKey/P256.hs b/tests/KAT_PubKey/P256.hs index 9549564..6b6d279 100644 --- a/tests/KAT_PubKey/P256.hs +++ b/tests/KAT_PubKey/P256.hs @@ -97,7 +97,7 @@ tests = testGroup "P256" [ testProperty "marshalling" $ \rx ry -> let p = P256.pointFromIntegers (unP256 rx, unP256 ry) b = P256.pointToBinary p :: Bytes - p' = P256.pointFromBinary b + p' = P256.unsafePointFromBinary b in propertyHold [ eqTest "point" (CryptoPassed p) p' ] , testProperty "marshalling-integer" $ \rx ry -> let p = P256.pointFromIntegers (unP256 rx, unP256 ry)