module Crypto.Lol.RLWE.Continuous where
import Crypto.Lol.Cyclotomic.Cyc as C
import Crypto.Lol.Cyclotomic.Tensor (TElt)
import Crypto.Lol.Cyclotomic.UCyc as U
import Crypto.Lol.Prelude
import Control.Applicative
import Control.Monad.Random
type Sample t m zq rrq = (Cyc t m zq, UCyc t m D rrq)
type RLWECtx t m zq rrq =
(Fact m, Ring zq, CElt t zq, Subgroup zq rrq, Lift' rrq,
TElt t rrq, TElt t (LiftOf rrq))
sample :: forall rnd v t m zq rrq .
(RLWECtx t m zq rrq, Random zq, Random (LiftOf rrq), OrdFloat (LiftOf rrq),
MonadRandom rnd, ToRational v)
=> v -> Cyc t m zq -> rnd (Sample t m zq rrq)
sample svar s = let s' = adviseCRT s in do
a <- getRandom
e :: UCyc t m D (LiftOf rrq) <- U.tGaussian svar
let as = fmapDec fromSubgroup $ uncycDec $ a * s' :: UCyc t m D rrq
return (a, as + reduce e)
errorTerm :: (RLWECtx t m zq rrq)
=> Cyc t m zq -> Sample t m zq rrq -> UCyc t m D (LiftOf rrq)
errorTerm s = let s' = adviseCRT s
in \(a,b) -> lift $ b fmapDec fromSubgroup (uncycDec $ a * s')
errorGSqNorm :: (RLWECtx t m zq rrq, Ring (LiftOf rrq))
=> Cyc t m zq -> Sample t m zq rrq -> LiftOf rrq
errorGSqNorm s = U.gSqNorm . errorTerm s
errorBound :: (Ord v, Transcendental v, Fact m)
=> v
-> v
-> Tagged m v
errorBound v eps = do
n <- fromIntegral <$> totientFact
mhat <- fromIntegral <$> valueHatFact
let stabilize x =
let x' = (1/2 + log (2 * pi * x)/2 log eps/n)/pi
in if x'x < 0.0001 then x' else stabilize x'
return $ mhat * n * v * stabilize (1/(2*pi))