module Crypto.Lol.Cyclotomic.Cyc
(
Cyc, U.CElt, cyc, unsafeUnCyc
, mulG, divG
, scalarCyc, liftCyc
, advisePow, adviseDec, adviseCRT
, tGaussian, errorRounded, errorCoset
, embed, twace, powBasis, crtSet, coeffsCyc
, module Crypto.Lol.Cyclotomic.Utility
) where
import Algebra.Additive as Additive (C)
import Algebra.Ring as Ring (C)
import Crypto.Lol.Cyclotomic.UCyc (CElt, UCyc)
import qualified Crypto.Lol.Cyclotomic.UCyc as U
import Crypto.Lol.Cyclotomic.Utility
import Crypto.Lol.Gadget
import Crypto.Lol.LatticePrelude as LP
import Crypto.Lol.Types.ZPP
import Control.Applicative hiding ((*>))
import Control.DeepSeq
import Control.Monad.Random
import Data.Coerce
import Test.QuickCheck
newtype Cyc t m r = Cyc {
unsafeUnCyc :: UCyc t m r }
deriving (Arbitrary, Random)
deriving instance NFData (UCyc t m a) => NFData (Cyc t m a)
deriving instance Show (UCyc t m a) => Show (Cyc t m a)
deriving instance Eq (UCyc t m a) => Eq (Cyc t m a)
deriving instance Additive (UCyc t m a) => Additive.C (Cyc t m a)
deriving instance Ring (UCyc t m a) => Ring.C (Cyc t m a)
deriving instance Gadget gad (UCyc t m a) => Gadget gad (Cyc t m a)
deriving instance Correct gad (UCyc t m a) => Correct gad (Cyc t m a)
cyc :: UCyc t m r -> Cyc t m r
cyc = Cyc
type family O a where
O (Cyc t m a) = UCyc t m a
O (a -> b) = O a -> O b
O (m a) = m (O a)
O a = a
coerceCyc :: (Coercible (O a) a) => O a -> a
coerceCyc = coerce
instance (Reduce a b, Fact m, CElt t a, CElt t b)
=> Reduce (Cyc t m a) (Cyc t m b) where
reduce = coerceCyc reduce
instance (RescaleCyc (UCyc t) a b) => RescaleCyc (Cyc t) a b where
rescaleCyc = coerceCyc rescaleCyc
instance (Decompose gad (UCyc t m zq),
Reduce (Cyc t m (DecompOf zq)) (Cyc t m zq))
=> Decompose gad (Cyc t m zq) where
type DecompOf (Cyc t m zq) = Cyc t m (DecompOf zq)
decompose = coerceCyc decompose
adviseCRT, advisePow, adviseDec :: (Fact m, CElt t r) => Cyc t m r -> Cyc t m r
adviseCRT = coerceCyc U.adviseCRT
advisePow = coerceCyc U.forcePow
adviseDec = coerceCyc U.forceDec
mulG :: (Fact m, CElt t r) => Cyc t m r -> Cyc t m r
mulG = coerceCyc U.mulG
divG :: (Fact m, CElt t r) => Cyc t m r -> Maybe (Cyc t m r)
divG = coerceCyc U.divG
tGaussian :: (Fact m, OrdFloat q, Random q, CElt t q,
ToRational v, MonadRandom rnd)
=> v -> rnd (Cyc t m q)
tGaussian = (Cyc <$>) . U.tGaussian
errorRounded :: (ToInteger z, Fact m, CElt t z,
ToRational v, MonadRandom rnd)
=> v -> rnd (Cyc t m z)
errorRounded = (Cyc <$>) . U.errorRounded
errorCoset ::
(Mod zp, z ~ ModRep zp, Lift zp z, Fact m,
CElt t zp, CElt t z, ToRational v, MonadRandom rnd)
=> v -> Cyc t m zp -> rnd (Cyc t m z)
errorCoset v = (Cyc <$>) . U.errorCoset v . unsafeUnCyc
embed :: (m `Divides` m', CElt t r) => Cyc t m r -> Cyc t m' r
embed = coerceCyc U.embed
twace :: (m `Divides` m', CElt t r) => Cyc t m' r -> Cyc t m r
twace = coerceCyc U.twace
coeffsCyc :: (m `Divides` m', CElt t r)
=> Basis -> Cyc t m' r -> [Cyc t m r]
coeffsCyc = coerceCyc U.coeffsCyc
powBasis :: (m `Divides` m', CElt t r) => Tagged m [Cyc t m' r]
powBasis = coerceCyc U.powBasis
crtSet :: (m `Divides` m', ZPP r, CElt t r, CElt t (ZPOf r))
=> Tagged m [Cyc t m' r]
crtSet = coerceCyc U.crtSet
liftCyc :: (Lift b a, Fact m, CElt t a, CElt t b)
=> Basis -> Cyc t m b -> Cyc t m a
liftCyc = coerceCyc U.liftCyc
scalarCyc :: (Fact m, CElt t a) => a -> Cyc t m a
scalarCyc = Cyc . U.scalarCyc