diff --git a/benchmarks/Election.hs b/benchmarks/Election.hs
--- a/benchmarks/Election.hs
+++ b/benchmarks/Election.hs
@@ -13,10 +13,9 @@
 makeElection ::
  forall crypto v c.
  Reifies v Version =>
- Reifies c crypto =>
- JSON.ToJSON crypto =>
- JSON.ToJSON (FieldElement crypto c) =>
+ GroupParams crypto c =>
  Key crypto =>
+ JSON.ToJSON crypto =>
  Int -> Int -> Election crypto v c
 makeElection nQuests nChoices = elec
 	where
@@ -48,11 +47,7 @@
 
 makeBallot ::
  Reifies v Version =>
- Reifies c crypto =>
- Group crypto =>
- Key crypto =>
- Multiplicative (FieldElement crypto c) =>
- ToNatural (FieldElement crypto c) =>
+ GroupParams crypto c => Key crypto =>
  Election crypto v c -> Ballot crypto v c
 makeBallot elec =
 	case runExcept $ (`evalStateT` mkStdGen seed) $ do
@@ -74,18 +69,13 @@
 
 benchEncryptBallot ::
  forall crypto v c.
+ GroupParams crypto c =>
  Reifies v Version =>
- Reifies c crypto =>
- JSON.ToJSON crypto =>
- Group crypto =>
  Key crypto =>
+ JSON.ToJSON crypto =>
  NFData crypto =>
- NFData (FieldElement crypto c) =>
- Multiplicative (FieldElement crypto c) =>
- ToNatural (FieldElement crypto c) =>
- JSON.ToJSON (FieldElement crypto c) =>
  Proxy v -> Proxy c -> Int -> Int -> Benchmark
-benchEncryptBallot (_v::Proxy v) (_c::Proxy c) nQuests nChoices =
+benchEncryptBallot _v _c nQuests nChoices =
 	let setupEnv = do
 		let elec :: Election crypto v c = makeElection nQuests nChoices
 		return elec in
@@ -96,15 +86,10 @@
 benchVerifyBallot ::
  forall crypto v c.
  Reifies v Version =>
- Reifies c crypto =>
- JSON.ToJSON crypto =>
- Group crypto =>
+ GroupParams crypto c =>
  Key crypto =>
+ JSON.ToJSON crypto =>
  NFData crypto =>
- NFData (FieldElement crypto c) =>
- Multiplicative (FieldElement crypto c) =>
- ToNatural (FieldElement crypto c) =>
- JSON.ToJSON (FieldElement crypto c) =>
  Proxy v -> Proxy c -> Int -> Int -> Benchmark
 benchVerifyBallot (_v::Proxy v) (_c::Proxy c) nQuests nChoices =
 	let setupEnv = do
@@ -117,31 +102,40 @@
 
 benchmarks :: [Benchmark]
 benchmarks =
- let inputs =
-	 [ (nQ,nC)
-	 | nQ <- [1,5,10,15,20,25]
-	 , nC <- [5,7]
-	 ] in
- [ bgroup "stableVersion" $ reify stableVersion $ \v ->
-	 [ bgroup "weakFFC" $ reify weakFFC $ \c ->
-		 [ bgroup "encryptBallot"
-			 [ benchEncryptBallot v c nQuests nChoices
-			 | (nQuests,nChoices) <- inputs
-			 ]
-		 , bgroup "verifyBallot"
-			 [ benchVerifyBallot v c nQuests nChoices
-			 | (nQuests,nChoices) <- inputs
-			 ]
+ [ benchsByVersion stableVersion
+ -- , benchsByVersion experimentalVersion
+ ]
+
+benchsByVersion :: Version -> Benchmark
+benchsByVersion version =
+	reify version $ \v ->
+	bgroup ("v"<>show version)
+		[ benchsByCrypto v weakFFC
+		, benchsByCrypto v beleniosFFC
+		]
+
+benchsByCrypto ::
+ Reifies v Version =>
+ ReifyCrypto crypto =>
+ Key crypto =>
+ JSON.ToJSON crypto =>
+ NFData crypto =>
+ Proxy v -> crypto -> Benchmark
+benchsByCrypto v crypto =
+	reifyCrypto crypto $ \c ->
+	bgroup (Text.unpack (cryptoName crypto))
+	 [ bgroup "encryptBallot"
+		 [ benchEncryptBallot v c nQuests nChoices
+		 | (nQuests,nChoices) <- inputs
 		 ]
-	 , bgroup "beleniosFFC" $ reify beleniosFFC $ \c ->
-		 [ bgroup "encryptBallot"
-			 [ benchEncryptBallot v c nQuests nChoices
-			 | (nQuests,nChoices) <- inputs
-			 ]
-		 , bgroup "verifyBallot"
-			 [ benchVerifyBallot v c nQuests nChoices
-			 | (nQuests,nChoices) <- inputs
-			 ]
+	 , bgroup "verifyBallot"
+		 [ benchVerifyBallot v c nQuests nChoices
+		 | (nQuests,nChoices) <- inputs
 		 ]
 	 ]
- ]
+	where
+	inputs =
+		[ (nQ,nC)
+		| nQ <- [1,5,10,15,20,25]
+		, nC <- [5,7]
+		]
diff --git a/hjugement-protocol.cabal b/hjugement-protocol.cabal
--- a/hjugement-protocol.cabal
+++ b/hjugement-protocol.cabal
@@ -2,7 +2,7 @@
 -- PVP:  +-+------- breaking API changes
 --       | | +----- non-breaking API additions
 --       | | | +--- code changes with no API change
-version: 0.0.8.20191027
+version: 0.0.9.20191031
 category: Politic
 synopsis: A cryptographic protocol for the Majority Judgment.
 description:
@@ -72,7 +72,7 @@
   default-language: Haskell2010
   default-extensions:
     AllowAmbiguousTypes
-    ConstraintKinds
+    -- ConstraintKinds
     DefaultSignatures
     FlexibleContexts
     FlexibleInstances
@@ -211,6 +211,7 @@
   build-depends:
     base >= 4.6 && < 5
     , hjugement-protocol
+    , aeson >= 1.3
     , containers >= 0.5
     , criterion >= 1.4
     , deepseq >= 1.4
diff --git a/src/Voting/Protocol/Arith.hs b/src/Voting/Protocol/Arith.hs
--- a/src/Voting/Protocol/Arith.hs
+++ b/src/Voting/Protocol/Arith.hs
@@ -2,13 +2,12 @@
 {-# LANGUAGE DeriveAnyClass #-}
 {-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE GADTs #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE Rank2Types #-} -- for ReifyCrypto
 {-# LANGUAGE UndecidableInstances #-} -- for Reifies instances
 {-# OPTIONS_GHC -fno-warn-orphans #-}
--- | Finite Field Cryptography (FFC)
--- is a method of implementing discrete logarithm cryptography
--- using finite field mathematics.
+-- | Arithmetic
 module Voting.Protocol.Arith where
 
 import Control.Arrow (first)
@@ -100,102 +99,72 @@
 
 -- | @(b '^' e)@ returns the modular exponentiation of base 'b' by exponent 'e'.
 (^) ::
+ forall crypto c.
  Reifies c crypto =>
- Multiplicative (FieldElement crypto c) =>
+ Multiplicative (G crypto c) =>
  G crypto c -> E crypto c -> G crypto c
 (^) b (E e)
  | e == 0 = one
  | otherwise = t * (b*b) ^ E (e`shiftR`1)
-	where
-	t | testBit e 0 = b
-		| otherwise   = one
+	where t | testBit e 0 = b
+	        | otherwise   = one
 infixr 8 ^
 
--- | 'groupGenInverses' returns the infinite list
--- of 'inv'erse powers of 'groupGen':
--- @['groupGen' '^' 'neg' i | i <- [0..]]@,
--- but by computing each value from the previous one.
---
--- Used by 'intervalDisjunctions'.
-groupGenInverses ::
- forall crypto c.
- Reifies c crypto =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
- [G crypto c]
-groupGenInverses = go one
-	where
-	invGen = inv $ groupGen @crypto @c
-	go g = g : go (g * invGen)
-
-groupGenPowers ::
- forall crypto c.
- Reifies c crypto =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
- [G crypto c]
-groupGenPowers = go one
-	where go g = g : go (g * groupGen @crypto @c)
-
--- | @('randomR' i)@ returns a random integer in @[0..i-1]@.
-randomR ::
- Monad m =>
- Random.RandomGen r =>
- Random.Random i =>
- Negable i =>
- Multiplicative i =>
- i -> S.StateT r m i
-randomR i = S.StateT $ return . Random.randomR (zero, i-one)
-
--- | @('random')@ returns a random integer
--- in the range determined by its type.
-random ::
- Monad m =>
- Random.RandomGen r =>
- Random.Random i =>
- Negable i =>
- Multiplicative i =>
- S.StateT r m i
-random = S.StateT $ return . Random.random
-
-instance Random.Random Natural where
-	randomR (mini,maxi) =
-		first (fromIntegral::Integer -> Natural) .
-		Random.randomR (fromIntegral mini, fromIntegral maxi)
-	random = first (fromIntegral::Integer -> Natural) . Random.random
-
--- * Type family 'FieldElement'
-type family FieldElement crypto :: * -> *
+-- * Class 'GroupParams' where
+class
+ ( Multiplicative (G crypto c)
+ , Invertible     (G crypto c)
+ , FromNatural    (G crypto c)
+ , ToNatural      (G crypto c)
+ , Eq             (G crypto c)
+ , Ord            (G crypto c)
+ , Show           (G crypto c)
+ , NFData         (G crypto c)
+ , FromJSON       (G crypto c)
+ , ToJSON         (G crypto c)
+ , Reifies c crypto
+ ) => GroupParams crypto c where
+	-- | A generator of the subgroup.
+	groupGen   :: G crypto c
+	-- | The order of the subgroup.
+	groupOrder :: Proxy c -> Natural
+	
+	-- | 'groupGenPowers' returns the infinite list
+	-- of powers of 'groupGen'.
+	--
+	-- NOTE: In the 'GroupParams' class to keep
+	-- computed values in memory across calls to 'groupGenPowers'.
+	groupGenPowers :: [G crypto c]
+	groupGenPowers = go one
+		where go g = g : go (g * groupGen)
+	
+	-- | 'groupGenInverses' returns the infinite list
+	-- of 'inv'erse powers of 'groupGen':
+	-- @['groupGen' '^' 'neg' i | i <- [0..]]@,
+	-- but by computing each value from the previous one.
+	--
+	-- NOTE: In the 'GroupParams' class to keep
+	-- computed values in memory across calls to 'groupGenInverses'.
+	--
+	-- Used by 'intervalDisjunctions'.
+	groupGenInverses :: [G crypto c]
+	groupGenInverses = go one
+		where
+		invGen = inv $ groupGen
+		go g = g : go (g * invGen)
 
--- * Class 'Group' where
-class Group crypto where
-	groupGen   :: Reifies c crypto => G crypto c
-	groupOrder :: Reifies c crypto => Proxy c -> Natural
+-- ** Class 'ReifyCrypto'
+class ReifyCrypto crypto where
+	-- | Like 'reify' but augmented with the 'GroupParams' constraint.
+	reifyCrypto :: crypto -> (forall c. Reifies c crypto => GroupParams crypto c => Proxy c -> r) -> r
 
 -- ** Type 'G'
 -- | The type of the elements of a subgroup of a field.
-newtype G crypto c = G { unG :: FieldElement crypto c }
-deriving newtype instance Eq     (FieldElement crypto c) => Eq     (G crypto c)
-deriving newtype instance Ord    (FieldElement crypto c) => Ord    (G crypto c)
-deriving newtype instance Show   (FieldElement crypto c) => Show   (G crypto c)
-deriving newtype instance NFData (FieldElement crypto c) => NFData (G crypto c)
-instance ToJSON (FieldElement crypto c) => ToJSON (G crypto c) where
-	toJSON = JSON.toJSON . unG
-instance FromNatural (FieldElement crypto c) => FromNatural (G crypto c) where
-	fromNatural = G . fromNatural
-instance ToNatural (FieldElement crypto c) => ToNatural (G crypto c) where
-	nat = nat . unG
-instance Multiplicative (FieldElement crypto c) => Multiplicative (G crypto c) where
-	one = G one
-	G x * G y = G (x * y)
-instance
- ( Reifies c crypto
- , Group crypto
- , Multiplicative (FieldElement crypto c)
- ) => Invertible (G crypto c) where
-	-- | NOTE: add 'groupOrder' so the exponent given to (^) is positive.
-	inv = (^ E (fromJust $ groupOrder @crypto (Proxy @c)`minusNaturalMaybe`1))
+newtype G crypto c = G { unG :: FieldElement crypto }
 
+-- *** Type family 'FieldElement'
+type family FieldElement crypto :: *
+
 -- ** Type 'E'
 -- | An exponent of a (cyclic) subgroup of a field.
 -- The value is always in @[0..'groupOrder'-1]@.
@@ -204,43 +173,43 @@
  deriving newtype NFData
 instance ToJSON (E crypto c) where
 	toJSON = JSON.toJSON . show . unE
-instance (Reifies c crypto, Group crypto) => FromJSON (E crypto c) where
+instance GroupParams crypto c => FromJSON (E crypto c) where
 	parseJSON (JSON.String s)
 	 | Just (c0,_) <- Text.uncons s
 	 , c0 /= '0'
 	 , Text.all Char.isDigit s
 	 , Just x <- readMaybe (Text.unpack s)
-	 , x < groupOrder @crypto (Proxy @c)
+	 , x < groupOrder (Proxy @c)
 	 = return (E x)
 	parseJSON json = JSON.typeMismatch "Exponent" json
-instance (Reifies c crypto, Group crypto) => FromNatural (E crypto c) where
+instance GroupParams crypto c => FromNatural (E crypto c) where
 	fromNatural i =
-		E $ abs $ i `mod` groupOrder @crypto (Proxy @c)
+		E $ abs $ i `mod` groupOrder (Proxy @c)
 		where
-		abs x | x < 0 = x + groupOrder @crypto (Proxy @c)
+		abs x | x < 0 = x + groupOrder (Proxy @c)
 		      | otherwise = x
 instance ToNatural (E crypto c) where
 	nat = unE
-instance (Reifies c crypto, Group crypto) => Additive (E crypto c) where
+instance GroupParams crypto c => Additive (E crypto c) where
 	zero = E zero
-	E x + E y = E $ (x + y) `mod` groupOrder @crypto (Proxy @c)
-instance (Reifies c crypto, Group crypto) => Negable (E crypto c) where
+	E x + E y = E $ (x + y) `mod` groupOrder (Proxy @c)
+instance GroupParams crypto c => Negable (E crypto c) where
 	neg (E x)
 	 | x == 0 = zero
-	 | otherwise = E $ fromJust $ nat (groupOrder @crypto (Proxy @c))`minusNaturalMaybe`x
-instance (Reifies c crypto, Group crypto) => Multiplicative (E crypto c) where
+	 | otherwise = E $ fromJust $ nat (groupOrder (Proxy @c))`minusNaturalMaybe`x
+instance GroupParams crypto c => Multiplicative (E crypto c) where
 	one = E one
-	E x * E y = E $ (x * y) `mod` groupOrder @crypto (Proxy @c)
-instance (Reifies c crypto, Group crypto) => Random.Random (E crypto c) where
+	E x * E y = E $ (x * y) `mod` groupOrder (Proxy @c)
+instance GroupParams crypto c => Random.Random (E crypto c) where
 	randomR (E lo, E hi) =
 		first (E . fromIntegral) .
 		Random.randomR
 		 ( 0`max`toInteger lo
-		 , toInteger hi`min`(toInteger (groupOrder @crypto (Proxy @c)) - 1) )
+		 , toInteger hi`min`(toInteger (groupOrder (Proxy @c)) - 1) )
 	random =
 		first (E . fromIntegral) .
-		Random.randomR (0, toInteger (groupOrder @crypto (Proxy @c)) - 1)
-instance (Reifies c crypto, Group crypto) => Enum (E crypto c) where
+		Random.randomR (0, toInteger (groupOrder (Proxy @c)) - 1)
+instance GroupParams crypto c => Enum (E crypto c) where
 	toEnum = fromNatural . fromIntegral
 	fromEnum = fromIntegral . nat
 	enumFromTo lo hi = List.unfoldr
@@ -275,13 +244,7 @@
 -- Used by 'proveEncryption' and 'verifyEncryption',
 -- where the 'bs' usually contains the 'statement' to be proven,
 -- and the 'gs' contains the 'commitments'.
-hash ::
- Reifies c crypto =>
- Group crypto =>
- ToNatural (FieldElement crypto c) =>
- BS.ByteString ->
- [G crypto c] ->
- E crypto c
+hash :: GroupParams crypto c => BS.ByteString -> [G crypto c] -> E crypto c
 hash bs gs = do
 	let s = bs <> BS.intercalate (fromString ",") (bytesNat <$> gs)
 	let h = Crypto.hashWith Crypto.SHA256 s
@@ -333,3 +296,32 @@
 	TL.toStrict $
 	TL.tail $ TLB.toLazyText $ TLB.hexadecimal $
 	setBit n 256
+
+-- * Random
+
+-- | @('randomR' i)@ returns a random integer in @[0..i-1]@.
+randomR ::
+ Monad m =>
+ Random.RandomGen r =>
+ Random.Random i =>
+ Negable i =>
+ Multiplicative i =>
+ i -> S.StateT r m i
+randomR i = S.StateT $ return . Random.randomR (zero, i-one)
+
+-- | @('random')@ returns a random integer
+-- in the range determined by its type.
+random ::
+ Monad m =>
+ Random.RandomGen r =>
+ Random.Random i =>
+ Negable i =>
+ Multiplicative i =>
+ S.StateT r m i
+random = S.StateT $ return . Random.random
+
+instance Random.Random Natural where
+	randomR (mini,maxi) =
+		first (fromIntegral::Integer -> Natural) .
+		Random.randomR (fromIntegral mini, fromIntegral maxi)
+	random = first (fromIntegral::Integer -> Natural) . Random.random
diff --git a/src/Voting/Protocol/Election.hs b/src/Voting/Protocol/Election.hs
--- a/src/Voting/Protocol/Election.hs
+++ b/src/Voting/Protocol/Election.hs
@@ -53,7 +53,6 @@
 import Voting.Protocol.Utils
 import Voting.Protocol.Arith
 import Voting.Protocol.Credential
-import Voting.Protocol.FFC (FFC)
 
 -- * Type 'Encryption'
 -- | ElGamal-like encryption.
@@ -75,13 +74,12 @@
    -- ^ Encrypted 'clear' text,
    -- equal to @('pubKey' '^'encNone '*' 'groupGen' '^'clear)@
  } deriving (Generic)
-deriving instance Eq (FieldElement crypto c) => Eq (Encryption crypto v c)
-deriving instance (Show (FieldElement crypto c), Show (G crypto c)) => Show (Encryption crypto v c)
-deriving instance NFData (FieldElement crypto c) => NFData (Encryption crypto v c)
+deriving instance Eq (G crypto c) => Eq (Encryption crypto v c)
+deriving instance (Show (G crypto c), Show (G crypto c)) => Show (Encryption crypto v c)
+deriving instance NFData (G crypto c) => NFData (Encryption crypto v c)
 instance
  ( Reifies v Version
- , Reifies c crypto
- , ToJSON (FieldElement crypto c)
+ , GroupParams crypto c
  ) => ToJSON (Encryption crypto v c) where
 	toJSON Encryption{..} =
 		JSON.object
@@ -95,8 +93,7 @@
 		 )
 instance
  ( Reifies v Version
- , Reifies c crypto
- , FromJSON (G crypto c)
+ , GroupParams crypto c
  ) => FromJSON (Encryption crypto v c) where
 	parseJSON = JSON.withObject "Encryption" $ \o -> do
 		encryption_nonce <- o .: "alpha"
@@ -105,10 +102,7 @@
 
 -- | Additive homomorphism.
 -- Using the fact that: @'groupGen' '^'x '*' 'groupGen' '^'y '==' 'groupGen' '^'(x'+'y)@.
-instance
- ( Reifies c crypto
- , Multiplicative (FieldElement crypto c)
- ) => Additive (Encryption crypto v c) where
+instance GroupParams crypto c => Additive (Encryption crypto v c) where
 	zero = Encryption one one
 	x+y = Encryption
 	 (encryption_nonce x * encryption_nonce y)
@@ -127,9 +121,7 @@
 -- without the 'SecretKey' associated with 'pubKey'.
 encrypt ::
  Reifies v Version =>
- Reifies c crypto =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
+ GroupParams crypto c =>
  Monad m => RandomGen r =>
  PublicKey crypto c -> E crypto c ->
  S.StateT r m (EncryptionNonce crypto c, Encryption crypto v c)
@@ -177,7 +169,7 @@
    -- to ensure that each 'prove' does not reveal any information
    -- about its secret.
  } deriving (Eq,Show,NFData,Generic)
-instance Group crypto => ToJSON (Proof crypto v c) where
+instance ToJSON (Proof crypto v c) where
 	toJSON Proof{..} =
 		JSON.object
 		 [ "challenge" .= proof_challenge
@@ -188,7 +180,7 @@
 		 (  "challenge" .= proof_challenge
 		 <> "response"  .= proof_response
 		 )
-instance (Reifies c crypto, Group crypto) => FromJSON (Proof crypto v c) where
+instance GroupParams crypto c => FromJSON (Proof crypto v c) where
 	parseJSON = JSON.withObject "TrusteePublicKey" $ \o -> do
 		proof_challenge <- o .: "challenge"
 		proof_response  <- o .: "response"
@@ -241,10 +233,8 @@
 -- can be used to deduce @sec@ (using the special-soundness).
 prove ::
  forall crypto v c list m r.
- Reifies c crypto =>
  Reifies v Version =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
+ GroupParams crypto c =>
  Monad m => RandomGen r => Functor list =>
  E crypto c ->
  list (G crypto c) ->
@@ -268,10 +258,8 @@
 -- | Like 'prove' but quicker. It chould replace 'prove' entirely
 -- when Helios-C specifications will be fixed.
 proveQuicker ::
- Reifies c crypto =>
  Reifies v Version =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
+ GroupParams crypto c =>
  Monad m => RandomGen r => Functor list =>
  E crypto c ->
  list (G crypto c) ->
@@ -295,8 +283,7 @@
 -- Used in 'proveEncryption' to fill the returned 'DisjProof'
 -- with fake 'Proof's for all 'Disjunction's but the encrypted one.
 fakeProof ::
- Reifies c crypto =>
- Group crypto =>
+ GroupParams crypto c =>
  Monad m => RandomGen r =>
  S.StateT r m (Proof crypto v c)
 fakeProof = do
@@ -315,9 +302,7 @@
 commit ::
  forall crypto v c.
  Reifies v Version =>
- Reifies c crypto =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
+ GroupParams crypto c =>
  Proof crypto v c ->
  G crypto c ->
  G crypto c ->
@@ -339,8 +324,7 @@
 -- | Like 'commit' but quicker. It chould replace 'commit' entirely
 -- when Helios-C specifications will be fixed.
 commitQuicker ::
- Reifies c crypto =>
- Multiplicative (FieldElement crypto c) =>
+ GroupParams crypto c =>
  Proof crypto v c ->
  G crypto c ->
  G crypto c ->
@@ -357,17 +341,13 @@
 
 booleanDisjunctions ::
  forall crypto c.
- Reifies c crypto =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
+ GroupParams crypto c =>
  [Disjunction crypto c]
 booleanDisjunctions = List.take 2 $ groupGenInverses @crypto
 
 intervalDisjunctions ::
  forall crypto c.
- Reifies c crypto =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
+ GroupParams crypto c =>
  Natural -> Natural -> [Disjunction crypto c]
 intervalDisjunctions mini maxi =
 	List.genericTake (fromJust $ (nat maxi + 1)`minusNaturalMaybe`nat mini) $
@@ -386,19 +366,6 @@
 newtype DisjProof crypto v c = DisjProof [Proof crypto v c]
  deriving (Eq,Show,Generic)
  deriving newtype (NFData,ToJSON,FromJSON)
-{-
-deriving instance Eq (GroupExponent crypto c) => Eq (DisjProof crypto v c)
-deriving instance Show (GroupExponent crypto c) => Show (DisjProof crypto v c)
-deriving newtype instance NFData (GroupExponent crypto c) => NFData (DisjProof crypto v c)
-deriving newtype instance
- ( Reifies c crypto
- , ToJSON (GroupExponent crypto c)
- ) => ToJSON (DisjProof crypto v c)
-deriving newtype instance
- ( Reifies c crypto
- , FromJSON (GroupExponent crypto c)
- ) => FromJSON (DisjProof crypto v c)
--}
 
 -- | @('proveEncryption' elecPubKey voterZKP (prevDisjs,nextDisjs) (encNonce,enc))@
 -- returns a 'DisjProof' that 'enc' 'encrypt's
@@ -412,10 +379,7 @@
 -- DOC: Pierrick Gaudry. <https://hal.inria.fr/hal-01576379 Some ZK security proofs for Belenios>, 2017.
 proveEncryption ::
  Reifies v Version =>
- Reifies c crypto =>
- Group crypto =>
- ToNatural (FieldElement crypto c) =>
- Multiplicative (FieldElement crypto c) =>
+ GroupParams crypto c =>
  Monad m => RandomGen r =>
  PublicKey crypto c -> ZKP ->
  ([Disjunction crypto c],[Disjunction crypto c]) ->
@@ -445,10 +409,7 @@
 
 verifyEncryption ::
  Reifies v Version =>
- Reifies c crypto =>
- Group crypto =>
- ToNatural (FieldElement crypto c) =>
- Multiplicative (FieldElement crypto c) =>
+ GroupParams crypto c =>
  Monad m =>
  PublicKey crypto c -> ZKP ->
  [Disjunction crypto c] -> (Encryption crypto v c, DisjProof crypto v c) ->
@@ -467,8 +428,7 @@
 
 -- ** Hashing
 encryptionStatement ::
- Reifies c crypto =>
- ToNatural (FieldElement crypto c) =>
+ GroupParams crypto c =>
  ZKP -> Encryption crypto v c -> BS.ByteString
 encryptionStatement (ZKP voterZKP) Encryption{..} =
 	"prove|"<>voterZKP<>"|"
@@ -482,9 +442,7 @@
 -- and for the verifier the 'Proof' comes from the prover.
 encryptionCommitments ::
  Reifies v Version =>
- Reifies c crypto =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
+ GroupParams crypto c =>
  PublicKey crypto c -> Encryption crypto v c ->
  Disjunction crypto c -> Proof crypto v c -> [G crypto c]
 encryptionCommitments elecPubKey Encryption{..} disj proof =
@@ -546,14 +504,12 @@
    -- is an element of @[mini..maxi]@.
  -- , answer_blankProof ::
  } deriving (Generic)
-deriving instance Eq (FieldElement crypto c) => Eq (Answer crypto v c)
-deriving instance (Show (FieldElement crypto c), Show (G crypto c)) => Show (Answer crypto v c)
-deriving instance NFData (FieldElement crypto c) => NFData (Answer crypto v c)
+deriving instance Eq (G crypto c) => Eq (Answer crypto v c)
+deriving instance (Show (G crypto c), Show (G crypto c)) => Show (Answer crypto v c)
+deriving instance NFData (G crypto c) => NFData (Answer crypto v c)
 instance
  ( Reifies v Version
- , Reifies c crypto
- , ToJSON (FieldElement crypto c)
- , Group crypto
+ , GroupParams crypto c
  ) => ToJSON (Answer crypto v c) where
 	toJSON Answer{..} =
 		let (answer_choices, answer_individual_proofs) =
@@ -573,9 +529,7 @@
 		 )
 instance
  ( Reifies v Version
- , Reifies c crypto
- , FromJSON (G crypto c)
- , Group crypto
+ , GroupParams crypto c
  ) => FromJSON (Answer crypto v c) where
 	parseJSON = JSON.withObject "Answer" $ \o -> do
 		answer_choices <- o .: "choices"
@@ -589,15 +543,12 @@
 -- unless an 'ErrorAnswer' is returned.
 encryptAnswer ::
  Reifies v Version =>
- Reifies c crypto =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
- ToNatural (FieldElement crypto c) =>
+ GroupParams crypto c =>
  Monad m => RandomGen r =>
  PublicKey crypto c -> ZKP ->
  Question v -> [Bool] ->
  S.StateT r (ExceptT ErrorAnswer m) (Answer crypto v c)
-encryptAnswer elecPubKey zkp Question{..} opinionByChoice
+encryptAnswer (elecPubKey::PublicKey crypto c) zkp Question{..} opinionByChoice
  | not (question_mini <= opinionsSum && opinionsSum <= question_maxi) =
 	lift $ throwE $
 		ErrorAnswer_WrongSumOfOpinions opinionsSum question_mini question_maxi
@@ -633,23 +584,21 @@
 
 verifyAnswer ::
  Reifies v Version =>
- Reifies c crypto =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
- ToNatural (FieldElement crypto c) =>
+ GroupParams crypto c =>
  PublicKey crypto c -> ZKP ->
  Question v -> Answer crypto v c -> Bool
-verifyAnswer elecPubKey zkp Question{..} Answer{..}
+verifyAnswer (elecPubKey::PublicKey crypto c) zkp Question{..} Answer{..}
  | List.length question_choices /= List.length answer_opinions = False
- | otherwise = either (const False) id $ runExcept $ do
-	validOpinions <-
-		verifyEncryption elecPubKey zkp booleanDisjunctions
-		 `traverse` answer_opinions
-	validSum <- verifyEncryption elecPubKey zkp
-	 (intervalDisjunctions question_mini question_maxi)
-	 ( sum (fst <$> answer_opinions)
-	 , answer_sumProof )
-	return (and validOpinions && validSum)
+ | otherwise = do
+	either (const False) id $ runExcept $ do
+		validOpinions <-
+			verifyEncryption elecPubKey zkp booleanDisjunctions
+			 `traverse` answer_opinions
+		validSum <- verifyEncryption elecPubKey zkp
+		 (intervalDisjunctions question_mini question_maxi)
+		 ( sum (fst <$> answer_opinions)
+		 , answer_sumProof )
+		return (and validOpinions && validSum)
 
 -- ** Type 'ErrorAnswer'
 -- | Error raised by 'encryptAnswer'.
@@ -673,14 +622,13 @@
  , election_version     :: !(Maybe Version)
  , election_public_key  :: !(PublicKey crypto c)
  } deriving (Generic)
-deriving instance (Eq crypto, Eq (FieldElement crypto c)) => Eq (Election crypto v c)
-deriving instance (Show crypto, Show (FieldElement crypto c)) => Show (Election crypto v c)
-deriving instance (NFData crypto, NFData (FieldElement crypto c)) => NFData (Election crypto v c)
+deriving instance (Eq crypto, Eq (G crypto c)) => Eq (Election crypto v c)
+deriving instance (Show crypto, Show (G crypto c)) => Show (Election crypto v c)
+deriving instance (NFData crypto, NFData (G crypto c)) => NFData (Election crypto v c)
 instance
- ( ToJSON crypto
- , ToJSON (FieldElement crypto c)
- , Reifies v Version
- , Reifies c crypto
+ ( Reifies v Version
+ , GroupParams crypto c
+ , ToJSON crypto
  ) => ToJSON (Election crypto v c) where
 	toJSON Election{..} =
 		JSON.object $
@@ -707,15 +655,22 @@
 		 ) <>
 		 maybe mempty ("version" .=) election_version
 
+hashElection ::
+ Reifies v Version =>
+ GroupParams crypto c =>
+ ToJSON crypto =>
+ Election crypto v c -> Base64SHA256
+hashElection = base64SHA256 . BSL.toStrict . JSON.encode
+
 readElection ::
- ReifyCrypto crypto =>
+ forall crypto r.
  FromJSON crypto =>
+ ReifyCrypto crypto =>
  FilePath ->
  (forall v c.
-  Reifies v Version =>
-  Reifies c crypto =>
-  FieldElementConstraints crypto c =>
-  Election crypto v c -> r) ->
+	Reifies v Version =>
+	GroupParams crypto c =>
+	Election crypto v c -> r) ->
  ExceptT String IO r
 readElection filePath k = do
 	fileData <- lift $ BS.readFile filePath
@@ -748,61 +703,6 @@
 				 , ..
 				 }
 
-hashElection ::
- ToJSON crypto =>
- Reifies c crypto =>
- Reifies v Version =>
- ToJSON (FieldElement crypto c) =>
- Election crypto v c -> Base64SHA256
-hashElection = base64SHA256 . BSL.toStrict . JSON.encode
-
--- ** Class 'ReifyCrypto'
--- | @('reifyCrypto' crypto k)@ is like @('reify' crypto k)@
--- but gives to @(k)@ more constraints than just @('Reifies' c crypto)@,
--- which is used when defining classes on @(crypto)@
--- where @(c)@ (the type variable guarantying the same
--- @crypto@graphic parameters are used throughout)
--- is not yet in scope and thus where one cannot
--- add those constraints requiring to have @(c)@ in scope.
--- See for instance the 'QuickcheckElection' class, in the tests.
---
--- For convenience, the 'ReifyCrypto' class also implies the pervasive
--- constraint 'Group'.
-class
- ( Group crypto
- , Key crypto
- , Show crypto
- , NFData crypto
- , JSON.ToJSON crypto
- , JSON.FromJSON crypto
- ) => ReifyCrypto crypto where
-	reifyCrypto ::
-	 crypto -> (forall c.
-	  Reifies c crypto =>
-	  FieldElementConstraints crypto c =>
-	  Proxy c -> r) -> r
-instance ReifyCrypto FFC where
-	reifyCrypto = reify
-
--- ** Class 'FieldElementConstraints'
--- | List the 'Constraint's on the element of the field
--- when the @(crypto)@ has not been instantiated to a specific type yet.
--- It concerns only 'Constraint's whose method act on @(a)@,
--- not @(x c)@ (eg. 'Group').
-type FieldElementConstraints crypto c =
- ( Multiplicative (FieldElement crypto c)
- , FromNatural    (FieldElement crypto c)
- , ToNatural      (FieldElement crypto c)
- , Eq             (FieldElement crypto c)
- , Ord            (FieldElement crypto c)
- , Show           (FieldElement crypto c)
- , NFData         (FieldElement crypto c)
- , FromJSON       (FieldElement crypto c)
- , ToJSON         (FieldElement crypto c)
- , FromJSON       (G crypto c)
- , ToJSON         (G crypto c)
- )
-
 -- * Type 'Ballot'
 data Ballot crypto v c = Ballot
  { ballot_answers       :: ![Answer crypto v c]
@@ -810,12 +710,11 @@
  , ballot_election_uuid :: !UUID
  , ballot_election_hash :: !Base64SHA256
  } deriving (Generic)
-deriving instance (NFData (FieldElement crypto c), NFData crypto) => NFData (Ballot crypto v c)
+deriving instance (NFData (G crypto c), NFData crypto) => NFData (Ballot crypto v c)
 instance
  ( Reifies v Version
- , Reifies c crypto
- , Group crypto
- , ToJSON (FieldElement crypto c)
+ , GroupParams crypto c
+ , ToJSON (G crypto c)
  ) => ToJSON (Ballot crypto v c) where
 	toJSON Ballot{..} =
 		JSON.object $
@@ -833,9 +732,7 @@
 		 maybe mempty ("signature" .=) ballot_signature
 instance
  ( Reifies v Version
- , Reifies c crypto
- , Group crypto
- , FromJSON (G crypto c)
+ , GroupParams crypto c
  ) => FromJSON (Ballot crypto v c) where
 	parseJSON = JSON.withObject "Ballot" $ \o -> do
 		ballot_answers       <- o .: "answers"
@@ -849,18 +746,13 @@
 -- where 'opinionsByQuest' is a list of 'Opinion's
 -- on each 'question_choices' of each 'election_questions'.
 encryptBallot ::
- forall crypto m v c r.
- Reifies c crypto =>
  Reifies v Version =>
- Group crypto =>
- Key crypto =>
- Multiplicative (FieldElement crypto c) =>
- ToNatural (FieldElement crypto c) =>
+ GroupParams crypto c => Key crypto =>
  Monad m => RandomGen r =>
  Election crypto v c ->
  Maybe (SecretKey crypto c) -> [[Bool]] ->
  S.StateT r (ExceptT ErrorBallot m) (Ballot crypto v c)
-encryptBallot Election{..} ballotSecKeyMay opinionsByQuest
+encryptBallot (Election{..}::Election crypto v c) ballotSecKeyMay opinionsByQuest
  | List.length election_questions /= List.length opinionsByQuest =
 	lift $ throwE $
 		ErrorBallot_WrongNumberOfAnswers
@@ -884,12 +776,12 @@
 		signature_proof <-
 			proveQuicker ballotSecKey (Identity groupGen) $
 			 \(Identity commitment) ->
-				hash @_ @crypto
+				hash @crypto
 				 -- NOTE: the order is unusual, the commitments are first
 				 -- then comes the statement. Best guess is that
 				 -- this is easier to code due to their respective types.
-				 (signatureCommitments @_ @crypto voterZKP commitment)
-				 (signatureStatement @_ @crypto ballot_answers)
+				 (signatureCommitments @crypto voterZKP commitment)
+				 (signatureStatement @crypto ballot_answers)
 		return $ Just Signature{..}
 	return Ballot
 	 { ballot_answers
@@ -899,16 +791,11 @@
 	 }
 
 verifyBallot ::
- forall crypto v c.
  Reifies v Version =>
- Reifies c crypto =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
- ToNatural (FieldElement crypto c) =>
- ToNatural (PublicKey crypto c) =>
+ GroupParams crypto c =>
  Election crypto v c ->
  Ballot crypto v c -> Bool
-verifyBallot Election{..} Ballot{..} =
+verifyBallot (Election{..}::Election crypto v c) Ballot{..} =
 	ballot_election_uuid == election_uuid &&
 	ballot_election_hash == election_hash &&
 	List.length election_questions == List.length ballot_answers &&
@@ -919,8 +806,8 @@
 			let zkp = ZKP (bytesNat signature_publicKey) in
 			(, zkp) $
 				proof_challenge signature_proof == hash
-				 (signatureCommitments @_ @crypto zkp (commitQuicker signature_proof groupGen signature_publicKey))
-				 (signatureStatement @_ @crypto ballot_answers)
+				 (signatureCommitments @crypto zkp (commitQuicker signature_proof groupGen signature_publicKey))
+				 (signatureStatement @crypto ballot_answers)
 	in
 	and $ isValidSign :
 		List.zipWith (verifyAnswer election_public_key zkpSign)
@@ -937,14 +824,10 @@
    -- ^ Verification key.
  , signature_proof     :: !(Proof crypto v c)
  } deriving (Generic)
-deriving instance
- ( NFData crypto
- , NFData (FieldElement crypto c)
- ) => NFData (Signature crypto v c)
+deriving instance (NFData crypto, NFData (G crypto c)) => NFData (Signature crypto v c)
 instance
- ( Reifies c crypto
- , Reifies v Version
- , ToJSON (FieldElement crypto c)
+ ( Reifies v Version
+ , GroupParams crypto c
  ) => ToJSON (Signature crypto v c) where
 	toJSON (Signature pubKey Proof{..}) =
 		JSON.object
@@ -959,10 +842,8 @@
 		 <> "response"   .= proof_response
 		 )
 instance
- ( Reifies c crypto
- , Reifies v Version
- , Group crypto
- , FromJSON (PublicKey crypto c)
+ ( Reifies v Version
+ , GroupParams crypto c
  ) => FromJSON (Signature crypto v c) where
 	parseJSON = JSON.withObject "Signature" $ \o -> do
 		signature_publicKey <- o .: "public_key"
@@ -976,7 +857,7 @@
 -- | @('signatureStatement' answers)@
 -- returns the encrypted material to be signed:
 -- all the 'encryption_nonce's and 'encryption_vault's of the given @answers@.
-signatureStatement :: Reifies c crypto => Foldable f => f (Answer crypto v c) -> [G crypto c]
+signatureStatement :: GroupParams crypto c => Foldable f => f (Answer crypto v c) -> [G crypto c]
 signatureStatement =
 	foldMap $ \Answer{..} ->
 		(`foldMap` answer_opinions) $ \(Encryption{..}, _proof) ->
@@ -984,8 +865,8 @@
 
 -- | @('signatureCommitments' voterZKP commitment)@
 signatureCommitments ::
- Reifies c crypto =>
- ToNatural (FieldElement crypto c) =>
+ GroupParams crypto c =>
+ ToNatural (G crypto c) =>
  ZKP -> Commitment crypto c -> BS.ByteString
 signatureCommitments (ZKP voterZKP) commitment =
 	"sig|"<>voterZKP<>"|" -- NOTE: this is actually part of the statement
diff --git a/src/Voting/Protocol/FFC.hs b/src/Voting/Protocol/FFC.hs
--- a/src/Voting/Protocol/FFC.hs
+++ b/src/Voting/Protocol/FFC.hs
@@ -24,7 +24,7 @@
 import Data.Monoid (Monoid(..))
 import Data.Ord (Ord(..))
 import Data.Proxy (Proxy(..))
-import Data.Reflection (Reifies(..))
+import Data.Reflection (Reifies(..), reify)
 import Data.Semigroup (Semigroup(..))
 import Data.Text (Text)
 import GHC.Generics (Generic)
@@ -45,7 +45,7 @@
 import Voting.Protocol.Credential
 
 -- * Type 'FFC'
--- | Mutiplicative Sub-Group of a Finite Prime Field.
+-- | Mutiplicative subgroup of a Finite Prime Field.
 --
 -- NOTE: an 'FFC' term-value is brought into the context of many functions
 -- through a type-variable @c@ whose 'Reifies' constraint enables to 'reflect'
@@ -57,7 +57,7 @@
 -- is encoded at the type-level by including @c@
 -- as a phantom type of 'F', 'G' and 'E'.
 data FFC = FFC
- {   ffc_name :: Text
+ {   ffc_name :: !Text
  ,   ffc_fieldCharac :: !Natural
      -- ^ The prime number characteristic of a Finite Prime Field.
      --
@@ -116,11 +116,25 @@
 		unless (fromJust (ffc_fieldCharac`minusNaturalMaybe`one) `rem` ffc_groupOrder == 0) $
 			JSON.typeMismatch "FFC: groupOrder does not divide fieldCharac-1" (JSON.Object o)
 		return FFC{..}
-instance Group FFC where
-	groupGen :: forall c. Reifies c FFC => G FFC c
-	groupGen = G $ F $ ffc_groupGen $ reflect (Proxy::Proxy c)
-	groupOrder :: forall c. Reifies c FFC => Proxy c -> Natural
+instance Reifies c FFC => GroupParams FFC c where
+	groupGen = G $ ffc_groupGen $ reflect (Proxy::Proxy c)
 	groupOrder c = ffc_groupOrder $ reflect c
+instance ReifyCrypto FFC where
+	reifyCrypto = reify
+instance Key FFC where
+	cryptoType _ = "FFC"
+	cryptoName = ffc_name
+	randomSecretKey = random
+	credentialSecretKey (UUID uuid) (Credential cred) =
+		fromNatural $ decodeBigEndian $
+		Crypto.fastPBKDF2_SHA256
+		 Crypto.Parameters
+		 { Crypto.iterCounts   = 1000
+		 , Crypto.outputLength = 32 -- bytes, ie. 256 bits
+		 }
+		 (Text.encodeUtf8 cred)
+		 (Text.encodeUtf8 uuid)
+	publicKey = (groupGen @FFC ^)
 
 fieldCharac :: forall c. Reifies c FFC => Natural
 fieldCharac = ffc_fieldCharac $ reflect (Proxy::Proxy c)
@@ -147,7 +161,6 @@
  , ffc_groupOrder  = 78571733251071885079927659812671450121821421258408794611510081919805623223441
  }
 
--- * Type 'F'
 -- | The type of the elements of a Finite Prime Field.
 --
 -- A field must satisfy the following properties:
@@ -171,19 +184,11 @@
 --   @(a'+'b)'*'c == (a'*'c) '+' (b'*'c)@
 --
 -- The 'Natural' is always within @[0..'fieldCharac'-1]@.
-newtype F c = F { unF :: Natural }
- deriving (Eq,Ord,Show)
- deriving newtype NFData
-type instance FieldElement FFC = F
-instance Reifies c FFC => FromJSON (F c) where
-	parseJSON (JSON.String s)
-	 | Just (c0,_) <- Text.uncons s
-	 , c0 /= '0'
-	 , Text.all Char.isDigit s
-	 , Just x <- readMaybe (Text.unpack s)
-	 , x < fieldCharac @c
-	 = return (F x)
-	parseJSON json = JSON.typeMismatch "FieldElement FFC" json
+type instance FieldElement FFC = Natural
+deriving newtype instance Eq     (G FFC c)
+deriving newtype instance Ord    (G FFC c)
+deriving newtype instance NFData (G FFC c)
+deriving newtype instance Show   (G FFC c)
 instance Reifies c FFC => FromJSON (G FFC c) where
 	parseJSON (JSON.String s)
 	 | Just (c0,_) <- Text.uncons s
@@ -191,52 +196,38 @@
 	 , Text.all Char.isDigit s
 	 , Just x <- readMaybe (Text.unpack s)
 	 , x < fieldCharac @c
-	 , r <- G (F x)
+	 , r <- G x
 	 , r ^ E (groupOrder @FFC (Proxy @c)) == one
 	 = return r
 	parseJSON json = JSON.typeMismatch "GroupElement" json
-instance ToJSON (F c) where
-	toJSON (F x) = JSON.toJSON (show x)
-instance Reifies c FFC => FromNatural (F c) where
-	fromNatural i = F $ abs $ i `mod` fieldCharac @c
+instance ToJSON (G FFC c) where
+	toJSON (G x) = JSON.toJSON (show x)
+instance Reifies c FFC => FromNatural (G FFC c) where
+	fromNatural i = G $ abs $ i `mod` fieldCharac @c
 		where
 		abs x | x < 0 = x + fieldCharac @c
 		      | otherwise = x
-instance ToNatural (F c) where
-	nat = unF
-instance Reifies c FFC => Additive (F c) where
-	zero = F 0
-	F x + F y = F $ (x + y) `mod` fieldCharac @c
-instance Reifies c FFC => Negable (F c) where
-	neg (F x)
+instance ToNatural (G FFC c) where
+	nat = unG
+instance Reifies c FFC => Additive (G FFC c) where
+	zero = G 0
+	G x + G y = G $ (x + y) `mod` fieldCharac @c
+instance Reifies c FFC => Negable (G FFC c) where
+	neg (G x)
 	 | x == 0 = zero
-	 | otherwise = F $ fromJust $ nat (fieldCharac @c)`minusNaturalMaybe`x
-instance Reifies c FFC => Multiplicative (F c) where
-	one = F 1
-	F x * F y = F $ (x * y) `mod` fieldCharac @c
-instance Reifies c FFC => Random.Random (F c) where
-	randomR (F lo, F hi) =
-		first (F . fromIntegral) .
+	 | otherwise = G $ fromJust $ nat (fieldCharac @c)`minusNaturalMaybe`x
+instance Reifies c FFC => Multiplicative (G FFC c) where
+	one = G 1
+	G x * G y = G $ (x * y) `mod` fieldCharac @c
+instance Reifies c FFC => Random.Random (G FFC c) where
+	randomR (G lo, G hi) =
+		first (G . fromIntegral) .
 		Random.randomR
 		 ( 0`max`toInteger lo
 		 , toInteger hi`min`(toInteger (fieldCharac @c) - 1) )
 	random =
-		first (F . fromIntegral) .
+		first (G . fromIntegral) .
 		Random.randomR (0, toInteger (fieldCharac @c) - 1)
-
--- * Conversions
-
-instance Key FFC where
-	cryptoType _ = "FFC"
-	cryptoName = ffc_name
-	randomSecretKey = random
-	credentialSecretKey (UUID uuid) (Credential cred) =
-		fromNatural $ decodeBigEndian $
-		Crypto.fastPBKDF2_SHA256
-		 Crypto.Parameters
-		 { Crypto.iterCounts   = 1000
-		 , Crypto.outputLength = 32 -- bytes, ie. 256 bits
-		 }
-		 (Text.encodeUtf8 cred)
-		 (Text.encodeUtf8 uuid)
-	publicKey = (groupGen @FFC ^)
+instance Reifies c FFC => Invertible (G FFC c) where
+	-- | NOTE: add 'groupOrder' so the exponent given to (^) is positive.
+	inv = (^ E (fromJust $ groupOrder @FFC (Proxy @c)`minusNaturalMaybe`1))
diff --git a/src/Voting/Protocol/Tally.hs b/src/Voting/Protocol/Tally.hs
--- a/src/Voting/Protocol/Tally.hs
+++ b/src/Voting/Protocol/Tally.hs
@@ -14,7 +14,6 @@
 import Data.Functor ((<$>))
 import Data.Maybe (maybe)
 import Data.Semigroup (Semigroup(..))
-import Data.Ord (Ord(..))
 import Data.Reflection (Reifies(..))
 import Data.Tuple (fst, snd)
 import GHC.Generics (Generic)
@@ -50,14 +49,12 @@
  , tally_countByChoiceByQuest :: ![[Natural]]
    -- ^ The decrypted count of supportive 'Opinion's, by choice by 'Question'.
  } deriving (Generic)
-deriving instance Eq (FieldElement crypto c) => Eq (Tally crypto v c)
-deriving instance (Show (FieldElement crypto c), Show (G crypto c)) => Show (Tally crypto v c)
-deriving instance NFData (FieldElement crypto c) => NFData (Tally crypto v c)
+deriving instance Eq (G crypto c) => Eq (Tally crypto v c)
+deriving instance (Show (G crypto c), Show (G crypto c)) => Show (Tally crypto v c)
+deriving instance NFData (G crypto c) => NFData (Tally crypto v c)
 instance
  ( Reifies v Version
- , Reifies c crypto
- , Group crypto
- , ToJSON (FieldElement crypto c)
+ , GroupParams crypto c
  ) => ToJSON (Tally crypto v c) where
 	toJSON Tally{..} =
 		JSON.object
@@ -75,9 +72,7 @@
 		 )
 instance
  ( Reifies v Version
- , Reifies c crypto
- , Group crypto
- , FromJSON (G crypto c)
+ , GroupParams crypto c
  ) => FromJSON (Tally crypto v c) where
 	parseJSON = JSON.withObject "Tally" $ \o -> do
 		tally_countMax             <- o .: "num_tallied"
@@ -94,15 +89,13 @@
 -- returns the sum of the 'Encryption's of the given @ballots@,
 -- along with the number of 'Ballot's.
 encryptedTally ::
- Reifies c crypto =>
- Multiplicative (FieldElement crypto c) =>
+ GroupParams crypto c =>
  [Ballot crypto v c] -> (EncryptedTally crypto v c, Natural)
 encryptedTally = List.foldr insertEncryptedTally emptyEncryptedTally
 
 -- | The initial 'EncryptedTally' which tallies no 'Ballot'.
 emptyEncryptedTally ::
- Reifies c crypto =>
- Multiplicative (FieldElement crypto c) =>
+ GroupParams crypto c =>
  (EncryptedTally crypto v c, Natural)
 emptyEncryptedTally = (List.repeat (List.repeat zero), 0)
 
@@ -110,9 +103,10 @@
 -- returns the 'EncryptedTally' adding the votes of the given @(ballot)@
 -- to those of the given @(encTally)@.
 insertEncryptedTally ::
- Reifies c crypto =>
- Multiplicative (FieldElement crypto c) =>
- Ballot crypto v c -> (EncryptedTally crypto v c, Natural) -> (EncryptedTally crypto v c, Natural)
+ GroupParams crypto c =>
+ Ballot crypto v c ->
+ (EncryptedTally crypto v c, Natural) ->
+ (EncryptedTally crypto v c, Natural)
 insertEncryptedTally Ballot{..} (encTally, numBallots) =
 	( List.zipWith
 		 (\Answer{..} -> List.zipWith (+) (fst <$> answer_opinions))
@@ -128,13 +122,9 @@
  Except ErrorTally [[DecryptionFactor crypto c]]
 
 proveTally ::
- Reifies c crypto =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
- Ord (FieldElement crypto c) =>
+ GroupParams crypto c =>
  (EncryptedTally crypto v c, Natural) -> [DecryptionShare crypto v c] ->
- DecryptionShareCombinator crypto v c ->
- Except ErrorTally (Tally crypto v c)
+ DecryptionShareCombinator crypto v c -> Except ErrorTally (Tally crypto v c)
 proveTally
  (tally_encByChoiceByQuest, tally_countMax)
  tally_decShareByTrustee
@@ -156,10 +146,7 @@
 	return Tally{..}
 
 verifyTally ::
- Reifies c crypto =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
- Eq (FieldElement crypto c) =>
+ GroupParams crypto c =>
  Tally crypto v c ->
  DecryptionShareCombinator crypto v c ->
  Except ErrorTally ()
@@ -181,13 +168,10 @@
 newtype DecryptionShare crypto v c = DecryptionShare
  { unDecryptionShare :: [[(DecryptionFactor crypto c, Proof crypto v c)]] }
  deriving (Generic)
-deriving instance Eq (FieldElement crypto c) => Eq (DecryptionShare crypto v c)
+deriving instance Eq (G crypto c) => Eq (DecryptionShare crypto v c)
 deriving instance Show (G crypto c) => Show (DecryptionShare crypto v c)
-deriving newtype instance NFData (FieldElement crypto c) => NFData (DecryptionShare crypto v c)
-instance
- ( Group crypto
- , ToJSON (FieldElement crypto c)
- ) => ToJSON (DecryptionShare crypto v c) where
+deriving newtype instance NFData (G crypto c) => NFData (DecryptionShare crypto v c)
+instance ToJSON (G crypto c) => ToJSON (DecryptionShare crypto v c) where
 	toJSON (DecryptionShare decByChoiceByQuest) =
 		JSON.object
 		 [ "decryption_factors" .=
@@ -201,11 +185,7 @@
 			 (JSON.list (JSON.list (toEncoding . fst)) decByChoiceByQuest) <>
 			JSON.pair "decryption_proofs"
 			 (JSON.list (JSON.list (toEncoding . snd)) decByChoiceByQuest)
-instance
- ( Reifies c crypto
- , Group crypto
- , FromJSON (G crypto c)
- ) => FromJSON (DecryptionShare crypto v c) where
+instance GroupParams crypto c => FromJSON (DecryptionShare crypto v c) where
 	parseJSON = JSON.withObject "DecryptionShare" $ \o -> do
 		decFactors <- o .: "decryption_factors"
 		decProofs  <- o .: "decryption_proofs"
@@ -223,11 +203,8 @@
 -- @('proveDecryptionShare' encByChoiceByQuest trusteeSecKey)@
 proveDecryptionShare ::
  Reifies v Version =>
- Reifies c crypto =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
+ GroupParams crypto c =>
  Key crypto =>
- ToNatural (FieldElement crypto c) =>
  Monad m => RandomGen r =>
  EncryptedTally crypto v c -> SecretKey crypto c -> S.StateT r m (DecryptionShare crypto v c)
 proveDecryptionShare encByChoiceByQuest trusteeSecKey =
@@ -236,11 +213,8 @@
 
 proveDecryptionFactor ::
  Reifies v Version => 
- Reifies c crypto => 
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
+ GroupParams crypto c =>
  Key crypto =>
- ToNatural (FieldElement crypto c) =>
  Monad m => RandomGen r =>
  SecretKey crypto c -> Encryption crypto v c -> S.StateT r m (DecryptionFactor crypto c, Proof crypto v c)
 proveDecryptionFactor trusteeSecKey Encryption{..} = do
@@ -248,10 +222,7 @@
 	return (encryption_nonce^trusteeSecKey, proof)
 	where zkp = decryptionShareStatement (publicKey trusteeSecKey)
 
-decryptionShareStatement ::
- Reifies c crypto =>
- ToNatural (FieldElement crypto c) =>
- PublicKey crypto c -> BS.ByteString
+decryptionShareStatement :: GroupParams crypto c => PublicKey crypto c -> BS.ByteString
 decryptionShareStatement pubKey =
 	"decrypt|"<>bytesNat pubKey<>"|"
 
@@ -277,10 +248,7 @@
 -- is valid with respect to the 'EncryptedTally' 'encTally'.
 verifyDecryptionShare ::
  Reifies v Version =>
- Reifies c crypto =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
- ToNatural (FieldElement crypto c) =>
+ GroupParams crypto c =>
  Monad m =>
  EncryptedTally crypto v c -> PublicKey crypto c -> DecryptionShare crypto v c ->
  ExceptT ErrorTally m ()
@@ -298,10 +266,7 @@
 
 verifyDecryptionShareByTrustee ::
  Reifies v Version =>
- Reifies c crypto =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
- ToNatural (FieldElement crypto c) =>
+ GroupParams crypto c =>
  Monad m =>
  EncryptedTally crypto v c -> [PublicKey crypto c] -> [DecryptionShare crypto v c] ->
  ExceptT ErrorTally m ()
diff --git a/src/Voting/Protocol/Trustee/Indispensable.hs b/src/Voting/Protocol/Trustee/Indispensable.hs
--- a/src/Voting/Protocol/Trustee/Indispensable.hs
+++ b/src/Voting/Protocol/Trustee/Indispensable.hs
@@ -47,13 +47,10 @@
 	-- Which is done in 'proveIndispensableTrusteePublicKey'
 	-- and 'verifyIndispensableTrusteePublicKey'.
  } deriving (Generic)
-deriving instance Eq (FieldElement crypto c) => Eq (TrusteePublicKey crypto v c)
-deriving instance (Show (FieldElement crypto c), Show (PublicKey crypto c)) => Show (TrusteePublicKey crypto v c)
-deriving instance NFData (FieldElement crypto c) => NFData (TrusteePublicKey crypto v c)
-instance
- ( Group crypto
- , ToJSON (FieldElement crypto c)
- ) => ToJSON (TrusteePublicKey crypto v c) where
+deriving instance Eq (G crypto c) => Eq (TrusteePublicKey crypto v c)
+deriving instance (Show (G crypto c), Show (PublicKey crypto c)) => Show (TrusteePublicKey crypto v c)
+deriving instance NFData (G crypto c) => NFData (TrusteePublicKey crypto v c)
+instance ToJSON (G crypto c) => ToJSON (TrusteePublicKey crypto v c) where
 	toJSON TrusteePublicKey{..} =
 		JSON.object
 		 [ "pok"        .= trustee_SecretKeyProof
@@ -64,11 +61,7 @@
 		 (  "pok"        .= trustee_SecretKeyProof
 		 <> "public_key" .= trustee_PublicKey
 		 )
-instance
- ( Reifies c crypto
- , Group crypto
- , FromJSON (PublicKey crypto c)
- ) => FromJSON (TrusteePublicKey crypto v c) where
+instance GroupParams crypto c => FromJSON (TrusteePublicKey crypto v c) where
 	parseJSON = JSON.withObject "TrusteePublicKey" $ \o -> do
 		trustee_PublicKey <- o .: "public_key"
 		trustee_SecretKeyProof <- o .: "pok"
@@ -81,11 +74,8 @@
 -- and a 'Proof' of its knowledge.
 proveIndispensableTrusteePublicKey ::
  Reifies v Version =>
- Reifies c crypto =>
- Group crypto =>
+ GroupParams crypto c =>
  Key crypto =>
- Multiplicative (FieldElement crypto c) =>
- ToNatural (FieldElement crypto c) =>
  Monad m => RandomGen r =>
  SecretKey crypto c -> S.StateT r m (TrusteePublicKey crypto v c)
 proveIndispensableTrusteePublicKey trustSecKey = do
@@ -103,10 +93,7 @@
 -- the given 'trustee_PublicKey' is known by the trustee.
 verifyIndispensableTrusteePublicKey ::
  Reifies v Version =>
- Reifies c crypto =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
- ToNatural (FieldElement crypto c) =>
+ GroupParams crypto c =>
  Monad m =>
  TrusteePublicKey crypto v c ->
  ExceptT ErrorTrusteePublicKey m ()
@@ -126,8 +113,7 @@
 
 -- ** Hashing
 indispensableTrusteePublicKeyStatement ::
- Reifies c crypto =>
- ToNatural (FieldElement crypto c) =>
+ GroupParams crypto c =>
  PublicKey crypto c -> BS.ByteString
 indispensableTrusteePublicKeyStatement trustPubKey =
 	"pok|"<>bytesNat trustPubKey<>"|"
@@ -137,9 +123,7 @@
 -- ** Generating an 'Election''s 'PublicKey' from multiple 'TrusteePublicKey's.
 
 combineIndispensableTrusteePublicKeys ::
- Reifies c crypto =>
- Multiplicative (FieldElement crypto c) =>
- ToNatural (FieldElement crypto c) =>
+ GroupParams crypto c =>
  [TrusteePublicKey crypto v c] -> PublicKey crypto c
 combineIndispensableTrusteePublicKeys =
 	List.foldr (\TrusteePublicKey{..} -> (trustee_PublicKey *)) one
@@ -148,10 +132,7 @@
 
 verifyIndispensableDecryptionShareByTrustee ::
  Reifies v Version =>
- Reifies c crypto =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
- ToNatural (FieldElement crypto c) =>
+ GroupParams crypto c =>
  Monad m =>
  EncryptedTally crypto v c -> [PublicKey crypto c] -> [DecryptionShare crypto v c] ->
  ExceptT ErrorTally m ()
@@ -165,10 +146,7 @@
 -- returns the 'DecryptionFactor's by choice by 'Question'
 combineIndispensableDecryptionShares ::
  Reifies v Version =>
- Reifies c crypto =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
- ToNatural (FieldElement crypto c) =>
+ GroupParams crypto c =>
  [PublicKey crypto c] -> DecryptionShareCombinator crypto v c
 combineIndispensableDecryptionShares
  pubKeyByTrustee
diff --git a/tests/HUnit/Credential.hs b/tests/HUnit/Credential.hs
--- a/tests/HUnit/Credential.hs
+++ b/tests/HUnit/Credential.hs
@@ -35,7 +35,7 @@
 	 , "xLcs7ev6Jy6FHHE"  ==> Right (Credential "xLcs7ev6Jy6FHHE")
 	 ]
  , testGroup "credentialSecretKey" $
-	 [ testSecretKey beleniosFFC
+	 [  testSecretKey beleniosFFC
 		 (UUID "xLcs7ev6Jy6FHH")
 		 (Credential "xLcs7ev6Jy6FHHE")
 		 24202898752499029126606335829564687069186982035759723128887013101942425902424
@@ -43,10 +43,9 @@
  ]
 
 testSecretKey ::
- ReifyCrypto crypto =>
- Key crypto =>
+ ReifyCrypto crypto => Key crypto =>
  crypto -> UUID -> Credential -> Natural -> TestTree
 testSecretKey crypto uuid cred exp =
-	reifyCrypto crypto $ \(Proxy::Proxy c) ->
-	testCase (show (uuid,cred)) $
-		credentialSecretKey @_ @c uuid cred @?= E exp
+	reifyCrypto crypto $ \(_c::Proxy c) ->
+		testCase (show (uuid,cred)) $
+			credentialSecretKey @_ @c uuid cred @?= E exp
diff --git a/tests/HUnit/Election.hs b/tests/HUnit/Election.hs
--- a/tests/HUnit/Election.hs
+++ b/tests/HUnit/Election.hs
@@ -32,11 +32,9 @@
  ]
 
 hunitsEncryptBallot ::
- ReifyCrypto crypto =>
- JSON.ToJSON crypto =>
- Key crypto =>
- Reifies v Version => Proxy v ->
- crypto -> TestTree
+ Reifies v Version =>
+ ReifyCrypto crypto => Key crypto => JSON.ToJSON crypto =>
+ Proxy v -> crypto -> TestTree
 hunitsEncryptBallot v crypto =
 	testGroup (Text.unpack $ cryptoName crypto)
 	 [ hunitEncryptBallot v crypto 0
@@ -81,31 +79,28 @@
 	 ]
 
 hunitEncryptBallot ::
- ReifyCrypto crypto =>
- JSON.ToJSON crypto =>
- Key crypto =>
- Reifies v Version => Proxy v ->
- crypto -> Int -> [Question v] -> [[Bool]] ->
- Either ErrorBallot Bool ->
- TestTree
+ Reifies v Version =>
+ ReifyCrypto crypto => Key crypto => JSON.ToJSON crypto =>
+ Proxy v -> crypto -> Int -> [Question v] -> [[Bool]] ->
+ Either ErrorBallot Bool -> TestTree
 hunitEncryptBallot v election_crypto seed election_questions opins exp =
 	let got =
-		reifyCrypto election_crypto $ \(Proxy::Proxy c) ->
-		runExcept $
-		(`evalStateT` Random.mkStdGen seed) $ do
-			election_uuid <- randomUUID
-			cred <- randomCredential
-			let ballotSecKey = credentialSecretKey @_ @c election_uuid cred
-			election_public_key <- publicKey <$> randomSecretKey
-			let elec = Election
-				 { election_name        = "election"
-				 , election_description = "description"
-				 , election_hash        = hashElection elec
-				 , election_version     = Just (reflect v)
-				 , ..
-				 }
-			verifyBallot elec
-			 <$> encryptBallot elec (Just ballotSecKey) opins
+		reifyCrypto election_crypto $ \(_c::Proxy c) ->
+			runExcept $
+			(`evalStateT` Random.mkStdGen seed) $ do
+				election_uuid <- randomUUID
+				cred <- randomCredential
+				let ballotSecKey = credentialSecretKey @_ @c election_uuid cred
+				election_public_key <- publicKey <$> randomSecretKey
+				let elec = Election
+					 { election_name        = "election"
+					 , election_description = "description"
+					 , election_hash        = hashElection elec
+					 , election_version     = Just (reflect v)
+					 , ..
+					 }
+				verifyBallot elec
+				 <$> encryptBallot elec (Just ballotSecKey) opins
 	in
 	testCase (show opins) $
 		got @?= exp
diff --git a/tests/HUnit/FFC.hs b/tests/HUnit/FFC.hs
--- a/tests/HUnit/FFC.hs
+++ b/tests/HUnit/FFC.hs
@@ -38,13 +38,12 @@
 
 hunitInv ::
  forall crypto.
- ReifyCrypto crypto =>
- Key crypto =>
+ ReifyCrypto crypto => Key crypto =>
  crypto -> TestTree
 hunitInv crypto =
 	testGroup (Text.unpack $ cryptoName crypto)
 	 [ testCase "groupGen" $
 			reifyCrypto crypto $ \(_c::Proxy c) ->
-			inv (groupGen :: G crypto c) @?=
-				groupGen ^ E (fromJust $ groupOrder (Proxy @c) `minusNaturalMaybe` one)
+				inv (groupGen :: G crypto c) @?=
+					groupGen ^ E (fromJust $ groupOrder (Proxy @c) `minusNaturalMaybe` one)
 	 ]
diff --git a/tests/HUnit/Trustee/Indispensable.hs b/tests/HUnit/Trustee/Indispensable.hs
--- a/tests/HUnit/Trustee/Indispensable.hs
+++ b/tests/HUnit/Trustee/Indispensable.hs
@@ -24,9 +24,9 @@
  ]
 
 testsVerifyIndispensableTrusteePublicKey ::
- ReifyCrypto crypto =>
- Reifies v Version => Proxy v ->
- crypto -> TestTree
+ Reifies v Version =>
+ ReifyCrypto crypto => Key crypto =>
+ Proxy v -> crypto -> TestTree
 testsVerifyIndispensableTrusteePublicKey v crypto =
 	testGroup (Text.unpack $ cryptoName crypto)
 	 [ testVerifyIndispensableTrusteePublicKey v crypto 0 (Right ())
@@ -34,23 +34,23 @@
 
 testVerifyIndispensableTrusteePublicKey ::
  forall crypto v.
- ReifyCrypto crypto =>
+ ReifyCrypto crypto => Key crypto =>
  Reifies v Version => Proxy v ->
  crypto -> Int -> Either ErrorTrusteePublicKey () -> TestTree
 testVerifyIndispensableTrusteePublicKey (_v::Proxy v) crypto seed exp =
-	reifyCrypto crypto $ \(Proxy::Proxy c) ->
-	let got =
-		runExcept $
-		(`evalStateT` Random.mkStdGen seed) $ do
-			trusteeSecKey :: SecretKey crypto c <- randomSecretKey
-			trusteePubKey :: TrusteePublicKey crypto v c <- proveIndispensableTrusteePublicKey trusteeSecKey
-			lift $ verifyIndispensableTrusteePublicKey trusteePubKey
-	in
-	testCase (Text.unpack $ cryptoName crypto) $
-		got @?= exp
+	reifyCrypto crypto $ \(_c::Proxy c) ->
+		let got =
+			runExcept $
+			(`evalStateT` Random.mkStdGen seed) $ do
+				trusteeSecKey :: SecretKey crypto c <- randomSecretKey
+				trusteePubKey :: TrusteePublicKey crypto v c <- proveIndispensableTrusteePublicKey trusteeSecKey
+				lift $ verifyIndispensableTrusteePublicKey trusteePubKey
+		in
+		testCase (Text.unpack $ cryptoName @crypto crypto) $
+			got @?= exp
 
 testsVerifyTally ::
- ReifyCrypto crypto =>
+ ReifyCrypto crypto => Key crypto =>
  Reifies v Version => Proxy v ->
  crypto -> TestTree
 testsVerifyTally v crypto =
@@ -63,33 +63,33 @@
 	 ]
 
 testVerifyTally ::
- ReifyCrypto crypto =>
- Reifies v Version => Proxy v ->
- crypto -> Int -> Natural -> Natural -> Natural -> TestTree
+ Reifies v Version =>
+ ReifyCrypto crypto => Key crypto =>
+ Proxy v -> crypto -> Int -> Natural -> Natural -> Natural -> TestTree
 testVerifyTally (_v::Proxy v) crypto seed nTrustees nQuests nChoices =
 	let clearTallyResult = dummyTallyResult nQuests nChoices in
 	let decryptedTallyResult :: Either ErrorTally [[Natural]] =
-		reifyCrypto crypto $ \(Proxy::Proxy c) ->
-		runExcept $
-		(`evalStateT` Random.mkStdGen seed) $ do
-			secKeyByTrustee :: [SecretKey crypto c] <-
-				replicateM (fromIntegral nTrustees) $ randomSecretKey
-			trusteePubKeys
-			 :: [TrusteePublicKey crypto v c]
-			 <- forM secKeyByTrustee $ proveIndispensableTrusteePublicKey
-			let pubKeyByTrustee = trustee_PublicKey <$> trusteePubKeys
-			let elecPubKey = combineIndispensableTrusteePublicKeys trusteePubKeys
-			(encTally, countMax) <- encryptTallyResult elecPubKey clearTallyResult
-			decShareByTrustee
-			 :: [DecryptionShare crypto v c]
-			 <- forM secKeyByTrustee $ proveDecryptionShare encTally
-			lift $ verifyDecryptionShareByTrustee encTally pubKeyByTrustee decShareByTrustee
-			tally@Tally{..} <- lift $
-				proveTally (encTally, countMax) decShareByTrustee $
+		reifyCrypto crypto $ \(_c::Proxy c) ->
+			runExcept $
+			(`evalStateT` Random.mkStdGen seed) $ do
+				secKeyByTrustee :: [SecretKey crypto c] <-
+					replicateM (fromIntegral nTrustees) $ randomSecretKey
+				trusteePubKeys
+				 :: [TrusteePublicKey crypto v c]
+				 <- forM secKeyByTrustee $ proveIndispensableTrusteePublicKey
+				let pubKeyByTrustee = trustee_PublicKey <$> trusteePubKeys
+				let elecPubKey = combineIndispensableTrusteePublicKeys trusteePubKeys
+				(encTally, countMax) <- encryptTallyResult elecPubKey clearTallyResult
+				decShareByTrustee
+				 :: [DecryptionShare crypto v c]
+				 <- forM secKeyByTrustee $ proveDecryptionShare encTally
+				lift $ verifyDecryptionShareByTrustee encTally pubKeyByTrustee decShareByTrustee
+				tally@Tally{..} <- lift $
+					proveTally (encTally, countMax) decShareByTrustee $
+						combineIndispensableDecryptionShares pubKeyByTrustee
+				lift $ verifyTally tally $
 					combineIndispensableDecryptionShares pubKeyByTrustee
-			lift $ verifyTally tally $
-				combineIndispensableDecryptionShares pubKeyByTrustee
-			return tally_countByChoiceByQuest
+				return tally_countByChoiceByQuest
 	in
 	testCase (Printf.printf "#T=%i,#Q=%i,#C=%i (%i maxCount)"
 	 nTrustees nQuests nChoices
@@ -107,9 +107,7 @@
 
 encryptTallyResult ::
  Reifies v Version =>
- Reifies c crypto =>
- Group crypto =>
- Multiplicative (FieldElement crypto c) =>
+ GroupParams crypto c =>
  Monad m => RandomGen r =>
  PublicKey crypto c -> [[Natural]] -> StateT r m (EncryptedTally crypto v c, Natural)
 encryptTallyResult pubKey countByChoiceByQuest =
diff --git a/tests/QuickCheck/Election.hs b/tests/QuickCheck/Election.hs
--- a/tests/QuickCheck/Election.hs
+++ b/tests/QuickCheck/Election.hs
@@ -27,19 +27,19 @@
 quickcheck :: Reifies v Version => Proxy v -> TestTree
 quickcheck v =
 	testGroup "Election"
-	 [ testGroup "verifyBallot" $
-		 [ quickcheckElection v weakFFC
-		 , quickcheckElection v beleniosFFC
+	 [ testGroup "verifyBallot" $ 
+		 [ reify weakFFC $ quickcheckElection v
+		 , reify beleniosFFC $ quickcheckElection v
 		 ]
 	 ]
 
 quickcheckElection ::
- ReifyCrypto crypto =>
- Reifies v Version => Proxy v ->
- crypto -> TestTree
-quickcheckElection (_v::Proxy v) crypto =
-	reifyCrypto crypto $ \(Proxy::Proxy c) ->
-	testGroup (Text.unpack $ cryptoName crypto)
+ Reifies v Version => 
+ GroupParams crypto c =>
+ Key crypto => JSON.ToJSON crypto => Show crypto =>
+ Proxy v -> Proxy c -> TestTree
+quickcheckElection (_v::Proxy v) (c::Proxy c) =
+	testGroup (Text.unpack $ cryptoName (reflect c))
 	 [ testProperty "verifyBallot" $ \(seed, (elec::Election crypto v c) :> votes) ->
 		isRight $ runExcept $
 			(`evalStateT` mkStdGen seed) $ do
@@ -49,20 +49,15 @@
 					lift $ throwE $ ErrorBallot_Wrong
 	 ]
 
+{-
 instance Reifies c FFC => Arbitrary (F c) where
 	arbitrary = F <$> choose (zero, fromJust $ fieldCharac @c `minusNaturalMaybe` one)
-instance
- ( Reifies c crypto
- , Group crypto
- , Multiplicative (FieldElement crypto c)
- ) => Arbitrary (G crypto c) where
+-}
+instance GroupParams crypto c => Arbitrary (G crypto c) where
 	arbitrary = do
 		m <- arbitrary
 		return (groupGen ^ m)
-instance
- ( Reifies c crypto
- , Group crypto
- ) => Arbitrary (E crypto c) where
+instance GroupParams crypto c => Arbitrary (E crypto c) where
 	arbitrary = E <$> choose (zero, fromJust $ groupOrder @crypto (Proxy @c) `minusNaturalMaybe` one)
 instance Arbitrary UUID where
 	arbitrary = do
@@ -71,7 +66,7 @@
 			randomUUID
 instance
  ( Reifies v Version
- , Reifies c crypto
+ , GroupParams crypto c
  , Arbitrary (E crypto c)
  ) => Arbitrary (Proof crypto v c) where
 	arbitrary = do
@@ -95,12 +90,9 @@
 		]
 instance
  ( Reifies v Version
- , Reifies c crypto
- , Group crypto
+ , GroupParams crypto c
  , Key crypto
- , Multiplicative (FieldElement crypto c)
  , JSON.ToJSON crypto
- , JSON.ToJSON (FieldElement crypto c)
  ) => Arbitrary (Election crypto v c) where
 	arbitrary = do
 		let election_name = "election"
@@ -146,12 +138,9 @@
 		]
 instance
  ( Reifies v Version
- , Reifies c crypto
- , Group crypto
+ , GroupParams crypto c
  , Key crypto
  , JSON.ToJSON crypto
- , JSON.ToJSON (FieldElement crypto c)
- , Multiplicative (FieldElement crypto c)
  ) => Arbitrary (Election crypto v c :> [[Bool]]) where
 	arbitrary = do
 		elec@Election{..} <- arbitrary
diff --git a/tests/QuickCheck/Trustee.hs b/tests/QuickCheck/Trustee.hs
--- a/tests/QuickCheck/Trustee.hs
+++ b/tests/QuickCheck/Trustee.hs
@@ -15,18 +15,18 @@
 quickcheck v =
 	testGroup "Trustee" $
 	 [ testGroup "verifyIndispensableTrusteePublicKey" $
-		 [ testIndispensableTrusteePublicKey v weakFFC
-		 , testIndispensableTrusteePublicKey v beleniosFFC
+		 [ reify weakFFC $ testIndispensableTrusteePublicKey v
+		 , reify beleniosFFC $ testIndispensableTrusteePublicKey v
 		 ]
 	 ]
 
 testIndispensableTrusteePublicKey ::
- ReifyCrypto crypto =>
- Reifies v Version => Proxy v ->
- crypto -> TestTree
-testIndispensableTrusteePublicKey (_v::Proxy v) crypto =
-	reifyCrypto crypto $ \(Proxy::Proxy c) ->
-	testGroup (Text.unpack $ cryptoName crypto)
+ Reifies v Version =>
+ GroupParams crypto c =>
+ Key crypto =>
+ Proxy v -> Proxy c -> TestTree
+testIndispensableTrusteePublicKey (_v::Proxy v) (c::Proxy c) =
+	testGroup (Text.unpack $ cryptoName (reflect c))
 	 [ testProperty "Right" $ \seed ->
 		isRight $ runExcept $
 			(`evalStateT` mkStdGen seed) $ do
@@ -38,9 +38,7 @@
 
 instance
  ( Reifies v Version
- , Reifies c crypto
- , Group crypto
- , Multiplicative (FieldElement crypto c)
+ , GroupParams crypto c
  ) => Arbitrary (TrusteePublicKey crypto v c) where
 	arbitrary = do
 		trustee_PublicKey <- arbitrary
