diff --git a/ECDSA/Util.hs b/ECDSA/Util.hs
new file mode 100644
--- /dev/null
+++ b/ECDSA/Util.hs
@@ -0,0 +1,42 @@
+{-# LANGUAGE CPP #-}
+#ifndef MIN_VERSION_integer_gmp
+#define MIN_VERSION_integer_gmp(a,b,c) 0
+#endif
+#if MIN_VERSION_integer_gmp(0,5,1)
+{-# LANGUAGE MagicHash, UnboxedTuples, BangPatterns #-}
+#endif
+module ECDSA.Util (ECDSA.Util.pmul, lengthBytes) where
+
+import Crypto.Types.PubKey.ECC (Curve(CurveFP), CurvePrime(..), CurveCommon(..), Point(..))
+import Codec.Crypto.ECC.Base as Hecc (EC(ECi), ECPF(ECPa), getx, gety, pmul)
+
+#if MIN_VERSION_integer_gmp(0,5,1)
+import GHC.Integer.GMP.Internals
+#else
+import Data.Bits
+#endif
+
+pmul :: (Curve, Point) -> Integer -> Point
+pmul (c,p) = hecc2point . Hecc.pmul (point2hecc c p)
+
+curve2hecc :: Curve -> EC Integer
+curve2hecc (CurveFP (CurvePrime p (CurveCommon a b _ n 1))) =
+	ECi (8 * lengthBytes n) a b p n
+curve2hecc _ = error "TODO: binary curves"
+
+point2hecc :: Curve -> Point -> ECPF Integer
+point2hecc curve (Point x y) = ECPa (curve2hecc curve) x y
+point2hecc _ _ = error "Point at infinity cannot be represented"
+
+hecc2point :: ECPF Integer -> Point
+hecc2point p = Point (getx p) (gety p)
+
+-- crypto-numbers has this, but depends on crypto-random
+lengthBytes :: Integer -> Int
+#if MIN_VERSION_integer_gmp(0,5,1)
+lengthBytes n = I# (word2Int# (sizeInBaseInteger n 256#))
+#else
+lengthBytes n
+    | n < 256   = 1
+    | otherwise = 1 + lengthBytes (n `shiftR` 8)
+#endif
diff --git a/ecdsa.cabal b/ecdsa.cabal
--- a/ecdsa.cabal
+++ b/ecdsa.cabal
@@ -1,5 +1,5 @@
 name:            ecdsa
-version:         0.1
+version:         0.1.1
 cabal-version:   >= 1.8
 license:         OtherLicense
 license-file:    COPYING
@@ -22,6 +22,9 @@
 library
         exposed-modules:
                 ECDSA
+
+        other-modules:
+                ECDSA.Util
 
         build-depends:
                 base == 4.*,
