packages feed

lol 0.4.0.0 → 0.5.0.0

raw patch · 31 files changed

+992/−553 lines, 31 filesdep +ansi-terminaldep +statisticsdep −storable-recorddep ~containersPVP ok

version bump matches the API change (PVP)

Dependencies added: ansi-terminal, statistics

Dependencies removed: storable-record

Dependency ranges changed: containers

API changes (from Hackage documentation)

- Crypto.Lol.Cyclotomic.Tensor: fmapTM :: (Tensor t, Monad mon, Fact m, TElt t a, TElt t b) => (a -> mon b) -> t m a -> mon (t m b)
- Crypto.Lol.Cyclotomic.Tensor.CTensor: instance (GHC.Show.Show r, Foreign.Storable.Storable r) => GHC.Show.Show (Crypto.Lol.Cyclotomic.Tensor.CTensor.CT' m r)
- Crypto.Lol.Cyclotomic.UCyc: divG :: (Fact m, UCRTElt t r, ZeroTestable r, IntegralDomain r) => UCyc t m rep r -> Maybe (UCyc t m rep r)
- Crypto.Lol.Cyclotomic.UCyc: instance (System.Random.Random r, Crypto.Lol.Cyclotomic.UCyc.UCRTElt t r, Crypto.Lol.FactoredDefs.Fact m) => System.Random.Random (Data.Either.Either (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.P r) (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.C r))
- Crypto.Lol.Factored: oddRadicalPPs :: [PP] -> Int
- Crypto.Lol.Factored: radicalPPs :: [PP] -> Int
- Crypto.Lol.Factored: totientPPs :: [PP] -> Int
- Crypto.Lol.Factored: valuePPs :: [PP] -> Int
- Crypto.Lol.Prelude: instance forall k (m :: * -> *) (tag :: k). Control.Monad.Random.Class.MonadRandom m => Control.Monad.Random.Class.MonadRandom (Data.Functor.Trans.Tagged.TaggedT tag m)
- Crypto.Lol.Prelude: instance forall k1 (m :: k1 -> *) (a :: k1) k (s :: k). Control.DeepSeq.NFData (m a) => Control.DeepSeq.NFData (Data.Functor.Trans.Tagged.TaggedT s m a)
- Crypto.Lol.Types.FiniteField: instance forall fp k (d :: k). (GHC.Classes.Eq fp, Algebra.ZeroTestable.C fp) => GHC.Classes.Eq (Crypto.Lol.Types.FiniteField.GF fp d)
- Crypto.Lol.Types.ZqBasic: instance forall k k1 (p :: k) z (q :: k1). (Crypto.Lol.Reflects.Reflects p z, Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z, Crypto.Lol.Types.Numeric.Field (Crypto.Lol.Types.ZqBasic.ZqBasic q z), Crypto.Lol.Types.Numeric.Field (Crypto.Lol.Types.ZqBasic.ZqBasic p z)) => Crypto.Lol.Prelude.Encode (Crypto.Lol.Types.ZqBasic.ZqBasic p z) (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall k k1 (q :: k) z (q' :: k1). (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z, Crypto.Lol.Reflects.Reflects q' z, Crypto.Lol.Types.Numeric.Ring z) => Crypto.Lol.Prelude.Rescale (Crypto.Lol.Types.ZqBasic.ZqBasic q z) (Crypto.Lol.Types.ZqBasic.ZqBasic q' z)
+ Crypto.Lol.Cyclotomic.Tensor.CTensor: instance (Foreign.Storable.Storable r, GHC.Show.Show r) => GHC.Show.Show (Crypto.Lol.Cyclotomic.Tensor.CTensor.CT' m r)
+ Crypto.Lol.Cyclotomic.UCyc: divGCRTC :: (Fact m, UCRTElt t r) => UCyc t m C r -> UCyc t m C r
+ Crypto.Lol.Cyclotomic.UCyc: divGDec :: (Fact m, UCRTElt t r, ZeroTestable r, IntegralDomain r) => UCyc t m D r -> Maybe (UCyc t m D r)
+ Crypto.Lol.Cyclotomic.UCyc: divGPow :: (Fact m, UCRTElt t r, ZeroTestable r, IntegralDomain r) => UCyc t m P r -> Maybe (UCyc t m P r)
+ Crypto.Lol.Cyclotomic.UCyc: instance (System.Random.Random r, Crypto.Lol.Cyclotomic.UCyc.UCRTElt t r, Crypto.Lol.FactoredDefs.Fact m) => System.Random.Random (Crypto.Lol.Cyclotomic.UCyc.UCycPC t m r)
+ Crypto.Lol.Cyclotomic.UCyc: type UCycPC t m r = Either (UCyc t m P r) (UCyc t m C r)
+ Crypto.Lol.Factored: intToBin :: C z => z -> Bin
+ Crypto.Lol.Factored: intToFact :: Int -> Factored
+ Crypto.Lol.Factored: intToPos :: C z => z -> Pos
+ Crypto.Lol.Factored: oddRadicalF :: Factored -> Int
+ Crypto.Lol.Factored: oddRadicalPPow :: PPow pp => Tagged pp Int
+ Crypto.Lol.Factored: radicalF :: Factored -> Int
+ Crypto.Lol.Factored: radicalPPow :: PPow pp => Tagged pp Int
+ Crypto.Lol.Factored: totientF :: Factored -> Int
+ Crypto.Lol.Factored: valueF :: Factored -> Int
+ Crypto.Lol.Factored: valueHatF :: Factored -> Int
+ Crypto.Lol.Factored: valueHatPP :: PP -> Int
+ Crypto.Lol.Factored: valueHatPPow :: PPow pp => Tagged pp Int
+ Crypto.Lol.Factored: valueP :: PrimeBin -> Int
+ Crypto.Lol.Prelude: instance forall k (tag :: k) (m :: * -> *). Control.Monad.Random.Class.MonadRandom m => Control.Monad.Random.Class.MonadRandom (Data.Functor.Trans.Tagged.TaggedT tag m)
+ Crypto.Lol.Prelude: instance forall k1 (s :: k1) k (m :: k -> *) (a :: k). Control.DeepSeq.NFData (m a) => Control.DeepSeq.NFData (Data.Functor.Trans.Tagged.TaggedT s m a)
+ Crypto.Lol.Types.FiniteField: instance forall fp k (d :: k). (Algebra.ZeroTestable.C fp, GHC.Classes.Eq fp) => GHC.Classes.Eq (Crypto.Lol.Types.FiniteField.GF fp d)
+ Crypto.Lol.Types.FiniteField: instance forall k fp (d :: k). (System.Random.Random fp, Crypto.Lol.Reflects.Reflects d GHC.Types.Int) => System.Random.Random (Crypto.Lol.Types.FiniteField.GF fp d)
+ Crypto.Lol.Types.ZqBasic: goodQs :: (IntegralDomain a, ToInteger a) => a -> a -> [a]
+ Crypto.Lol.Types.ZqBasic: instance forall k k1 (p :: k1) z (q :: k). (Crypto.Lol.Reflects.Reflects p z, Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z, Crypto.Lol.Types.Numeric.Field (Crypto.Lol.Types.ZqBasic.ZqBasic q z), Crypto.Lol.Types.Numeric.Field (Crypto.Lol.Types.ZqBasic.ZqBasic p z)) => Crypto.Lol.Prelude.Encode (Crypto.Lol.Types.ZqBasic.ZqBasic p z) (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.Types.ZqBasic: instance forall k k1 (q :: k1) z (q' :: k). (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z, Crypto.Lol.Reflects.Reflects q' z, Crypto.Lol.Types.Numeric.Ring z) => Crypto.Lol.Prelude.Rescale (Crypto.Lol.Types.ZqBasic.ZqBasic q z) (Crypto.Lol.Types.ZqBasic.ZqBasic q' z)
- Crypto.Lol.Cyclotomic.Cyc: twace :: forall t m m' r. (m `Divides` m', CElt t r) => Cyc t m' r -> Cyc t m r
+ Crypto.Lol.Cyclotomic.Cyc: twace :: forall t m m' r. (m `Divides` m', UCRTElt t r, ZeroTestable r) => Cyc t m' r -> Cyc t m r
- Crypto.Lol.Cyclotomic.UCyc: twaceCRTC :: (m `Divides` m', UCRTElt t r) => UCyc t m' C r -> Either (UCyc t m P r) (UCyc t m C r)
+ Crypto.Lol.Cyclotomic.UCyc: twaceCRTC :: (m `Divides` m', UCRTElt t r) => UCyc t m' C r -> UCycPC t m r
- Crypto.Lol.Factored: data AddPosSym0 (l_amwl :: TyFun Pos (TyFun Pos Pos -> Type))
+ Crypto.Lol.Factored: data AddPosSym0 (l_aIr0 :: TyFun Pos (TyFun Pos Pos -> Type))
- Crypto.Lol.Factored: data AddPosSym1 (l_amwo :: Pos) (l_amwn :: TyFun Pos Pos)
+ Crypto.Lol.Factored: data AddPosSym1 (l_aIr3 :: Pos) (l_aIr2 :: TyFun Pos Pos)
- Crypto.Lol.Factored: data D0Sym0 (l_ao1G :: TyFun Bin Bin)
+ Crypto.Lol.Factored: data D0Sym0 (l_aJjC :: TyFun Bin Bin)
- Crypto.Lol.Factored: data D1Sym0 (l_ao1J :: TyFun Bin Bin)
+ Crypto.Lol.Factored: data D1Sym0 (l_aJjF :: TyFun Bin Bin)
- Crypto.Lol.Factored: data SSym0 (l_amw2 :: TyFun Pos Pos)
+ Crypto.Lol.Factored: data SSym0 (l_aIqH :: TyFun Pos Pos)
- Crypto.Lol.Factored: data SubPosSym0 (l_amw6 :: TyFun Pos (TyFun Pos Pos -> Type))
+ Crypto.Lol.Factored: data SubPosSym0 (l_aIqL :: TyFun Pos (TyFun Pos Pos -> Type))
- Crypto.Lol.Factored: data SubPosSym1 (l_amw9 :: Pos) (l_amw8 :: TyFun Pos Pos)
+ Crypto.Lol.Factored: data SubPosSym1 (l_aIqO :: Pos) (l_aIqN :: TyFun Pos Pos)
- Crypto.Lol.Factored: sAddPos :: forall (t_amAr :: Pos) (t_amAs :: Pos). Sing t_amAr -> Sing t_amAs -> Sing (Apply (Apply AddPosSym0 t_amAr) t_amAs :: Pos)
+ Crypto.Lol.Factored: sAddPos :: forall (t_aICB :: Pos) (t_aICC :: Pos). Sing t_aICB -> Sing t_aICC -> Sing (Apply (Apply AddPosSym0 t_aICB) t_aICC :: Pos)
- Crypto.Lol.Factored: sPToF :: forall (t_a1Dj0 :: PrimeBin). Sing t_a1Dj0 -> Sing (Apply PToFSym0 t_a1Dj0 :: Factored)
+ Crypto.Lol.Factored: sPToF :: forall (t_aZ2M :: PrimeBin). Sing t_aZ2M -> Sing (Apply PToFSym0 t_aZ2M :: Factored)
- Crypto.Lol.Factored: sPToPP :: forall (t_a1DiZ :: PrimeBin). Sing t_a1DiZ -> Sing (Apply PToPPSym0 t_a1DiZ :: PrimePower)
+ Crypto.Lol.Factored: sPToPP :: forall (t_aZ2L :: PrimeBin). Sing t_aZ2L -> Sing (Apply PToPPSym0 t_aZ2L :: PrimePower)
- Crypto.Lol.Factored: sPpToF :: forall (t_a1DiY :: PrimePower). Sing t_a1DiY -> Sing (Apply PpToFSym0 t_a1DiY :: Factored)
+ Crypto.Lol.Factored: sPpToF :: forall (t_aZ2K :: PrimePower). Sing t_aZ2K -> Sing (Apply PpToFSym0 t_aZ2K :: Factored)
- Crypto.Lol.Factored: sSubPos :: forall (t_amAp :: Pos) (t_amAq :: Pos). Sing t_amAp -> Sing t_amAq -> Sing (Apply (Apply SubPosSym0 t_amAp) t_amAq :: Pos)
+ Crypto.Lol.Factored: sSubPos :: forall (t_aICz :: Pos) (t_aICA :: Pos). Sing t_aICz -> Sing t_aICA -> Sing (Apply (Apply SubPosSym0 t_aICz) t_aICA :: Pos)
- Crypto.Lol.Factored: sUnF :: forall (t_a1Au7 :: Factored). Sing t_a1Au7 -> Sing (Apply UnFSym0 t_a1Au7 :: [PrimePower])
+ Crypto.Lol.Factored: sUnF :: forall (t_aWeT :: Factored). Sing t_aWeT -> Sing (Apply UnFSym0 t_aWeT :: [PrimePower])
- Crypto.Lol.Factored: sUnPP :: forall (t_a1Au8 :: PrimePower). Sing t_a1Au8 -> Sing (Apply UnPPSym0 t_a1Au8 :: (PrimeBin, Pos))
+ Crypto.Lol.Factored: sUnPP :: forall (t_aWeU :: PrimePower). Sing t_aWeU -> Sing (Apply UnPPSym0 t_aWeU :: (PrimeBin, Pos))
- Crypto.Lol.Factored: type D0Sym1 (t_ao1F :: Bin) = D0 t_ao1F
+ Crypto.Lol.Factored: type D0Sym1 (t_aJjB :: Bin) = D0 t_aJjB
- Crypto.Lol.Factored: type D1Sym1 (t_ao1I :: Bin) = D1 t_ao1I
+ Crypto.Lol.Factored: type D1Sym1 (t_aJjE :: Bin) = D1 t_aJjE
- Crypto.Lol.Factored: type SSym1 (t_amw1 :: Pos) = S t_amw1
+ Crypto.Lol.Factored: type SSym1 (t_aIqG :: Pos) = S t_aIqG
- Crypto.Lol.RLWE.Discrete: errorGSqNorm :: (RLWECtx t m zq, Ring (LiftOf zq)) => Cyc t m zq -> Sample t m zq -> LiftOf zq
+ Crypto.Lol.RLWE.Discrete: errorGSqNorm :: (RLWECtx t m zq) => Cyc t m zq -> Sample t m zq -> LiftOf zq
- Crypto.Proto.RLWE.Kq: Kq :: !(Word32) -> !(Double) -> !(Seq Double) -> Kq
+ Crypto.Proto.RLWE.Kq: Kq :: !(Word32) -> !(Word64) -> !(Seq Double) -> Kq
- Crypto.Proto.RLWE.Kq: [q] :: Kq -> !(Double)
+ Crypto.Proto.RLWE.Kq: [q] :: Kq -> !(Word64)

Files

Crypto/Lol/Cyclotomic/CRTSentinel.hs view
@@ -73,5 +73,5 @@ twaceCRTCS :: (Tensor t, m `Divides` m', CRTrans Maybe r, TElt t r)               => CSentinel t m' r -> CSentinel t m r -> t m' r -> t m r twaceCRTCS _ _ = fromJust twaceCRT-{-# INLINABLE twaceCRTCS #-}+{-# INLINE twaceCRTCS #-} 
Crypto/Lol/Cyclotomic/Cyc.hs view
@@ -59,8 +59,8 @@ import qualified Algebra.ZeroTestable as ZeroTestable (C)  import Crypto.Lol.Cyclotomic.UCyc hiding (coeffsDec, coeffsPow, crtSet,-                                   divG, errorCoset, errorRounded, gSqNorm,-                                   mulG, powBasis, tGaussian)+                                   errorCoset, errorRounded, gSqNorm, mulG,+                                   powBasis, tGaussian)  import           Crypto.Lol.CRTrans import qualified Crypto.Lol.Cyclotomic.RescaleCyc as R@@ -332,9 +332,10 @@ divG :: (Fact m, CElt t r, IntegralDomain r)         => Cyc t m r -> Maybe (Cyc t m r) {-# INLINABLE divG #-}-divG (Pow u) = Pow <$> U.divG u-divG (Dec u) = Dec <$> U.divG u-divG (CRT u) = CRT <$> either (fmap Left . U.divG) (fmap Right . U.divG) u+divG (Pow u) = Pow <$> U.divGPow u+divG (Dec u) = Dec <$> U.divGDec u+divG (CRT (Left u)) = Pow <$> U.divGPow (U.toPow u)+divG (CRT (Right u)) = Just $ (CRT . Right) $ U.divGCRTC u divG c@(Scalar _) = divG $ toCRT' c divG (Sub c) = divG $ embed' c  -- must go to full ring @@ -401,7 +402,7 @@ -- | The "tweaked trace" (twace) function -- \(\Tw(x) = (\hat{m} / \hat{m}') \cdot \Tr((g' / g) \cdot x)\), -- which fixes \(R\) pointwise (i.e., @twace . embed == id@).-twace :: forall t m m' r . (m `Divides` m', CElt t r)+twace :: forall t m m' r . (m `Divides` m', UCRTElt t r, ZeroTestable r)          => Cyc t m' r -> Cyc t m r {-# INLINABLE twace #-} twace (Pow u) = Pow $ U.twacePow u@@ -561,10 +562,10 @@  ---------- Change of representation (internal use only) ---------- -toPow', toDec', toCRT' :: (Fact m, CElt t r) => Cyc t m r -> Cyc t m r-{-# INLINE toPow' #-}-{-# INLINE toDec' #-}-{-# INLINE toCRT' #-}+toPow', toDec', toCRT' :: (Fact m, UCRTElt t r, ZeroTestable r) => Cyc t m r -> Cyc t m r+{-# INLINABLE toPow' #-}+{-# INLINABLE toDec' #-}+{-# INLINABLE toCRT' #-}  -- | Force to powerful-basis representation (for internal use only). toPow' c@(Pow _) = c
Crypto/Lol/Cyclotomic/Tensor.hs view
@@ -174,9 +174,6 @@    -- | Potentially optimized version of 'fmap' for types that satisfy 'TElt'.   fmapT :: (Fact m, TElt t a, TElt t b) => (a -> b) -> t m a -> t m b-  -- | Potentially optimized monadic 'fmap'.-  fmapTM :: (Monad mon, Fact m, TElt t a, TElt t b)-             => (a -> mon b) -> t m a -> mon (t m b)    -- | Potentially optimized zipWith for types that satisfy 'TElt'.   zipWithT :: (Fact m, TElt t a, TElt t b, TElt t c)@@ -186,12 +183,6 @@   unzipT :: (Fact m, TElt t (a,b), TElt t a, TElt t b)             => t m (a,b) -> (t m a, t m b) -  {- CJP: suppressed, apparently not needed--  -- | Unzip for arbitrary types.-  unzipTUnrestricted :: (Fact m) => t m (a,b) -> (t m a, t m b)-  -}- -- | Convenience value indicating whether 'crtFuncs' exists. hasCRTFuncs :: forall t m mon r . (CRTrans mon r, Tensor t, Fact m, TElt t r)                => TaggedT (t m r) mon ()@@ -211,7 +202,7 @@ {-# INLINABLE mulGCRT #-} {-# INLINABLE divGCRT #-} {-# INLINABLE crt #-}-{-# INLINABLE crtInv #-}+{-# INLINE crtInv #-}  -- | Multiply by \(g_m\) in the CRT basis. (This function is simply an -- appropriate entry from 'crtFuncs'.)@@ -232,6 +223,7 @@ -- (This function is simply an appropriate entry from 'crtExtFuncs'.) twaceCRT :: forall t m m' mon r . (CRTrans mon r, Tensor t, m `Divides` m', TElt t r)             => mon (t m' r -> t m r)+{-# INLINABLE twaceCRT #-} twaceCRT = proxyT hasCRTFuncs (Proxy::Proxy (t m' r)) *>            proxyT hasCRTFuncs (Proxy::Proxy (t m  r)) *>            (fst <$> crtExtFuncs)@@ -413,8 +405,8 @@ indexInfo = let pps = proxy ppsFact (Proxy::Proxy m)                 pps' = proxy ppsFact (Proxy::Proxy m')                 mpps = mergePPs pps pps'-                phi = totientPPs pps-                phi' = totientPPs pps'+                phi = proxy totientFact (Proxy::Proxy m)+                phi' = proxy totientFact (Proxy::Proxy m')                 tots = totients mpps             in tag (mpps, phi, phi', tots) @@ -422,6 +414,7 @@ -- the index into the powerful\/decoding basis of \(\O_{m'}\) of the -- \(i\)th entry of the powerful/decoding basis of \(\O_m\). extIndicesPowDec :: (m `Divides` m') => Tagged '(m, m') (U.Vector Int)+{-# INLINABLE extIndicesPowDec #-} extIndicesPowDec = do   (_, phi, _, tots) <- indexInfo   return $ U.generate phi (fromIndexPair tots . (0,))@@ -447,15 +440,15 @@ -- | A lookup table for 'toIndexPair' applied to indices \([\varphi(m')]\). baseIndicesPow :: forall m m' . (m `Divides` m')                   => Tagged '(m, m') (U.Vector (Int,Int))+{-# INLINABLE baseIndicesPow #-} -- | A lookup table for 'baseIndexDec' applied to indices \([\varphi(m')]\). baseIndicesDec :: forall m m' . (m `Divides` m')                   => Tagged '(m, m') (U.Vector (Maybe (Int,Bool)))-+{-# INLINABLE baseIndicesDec #-} -- | Same as 'baseIndicesPow', but only includes the second component -- of each pair. baseIndicesCRT :: forall m m' . (m `Divides` m')                   => Tagged '(m, m') (U.Vector Int)- baseIndicesPow = baseWrapper (toIndexPair . totients)  -- this one is more complicated; requires the prime powers
Crypto/Lol/Cyclotomic/Tensor/CTensor.hs view
@@ -21,8 +21,7 @@  -- | Wrapper for a C++ implementation of the 'Tensor' interface. -module Crypto.Lol.Cyclotomic.Tensor.CTensor-( CT ) where+module Crypto.Lol.Cyclotomic.Tensor.CTensor (CT) where  import Algebra.Additive     as Additive (C) import Algebra.Module       as Module (C)@@ -43,10 +42,10 @@ import Data.Traversable             as T import Data.Vector.Generic          as V (fromList, toList, unzip) import Data.Vector.Storable         as SV (Vector, convert, foldl',-                                           foldl1', fromList, generate,-                                           length, map, mapM, replicate,+                                           fromList, generate,+                                           length, map, replicate,                                            replicateM, thaw, thaw, toList,-                                           unsafeFreeze, unsafeSlice,+                                           unsafeFreeze,                                            unsafeWith, zipWith, (!)) import Data.Vector.Storable.Mutable as SM hiding (replicate) @@ -128,13 +127,13 @@    toProto (CT (CT' xs)) =     let m = fromIntegral $ proxy valueFact (Proxy::Proxy m)-        q = proxy value (Proxy::Proxy q) :: Double+        q = round (proxy value (Proxy::Proxy q) :: Double)     in Kq m q $ S.fromList $ SV.toList $ SV.map LP.lift xs   toProto x@(ZV _) = toProto $ toCT x    fromProto (Kq m' q' xs) =     let m = proxy valueFact (Proxy::Proxy m) :: Int-        q = proxy value (Proxy::Proxy q) :: Double+        q = round (proxy value (Proxy::Proxy q) :: Double)         n = proxy totientFact (Proxy::Proxy m)         xs' = SV.fromList $ F.toList xs         len = F.length xs@@ -144,7 +143,7 @@             "An error occurred while reading the proto type for CT.\n\             \Expected m=" ++ show m ++ ", got " ++ show m' ++ "\n\             \Expected n=" ++ show n ++ ", got " ++ show len ++ "\n\-            \Expected q=" ++ show (round q :: Int64) ++ ", got " ++ show q' ++ "."+            \Expected q=" ++ show q ++ ", got " ++ show q' ++ "."  toCT :: (Storable r) => CT m r -> CT m r toCT v@(CT _) = v@@ -158,12 +157,14 @@ zvToCT' :: forall m r . (Storable r) => IZipVector m r -> CT' m r zvToCT' v = coerce (convert $ unIZipVector v :: Vector r) -wrap :: (Storable r) => (CT' l r -> CT' m r) -> (CT l r -> CT m r)+wrap :: (Storable s, Storable r) => (CT' l s -> CT' m r) -> (CT l s -> CT m r)+{-# INLINABLE wrap #-} wrap f (CT v) = CT $ f v wrap f (ZV v) = CT $ f $ zvToCT' v -wrapM :: (Storable r, Monad mon) => (CT' l r -> mon (CT' m r))-         -> (CT l r -> mon (CT m r))+wrapM :: (Storable s, Storable r, Monad mon) => (CT' l s -> mon (CT' m r))+         -> (CT l s -> mon (CT m r))+{-# INLINABLE wrapM #-} wrapM f (CT v) = CT <$> f v wrapM f (ZV v) = CT <$> f (zvToCT' v) @@ -247,15 +248,14 @@    scalarPow = CT . scalarPow' -- Vector code -  l = wrap $ untag $ basicDispatch dl-  lInv = wrap $ untag $ basicDispatch dlinv+  l = wrap $ basicDispatch dl+  lInv = wrap $ basicDispatch dlinv -  mulGPow = wrap mulGPow'-  mulGDec = wrap $ untag $ basicDispatch dmulgdec+  mulGPow = wrap $ basicDispatch dmulgpow+  mulGDec = wrap $ basicDispatch dmulgdec -  divGPow = wrapM divGPow'-  -- we divide by p in the C code (for divGDec only(?)), do NOT call checkDiv!-  divGDec = wrapM $ Just . untag (basicDispatch dginvdec)+  divGPow = wrapM $ dispatchGInv dginvpow+  divGDec = wrapM $ dispatchGInv dginvdec    crtFuncs = (,,,,) <$>     return (CT . repl) <*>@@ -284,17 +284,16 @@    crtSetDec = (CT <$>) <$> coerceBasis crtSetDec' -  fmapT f (CT v) = CT $ coerce (SV.map f) v-  fmapT f v@(ZV _) = fmapT f $ toCT v--  fmapTM f (CT (CT' v)) = (CT . CT') <$> SV.mapM f v-  fmapTM f v@(ZV _) = fmapTM f $ toCT v+  fmapT f = wrap $ coerce (SV.map f) -  zipWithT f (CT (CT' v1)) (CT (CT' v2)) = CT $ CT' $ SV.zipWith f v1 v2-  zipWithT f v1 v2 = zipWithT f (toCT v1) (toCT v2)+  zipWithT f v1' v2' =+    let (CT (CT' v1)) = toCT v1'+        (CT (CT' v2)) = toCT v2'+    in CT $ CT' $ SV.zipWith f v1 v2 -  unzipT (CT (CT' v)) = (CT . CT') *** (CT . CT') $ unzip v-  unzipT v = unzipT $ toCT v+  unzipT v =+    let (CT (CT' x)) = toCT v+    in (CT . CT') *** (CT . CT') $ unzip x    {-# INLINABLE entailIndexT #-}   {-# INLINABLE entailEqT #-}@@ -315,15 +314,13 @@   {-# INLINABLE embedDec #-}   {-# INLINABLE tGaussianDec #-}   {-# INLINABLE gSqNormDec #-}-  {-# INLINABLE crtExtFuncs #-}+  {-# INLINE crtExtFuncs #-}   {-# INLINABLE coeffs #-}   {-# INLINABLE powBasisPow #-}   {-# INLINABLE crtSetDec #-}   {-# INLINABLE fmapT #-}-  {-# INLINABLE fmapTM #-}-  {-# INLINABLE zipWithT #-}-  {-# INLINABLE unzipT #-}-+  {-# INLINE zipWithT #-}+  {-# INLINE unzipT #-}  coerceTw :: (Functor mon) => TaggedT '(m, m') mon (Vector r -> Vector r) -> mon (CT' m' r -> CT' m r) coerceTw = (coerce <$>) . untagT@@ -341,12 +338,21 @@ coerceBasis :: Tagged '(m,m') [Vector r] -> Tagged m [CT' m' r] coerceBasis = coerce -mulGPow' :: (TElt CT r, Fact m) => CT' m r -> CT' m r-mulGPow' = untag $ basicDispatch dmulgpow--divGPow' :: (TElt CT r, Fact m, IntegralDomain r, ZeroTestable r)-            => CT' m r -> Maybe (CT' m r)-divGPow' = untag $ checkDiv $ basicDispatch dginvpow+dispatchGInv :: forall m r . (Storable r, Fact m)+             => (Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO Int16)+                 -> CT' m r -> Maybe (CT' m r)+dispatchGInv f =+  let factors = proxy (marshalFactors <$> ppsFact) (Proxy::Proxy m)+      totm = proxy (fromIntegral <$> totientFact) (Proxy::Proxy m)+      numFacts = fromIntegral $ SV.length factors+  in \(CT' x) -> unsafePerformIO $ do+    yout <- SV.thaw x+    ret <- SM.unsafeWith yout (\pout ->+             SV.unsafeWith factors (\pfac ->+               f pout totm pfac numFacts))+    if ret /= 0+    then Just . CT' <$> unsafeFreeze yout+    else return Nothing  withBasicArgs :: forall m r . (Fact m, Storable r)   => (Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO ())@@ -364,8 +370,8 @@  basicDispatch :: (Storable r, Fact m)                  => (Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO ())-                     -> Tagged m (CT' m r -> CT' m r)-basicDispatch f = return $ unsafePerformIO . withBasicArgs f+                     -> CT' m r -> CT' m r+basicDispatch f = unsafePerformIO . withBasicArgs f  gSqNormDec' :: (Storable r, Fact m, Dispatch r)                => Tagged m (CT' m r -> r)@@ -387,19 +393,6 @@   return $ \x -> unsafePerformIO $     withPtrArray ruinv' (\ruptr -> with mhatInv (flip withBasicArgs x . dcrtinv ruptr)) -checkDiv :: (Storable r, IntegralDomain r, ZeroTestable r, Fact m)-    => Tagged m (CT' m r -> CT' m r) -> Tagged m (CT' m r -> Maybe (CT' m r))-checkDiv f = do-  f' <- f-  oddRad' <- fromIntegral <$> oddRadicalFact-  return $ \x ->-    let (CT' y) = f' x-    in CT' <$> SV.mapM (`divIfDivis` oddRad') y--divIfDivis :: (IntegralDomain r, ZeroTestable r) => r -> r -> Maybe r-divIfDivis num den = let (q,r) = num `divMod` den-                     in if isZero r then Just q else Nothing- cZipDispatch :: (Storable r, Fact m)   => (Ptr r -> Ptr r -> Int64 -> IO ())      -> Tagged m (CT' m r -> CT' m r -> CT' m r)@@ -418,7 +411,8 @@          => var -> rnd (CT' m r) cDispatchGaussian var = flip proxyT (Proxy::Proxy m) $ do -- in TaggedT m rnd   -- get rus for (Complex r)-  ruinv' <- mapTaggedT (return . fromMaybe (error "complexGaussianRoots")) ruInv+  -- takes ru (not ruInv) to match RT+  ruinv' <- mapTaggedT (return . fromMaybe (error "complexGaussianRoots")) ru   totm <- pureT totientFact   m <- pureT valueFact   rad <- pureT radicalFact@@ -497,25 +491,3 @@                  => mon (CT' m r) gCRT = wrapVector gCRTK gInvCRT = wrapVector gInvCRTK---- we can't put this in Extension with the rest of the twace/embed--- functions because it needs access to the C backend-twaceCRT' :: forall mon m m' r .-             (TElt CT r, CRTrans mon r, m `Divides` m')-             => TaggedT '(m, m') mon (Vector r -> Vector r)-twaceCRT' = tagT $ do-  (CT' g') :: CT' m' r <- gCRT-  (CT' gInv) :: CT' m r <- gInvCRT-  embed <- proxyT embedCRT' (Proxy::Proxy '(m,m'))-  indices <- pure $ proxy extIndicesCRT (Proxy::Proxy '(m,m'))-  (_, m'hatinv) <- proxyT crtInfo (Proxy::Proxy m')-  let phi = proxy totientFact (Proxy::Proxy m)-      phi' = proxy totientFact (Proxy::Proxy m')-      mhat = fromIntegral $ proxy valueHatFact (Proxy::Proxy m)-      hatRatioInv = m'hatinv * mhat-      reltot = phi' `div` phi-      -- tweak = mhat * g' / (m'hat * g)-      tweak = SV.map (* hatRatioInv) $ SV.zipWith (*) (embed gInv) g'-  return $ \ arr -> -- take true trace after mul-by-tweak-    let v = backpermute' indices (SV.zipWith (*) tweak arr)-    in generate phi $ \i -> foldl1' (+) $ SV.unsafeSlice (i*reltot) reltot v
Crypto/Lol/Cyclotomic/Tensor/CTensor/Backend.hs view
@@ -31,10 +31,8 @@ , withArray, withPtrArray ) where -import Control.Applicative- import Crypto.Lol.Prelude       as LP (Complex, PP, Proxy (..), Tagged,-                                       map, mapM_, proxy, tag, (++))+                                       map, mapM_, proxy, tag) import Crypto.Lol.Reflects import Crypto.Lol.Types.RRq import Crypto.Lol.Types.ZqBasic@@ -49,7 +47,6 @@ import           Foreign.Marshal.Utils   (with) import           Foreign.Ptr             (Ptr, castPtr, plusPtr) import           Foreign.Storable        (Storable (..))-import qualified Foreign.Storable.Record as Store  #if __GLASGOW_HASKELL__ >= 800 import GHC.TypeLits -- for error message@@ -57,7 +54,7 @@  -- | Convert a list of prime powers to a suitable C representation. marshalFactors :: [PP] -> Vector CPP-marshalFactors = SV.fromList . LP.map (\(p,e) -> CPP (fromIntegral p) (fromIntegral e))+marshalFactors = SV.fromList . LP.map (\(p,e) -> (fromIntegral p, fromIntegral e))  -- http://stackoverflow.com/questions/6517387/vector-vector-foo-ptr-ptr-foo-io-a-io-a -- | Evaluates a C function that takes an "a** ptr" on a list of Vectors.@@ -69,24 +66,9 @@   LP.mapM_ (\(fp,_) -> touchForeignPtr fp) vs   return res +-- Note: These types need to be the same, otherwise something goes wrong on the C end... -- | C representation of a prime power.-data CPP = CPP {p' :: !Int32, e' :: !Int16}--- stolen from http://hackage.haskell.org/packages/archive/numeric-prelude/0.4.0.3/doc/html/src/Number-Complex.html#T--- the NumericPrelude Storable instance for complex numbers-instance Storable CPP where-   sizeOf    = Store.sizeOf store-   alignment = Store.alignment store-   peek      = Store.peek store-   poke      = Store.poke store--store :: Store.Dictionary CPP-store = Store.run $-   liftA2 CPP-      (Store.element p')-      (Store.element e')--instance Show CPP where-    show (CPP p e) = "(" LP.++ show p LP.++ "," LP.++ show e LP.++ ")"+type CPP = (Int16, Int16)  instance (Storable a, Storable b)   => Storable (a,b) where@@ -100,10 +82,6 @@     poke (castPtr p :: Ptr a) a     poke (castPtr (plusPtr p (sizeOf a)) :: Ptr b) b ---- data ZqB64D -- for type safety purposes data ComplexD data DoubleD@@ -118,7 +96,7 @@   CTypeOf (Complex Double) = ComplexD   CTypeOf (RRq (q :: k) Double) = RRqD #if __GLASGOW_HASKELL__ >= 800-  -- EAC: this doesn't display like I had hoped when there is a tuple involved...+  -- EAC: See #12237 and #11990   CTypeOf (ZqBasic (q :: k) i) = TypeError (Text "Unsupported C type: " :<>: ShowType (ZqBasic q i) :$$: Text "Use Int64 as the base ring")   CTypeOf (Complex i) = TypeError (Text "Unsupported C type: " :<>: ShowType (Complex i) :$$: Text "Use Double as the base ring")   CTypeOf (RRq (q :: k) i) = TypeError (Text "Unsupported C type: " :<>: ShowType (RRq q i) :$$: Text "Use Double as the base ring")@@ -188,9 +166,9 @@   -- | Equivalent to 'Tensor's @mulGDec@.   dmulgdec  :: Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO ()   -- | Equivalent to 'Tensor's @divGPow@.-  dginvpow  :: Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO ()+  dginvpow  :: Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO Int16   -- | Equivalent to 'Tensor's @divGDec@.-  dginvdec  :: Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO ()+  dginvdec  :: Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO Int16   -- | Equivalent to @zipWith (*)@   dmul :: Ptr r -> Ptr r -> Int64 -> IO () @@ -337,12 +315,12 @@ foreign import ccall unsafe "tensorGDecR" tensorGDecR ::         Int16 -> Ptr Int64 -> Int64 -> Ptr CPP -> Int16          -> IO () foreign import ccall unsafe "tensorGDecRq" tensorGDecRq ::       Int16 -> Ptr (ZqBasic q Int64) -> Int64 -> Ptr CPP -> Int16 -> Ptr Int64 -> IO () foreign import ccall unsafe "tensorGDecC" tensorGDecC ::         Int16 -> Ptr (Complex Double) -> Int64 -> Ptr CPP -> Int16          -> IO ()-foreign import ccall unsafe "tensorGInvPowR" tensorGInvPowR ::   Int16 -> Ptr Int64 -> Int64 -> Ptr CPP -> Int16          -> IO ()-foreign import ccall unsafe "tensorGInvPowRq" tensorGInvPowRq :: Int16 -> Ptr (ZqBasic q Int64) -> Int64 -> Ptr CPP -> Int16 -> Ptr Int64 -> IO ()-foreign import ccall unsafe "tensorGInvPowC" tensorGInvPowC ::   Int16 -> Ptr (Complex Double) -> Int64 -> Ptr CPP -> Int16          -> IO ()-foreign import ccall unsafe "tensorGInvDecR" tensorGInvDecR ::   Int16 -> Ptr Int64 -> Int64 -> Ptr CPP -> Int16          -> IO ()-foreign import ccall unsafe "tensorGInvDecRq" tensorGInvDecRq :: Int16 -> Ptr (ZqBasic q Int64) -> Int64 -> Ptr CPP -> Int16 -> Ptr Int64 -> IO ()-foreign import ccall unsafe "tensorGInvDecC" tensorGInvDecC ::   Int16 -> Ptr (Complex Double) -> Int64 -> Ptr CPP -> Int16          -> IO ()+foreign import ccall unsafe "tensorGInvPowR" tensorGInvPowR ::   Int16 -> Ptr Int64 -> Int64 -> Ptr CPP -> Int16          -> IO Int16+foreign import ccall unsafe "tensorGInvPowRq" tensorGInvPowRq :: Int16 -> Ptr (ZqBasic q Int64) -> Int64 -> Ptr CPP -> Int16 -> Ptr Int64 -> IO Int16+foreign import ccall unsafe "tensorGInvPowC" tensorGInvPowC ::   Int16 -> Ptr (Complex Double) -> Int64 -> Ptr CPP -> Int16          -> IO Int16+foreign import ccall unsafe "tensorGInvDecR" tensorGInvDecR ::   Int16 -> Ptr Int64 -> Int64 -> Ptr CPP -> Int16          -> IO Int16+foreign import ccall unsafe "tensorGInvDecRq" tensorGInvDecRq :: Int16 -> Ptr (ZqBasic q Int64) -> Int64 -> Ptr CPP -> Int16 -> Ptr Int64 -> IO Int16+foreign import ccall unsafe "tensorGInvDecC" tensorGInvDecC ::   Int16 -> Ptr (Complex Double) -> Int64 -> Ptr CPP -> Int16          -> IO Int16  foreign import ccall unsafe "tensorCRTRq" tensorCRTRq ::         Int16 -> Ptr (ZqBasic q Int64) -> Int64 -> Ptr CPP -> Int16 -> Ptr (Ptr (ZqBasic q Int64)) -> Ptr Int64 -> IO () foreign import ccall unsafe "tensorCRTC" tensorCRTC ::           Int16 -> Ptr (Complex Double) -> Int64 -> Ptr CPP -> Int16 -> Ptr (Ptr (Complex Double)) -> IO ()
Crypto/Lol/Cyclotomic/Tensor/CTensor/Extension.hs view
@@ -13,7 +13,7 @@  module Crypto.Lol.Cyclotomic.Tensor.CTensor.Extension ( embedPow', embedDec', embedCRT'-, twacePowDec' -- , twaceCRT'+, twacePowDec', twaceCRT' , coeffs', powBasisPow' , crtSetDec' , backpermute'@@ -32,8 +32,7 @@ import           Data.Maybe import           Data.Reflection      (reify) import qualified Data.Vector          as V-import           Data.Vector.Generic  as G (Vector, generate, length, (!))-import qualified Data.Vector.Storable as SV+import           Data.Vector.Storable as SV import qualified Data.Vector.Unboxed  as U  @@ -42,19 +41,21 @@ -- often much more efficient. -- -- > backpermute <a,b,c,d> <0,3,2,3,1,0> = <a,d,c,d,b,a>-backpermute' :: (Vector v a)-             => U.Vector Int -- ^ @is@ index vector (of length @n@)-             -> v a   -- ^ @xs@ value vector-             -> v a---{-# INLINE backpermute' #-}-backpermute' is v = generate (G.length is) (\i -> v ! (is ! i))+backpermute' :: (Storable a) =>+             U.Vector Int -- ^ @is@ index vector (of length @n@)+             -> Vector a   -- ^ @xs@ value vector+             -> Vector a+{-# INLINABLE backpermute' #-}+backpermute' is v = generate (U.length is) (\i -> v ! (is U.! i)) -embedPow', embedDec' :: (Additive r, Vector v r, m `Divides` m')-                     => Tagged '(m, m') (v r -> v r)+embedPow', embedDec' :: (Additive r, Storable r, m `Divides` m')+                     => Tagged '(m, m') (Vector r -> Vector r)+{-# INLINABLE embedPow' #-}+{-# INLINABLE embedDec' #-} -- | Embeds an vector in the powerful basis of the the mth cyclotomic ring -- to an vector in the powerful basis of the m'th cyclotomic ring when @m | m'@ embedPow' = (\indices arr -> generate (U.length indices) $ \idx ->-  let (j0,j1) = indices ! idx+  let (j0,j1) = indices U.! idx   in if j0 == 0      then arr ! j1      else zero) <$> baseIndicesPow@@ -67,8 +68,8 @@  -- | Embeds an vector in the CRT basis of the the mth cyclotomic ring -- to an vector in the CRT basis of the m'th cyclotomic ring when @m | m'@-embedCRT' :: forall mon m m' v r . (CRTrans mon r, Vector v r, m `Divides` m')-          => TaggedT '(m, m') mon (v r -> v r)+embedCRT' :: forall mon m m' r . (CRTrans mon r, Storable r, m `Divides` m')+          => TaggedT '(m, m') mon (Vector r -> Vector r) embedCRT' =   (lift (proxyT crtInfo (Proxy::Proxy m') :: mon (CRTInfo r))) >>   (pureT $ backpermute' <$> baseIndicesCRT)@@ -76,21 +77,46 @@ -- | maps a vector in the powerful/decoding basis, representing an -- O_m' element, to a vector of arrays representing O_m elements in -- the same type of basis-coeffs' :: (Vector v r, m `Divides` m')-        => Tagged '(m, m') (v r -> [v r])+coeffs' :: (Storable r, m `Divides` m')+        => Tagged '(m, m') (Vector r -> [Vector r]) coeffs' = flip (\x -> V.toList . V.map (`backpermute'` x))           <$> extIndicesCoeffs  -- | The "tweaked trace" function in either the powerful or decoding -- basis of the m'th cyclotomic ring to the mth cyclotomic ring when -- @m | m'@.-twacePowDec' :: forall m m' r v . (Vector v r, m `Divides` m')-             => Tagged '(m, m') (v r -> v r)+twacePowDec' :: forall m m' r . (Storable r, m `Divides` m')+             => Tagged '(m, m') (Vector r -> Vector r)+{-# INLINABLE twacePowDec' #-} twacePowDec' = backpermute' <$> extIndicesPowDec ---- EAC: twaceCRT is defined in CTensor because it needs access to C-backend functions+kronToVec :: forall mon m r . (Monad mon, Fact m, Ring r, Storable r)+  => TaggedT m mon (Kron r) -> TaggedT m mon (Vector r)+kronToVec v = do+  vmat <- v+  let n = proxy totientFact (Proxy::Proxy m)+  return $ generate n (flip (indexK vmat) 0) +twaceCRT' :: forall mon m m' r .+             (Storable r, CRTrans mon r, m `Divides` m')+             => TaggedT '(m, m') mon (Vector r -> Vector r)+{-# INLINE twaceCRT' #-}+twaceCRT' = tagT $ do+  g' <- proxyT (kronToVec gCRTK) (Proxy::Proxy m')+  gInv <- proxyT (kronToVec gInvCRTK) (Proxy::Proxy m)+  embed <- proxyT embedCRT' (Proxy::Proxy '(m,m'))+  indices <- pure $ proxy extIndicesCRT (Proxy::Proxy '(m,m'))+  (_, m'hatinv) <- proxyT crtInfo (Proxy::Proxy m')+  let phi = proxy totientFact (Proxy::Proxy m)+      phi' = proxy totientFact (Proxy::Proxy m')+      mhat = fromIntegral $ proxy valueHatFact (Proxy::Proxy m)+      hatRatioInv = m'hatinv * mhat+      reltot = phi' `div` phi+      -- tweak = mhat * g' / (m'hat * g)+      tweak = SV.map (* hatRatioInv) $ SV.zipWith (*) (embed gInv) g'+  return $ \ arr -> -- take true trace after mul-by-tweak+    let v = backpermute' indices (SV.zipWith (*) tweak arr)+    in generate phi $ \i -> foldl1' (+) $ SV.unsafeSlice (i*reltot) reltot v  -- | The powerful extension basis, wrt the powerful basis. -- Outputs a list of vectors in O_m' that are an O_m basis for O_m'@@ -125,4 +151,4 @@       cosets <- partitionCosets p       return $ LP.map (\is -> generate phi                           (\j -> hinv * trace'-                                      (sum $ LP.map (elt j) is))) cosets+                                      (LP.sum $ LP.map (elt j) is))) cosets
Crypto/Lol/Cyclotomic/Tensor/CTensor/common.h view
@@ -1,16 +1,7 @@ #ifndef COMMON_H_ #define COMMON_H_ -#include <stdio.h>-#include <stdlib.h> #include "types.h"--#define ASSERT(EXP) { \-  if (!(EXP)) { \-    fprintf (stderr, "Assertion in file '%s' line %d : " #EXP "  is false\n", __FILE__, __LINE__); \-    exit(-1); \-  } \-}  // calculates base ** exp hDim_t ipow(hDim_t base, hShort_t exp);
Crypto/Lol/Cyclotomic/Tensor/CTensor/crt.cpp view
@@ -336,40 +336,110 @@ template <typename ring> void crtpinv (ring* y, hShort_t tupSize, hDim_t lts, hDim_t rts,                 hDim_t p, hDim_t rustride, ring* ruinv) {-  if(p ==2) {-    // need this case so that we can divide overall by mhat^(-1)-    return;+  hDim_t tensorOffset;+  if(p == 2) {+      return;   }+  else if(p == 3) {+    hDim_t temp1 = rts*2;+    ring ru1 = ruinv[rustride*tupSize];+    ring ru2 = ruinv[(rustride<<1)*tupSize];++    for(hDim_t blockOffset = 0; blockOffset < lts; blockOffset++) {+      hDim_t temp2 = blockOffset*temp1;+      for(hDim_t modOffset = 0; modOffset < rts; modOffset++) {+        tensorOffset = temp2 + modOffset;+        ring y1, y2, shift;+        y1 = y[tensorOffset*tupSize];+        y2 = y[(tensorOffset+rts)*tupSize];++        shift = (ru2*y1) + (ru1*y2);++        y[tensorOffset*tupSize]      +=                 y2  - shift;+        y[(tensorOffset+rts)*tupSize] = (ru1*y1) + (ru2*y2) - shift;+      }+    }+  }+  else if(p == 5) {+    hDim_t temp1 = rts*4;+    ring ru1 = ruinv[rustride*tupSize];+    ring ru2 = ruinv[(rustride<<1)*tupSize];+    ring ru3 = ruinv[(rustride*3)*tupSize];+    ring ru4 = ruinv[(rustride<<2)*tupSize];++    for(hDim_t blockOffset = 0; blockOffset < lts; blockOffset++) {+      hDim_t temp2 = blockOffset*temp1;+      for(hDim_t modOffset = 0; modOffset < rts; modOffset++) {+        tensorOffset = temp2 + modOffset;+        ring y1, y2, y3, y4, shift;+        y1 = y[tensorOffset*tupSize];+        y2 = y[(tensorOffset+rts)*tupSize];+        y3 = y[(tensorOffset+(rts<<1))*tupSize];+        y4 = y[(tensorOffset+3*rts)*tupSize];++        shift = (ru4*y1) + (ru3*y2) + (ru2*y3) + (ru1*y4);++        y[tensorOffset*tupSize]           +=                 y2  +      y3  +      y4  - shift;+        y[(tensorOffset+rts)*tupSize]      = (ru1*y1) + (ru2*y2) + (ru3*y3) + (ru4*y4) - shift;+        y[(tensorOffset+(rts<<1))*tupSize] = (ru2*y1) + (ru4*y2) + (ru1*y3) + (ru3*y4) - shift;+        y[(tensorOffset+rts*3)*tupSize]    = (ru3*y1) + (ru1*y2) + (ru4*y3) + (ru2*y4) - shift;+      }+    }+  }+  else if(p == 7) {+    hDim_t temp1 = rts*6;+    ring ru1 = ruinv[rustride*tupSize];+    ring ru2 = ruinv[(rustride<<1)*tupSize];+    ring ru3 = ruinv[(rustride*3)*tupSize];+    ring ru4 = ruinv[(rustride<<2)*tupSize];+    ring ru5 = ruinv[(rustride*5)*tupSize];+    ring ru6 = ruinv[(rustride*6)*tupSize];+    for(hDim_t blockOffset = 0; blockOffset < lts; blockOffset++) {+      hDim_t temp2 = blockOffset*temp1;+      for(hDim_t modOffset = 0; modOffset < rts; modOffset++) {+        tensorOffset = temp2 + modOffset;+        ring y1, y2, y3, y4, y5, y6, shift;+        y1 = y[tensorOffset*tupSize];+        y2 = y[(tensorOffset+rts)*tupSize];+        y3 = y[(tensorOffset+(rts<<1))*tupSize];+        y4 = y[(tensorOffset+3*rts)*tupSize];+        y5 = y[(tensorOffset+(rts<<2))*tupSize];+        y6 = y[(tensorOffset+rts*5)*tupSize];++        shift = (ru6*y1) + (ru5*y2) + (ru4*y3) + (ru3*y4) + (ru2*y5) + (ru1*y6);++        y[tensorOffset*tupSize]           +=                 y2  +      y3  +      y4  +      y5  +      y6  - shift;+        y[(tensorOffset+rts)*tupSize]      = (ru1*y1) + (ru2*y2) + (ru3*y3) + (ru4*y4) + (ru5*y5) + (ru6*y6) - shift;+        y[(tensorOffset+(rts<<1))*tupSize] = (ru2*y1) + (ru4*y2) + (ru6*y3) + (ru1*y4) + (ru3*y5) + (ru5*y6) - shift;+        y[(tensorOffset+rts*3)*tupSize]    = (ru3*y1) + (ru6*y2) + (ru2*y3) + (ru5*y4) + (ru1*y5) + (ru4*y6) - shift;+        y[(tensorOffset+(rts<<2))*tupSize] = (ru4*y1) + (ru1*y2) + (ru5*y3) + (ru2*y4) + (ru6*y5) + (ru3*y6) - shift;+        y[(tensorOffset+rts*5)*tupSize]    = (ru5*y1) + (ru3*y2) + (ru1*y3) + (ru6*y4) + (ru4*y5) + (ru2*y6) - shift;+      }+    }+  }   else {-    hDim_t tensorOffset,i;     ring* tempSpace = (ring*)malloc((p-1)*sizeof(ring));     hDim_t temp1 = rts*(p-1);     for(hDim_t blockOffset = 0; blockOffset < lts; blockOffset++) {       hDim_t temp2 = blockOffset*temp1;       for(hDim_t modOffset = 0; modOffset < rts; modOffset++) {         tensorOffset = temp2 + modOffset;--        for(i = 0; i < p-1; i++) {-          tempSpace[i] = (int)0;-          int j;-          for(j = 0; j < p-1; j++) {-            int ruIdx = ((j+1)*i) % p;-            tempSpace[i] += (y[(tensorOffset+j*rts)*tupSize] * ruinv[ruIdx*rustride*tupSize]);+        ring shift;+        shift = 0;+        for(hDim_t row = 0; row < p-1; row++) {+          shift += (y[(tensorOffset+row*rts)*tupSize]*ruinv[(p-row-1)*rustride*tupSize]);+          tempSpace[row] = 0;+          for(hDim_t col = 0; col < p-1; col++) {+            tempSpace[row] += (y[(tensorOffset+col*rts)*tupSize]*ruinv[((row*(col+1)) % p)*rustride*tupSize]);           }         } -        ring shift; // can't assign to a constant on the same line(?)-        shift=0;-        for(i = 0; i < p-1; i++) {-          // we were given the inverse rus, so we need to negate the indices-          shift += (y[(tensorOffset+i*rts)*tupSize] * ruinv[rustride*(p-(i+1))*tupSize]);-        }--        for(i = 0; i < p-1; i++) {-          y[(tensorOffset+i*rts)*tupSize] = tempSpace[i] - shift;+        for(hDim_t row = 0; row < p-1; row++) {+          y[(tensorOffset+rts*row)*tupSize] = tempSpace[row] - shift;         }       }     }+    free(tempSpace);   } } 
Crypto/Lol/Cyclotomic/Tensor/CTensor/g.cpp view
@@ -99,12 +99,11 @@       }
       ring rp;
       rp = p;
-      ring acc = lastOut / rp;
-      ASSERT ((acc * rp) == lastOut);  // this line asserts that lastOut % p == 0, without calling % operator
+      ring acc = lastOut;
       for (i = p-2; i > 0; --i) {
         hDim_t idx = tensorOffset + i*rts;
         ring tmp = acc;
-        acc -= y[idx*tupSize]; // we already divided acc by p, do not multiply y[idx] by p
+        acc -= y[idx*tupSize]*rp;
         y[idx*tupSize] = tmp;
       }
       y[tensorOffset*tupSize] = acc;
@@ -144,34 +143,120 @@   tensorFuserPrime (y, tupSize, gDec, totm, peArr, sizeOfPE, (hInt_t*)0);
 }
 
-extern "C" void tensorGInvPowR (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
+hInt_t oddRad(PrimeExponent* peArr, hShort_t sizeOfPE) {
+  hInt_t oddrad;
+  oddrad = 1;
+  for(int i = 0; i < sizeOfPE; i++) {
+    hShort_t p = peArr[i].prime;
+    if (p != 2) {
+      oddrad *= peArr[i].prime;
+    }
+  }
+  return oddrad;
+}
+
+extern "C" hShort_t tensorGInvPowR (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
 {
   tensorFuserPrime (y, tupSize, gInvPow, totm, peArr, sizeOfPE, (hInt_t*)0);
+
+  hInt_t oddrad = oddRad(peArr, sizeOfPE);
+
+  for(int i = 0; i < tupSize*totm; i++) {
+    if (y[i] % oddrad) {
+      y[i] /= oddrad;
+    }
+    else {
+      return 0;
+    }
+  }
+  return 1;
 }
 
-extern "C" void tensorGInvPowRq (hShort_t tupSize, Zq* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs)
+extern "C" hShort_t tensorGInvPowRq (hShort_t tupSize, Zq* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs)
 {
   tensorFuserPrime (y, tupSize, gInvPow, totm, peArr, sizeOfPE, qs);
+
+  hInt_t oddrad = oddRad(peArr, sizeOfPE);
+
+  for(int i = 0; i < tupSize; i++) {
+    Zq::q = qs[i]; // global update
+    hInt_t ori = reciprocal(Zq::q, oddrad);
+    Zq oddradInv;
+    oddradInv = ori;
+    if (ori == 0) {
+      return 0; // error condition
+    }
+    for(hDim_t j = 0; j < totm; j++) {
+      y[j*tupSize+i] *= oddradInv;
+    }
+  }
+
   canonicalizeZq(y,tupSize,totm,qs);
+  return 1;
 }
 
-extern "C" void tensorGInvPowC (hShort_t tupSize, Complex* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
+extern "C" hShort_t tensorGInvPowC (hShort_t tupSize, Complex* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
 {
   tensorFuserPrime (y, tupSize, gInvPow, totm, peArr, sizeOfPE, (hInt_t*)0);
+
+  hInt_t oddrad = oddRad(peArr, sizeOfPE);
+  Complex oddradInv;
+  oddradInv = 1 / oddrad;
+  for(int i = 0; i < tupSize*totm; i++) {
+    y[i] *= oddradInv;
+  }
+  return 1;
 }
 
-extern "C" void tensorGInvDecR (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
+extern "C" hShort_t tensorGInvDecR (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
 {
   tensorFuserPrime (y, tupSize, gInvDec, totm, peArr, sizeOfPE, (hInt_t*)0);
+
+  hInt_t oddrad = oddRad(peArr, sizeOfPE);
+
+  for(int i = 0; i < tupSize*totm; i++) {
+    if (y[i] % oddrad) {
+      y[i] /= oddrad;
+    }
+    else {
+      return 0;
+    }
+  }
+  return 1;
 }
 
-extern "C" void tensorGInvDecRq (hShort_t tupSize, Zq* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs)
+extern "C" hShort_t tensorGInvDecRq (hShort_t tupSize, Zq* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs)
 {
   tensorFuserPrime (y, tupSize, gInvDec, totm, peArr, sizeOfPE, qs);
+
+  hInt_t oddrad = oddRad(peArr, sizeOfPE);
+
+  for(int i = 0; i < tupSize; i++) {
+    Zq::q = qs[i]; // global update
+    hInt_t ori = reciprocal(Zq::q, oddrad);
+    Zq oddradInv;
+    oddradInv = ori;
+    if (ori == 0) {
+      return 0; // error condition
+    }
+    for(hDim_t j = 0; j < totm; j++) {
+      y[j*tupSize+i] *= oddradInv;
+    }
+  }
+
   canonicalizeZq(y,tupSize,totm,qs);
+  return 1;
 }
 
-extern "C" void tensorGInvDecC (hShort_t tupSize, Complex* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
+extern "C" hShort_t tensorGInvDecC (hShort_t tupSize, Complex* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
 {
   tensorFuserPrime (y, tupSize, gInvDec, totm, peArr, sizeOfPE, (hInt_t*)0);
+
+  hInt_t oddrad = oddRad(peArr, sizeOfPE);
+  Complex oddradInv;
+  oddradInv = 1 / oddrad;
+  for(int i = 0; i < tupSize*totm; i++) {
+    y[i] *= oddradInv;
+  }
+  return 1;
 }
Crypto/Lol/Cyclotomic/Tensor/CTensor/random.cpp view
@@ -3,9 +3,9 @@ #include "common.h" #include <math.h> -// this function takes *inverse* RUs, so no negation is needed on the indexing // I had been negating the ru-idx, but this was causing a *negative* mod, resulting in a hard-to-find bug-void primeD (double *y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p, hDim_t rustride, Complex* ruinv)+// current behavior (taking rus, rather than ruInv) matches RT+void primeD (double *y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p, hDim_t rustride, Complex* ru) { 	if(p == 2) {     return;@@ -22,10 +22,10 @@       for(row = 0; row < p-1; row++) {         double acc = 0;         for(col = 1; col <= (p>>1); col++) {-          acc += 2 * ruinv[((row*col) % p)*rustride*tupSize].real * y[(tensorOffset+rts*(col-1))*tupSize];+          acc += 2 * ru[((row*col) % p)*rustride*tupSize].real * y[(tensorOffset+rts*(col-1))*tupSize];         }         for(col = (p>>1)+1; col <= p-1; col++) {-          acc += 2 * ruinv[((row*col) % p)*rustride*tupSize].imag * y[(tensorOffset+rts*(col-1))*tupSize];+          acc += 2 * ru[((row*col) % p)*rustride*tupSize].imag * y[(tensorOffset+rts*(col-1))*tupSize];         }         tempSpace[row] = acc/sqrt(2);       }@@ -38,16 +38,16 @@   free(tempSpace); } -void ppD (double *y, hShort_t tupSize, hDim_t lts, hDim_t rts, PrimeExponent pe, Complex *ruinv)+void ppD (double *y, hShort_t tupSize, hDim_t lts, hDim_t rts, PrimeExponent pe, Complex *ru) {   hDim_t p = pe.prime;   hDim_t e = pe.exponent;   hDim_t mprime = ipow(p,e-1);-  primeD (y, tupSize, lts*mprime, rts, p, mprime, ruinv);+  primeD (y, tupSize, lts*mprime, rts, p, mprime, ru); }  //the contents of y will be destroyed, but should be initialized in Haskell-land to independent Guassians over the reals-extern "C" void tensorGaussianDec (hShort_t tupSize, double *y, hDim_t totm, PrimeExponent *peArr, hShort_t sizeOfPE, Complex** ruinv)+extern "C" void tensorGaussianDec (hShort_t tupSize, double *y, hDim_t totm, PrimeExponent *peArr, hShort_t sizeOfPE, Complex** ru) {-	tensorFuserCRT (y, tupSize, ppD, totm, peArr, sizeOfPE, ruinv, (hInt_t*)0);+	tensorFuserCRT (y, tupSize, ppD, totm, peArr, sizeOfPE, ru, (hInt_t*)0); }
Crypto/Lol/Cyclotomic/Tensor/CTensor/types.h view
@@ -3,6 +3,8 @@ #define TENSORTYPES_H_
 
 #include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
 
 typedef int64_t hInt_t ;
 typedef int32_t hDim_t ;
@@ -11,13 +13,20 @@ 
 typedef struct
 {
-  hDim_t prime;
+  hShort_t prime;
   hShort_t exponent;
 } PrimeExponent;
 
 
 hInt_t reciprocal (hInt_t a, hInt_t b);
 
+#define ASSERT(EXP) { \
+  if (!(EXP)) { \
+    fprintf (stderr, "Assertion in file '%s' line %d : " #EXP "  is false\n", __FILE__, __LINE__); \
+    exit(-1); \
+  } \
+}
+
 //http://stackoverflow.com/questions/37572628
 #ifdef __cplusplus
 //http://stackoverflow.com/a/4421719
@@ -55,14 +64,11 @@   {
     Zq binv;
     binv = reciprocal(q,b.x);
+    ASSERT (binv.x); // binv == 0 indicates that x is not invertible mod q
     *this *= binv;
     return *this;
   }
 };
-inline char operator==(Zq a, const Zq& b)
-{
-  return (a.x == b.x);
-}
 inline Zq operator+(Zq a, const Zq& b)
 {
   a += b;
@@ -129,13 +135,6 @@     return *this;
   }
 };
-inline char operator==(Complex a, const Complex& b)
-{
-  // This is only used in divGDec, where we do a divisiblity check.
-  // The divisibility check should always succeed for Complex since \C is a field,
-  // however if we actually implement equality, it would fail due to roundoff.
-  return 1;
-}
 inline Complex operator+(Complex a, const Complex& b)
 {
   a += b;
Crypto/Lol/Cyclotomic/Tensor/CTensor/zq.cpp view
@@ -17,7 +17,10 @@     y  = lasty - quotient*y;     lasty = tmp;   }-  ASSERT (a==1);  // if this one fails, then b is not invertible mod a+  // if a!=1, then b is not invertible mod a+  if(a!=1) {+    return 0;+  }    // this actually returns EITHER the reciprocal OR reciprocal + fieldSize   hInt_t res = lasty + fieldSize;
Crypto/Lol/Cyclotomic/Tensor/RepaTensor.hs view
@@ -82,13 +82,13 @@    toProto (RT (Arr xs)) =     let m = fromIntegral $ proxy valueFact (Proxy::Proxy m)-        q = proxy value (Proxy::Proxy q) :: Double+        q = round (proxy value (Proxy::Proxy q) :: Double)     in Kq m q $ S.fromList $ RT.toList $ RT.map lift xs   toProto x@(ZV _) = toProto $ toRT x    fromProto (Kq m' q' xs) =     let m = proxy valueFact (Proxy::Proxy m) :: Int-        q = proxy value (Proxy::Proxy q) :: Double+        q = round (proxy value (Proxy::Proxy q) :: Double)         n = proxy totientFact (Proxy::Proxy m)         xs' = RT.fromList (Z:.n) $ LP.map reduce $ F.toList xs         len = F.length xs@@ -98,7 +98,7 @@             "An error occurred while reading the proto type for RT.\n\             \Expected m=" ++ show m ++ ", got " ++ show m' ++ "\n\             \Expected n=" ++ show n ++ ", got " ++ show len ++ "\n\-            \Expected q=" ++ show (round q :: Int64) ++ ", got " ++ show q' ++ "."+            \Expected q=" ++ show q ++ ", got " ++ show q' ++ "."  instance Eq r => Eq (RT m r) where   (ZV a) == (ZV b) = a == b@@ -183,12 +183,6 @@   fmapT f (RT v) = RT $ (coerce $ force . RT.map f) v   fmapT f v@(ZV _) = fmapT f $ toRT v -  -- Repa arrays don't have mapM, so apply to underlying Unboxed-  -- vector instead-  fmapTM f (RT (Arr arr)) = (RT . Arr . fromUnboxed (extent arr)) <$>-                            U.mapM f (toUnboxed arr)-  fmapTM f v = fmapTM f $ toRT v-   zipWithT f (RT (Arr a1)) (RT (Arr a2)) = RT $ Arr $ force $ RT.zipWith f a1 a2   zipWithT f v1 v2 = zipWithT f (toRT v1) (toRT v2) @@ -219,7 +213,6 @@   {-# INLINABLE powBasisPow #-}   {-# INLINABLE crtSetDec #-}   {-# INLINABLE fmapT #-}-  {-# INLINABLE fmapTM #-}   {-# INLINABLE zipWithT #-}   {-# INLINABLE unzipT #-} 
Crypto/Lol/Cyclotomic/Tensor/RepaTensor/CRT.hs view
@@ -28,8 +28,8 @@               => mon (r -> Arr m r) {-# INLINABLE scalarCRT' #-} scalarCRT'-  = let pps = proxy ppsFact (Proxy::Proxy m)-        sz = Z :. totientPPs pps+  = let n = proxy totientFact (Proxy::Proxy m)+        sz = Z :. n     in pure $ Arr . force . fromFunction sz . const  -- | Multiply by @g_m@ in the CRT basis (when it exists).
Crypto/Lol/Cyclotomic/UCyc.hs view
@@ -33,14 +33,14 @@ module Crypto.Lol.Cyclotomic.UCyc ( -- * Data types and constraints-  UCyc, P, D, C, E, UCycEC, UCRTElt, NFElt+  UCyc, P, D, C, E, UCycEC, UCycPC, UCRTElt, NFElt -- * Changing representation , toPow, toDec, toCRT, fmapPow, fmapDec , unzipPow, unzipDec, unzipCRTC, unzipCRTE -- * Scalars , scalarPow, scalarCRT -- * Basic operations-, mulG, divG, gSqNorm+, mulG, divGPow, divGDec, divGCRTC, gSqNorm -- * Error sampling , tGaussian, errorRounded, errorCoset -- * Inter-ring operations and values@@ -49,8 +49,9 @@ , coeffsPow, coeffsDec, powBasis, crtSet ) where -import Crypto.Lol.Cyclotomic.Tensor hiding (embedCRT, embedDec, embedPow,-                                     scalarCRT, scalarPow, twaceCRT)+import Crypto.Lol.Cyclotomic.Tensor hiding (divGDec, divGPow, embedCRT,+                                     embedDec, embedPow, scalarCRT,+                                     scalarPow, twaceCRT)  import           Crypto.Lol.CRTrans import           Crypto.Lol.Cyclotomic.CRTSentinel@@ -91,6 +92,9 @@ -- | Convenient synonym for either CRT representation. type UCycEC t m r = Either (UCyc t m E r) (UCyc t m C r) +-- | Convenient synonym for random sampling.+type UCycPC t m r = Either (UCyc t m P r) (UCyc t m C r)+ -- | Represents a cyclotomic ring such as \(\Z[\zeta_m]\), -- \(\Z_q[\zeta_m]\), and \(\Q(\zeta_m)\) in an explicit -- representation: @t@ is the 'Tensor' type for storing coefficient tensors;@@ -329,6 +333,7 @@              => UCyc t m C (a,b)              -> (Either (UCyc t m P a) (UCyc t m C a),                  Either (UCyc t m P b) (UCyc t m C b))+{-# INLINABLE unzipCRTC #-} unzipCRTC (CRTC s v)   = let (ac,bc) = unzipT v         (ap,bp) = Pow *** Pow $ unzipT $ crtInvCS s v@@ -342,6 +347,7 @@              => UCyc t m E (a,b)              -> (Either (UCyc t m P a) (UCyc t m E a),                  Either (UCyc t m P b) (UCyc t m E b))+{-# INLINABLE unzipCRTE #-} unzipCRTE (CRTE _ v)   = let (ae,be) = unzipT v         (a',b') = unzipT $ fmapT fromExt $ runIdentity crtInv v@@ -352,24 +358,37 @@  -- | Multiply by the special element \(g_m\). mulG :: (Fact m, UCRTElt t r) => UCyc t m rep r -> UCyc t m rep r-{-# INLINABLE mulG #-}+{-# INLINE mulG #-} mulG (Pow v) = Pow $ mulGPow v mulG (Dec v) = Dec $ mulGDec v mulG (CRTC s v) = CRTC s $ mulGCRTCS s v mulG (CRTE s v) = CRTE s $ runIdentity mulGCRT v +-- Note: We do not implement divGCRTE because we can't tell whether+-- the element is actually divisible by g when using the CRT extension+-- basis.+ -- | Divide by the special element \(g_m\). -- WARNING: this implementation is not a constant-time algorithm, so -- information about the argument may be leaked through a timing -- channel.-divG :: (Fact m, UCRTElt t r, ZeroTestable r, IntegralDomain r)-        => UCyc t m rep r -> Maybe (UCyc t m rep r)-{-# INLINABLE divG #-}-divG (Pow v) = Pow <$> divGPow v-divG (Dec v) = Dec <$> divGDec v-divG (CRTC s v) = Just $ CRTC s $ divGCRTCS s v-divG (CRTE s v) = Just $ CRTE s $ runIdentity divGCRT v+divGPow :: (Fact m, UCRTElt t r, ZeroTestable r, IntegralDomain r)+        => UCyc t m P r -> Maybe (UCyc t m P r)+{-# INLINABLE divGPow #-}+divGPow (Pow v) = Pow <$> T.divGPow v +-- | Similar to 'divGPow'.+divGDec :: (Fact m, UCRTElt t r, ZeroTestable r, IntegralDomain r)+        => UCyc t m D r -> Maybe (UCyc t m D r)+{-# INLINABLE divGDec #-}+divGDec (Dec v) = Dec <$> T.divGDec v++-- | Similar to 'divGPow'.+divGCRTC :: (Fact m, UCRTElt t r)+        => UCyc t m C r -> UCyc t m C r+{-# INLINE divGCRTC #-}+divGCRTC (CRTC s v) = CRTC s $ divGCRTCS s v+ -- | Yield the scaled squared norm of \(g_m \cdot e\) under -- the canonical embedding, namely, -- \(\hat{m}^{-1} \cdot \| \sigma(g_m \cdot e) \|^2\) .@@ -467,8 +486,8 @@ -- | Twace into a subring, for the CRT basis.  (The output is an -- 'Either' because the subring might not support 'C'.) twaceCRTC :: (m `Divides` m', UCRTElt t r)-             => UCyc t m' C r -> Either (UCyc t m P r) (UCyc t m C r)-{-# INLINABLE twaceCRTC #-}+             => UCyc t m' C r -> UCycPC t m r+{-# INLINE twaceCRTC #-} twaceCRTC x@(CRTC s' v) =   case crtSentinel of     -- go to CRTC if valid for target, else go to Pow@@ -533,128 +552,6 @@  --------- Conversion methods ------------------ ---- {-# SPECIALIZE toPow :: (Fact m, Reflects q Int64) => UCyc RT m D (ZqBasic q Int64) -> UCyc RT m P (ZqBasic q Int64) #-}--- EAC: I can't specialize toPow due to the constraint synonym TElt. See GHC ticket 12068--- For future reference, it seemed to help in general to simplify constraints as much as possible--- (i.e. replacing (Ring (ZqBasic q z)) with (Ring z, Reflects t z)) and--- removing type synonyms wherever possible.--{--EAC: I tried specializing the function-toPow :: (Fact m, C) for C \subseteq [Tensor t , CRTEmbed r , CRTrans Maybe r , TElt t r , CRTrans Identity (CRTExt r) , TElt t (CRTExt r)]-using-{-# SPECIALIZE toPow :: (Fact m, Reflects q Int64) => UCyc RT m D (ZqBasic q Int64) -> UCyc RT m P (ZqBasic q Int64) #-}--The results for subsets with (Tensor t) were identical to those without (Tensor t), so we ignore (Tensor t) in what follows--There were three outcomes:-1. "Good": no warnings.-2. "NB": Warning: Forall'd constraint ‘Reflects k q Int64’ is not bound in RULE lhs-3. "Bad": Warning: RULE left-hand side too complicated to desugar--BAD:  CRTEmbed r, CRTrans Maybe r, TElt t r, CRTrans Identity (CRTExt r), TElt t (CRTExt r)-BAD:  CRTEmbed r, CRTrans Maybe r, TElt t r, CRTrans Identity (CRTExt r)-BAD:  CRTEmbed r, CRTrans Maybe r, TElt t r,                              TElt t (CRTExt r)-BAD:  CRTEmbed r, CRTrans Maybe r, TElt t r-BAD:  CRTEmbed r, CRTrans Maybe r,           CRTrans Identity (CRTExt r), TElt t (CRTExt r)-good: CRTEmbed r, CRTrans Maybe r,           CRTrans Identity (CRTExt r)-BAD:  CRTEmbed r, CRTrans Maybe r,                                        TElt t (CRTExt r)-good: CRTEmbed r, CRTrans Maybe r-BAD:  CRTEmbed r,                  TElt t r, CRTrans Identity (CRTExt r), TElt t (CRTExt r)-BAD:  CRTEmbed r,                  TElt t r, CRTrans Identity (CRTExt r)-BAD:  CRTEmbed r,                  TElt t r,                              TElt t (CRTExt r)-good: CRTEmbed r,                  TElt t r-BAD:  CRTEmbed r,                            CRTrans Identity (CRTExt r), TElt t (CRTExt r)-good: CRTEmbed r,                            CRTrans Identity (CRTExt r)-good: CRTEmbed r,                                                         TElt t (CRTExt r)-good: CRTEmbed r-BAD:              CRTrans Maybe r, TElt t r, CRTrans Identity (CRTExt r), TElt t (CRTExt r)-good:             CRTrans Maybe r, TElt t r, CRTrans Identity (CRTExt r)-BAD:              CRTrans Maybe r, TElt t r,                              TElt t (CRTExt r)-good:             CRTrans Maybe r, TElt t r-good:             CRTrans Maybe r,           CRTrans Identity (CRTExt r), TElt t (CRTExt r)-good:             CRTrans Maybe r,           CRTrans Identity (CRTExt r)-good:             CRTrans Maybe r,                                        TElt t (CRTExt r)-good:             CRTrans Maybe r-NB:                                TElt t r, CRTrans Identity (CRTExt r), TElt t (CRTExt r)-NB:                                TElt t r, CRTrans Identity (CRTExt r)-NB:                                TElt t r,                              TElt t (CRTExt r)-NB:                                TElt t r-NB:                                          CRTrans Identity (CRTExt r), TElt t (CRTExt r)-NB:                                          CRTrans Identity (CRTExt r)-NB:                                                                       TElt t (CRTExt r)-NB:--Assigning variables to constraints as follows,--A=CRTEmbed r-B=CRTrans Maybe r-C=TElt t r-D=CRTrans Identity (CRTExt r)-E=TElt t (CRTExt r)--using outcome values--BAD=0-NB=0-GOOD=1--the formula for results is--y=(-A)*B*(-C) + (-A)*B*(-E) + A*(-C)*(-E) + A*(-B)*(-C)*(-D) + A*(-B)*(-D)*(-E)--Below this line, I've reordered the subsets into logical groups.---- always nb if we don't have either of (CRTEmbed r) or (CRTrans Maybe r)--- I think this error makes sense: type families aren't injective, so references--- to TElt and CRTExt may not refer to 'r' on their RHS.-NB:                                TElt t r, CRTrans Identity (CRTExt r), TElt t (CRTExt r)-NB:                                TElt t r, CRTrans Identity (CRTExt r)-NB:                                TElt t r,                              TElt t (CRTExt r)-NB:                                TElt t r-NB:                                          CRTrans Identity (CRTExt r), TElt t (CRTExt r)-NB:                                          CRTrans Identity (CRTExt r)-NB:                                                                       TElt t (CRTExt r)-NB:---- always bad if we have both TElt constraints.-BAD:  CRTEmbed r, CRTrans Maybe r, TElt t r,                              TElt t (CRTExt r)-BAD:  CRTEmbed r, CRTrans Maybe r, TElt t r, CRTrans Identity (CRTExt r), TElt t (CRTExt r)-BAD:  CRTEmbed r,                  TElt t r, CRTrans Identity (CRTExt r), TElt t (CRTExt r)-BAD:              CRTrans Maybe r, TElt t r, CRTrans Identity (CRTExt r), TElt t (CRTExt r)-BAD:  CRTEmbed r,                  TElt t r,                              TElt t (CRTExt r)-BAD:              CRTrans Maybe r, TElt t r,                              TElt t (CRTExt r)---- always good if we don't have either TElt constraint.-good: CRTEmbed r, CRTrans Maybe r-good: CRTEmbed r, CRTrans Maybe r,           CRTrans Identity (CRTExt r)-good: CRTEmbed r,                            CRTrans Identity (CRTExt r)-good:             CRTrans Maybe r,           CRTrans Identity (CRTExt r)-good: CRTEmbed r-good:             CRTrans Maybe r---- bad if we have both (CRTEmbed r) and (CRTrans Maybe r) with at least one of the TElt constraints-BAD:  CRTEmbed r, CRTrans Maybe r, TElt t r, CRTrans Identity (CRTExt r)-BAD:  CRTEmbed r, CRTrans Maybe r, TElt t r-BAD:  CRTEmbed r, CRTrans Maybe r,           CRTrans Identity (CRTExt r), TElt t (CRTExt r)-BAD:  CRTEmbed r, CRTrans Maybe r,                                        TElt t (CRTExt r)---- a few more good cases: symmetric for (CRTEmbed r)  and (CRTrans Maybe r)-good: CRTEmbed r,                  TElt t r-good:             CRTrans Maybe r, TElt t r-good: CRTEmbed r,                                                         TElt t (CRTExt r)-good:             CRTrans Maybe r,                                        TElt t (CRTExt r)---- strange cases: works for (CRTrans Maybe r), fails for (CRTEmbed r)---   removing the (Ring (CRTExt r)) superclass constraint from CRTEmbed makes all four of these work.---   (but doesn't change the behavior of other failing cases)-BAD:  CRTEmbed r,                  TElt t r, CRTrans Identity (CRTExt r)-good:             CRTrans Maybe r, TElt t r, CRTrans Identity (CRTExt r)-BAD:  CRTEmbed r,                            CRTrans Identity (CRTExt r), TElt t (CRTExt r)-good:             CRTrans Maybe r,           CRTrans Identity (CRTExt r), TElt t (CRTExt r)---} -- | Convert to powerful-basis representation. toPow :: (Fact m, UCRTElt t r) => UCyc t m rep r -> UCyc t m P r {-# INLINABLE toPow #-}@@ -771,7 +668,7 @@   randomR _ = error "randomR non-sensical for UCyc"  instance (Random r, UCRTElt t r, Fact m)-         => Random (Either (UCyc t m P r) (UCyc t m C r)) where+         => Random (UCycPC t m r) where    -- create in CRTC basis if possible, otherwise in powerful   random = let cons = case crtSentinel of
Crypto/Lol/FactoredDefs.hs view
@@ -13,14 +13,14 @@ module Crypto.Lol.FactoredDefs ( -- * Factored natural numbers-  reifyFact, reifyFactI-, Factored, SFactored, Fact, fType, fDec+  Factored, SFactored, Fact, fType, fDec+, reifyFact, reifyFactI, intToFact -- * Prime powers-, reifyPPow, reifyPPowI , PrimePower, SPrimePower, Sing(SPP), PPow, ppType, ppDec+, reifyPPow, reifyPPowI -- * Primes-, reifyPrime, reifyPrimeI , PrimeBin, SPrimeBin, Prime, pType, pDec+, reifyPrime, reifyPrimeI, valueP -- * Constructors , pToPP, sPToPP, PToPP, ppToF, sPpToF, PpToF, pToF, sPToF, PToF -- * Unwrappers@@ -32,17 +32,18 @@ , fOddRadical, FOddRadical , pFree, PFree -- * Convenient reflections-, ppsFact, valueFact, totientFact, valueHatFact, radicalFact, oddRadicalFact-, ppPPow, primePPow, exponentPPow, valuePPow, totientPPow+, ppsFact, valueFact, totientFact, radicalFact, oddRadicalFact, valueHatFact+, ppPPow, primePPow, exponentPPow, valuePPow, totientPPow, radicalPPow, oddRadicalPPow, valueHatPPow , valuePrime+-- * Data-level equivalents of reflections for 'Factored' data+, valueF, totientF, radicalF, oddRadicalF, valueHatF -- * Number-theoretic laws , transDivides, gcdDivides, lcmDivides, lcm2Divides , pSplitTheorems, pFreeDivides , (\\) -- re-export from Data.Constraint for convenience -- * Utility operations on prime powers , valueHat-, PP, ppToPP, valuePP, totientPP, radicalPP, oddRadicalPP-, valuePPs, totientPPs, radicalPPs, oddRadicalPPs+, PP, ppToPP, valuePP, totientPP, radicalPP, oddRadicalPP, valueHatPP -- * Re-export , module Crypto.Lol.PosBin ) where@@ -329,34 +330,51 @@ -- | Type synonym for @(prime, exponent)@ pair. type PP = (Int, Int) +-- | Conversion.+ppToPP :: PrimePower -> PP+ppToPP = (binToInt . unP *** posToInt) . unPP++-- | Reflect a 'PrimePower' type to a 'PP' value.+ppPPow :: forall pp . PPow pp => Tagged pp PP+ppPPow = tag $ ppToPP $ fromSing (sing :: SPrimePower pp)+ -- | Value-level prime-power factorization tagged by a 'Factored' type. ppsFact :: forall m . Fact m => Tagged m [PP] ppsFact = tag $ map ppToPP $ unF $ fromSing (sing :: SFactored m) -valueFact, totientFact, valueHatFact, radicalFact, oddRadicalFact ::-  Fact m => Tagged m Int+-- | The value of a 'PrimeBin' type.+valuePrime :: forall p . Prime p => Tagged p Int+valuePrime = tag $ binToInt $ unP $ fromSing (sing :: SPrimeBin p) ++valueFact, totientFact, radicalFact, oddRadicalFact, valueHatFact ::+  Fact m => Tagged m Int -- | The value of a 'Factored' type. valueFact = valuePPs <$> ppsFact- -- | The totient of a 'Factored' type's value. totientFact = totientPPs <$> ppsFact- -- | The "hat" of a 'Factored' type's value: -- \( \hat{m} = \begin{cases} m & \mbox{if } m \text{ is odd} \\ m/2 & \text{otherwise} \end{cases} \). valueHatFact = valueHat <$> valueFact- -- | The radical (product of prime divisors) of a 'Factored' type. radicalFact = radicalPPs <$> ppsFact- -- | The odd radical (product of odd prime divisors) of a 'Factored' type. oddRadicalFact = oddRadicalPPs <$> ppsFact --- | Reflect a 'PrimePower' type to a 'PP' value.-ppPPow :: forall pp . PPow pp => Tagged pp PP-ppPPow = tag $ ppToPP $ fromSing (sing :: SPrimePower pp)+valueF, totientF, radicalF, oddRadicalF, valueHatF :: Factored -> Int+-- | The value of a 'Factored'.+valueF = valuePPs . map ppToPP . unF+-- | Totient of a 'Factored'.+totientF = totientPPs . map ppToPP . unF+-- | The hat of a 'Factored'.+valueHatF = valueHat . valueF+-- | The radical of a 'Factored'.+radicalF = radicalPPs . map ppToPP . unF+-- | The odd radical of a 'Factored'.+oddRadicalF = oddRadicalPPs . map ppToPP . unF -primePPow, exponentPPow, valuePPow, totientPPow :: PPow pp => Tagged pp Int+primePPow, exponentPPow, valuePPow, totientPPow, radicalPPow, oddRadicalPPow, valueHatPPow ::+  PPow pp => Tagged pp Int -- | Reflect the prime component of a 'PrimePower' type. primePPow = fst <$> ppPPow -- | Reflect the exponent component of a 'PrimePower' type.@@ -365,46 +383,50 @@ valuePPow = valuePP <$> ppPPow -- | The totient of a 'PrimePower' type's value. totientPPow = totientPP <$> ppPPow---- | The value of a 'PrimeBin' type.-valuePrime :: forall p . Prime p => Tagged p Int-valuePrime = tag $ binToInt $ unP $ fromSing (sing :: SPrimeBin p)---- | Return \( m \) if \( m \) is odd, and \( m/2 \) otherwise.-valueHat :: Integral i => i -> i-valueHat m = if m `mod` 2 == 0 then m `div` 2 else m+-- | The "hat" of a 'PrimePower' type's value:+-- \( p^e \) if \( p \) is odd, \( 2^{e-1} \) otherwise.+valueHatPPow = valueHat <$> valuePPow+-- | The radical of a 'PrimePower' type's value.+radicalPPow = radicalPP <$> ppPPow+-- | The odd radical of a 'PrimePower' type's value.+oddRadicalPPow = oddRadicalPP <$> ppPPow --- | Conversion.-ppToPP :: PrimePower -> PP-ppToPP = (binToInt . unP *** posToInt) . unPP+-- functions on data-level [PP]+valuePPs, totientPPs, radicalPPs, oddRadicalPPs :: [PP] -> Int+-- | Product of values of individual 'PP's+valuePPs = product . map valuePP+-- | Product of totients of individual 'PP's+totientPPs = product . map totientPP+-- | Product of radicals of individual 'PP's+radicalPPs = product . map radicalPP+-- | Product of odd radicals of individual 'PP's+oddRadicalPPs = product . map oddRadicalPP -valuePP, totientPP, radicalPP, oddRadicalPP :: PP -> Int+-- functions on data-level PP+valuePP, totientPP, radicalPP, oddRadicalPP, valueHatPP :: PP -> Int -- | The value of a prime power. valuePP (p,e) = p^e- -- | Totient of a prime power. totientPP (_,0) = 1 totientPP (p,e) = (p-1)*(p^(e-1))-+-- | The "hat" of a prime power: \( p^e \) if \( p \) is odd, \( 2^{e-1} \)+-- otherwise.+valueHatPP = valueHat . valuePP -- | The radical of a prime power. radicalPP (_,0) = 1 radicalPP (p,_) = p- -- | The odd radical of a prime power. oddRadicalPP (2,_) = 1 oddRadicalPP (p,_) = p -valuePPs, totientPPs, radicalPPs, oddRadicalPPs :: [PP] -> Int--- | Product of values of individual 'PP's-valuePPs = product . map valuePP--- | Product of totients of individual 'PP's-totientPPs = product . map totientPP--- | Product of radicals of individual 'PP's-radicalPPs = product . map radicalPP--- | Product of odd radicals of individual 'PP's-oddRadicalPPs = product . map oddRadicalPP+valueP :: PrimeBin -> Int+valueP (P p) = binToInt p +-- | Return \( m \) if \( m \) is odd, and \( m/2 \) otherwise.+valueHat :: Integral i => i -> i+valueHat m = if m `mod` 2 == 0 then m `div` 2 else m + -- | Template Haskell splice for the 'PrimeBin' type corresponding to a -- given positive prime integer.  (Uses 'prime' to enforce primality -- of the base, so should only be used on small-to-moderate-sized@@ -449,6 +471,12 @@ fDec :: Int -> DecQ fDec n = tySynD (mkName $ 'F' : show n) [] $ fType n +intToFact :: Int -> Factored+intToFact m =+  let fcts = factorize m+      fcts' = map (\(p,e) -> PP (P $ intToBin p, intToPos e)) fcts+  in F fcts'+ -- | Factorize a positive integer into an ordered list of its prime -- divisors, with possible duplicates.  First argument is infinite -- list of primes left to consider.@@ -465,4 +493,3 @@ -- pairs, in strictly increasing order by prime. factorize :: Int -> [(Int,Int)] factorize = map (head &&& length) . group . factorize' primes-
Crypto/Lol/GaussRandom.hs view
@@ -18,7 +18,7 @@ -- @svar = true variance * (2*pi)@. See -- <http://www.alpheratz.net/murison/Maple/GaussianDistribution/GaussianDistribution.pdf -- this link> for details.-+{-# INLINABLE realGaussian #-} realGaussian :: forall v q m .                 (ToRational v, OrdFloat q, Random q, MonadRandom m)                 => v -> m (q,q)@@ -44,6 +44,7 @@ realGaussians ::     (ToRational svar, OrdFloat i, Random i, V.Vector v i, MonadRandom m)     => svar -> Int -> m (v i)+{-# INLINABLE realGaussians #-} realGaussians var n     | odd n = V.tail <$> realGaussians var (n+1) -- O(1) tail     | otherwise = (V.fromList . uncurry (++) . unzip) <$>@@ -59,11 +60,13 @@ -- | Execute an action repeatedly until its result fails to satisfy a predicate, -- and return that result (discarding all others). iterateWhile :: (Monad m) => (a -> Bool) -> m a -> m a+{-# INLINE iterateWhile #-} iterateWhile p x = x >>= iterateUntilM (not . p) (const x)  -- | Analogue of @('Prelude.until')@ -- Yields the result of applying f until p holds. iterateUntilM :: (Monad m) => (a -> Bool) -> (a -> m a) -> a -> m a+{-# INLINE iterateUntilM #-} iterateUntilM p f v     | p v       = return v     | otherwise = f v >>= iterateUntilM p f
Crypto/Lol/PosBinDefs.hs view
@@ -12,15 +12,13 @@  module Crypto.Lol.PosBinDefs ( -- * Positive naturals in Peano representation-  Pos(..), Sing(SO, SS), SPos, PosC-, posToInt, addPos, sAddPos, AddPos, subPos, sSubPos, SubPos-, reifyPos, reifyPosI-, posType, posDec+  Pos(..), Sing(SO, SS), SPos, PosC, posType, posDec+, reifyPos, reifyPosI, posToInt, intToPos+, addPos, sAddPos, AddPos, subPos, sSubPos, SubPos , OSym0, SSym0, SSym1, AddPosSym0, AddPosSym1, SubPosSym0, SubPosSym1   -- * Positive naturals in binary representation-, Bin(..), Sing(SB1, SD0, SD1), SBin, BinC-, reifyBin, reifyBinI-, binToInt, binType, binDec+, Bin(..), Sing(SB1, SD0, SD1), SBin, BinC, binType, binDec+, reifyBin, reifyBinI, binToInt, intToBin , B1Sym0, D0Sym0, D0Sym1, D1Sym0, D1Sym1   -- * Miscellaneous , intDec, primes, prime@@ -60,6 +58,7 @@ -- not promotable due to numeric output  -- | Convert a 'Pos' to an integral type.+{-# INLINABLE posToInt #-} posToInt :: ToInteger.C z => Pos -> z posToInt O = one posToInt (S a) = one + posToInt a@@ -90,11 +89,26 @@             |] +-- | Convert an integral type to a 'Pos'.+intToPos :: ToInteger.C z => z -> Pos+intToPos 1 = O+intToPos x | x > 0 = S $ intToPos $ x-1+intToPos _ = error "cannot convert non-positive value to a Pos"+ -- | Convert a 'Bin' to an integral type.+{-# INLINABLE binToInt #-} binToInt :: ToInteger.C z => Bin -> z binToInt B1 = one binToInt (D0 a) = 2 * binToInt a binToInt (D1 a) = 1 + 2 * binToInt a++-- | Convert an integral type to a 'Bin'.+intToBin :: ToInteger.C z => z -> Bin+intToBin 1 = B1+intToBin x | x > 0 =+  case even x of+    True -> D0 $ intToBin $ x `div` 2+    False -> D1 $ intToBin $ x `div` 2  -- | Kind-restricted synonym for 'SingI'. type PosC (p :: Pos) = SingI p
Crypto/Lol/RLWE/Discrete.hs view
@@ -39,7 +39,7 @@  -- | The 'gSqNorm' of the error term of an RLWE sample, given the -- purported secret.-errorGSqNorm :: (RLWECtx t m zq, Ring (LiftOf zq))+errorGSqNorm :: (RLWECtx t m zq)                 => Cyc t m zq -> Sample t m zq -> LiftOf zq {-# INLINABLE errorGSqNorm #-} errorGSqNorm s = gSqNorm . errorTerm s
Crypto/Lol/Types/FiniteField.hs view
@@ -39,10 +39,12 @@  import Math.NumberTheory.Primes.Factorisation -import           Control.Applicative hiding ((*>))+import           Control.Applicative  hiding ((*>)) import           Control.DeepSeq import           Control.Monad-import qualified Data.Vector         as V+import           Control.Monad.Random (liftRand, runRand)+import qualified Data.Vector          as V+import           System.Random  --import qualified Debug.Trace as DT @@ -61,9 +63,16 @@ type GFCtx fp d = (PrimeField fp, Reflects d Int)  instance (GFCtx fp d) => Enumerable (GF fp d) where-  values = GF <$> fromCoeffs <$>+  values = GF . fromCoeffs <$>            -- d-fold cartesian product of Fp values            replicateM (proxy value (Proxy::Proxy d)) values++instance (Random fp, Reflects d Int) => Random (GF fp d) where+  random = let d = proxy value (Proxy::Proxy d)+           in runRand $ (GF . fromCoeffs) <$> replicateM d (liftRand random)+  {-# INLINABLE random #-}++  randomR _ = error "randomR non-sensical for GF"  instance (GFCtx fp d) => Ring.C (GF fp d) where 
Crypto/Lol/Types/Random.hs view
@@ -33,3 +33,6 @@    split (CryptoRand g) =     either (error . show) (CryptoRand *** CryptoRand) $ splitGen g++  {-# INLINABLE next #-}+  {-# INLINABLE split #-}
Crypto/Lol/Types/ZqBasic.hs view
@@ -15,6 +15,7 @@ 
 module Crypto.Lol.Types.ZqBasic
 ( ZqBasic -- export the type, but not the constructor (for safety)
+, goodQs
 ) where
 
 import Crypto.Lol.CRTrans
@@ -53,6 +54,12 @@ import qualified Algebra.Ring           as Ring (C)
 import qualified Algebra.ZeroTestable   as ZeroTestable (C)
 
+-- an infinite list of primes greater than the input and congruent to
+-- 1 mod m
+goodQs :: (IntegralDomain a, ToInteger a) => a -> a -> [a]
+goodQs m lower = filter (isPrime . toInteger) $
+  iterate (+m) $ lower + ((m-lower) `mod` m) + 1
+
 -- | The ring \(\Z_q\) of integers modulo 'q', using underlying integer
 -- type 'z'.
 newtype ZqBasic q z = ZqB z
@@ -301,6 +308,7 @@                     in (ZqB x, g')
 
   randomR _ = error "randomR non-sensical for Zq types"
+  {-# INLINABLE random #-}
 
 -- instance of Arbitrary
 instance (Reflects q z, ToInteger z, Random z) => Arbitrary (ZqBasic q z) where
Crypto/Proto/RLWE.hs view
@@ -14,10 +14,10 @@ protoInfo :: ProtoInfo protoInfo  = Prelude'.read-    "ProtoInfo {protoMod = ProtoName {protobufName = FIName \".RLWE\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [], baseName = MName \"RLWE\"}, protoFilePath = [\"Crypto\",\"Proto\",\"RLWE.hs\"], protoSource = \"RLWE.proto\", extensionKeys = fromList [], messages = [DescriptorInfo {descName = ProtoName {protobufName = FIName \".RLWE.SampleCont\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"SampleCont\"}, descFilePath = [\"Crypto\",\"Proto\",\"RLWE\",\"SampleCont.hs\"], isGroup = False, fields = fromList [FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.SampleCont.a\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"SampleCont\"], baseName' = FName \"a\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 1}, wireTag = WireTag {getWireTag = 10}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 11}, typeName = Just (ProtoName {protobufName = FIName \".RLWE.Rq\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"Rq\"}), hsRawDefault = Nothing, hsDefault = Nothing},FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.SampleCont.b\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"SampleCont\"], baseName' = FName \"b\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 2}, wireTag = WireTag {getWireTag = 18}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 11}, typeName = Just (ProtoName {protobufName = FIName \".RLWE.Kq\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"Kq\"}), hsRawDefault = Nothing, hsDefault = Nothing}], descOneofs = fromList [], keys = fromList [], extRanges = [], knownKeys = fromList [], storeUnknown = False, lazyFields = False, makeLenses = False},DescriptorInfo {descName = ProtoName {protobufName = FIName \".RLWE.SampleDisc\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"SampleDisc\"}, descFilePath = [\"Crypto\",\"Proto\",\"RLWE\",\"SampleDisc.hs\"], isGroup = False, fields = fromList [FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.SampleDisc.a\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"SampleDisc\"], baseName' = FName \"a\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 1}, wireTag = WireTag {getWireTag = 10}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 11}, typeName = Just (ProtoName {protobufName = FIName \".RLWE.Rq\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"Rq\"}), hsRawDefault = Nothing, hsDefault = Nothing},FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.SampleDisc.b\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"SampleDisc\"], baseName' = FName \"b\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 2}, wireTag = WireTag {getWireTag = 18}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 11}, typeName = Just (ProtoName {protobufName = FIName \".RLWE.Rq\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"Rq\"}), hsRawDefault = Nothing, hsDefault = Nothing}], descOneofs = fromList [], keys = fromList [], extRanges = [], knownKeys = fromList [], storeUnknown = False, lazyFields = False, makeLenses = False},DescriptorInfo {descName = ProtoName {protobufName = FIName \".RLWE.SampleRLWR\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"SampleRLWR\"}, descFilePath = [\"Crypto\",\"Proto\",\"RLWE\",\"SampleRLWR.hs\"], isGroup = False, fields = fromList [FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.SampleRLWR.a\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"SampleRLWR\"], baseName' = FName \"a\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 1}, wireTag = WireTag {getWireTag = 10}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 11}, typeName = Just (ProtoName {protobufName = FIName \".RLWE.Rq\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"Rq\"}), hsRawDefault = Nothing, hsDefault = Nothing},FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.SampleRLWR.b\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"SampleRLWR\"], baseName' = FName \"b\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 2}, wireTag = WireTag {getWireTag = 18}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 11}, typeName = Just (ProtoName {protobufName = FIName \".RLWE.Rq\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"Rq\"}), hsRawDefault = Nothing, hsDefault = Nothing}], descOneofs = fromList [], keys = fromList [], extRanges = [], knownKeys = fromList [], storeUnknown = False, lazyFields = False, makeLenses = False},DescriptorInfo {descName = ProtoName {protobufName = FIName \".RLWE.Rq\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"Rq\"}, descFilePath = [\"Crypto\",\"Proto\",\"RLWE\",\"Rq.hs\"], isGroup = False, fields = fromList [FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.Rq.m\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"Rq\"], baseName' = FName \"m\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 1}, wireTag = WireTag {getWireTag = 8}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 13}, typeName = Nothing, hsRawDefault = Nothing, hsDefault = Nothing},FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.Rq.q\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"Rq\"], baseName' = FName \"q\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 2}, wireTag = WireTag {getWireTag = 16}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 4}, typeName = Nothing, hsRawDefault = Nothing, hsDefault = Nothing},FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.Rq.xs\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"Rq\"], baseName' = FName \"xs\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 3}, wireTag = WireTag {getWireTag = 24}, packedTag = Just (WireTag {getWireTag = 24},WireTag {getWireTag = 26}), wireTagLength = 1, isPacked = False, isRequired = False, canRepeat = True, mightPack = True, typeCode = FieldType {getFieldType = 18}, typeName = Nothing, hsRawDefault = Nothing, hsDefault = Nothing}], descOneofs = fromList [], keys = fromList [], extRanges = [], knownKeys = fromList [], storeUnknown = False, lazyFields = False, makeLenses = False},DescriptorInfo {descName = ProtoName {protobufName = FIName \".RLWE.Kq\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"Kq\"}, descFilePath = [\"Crypto\",\"Proto\",\"RLWE\",\"Kq.hs\"], isGroup = False, fields = fromList [FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.Kq.m\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"Kq\"], baseName' = FName \"m\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 1}, wireTag = WireTag {getWireTag = 8}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 13}, typeName = Nothing, hsRawDefault = Nothing, hsDefault = Nothing},FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.Kq.q\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"Kq\"], baseName' = FName \"q\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 2}, wireTag = WireTag {getWireTag = 17}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 1}, typeName = Nothing, hsRawDefault = Nothing, hsDefault = Nothing},FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.Kq.xs\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"Kq\"], baseName' = FName \"xs\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 3}, wireTag = WireTag {getWireTag = 25}, packedTag = Just (WireTag {getWireTag = 25},WireTag {getWireTag = 26}), wireTagLength = 1, isPacked = False, isRequired = False, canRepeat = True, mightPack = True, typeCode = FieldType {getFieldType = 1}, typeName = Nothing, hsRawDefault = Nothing, hsDefault = Nothing}], descOneofs = fromList [], keys = fromList [], extRanges = [], knownKeys = fromList [], storeUnknown = False, lazyFields = False, makeLenses = False}], enums = [], oneofs = [], knownKeyMap = fromList []}"+    "ProtoInfo {protoMod = ProtoName {protobufName = FIName \".RLWE\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [], baseName = MName \"RLWE\"}, protoFilePath = [\"Crypto\",\"Proto\",\"RLWE.hs\"], protoSource = \"RLWE.proto\", extensionKeys = fromList [], messages = [DescriptorInfo {descName = ProtoName {protobufName = FIName \".RLWE.SampleCont\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"SampleCont\"}, descFilePath = [\"Crypto\",\"Proto\",\"RLWE\",\"SampleCont.hs\"], isGroup = False, fields = fromList [FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.SampleCont.a\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"SampleCont\"], baseName' = FName \"a\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 1}, wireTag = WireTag {getWireTag = 10}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 11}, typeName = Just (ProtoName {protobufName = FIName \".RLWE.Rq\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"Rq\"}), hsRawDefault = Nothing, hsDefault = Nothing},FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.SampleCont.b\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"SampleCont\"], baseName' = FName \"b\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 2}, wireTag = WireTag {getWireTag = 18}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 11}, typeName = Just (ProtoName {protobufName = FIName \".RLWE.Kq\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"Kq\"}), hsRawDefault = Nothing, hsDefault = Nothing}], descOneofs = fromList [], keys = fromList [], extRanges = [], knownKeys = fromList [], storeUnknown = False, lazyFields = False, makeLenses = False},DescriptorInfo {descName = ProtoName {protobufName = FIName \".RLWE.SampleDisc\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"SampleDisc\"}, descFilePath = [\"Crypto\",\"Proto\",\"RLWE\",\"SampleDisc.hs\"], isGroup = False, fields = fromList [FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.SampleDisc.a\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"SampleDisc\"], baseName' = FName \"a\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 1}, wireTag = WireTag {getWireTag = 10}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 11}, typeName = Just (ProtoName {protobufName = FIName \".RLWE.Rq\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"Rq\"}), hsRawDefault = Nothing, hsDefault = Nothing},FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.SampleDisc.b\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"SampleDisc\"], baseName' = FName \"b\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 2}, wireTag = WireTag {getWireTag = 18}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 11}, typeName = Just (ProtoName {protobufName = FIName \".RLWE.Rq\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"Rq\"}), hsRawDefault = Nothing, hsDefault = Nothing}], descOneofs = fromList [], keys = fromList [], extRanges = [], knownKeys = fromList [], storeUnknown = False, lazyFields = False, makeLenses = False},DescriptorInfo {descName = ProtoName {protobufName = FIName \".RLWE.SampleRLWR\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"SampleRLWR\"}, descFilePath = [\"Crypto\",\"Proto\",\"RLWE\",\"SampleRLWR.hs\"], isGroup = False, fields = fromList [FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.SampleRLWR.a\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"SampleRLWR\"], baseName' = FName \"a\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 1}, wireTag = WireTag {getWireTag = 10}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 11}, typeName = Just (ProtoName {protobufName = FIName \".RLWE.Rq\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"Rq\"}), hsRawDefault = Nothing, hsDefault = Nothing},FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.SampleRLWR.b\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"SampleRLWR\"], baseName' = FName \"b\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 2}, wireTag = WireTag {getWireTag = 18}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 11}, typeName = Just (ProtoName {protobufName = FIName \".RLWE.Rq\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"Rq\"}), hsRawDefault = Nothing, hsDefault = Nothing}], descOneofs = fromList [], keys = fromList [], extRanges = [], knownKeys = fromList [], storeUnknown = False, lazyFields = False, makeLenses = False},DescriptorInfo {descName = ProtoName {protobufName = FIName \".RLWE.Rq\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"Rq\"}, descFilePath = [\"Crypto\",\"Proto\",\"RLWE\",\"Rq.hs\"], isGroup = False, fields = fromList [FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.Rq.m\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"Rq\"], baseName' = FName \"m\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 1}, wireTag = WireTag {getWireTag = 8}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 13}, typeName = Nothing, hsRawDefault = Nothing, hsDefault = Nothing},FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.Rq.q\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"Rq\"], baseName' = FName \"q\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 2}, wireTag = WireTag {getWireTag = 16}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 4}, typeName = Nothing, hsRawDefault = Nothing, hsDefault = Nothing},FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.Rq.xs\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"Rq\"], baseName' = FName \"xs\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 3}, wireTag = WireTag {getWireTag = 24}, packedTag = Just (WireTag {getWireTag = 24},WireTag {getWireTag = 26}), wireTagLength = 1, isPacked = False, isRequired = False, canRepeat = True, mightPack = True, typeCode = FieldType {getFieldType = 18}, typeName = Nothing, hsRawDefault = Nothing, hsDefault = Nothing}], descOneofs = fromList [], keys = fromList [], extRanges = [], knownKeys = fromList [], storeUnknown = False, lazyFields = False, makeLenses = False},DescriptorInfo {descName = ProtoName {protobufName = FIName \".RLWE.Kq\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"Kq\"}, descFilePath = [\"Crypto\",\"Proto\",\"RLWE\",\"Kq.hs\"], isGroup = False, fields = fromList [FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.Kq.m\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"Kq\"], baseName' = FName \"m\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 1}, wireTag = WireTag {getWireTag = 8}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 13}, typeName = Nothing, hsRawDefault = Nothing, hsDefault = Nothing},FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.Kq.q\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"Kq\"], baseName' = FName \"q\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 2}, wireTag = WireTag {getWireTag = 16}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 4}, typeName = Nothing, hsRawDefault = Nothing, hsDefault = Nothing},FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.Kq.xs\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"Kq\"], baseName' = FName \"xs\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 3}, wireTag = WireTag {getWireTag = 25}, packedTag = Just (WireTag {getWireTag = 25},WireTag {getWireTag = 26}), wireTagLength = 1, isPacked = False, isRequired = False, canRepeat = True, mightPack = True, typeCode = FieldType {getFieldType = 1}, typeName = Nothing, hsRawDefault = Nothing, hsDefault = Nothing}], descOneofs = fromList [], keys = fromList [], extRanges = [], knownKeys = fromList [], storeUnknown = False, lazyFields = False, makeLenses = False}], enums = [], oneofs = [], knownKeyMap = fromList []}"  fileDescriptorProto :: FileDescriptorProto fileDescriptorProto  = P'.getFromBS (P'.wireGet 11)     (P'.pack-      "\132\STX\n\nRLWE.proto\"6\n\nSampleCont\DC2\DC3\n\SOHa\CAN\SOH \STX(\v2\b.RLWE.Rq\DC2\DC3\n\SOHb\CAN\STX \STX(\v2\b.RLWE.Kq\"6\n\nSampleDisc\DC2\DC3\n\SOHa\CAN\SOH \STX(\v2\b.RLWE.Rq\DC2\DC3\n\SOHb\CAN\STX \STX(\v2\b.RLWE.Rq\"6\n\nSampleRLWR\DC2\DC3\n\SOHa\CAN\SOH \STX(\v2\b.RLWE.Rq\DC2\DC3\n\SOHb\CAN\STX \STX(\v2\b.RLWE.Rq\"&\n\STXRq\DC2\t\n\SOHm\CAN\SOH \STX(\r\DC2\t\n\SOHq\CAN\STX \STX(\EOT\DC2\n\n\STXxs\CAN\ETX \ETX(\DC2\"&\n\STXKq\DC2\t\n\SOHm\CAN\SOH \STX(\r\DC2\t\n\SOHq\CAN\STX \STX(\SOH\DC2\n\n\STXxs\CAN\ETX \ETX(\SOH")+      "\132\STX\n\nRLWE.proto\"6\n\nSampleCont\DC2\DC3\n\SOHa\CAN\SOH \STX(\v2\b.RLWE.Rq\DC2\DC3\n\SOHb\CAN\STX \STX(\v2\b.RLWE.Kq\"6\n\nSampleDisc\DC2\DC3\n\SOHa\CAN\SOH \STX(\v2\b.RLWE.Rq\DC2\DC3\n\SOHb\CAN\STX \STX(\v2\b.RLWE.Rq\"6\n\nSampleRLWR\DC2\DC3\n\SOHa\CAN\SOH \STX(\v2\b.RLWE.Rq\DC2\DC3\n\SOHb\CAN\STX \STX(\v2\b.RLWE.Rq\"&\n\STXRq\DC2\t\n\SOHm\CAN\SOH \STX(\r\DC2\t\n\SOHq\CAN\STX \STX(\EOT\DC2\n\n\STXxs\CAN\ETX \ETX(\DC2\"&\n\STXKq\DC2\t\n\SOHm\CAN\SOH \STX(\r\DC2\t\n\SOHq\CAN\STX \STX(\EOT\DC2\n\n\STXxs\CAN\ETX \ETX(\SOH")
Crypto/Proto/RLWE/Kq.hs view
@@ -8,7 +8,7 @@ import qualified Data.Data as Prelude' import qualified Text.ProtocolBuffers.Header as P' -data Kq = Kq{m :: !(P'.Word32), q :: !(P'.Double), xs :: !(P'.Seq P'.Double)}+data Kq = Kq{m :: !(P'.Word32), q :: !(P'.Word64), xs :: !(P'.Seq P'.Double)}         deriving (Prelude'.Show, Prelude'.Eq, Prelude'.Ord, Prelude'.Typeable, Prelude'.Data, Prelude'.Generic)  instance P'.Mergeable Kq where@@ -24,7 +24,7 @@        11 -> P'.prependMessageSize calc'Size        _ -> P'.wireSizeErr ft' self'     where-        calc'Size = (P'.wireSizeReq 1 13 x'1 + P'.wireSizeReq 1 1 x'2 + P'.wireSizeRep 1 1 x'3)+        calc'Size = (P'.wireSizeReq 1 13 x'1 + P'.wireSizeReq 1 4 x'2 + P'.wireSizeRep 1 1 x'3)   wirePut ft' self'@(Kq x'1 x'2 x'3)    = case ft' of        10 -> put'Fields@@ -36,7 +36,7 @@         put'Fields          = do              P'.wirePutReq 8 13 x'1-             P'.wirePutReq 17 1 x'2+             P'.wirePutReq 16 4 x'2              P'.wirePutRep 25 1 x'3   wireGet ft'    = case ft' of@@ -47,7 +47,7 @@         update'Self wire'Tag old'Self          = case wire'Tag of              8 -> Prelude'.fmap (\ !new'Field -> old'Self{m = new'Field}) (P'.wireGet 13)-             17 -> Prelude'.fmap (\ !new'Field -> old'Self{q = new'Field}) (P'.wireGet 1)+             16 -> Prelude'.fmap (\ !new'Field -> old'Self{q = new'Field}) (P'.wireGet 4)              25 -> Prelude'.fmap (\ !new'Field -> old'Self{xs = P'.append (xs old'Self) new'Field}) (P'.wireGet 1)              26 -> Prelude'.fmap (\ !new'Field -> old'Self{xs = P'.mergeAppend (xs old'Self) new'Field}) (P'.wireGetPacked 1)              _ -> let (field'Number, wire'Type) = P'.splitWireTag wire'Tag in P'.unknown field'Number wire'Type old'Self@@ -58,10 +58,10 @@ instance P'.GPB Kq  instance P'.ReflectDescriptor Kq where-  getMessageInfo _ = P'.GetMessageInfo (P'.fromDistinctAscList [8, 17]) (P'.fromDistinctAscList [8, 17, 25, 26])+  getMessageInfo _ = P'.GetMessageInfo (P'.fromDistinctAscList [8, 16]) (P'.fromDistinctAscList [8, 16, 25, 26])   reflectDescriptorInfo _    = Prelude'.read-      "DescriptorInfo {descName = ProtoName {protobufName = FIName \".RLWE.Kq\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"Kq\"}, descFilePath = [\"Crypto\",\"Proto\",\"RLWE\",\"Kq.hs\"], isGroup = False, fields = fromList [FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.Kq.m\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"Kq\"], baseName' = FName \"m\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 1}, wireTag = WireTag {getWireTag = 8}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 13}, typeName = Nothing, hsRawDefault = Nothing, hsDefault = Nothing},FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.Kq.q\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"Kq\"], baseName' = FName \"q\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 2}, wireTag = WireTag {getWireTag = 17}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 1}, typeName = Nothing, hsRawDefault = Nothing, hsDefault = Nothing},FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.Kq.xs\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"Kq\"], baseName' = FName \"xs\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 3}, wireTag = WireTag {getWireTag = 25}, packedTag = Just (WireTag {getWireTag = 25},WireTag {getWireTag = 26}), wireTagLength = 1, isPacked = False, isRequired = False, canRepeat = True, mightPack = True, typeCode = FieldType {getFieldType = 1}, typeName = Nothing, hsRawDefault = Nothing, hsDefault = Nothing}], descOneofs = fromList [], keys = fromList [], extRanges = [], knownKeys = fromList [], storeUnknown = False, lazyFields = False, makeLenses = False}"+      "DescriptorInfo {descName = ProtoName {protobufName = FIName \".RLWE.Kq\", haskellPrefix = [MName \"Crypto\",MName \"Proto\"], parentModule = [MName \"RLWE\"], baseName = MName \"Kq\"}, descFilePath = [\"Crypto\",\"Proto\",\"RLWE\",\"Kq.hs\"], isGroup = False, fields = fromList [FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.Kq.m\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"Kq\"], baseName' = FName \"m\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 1}, wireTag = WireTag {getWireTag = 8}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 13}, typeName = Nothing, hsRawDefault = Nothing, hsDefault = Nothing},FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.Kq.q\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"Kq\"], baseName' = FName \"q\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 2}, wireTag = WireTag {getWireTag = 16}, packedTag = Nothing, wireTagLength = 1, isPacked = False, isRequired = True, canRepeat = False, mightPack = False, typeCode = FieldType {getFieldType = 4}, typeName = Nothing, hsRawDefault = Nothing, hsDefault = Nothing},FieldInfo {fieldName = ProtoFName {protobufName' = FIName \".RLWE.Kq.xs\", haskellPrefix' = [MName \"Crypto\",MName \"Proto\"], parentModule' = [MName \"RLWE\",MName \"Kq\"], baseName' = FName \"xs\", baseNamePrefix' = \"\"}, fieldNumber = FieldId {getFieldId = 3}, wireTag = WireTag {getWireTag = 25}, packedTag = Just (WireTag {getWireTag = 25},WireTag {getWireTag = 26}), wireTagLength = 1, isPacked = False, isRequired = False, canRepeat = True, mightPack = True, typeCode = FieldType {getFieldType = 1}, typeName = Nothing, hsRawDefault = Nothing, hsDefault = Nothing}], descOneofs = fromList [], keys = fromList [], extRanges = [], knownKeys = fromList [], storeUnknown = False, lazyFields = False, makeLenses = False}"  instance P'.TextType Kq where   tellT = P'.tellSubMessage
benchmarks/CycBenches.hs view
@@ -1,13 +1,14 @@-{-# LANGUAGE DataKinds, FlexibleContexts,-             NoImplicitPrelude, RebindableSyntax,-             ScopedTypeVariables, TypeFamilies,-             TypeOperators, UndecidableInstances #-}+{-# LANGUAGE DataKinds           #-}+{-# LANGUAGE FlexibleContexts    #-}+{-# LANGUAGE NoImplicitPrelude   #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies        #-}  module CycBenches (cycBenches) where  import Apply.Cyc import Benchmarks-import Utils+import BenchParams  import Control.Monad.Random @@ -15,24 +16,30 @@ import Crypto.Lol.Types import Crypto.Random.DRBG -import Data.Singletons-import Data.Promotion.Prelude.Eq-import Data.Singletons.TypeRepStar ()- cycBenches :: IO Benchmark cycBenches = benchGroup "Cyc" [-  benchGroup "unzipCycPow" $ applyUnzip  allParams    $ hideArgs bench_unzipCycPow,-  benchGroup "unzipCycCRT" $ applyUnzip  allParams    $ hideArgs bench_unzipCycCRT,-  benchGroup "*"           $ applyBasic  allParams    $ hideArgs bench_mul,-  benchGroup "crt"         $ applyBasic  allParams    $ hideArgs bench_crt,-  benchGroup "crtInv"      $ applyBasic  allParams    $ hideArgs bench_crtInv,-  benchGroup "l"           $ applyBasic  allParams    $ hideArgs bench_l,-  benchGroup "*g Pow"      $ applyBasic  allParams    $ hideArgs bench_mulgPow,-  benchGroup "*g CRT"      $ applyBasic  allParams    $ hideArgs bench_mulgCRT,-  benchGroup "lift"        $ applyLift   liftParams   $ hideArgs bench_liftPow,-  benchGroup "error"       $ applyError  errorParams  $ hideArgs $ bench_errRounded 0.1,-  benchGroup "twace"       $ applyTwoIdx twoIdxParams $ hideArgs bench_twacePow,-  benchGroup "embed"       $ applyTwoIdx twoIdxParams $ hideArgs bench_embedPow+  benchGroup "unzipPow"    $ [hideArgs bench_unzipCycPow testParam],+  benchGroup "unzipDec"    $ [hideArgs bench_unzipCycDec testParam],+  benchGroup "unzipCRT"    $ [hideArgs bench_unzipCycCRT testParam],+  benchGroup "zipWith (*)" $ [hideArgs bench_mul testParam],+  benchGroup "crt"         $ [hideArgs bench_crt testParam],+  benchGroup "crtInv"      $ [hideArgs bench_crtInv testParam],+  benchGroup "l"           $ [hideArgs bench_l testParam],+  benchGroup "lInv"        $ [hideArgs bench_lInv testParam],+  benchGroup "*g Pow"      $ [hideArgs bench_mulgPow testParam],+  benchGroup "*g Dec"      $ [hideArgs bench_mulgDec testParam],+  benchGroup "*g CRT"      $ [hideArgs bench_mulgCRT testParam],+  benchGroup "divg Pow"    $ [hideArgs bench_divgPow testParam],+  benchGroup "divg Dec"    $ [hideArgs bench_divgDec testParam],+  benchGroup "divg CRT"    $ [hideArgs bench_divgCRT testParam],+  benchGroup "lift"        $ [hideArgs bench_liftPow testParam],+  benchGroup "error"       $ [hideArgs (bench_errRounded 0.1) testParam'],+  benchGroup "twacePow"    $ [hideArgs bench_twacePow twoIdxParam],+  benchGroup "twaceDec"    $ [hideArgs bench_twaceDec twoIdxParam],+  benchGroup "twaceCRT"    $ [hideArgs bench_twaceCRT twoIdxParam],+  benchGroup "embedPow"    $ [hideArgs bench_embedPow twoIdxParam],+  benchGroup "embedDec"    $ [hideArgs bench_embedDec twoIdxParam],+  benchGroup "embedCRT"    $ [hideArgs bench_embedCRT twoIdxParam]   ]  bench_unzipCycPow :: (UnzipCtx t m r) => Cyc t m (r,r) -> Bench '(t,m,r)@@ -40,6 +47,11 @@   let a' = advisePow a   in bench unzipCyc a' +bench_unzipCycDec :: (UnzipCtx t m r) => Cyc t m (r,r) -> Bench '(t,m,r)+bench_unzipCycDec a =+  let a' = adviseDec a+  in bench unzipCyc a'+ bench_unzipCycCRT :: (UnzipCtx t m r) => Cyc t m (r,r) -> Bench '(t,m,r) bench_unzipCycCRT a =   let a' = adviseCRT a@@ -64,18 +76,38 @@ bench_l :: (BasicCtx t m r) => Cyc t m r -> Bench '(t,m,r) bench_l x = let y = adviseDec x in bench advisePow y +-- convert input from Pow basis to Dec basis+bench_lInv :: (BasicCtx t m r) => Cyc t m r -> Bench '(t,m,r)+bench_lInv x = let y = advisePow x in bench adviseDec y+ -- lift an element in the Pow basis bench_liftPow :: forall t m r . (LiftCtx t m r) => Cyc t m r -> Bench '(t,m,r)-bench_liftPow x = let y = advisePow x in bench (liftCyc Pow :: Cyc t m r -> Cyc t m (LiftOf r)) y+bench_liftPow x = let y = advisePow x in bench (liftCyc Pow) y  -- multiply by g when input is in Pow basis bench_mulgPow :: (BasicCtx t m r) => Cyc t m r -> Bench '(t,m,r) bench_mulgPow x = let y = advisePow x in bench mulG y +-- multiply by g when input is in Dec basis+bench_mulgDec :: (BasicCtx t m r) => Cyc t m r -> Bench '(t,m,r)+bench_mulgDec x = let y = adviseDec x in bench mulG y+ -- multiply by g when input is in CRT basis bench_mulgCRT :: (BasicCtx t m r) => Cyc t m r -> Bench '(t,m,r) bench_mulgCRT x = let y = adviseCRT x in bench mulG y +-- divide by g when input is in Pow basis+bench_divgPow :: (BasicCtx t m r) => Cyc t m r -> Bench '(t,m,r)+bench_divgPow x = let y = advisePow $ mulG x in bench divG y++-- divide by g when input is in Dec basis+bench_divgDec :: (BasicCtx t m r) => Cyc t m r -> Bench '(t,m,r)+bench_divgDec x = let y = adviseDec $ mulG x in bench divG y++-- divide by g when input is in CRT basis+bench_divgCRT :: (BasicCtx t m r) => Cyc t m r -> Bench '(t,m,r)+bench_divgCRT x = let y = adviseCRT x in bench divG y+ -- generate a rounded error term bench_errRounded :: forall t m r gen . (ErrorCtx t m r gen)   => Double -> Bench '(t,m,r,gen)@@ -89,46 +121,32 @@   let y = advisePow x   in bench (twace :: Cyc t m' r -> Cyc t m r) y +bench_twaceDec :: forall t m m' r . (TwoIdxCtx t m m' r)+  => Cyc t m' r -> Bench '(t,m,m',r)+bench_twaceDec x =+  let y = adviseDec x+  in bench (twace :: Cyc t m' r -> Cyc t m r) y++bench_twaceCRT :: forall t m m' r . (TwoIdxCtx t m m' r)+  => Cyc t m' r -> Bench '(t,m,m',r)+bench_twaceCRT x =+  let y = adviseCRT x+  in bench (twace :: Cyc t m' r -> Cyc t m r) y+ bench_embedPow :: forall t m m' r . (TwoIdxCtx t m m' r)   => Cyc t m r -> Bench '(t,m,m',r) bench_embedPow x =   let y = advisePow x-  in bench (embed :: Cyc t m r -> Cyc t m' r) y--type Tensors = '[CT,RT]-type MRCombos =-  '[ '(F1024, Zq 1051649),      -- 1024 / 512-     '(F2048, Zq 1054721),      -- 2048 / 1024-     '(F64 * F27, Zq 1048897),  -- 1728 / 576-     '(F64 * F81, Zq 1073089),  -- 5184 / 1728-     '(F64*F9*F25, Zq 1065601)  -- 14400 / 3840-    ]--type MM'RCombos =-  '[ '(F8 * F91, F8 * F91 * F4, Zq 8737),-     '(F8 * F91, F8 * F91 * F5, Zq 14561),-     '(F128, F128 * F91, Zq 23297)-    ]---- EAC: must be careful where we use Nub: apparently TypeRepStar doesn't work well with the Tensor constructors-type AllParams = ( '(,) <$> Tensors) <*> MRCombos-allParams :: Proxy AllParams-allParams = Proxy--type LiftParams = ( '(,) <$> Tensors) <*> MRCombos-liftParams :: Proxy LiftParams-liftParams = Proxy--type TwoIdxParams = ( '(,) <$> Tensors) <*> MM'RCombos-twoIdxParams :: Proxy TwoIdxParams-twoIdxParams = Proxy--type ErrorParams = ( '(,) <$> '[HashDRBG]) <*> LiftParams-errorParams :: Proxy ErrorParams-errorParams = Proxy+  in bench (advisePow . embed :: Cyc t m r -> Cyc t m' r) y -data Liftable :: TyFun (Factored, *) Bool -> *-type instance Apply Liftable '(m',r) = Int64 :== (LiftOf r)+bench_embedDec :: forall t m m' r . (TwoIdxCtx t m m' r)+  => Cyc t m r -> Bench '(t,m,m',r)+bench_embedDec x =+  let y = adviseDec x+  in bench (adviseDec . embed :: Cyc t m r -> Cyc t m' r) y -data RemoveM :: TyFun (Factored, Factored, *) (Factored, *) -> *-type instance Apply RemoveM '(m,m',r) = '(m',r)+bench_embedCRT :: forall t m m' r . (TwoIdxCtx t m m' r)+  => Cyc t m r -> Bench '(t,m,m',r)+bench_embedCRT x =+  let y = adviseCRT x+  in bench (adviseCRT . embed :: Cyc t m r -> Cyc t m' r) y
benchmarks/Main.hs view
@@ -1,15 +1,177 @@+{-+import TensorBenches+import Criterion.Main +main :: IO ()+main = defaultMain =<< sequence [+  tensorBenches+  ]+-}+{-# LANGUAGE BangPatterns, RecordWildCards #-}+ import CycBenches+import SimpleTensorBenches import TensorBenches+import SimpleUCycBenches import UCycBenches-import ZqBenches -import Criterion.Main+import Criterion.Internal (runAndAnalyseOne)+import Criterion.Main.Options (defaultConfig)+import Criterion.Measurement (secs)+import Criterion.Monad (Criterion, withConfig)+import Criterion.Types+import Control.Monad (foldM, forM_, when)+import Control.Monad.IO.Class (MonadIO, liftIO) -main :: IO ()-main = defaultMain =<< sequence [-  zqBenches,-  tensorBenches,-  ucycBenches,-  cycBenches+import Control.Exception (evaluate)++import Control.DeepSeq (rnf)++import Data.List (transpose)+import qualified Data.Map as Map+import Data.Maybe++import Statistics.Resampling.Bootstrap (Estimate(..))+import System.Console.ANSI+import System.IO+import Text.Printf++-- table print parameters+colWidth, testNameWidth :: Int+colWidth = 15+testNameWidth = 40+verb :: Verb+verb = Progress++benches :: [String]+benches = [+  "unzipPow",+  "unzipDec",+  "unzipCRT",+  "zipWith (*)",+  "crt",+  "crtInv",+  "l",+  "lInv",+  "*g Pow",+  "*g Dec",+  "*g CRT",+  "divg Pow",+  "divg Dec",+  "divg CRT",+  "lift",+  "error",+  "twacePow",+  "twaceDec",+  "twaceCRT",+  "embedPow",+  "embedDec",+  "embedCRT"+   ]++data Verb = Progress | Abridged | Full deriving (Eq)++main :: IO ()+main = do+  hSetBuffering stdout NoBuffering -- for better printing of progress+  reports <- mapM (getReports =<<) [+    simpleTensorBenches,+    tensorBenches,+    simpleUCycBenches,+    ucycBenches,+    cycBenches+    ]+  when (verb == Progress) $ putStrLn ""+  printTable $ map reverse reports++printTable :: [[Report]] -> IO ()+printTable rpts = do+  let colLbls = map (takeWhile (/= '/') . reportName . head) rpts+  printf testName ""+  mapM_ (\lbl -> printf col lbl) colLbls+  printf "\n"+  mapM_ printRow $ transpose rpts++col, testName :: String+testName = "%-" ++ (show testNameWidth) ++ "s "+col = "%-" ++ (show colWidth) ++ "s "++printANSI :: (MonadIO m) => Color -> String -> m ()+printANSI sgr str = liftIO $ do+  setSGR [SetColor Foreground Vivid sgr]+  putStrLn str+  setSGR [Reset]++config :: Config+config = defaultConfig {verbosity = if verb == Full then Normal else Quiet}++getRuntime :: Report -> Double+getRuntime Report{..} =+  let SampleAnalysis{..} = reportAnalysis+      (builtin, _) = splitAt 1 anRegress+      mests = map (\Regression{..} -> Map.lookup "iters" regCoeffs) builtin+      [Estimate{..}] = catMaybes mests+  in estPoint++-- See Criterion.Internal.analyseOne+printRow :: [Report] -> IO ()+printRow xs@(rpt : _) = do+  printf testName $ stripOuterGroup $ reportName rpt+  let times = map getRuntime xs+      minTime = minimum times+      printCol t =+        if t > (1.1*minTime)+        then do+          setSGR [SetColor Foreground Vivid Red]+          printf col $ secs t+          setSGR [Reset]+        else printf col $ secs t+  forM_ times printCol+  putStrLn ""++stripOuterGroup :: String -> String+stripOuterGroup = tail . dropWhile (/= '/')++getReports :: Benchmark -> IO [Report]+getReports = withConfig config . runAndAnalyse++-- | Run, and analyse, one or more benchmarks.+-- From Criterion.Internal+runAndAnalyse :: Benchmark+              -> Criterion [Report]+runAndAnalyse bs = for bs $ \idx desc bm -> do+  when (verb == Abridged || verb == Full) $ liftIO $ putStr $ "benchmark " ++ desc+  when (verb == Full) $ liftIO $ putStrLn ""+  (Analysed rpt) <- runAndAnalyseOne idx desc bm+  when (verb == Progress) $ liftIO $ putStr "."+  when (verb == Abridged) $ liftIO $ putStrLn $ "..." ++ (secs $ getRuntime rpt)+  return rpt++-- | Iterate over benchmarks.+-- From Criterion.Internal+for :: MonadIO m => Benchmark+    -> (Int -> String -> Benchmarkable -> m a) -> m [a]+for bs0 handle = snd <$> go (0::Int, []) ("", bs0)+  where+    select = flip elem benches . takeWhile (/= '/') . stripOuterGroup+    go (!idx,drs) (pfx, Environment mkenv mkbench)+      | shouldRun pfx mkbench = do+        e <- liftIO $ do+          ee <- mkenv+          evaluate (rnf ee)+          return ee+        go (idx,drs) (pfx, mkbench e)+      | otherwise = return (idx,drs)+    go (!idx, drs) (pfx, Benchmark desc b)+      | select desc' = do+          x <- handle idx desc' b;+          return (idx + 1, x:drs)+      | otherwise    = return (idx, drs)+      where desc' = addPrefix pfx desc+    go (!idx,drs) (pfx, BenchGroup desc bs) =+      foldM go (idx,drs) [(addPrefix pfx desc, b) | b <- bs]++    shouldRun pfx mkbench =+      any (select . addPrefix pfx) . benchNames . mkbench $+      error "Criterion.env could not determine the list of your benchmarks since they force the environment (see the documentation for details)"
benchmarks/TensorBenches.hs view
@@ -1,28 +1,131 @@-{-# LANGUAGE DataKinds, FlexibleContexts,-             NoImplicitPrelude, RebindableSyntax,-             ScopedTypeVariables, TypeFamilies,-             TypeOperators, UndecidableInstances #-}+{-# LANGUAGE DataKinds            #-}+{-# LANGUAGE FlexibleContexts     #-}+{-# LANGUAGE NoImplicitPrelude    #-}+{-# LANGUAGE ScopedTypeVariables  #-}+{-# LANGUAGE TypeFamilies         #-}+{-# LANGUAGE TypeOperators        #-}+{-# LANGUAGE UndecidableInstances #-}  module TensorBenches (tensorBenches) where  import Apply.Cyc import Benchmarks-import Utils+import BenchParams -import Crypto.Lol+import Control.Applicative+import Control.Monad.Random++import Crypto.Lol.Prelude import Crypto.Lol.Cyclotomic.Tensor import Crypto.Lol.Types+import Crypto.Random.DRBG  tensorBenches :: IO Benchmark tensorBenches = benchGroup "Tensor" [-  benchGroup "l" $ applyBasic (Proxy::Proxy QuickParams) $ hideArgs bench_l]+  benchGroup "unzipPow"    $ [hideArgs bench_unzip testParam],+  benchGroup "unzipDec"    $ [hideArgs bench_unzip testParam],+  benchGroup "unzipCRT"    $ [hideArgs bench_unzip testParam],+  benchGroup "zipWith (*)" $ [hideArgs bench_mul testParam],+  benchGroup "crt"         $ [hideArgs bench_crt testParam],+  benchGroup "crtInv"      $ [hideArgs bench_crtInv testParam],+  benchGroup "l"           $ [hideArgs bench_l testParam],+  benchGroup "lInv"        $ [hideArgs bench_lInv testParam],+  benchGroup "*g Pow"      $ [hideArgs bench_mulgPow testParam],+  benchGroup "*g Dec"      $ [hideArgs bench_mulgDec testParam],+  benchGroup "*g CRT"      $ [hideArgs bench_mulgCRT testParam],+  benchGroup "divg Pow"    $ [hideArgs bench_divgPow testParam],+  benchGroup "divg Dec"    $ [hideArgs bench_divgDec testParam],+  benchGroup "divg CRT"    $ [hideArgs bench_divgCRT testParam],+  benchGroup "lift"        $ [hideArgs bench_liftPow testParam],+  benchGroup "error"       $ [hideArgs (bench_errRounded 0.1) testParam'],+  benchGroup "twacePow"    $ [hideArgs bench_twacePow twoIdxParam],+  benchGroup "twaceDec"    $ [hideArgs bench_twacePow twoIdxParam], -- yes, twacePow is correct here. It's the same function!+  benchGroup "twaceCRT"    $ [hideArgs bench_twaceCRT twoIdxParam],+  benchGroup "embedPow"    $ [hideArgs bench_embedPow twoIdxParam],+  benchGroup "embedDec"    $ [hideArgs bench_embedDec twoIdxParam],+  benchGroup "embedCRT"    $ [hideArgs bench_embedCRT twoIdxParam]+  ] +bench_unzip :: (UnzipCtx t m r) => t m (r,r) -> Bench '(t,m,r)+bench_unzip = bench unzipT++-- no CRT conversion, just coefficient-wise multiplication+bench_mul :: (BasicCtx t m r) => t m r -> t m r -> Bench '(t,m,r)+bench_mul a = bench (zipWithT (*) a)++-- convert input from Pow basis to CRT basis+bench_crt :: (BasicCtx t m r) => t m r -> Bench '(t,m,r)+bench_crt = bench (fromJust' "TensorBenches.bench_crt" crt)++-- convert input from CRT basis to Pow basis+bench_crtInv :: (BasicCtx t m r) => t m r -> Bench '(t,m,r)+bench_crtInv = bench (fromJust' "TensorBenches.bench_crtInv" crtInv)+ -- convert input from Dec basis to Pow basis-bench_l :: (Tensor t, Fact m, Additive r, TElt t r, NFData (t m r)) => t m r -> Bench '(t,m,r)+bench_l :: (BasicCtx t m r) => t m r -> Bench '(t,m,r) bench_l = bench l -type QuickTest = '[ '(F128, Zq 257),-                    '(F32 * F9, Zq 577),-                    '(F32 * F9, Int64) ]-type Tensors = '[CT,RT]-type QuickParams = ( '(,) <$> Tensors) <*> QuickTest+-- convert input from Dec basis to Pow basis+bench_lInv :: (BasicCtx t m r) => t m r -> Bench '(t,m,r)+bench_lInv = bench lInv++-- lift an element in the Pow basis+bench_liftPow :: forall t m r . (LiftCtx t m r) => t m r -> Bench '(t,m,r)+bench_liftPow = bench (fmapT lift)++-- multiply by g when input is in Pow basis+bench_mulgPow :: (BasicCtx t m r) => t m r -> Bench '(t,m,r)+bench_mulgPow = bench mulGPow++-- multiply by g when input is in Dec basis+bench_mulgDec :: (BasicCtx t m r) => t m r -> Bench '(t,m,r)+bench_mulgDec = bench mulGDec++-- multiply by g when input is in CRT basis+bench_mulgCRT :: (BasicCtx t m r) => t m r -> Bench '(t,m,r)+bench_mulgCRT = bench (fromJust' "TensorBenches.bench_mulgCRT" mulGCRT)++-- divide by g when input is in Pow basis+bench_divgPow :: (BasicCtx t m r) => t m r -> Bench '(t,m,r)+bench_divgPow x =+  let y = mulGPow x+  in bench divGPow y++-- divide by g when input is in Dec basis+bench_divgDec :: (BasicCtx t m r) => t m r -> Bench '(t,m,r)+bench_divgDec x =+  let y = mulGDec x+  in bench divGDec y++-- divide by g when input is in CRT basis+bench_divgCRT :: (BasicCtx t m r) => t m r -> Bench '(t,m,r)+bench_divgCRT = bench (fromJust' "TensorBenches.bench_divgCRT" divGCRT)++-- generate a rounded error term+bench_errRounded :: forall t m r gen . (ErrorCtx t m r gen)+  => Double -> Bench '(t,m,r,gen)+bench_errRounded v = benchIO $ do+  gen <- newGenIO+  return $ evalRand+    (fmapT (roundMult one) <$>+      (tGaussianDec v :: Rand (CryptoRand gen) (t m Double)) :: Rand (CryptoRand gen) (t m (LiftOf r))) gen++bench_twacePow :: forall t m m' r . (TwoIdxCtx t m m' r)+  => t m' r -> Bench '(t,m,m',r)+bench_twacePow = bench (twacePowDec :: t m' r -> t m r)++bench_twaceCRT :: forall t m m' r . (TwoIdxCtx t m m' r)+  => t m' r -> Bench '(t,m,m',r)+bench_twaceCRT = bench (fromJust' "TensorBenches.bench_twaceCRT" twaceCRT :: t m' r -> t m r)++bench_embedPow :: forall t m m' r . (TwoIdxCtx t m m' r)+  => t m r -> Bench '(t,m,m',r)+bench_embedPow = bench (embedPow :: t m r -> t m' r)++bench_embedDec :: forall t m m' r . (TwoIdxCtx t m m' r)+  => t m r -> Bench '(t,m,m',r)+bench_embedDec = bench (embedDec :: t m r -> t m' r)++bench_embedCRT :: forall t m m' r . (TwoIdxCtx t m m' r)+  => t m r -> Bench '(t,m,m',r)+bench_embedCRT = bench (fromJust' "TensorBenches.bench_embedCRT" embedCRT :: t m r -> t m' r)
benchmarks/UCycBenches.hs view
@@ -1,48 +1,142 @@-{-# LANGUAGE DataKinds, FlexibleContexts,-             NoImplicitPrelude, RebindableSyntax,-             ScopedTypeVariables, TypeFamilies,-             TypeOperators, UndecidableInstances #-}+{-# LANGUAGE DataKinds            #-}+{-# LANGUAGE FlexibleContexts     #-}+{-# LANGUAGE NoImplicitPrelude    #-}+{-# LANGUAGE ScopedTypeVariables  #-}+{-# LANGUAGE TypeFamilies         #-}  module UCycBenches (ucycBenches) where  import Apply.Cyc import Benchmarks-import Utils+import BenchParams -import Crypto.Lol+import Control.Monad.Random++import Crypto.Lol.Prelude import Crypto.Lol.Cyclotomic.UCyc import Crypto.Lol.Types+import Crypto.Random.DRBG  ucycBenches :: IO Benchmark ucycBenches = benchGroup "UCyc" [-  benchGroup "l"     $ applyBasic (Proxy::Proxy QuickParams) $ hideArgs bench_l,-  benchGroup "twace" $ applyTwoIdx twoIdxParams $ hideArgs bench_twacePow,-  benchGroup "embed" $ applyTwoIdx twoIdxParams $ hideArgs bench_embedPow+  benchGroup "unzipPow"    $ [hideArgs bench_unzipUCycPow testParam],+  benchGroup "unzipDec"    $ [hideArgs bench_unzipUCycDec testParam],+  benchGroup "unzipCRT"    $ [hideArgs bench_unzipUCycCRT testParam],+  benchGroup "zipWith (*)" $ [hideArgs bench_mul testParam],+  benchGroup "crt"         $ [hideArgs bench_crt testParam],+  benchGroup "crtInv"      $ [hideArgs bench_crtInv testParam],+  benchGroup "l"           $ [hideArgs bench_l testParam],+  benchGroup "lInv"        $ [hideArgs bench_lInv testParam],+  benchGroup "*g Pow"      $ [hideArgs bench_mulgPow testParam],+  benchGroup "*g Dec"      $ [hideArgs bench_mulgDec testParam],+  benchGroup "*g CRT"      $ [hideArgs bench_mulgCRT testParam],+  benchGroup "divg Pow"    $ [hideArgs bench_divgPow testParam],+  benchGroup "divg Dec"    $ [hideArgs bench_divgDec testParam],+  benchGroup "divg CRT"    $ [hideArgs bench_divgCRT testParam],+  benchGroup "lift"        $ [hideArgs bench_liftPow testParam],+  benchGroup "error"       $ [hideArgs (bench_errRounded 0.1) testParam'],+  benchGroup "twacePow"    $ [hideArgs bench_twacePow twoIdxParam],+  benchGroup "twaceDec"    $ [hideArgs bench_twaceDec twoIdxParam],+  benchGroup "twaceCRT"    $ [hideArgs bench_twaceCRT twoIdxParam],+  benchGroup "embedPow"    $ [hideArgs bench_embedPow twoIdxParam],+  benchGroup "embedDec"    $ [hideArgs bench_embedDec twoIdxParam],+  benchGroup "embedCRT"    $ [hideArgs bench_embedCRT twoIdxParam]   ] +bench_unzipUCycPow :: (UnzipCtx t m r) => UCyc t m P (r,r) -> Bench '(t,m,r)+bench_unzipUCycPow = bench unzipPow++bench_unzipUCycDec :: (UnzipCtx t m r) => UCyc t m D (r,r) -> Bench '(t,m,r)+bench_unzipUCycDec = bench unzipDec++bench_unzipUCycCRT :: (UnzipCtx t m r) => UCycPC t m (r,r) -> Bench '(t,m,r)+bench_unzipUCycCRT (Right a) = bench unzipCRTC a++pcToEC :: UCycPC t m r -> UCycEC t m r+pcToEC (Right x) = (Right x)++-- no CRT conversion, just coefficient-wise multiplication+bench_mul :: (BasicCtx t m r) => UCycPC t m r -> UCycPC t m r -> Bench '(t,m,r)+bench_mul a b =+  let a' = pcToEC a+      b' = pcToEC b+  in bench (a' *) b'++-- convert input from Pow basis to CRT basis+bench_crt :: (BasicCtx t m r) => UCyc t m P r -> Bench '(t,m,r)+bench_crt = bench toCRT++-- convert input from CRT basis to Pow basis+bench_crtInv :: (BasicCtx t m r) => UCycPC t m r -> Bench '(t,m,r)+bench_crtInv (Right a) = bench toPow a+ -- convert input from Dec basis to Pow basis bench_l :: (BasicCtx t m r) => UCyc t m D r -> Bench '(t,m,r) bench_l = bench toPow +-- convert input from Pow basis to Dec basis+bench_lInv :: (BasicCtx t m r) => UCyc t m P r -> Bench '(t,m,r)+bench_lInv = bench toDec++-- lift an element in the Pow basis+bench_liftPow :: (LiftCtx t m r) => UCyc t m P r -> Bench '(t,m,r)+bench_liftPow = bench lift++-- multiply by g when input is in Pow basis+bench_mulgPow :: (BasicCtx t m r) => UCyc t m P r -> Bench '(t,m,r)+bench_mulgPow = bench mulG++-- multiply by g when input is in Dec basis+bench_mulgDec :: (BasicCtx t m r) => UCyc t m D r -> Bench '(t,m,r)+bench_mulgDec = bench mulG++-- multiply by g when input is in CRT basis+bench_mulgCRT :: (BasicCtx t m r) => UCycPC t m r -> Bench '(t,m,r)+bench_mulgCRT (Right a) = bench mulG a++-- divide by g when input is in Pow basis+bench_divgPow :: (BasicCtx t m r) => UCyc t m P r -> Bench '(t,m,r)+bench_divgPow x =+  let y = mulG x+  in bench divGPow y++-- divide by g when input is in Dec basis+bench_divgDec :: (BasicCtx t m r) => UCyc t m D r -> Bench '(t,m,r)+bench_divgDec x =+  let y = mulG x+  in bench divGDec y++-- divide by g when input is in CRT basis+bench_divgCRT :: (BasicCtx t m r) => UCycPC t m r -> Bench '(t,m,r)+bench_divgCRT (Right a) = bench divGCRTC a++-- generate a rounded error term+bench_errRounded :: forall t m r gen . (ErrorCtx t m r gen)+  => Double -> Bench '(t,m,r,gen)+bench_errRounded v = benchIO $ do+  gen <- newGenIO+  return $ evalRand (errorRounded v :: Rand (CryptoRand gen) (UCyc t m D (LiftOf r))) gen+ bench_twacePow :: forall t m m' r . (TwoIdxCtx t m m' r)   => UCyc t m' P r -> Bench '(t,m,m',r) bench_twacePow = bench (twacePow :: UCyc t m' P r -> UCyc t m P r) +bench_twaceDec :: forall t m m' r . (TwoIdxCtx t m m' r)+  => UCyc t m' D r -> Bench '(t,m,m',r)+bench_twaceDec = bench (twaceDec :: UCyc t m' D r -> UCyc t m D r)++bench_twaceCRT :: forall t m m' r . (TwoIdxCtx t m m' r)+  => UCycPC t m' r -> Bench '(t,m,m',r)+bench_twaceCRT (Right a) = bench (twaceCRTC :: UCyc t m' C r -> UCycPC t m r) a+ bench_embedPow :: forall t m m' r . (TwoIdxCtx t m m' r)   => UCyc t m P r -> Bench '(t,m,m',r) bench_embedPow = bench (embedPow :: UCyc t m P r -> UCyc t m' P r) -type QuickTest = '[ '(F128, Zq 257),-                    '(F32 * F9, Zq 577),-                    '(F32 * F9, Int64) ]-type Tensors = '[CT,RT]-type QuickParams = ( '(,) <$> Tensors) <*> QuickTest+bench_embedDec :: forall t m m' r . (TwoIdxCtx t m m' r)+  => UCyc t m D r -> Bench '(t,m,m',r)+bench_embedDec = bench (embedDec :: UCyc t m D r -> UCyc t m' D r) -type MM'RCombos =-  '[ '(F8 * F91, F8 * F91 * F4, Zq 8737),-     '(F8 * F91, F8 * F91 * F5, Zq 14561),-     '(F128, F128 * F91, Zq 23297)-    ]-type TwoIdxParams = ( '(,) <$> Tensors) <*> MM'RCombos-twoIdxParams :: Proxy TwoIdxParams-twoIdxParams = Proxy+bench_embedCRT :: forall t m m' r . (TwoIdxCtx t m m' r)+  => UCycPC t m r -> Bench '(t,m,m',r)+bench_embedCRT (Right a) = bench (embedCRTC :: UCyc t m C r -> UCycPC t m' r) a
lol.cabal view
@@ -5,7 +5,7 @@ -- PVP summary:      +-+------- breaking API changes --                   | | +----- non-breaking API additions --                   | | | +--- code changes with no API change-version:             0.4.0.0+version:             0.5.0.0 synopsis:            A library for lattice cryptography. homepage:            https://github.com/cpeikert/Lol Bug-Reports:         https://github.com/cpeikert/Lol/issues@@ -84,8 +84,8 @@    -- ghc optimizations   if flag(opt)-    ghc-options: -O3 -Odph -funbox-strict-fields -fno-liberate-case -funfolding-use-threshold1000 -funfolding-keeness-factor1000-+    -- makes lift much faster!+    ghc-options: -funfolding-use-threshold1000   exposed-modules:     Crypto.Lol     Crypto.Lol.Types@@ -163,7 +163,6 @@     reflection >= 1.5.1 && < 2.2,     repa==3.4.*,     singletons >= 1.1.2.1 && < 2.2,-    storable-record >= 0.0.3 && < 0.1,     th-desugar >= 1.5.4 && < 1.7,     tagged-transformer >= 0.7 && < 0.9,     template-haskell  >=  2.2.0.0,@@ -206,14 +205,15 @@    if flag(llvm)     ghc-options: -fllvm -optlo-O3-  -- ghc-options: -threaded -rtsopts-  ghc-options: -O3 -Odph -funbox-strict-fields -fno-liberate-case -funfolding-use-threshold1000 -funfolding-keeness-factor1000-  -- ghc-options: -O2 -Odph -funbox-strict-fields -fwarn-dodgy-imports -rtsopts-  -- ghc-options: -fno-liberate-case -funfolding-use-threshold1000 -funfolding-keeness-factor1000+  ghc-options: -O2+  -- ghc-options: -ddump-to-file -ddump-simpl+  -- ghc-options: -dsuppress-coercions -dsuppress-type-applications -dsuppress-uniques -dsuppress-module-prefixes    build-depends:+    ansi-terminal,     arithmoi,     base,+    containers,     criterion,     deepseq,     DRBG,@@ -221,6 +221,7 @@     MonadRandom,     mtl,     singletons,+    statistics,     transformers,     vector,     repa
utils/Apply/Cyc.hs view
@@ -46,7 +46,7 @@  data UnzipCtxD type UnzipCtx t m r =-  (Fact m, CElt t (r,r), Random (t m (r,r)), CElt t r, ShowType '(t,m,r), NFElt r, Random r)+  (Fact m, CElt t (r,r), Random (t m (r,r)), CElt t r, ShowType '(t,m,r), NFElt r, Random r, NFData (t m r)) data instance ArgsCtx UnzipCtxD where     UzC :: (UnzipCtx t m r) => Proxy '(t,m,r) -> ArgsCtx UnzipCtxD instance (params `Satisfy` UnzipCtxD, UnzipCtx t m r)@@ -64,7 +64,7 @@ data LiftCtxD type LiftCtx t m r =   (BasicCtx t m r, Lift' r, CElt t (LiftOf r), NFElt (LiftOf r), ToInteger (LiftOf r),-   TElt CT r, TElt RT r, TElt CT (LiftOf r), TElt RT (LiftOf r))+   TElt CT r, TElt RT r, TElt CT (LiftOf r), TElt RT (LiftOf r), NFData (t m (LiftOf r))) data instance ArgsCtx LiftCtxD where     LC :: (LiftCtx t m r) => Proxy '(t,m,r) -> ArgsCtx LiftCtxD instance (params `Satisfy` LiftCtxD, LiftCtx t m r)@@ -81,7 +81,7 @@ data ErrorCtxD type ErrorCtx t m r gen = (CElt t r, Fact m, ShowType '(t,m,r,gen),                            CElt t (LiftOf r), NFElt (LiftOf r), Lift' r,-                           ToInteger (LiftOf r), CryptoRandomGen gen)+                           ToInteger (LiftOf r), CryptoRandomGen gen, NFData (t m (LiftOf r))) data instance ArgsCtx ErrorCtxD where     EC :: (ErrorCtx t m r gen) => Proxy '(t,m,r,gen) -> ArgsCtx ErrorCtxD instance (params `Satisfy` ErrorCtxD, ErrorCtx t m r gen)@@ -97,7 +97,7 @@  data TwoIdxCtxD type TwoIdxCtx t m m' r = (m `Divides` m', CElt t r, IntegralDomain r, Eq r, Random r, NFElt r,-                           ShowType '(t,m,m',r), Random (t m r), Random (t m' r))+                           ShowType '(t,m,m',r), Random (t m r), Random (t m' r), NFData (t m r), NFData (t m' r)) data instance ArgsCtx TwoIdxCtxD where     TI :: (TwoIdxCtx t m m' r) => Proxy '(t,m,m',r) -> ArgsCtx TwoIdxCtxD instance (params `Satisfy` TwoIdxCtxD, TwoIdxCtx t m m' r)
utils/Utils.hs view
@@ -10,7 +10,6 @@ ,type (<*>)  ,module Data.Promotion.Prelude.List-,goodQs ,showType ,ShowType) where @@ -22,16 +21,6 @@ import Crypto.Random.DRBG  import Data.Promotion.Prelude.List--import Math.NumberTheory.Primes.Testing (isPrime)---- an infinite list of primes greater than the input and congruent to--- 1 mod m-goodQs :: (Integral i) => i -> i -> [i]-goodQs m lower = checkVal (lower + ((m-lower) `mod` m) + 1)-  where checkVal v = if (isPrime (fromIntegral v :: Integer))-                     then v : checkVal (v+m)-                    else checkVal (v+m)  infixr 9 ** data a ** b