module Crypto.Lol.Types.Unsafe.RRq
( RRq(..)
) where
import Algebra.Additive as Additive (C)
import Algebra.ZeroTestable as ZeroTestable (C)
import Control.DeepSeq
import Crypto.Lol.Prelude
import Crypto.Lol.Reflects
import Crypto.Lol.Types.Unsafe.ZqBasic hiding (ZqB)
newtype RRq q r = RRq' r
deriving (Eq, Ord, ZeroTestable.C, Show, NFData)
reduce' :: forall q r . (Reflects q r, RealField r) => r -> RRq q r
reduce' = let q = proxy value (Proxy::Proxy q)
in \x -> RRq' $ x q * floor (x / q)
decode' :: forall q r . (Reflects q r, Ord r, Ring r)
=> RRq q r -> r
decode' = let qval = proxy value (Proxy::Proxy q)
in \(RRq' x) -> if x + x < qval then x else x qval
instance (Reflects q r, RealField r, Additive (RRq q r))
=> Reduce r (RRq q r) where
reduce = reduce'
type instance LiftOf (RRq q r) = r
instance (Reflects q r, Reduce r (RRq q r), Ord r, Ring r)
=> Lift' (RRq q r) where
lift = decode'
instance (Reflects q r, RealField r, Ord r) => Additive.C (RRq q r) where
zero = RRq' zero
(+) = let qval = proxy value (Proxy::Proxy q)
in \ (RRq' x) (RRq' y) ->
let z = x + y
in RRq' (if z >= qval then z qval else z)
negate (RRq' x) = reduce' $ negate x
instance (ToInteger i, RealField r, Reflects q i, Reflects q r)
=> Subgroup (ZqBasic q i) (RRq q r) where
fromSubgroup = reduce' . fromIntegral . lift