diff --git a/Crypto/PubKey/ECC/P256.hs b/Crypto/PubKey/ECC/P256.hs index 511b4c8..3b1e9ed 100644 --- a/Crypto/PubKey/ECC/P256.hs +++ b/Crypto/PubKey/ECC/P256.hs @@ -38,9 +38,6 @@ newtype Scalar = Scalar SecureBytes data Point = Point !Bytes !Bytes deriving (Show,Eq) -publicKeySize :: Int -publicKeySize = 32 - scalarSize :: Int scalarSize = 32 @@ -65,6 +62,12 @@ toPoint :: Scalar -> Point toPoint s = withNewPoint $ \px py -> withScalar s $ \p -> ccryptonite_p256_basepoint_mul p px py +-- | Add a point to another point +pointAdd :: Point -> Point -> Point +pointAdd a b = withNewPoint $ \dx dy -> + withPoint a $ \ax ay -> withPoint b $ \bx by -> + ccryptonite_p256e_point_add ax ay bx by dx dy + -- | Multiply a point by a scalar pointMul :: Scalar -> Point -> Point pointMul scalar p = withNewPoint $ \dx dy -> @@ -194,6 +197,12 @@ foreign import ccall "cryptonite_p256_base_point_mul" ccryptonite_p256_basepoint_mul :: Ptr P256Scalar -> Ptr P256X -> Ptr P256Y -> IO () + +foreign import ccall "cryptonite_p256e_point_add" + ccryptonite_p256e_point_add :: Ptr P256X -> Ptr P256Y + -> Ptr P256X -> Ptr P256Y + -> Ptr P256X -> Ptr P256Y + -> IO () foreign import ccall "cryptonite_p256_point_mul" ccryptonite_p256_point_mul :: Ptr P256Scalar -> Ptr P256X -> Ptr P256Y diff --git a/cbits/p256/p256_ec.c b/cbits/p256/p256_ec.c index cc8e040..e9c41e1 100644 --- a/cbits/p256/p256_ec.c +++ b/cbits/p256/p256_ec.c @@ -1277,3 +1277,29 @@ void cryptonite_p256_points_mul_vartime( from_montgomery(out_x, px); from_montgomery(out_y, py); } + +/* this function is not part of the original source + add 2 points together. so far untested. + probably vartime, as it use point_add_or_double_vartime + */ +void cryptonite_p256e_point_add( + const cryptonite_p256_int *in_x1, const cryptonite_p256_int *in_y1, + const cryptonite_p256_int *in_x2, const cryptonite_p256_int *in_y2, + cryptonite_p256_int *out_x, cryptonite_p256_int *out_y) +{ + felem x1, y1, z1, x2, y2, z2, px1, py1, px2, py2; + const cryptonite_p256_int one = P256_ONE; + + to_montgomery(px1, in_x1); + to_montgomery(py1, in_y1); + to_montgomery(px2, in_x2); + to_montgomery(py2, in_y2); + + scalar_mult(x1, y1, z1, px1, py1, &one); + scalar_mult(x2, y2, z2, px2, py2, &one); + point_add_or_double_vartime(x1, y1, z1, x1, y1, z1, x2, y2, z2); + + point_to_affine(px1, py1, x1, y1, z1); + from_montgomery(out_x, px1); + from_montgomery(out_y, py1); +}