module Crypto.Lol.CRTrans
( CRTrans(..), CRTEmbed(..)
, CRTInfo
, crtInfoFact, crtInfoPPow, crtInfoPrime
, gEmbPPow, gEmbPrime
) where
import Crypto.Lol.LatticePrelude
import Control.Arrow
import Data.Singletons
import Data.Singletons.Prelude
type CRTInfo r = (Int -> r, r)
class Ring r => CRTrans r where
crtInfo :: Int -> Maybe (CRTInfo r)
crtInfo = const Nothing
class (Ring r, Ring (CRTExt r)) => CRTEmbed r where
type CRTExt r
toExt :: r -> CRTExt r
fromExt :: CRTExt r -> r
instance (CRTrans a, CRTrans b) => CRTrans (a,b) where
crtInfo i = do
(apow, aiInv) <- crtInfo i
(bpow, biInv) <- crtInfo i
return (apow &&& bpow, (aiInv, biInv))
instance (CRTEmbed a, CRTEmbed b) => CRTEmbed (a,b) where
type CRTExt (a,b) = (CRTExt a, CRTExt b)
toExt = toExt *** toExt
fromExt = fromExt *** fromExt
omegaPowC :: (Transcendental a) => Int -> Int -> Complex a
omegaPowC m i = cis (2*pi*fromIntegral i / fromIntegral m)
crtInfoFact :: (Fact m, CRTrans r) => TaggedT m Maybe (CRTInfo r)
crtInfoFact = (tagT . crtInfo) =<< pureT valueFact
crtInfoPPow :: (PPow pp, CRTrans r) => TaggedT pp Maybe (CRTInfo r)
crtInfoPPow = (tagT . crtInfo) =<< pureT valuePPow
crtInfoPrime :: (Prim p, CRTrans r) => TaggedT p Maybe (CRTInfo r)
crtInfoPrime = (tagT . crtInfo) =<< pureT valuePrime
gEmbPPow :: forall pp r . (PPow pp, CRTrans r) => TaggedT pp Maybe (Int -> r)
gEmbPPow = tagT $ case (sing :: SPrimePower pp) of
(SPP (STuple2 sp _)) -> withWitnessT gEmbPrime sp
gEmbPrime :: (Prim p, CRTrans r) => TaggedT p Maybe (Int -> r)
gEmbPrime = do
(f, _) <- crtInfoPrime
return $ \i -> one f i
instance (Transcendental a) => CRTrans (Complex a) where
crtInfo m = Just (omegaPowC m, recip $ fromIntegral $ valueHat m)
instance (Transcendental a) => CRTEmbed (Complex a) where
type CRTExt (Complex a) = Complex a
toExt = id
fromExt = id
instance CRTrans Double
instance CRTrans Int
instance CRTrans Int64
instance CRTrans Integer
instance CRTEmbed Double where
type CRTExt Double = Complex Double
toExt = fromReal . realToField
fromExt = realToField . real
instance CRTEmbed Int where
type CRTExt Int = Complex Double
toExt = fromIntegral
fromExt = fst . roundComplex
instance CRTEmbed Int64 where
type CRTExt Int64 = Complex Double
toExt = fromIntegral
fromExt = fst . roundComplex
instance CRTEmbed Integer where
type CRTExt Integer = Complex Double
toExt = fromIntegral
fromExt = fst . roundComplex