module Group ( Group(..) ) where import Protolude import Control.Monad.Random (MonadRandom, Random, getRandom) import Test.Tasty.QuickCheck (Arbitrary) import Text.PrettyPrint.Leijen.Text (Pretty) ------------------------------------------------------------------------------- -- Types ------------------------------------------------------------------------------- -- | Groups. class (Arbitrary g, Eq g, Generic g, Monoid g, Pretty g, Random g, Show g) => Group g where {-# MINIMAL add, dbl, def, gen, id, inv, order #-} -- | Element addition. add :: g -> g -> g -- | Element doubling. dbl :: g -> g -- | Check well-defined. def :: g -> Bool -- | Group generator. gen :: g -- | Identity element. id :: g -- | Element inversion. inv :: g -> g -- | Element multiplication. mul' :: g -> Integer -> g mul' p n | n < 0 = inv (mul' p (-n)) | n == 0 = id | n == 1 = p | even n = p' | otherwise = add p p' where p' = mul' (dbl p) (div n 2) {-# INLINABLE mul' #-} -- | Curve order. order :: g -> Integer -- | Random element. rnd :: MonadRandom m => m g rnd = getRandom {-# INLINABLE rnd #-}