diff --git a/Crypto/ECC/Ed25519.hs b/Crypto/ECC/Ed25519.hs index cf9fcd6..0a18223 100644 --- a/Crypto/ECC/Ed25519.hs +++ b/Crypto/ECC/Ed25519.hs @@ -26,6 +26,7 @@ module Crypto.ECC.Ed25519 , pointAdd , pointDouble , pointMul + , pointsMulVarTime ) where import Data.Bits @@ -204,6 +205,21 @@ pointMul (Scalar scalar) (Point base) = withByteArray base $ \pbase -> ed25519_point_scalarmul out pbase pscalar +-- | Multiply the point @p@ with @s2@ and add a lifted to curve value @s1@. +-- +-- @ +-- pointsMulVarTime s1 s2 p = 'pointAdd' ('toPoint' s1) ('pointMul' s2 p) +-- @ +-- +-- /WARNING:/ variable time +pointsMulVarTime :: Scalar -> Scalar -> Point -> Point +pointsMulVarTime (Scalar s1) (Scalar s2) (Point p) = + Point $ B.allocAndFreeze pointArraySize $ \out -> + withByteArray s1 $ \ps1 -> + withByteArray s2 $ \ps2 -> + withByteArray p $ \pp -> + ed25519_base_double_scalarmul_vartime out ps1 pp ps2 + foreign import ccall "cryptonite_ed25519_scalar_eq" ed25519_scalar_eq :: Ptr Scalar -> Ptr Scalar @@ -273,3 +289,10 @@ foreign import ccall "cryptonite_ed25519_point_scalarmul" -> Ptr Point -- base -> Ptr Scalar -- scalar -> IO () + +foreign import ccall "cryptonite_ed25519_base_double_scalarmul_vartime" + ed25519_base_double_scalarmul_vartime :: Ptr Point -- combo + -> Ptr Scalar -- scalar1 + -> Ptr Point -- base2 + -> Ptr Scalar -- scalar2 + -> IO () diff --git a/cbits/ed25519/ed25519-cryptonite-exts.h b/cbits/ed25519/ed25519-cryptonite-exts.h index 4bca444..78a657a 100644 --- a/cbits/ed25519/ed25519-cryptonite-exts.h +++ b/cbits/ed25519/ed25519-cryptonite-exts.h @@ -138,3 +138,9 @@ ED25519_FN(ed25519_point_scalarmul) (ge25519 *r, const ge25519 *p, const bignum2 } } } + +void +ED25519_FN(ed25519_base_double_scalarmul_vartime) (ge25519 *r, const bignum256modm s1, const ge25519 *p2, const bignum256modm s2) { + // computes [s1]basepoint + [s2]p2 + ge25519_double_scalarmult_vartime(r, p2, s2, s1); +} diff --git a/tests/ECC/Ed25519.hs b/tests/ECC/Ed25519.hs index dd0bcc1..66505ea 100644 --- a/tests/ECC/Ed25519.hs +++ b/tests/ECC/Ed25519.hs @@ -87,6 +87,9 @@ tests = testGroup "ECC.Ed25519" , testProperty "scalarmult distributive" $ \x y p -> let pR = Ed25519.pointMul x p `Ed25519.pointAdd` Ed25519.pointMul y p in pR `propertyEq` Ed25519.pointMul (x `Ed25519.scalarAdd` y) p + , testProperty "double scalarmult" $ \n1 n2 p -> + let pR = Ed25519.pointAdd (Ed25519.toPoint n1) (Ed25519.pointMul n2 p) + in pR `propertyEq` Ed25519.pointsMulVarTime n1 n2 p ] ] where