diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,11 @@
 # Change log for elliptic-curve
 
+## 0.2.2
+
+* Fix `Arbitrary` instances for elliptic curves.
+* Fix `Random` instances for elliptic curves.
+* Fix `Functor` instances for groups.
+
 ## 0.2.1
 
 * Fix dependency issue with `galois-field`.
diff --git a/elliptic-curve.cabal b/elliptic-curve.cabal
--- a/elliptic-curve.cabal
+++ b/elliptic-curve.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 664a809970025f3cc9258b03d8eaed1d4a44189ed18d2cda5ffb313eb866a2ce
+-- hash: c5865759f58bc792d7eb06624580c9d93023c42e4ec63b310c5a6d34c01e81ae
 
 name:           elliptic-curve
-version:        0.2.1
+version:        0.2.2
 synopsis:       Elliptic curve library
 description:    An extensible library of elliptic curves used in cryptography research
 category:       Cryptography
diff --git a/generate/Generate/Binary/Curve.hs b/generate/Generate/Binary/Curve.hs
--- a/generate/Generate/Binary/Curve.hs
+++ b/generate/Generate/Binary/Curve.hs
@@ -20,6 +20,7 @@
   <$$> indent 2
     (    "( module Curve.Binary"
     <$$> ", module Curve.Binary." <> pretty curve
+    <$$> ", Point(..)"
     <$$> ") where"
     )
   <>   prettyBreak
diff --git a/generate/Generate/Edwards/Curve.hs b/generate/Generate/Edwards/Curve.hs
--- a/generate/Generate/Edwards/Curve.hs
+++ b/generate/Generate/Edwards/Curve.hs
@@ -20,6 +20,7 @@
   <$$> indent 2
     (    "( module Curve.Edwards"
     <$$> ", module Curve.Edwards." <> pretty curve
+    <$$> ", Point(..)"
     <$$> ") where"
     )
   <>   prettyBreak
diff --git a/generate/Generate/Montgomery/Curve.hs b/generate/Generate/Montgomery/Curve.hs
--- a/generate/Generate/Montgomery/Curve.hs
+++ b/generate/Generate/Montgomery/Curve.hs
@@ -20,6 +20,7 @@
   <$$> indent 2
     (    "( module Curve.Montgomery"
     <$$> ", module Curve.Montgomery." <> pretty curve
+    <$$> ", Point(..)"
     <$$> ") where"
     )
   <>   prettyBreak
diff --git a/generate/Generate/Weierstrass/Curve.hs b/generate/Generate/Weierstrass/Curve.hs
--- a/generate/Generate/Weierstrass/Curve.hs
+++ b/generate/Generate/Weierstrass/Curve.hs
@@ -20,6 +20,7 @@
   <$$> indent 2
     (    "( module Curve.Weierstrass"
     <$$> ", module Curve.Weierstrass." <> pretty curve
+    <$$> ", Point(..)"
     <$$> ") where"
     )
   <>   prettyBreak
diff --git a/src/Curve.hs b/src/Curve.hs
--- a/src/Curve.hs
+++ b/src/Curve.hs
@@ -8,7 +8,7 @@
 import Control.Monad.Random (Random(..))
 import GaloisField (GaloisField)
 import PrimeField (PrimeField, toInt)
-import Test.Tasty.QuickCheck (Arbitrary(..), suchThatMap)
+import Test.Tasty.QuickCheck (Arbitrary(..))
 
 import Group (Group(..))
 
@@ -17,7 +17,7 @@
 -------------------------------------------------------------------------------
 
 -- | Elliptic curves.
-class (GaloisField q, GaloisField r, Group (Point f c e q r))
+class (GaloisField q, PrimeField' r, Group (Point f c e q r))
   => Curve (f :: Form) (c :: Coordinates) e q r where
   {-# MINIMAL char, cof, disc, fromA, point, pointX, toA, yX #-}
 
@@ -38,8 +38,8 @@
   data family Point f c e q r :: *
 
   -- | Curve point multiplication.
-  mul :: r ~ PrimeField p => Point f c e q r -> r -> Point f c e q r
-  mul = (. toInt) . mul'
+  mul :: Point f c e q r -> r -> Point f c e q r
+  mul = (. toInt') . mul'
   {-# INLINABLE mul #-}
 
   -- | Get point from X and Y coordinates.
@@ -74,30 +74,56 @@
 -- Instances
 -------------------------------------------------------------------------------
 
+-- Elliptic curve points are arbitrary.
+instance Curve f c e q r => Arbitrary (Point f c e q r) where
+
+  -- Arbitrary group element.
+  arbitrary = mul gen <$> arbitrary
+  {- Arbitrary curve point.
+  arbitrary = suchThatMap arbitrary pointX
+  -}
+  {-# INLINABLE arbitrary #-}
+
 -- Elliptic curve points are monoids.
 instance Curve f c e q r => Monoid (Point f c e q r) where
 
   mempty = id
   {-# INLINABLE mempty #-}
 
+-- Elliptic curve points are random.
+instance Curve f c e q r => Random (Point f c e q r) where
+
+  -- Random group element.
+  random  = first (mul gen) . random
+  {- Random curve point.
+  random g = case pointX x of
+    Just p -> (p, g')
+    _      -> random g'
+    where
+      (x, g') = random g
+  -}
+  {-# INLINABLE random #-}
+
+  randomR = panic "not implemented."
+
 -- Elliptic curve points are semigroups.
 instance Curve f c e q r => Semigroup (Point f c e q r) where
 
   p <> q = if p == q then dbl p else add p q
   {-# INLINABLE (<>) #-}
 
--- Elliptic curve points are arbitrary.
-instance Curve f c e q r => Arbitrary (Point f c e q r) where
+-------------------------------------------------------------------------------
+-- Temporary
+-------------------------------------------------------------------------------
 
-  arbitrary = suchThatMap arbitrary pointX
-  {-# INLINABLE arbitrary #-}
+-- Prime field class.
+class GaloisField k => PrimeField' k where
+  {-# MINIMAL toInt' #-}
 
--- Elliptic curve points are random.
-instance Curve f c e q r => Random (Point f c e q r) where
+  toInt' :: k -> Integer
 
-  random g = let (x, g') = random g in case pointX x of
-    Just p -> (p, g')
-    _      -> random g'
-  {-# INLINABLE random #-}
+-- Prime field instance.
+instance KnownNat p => PrimeField' (PrimeField p) where
 
-  randomR = panic "not implemented."
+  toInt' = toInt
+  {-# INLINABLE toInt' #-}
diff --git a/src/Curve/Binary.hs b/src/Curve/Binary.hs
--- a/src/Curve/Binary.hs
+++ b/src/Curve/Binary.hs
@@ -4,6 +4,7 @@
   ( module Curve
   , module Curve.Binary
   , module Group
+  , Point(..)
   ) where
 
 import Protolude
@@ -11,7 +12,7 @@
 import GaloisField (GaloisField(..))
 import Text.PrettyPrint.Leijen.Text (Pretty(..))
 
-import Curve (Coordinates(..), Curve(..), Form(..))
+import Curve (Coordinates(..), Curve(..), Form(..), PrimeField')
 import Group (Group(..))
 
 -------------------------------------------------------------------------------
@@ -22,7 +23,7 @@
 type BPoint = Point 'Binary
 
 -- | Binary curves.
-class (GaloisField q, GaloisField r, Curve 'Binary c e q r) => BCurve c e q r where
+class (GaloisField q, PrimeField' r, Curve 'Binary c e q r) => BCurve c e q r where
   {-# MINIMAL a_, b_, h_, p_, r_, x_, y_ #-}
   a_ :: BPoint c e q r -> q       -- ^ Coefficient @A@.
   b_ :: BPoint c e q r -> q       -- ^ Coefficient @B@.
diff --git a/src/Curve/Binary/SECT113R1.hs b/src/Curve/Binary/SECT113R1.hs
--- a/src/Curve/Binary/SECT113R1.hs
+++ b/src/Curve/Binary/SECT113R1.hs
@@ -1,6 +1,7 @@
 module Curve.Binary.SECT113R1
   ( module Curve.Binary
   , module Curve.Binary.SECT113R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Binary/SECT113R2.hs b/src/Curve/Binary/SECT113R2.hs
--- a/src/Curve/Binary/SECT113R2.hs
+++ b/src/Curve/Binary/SECT113R2.hs
@@ -1,6 +1,7 @@
 module Curve.Binary.SECT113R2
   ( module Curve.Binary
   , module Curve.Binary.SECT113R2
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Binary/SECT131R1.hs b/src/Curve/Binary/SECT131R1.hs
--- a/src/Curve/Binary/SECT131R1.hs
+++ b/src/Curve/Binary/SECT131R1.hs
@@ -1,6 +1,7 @@
 module Curve.Binary.SECT131R1
   ( module Curve.Binary
   , module Curve.Binary.SECT131R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Binary/SECT131R2.hs b/src/Curve/Binary/SECT131R2.hs
--- a/src/Curve/Binary/SECT131R2.hs
+++ b/src/Curve/Binary/SECT131R2.hs
@@ -1,6 +1,7 @@
 module Curve.Binary.SECT131R2
   ( module Curve.Binary
   , module Curve.Binary.SECT131R2
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Binary/SECT163K1.hs b/src/Curve/Binary/SECT163K1.hs
--- a/src/Curve/Binary/SECT163K1.hs
+++ b/src/Curve/Binary/SECT163K1.hs
@@ -1,6 +1,7 @@
 module Curve.Binary.SECT163K1
   ( module Curve.Binary
   , module Curve.Binary.SECT163K1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Binary/SECT163R1.hs b/src/Curve/Binary/SECT163R1.hs
--- a/src/Curve/Binary/SECT163R1.hs
+++ b/src/Curve/Binary/SECT163R1.hs
@@ -1,6 +1,7 @@
 module Curve.Binary.SECT163R1
   ( module Curve.Binary
   , module Curve.Binary.SECT163R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Binary/SECT163R2.hs b/src/Curve/Binary/SECT163R2.hs
--- a/src/Curve/Binary/SECT163R2.hs
+++ b/src/Curve/Binary/SECT163R2.hs
@@ -1,6 +1,7 @@
 module Curve.Binary.SECT163R2
   ( module Curve.Binary
   , module Curve.Binary.SECT163R2
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Binary/SECT193R1.hs b/src/Curve/Binary/SECT193R1.hs
--- a/src/Curve/Binary/SECT193R1.hs
+++ b/src/Curve/Binary/SECT193R1.hs
@@ -1,6 +1,7 @@
 module Curve.Binary.SECT193R1
   ( module Curve.Binary
   , module Curve.Binary.SECT193R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Binary/SECT193R2.hs b/src/Curve/Binary/SECT193R2.hs
--- a/src/Curve/Binary/SECT193R2.hs
+++ b/src/Curve/Binary/SECT193R2.hs
@@ -1,6 +1,7 @@
 module Curve.Binary.SECT193R2
   ( module Curve.Binary
   , module Curve.Binary.SECT193R2
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Binary/SECT233K1.hs b/src/Curve/Binary/SECT233K1.hs
--- a/src/Curve/Binary/SECT233K1.hs
+++ b/src/Curve/Binary/SECT233K1.hs
@@ -1,6 +1,7 @@
 module Curve.Binary.SECT233K1
   ( module Curve.Binary
   , module Curve.Binary.SECT233K1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Binary/SECT233R1.hs b/src/Curve/Binary/SECT233R1.hs
--- a/src/Curve/Binary/SECT233R1.hs
+++ b/src/Curve/Binary/SECT233R1.hs
@@ -1,6 +1,7 @@
 module Curve.Binary.SECT233R1
   ( module Curve.Binary
   , module Curve.Binary.SECT233R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Binary/SECT239K1.hs b/src/Curve/Binary/SECT239K1.hs
--- a/src/Curve/Binary/SECT239K1.hs
+++ b/src/Curve/Binary/SECT239K1.hs
@@ -1,6 +1,7 @@
 module Curve.Binary.SECT239K1
   ( module Curve.Binary
   , module Curve.Binary.SECT239K1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Binary/SECT283K1.hs b/src/Curve/Binary/SECT283K1.hs
--- a/src/Curve/Binary/SECT283K1.hs
+++ b/src/Curve/Binary/SECT283K1.hs
@@ -1,6 +1,7 @@
 module Curve.Binary.SECT283K1
   ( module Curve.Binary
   , module Curve.Binary.SECT283K1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Binary/SECT283R1.hs b/src/Curve/Binary/SECT283R1.hs
--- a/src/Curve/Binary/SECT283R1.hs
+++ b/src/Curve/Binary/SECT283R1.hs
@@ -1,6 +1,7 @@
 module Curve.Binary.SECT283R1
   ( module Curve.Binary
   , module Curve.Binary.SECT283R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Binary/SECT409K1.hs b/src/Curve/Binary/SECT409K1.hs
--- a/src/Curve/Binary/SECT409K1.hs
+++ b/src/Curve/Binary/SECT409K1.hs
@@ -1,6 +1,7 @@
 module Curve.Binary.SECT409K1
   ( module Curve.Binary
   , module Curve.Binary.SECT409K1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Binary/SECT409R1.hs b/src/Curve/Binary/SECT409R1.hs
--- a/src/Curve/Binary/SECT409R1.hs
+++ b/src/Curve/Binary/SECT409R1.hs
@@ -1,6 +1,7 @@
 module Curve.Binary.SECT409R1
   ( module Curve.Binary
   , module Curve.Binary.SECT409R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Binary/SECT571K1.hs b/src/Curve/Binary/SECT571K1.hs
--- a/src/Curve/Binary/SECT571K1.hs
+++ b/src/Curve/Binary/SECT571K1.hs
@@ -1,6 +1,7 @@
 module Curve.Binary.SECT571K1
   ( module Curve.Binary
   , module Curve.Binary.SECT571K1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Binary/SECT571R1.hs b/src/Curve/Binary/SECT571R1.hs
--- a/src/Curve/Binary/SECT571R1.hs
+++ b/src/Curve/Binary/SECT571R1.hs
@@ -1,6 +1,7 @@
 module Curve.Binary.SECT571R1
   ( module Curve.Binary
   , module Curve.Binary.SECT571R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Edwards.hs b/src/Curve/Edwards.hs
--- a/src/Curve/Edwards.hs
+++ b/src/Curve/Edwards.hs
@@ -4,6 +4,7 @@
   ( module Curve
   , module Curve.Edwards
   , module Group
+  , Point(..)
   ) where
 
 import Protolude
@@ -11,7 +12,7 @@
 import GaloisField (GaloisField(..))
 import Text.PrettyPrint.Leijen.Text (Pretty(..))
 
-import Curve (Coordinates(..), Curve(..), Form(..))
+import Curve (Coordinates(..), Curve(..), Form(..), PrimeField')
 import Group (Group(..))
 
 -------------------------------------------------------------------------------
@@ -22,7 +23,7 @@
 type EPoint = Point 'Edwards
 
 -- | Edwards curves.
-class (GaloisField q, GaloisField r, Curve 'Edwards c e q r) => ECurve c e q r where
+class (GaloisField q, PrimeField' r, Curve 'Edwards c e q r) => ECurve c e q r where
   {-# MINIMAL a_, d_, h_, q_, r_, x_, y_ #-}
   a_ :: EPoint c e q r -> q       -- ^ Coefficient @A@.
   d_ :: EPoint c e q r -> q       -- ^ Coefficient @D@.
diff --git a/src/Curve/Edwards/Curve1174.hs b/src/Curve/Edwards/Curve1174.hs
--- a/src/Curve/Edwards/Curve1174.hs
+++ b/src/Curve/Edwards/Curve1174.hs
@@ -1,6 +1,7 @@
 module Curve.Edwards.Curve1174
   ( module Curve.Edwards
   , module Curve.Edwards.Curve1174
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Edwards/Curve41417.hs b/src/Curve/Edwards/Curve41417.hs
--- a/src/Curve/Edwards/Curve41417.hs
+++ b/src/Curve/Edwards/Curve41417.hs
@@ -1,6 +1,7 @@
 module Curve.Edwards.Curve41417
   ( module Curve.Edwards
   , module Curve.Edwards.Curve41417
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Edwards/E222.hs b/src/Curve/Edwards/E222.hs
--- a/src/Curve/Edwards/E222.hs
+++ b/src/Curve/Edwards/E222.hs
@@ -1,6 +1,7 @@
 module Curve.Edwards.E222
   ( module Curve.Edwards
   , module Curve.Edwards.E222
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Edwards/E382.hs b/src/Curve/Edwards/E382.hs
--- a/src/Curve/Edwards/E382.hs
+++ b/src/Curve/Edwards/E382.hs
@@ -1,6 +1,7 @@
 module Curve.Edwards.E382
   ( module Curve.Edwards
   , module Curve.Edwards.E382
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Edwards/E521.hs b/src/Curve/Edwards/E521.hs
--- a/src/Curve/Edwards/E521.hs
+++ b/src/Curve/Edwards/E521.hs
@@ -1,6 +1,7 @@
 module Curve.Edwards.E521
   ( module Curve.Edwards
   , module Curve.Edwards.E521
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Edwards/Ed25519.hs b/src/Curve/Edwards/Ed25519.hs
--- a/src/Curve/Edwards/Ed25519.hs
+++ b/src/Curve/Edwards/Ed25519.hs
@@ -1,6 +1,7 @@
 module Curve.Edwards.Ed25519
   ( module Curve.Edwards
   , module Curve.Edwards.Ed25519
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Edwards/Ed3363.hs b/src/Curve/Edwards/Ed3363.hs
--- a/src/Curve/Edwards/Ed3363.hs
+++ b/src/Curve/Edwards/Ed3363.hs
@@ -1,6 +1,7 @@
 module Curve.Edwards.Ed3363
   ( module Curve.Edwards
   , module Curve.Edwards.Ed3363
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Edwards/Ed448.hs b/src/Curve/Edwards/Ed448.hs
--- a/src/Curve/Edwards/Ed448.hs
+++ b/src/Curve/Edwards/Ed448.hs
@@ -1,6 +1,7 @@
 module Curve.Edwards.Ed448
   ( module Curve.Edwards
   , module Curve.Edwards.Ed448
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Edwards/JubJub.hs b/src/Curve/Edwards/JubJub.hs
--- a/src/Curve/Edwards/JubJub.hs
+++ b/src/Curve/Edwards/JubJub.hs
@@ -1,6 +1,7 @@
 module Curve.Edwards.JubJub
   ( module Curve.Edwards
   , module Curve.Edwards.JubJub
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Montgomery.hs b/src/Curve/Montgomery.hs
--- a/src/Curve/Montgomery.hs
+++ b/src/Curve/Montgomery.hs
@@ -4,6 +4,7 @@
   ( module Curve
   , module Curve.Montgomery
   , module Group
+  , Point(..)
   ) where
 
 import Protolude
@@ -11,7 +12,7 @@
 import GaloisField (GaloisField(..))
 import Text.PrettyPrint.Leijen.Text (Pretty(..))
 
-import Curve (Coordinates(..), Curve(..), Form(..))
+import Curve (Coordinates(..), Curve(..), Form(..), PrimeField')
 import Group (Group(..))
 
 -------------------------------------------------------------------------------
@@ -22,7 +23,7 @@
 type MPoint = Point 'Montgomery
 
 -- | Montgomery curves.
-class (GaloisField q, GaloisField r, Curve 'Montgomery c e q r) => MCurve c e q r where
+class (GaloisField q, PrimeField' r, Curve 'Montgomery c e q r) => MCurve c e q r where
   {-# MINIMAL a_, b_, h_, q_, r_, x_, y_ #-}
   a_ :: MPoint c e q r -> q       -- ^ Coefficient @A@.
   b_ :: MPoint c e q r -> q       -- ^ Coefficient @B@.
diff --git a/src/Curve/Montgomery/Curve25519.hs b/src/Curve/Montgomery/Curve25519.hs
--- a/src/Curve/Montgomery/Curve25519.hs
+++ b/src/Curve/Montgomery/Curve25519.hs
@@ -1,6 +1,7 @@
 module Curve.Montgomery.Curve25519
   ( module Curve.Montgomery
   , module Curve.Montgomery.Curve25519
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Montgomery/Curve383187.hs b/src/Curve/Montgomery/Curve383187.hs
--- a/src/Curve/Montgomery/Curve383187.hs
+++ b/src/Curve/Montgomery/Curve383187.hs
@@ -1,6 +1,7 @@
 module Curve.Montgomery.Curve383187
   ( module Curve.Montgomery
   , module Curve.Montgomery.Curve383187
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Montgomery/Curve448.hs b/src/Curve/Montgomery/Curve448.hs
--- a/src/Curve/Montgomery/Curve448.hs
+++ b/src/Curve/Montgomery/Curve448.hs
@@ -1,6 +1,7 @@
 module Curve.Montgomery.Curve448
   ( module Curve.Montgomery
   , module Curve.Montgomery.Curve448
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Montgomery/M221.hs b/src/Curve/Montgomery/M221.hs
--- a/src/Curve/Montgomery/M221.hs
+++ b/src/Curve/Montgomery/M221.hs
@@ -1,6 +1,7 @@
 module Curve.Montgomery.M221
   ( module Curve.Montgomery
   , module Curve.Montgomery.M221
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Montgomery/M383.hs b/src/Curve/Montgomery/M383.hs
--- a/src/Curve/Montgomery/M383.hs
+++ b/src/Curve/Montgomery/M383.hs
@@ -1,6 +1,7 @@
 module Curve.Montgomery.M383
   ( module Curve.Montgomery
   , module Curve.Montgomery.M383
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Montgomery/M511.hs b/src/Curve/Montgomery/M511.hs
--- a/src/Curve/Montgomery/M511.hs
+++ b/src/Curve/Montgomery/M511.hs
@@ -1,6 +1,7 @@
 module Curve.Montgomery.M511
   ( module Curve.Montgomery
   , module Curve.Montgomery.M511
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass.hs b/src/Curve/Weierstrass.hs
--- a/src/Curve/Weierstrass.hs
+++ b/src/Curve/Weierstrass.hs
@@ -4,6 +4,7 @@
   ( module Curve
   , module Curve.Weierstrass
   , module Group
+  , Point(..)
   ) where
 
 import Protolude
@@ -11,7 +12,7 @@
 import GaloisField (GaloisField(..))
 import Text.PrettyPrint.Leijen.Text (Pretty(..))
 
-import Curve (Coordinates(..), Curve(..), Form(..))
+import Curve (Coordinates(..), Curve(..), Form(..), PrimeField')
 import Group (Group(..))
 
 -------------------------------------------------------------------------------
@@ -22,7 +23,7 @@
 type WPoint = Point 'Weierstrass
 
 -- | Weierstrass curves.
-class (GaloisField q, GaloisField r, Curve 'Weierstrass c e q r) => WCurve c e q r where
+class (GaloisField q, PrimeField' r, Curve 'Weierstrass c e q r) => WCurve c e q r where
   {-# MINIMAL a_, b_, h_, q_, r_, x_, y_ #-}
   a_ :: WPoint c e q r -> q       -- ^ Coefficient @A@.
   b_ :: WPoint c e q r -> q       -- ^ Coefficient @B@.
@@ -337,9 +338,10 @@
   dbl (P  _  _  0) = P  0  1  0
   dbl (P x1 y1 z1) = P x3 y3 z3
     where
+      a   = a_ (witness :: WPPoint e q r)
       xx  = x1 * x1
       zz  = z1 * z1
-      w   = a_ (witness :: WPPoint e q r) * zz + 3 * xx
+      w   = a * zz + 3 * xx
       s   = 2 * y1 * z1
       ss  = s * s
       sss = s * ss
diff --git a/src/Curve/Weierstrass/ANSSIFRP256V1.hs b/src/Curve/Weierstrass/ANSSIFRP256V1.hs
--- a/src/Curve/Weierstrass/ANSSIFRP256V1.hs
+++ b/src/Curve/Weierstrass/ANSSIFRP256V1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.ANSSIFRP256V1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.ANSSIFRP256V1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/Anomalous.hs b/src/Curve/Weierstrass/Anomalous.hs
--- a/src/Curve/Weierstrass/Anomalous.hs
+++ b/src/Curve/Weierstrass/Anomalous.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.Anomalous
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.Anomalous
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BLS12381.hs b/src/Curve/Weierstrass/BLS12381.hs
--- a/src/Curve/Weierstrass/BLS12381.hs
+++ b/src/Curve/Weierstrass/BLS12381.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BLS12381
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BLS12381
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BLS12381T.hs b/src/Curve/Weierstrass/BLS12381T.hs
--- a/src/Curve/Weierstrass/BLS12381T.hs
+++ b/src/Curve/Weierstrass/BLS12381T.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BLS12381T
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BLS12381T
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BLS48581.hs b/src/Curve/Weierstrass/BLS48581.hs
--- a/src/Curve/Weierstrass/BLS48581.hs
+++ b/src/Curve/Weierstrass/BLS48581.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BLS48581
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BLS48581
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BLS48581T.hs b/src/Curve/Weierstrass/BLS48581T.hs
--- a/src/Curve/Weierstrass/BLS48581T.hs
+++ b/src/Curve/Weierstrass/BLS48581T.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BLS48581T
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BLS48581T
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BN224.hs b/src/Curve/Weierstrass/BN224.hs
--- a/src/Curve/Weierstrass/BN224.hs
+++ b/src/Curve/Weierstrass/BN224.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BN224
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BN224
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BN254.hs b/src/Curve/Weierstrass/BN254.hs
--- a/src/Curve/Weierstrass/BN254.hs
+++ b/src/Curve/Weierstrass/BN254.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BN254
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BN254
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BN254A.hs b/src/Curve/Weierstrass/BN254A.hs
--- a/src/Curve/Weierstrass/BN254A.hs
+++ b/src/Curve/Weierstrass/BN254A.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BN254A
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BN254A
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BN254AT.hs b/src/Curve/Weierstrass/BN254AT.hs
--- a/src/Curve/Weierstrass/BN254AT.hs
+++ b/src/Curve/Weierstrass/BN254AT.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BN254AT
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BN254AT
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BN254B.hs b/src/Curve/Weierstrass/BN254B.hs
--- a/src/Curve/Weierstrass/BN254B.hs
+++ b/src/Curve/Weierstrass/BN254B.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BN254B
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BN254B
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BN254BT.hs b/src/Curve/Weierstrass/BN254BT.hs
--- a/src/Curve/Weierstrass/BN254BT.hs
+++ b/src/Curve/Weierstrass/BN254BT.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BN254BT
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BN254BT
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BN254T.hs b/src/Curve/Weierstrass/BN254T.hs
--- a/src/Curve/Weierstrass/BN254T.hs
+++ b/src/Curve/Weierstrass/BN254T.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BN254T
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BN254T
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BN256.hs b/src/Curve/Weierstrass/BN256.hs
--- a/src/Curve/Weierstrass/BN256.hs
+++ b/src/Curve/Weierstrass/BN256.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BN256
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BN256
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BN384.hs b/src/Curve/Weierstrass/BN384.hs
--- a/src/Curve/Weierstrass/BN384.hs
+++ b/src/Curve/Weierstrass/BN384.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BN384
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BN384
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BN462.hs b/src/Curve/Weierstrass/BN462.hs
--- a/src/Curve/Weierstrass/BN462.hs
+++ b/src/Curve/Weierstrass/BN462.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BN462
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BN462
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BN462T.hs b/src/Curve/Weierstrass/BN462T.hs
--- a/src/Curve/Weierstrass/BN462T.hs
+++ b/src/Curve/Weierstrass/BN462T.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BN462T
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BN462T
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BN512.hs b/src/Curve/Weierstrass/BN512.hs
--- a/src/Curve/Weierstrass/BN512.hs
+++ b/src/Curve/Weierstrass/BN512.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BN512
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BN512
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BrainpoolP160R1.hs b/src/Curve/Weierstrass/BrainpoolP160R1.hs
--- a/src/Curve/Weierstrass/BrainpoolP160R1.hs
+++ b/src/Curve/Weierstrass/BrainpoolP160R1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BrainpoolP160R1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BrainpoolP160R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BrainpoolP160T1.hs b/src/Curve/Weierstrass/BrainpoolP160T1.hs
--- a/src/Curve/Weierstrass/BrainpoolP160T1.hs
+++ b/src/Curve/Weierstrass/BrainpoolP160T1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BrainpoolP160T1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BrainpoolP160T1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BrainpoolP192R1.hs b/src/Curve/Weierstrass/BrainpoolP192R1.hs
--- a/src/Curve/Weierstrass/BrainpoolP192R1.hs
+++ b/src/Curve/Weierstrass/BrainpoolP192R1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BrainpoolP192R1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BrainpoolP192R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BrainpoolP192T1.hs b/src/Curve/Weierstrass/BrainpoolP192T1.hs
--- a/src/Curve/Weierstrass/BrainpoolP192T1.hs
+++ b/src/Curve/Weierstrass/BrainpoolP192T1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BrainpoolP192T1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BrainpoolP192T1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BrainpoolP224R1.hs b/src/Curve/Weierstrass/BrainpoolP224R1.hs
--- a/src/Curve/Weierstrass/BrainpoolP224R1.hs
+++ b/src/Curve/Weierstrass/BrainpoolP224R1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BrainpoolP224R1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BrainpoolP224R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BrainpoolP224T1.hs b/src/Curve/Weierstrass/BrainpoolP224T1.hs
--- a/src/Curve/Weierstrass/BrainpoolP224T1.hs
+++ b/src/Curve/Weierstrass/BrainpoolP224T1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BrainpoolP224T1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BrainpoolP224T1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BrainpoolP256R1.hs b/src/Curve/Weierstrass/BrainpoolP256R1.hs
--- a/src/Curve/Weierstrass/BrainpoolP256R1.hs
+++ b/src/Curve/Weierstrass/BrainpoolP256R1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BrainpoolP256R1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BrainpoolP256R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BrainpoolP256T1.hs b/src/Curve/Weierstrass/BrainpoolP256T1.hs
--- a/src/Curve/Weierstrass/BrainpoolP256T1.hs
+++ b/src/Curve/Weierstrass/BrainpoolP256T1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BrainpoolP256T1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BrainpoolP256T1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BrainpoolP320R1.hs b/src/Curve/Weierstrass/BrainpoolP320R1.hs
--- a/src/Curve/Weierstrass/BrainpoolP320R1.hs
+++ b/src/Curve/Weierstrass/BrainpoolP320R1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BrainpoolP320R1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BrainpoolP320R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BrainpoolP320T1.hs b/src/Curve/Weierstrass/BrainpoolP320T1.hs
--- a/src/Curve/Weierstrass/BrainpoolP320T1.hs
+++ b/src/Curve/Weierstrass/BrainpoolP320T1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BrainpoolP320T1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BrainpoolP320T1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BrainpoolP384R1.hs b/src/Curve/Weierstrass/BrainpoolP384R1.hs
--- a/src/Curve/Weierstrass/BrainpoolP384R1.hs
+++ b/src/Curve/Weierstrass/BrainpoolP384R1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BrainpoolP384R1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BrainpoolP384R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BrainpoolP384T1.hs b/src/Curve/Weierstrass/BrainpoolP384T1.hs
--- a/src/Curve/Weierstrass/BrainpoolP384T1.hs
+++ b/src/Curve/Weierstrass/BrainpoolP384T1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BrainpoolP384T1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BrainpoolP384T1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BrainpoolP512R1.hs b/src/Curve/Weierstrass/BrainpoolP512R1.hs
--- a/src/Curve/Weierstrass/BrainpoolP512R1.hs
+++ b/src/Curve/Weierstrass/BrainpoolP512R1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BrainpoolP512R1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BrainpoolP512R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/BrainpoolP512T1.hs b/src/Curve/Weierstrass/BrainpoolP512T1.hs
--- a/src/Curve/Weierstrass/BrainpoolP512T1.hs
+++ b/src/Curve/Weierstrass/BrainpoolP512T1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.BrainpoolP512T1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.BrainpoolP512T1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/SECP112R1.hs b/src/Curve/Weierstrass/SECP112R1.hs
--- a/src/Curve/Weierstrass/SECP112R1.hs
+++ b/src/Curve/Weierstrass/SECP112R1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.SECP112R1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.SECP112R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/SECP112R2.hs b/src/Curve/Weierstrass/SECP112R2.hs
--- a/src/Curve/Weierstrass/SECP112R2.hs
+++ b/src/Curve/Weierstrass/SECP112R2.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.SECP112R2
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.SECP112R2
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/SECP128R1.hs b/src/Curve/Weierstrass/SECP128R1.hs
--- a/src/Curve/Weierstrass/SECP128R1.hs
+++ b/src/Curve/Weierstrass/SECP128R1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.SECP128R1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.SECP128R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/SECP128R2.hs b/src/Curve/Weierstrass/SECP128R2.hs
--- a/src/Curve/Weierstrass/SECP128R2.hs
+++ b/src/Curve/Weierstrass/SECP128R2.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.SECP128R2
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.SECP128R2
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/SECP160K1.hs b/src/Curve/Weierstrass/SECP160K1.hs
--- a/src/Curve/Weierstrass/SECP160K1.hs
+++ b/src/Curve/Weierstrass/SECP160K1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.SECP160K1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.SECP160K1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/SECP160R1.hs b/src/Curve/Weierstrass/SECP160R1.hs
--- a/src/Curve/Weierstrass/SECP160R1.hs
+++ b/src/Curve/Weierstrass/SECP160R1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.SECP160R1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.SECP160R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/SECP160R2.hs b/src/Curve/Weierstrass/SECP160R2.hs
--- a/src/Curve/Weierstrass/SECP160R2.hs
+++ b/src/Curve/Weierstrass/SECP160R2.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.SECP160R2
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.SECP160R2
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/SECP192K1.hs b/src/Curve/Weierstrass/SECP192K1.hs
--- a/src/Curve/Weierstrass/SECP192K1.hs
+++ b/src/Curve/Weierstrass/SECP192K1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.SECP192K1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.SECP192K1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/SECP192R1.hs b/src/Curve/Weierstrass/SECP192R1.hs
--- a/src/Curve/Weierstrass/SECP192R1.hs
+++ b/src/Curve/Weierstrass/SECP192R1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.SECP192R1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.SECP192R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/SECP224K1.hs b/src/Curve/Weierstrass/SECP224K1.hs
--- a/src/Curve/Weierstrass/SECP224K1.hs
+++ b/src/Curve/Weierstrass/SECP224K1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.SECP224K1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.SECP224K1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/SECP224R1.hs b/src/Curve/Weierstrass/SECP224R1.hs
--- a/src/Curve/Weierstrass/SECP224R1.hs
+++ b/src/Curve/Weierstrass/SECP224R1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.SECP224R1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.SECP224R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/SECP256K1.hs b/src/Curve/Weierstrass/SECP256K1.hs
--- a/src/Curve/Weierstrass/SECP256K1.hs
+++ b/src/Curve/Weierstrass/SECP256K1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.SECP256K1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.SECP256K1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/SECP256R1.hs b/src/Curve/Weierstrass/SECP256R1.hs
--- a/src/Curve/Weierstrass/SECP256R1.hs
+++ b/src/Curve/Weierstrass/SECP256R1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.SECP256R1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.SECP256R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/SECP384R1.hs b/src/Curve/Weierstrass/SECP384R1.hs
--- a/src/Curve/Weierstrass/SECP384R1.hs
+++ b/src/Curve/Weierstrass/SECP384R1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.SECP384R1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.SECP384R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Curve/Weierstrass/SECP521R1.hs b/src/Curve/Weierstrass/SECP521R1.hs
--- a/src/Curve/Weierstrass/SECP521R1.hs
+++ b/src/Curve/Weierstrass/SECP521R1.hs
@@ -1,6 +1,7 @@
 module Curve.Weierstrass.SECP521R1
   ( module Curve.Weierstrass
   , module Curve.Weierstrass.SECP521R1
+  , Point(..)
   ) where
 
 import Protolude
diff --git a/src/Group/Field.hs b/src/Group/Field.hs
--- a/src/Group/Field.hs
+++ b/src/Group/Field.hs
@@ -7,9 +7,10 @@
 
 import Control.Monad.Random (Random(..))
 import GaloisField (GaloisField(..))
-import Test.Tasty.QuickCheck (Arbitrary(..), suchThatMap)
+import Test.Tasty.QuickCheck (Arbitrary(..))
 import Text.PrettyPrint.Leijen.Text (Pretty(..))
 
+import Curve (PrimeField')
 import Group (Group(..))
 
 -------------------------------------------------------------------------------
@@ -17,15 +18,15 @@
 -------------------------------------------------------------------------------
 
 -- | Field groups.
-class GaloisField k => FGroup k where
-  {-# MINIMAL g_, q_, r_, x_ #-}
-  g_ :: Element k            -- ^ Group generator.
-  q_ :: Element k -> Integer -- ^ Group characteristic.
-  r_ :: Element k -> Integer -- ^ Group order.
-  x_ :: k                    -- ^ Group element.
+class (GaloisField q, PrimeField' r) => FGroup r q where
+  {-# MINIMAL g_, h_, q_, r_ #-}
+  g_ :: Element r q            -- ^ Group generator.
+  h_ :: Element r q -> Integer -- ^ Group cofactor.
+  q_ :: Element r q -> Integer -- ^ Group characteristic.
+  r_ :: Element r q -> Integer -- ^ Group order.
 
 -- | Field elements.
-newtype Element k = F k
+newtype Element r q = F q
   deriving (Eq, Functor, Generic, NFData, Read, Show)
 
 -------------------------------------------------------------------------------
@@ -33,7 +34,7 @@
 -------------------------------------------------------------------------------
 
 -- Field elements are groups.
-instance FGroup k => Group (Element k) where
+instance FGroup r q => Group (Element r q) where
 
   add = (<>)
   {-# INLINABLE add #-}
@@ -50,23 +51,23 @@
   id = mempty
   {-# INLINABLE id #-}
 
-  inv (F x) = F (recip x)
+  inv = (<$>) recip
   {-# INLINABLE inv #-}
 
-  mul' (F x) n = F (pow x n)
+  mul' = (. flip pow) . flip (<$>)
   {-# INLINABLE mul' #-}
 
   order = r_
   {-# INLINABLE order #-}
 
 -- Field elements are monoids.
-instance FGroup k => Monoid (Element k) where
+instance FGroup r q => Monoid (Element r q) where
 
   mempty = F 1
   {-# INLINABLE mempty #-}
 
 -- Field elements are semigroups.
-instance FGroup k => Semigroup (Element k) where
+instance FGroup r q => Semigroup (Element r q) where
 
   F x <> F y = F (x * y)
   {-# INLINABLE (<>) #-}
@@ -76,25 +77,33 @@
 -------------------------------------------------------------------------------
 
 -- Field elements are arbitrary.
-instance FGroup k => Arbitrary (Element k) where
+instance FGroup r q => Arbitrary (Element r q) where
 
+  -- Arbitrary group element.
+  arbitrary = mul' gen <$> arbitrary
+  {- Arbitrary field element.
   arbitrary = suchThatMap arbitrary defX
     where
       defX 0 = Nothing
       defX x = Just (F x)
+  -}
   {-# INLINABLE arbitrary #-}
 
 -- Field elements are pretty.
-instance FGroup k => Pretty (Element k) where
+instance FGroup r q => Pretty (Element r q) where
 
   pretty (F x) = pretty x
 
 -- Field elements are random.
-instance FGroup k => Random (Element k) where
+instance FGroup r q => Random (Element r q) where
 
+  -- Random group element.
+  random = first (mul' gen) . random
+  {- Random field element.
   random g = case random g of
     (0, g') -> random g'
     (x, g') -> (F x, g')
+  -}
   {-# INLINABLE random #-}
 
   randomR  = panic "not implemented."
diff --git a/src/Group/Field/BN254TF.hs b/src/Group/Field/BN254TF.hs
--- a/src/Group/Field/BN254TF.hs
+++ b/src/Group/Field/BN254TF.hs
@@ -7,6 +7,7 @@
 import Protolude
 
 import ExtensionField
+import PrimeField
 
 import Curve.Weierstrass.BN254T (Fq2)
 import Group
@@ -16,7 +17,10 @@
 -- Types
 -------------------------------------------------------------------------------
 
--- | Field of BN254TF group.
+-- | Field of coefficients of BN254TF group.
+type Fr = PrimeField 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
+
+-- | Field of elements of BN254TF group.
 data PolynomialV
 instance IrreducibleMonic Fq2 PolynomialV where
   split _ = X3 - Y X - 9
@@ -27,18 +31,18 @@
 type Fq12 = ExtensionField Fq6 PolynomialW
 
 -- | BN254TF group is a field group.
-instance FGroup Fq12 where
+instance FGroup Fr Fq12 where
   g_ = _g
   {-# INLINABLE g_ #-}
+  h_ = const _h
+  {-# INLINABLE h_ #-}
   q_ = const _q
   {-# INLINABLE q_ #-}
   r_ = const _r
   {-# INLINABLE r_ #-}
-  x_ = _x
-  {-# INLINABLE x_ #-}
 
 -- | Element of BN254TF group.
-type P = Element Fq12
+type P = Element Fr Fq12
 
 -------------------------------------------------------------------------------
 -- Parameters
@@ -48,6 +52,11 @@
 _g :: P
 _g = F _x
 {-# INLINABLE _g #-}
+
+-- | Cofactor of BN254TF group.
+_h :: Integer
+_h = 0x2f4b6dc97020fddadf107d20bc842d43bf6369b1ff6a1c71015f3f7be2e1e30a73bb94fec0daf15466b2383a5d3ec3d15ad524d8f70c54efee1bd8c3b21377e563a09a1b705887e72eceaddea3790364a61f676baaf977870e88d5c6c8fef0781361e443ae77f5b63a2a2264487f2940a8b1ddb3d15062cd0fb2015dfc6668449aed3cc48a82d0d602d268c7daab6a41294c0cc4ebe5664568dfc50e1648a45a4a1e3a5195846a3ed011a337a02088ec80e0ebae8755cfe107acf3aafb40494e406f804216bb10cf430b0f37856b42db8dc5514724ee93dfb10826f0dd4a0364b9580291d2cd65664814fde37ca80bb4ea44eacc5e641bbadf423f9a2cbf813b8d145da90029baee7ddadda71c7f3811c4105262945bba1668c3be69a3c230974d83561841d766f9c9d570bb7fbe04c7e8a6c3c760c0de81def35692da361102b6b9b2b918837fa97896e84abb40a4efb7e54523a486964b64ca86f120
+{-# INLINABLE _h #-}
 
 -- | Characteristic of BN254TF group.
 _q :: Integer
diff --git a/tests/FieldTests.hs b/tests/FieldTests.hs
--- a/tests/FieldTests.hs
+++ b/tests/FieldTests.hs
@@ -7,5 +7,5 @@
 
 testField :: TestTree
 testField = testGroup "Field"
-  [ test' "BN254TF" BN254TF._g BN254TF._q BN254TF._r
+  [ test' "BN254TF" BN254TF._g BN254TF._h BN254TF._q BN254TF._r
   ]
diff --git a/tests/GroupTests.hs b/tests/GroupTests.hs
--- a/tests/GroupTests.hs
+++ b/tests/GroupTests.hs
@@ -7,7 +7,6 @@
 import Group
 import Group.Field
 import Math.NumberTheory.Primes.Testing
-import PrimeField
 import Test.Tasty
 import Test.Tasty.HUnit
 import Test.Tasty.QuickCheck
@@ -63,24 +62,23 @@
 doubleHomeomorphism :: (Eq a, Eq b) => (a -> a) -> (b -> b) -> (a -> b) -> (b -> a) -> b -> Bool
 doubleHomeomorphism op op' f t x = t (op' x) == op (t x) && f (op (t x)) == op' x
 
-curveParameters :: forall f c e q r p
-  . (r ~ PrimeField p, Curve f 'Affine e q r, Curve f c e q r)
+curveParameters :: forall f c e q r . (Curve f 'Affine e q r, Curve f c e q r)
   => Point f c e q r -> Integer -> Integer -> Integer -> TestTree
 curveParameters g h q r = testGroup "Curve parameters"
   [ testCase "generator is parametrised" $
     gen @?= g
   , testCase "cofactor is parametrised" $
-    cof (witness :: Point f c e q r) @?= h
+    cof g @?= h
   , testCase "characteristic is parametrised" $
-    Curve.char (witness :: Point f c e q r) @?= q
+    Curve.char g @?= q
   , testCase "order is parametrised" $
-    Group.order (witness :: Point f c e q r) @?= r
+    Group.order g @?= r
   , testCase "characteristic is prime" $
     isPrime q @?= True
   , testCase "discriminant is nonzero" $
-    disc (witness :: Point f c e q r) /= 0 @?= True
+    disc g /= 0 @?= True
   , testCase "generator is well-defined" $
-    def (gen :: Point f c e q r) @?= True
+    def g @?= True
   , testCase "generator is in cyclic subgroup" $
     mul' g r @?= mempty
   , testCase "cyclic subgroup has prime order" $
@@ -97,26 +95,31 @@
     doubleHomeomorphism (flip mul 3) (flip mul 3) fromA (toA :: Point f c e q r -> Point f 'Affine e q r)
   ]
 
-test :: (r ~ PrimeField p, Curve f c e q r, Curve f 'Affine e q r)
+test :: (Curve f c e q r, Curve f 'Affine e q r)
   => TestName -> Point f c e q r -> Integer -> Integer -> Integer -> TestTree
 test s g h q r = testGroup s [groupAxioms g, curveParameters g h q r]
 
-fieldParameters :: forall k . FGroup k
-  => Element k -> Integer -> Integer -> TestTree
-fieldParameters g q r = testGroup "Group parameters"
+fieldParameters :: forall q r . FGroup r q
+  => Element r q -> Integer -> Integer -> Integer -> TestTree
+fieldParameters g h q r = testGroup "Group parameters"
   [ testCase "generator is parametrised" $
     gen @?= g
   , testCase "characteristic is parametrised" $
-    GaloisField.char (witness :: k) @?= q
+    GaloisField.char (witness :: q) @?= q
   , testCase "order is parametrised" $
-    Group.order (witness :: Element k) @?= r
+    Group.order g @?= r
   , testCase "characteristic is prime" $
     isPrime q @?= True
   , testCase "generator is well-defined" $
-    def (gen :: Element k) @?= True
+    def g @?= True
   , testCase "generator is in cyclic subgroup" $
     mul' g r @?= mempty
+  , testCase "cyclic subgroup has prime order" $
+    isPrime r @?= True
+  , testCase "hasse theorem holds" $
+    hasseTheorem h r (GaloisField.order (witness :: q)) @?= True
   ]
 
-test' :: FGroup k => TestName -> Element k -> Integer -> Integer -> TestTree
-test' s g q r = testGroup s [groupAxioms g, fieldParameters g q r]
+test' :: FGroup r q
+  => TestName -> Element r q -> Integer -> Integer -> Integer -> TestTree
+test' s g h q r = testGroup s [groupAxioms g, fieldParameters g h q r]
