diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Changelog
 
+## 0.3.0 (2017-11-11)
+
+* Depend on protolude 0.2 minimum
+
 ## 0.2.0 (2017-06-08)
 
 * `Group` typeclass split into `Group` and `AbelianGroup` typeclasses
diff --git a/cmd/interop-entrypoint/Main.hs b/cmd/interop-entrypoint/Main.hs
--- a/cmd/interop-entrypoint/Main.hs
+++ b/cmd/interop-entrypoint/Main.hs
@@ -20,7 +20,7 @@
 import Crypto.Hash (SHA256(..))
 import Data.ByteArray.Encoding (convertFromBase, convertToBase, Base(Base16))
 import Options.Applicative
-import System.IO (hFlush, hGetLine, hPutStrLn)
+import System.IO (hFlush, hGetLine)
 
 import qualified Crypto.Spake2 as Spake2
 import Crypto.Spake2
@@ -64,7 +64,7 @@
 -- | Terminate the test with a failure, printing a message to stderr.
 abort :: HasCallStack => Text -> IO ()
 abort message = do
-  hPutStrLn stderr $ toS ("ERROR: " <> message)
+  hPutStrLn stderr ("ERROR: " <> message)
   exitWith (ExitFailure 1)
 
 
@@ -94,7 +94,7 @@
 
   where
     output message = do
-      hPutStrLn outH (toS (convertToBase Base16 message :: ByteString))
+      hPutStrLn outH (convertToBase Base16 message :: ByteString)
       hFlush outH
 
     parseHex line =
diff --git a/spake2.cabal b/spake2.cabal
--- a/spake2.cabal
+++ b/spake2.cabal
@@ -1,9 +1,9 @@
--- This file has been generated from package.yaml by hpack version 0.15.0.
+-- This file has been generated from package.yaml by hpack version 0.17.1.
 --
 -- see: https://github.com/sol/hpack
 
 name:           spake2
-version:        0.2.0
+version:        0.3.0
 synopsis:       Implementation of the SPAKE2 Password-Authenticated Key Exchange algorithm
 description:    This library implements the SPAKE2 password-authenticated key exchange
                 ("PAKE") algorithm. This allows two parties, who share a weak password, to
@@ -32,7 +32,7 @@
   ghc-options: -Wall -Wno-type-defaults
   build-depends:
       base >= 4.9 && < 5
-    , protolude
+    , protolude >= 0.2
     , bytestring
     , cryptonite
     , memory
@@ -54,7 +54,7 @@
   ghc-options: -Wall -Wno-type-defaults -threaded
   build-depends:
       base >= 4.9 && < 5
-    , protolude
+    , protolude >= 0.2
     , cryptonite
     , memory
     , optparse-applicative
@@ -70,7 +70,7 @@
   ghc-options: -Wall -Wno-type-defaults
   build-depends:
       base >= 4.9 && < 5
-    , protolude
+    , protolude >= 0.2
     , cryptonite
     , QuickCheck
     , spake2
diff --git a/src/Crypto/Spake2/Groups/Ed25519.hs b/src/Crypto/Spake2/Groups/Ed25519.hs
--- a/src/Crypto/Spake2/Groups/Ed25519.hs
+++ b/src/Crypto/Spake2/Groups/Ed25519.hs
@@ -18,7 +18,7 @@
   , generator
   ) where
 
-import Protolude hiding (clamp, group, zero)
+import Protolude hiding (group, zero)
 
 import Crypto.Error (CryptoFailable(..), CryptoError(..))
 import Crypto.Number.Generate (generateMax)
@@ -65,7 +65,7 @@
   type Element Ed25519 = ExtendedPoint 'Member
 
   elementAdd _ x y = addExtendedPoints x y
-  elementNegate group = scalarMultiply group (l - 1)
+  elementNegate _ x = negateExtendedPoint x
   groupIdentity _ = assertInGroup extendedZero
 
   encodeElement _ x = encodeAffinePoint (extendedToAffine' x)
@@ -140,7 +140,7 @@
 
 -- TODO document this
 dConst :: Integer
-dConst = -121665 * inv 121666  -- XXX: force eval?
+dConst = (-121665 * inv 121666) `mod` q  -- XXX: force eval?
 
 -- TODO document this
 i :: Integer
@@ -287,6 +287,11 @@
     d' = (-a) `mod` q
     -- J = (X1+Y1) % Q
     j = (x1 + y1) `mod` q
+
+-- | Negate an extended point.
+negateExtendedPoint :: ExtendedPoint preserving -> ExtendedPoint preserving
+negateExtendedPoint ExtendedPoint{x = x1, y = y1, z = z1, t = t1} =
+  ExtendedPoint{x= q - x1, y = y1, z = z1, t = q - t1}
 
 -- | Multiply a point (might be in the group, might not) by a scalar.
 safeScalarMultiply :: Integer -> ExtendedPoint a -> ExtendedPoint a
