packages feed

lol 0.2.0.1 → 0.3.0.0

raw patch · 86 files changed

+4498/−5193 lines, 86 filesdep +monadcryptorandomdep +protocol-buffersdep +protocol-buffers-descriptordep ~data-defaultdep ~singletonsdep ~th-desugarsetup-changedPVP ok

version bump matches the API change (PVP)

Dependencies added: monadcryptorandom, protocol-buffers, protocol-buffers-descriptor

Dependency ranges changed: data-default, singletons, th-desugar, transformers

API changes (from Hackage documentation)

- Crypto.Lol.CRTrans: crtInfoFact :: (Fact m, CRTrans r) => TaggedT m Maybe (CRTInfo r)
- Crypto.Lol.CRTrans: crtInfoPPow :: (PPow pp, CRTrans r) => TaggedT pp Maybe (CRTInfo r)
- Crypto.Lol.CRTrans: crtInfoPrime :: (Prim p, CRTrans r) => TaggedT p Maybe (CRTInfo r)
- Crypto.Lol.CRTrans: gEmbPPow :: (PPow pp, CRTrans r) => TaggedT pp Maybe (Int -> r)
- Crypto.Lol.CRTrans: gEmbPrime :: (Prim p, CRTrans r) => TaggedT p Maybe (Int -> r)
- Crypto.Lol.CRTrans: instance (Crypto.Lol.CRTrans.CRTrans a, Crypto.Lol.CRTrans.CRTrans b) => Crypto.Lol.CRTrans.CRTrans (a, b)
- Crypto.Lol.CRTrans: instance Crypto.Lol.CRTrans.CRTrans GHC.Int.Int64
- Crypto.Lol.CRTrans: instance Crypto.Lol.CRTrans.CRTrans GHC.Integer.Type.Integer
- Crypto.Lol.CRTrans: instance Crypto.Lol.CRTrans.CRTrans GHC.Types.Double
- Crypto.Lol.CRTrans: instance Crypto.Lol.CRTrans.CRTrans GHC.Types.Int
- Crypto.Lol.CRTrans: instance Crypto.Lol.Types.Numeric.Transcendental a => Crypto.Lol.CRTrans.CRTrans (Crypto.Lol.Types.Complex.Complex a)
- Crypto.Lol.Cyclotomic.Cyc: instance (Crypto.Lol.LatticePrelude.Mod a, Crypto.Lol.Types.Numeric.Field b, Crypto.Lol.LatticePrelude.Lift a (Crypto.Lol.LatticePrelude.ModRep a), Crypto.Lol.LatticePrelude.Reduce (Crypto.Lol.LatticePrelude.LiftOf a) b, Crypto.Lol.Cyclotomic.Cyc.CElt t (a, b), Crypto.Lol.Cyclotomic.Cyc.CElt t a, Crypto.Lol.Cyclotomic.Cyc.CElt t b, Crypto.Lol.Cyclotomic.Cyc.CElt t (Crypto.Lol.LatticePrelude.LiftOf a)) => Crypto.Lol.Cyclotomic.RescaleCyc.RescaleCyc (Crypto.Lol.Cyclotomic.Cyc.Cyc t) (a, b) b
- Crypto.Lol.Cyclotomic.Cyc: instance (Crypto.Lol.LatticePrelude.Reduce a b, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Cyc.CElt t a, Crypto.Lol.Cyclotomic.Cyc.CElt t b) => Crypto.Lol.LatticePrelude.Reduce (Crypto.Lol.Cyclotomic.Cyc.Cyc t m a) (Crypto.Lol.Cyclotomic.Cyc.Cyc t m b)
- Crypto.Lol.Cyclotomic.Cyc: instance (Crypto.Lol.LatticePrelude.Rescale a b, Crypto.Lol.Cyclotomic.Cyc.CElt t a, Crypto.Lol.Cyclotomic.Tensor.TElt t b) => Crypto.Lol.Cyclotomic.RescaleCyc.RescaleCyc (Crypto.Lol.Cyclotomic.Cyc.Cyc t) a b
- Crypto.Lol.Cyclotomic.Cyc: instance (GHC.Show.Show r, GHC.Show.Show (Crypto.Lol.CRTrans.CRTExt r), Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Tensor.TElt t r, Crypto.Lol.Cyclotomic.Tensor.TElt t (Crypto.Lol.CRTrans.CRTExt r)) => GHC.Show.Show (Crypto.Lol.Cyclotomic.Cyc.Cyc t m r)
- Crypto.Lol.Cyclotomic.Cyc: instance (System.Random.Random r, Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Tensor.CRTElt t r) => System.Random.Random (Crypto.Lol.Cyclotomic.Cyc.Cyc t m r)
- Crypto.Lol.Cyclotomic.Cyc: unzipCElt :: (Tensor t, Fact m, CElt t (a, b), CElt t a, CElt t b) => Cyc t m (a, b) -> (Cyc t m a, Cyc t m b)
- Crypto.Lol.Cyclotomic.Linear: instance (Crypto.Lol.Cyclotomic.Cyc.CElt t zp, Crypto.Lol.Cyclotomic.Cyc.CElt t z, z ~ Crypto.Lol.LatticePrelude.LiftOf zp, Crypto.Lol.LatticePrelude.Lift zp z, Crypto.Lol.FactoredDefs.Fact s) => Crypto.Lol.LatticePrelude.Lift' (Crypto.Lol.Cyclotomic.Linear.Linear t zp e r s)
- Crypto.Lol.Cyclotomic.Linear: instance (Crypto.Lol.LatticePrelude.Reduce z zq, Crypto.Lol.FactoredDefs.Fact s, Crypto.Lol.Cyclotomic.Cyc.CElt t z, Crypto.Lol.Cyclotomic.Cyc.CElt t zq) => Crypto.Lol.LatticePrelude.Reduce (Crypto.Lol.Cyclotomic.Linear.Linear t z e r s) (Crypto.Lol.Cyclotomic.Linear.Linear t zq e r s)
- Crypto.Lol.Cyclotomic.Tensor: type CRTElt t r = (ZeroTestable r, IntegralDomain r, CRTrans r, TElt t r)
- Crypto.Lol.Cyclotomic.Tensor: unzipTElt :: (Tensor t, Fact m, TElt t (a, b), TElt t a, TElt t b) => t m (a, b) -> (t m a, t m b)
- Crypto.Lol.Cyclotomic.UCyc: embedCRT :: (m `Divides` m', UCElt t r) => UCyc t m C r -> Either (UCyc t m' P r) (UCyc t m' C r)
- Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.UCyc.UCElt t r) => Algebra.Additive.C (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.C r)
- Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.UCyc.UCElt t r) => Algebra.Ring.C (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.C r)
- Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.LatticePrelude.Lift' r, Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Tensor.TElt t r, Crypto.Lol.Cyclotomic.Tensor.TElt t (Crypto.Lol.LatticePrelude.LiftOf r)) => Crypto.Lol.LatticePrelude.Lift' (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.D r)
- Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.LatticePrelude.Lift' r, Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Tensor.TElt t r, Crypto.Lol.Cyclotomic.Tensor.TElt t (Crypto.Lol.LatticePrelude.LiftOf r)) => Crypto.Lol.LatticePrelude.Lift' (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.P r)
- Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.LatticePrelude.Reduce a b, Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Tensor.TElt t a, Crypto.Lol.Cyclotomic.Tensor.TElt t b) => Crypto.Lol.LatticePrelude.Reduce (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.D a) (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.D b)
- Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.LatticePrelude.Reduce a b, Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Tensor.TElt t a, Crypto.Lol.Cyclotomic.Tensor.TElt t b) => Crypto.Lol.LatticePrelude.Reduce (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.P a) (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.P b)
- Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.LatticePrelude.Rescale a b, Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Tensor.TElt t a, Crypto.Lol.Cyclotomic.Tensor.TElt t b) => Crypto.Lol.LatticePrelude.Rescale (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.D a) (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.D b)
- Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.LatticePrelude.Rescale a b, Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Tensor.TElt t a, Crypto.Lol.Cyclotomic.Tensor.TElt t b) => Crypto.Lol.LatticePrelude.Rescale (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.P a) (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.P b)
- Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.Types.Numeric.Ring r, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.UCyc.UCElt t r) => Algebra.Module.C r (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.C r)
- Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.Types.Numeric.ZeroTestable r, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.UCyc.UCElt t r) => Algebra.ZeroTestable.C (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.C r)
- Crypto.Lol.Cyclotomic.UCyc: instance (GHC.Classes.Eq r, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.UCyc.UCElt t r) => GHC.Classes.Eq (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.C r)
- Crypto.Lol.Cyclotomic.UCyc: instance (GHC.Show.Show r, GHC.Show.Show (Crypto.Lol.CRTrans.CRTExt r), Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Tensor.TElt t r, Crypto.Lol.Cyclotomic.Tensor.TElt t (Crypto.Lol.CRTrans.CRTExt r)) => GHC.Show.Show (Crypto.Lol.Cyclotomic.UCyc.UCyc t m rep r)
- Crypto.Lol.Cyclotomic.UCyc: instance (System.Random.Random r, Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Tensor.CRTElt t r) => 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.Cyclotomic.UCyc: instance forall (k :: BOX) (t :: k -> * -> *) (m :: k) r. Test.QuickCheck.Arbitrary.Arbitrary (t m r) => Test.QuickCheck.Arbitrary.Arbitrary (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.C r)
- Crypto.Lol.Cyclotomic.UCyc: instance forall (k :: BOX) (t :: k -> * -> *) (m :: k) r. Test.QuickCheck.Arbitrary.Arbitrary (t m r) => Test.QuickCheck.Arbitrary.Arbitrary (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.D r)
- Crypto.Lol.Cyclotomic.UCyc: instance forall (k :: BOX) (t :: k -> * -> *) (m :: k) r. Test.QuickCheck.Arbitrary.Arbitrary (t m r) => Test.QuickCheck.Arbitrary.Arbitrary (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.P r)
- Crypto.Lol.Cyclotomic.UCyc: instance forall (k :: BOX) fp (d :: k) (t :: Crypto.Lol.FactoredDefs.Factored -> * -> *) (m :: Crypto.Lol.FactoredDefs.Factored). (Crypto.Lol.Types.FiniteField.GFCtx fp d, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.UCyc.UCElt t fp) => Algebra.Module.C (Crypto.Lol.Types.FiniteField.GF fp d) (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.P fp)
- Crypto.Lol.Cyclotomic.UCyc: twaceCRT :: (m `Divides` m', UCElt t r) => UCyc t m' C r -> Either (UCyc t m P r) (UCyc t m C r)
- Crypto.Lol.Cyclotomic.UCyc: type UCElt t r = (Tensor t, CRTEmbed r, CRTElt t r, CRTElt t (CRTExt r))
- Crypto.Lol.Cyclotomic.UCyc: unzipCyc :: (Tensor t, Fact m) => UCyc t m rep (a, b) -> (UCyc t m rep a, UCyc t m rep b)
- Crypto.Lol.Cyclotomic.UCyc: unzipUCElt :: (Tensor t, Fact m, UCElt t (a, b), UCElt t a, UCElt t b) => UCyc t m rep (a, b) -> (UCyc t m rep a, UCyc t m rep b)
- Crypto.Lol.Factored: data Prime
- Crypto.Lol.Factored: type Prim (p :: Prime) = SingI p
- Crypto.Lol.Factored: type SPrime = (Sing :: Prime -> *)
- Crypto.Lol.Gadget: instance forall (k :: BOX) (gad :: k) a b. (Crypto.Lol.Gadget.Correct gad a, Crypto.Lol.Gadget.Correct gad b, Crypto.Lol.LatticePrelude.Mod a, Crypto.Lol.LatticePrelude.Mod b, Crypto.Lol.Types.Numeric.Field a, Crypto.Lol.Types.Numeric.Field b, Crypto.Lol.LatticePrelude.Lift' a, Crypto.Lol.LatticePrelude.Lift' b, Crypto.Lol.Types.Numeric.ToInteger (Crypto.Lol.LatticePrelude.LiftOf a), Crypto.Lol.Types.Numeric.ToInteger (Crypto.Lol.LatticePrelude.LiftOf b)) => Crypto.Lol.Gadget.Correct gad (a, b)
- Crypto.Lol.LatticePrelude: (^) :: (Ring a, ToInteger i) => a -> i -> a
- Crypto.Lol.LatticePrelude: abs :: Absolute a => a -> a
- Crypto.Lol.LatticePrelude: cis :: Transcendental a => a -> Complex a
- Crypto.Lol.LatticePrelude: class (Field src, Field tgt) => Encode src tgt
- Crypto.Lol.LatticePrelude: class Enumerable a
- Crypto.Lol.LatticePrelude: class (Reduce (LiftOf b) b) => Lift' b
- Crypto.Lol.LatticePrelude: class (ToInteger (ModRep a), Additive a) => Mod a where type family ModRep a
- Crypto.Lol.LatticePrelude: class (Additive a, Additive b) => Reduce a b
- Crypto.Lol.LatticePrelude: class (Additive a, Additive b) => Rescale a b
- Crypto.Lol.LatticePrelude: data Complex a
- Crypto.Lol.LatticePrelude: data Int64 :: *
- Crypto.Lol.LatticePrelude: decomp :: (IntegralDomain z, Ord z) => [z] -> z -> [z]
- Crypto.Lol.LatticePrelude: divModCent :: (IntegralDomain i, Ord i) => i -> i -> (i, i)
- Crypto.Lol.LatticePrelude: fromJust' :: String -> Maybe a -> a
- Crypto.Lol.LatticePrelude: fromReal :: Additive a => a -> Complex a
- Crypto.Lol.LatticePrelude: imag :: Complex a -> a
- Crypto.Lol.LatticePrelude: instance (Crypto.Lol.LatticePrelude.Encode s t1, Crypto.Lol.LatticePrelude.Encode s t2, Crypto.Lol.Types.Numeric.Field (t1, t2)) => Crypto.Lol.LatticePrelude.Encode s (t1, t2)
- Crypto.Lol.LatticePrelude: instance (Crypto.Lol.LatticePrelude.Mod a, Crypto.Lol.LatticePrelude.Mod b) => Crypto.Lol.LatticePrelude.Mod (a, b)
- Crypto.Lol.LatticePrelude: instance (Crypto.Lol.LatticePrelude.Mod a, Crypto.Lol.LatticePrelude.Mod b, Crypto.Lol.LatticePrelude.Lift' a, Crypto.Lol.LatticePrelude.Lift' b, Crypto.Lol.LatticePrelude.Reduce GHC.Integer.Type.Integer (a, b), Crypto.Lol.Types.Numeric.ToInteger (Crypto.Lol.LatticePrelude.LiftOf a), Crypto.Lol.Types.Numeric.ToInteger (Crypto.Lol.LatticePrelude.LiftOf b)) => Crypto.Lol.LatticePrelude.Lift' (a, b)
- Crypto.Lol.LatticePrelude: instance (Crypto.Lol.LatticePrelude.Mod a, Crypto.Lol.Types.Numeric.Field b, Crypto.Lol.LatticePrelude.Lift a (Crypto.Lol.LatticePrelude.ModRep a), Crypto.Lol.LatticePrelude.Reduce (Crypto.Lol.LatticePrelude.LiftOf a) b) => Crypto.Lol.LatticePrelude.Rescale (a, b) b
- Crypto.Lol.LatticePrelude: instance (Crypto.Lol.LatticePrelude.Mod b, Crypto.Lol.Types.Numeric.Field a, Crypto.Lol.LatticePrelude.Lift b (Crypto.Lol.LatticePrelude.ModRep b), Crypto.Lol.LatticePrelude.Reduce (Crypto.Lol.LatticePrelude.LiftOf b) a) => Crypto.Lol.LatticePrelude.Rescale (a, b) a
- Crypto.Lol.LatticePrelude: instance (Crypto.Lol.LatticePrelude.Reduce a b1, Crypto.Lol.LatticePrelude.Reduce a b2) => Crypto.Lol.LatticePrelude.Reduce a (b1, b2)
- Crypto.Lol.LatticePrelude: instance (Crypto.Lol.LatticePrelude.Rescale ((a, b), c) (a, b), Crypto.Lol.LatticePrelude.Rescale (a, b) a) => Crypto.Lol.LatticePrelude.Rescale ((a, b), c) a
- Crypto.Lol.LatticePrelude: instance (Crypto.Lol.LatticePrelude.Rescale (a, (b, c)) (b, c), Crypto.Lol.LatticePrelude.Rescale (b, c) c) => Crypto.Lol.LatticePrelude.Rescale (a, (b, c)) c
- Crypto.Lol.LatticePrelude: instance (Crypto.Lol.Types.Numeric.Field f1, Crypto.Lol.Types.Numeric.Field f2) => Algebra.Field.C (f1, f2)
- Crypto.Lol.LatticePrelude: instance (Crypto.Lol.Types.Numeric.IntegralDomain a, Crypto.Lol.Types.Numeric.IntegralDomain b) => Algebra.IntegralDomain.C (a, b)
- Crypto.Lol.LatticePrelude: instance (Crypto.Lol.Types.Numeric.Ring a, Crypto.Lol.LatticePrelude.Mod b, Crypto.Lol.LatticePrelude.Reduce (Crypto.Lol.LatticePrelude.ModRep b) a) => Crypto.Lol.LatticePrelude.Rescale a (a, b)
- Crypto.Lol.LatticePrelude: instance (Crypto.Lol.Types.Numeric.Ring b, Crypto.Lol.LatticePrelude.Mod a, Crypto.Lol.LatticePrelude.Reduce (Crypto.Lol.LatticePrelude.ModRep a) b) => Crypto.Lol.LatticePrelude.Rescale b (a, b)
- Crypto.Lol.LatticePrelude: instance (Crypto.Lol.Types.Numeric.Ring r1, Crypto.Lol.Types.Numeric.Ring r2) => Algebra.Ring.C (r1, r2)
- Crypto.Lol.LatticePrelude: instance (Data.Default.Class.Default a0, Data.Vector.Unboxed.Base.Unbox a0) => Data.Vector.Generic.Base.Vector Data.Vector.Unboxed.Base.Vector (GHC.Base.Maybe a0)
- Crypto.Lol.LatticePrelude: instance (Data.Default.Class.Default a0, Data.Vector.Unboxed.Base.Unbox a0) => Data.Vector.Generic.Mutable.Base.MVector Data.Vector.Unboxed.Base.MVector (GHC.Base.Maybe a0)
- Crypto.Lol.LatticePrelude: instance (Data.Default.Class.Default a0, Data.Vector.Unboxed.Base.Unbox a0) => Data.Vector.Unboxed.Base.Unbox (GHC.Base.Maybe a0)
- Crypto.Lol.LatticePrelude: instance (System.Random.Random a, System.Random.Random b) => System.Random.Random (a, b)
- Crypto.Lol.LatticePrelude: instance Data.Default.Class.Default GHC.Types.Bool
- Crypto.Lol.LatticePrelude: instance forall (k :: BOX) (a :: k). Control.DeepSeq.NFData (Data.Proxy.Proxy a)
- Crypto.Lol.LatticePrelude: instance forall (k :: BOX) (k1 :: BOX) (s :: k) (m :: k1 -> *) (a :: k1). Control.DeepSeq.NFData (m a) => Control.DeepSeq.NFData (Data.Functor.Trans.Tagged.TaggedT s m a)
- Crypto.Lol.LatticePrelude: instance forall (k :: BOX) (tag :: k) (m :: * -> *). Control.Monad.Random.Class.MonadRandom m => Control.Monad.Random.Class.MonadRandom (Data.Functor.Trans.Tagged.TaggedT tag m)
- Crypto.Lol.LatticePrelude: lift :: Lift' b => b -> LiftOf b
- Crypto.Lol.LatticePrelude: lsdToMSD :: Encode src tgt => (src, tgt)
- Crypto.Lol.LatticePrelude: max :: Ord a => a -> a -> a
- Crypto.Lol.LatticePrelude: min :: Ord a => a -> a -> a
- Crypto.Lol.LatticePrelude: modinv :: (PID i, Eq i) => i -> i -> Maybe i
- Crypto.Lol.LatticePrelude: modulus :: Mod a => Tagged a (ModRep a)
- Crypto.Lol.LatticePrelude: msdToLSD :: (Encode src tgt) => (src, tgt)
- Crypto.Lol.LatticePrelude: pasteT :: TaggedT t f a -> Tagged t (f a)
- Crypto.Lol.LatticePrelude: peelT :: Tagged t (f a) -> TaggedT t f a
- Crypto.Lol.LatticePrelude: pureT :: Applicative f => TaggedT t Identity a -> TaggedT t f a
- Crypto.Lol.LatticePrelude: real :: Complex a -> a
- Crypto.Lol.LatticePrelude: realToField :: (Field b, ToRational a) => a -> b
- Crypto.Lol.LatticePrelude: reduce :: Reduce a b => a -> b
- Crypto.Lol.LatticePrelude: rescale :: Rescale a b => a -> b
- Crypto.Lol.LatticePrelude: rescaleMod :: (Mod a, Mod b, (ModRep a) ~ (ModRep b), Lift a (ModRep b), Ring b) => a -> b
- Crypto.Lol.LatticePrelude: roundComplex :: (RealRing a, ToInteger b) => Complex a -> (b, b)
- Crypto.Lol.LatticePrelude: roundCoset :: (Mod zp, z ~ ModRep zp, Lift zp z, RealField r) => zp -> r -> z
- Crypto.Lol.LatticePrelude: roundMult :: (RealField r, ToInteger i) => i -> r -> i
- Crypto.Lol.LatticePrelude: roundScalarCentered :: (RealField r, Random r, ToInteger i, MonadRandom mon) => i -> r -> mon i
- Crypto.Lol.LatticePrelude: type Absolute a = C a
- Crypto.Lol.LatticePrelude: type Additive a = C a
- Crypto.Lol.LatticePrelude: type Algebraic a = C a
- Crypto.Lol.LatticePrelude: type Field a = C a
- Crypto.Lol.LatticePrelude: type IntegralDomain a = C a
- Crypto.Lol.LatticePrelude: type Lift b a = (Lift' b, LiftOf b ~ a)
- Crypto.Lol.LatticePrelude: type Module a v = C a v
- Crypto.Lol.LatticePrelude: type OrdFloat a = (Ord a, Transcendental a)
- Crypto.Lol.LatticePrelude: type PID a = C a
- Crypto.Lol.LatticePrelude: type Polynomial a = T a
- Crypto.Lol.LatticePrelude: type RealField a = C a
- Crypto.Lol.LatticePrelude: type RealIntegral a = C a
- Crypto.Lol.LatticePrelude: type RealRing a = C a
- Crypto.Lol.LatticePrelude: type RealTranscendental a = C a
- Crypto.Lol.LatticePrelude: type Ring a = C a
- Crypto.Lol.LatticePrelude: type ToInteger a = C a
- Crypto.Lol.LatticePrelude: type ToRational a = C a
- Crypto.Lol.LatticePrelude: type Transcendental a = C a
- Crypto.Lol.LatticePrelude: type ZeroTestable a = C a
- Crypto.Lol.LatticePrelude: values :: Enumerable a => [a]
- Crypto.Lol.LatticePrelude: withWitness :: (SingI n => Tagged n r) -> Sing n -> r
- Crypto.Lol.LatticePrelude: withWitnessT :: (SingI n => TaggedT n mon r) -> Sing n -> mon r
- Crypto.Lol.Reflects: instance (Crypto.Lol.FactoredDefs.Prim p, Algebra.ToInteger.C i) => Crypto.Lol.Reflects.Reflects p i
- Crypto.Lol.Reflects: instance Data.Reflection.Reifies rei a => Crypto.Lol.Reflects.Reflects rei a
- Crypto.Lol.Types.FiniteField: instance forall (k :: BOX) fp (d :: k). Crypto.Lol.Types.FiniteField.GFCtx fp d => Crypto.Lol.CRTrans.CRTrans (Crypto.Lol.Types.FiniteField.GF fp d)
- Crypto.Lol.Types.FiniteField: instance forall (k :: BOX) fp (d :: k). Crypto.Lol.Types.FiniteField.GFCtx fp d => Crypto.Lol.LatticePrelude.Enumerable (Crypto.Lol.Types.FiniteField.GF fp d)
- Crypto.Lol.Types.IrreducibleChar2: instance (Crypto.Lol.LatticePrelude.CharOf a ~ Crypto.Lol.Factored.Prime2, Crypto.Lol.Types.Numeric.Field a) => Crypto.Lol.Types.FiniteField.IrreduciblePoly a
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (k1 :: BOX) (b :: k) (q :: k1) z. (Crypto.Lol.Types.ZqBasic.ReflectsTI q z, Crypto.Lol.Types.Numeric.RealIntegral z, Crypto.Lol.Reflects.Reflects b z) => Crypto.Lol.Gadget.Gadget (Crypto.Lol.Gadget.BaseBGad b) (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (k1 :: BOX) (b :: k) (q :: k1) z. (Crypto.Lol.Types.ZqBasic.ReflectsTI q z, Crypto.Lol.Types.Numeric.Ring z, Crypto.Lol.Reflects.Reflects b z) => Crypto.Lol.Gadget.Correct (Crypto.Lol.Gadget.BaseBGad b) (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (k1 :: BOX) (b :: k) (q :: k1) z. (Crypto.Lol.Types.ZqBasic.ReflectsTI q z, Crypto.Lol.Types.Numeric.Ring z, Crypto.Lol.Types.Numeric.ZeroTestable z, Crypto.Lol.Reflects.Reflects b z) => Crypto.Lol.Gadget.Decompose (Crypto.Lol.Gadget.BaseBGad b) (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (k1 :: BOX) (p :: k) z (q :: k1). (Crypto.Lol.Reflects.Reflects p z, Crypto.Lol.Types.ZqBasic.ReflectsTI q z, Crypto.Lol.Types.Numeric.Field (Crypto.Lol.Types.ZqBasic.ZqBasic p z), Crypto.Lol.Types.Numeric.Field (Crypto.Lol.Types.ZqBasic.ZqBasic q z)) => Crypto.Lol.LatticePrelude.Encode (Crypto.Lol.Types.ZqBasic.ZqBasic p z) (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (k1 :: BOX) (q :: k) z (q' :: k1). (Crypto.Lol.Types.ZqBasic.ReflectsTI q z, Crypto.Lol.Types.ZqBasic.ReflectsTI q' z, Crypto.Lol.Types.Numeric.Ring z) => Crypto.Lol.LatticePrelude.Rescale (Crypto.Lol.Types.ZqBasic.ZqBasic q z) (Crypto.Lol.Types.ZqBasic.ZqBasic q' z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.Ring (Crypto.Lol.Types.ZqBasic.ZqBasic q z)) => Crypto.Lol.LatticePrelude.Reduce GHC.Integer.Type.Integer (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Types.ZqBasic.ReflectsTI q z, Crypto.Lol.Types.Numeric.Additive z) => Algebra.Additive.C (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Types.ZqBasic.ReflectsTI q z, Crypto.Lol.Types.Numeric.Additive z) => Crypto.Lol.Gadget.Gadget Crypto.Lol.Gadget.TrivGad (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Types.ZqBasic.ReflectsTI q z, Crypto.Lol.Types.Numeric.PID z, Crypto.Lol.LatticePrelude.Enumerable (Crypto.Lol.Types.ZqBasic.ZqBasic q z)) => Crypto.Lol.CRTrans.CRTrans (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Types.ZqBasic.ReflectsTI q z, Crypto.Lol.Types.Numeric.PID z, GHC.Show.Show z) => Algebra.Field.C (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Types.ZqBasic.ReflectsTI q z, Crypto.Lol.Types.Numeric.Ring (Crypto.Lol.Types.ZqBasic.ZqBasic q z)) => Crypto.Lol.CRTrans.CRTEmbed (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Types.ZqBasic.ReflectsTI q z, Crypto.Lol.Types.Numeric.Ring z) => Algebra.Ring.C (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Types.ZqBasic.ReflectsTI q z, Crypto.Lol.Types.Numeric.Ring z) => Crypto.Lol.Gadget.Correct Crypto.Lol.Gadget.TrivGad (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Types.ZqBasic.ReflectsTI q z, Crypto.Lol.Types.Numeric.Ring z) => Crypto.Lol.Gadget.Decompose Crypto.Lol.Gadget.TrivGad (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Types.ZqBasic.ReflectsTI q z, GHC.Enum.Enum z) => Crypto.Lol.LatticePrelude.Enumerable (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Types.ZqBasic.ReflectsTI q z, System.Random.Random z) => System.Random.Random (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Types.ZqBasic.ReflectsTI q z, System.Random.Random z) => Test.QuickCheck.Arbitrary.Arbitrary (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. Crypto.Lol.Types.Numeric.Field (Crypto.Lol.Types.ZqBasic.ZqBasic q z) => Algebra.IntegralDomain.C (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. Crypto.Lol.Types.ZqBasic.ReflectsTI q z => Crypto.Lol.LatticePrelude.Lift' (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. Crypto.Lol.Types.ZqBasic.ReflectsTI q z => Crypto.Lol.LatticePrelude.Mod (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
- Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) z (q :: k). Crypto.Lol.Types.ZqBasic.ReflectsTI q z => Crypto.Lol.LatticePrelude.Reduce z (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.CRTrans: instance (Crypto.Lol.CRTrans.CRTrans mon a, Crypto.Lol.CRTrans.CRTrans mon b) => Crypto.Lol.CRTrans.CRTrans mon (a, b)
+ Crypto.Lol.CRTrans: instance (GHC.Base.Monad mon, Crypto.Lol.Types.Numeric.Transcendental a) => Crypto.Lol.CRTrans.CRTrans mon (Crypto.Lol.Types.Complex.Complex a)
+ Crypto.Lol.CRTrans: instance Crypto.Lol.CRTrans.CRTrans GHC.Base.Maybe GHC.Int.Int64
+ Crypto.Lol.CRTrans: instance Crypto.Lol.CRTrans.CRTrans GHC.Base.Maybe GHC.Integer.Type.Integer
+ Crypto.Lol.CRTrans: instance Crypto.Lol.CRTrans.CRTrans GHC.Base.Maybe GHC.Types.Double
+ Crypto.Lol.CRTrans: instance Crypto.Lol.CRTrans.CRTrans GHC.Base.Maybe GHC.Types.Int
+ Crypto.Lol.Cyclotomic.Cyc: coeffsDec :: (m `Divides` m', CElt t r) => Cyc t m' r -> [Cyc t m r]
+ Crypto.Lol.Cyclotomic.Cyc: coeffsPow :: (m `Divides` m', CElt t r) => Cyc t m' r -> [Cyc t m r]
+ Crypto.Lol.Cyclotomic.Cyc: cycCRTC :: UCyc t m C r -> Cyc t m r
+ Crypto.Lol.Cyclotomic.Cyc: cycCRTE :: UCyc t m E r -> Cyc t m r
+ Crypto.Lol.Cyclotomic.Cyc: cycPC :: Either (UCyc t m P r) (UCyc t m C r) -> Cyc t m r
+ Crypto.Lol.Cyclotomic.Cyc: cycPE :: Either (UCyc t m P r) (UCyc t m E r) -> Cyc t m r
+ Crypto.Lol.Cyclotomic.Cyc: instance (Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Cyc.CElt t r, Crypto.Lol.Types.Proto.Protoable (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.D r)) => Crypto.Lol.Types.Proto.Protoable (Crypto.Lol.Cyclotomic.Cyc.Cyc t m r)
+ Crypto.Lol.Cyclotomic.Cyc: instance (Crypto.Lol.Prelude.Mod a, Crypto.Lol.Types.Numeric.Field b, Crypto.Lol.Prelude.Lift a (Crypto.Lol.Prelude.ModRep a), Crypto.Lol.Prelude.Reduce (Crypto.Lol.Prelude.LiftOf a) b, Crypto.Lol.Cyclotomic.Cyc.CElt t (a, b), Crypto.Lol.Cyclotomic.Cyc.CElt t a, Crypto.Lol.Cyclotomic.Cyc.CElt t b, Crypto.Lol.Cyclotomic.Cyc.CElt t (Crypto.Lol.Prelude.LiftOf a)) => Crypto.Lol.Cyclotomic.RescaleCyc.RescaleCyc (Crypto.Lol.Cyclotomic.Cyc.Cyc t) (a, b) b
+ Crypto.Lol.Cyclotomic.Cyc: instance (Crypto.Lol.Prelude.Reduce a b, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Cyc.CElt t a, Crypto.Lol.Cyclotomic.Cyc.CElt t b) => Crypto.Lol.Prelude.Reduce (Crypto.Lol.Cyclotomic.Cyc.Cyc t m a) (Crypto.Lol.Cyclotomic.Cyc.Cyc t m b)
+ Crypto.Lol.Cyclotomic.Cyc: instance (Crypto.Lol.Prelude.Rescale a b, Crypto.Lol.Cyclotomic.Cyc.CElt t a, Crypto.Lol.Cyclotomic.Tensor.TElt t b) => Crypto.Lol.Cyclotomic.RescaleCyc.RescaleCyc (Crypto.Lol.Cyclotomic.Cyc.Cyc t) a b
+ Crypto.Lol.Cyclotomic.Cyc: instance (System.Random.Random r, Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.UCyc.UCRTElt t r) => System.Random.Random (Crypto.Lol.Cyclotomic.Cyc.Cyc t m r)
+ Crypto.Lol.Cyclotomic.Linear: instance (Crypto.Lol.Cyclotomic.Cyc.CElt t zp, Crypto.Lol.Cyclotomic.Cyc.CElt t z, z ~ Crypto.Lol.Prelude.LiftOf zp, Crypto.Lol.Prelude.Lift zp z, Crypto.Lol.FactoredDefs.Fact s) => Crypto.Lol.Prelude.Lift' (Crypto.Lol.Cyclotomic.Linear.Linear t zp e r s)
+ Crypto.Lol.Cyclotomic.Linear: instance (Crypto.Lol.Prelude.Reduce z zq, Crypto.Lol.FactoredDefs.Fact s, Crypto.Lol.Cyclotomic.Cyc.CElt t z, Crypto.Lol.Cyclotomic.Cyc.CElt t zq) => Crypto.Lol.Prelude.Reduce (Crypto.Lol.Cyclotomic.Linear.Linear t z e r s) (Crypto.Lol.Cyclotomic.Linear.Linear t zq e r s)
+ Crypto.Lol.Cyclotomic.Tensor: gCRTM :: (Fact m, CRTrans mon r) => TaggedT m mon (Matrix r)
+ Crypto.Lol.Cyclotomic.Tensor: gInvCRTM :: (Fact m, CRTrans mon r) => TaggedT m mon (Matrix r)
+ Crypto.Lol.Cyclotomic.Tensor.CTensor: instance forall (k :: BOX) (m :: Crypto.Lol.FactoredDefs.Factored) (q :: k). (Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Reflects.Reflects q GHC.Int.Int64) => Crypto.Lol.Types.Proto.Protoable (Crypto.Lol.Cyclotomic.Tensor.CTensor.CT m (Crypto.Lol.Types.ZqBasic.ZqBasic q GHC.Int.Int64))
+ Crypto.Lol.Cyclotomic.Tensor.CTensor: instance forall (k :: BOX) (m :: Crypto.Lol.FactoredDefs.Factored) (q :: k). (Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Reflects.Reflects q GHC.Types.Double) => Crypto.Lol.Types.Proto.Protoable (Crypto.Lol.Cyclotomic.Tensor.CTensor.CT m (Crypto.Lol.Types.RRq.RRq q GHC.Types.Double))
+ Crypto.Lol.Cyclotomic.Tensor.RepaTensor: instance forall (k :: BOX) (m :: Crypto.Lol.FactoredDefs.Factored) (q :: k). (Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Reflects.Reflects q GHC.Int.Int64) => Crypto.Lol.Types.Proto.Protoable (Crypto.Lol.Cyclotomic.Tensor.RepaTensor.RT m (Crypto.Lol.Types.ZqBasic.ZqBasic q GHC.Int.Int64))
+ Crypto.Lol.Cyclotomic.Tensor.RepaTensor: instance forall (k :: BOX) (m :: Crypto.Lol.FactoredDefs.Factored) (q :: k). (Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Reflects.Reflects q GHC.Types.Double) => Crypto.Lol.Types.Proto.Protoable (Crypto.Lol.Cyclotomic.Tensor.RepaTensor.RT m (Crypto.Lol.Types.RRq.RRq q GHC.Types.Double))
+ Crypto.Lol.Cyclotomic.UCyc: data E
+ Crypto.Lol.Cyclotomic.UCyc: embedCRTC :: (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: embedCRTE :: (m `Divides` m', UCRTElt t r) => UCyc t m E r -> Either (UCyc t m' P r) (UCyc t m' E r)
+ Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m) => Data.Foldable.Foldable (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.C)
+ Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.UCyc.UCRTElt t r) => Algebra.Additive.C (Crypto.Lol.Cyclotomic.UCyc.UCycEC t m r)
+ Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.UCyc.UCRTElt t r) => Algebra.Ring.C (Crypto.Lol.Cyclotomic.UCyc.UCycEC t m r)
+ Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Types.Proto.Protoable (t m r)) => Crypto.Lol.Types.Proto.Protoable (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.D r)
+ Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.Prelude.Lift' r, Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Tensor.TElt t r, Crypto.Lol.Cyclotomic.Tensor.TElt t (Crypto.Lol.Prelude.LiftOf r)) => Crypto.Lol.Prelude.Lift' (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.D r)
+ Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.Prelude.Lift' r, Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Tensor.TElt t r, Crypto.Lol.Cyclotomic.Tensor.TElt t (Crypto.Lol.Prelude.LiftOf r)) => Crypto.Lol.Prelude.Lift' (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.P r)
+ Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.Prelude.Reduce a b, Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Tensor.TElt t a, Crypto.Lol.Cyclotomic.Tensor.TElt t b) => Crypto.Lol.Prelude.Reduce (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.D a) (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.D b)
+ Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.Prelude.Reduce a b, Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Tensor.TElt t a, Crypto.Lol.Cyclotomic.Tensor.TElt t b) => Crypto.Lol.Prelude.Reduce (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.P a) (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.P b)
+ Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.Prelude.Rescale a b, Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Tensor.TElt t a, Crypto.Lol.Cyclotomic.Tensor.TElt t b) => Crypto.Lol.Prelude.Rescale (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.D a) (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.D b)
+ Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.Prelude.Rescale a b, Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Tensor.TElt t a, Crypto.Lol.Cyclotomic.Tensor.TElt t b) => Crypto.Lol.Prelude.Rescale (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.P a) (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.P b)
+ Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.Types.Numeric.Ring r, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.UCyc.UCRTElt t r) => Algebra.Module.C r (Crypto.Lol.Cyclotomic.UCyc.UCycEC t m r)
+ Crypto.Lol.Cyclotomic.UCyc: instance (Crypto.Lol.Types.Numeric.ZeroTestable r, Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Tensor.TElt t r) => Algebra.ZeroTestable.C (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.C r)
+ Crypto.Lol.Cyclotomic.UCyc: instance (GHC.Classes.Eq r, Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Tensor.TElt t r) => GHC.Classes.Eq (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.C 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.UCyc t m Crypto.Lol.Cyclotomic.UCyc.D 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.UCyc t m Crypto.Lol.Cyclotomic.UCyc.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 (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.Cyclotomic.UCyc: instance Test.QuickCheck.Arbitrary.Arbitrary (t m r) => Test.QuickCheck.Arbitrary.Arbitrary (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.D r)
+ Crypto.Lol.Cyclotomic.UCyc: instance Test.QuickCheck.Arbitrary.Arbitrary (t m r) => Test.QuickCheck.Arbitrary.Arbitrary (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.P r)
+ Crypto.Lol.Cyclotomic.UCyc: instance forall (k :: BOX) fp (d :: k) (t :: Crypto.Lol.FactoredDefs.Factored -> * -> *) (m :: Crypto.Lol.FactoredDefs.Factored). (Crypto.Lol.Types.FiniteField.GFCtx fp d, Crypto.Lol.FactoredDefs.Fact m, Crypto.Lol.Cyclotomic.Tensor.Tensor t, Crypto.Lol.Cyclotomic.Tensor.TElt t fp) => Algebra.Module.C (Crypto.Lol.Types.FiniteField.GF fp d) (Crypto.Lol.Cyclotomic.UCyc.UCyc t m Crypto.Lol.Cyclotomic.UCyc.P fp)
+ 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: twaceCRTE :: (m `Divides` m', UCRTElt t r) => UCyc t m' E r -> Either (UCyc t m P r) (UCyc t m E r)
+ Crypto.Lol.Cyclotomic.UCyc: type UCRTElt t r = (Tensor t, CRTEmbed r, CRTrans Maybe r, TElt t r, CRTrans Identity (CRTExt r), TElt t (CRTExt r))
+ Crypto.Lol.Cyclotomic.UCyc: type UCycEC t m r = Either (UCyc t m E r) (UCyc t m C r)
+ Crypto.Lol.Cyclotomic.UCyc: unzipCRTC :: (Tensor t, Fact m, UCRTElt t (a, b), UCRTElt t a, UCRTElt t b) => 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))
+ Crypto.Lol.Cyclotomic.UCyc: unzipCRTE :: (Tensor t, Fact m, UCRTElt t (a, b), UCRTElt t a, UCRTElt t b) => 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))
+ Crypto.Lol.Cyclotomic.UCyc: unzipDec :: (Tensor t, Fact m, TElt t (a, b), TElt t a, TElt t b) => UCyc t m D (a, b) -> (UCyc t m D a, UCyc t m D b)
+ Crypto.Lol.Cyclotomic.UCyc: unzipPow :: (Tensor t, Fact m, TElt t (a, b), TElt t a, TElt t b) => UCyc t m P (a, b) -> (UCyc t m P a, UCyc t m P b)
+ Crypto.Lol.Factored: data PrimeBin
+ Crypto.Lol.Factored: reifyFact :: Int -> (forall m. SFactored m -> a) -> a
+ Crypto.Lol.Factored: reifyFactI :: Int -> (forall m proxy. Fact m => proxy m -> a) -> a
+ Crypto.Lol.Factored: reifyPPow :: (Int, Int) -> (forall pp. SPrimePower pp -> a) -> a
+ Crypto.Lol.Factored: reifyPPowI :: (Int, Int) -> (forall pp proxy. PPow pp => proxy pp -> a) -> a
+ Crypto.Lol.Factored: reifyPrime :: Int -> (forall p. SPrimeBin p -> a) -> a
+ Crypto.Lol.Factored: reifyPrimeI :: Int -> (forall p proxy. Prime p => proxy p -> a) -> a
+ Crypto.Lol.Factored: type Prime (p :: PrimeBin) = SingI p
+ Crypto.Lol.Factored: type SPrimeBin = (Sing :: PrimeBin -> *)
+ Crypto.Lol.Gadget: instance forall (k :: BOX) (gad :: k) a b. (Crypto.Lol.Gadget.Correct gad a, Crypto.Lol.Gadget.Correct gad b, Crypto.Lol.Prelude.Mod a, Crypto.Lol.Prelude.Mod b, Crypto.Lol.Types.Numeric.Field a, Crypto.Lol.Types.Numeric.Field b, Crypto.Lol.Prelude.Lift' a, Crypto.Lol.Prelude.Lift' b, Crypto.Lol.Types.Numeric.ToInteger (Crypto.Lol.Prelude.LiftOf a), Crypto.Lol.Types.Numeric.ToInteger (Crypto.Lol.Prelude.LiftOf b)) => Crypto.Lol.Gadget.Correct gad (a, b)
+ Crypto.Lol.PosBin: reifyBin :: Int -> (forall b. SBin b -> a) -> a
+ Crypto.Lol.PosBin: reifyBinI :: Int -> (forall b proxy. BinC b => proxy b -> a) -> a
+ Crypto.Lol.PosBin: reifyPos :: Int -> (forall p. SPos p -> a) -> a
+ Crypto.Lol.PosBin: reifyPosI :: Int -> (forall p proxy. PosC p => proxy p -> a) -> a
+ Crypto.Lol.Prelude: (^) :: (Ring a, ToInteger i) => a -> i -> a
+ Crypto.Lol.Prelude: abs :: Absolute a => a -> a
+ Crypto.Lol.Prelude: cis :: Transcendental a => a -> Complex a
+ Crypto.Lol.Prelude: class (Field src, Field tgt) => Encode src tgt
+ Crypto.Lol.Prelude: class Enumerable a
+ Crypto.Lol.Prelude: class (Reduce (LiftOf b) b) => Lift' b
+ Crypto.Lol.Prelude: class (ToInteger (ModRep a), Additive a) => Mod a where type family ModRep a
+ Crypto.Lol.Prelude: class (Additive a, Additive b) => Reduce a b
+ Crypto.Lol.Prelude: class (Additive a, Additive b) => Rescale a b
+ Crypto.Lol.Prelude: class (Additive a, Additive b) => Subgroup a b
+ Crypto.Lol.Prelude: data Complex a
+ Crypto.Lol.Prelude: data Int64 :: *
+ Crypto.Lol.Prelude: decomp :: (IntegralDomain z, Ord z) => [z] -> z -> [z]
+ Crypto.Lol.Prelude: divModCent :: (IntegralDomain i, Ord i) => i -> i -> (i, i)
+ Crypto.Lol.Prelude: fromJust' :: String -> Maybe a -> a
+ Crypto.Lol.Prelude: fromReal :: Additive a => a -> Complex a
+ Crypto.Lol.Prelude: fromSubgroup :: Subgroup a b => a -> b
+ Crypto.Lol.Prelude: imag :: Complex a -> a
+ Crypto.Lol.Prelude: instance (Crypto.Lol.Prelude.Encode s t1, Crypto.Lol.Prelude.Encode s t2, Crypto.Lol.Types.Numeric.Field (t1, t2)) => Crypto.Lol.Prelude.Encode s (t1, t2)
+ Crypto.Lol.Prelude: instance (Crypto.Lol.Prelude.Mod a, Crypto.Lol.Prelude.Mod b) => Crypto.Lol.Prelude.Mod (a, b)
+ Crypto.Lol.Prelude: instance (Crypto.Lol.Prelude.Mod a, Crypto.Lol.Prelude.Mod b, Crypto.Lol.Prelude.Lift' a, Crypto.Lol.Prelude.Lift' b, Crypto.Lol.Prelude.Reduce GHC.Integer.Type.Integer (a, b), Crypto.Lol.Types.Numeric.ToInteger (Crypto.Lol.Prelude.LiftOf a), Crypto.Lol.Types.Numeric.ToInteger (Crypto.Lol.Prelude.LiftOf b)) => Crypto.Lol.Prelude.Lift' (a, b)
+ Crypto.Lol.Prelude: instance (Crypto.Lol.Prelude.Mod a, Crypto.Lol.Types.Numeric.Field b, Crypto.Lol.Prelude.Lift a (Crypto.Lol.Prelude.ModRep a), Crypto.Lol.Prelude.Reduce (Crypto.Lol.Prelude.LiftOf a) b) => Crypto.Lol.Prelude.Rescale (a, b) b
+ Crypto.Lol.Prelude: instance (Crypto.Lol.Prelude.Mod b, Crypto.Lol.Types.Numeric.Field a, Crypto.Lol.Prelude.Lift b (Crypto.Lol.Prelude.ModRep b), Crypto.Lol.Prelude.Reduce (Crypto.Lol.Prelude.LiftOf b) a) => Crypto.Lol.Prelude.Rescale (a, b) a
+ Crypto.Lol.Prelude: instance (Crypto.Lol.Prelude.Reduce a b1, Crypto.Lol.Prelude.Reduce a b2) => Crypto.Lol.Prelude.Reduce a (b1, b2)
+ Crypto.Lol.Prelude: instance (Crypto.Lol.Prelude.Rescale ((a, b), c) (a, b), Crypto.Lol.Prelude.Rescale (a, b) a) => Crypto.Lol.Prelude.Rescale ((a, b), c) a
+ Crypto.Lol.Prelude: instance (Crypto.Lol.Prelude.Rescale (a, (b, c)) (b, c), Crypto.Lol.Prelude.Rescale (b, c) c) => Crypto.Lol.Prelude.Rescale (a, (b, c)) c
+ Crypto.Lol.Prelude: instance (Crypto.Lol.Types.Numeric.Field f1, Crypto.Lol.Types.Numeric.Field f2) => Algebra.Field.C (f1, f2)
+ Crypto.Lol.Prelude: instance (Crypto.Lol.Types.Numeric.IntegralDomain a, Crypto.Lol.Types.Numeric.IntegralDomain b) => Algebra.IntegralDomain.C (a, b)
+ Crypto.Lol.Prelude: instance (Crypto.Lol.Types.Numeric.Ring a, Crypto.Lol.Prelude.Mod b, Crypto.Lol.Prelude.Reduce (Crypto.Lol.Prelude.ModRep b) a) => Crypto.Lol.Prelude.Rescale a (a, b)
+ Crypto.Lol.Prelude: instance (Crypto.Lol.Types.Numeric.Ring b, Crypto.Lol.Prelude.Mod a, Crypto.Lol.Prelude.Reduce (Crypto.Lol.Prelude.ModRep a) b) => Crypto.Lol.Prelude.Rescale b (a, b)
+ Crypto.Lol.Prelude: instance (Crypto.Lol.Types.Numeric.Ring r1, Crypto.Lol.Types.Numeric.Ring r2) => Algebra.Ring.C (r1, r2)
+ Crypto.Lol.Prelude: instance (Data.Default.Class.Default a0, Data.Vector.Unboxed.Base.Unbox a0) => Data.Vector.Generic.Base.Vector Data.Vector.Unboxed.Base.Vector (GHC.Base.Maybe a0)
+ Crypto.Lol.Prelude: instance (Data.Default.Class.Default a0, Data.Vector.Unboxed.Base.Unbox a0) => Data.Vector.Generic.Mutable.Base.MVector Data.Vector.Unboxed.Base.MVector (GHC.Base.Maybe a0)
+ Crypto.Lol.Prelude: instance (Data.Default.Class.Default a0, Data.Vector.Unboxed.Base.Unbox a0) => Data.Vector.Unboxed.Base.Unbox (GHC.Base.Maybe a0)
+ Crypto.Lol.Prelude: instance (System.Random.Random a, System.Random.Random b) => System.Random.Random (a, b)
+ Crypto.Lol.Prelude: instance Data.Default.Class.Default GHC.Types.Bool
+ Crypto.Lol.Prelude: instance forall (k :: BOX) (a :: k). Control.DeepSeq.NFData (Data.Proxy.Proxy a)
+ Crypto.Lol.Prelude: instance forall (k :: BOX) (k1 :: BOX) (s :: k) (m :: k1 -> *) (a :: k1). Control.DeepSeq.NFData (m a) => Control.DeepSeq.NFData (Data.Functor.Trans.Tagged.TaggedT s m a)
+ Crypto.Lol.Prelude: instance forall (k :: BOX) (tag :: k) (m :: * -> *). Control.Monad.Random.Class.MonadRandom m => Control.Monad.Random.Class.MonadRandom (Data.Functor.Trans.Tagged.TaggedT tag m)
+ Crypto.Lol.Prelude: lift :: Lift' b => b -> LiftOf b
+ Crypto.Lol.Prelude: lsdToMSD :: Encode src tgt => (src, tgt)
+ Crypto.Lol.Prelude: max :: Ord a => a -> a -> a
+ Crypto.Lol.Prelude: min :: Ord a => a -> a -> a
+ Crypto.Lol.Prelude: modinv :: (PID i, Eq i) => i -> i -> Maybe i
+ Crypto.Lol.Prelude: modulus :: Mod a => Tagged a (ModRep a)
+ Crypto.Lol.Prelude: msdToLSD :: (Encode src tgt) => (src, tgt)
+ Crypto.Lol.Prelude: pasteT :: TaggedT t f a -> Tagged t (f a)
+ Crypto.Lol.Prelude: peelT :: Tagged t (f a) -> TaggedT t f a
+ Crypto.Lol.Prelude: pureT :: Applicative f => Tagged t a -> TaggedT t f a
+ Crypto.Lol.Prelude: real :: Complex a -> a
+ Crypto.Lol.Prelude: realToField :: (Field b, ToRational a) => a -> b
+ Crypto.Lol.Prelude: reduce :: Reduce a b => a -> b
+ Crypto.Lol.Prelude: rescale :: Rescale a b => a -> b
+ Crypto.Lol.Prelude: rescaleMod :: (Mod a, Mod b, (ModRep a) ~ (ModRep b), Lift a (ModRep b), Ring b) => a -> b
+ Crypto.Lol.Prelude: roundComplex :: (RealRing a, ToInteger b) => Complex a -> (b, b)
+ Crypto.Lol.Prelude: roundCoset :: (Mod zp, z ~ ModRep zp, Lift zp z, RealField r) => zp -> r -> z
+ Crypto.Lol.Prelude: roundMult :: (RealField r, ToInteger i) => i -> r -> i
+ Crypto.Lol.Prelude: roundScalarCentered :: (RealField r, Random r, ToInteger i, MonadRandom mon) => i -> r -> mon i
+ Crypto.Lol.Prelude: type Absolute a = C a
+ Crypto.Lol.Prelude: type Additive a = C a
+ Crypto.Lol.Prelude: type Algebraic a = C a
+ Crypto.Lol.Prelude: type Field a = C a
+ Crypto.Lol.Prelude: type IntegralDomain a = C a
+ Crypto.Lol.Prelude: type Lift b a = (Lift' b, LiftOf b ~ a)
+ Crypto.Lol.Prelude: type Module a v = C a v
+ Crypto.Lol.Prelude: type OrdFloat a = (Ord a, Transcendental a)
+ Crypto.Lol.Prelude: type PID a = C a
+ Crypto.Lol.Prelude: type Polynomial a = T a
+ Crypto.Lol.Prelude: type RealField a = C a
+ Crypto.Lol.Prelude: type RealIntegral a = C a
+ Crypto.Lol.Prelude: type RealRing a = C a
+ Crypto.Lol.Prelude: type RealTranscendental a = C a
+ Crypto.Lol.Prelude: type Ring a = C a
+ Crypto.Lol.Prelude: type ToInteger a = C a
+ Crypto.Lol.Prelude: type ToRational a = C a
+ Crypto.Lol.Prelude: type Transcendental a = C a
+ Crypto.Lol.Prelude: type ZeroTestable a = C a
+ Crypto.Lol.Prelude: values :: Enumerable a => [a]
+ Crypto.Lol.Prelude: withWitness :: (SingI n => Tagged n r) -> Sing n -> r
+ Crypto.Lol.Prelude: withWitnessT :: (SingI n => TaggedT n mon r) -> Sing n -> mon r
+ Crypto.Lol.RLWE.Continuous: errorBound :: (Ord v, Transcendental v, Fact m) => v -> v -> Tagged m v
+ Crypto.Lol.RLWE.Continuous: errorGSqNorm :: (RLWECtx t m zq rrq, Ring (LiftOf rrq)) => Cyc t m zq -> Sample t m zq rrq -> LiftOf rrq
+ Crypto.Lol.RLWE.Continuous: errorTerm :: (RLWECtx t m zq rrq) => Cyc t m zq -> Sample t m zq rrq -> UCyc t m D (LiftOf rrq)
+ Crypto.Lol.RLWE.Continuous: sample :: (RLWECtx t m zq rrq, Random zq, Random (LiftOf rrq), OrdFloat (LiftOf rrq), MonadRandom rnd, ToRational v) => v -> Cyc t m zq -> rnd (Sample t m zq rrq)
+ Crypto.Lol.RLWE.Continuous: type RLWECtx t m zq rrq = (Fact m, Ring zq, CElt t zq, Subgroup zq rrq, Lift' rrq, TElt t rrq, TElt t (LiftOf rrq))
+ Crypto.Lol.RLWE.Continuous: type Sample t m zq rrq = (Cyc t m zq, UCyc t m D rrq)
+ Crypto.Lol.RLWE.Discrete: errorBound :: (RealRing v, Transcendental v, Fact m) => v -> v -> Tagged m Int64
+ 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: errorTerm :: (RLWECtx t m zq) => Cyc t m zq -> Sample t m zq -> Cyc t m (LiftOf zq)
+ Crypto.Lol.RLWE.Discrete: sample :: (RLWECtx t m zq, Random zq, MonadRandom rnd, ToRational v) => v -> Cyc t m zq -> rnd (Sample t m zq)
+ Crypto.Lol.RLWE.Discrete: type RLWECtx t m zq = (Fact m, Ring zq, Lift' zq, ToInteger (LiftOf zq), CElt t zq, CElt t (LiftOf zq))
+ Crypto.Lol.RLWE.Discrete: type Sample t m zq = (Cyc t m zq, Cyc t m zq)
+ Crypto.Lol.RLWE.RLWR: roundedProd :: (RLWRCtx t m zq zp) => Cyc t m zq -> Cyc t m zq -> Cyc t m zp
+ Crypto.Lol.RLWE.RLWR: sample :: (RLWRCtx t m zq zp, Random zq, MonadRandom rnd) => Cyc t m zq -> rnd (Sample t m zq zp)
+ Crypto.Lol.RLWE.RLWR: type RLWRCtx t m zq zp = (Fact m, Ring zq, RescaleCyc (Cyc t) zq zp, CElt t zq, CElt t zp)
+ Crypto.Lol.RLWE.RLWR: type Sample t m zq zp = (Cyc t m zq, Cyc t m zp)
+ Crypto.Lol.Reflects: instance (Crypto.Lol.FactoredDefs.Prime p, Algebra.ToInteger.C i) => Crypto.Lol.Reflects.Reflects p i
+ Crypto.Lol.Reflects: instance (Data.Reflection.Reifies q i, Algebra.ToInteger.C i, Algebra.Ring.C r) => Crypto.Lol.Reflects.Reflects q r
+ Crypto.Lol.Types.FiniteField: instance forall (k :: BOX) fp (d :: k). Crypto.Lol.Types.FiniteField.GFCtx fp d => Crypto.Lol.CRTrans.CRTrans GHC.Base.Maybe (Crypto.Lol.Types.FiniteField.GF fp d)
+ Crypto.Lol.Types.FiniteField: instance forall (k :: BOX) fp (d :: k). Crypto.Lol.Types.FiniteField.GFCtx fp d => Crypto.Lol.Prelude.Enumerable (Crypto.Lol.Types.FiniteField.GF fp d)
+ Crypto.Lol.Types.IrreducibleChar2: instance (Crypto.Lol.Prelude.CharOf a ~ Crypto.Lol.Factored.Prime2, Crypto.Lol.Types.Numeric.Field a) => Crypto.Lol.Types.FiniteField.IrreduciblePoly a
+ Crypto.Lol.Types.Proto: class Protoable a where type family ProtoType a
+ Crypto.Lol.Types.Proto: fromProto :: (Protoable a, MonadError String m) => ProtoType a -> m a
+ Crypto.Lol.Types.Proto: instance (Crypto.Lol.Types.Proto.Protoable a, Crypto.Lol.Types.Proto.Protoable b) => Crypto.Lol.Types.Proto.Protoable (a, b)
+ Crypto.Lol.Types.Proto: instance Crypto.Lol.Types.Proto.Protoable a => Crypto.Lol.Types.Proto.Protoable [a]
+ Crypto.Lol.Types.Proto: msgGet :: (ReflectDescriptor (ProtoType a), Wire (ProtoType a), Protoable a) => ByteString -> Either String (a, ByteString)
+ Crypto.Lol.Types.Proto: msgPut :: (ReflectDescriptor (ProtoType a), Wire (ProtoType a), Protoable a) => a -> ByteString
+ Crypto.Lol.Types.Proto: toProto :: Protoable a => a -> ProtoType a
+ Crypto.Lol.Types.RRq: data RRq q r
+ Crypto.Lol.Types.RRq: instance forall (k :: BOX) (q :: k) i r. (Crypto.Lol.Types.Numeric.ToInteger i, Crypto.Lol.Types.Numeric.RealField r, Crypto.Lol.Reflects.Reflects q i, Crypto.Lol.Reflects.Reflects q r) => Crypto.Lol.Prelude.Subgroup (Crypto.Lol.Types.ZqBasic.ZqBasic q i) (Crypto.Lol.Types.RRq.RRq q r)
+ Crypto.Lol.Types.RRq: instance forall (k :: BOX) (q :: k) r. (Crypto.Lol.Reflects.Reflects q r, Crypto.Lol.Prelude.Reduce r (Crypto.Lol.Types.RRq.RRq q r), GHC.Classes.Ord r, Crypto.Lol.Types.Numeric.Ring r) => Crypto.Lol.Prelude.Lift' (Crypto.Lol.Types.RRq.RRq q r)
+ Crypto.Lol.Types.RRq: instance forall (k :: BOX) (q :: k) r. (Crypto.Lol.Reflects.Reflects q r, Crypto.Lol.Types.Numeric.RealField r, GHC.Classes.Ord r) => Algebra.Additive.C (Crypto.Lol.Types.RRq.RRq q r)
+ Crypto.Lol.Types.RRq: instance forall (k :: BOX) (q :: k) r. Algebra.ZeroTestable.C r => Algebra.ZeroTestable.C (Crypto.Lol.Types.RRq.RRq q r)
+ Crypto.Lol.Types.RRq: instance forall (k :: BOX) (q :: k) r. Control.DeepSeq.NFData r => Control.DeepSeq.NFData (Crypto.Lol.Types.RRq.RRq q r)
+ Crypto.Lol.Types.RRq: instance forall (k :: BOX) (q :: k) r. Data.Array.Repa.Eval.Elt.Elt r => Data.Array.Repa.Eval.Elt.Elt (Crypto.Lol.Types.RRq.RRq q r)
+ Crypto.Lol.Types.RRq: instance forall (k :: BOX) (q :: k) r. Data.Vector.Unboxed.Base.Unbox r => Data.Vector.Generic.Base.Vector Data.Vector.Unboxed.Base.Vector (Crypto.Lol.Types.RRq.RRq q r)
+ Crypto.Lol.Types.RRq: instance forall (k :: BOX) (q :: k) r. Data.Vector.Unboxed.Base.Unbox r => Data.Vector.Generic.Mutable.Base.MVector Data.Vector.Unboxed.Base.MVector (Crypto.Lol.Types.RRq.RRq q r)
+ Crypto.Lol.Types.RRq: instance forall (k :: BOX) (q :: k) r. Data.Vector.Unboxed.Base.Unbox r => Data.Vector.Unboxed.Base.Unbox (Crypto.Lol.Types.RRq.RRq q r)
+ Crypto.Lol.Types.RRq: instance forall (k :: BOX) (q :: k) r. Foreign.Storable.Storable r => Foreign.Storable.Storable (Crypto.Lol.Types.RRq.RRq q r)
+ Crypto.Lol.Types.RRq: instance forall (k :: BOX) (q :: k) r. GHC.Classes.Eq r => GHC.Classes.Eq (Crypto.Lol.Types.RRq.RRq q r)
+ Crypto.Lol.Types.RRq: instance forall (k :: BOX) (q :: k) r. GHC.Classes.Ord r => GHC.Classes.Ord (Crypto.Lol.Types.RRq.RRq q r)
+ Crypto.Lol.Types.RRq: instance forall (k :: BOX) (q :: k) r. GHC.Show.Show r => GHC.Show.Show (Crypto.Lol.Types.RRq.RRq q r)
+ Crypto.Lol.Types.RRq: instance forall (k :: BOX) r (q :: k). (Crypto.Lol.Reflects.Reflects q r, Crypto.Lol.Types.Numeric.RealField r, Crypto.Lol.Types.Numeric.Additive (Crypto.Lol.Types.RRq.RRq q r)) => Crypto.Lol.Prelude.Reduce r (Crypto.Lol.Types.RRq.RRq q r)
+ Crypto.Lol.Types.Random: evalCryptoRandIO :: (CryptoRandomGen g, MonadIO io) => RandT g io a -> io a
+ Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (k1 :: BOX) (b :: k) (q :: k1) z. (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z, Crypto.Lol.Types.Numeric.RealIntegral z, Crypto.Lol.Reflects.Reflects b z) => Crypto.Lol.Gadget.Gadget (Crypto.Lol.Gadget.BaseBGad b) (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (k1 :: BOX) (b :: k) (q :: k1) z. (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z, Crypto.Lol.Types.Numeric.Ring z, Crypto.Lol.Reflects.Reflects b z) => Crypto.Lol.Gadget.Correct (Crypto.Lol.Gadget.BaseBGad b) (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (k1 :: BOX) (b :: k) (q :: k1) z. (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z, Crypto.Lol.Types.Numeric.Ring z, Crypto.Lol.Types.Numeric.ZeroTestable z, Crypto.Lol.Reflects.Reflects b z) => Crypto.Lol.Gadget.Decompose (Crypto.Lol.Gadget.BaseBGad b) (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (k1 :: BOX) (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 :: BOX) (k1 :: BOX) (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.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z) => Crypto.Lol.Prelude.Lift' (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z) => Crypto.Lol.Prelude.Mod (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z, Crypto.Lol.Types.Numeric.Additive (Crypto.Lol.Types.ZqBasic.ZqBasic q z)) => Crypto.Lol.Prelude.Reduce GHC.Integer.Type.Integer (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z, Crypto.Lol.Types.Numeric.Additive z) => Algebra.Additive.C (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z, Crypto.Lol.Types.Numeric.Additive z) => Crypto.Lol.Gadget.Gadget Crypto.Lol.Gadget.TrivGad (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) 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)) => Algebra.IntegralDomain.C (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z, Crypto.Lol.Types.Numeric.PID z, Crypto.Lol.Prelude.Enumerable (Crypto.Lol.Types.ZqBasic.ZqBasic q z)) => Crypto.Lol.CRTrans.CRTrans GHC.Base.Maybe (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z, Crypto.Lol.Types.Numeric.PID z, GHC.Show.Show z) => Algebra.Field.C (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z, Crypto.Lol.Types.Numeric.Ring (Crypto.Lol.Types.ZqBasic.ZqBasic q z)) => Crypto.Lol.CRTrans.CRTEmbed (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z, Crypto.Lol.Types.Numeric.Ring z) => Algebra.Ring.C (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z, Crypto.Lol.Types.Numeric.Ring z) => Crypto.Lol.Gadget.Correct Crypto.Lol.Gadget.TrivGad (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z, Crypto.Lol.Types.Numeric.Ring z) => Crypto.Lol.Gadget.Decompose Crypto.Lol.Gadget.TrivGad (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z, GHC.Enum.Enum z) => Crypto.Lol.Prelude.Enumerable (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z, System.Random.Random z) => System.Random.Random (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) (q :: k) z. (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z, System.Random.Random z) => Test.QuickCheck.Arbitrary.Arbitrary (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Lol.Types.ZqBasic: instance forall (k :: BOX) z (q :: k). (Crypto.Lol.Reflects.Reflects q z, Crypto.Lol.Types.Numeric.ToInteger z) => Crypto.Lol.Prelude.Reduce z (Crypto.Lol.Types.ZqBasic.ZqBasic q z)
+ Crypto.Proto.RLWE: fileDescriptorProto :: FileDescriptorProto
+ Crypto.Proto.RLWE: protoInfo :: ProtoInfo
+ Crypto.Proto.RLWE.Kq: Kq :: !(Word32) -> !(Double) -> !(Seq Double) -> Kq
+ Crypto.Proto.RLWE.Kq: [m] :: Kq -> !(Word32)
+ Crypto.Proto.RLWE.Kq: [q] :: Kq -> !(Double)
+ Crypto.Proto.RLWE.Kq: [xs] :: Kq -> !(Seq Double)
+ Crypto.Proto.RLWE.Kq: data Kq
+ Crypto.Proto.RLWE.Kq: instance Data.Data.Data Crypto.Proto.RLWE.Kq.Kq
+ Crypto.Proto.RLWE.Kq: instance GHC.Classes.Eq Crypto.Proto.RLWE.Kq.Kq
+ Crypto.Proto.RLWE.Kq: instance GHC.Classes.Ord Crypto.Proto.RLWE.Kq.Kq
+ Crypto.Proto.RLWE.Kq: instance GHC.Generics.Constructor Crypto.Proto.RLWE.Kq.C1_0Kq
+ Crypto.Proto.RLWE.Kq: instance GHC.Generics.Datatype Crypto.Proto.RLWE.Kq.D1Kq
+ Crypto.Proto.RLWE.Kq: instance GHC.Generics.Generic Crypto.Proto.RLWE.Kq.Kq
+ Crypto.Proto.RLWE.Kq: instance GHC.Generics.Selector Crypto.Proto.RLWE.Kq.S1_0_0Kq
+ Crypto.Proto.RLWE.Kq: instance GHC.Generics.Selector Crypto.Proto.RLWE.Kq.S1_0_1Kq
+ Crypto.Proto.RLWE.Kq: instance GHC.Generics.Selector Crypto.Proto.RLWE.Kq.S1_0_2Kq
+ Crypto.Proto.RLWE.Kq: instance GHC.Show.Show Crypto.Proto.RLWE.Kq.Kq
+ Crypto.Proto.RLWE.Kq: instance Text.ProtocolBuffers.Basic.Default Crypto.Proto.RLWE.Kq.Kq
+ Crypto.Proto.RLWE.Kq: instance Text.ProtocolBuffers.Basic.Mergeable Crypto.Proto.RLWE.Kq.Kq
+ Crypto.Proto.RLWE.Kq: instance Text.ProtocolBuffers.Extensions.GPB Crypto.Proto.RLWE.Kq.Kq
+ Crypto.Proto.RLWE.Kq: instance Text.ProtocolBuffers.Extensions.MessageAPI msg' (msg' -> Crypto.Proto.RLWE.Kq.Kq) Crypto.Proto.RLWE.Kq.Kq
+ Crypto.Proto.RLWE.Kq: instance Text.ProtocolBuffers.Reflections.ReflectDescriptor Crypto.Proto.RLWE.Kq.Kq
+ Crypto.Proto.RLWE.Kq: instance Text.ProtocolBuffers.TextMessage.TextMsg Crypto.Proto.RLWE.Kq.Kq
+ Crypto.Proto.RLWE.Kq: instance Text.ProtocolBuffers.TextMessage.TextType Crypto.Proto.RLWE.Kq.Kq
+ Crypto.Proto.RLWE.Kq: instance Text.ProtocolBuffers.WireMessage.Wire Crypto.Proto.RLWE.Kq.Kq
+ Crypto.Proto.RLWE.Rq: Rq :: !(Word32) -> !(Word64) -> !(Seq Int64) -> Rq
+ Crypto.Proto.RLWE.Rq: [m] :: Rq -> !(Word32)
+ Crypto.Proto.RLWE.Rq: [q] :: Rq -> !(Word64)
+ Crypto.Proto.RLWE.Rq: [xs] :: Rq -> !(Seq Int64)
+ Crypto.Proto.RLWE.Rq: data Rq
+ Crypto.Proto.RLWE.Rq: instance Data.Data.Data Crypto.Proto.RLWE.Rq.Rq
+ Crypto.Proto.RLWE.Rq: instance GHC.Classes.Eq Crypto.Proto.RLWE.Rq.Rq
+ Crypto.Proto.RLWE.Rq: instance GHC.Classes.Ord Crypto.Proto.RLWE.Rq.Rq
+ Crypto.Proto.RLWE.Rq: instance GHC.Generics.Constructor Crypto.Proto.RLWE.Rq.C1_0Rq
+ Crypto.Proto.RLWE.Rq: instance GHC.Generics.Datatype Crypto.Proto.RLWE.Rq.D1Rq
+ Crypto.Proto.RLWE.Rq: instance GHC.Generics.Generic Crypto.Proto.RLWE.Rq.Rq
+ Crypto.Proto.RLWE.Rq: instance GHC.Generics.Selector Crypto.Proto.RLWE.Rq.S1_0_0Rq
+ Crypto.Proto.RLWE.Rq: instance GHC.Generics.Selector Crypto.Proto.RLWE.Rq.S1_0_1Rq
+ Crypto.Proto.RLWE.Rq: instance GHC.Generics.Selector Crypto.Proto.RLWE.Rq.S1_0_2Rq
+ Crypto.Proto.RLWE.Rq: instance GHC.Show.Show Crypto.Proto.RLWE.Rq.Rq
+ Crypto.Proto.RLWE.Rq: instance Text.ProtocolBuffers.Basic.Default Crypto.Proto.RLWE.Rq.Rq
+ Crypto.Proto.RLWE.Rq: instance Text.ProtocolBuffers.Basic.Mergeable Crypto.Proto.RLWE.Rq.Rq
+ Crypto.Proto.RLWE.Rq: instance Text.ProtocolBuffers.Extensions.GPB Crypto.Proto.RLWE.Rq.Rq
+ Crypto.Proto.RLWE.Rq: instance Text.ProtocolBuffers.Extensions.MessageAPI msg' (msg' -> Crypto.Proto.RLWE.Rq.Rq) Crypto.Proto.RLWE.Rq.Rq
+ Crypto.Proto.RLWE.Rq: instance Text.ProtocolBuffers.Reflections.ReflectDescriptor Crypto.Proto.RLWE.Rq.Rq
+ Crypto.Proto.RLWE.Rq: instance Text.ProtocolBuffers.TextMessage.TextMsg Crypto.Proto.RLWE.Rq.Rq
+ Crypto.Proto.RLWE.Rq: instance Text.ProtocolBuffers.TextMessage.TextType Crypto.Proto.RLWE.Rq.Rq
+ Crypto.Proto.RLWE.Rq: instance Text.ProtocolBuffers.WireMessage.Wire Crypto.Proto.RLWE.Rq.Rq
+ Crypto.Proto.RLWE.SampleCont: SampleCont :: !(Rq) -> !(Kq) -> SampleCont
+ Crypto.Proto.RLWE.SampleCont: [a] :: SampleCont -> !(Rq)
+ Crypto.Proto.RLWE.SampleCont: [b] :: SampleCont -> !(Kq)
+ Crypto.Proto.RLWE.SampleCont: data SampleCont
+ Crypto.Proto.RLWE.SampleCont: instance Data.Data.Data Crypto.Proto.RLWE.SampleCont.SampleCont
+ Crypto.Proto.RLWE.SampleCont: instance GHC.Classes.Eq Crypto.Proto.RLWE.SampleCont.SampleCont
+ Crypto.Proto.RLWE.SampleCont: instance GHC.Classes.Ord Crypto.Proto.RLWE.SampleCont.SampleCont
+ Crypto.Proto.RLWE.SampleCont: instance GHC.Generics.Constructor Crypto.Proto.RLWE.SampleCont.C1_0SampleCont
+ Crypto.Proto.RLWE.SampleCont: instance GHC.Generics.Datatype Crypto.Proto.RLWE.SampleCont.D1SampleCont
+ Crypto.Proto.RLWE.SampleCont: instance GHC.Generics.Generic Crypto.Proto.RLWE.SampleCont.SampleCont
+ Crypto.Proto.RLWE.SampleCont: instance GHC.Generics.Selector Crypto.Proto.RLWE.SampleCont.S1_0_0SampleCont
+ Crypto.Proto.RLWE.SampleCont: instance GHC.Generics.Selector Crypto.Proto.RLWE.SampleCont.S1_0_1SampleCont
+ Crypto.Proto.RLWE.SampleCont: instance GHC.Show.Show Crypto.Proto.RLWE.SampleCont.SampleCont
+ Crypto.Proto.RLWE.SampleCont: instance Text.ProtocolBuffers.Basic.Default Crypto.Proto.RLWE.SampleCont.SampleCont
+ Crypto.Proto.RLWE.SampleCont: instance Text.ProtocolBuffers.Basic.Mergeable Crypto.Proto.RLWE.SampleCont.SampleCont
+ Crypto.Proto.RLWE.SampleCont: instance Text.ProtocolBuffers.Extensions.GPB Crypto.Proto.RLWE.SampleCont.SampleCont
+ Crypto.Proto.RLWE.SampleCont: instance Text.ProtocolBuffers.Extensions.MessageAPI msg' (msg' -> Crypto.Proto.RLWE.SampleCont.SampleCont) Crypto.Proto.RLWE.SampleCont.SampleCont
+ Crypto.Proto.RLWE.SampleCont: instance Text.ProtocolBuffers.Reflections.ReflectDescriptor Crypto.Proto.RLWE.SampleCont.SampleCont
+ Crypto.Proto.RLWE.SampleCont: instance Text.ProtocolBuffers.TextMessage.TextMsg Crypto.Proto.RLWE.SampleCont.SampleCont
+ Crypto.Proto.RLWE.SampleCont: instance Text.ProtocolBuffers.TextMessage.TextType Crypto.Proto.RLWE.SampleCont.SampleCont
+ Crypto.Proto.RLWE.SampleCont: instance Text.ProtocolBuffers.WireMessage.Wire Crypto.Proto.RLWE.SampleCont.SampleCont
+ Crypto.Proto.RLWE.SampleDisc: SampleDisc :: !(Rq) -> !(Rq) -> SampleDisc
+ Crypto.Proto.RLWE.SampleDisc: [a] :: SampleDisc -> !(Rq)
+ Crypto.Proto.RLWE.SampleDisc: [b] :: SampleDisc -> !(Rq)
+ Crypto.Proto.RLWE.SampleDisc: data SampleDisc
+ Crypto.Proto.RLWE.SampleDisc: instance Data.Data.Data Crypto.Proto.RLWE.SampleDisc.SampleDisc
+ Crypto.Proto.RLWE.SampleDisc: instance GHC.Classes.Eq Crypto.Proto.RLWE.SampleDisc.SampleDisc
+ Crypto.Proto.RLWE.SampleDisc: instance GHC.Classes.Ord Crypto.Proto.RLWE.SampleDisc.SampleDisc
+ Crypto.Proto.RLWE.SampleDisc: instance GHC.Generics.Constructor Crypto.Proto.RLWE.SampleDisc.C1_0SampleDisc
+ Crypto.Proto.RLWE.SampleDisc: instance GHC.Generics.Datatype Crypto.Proto.RLWE.SampleDisc.D1SampleDisc
+ Crypto.Proto.RLWE.SampleDisc: instance GHC.Generics.Generic Crypto.Proto.RLWE.SampleDisc.SampleDisc
+ Crypto.Proto.RLWE.SampleDisc: instance GHC.Generics.Selector Crypto.Proto.RLWE.SampleDisc.S1_0_0SampleDisc
+ Crypto.Proto.RLWE.SampleDisc: instance GHC.Generics.Selector Crypto.Proto.RLWE.SampleDisc.S1_0_1SampleDisc
+ Crypto.Proto.RLWE.SampleDisc: instance GHC.Show.Show Crypto.Proto.RLWE.SampleDisc.SampleDisc
+ Crypto.Proto.RLWE.SampleDisc: instance Text.ProtocolBuffers.Basic.Default Crypto.Proto.RLWE.SampleDisc.SampleDisc
+ Crypto.Proto.RLWE.SampleDisc: instance Text.ProtocolBuffers.Basic.Mergeable Crypto.Proto.RLWE.SampleDisc.SampleDisc
+ Crypto.Proto.RLWE.SampleDisc: instance Text.ProtocolBuffers.Extensions.GPB Crypto.Proto.RLWE.SampleDisc.SampleDisc
+ Crypto.Proto.RLWE.SampleDisc: instance Text.ProtocolBuffers.Extensions.MessageAPI msg' (msg' -> Crypto.Proto.RLWE.SampleDisc.SampleDisc) Crypto.Proto.RLWE.SampleDisc.SampleDisc
+ Crypto.Proto.RLWE.SampleDisc: instance Text.ProtocolBuffers.Reflections.ReflectDescriptor Crypto.Proto.RLWE.SampleDisc.SampleDisc
+ Crypto.Proto.RLWE.SampleDisc: instance Text.ProtocolBuffers.TextMessage.TextMsg Crypto.Proto.RLWE.SampleDisc.SampleDisc
+ Crypto.Proto.RLWE.SampleDisc: instance Text.ProtocolBuffers.TextMessage.TextType Crypto.Proto.RLWE.SampleDisc.SampleDisc
+ Crypto.Proto.RLWE.SampleDisc: instance Text.ProtocolBuffers.WireMessage.Wire Crypto.Proto.RLWE.SampleDisc.SampleDisc
+ Crypto.Proto.RLWE.SampleRLWR: SampleRLWR :: !(Rq) -> !(Rq) -> SampleRLWR
+ Crypto.Proto.RLWE.SampleRLWR: [a] :: SampleRLWR -> !(Rq)
+ Crypto.Proto.RLWE.SampleRLWR: [b] :: SampleRLWR -> !(Rq)
+ Crypto.Proto.RLWE.SampleRLWR: data SampleRLWR
+ Crypto.Proto.RLWE.SampleRLWR: instance Data.Data.Data Crypto.Proto.RLWE.SampleRLWR.SampleRLWR
+ Crypto.Proto.RLWE.SampleRLWR: instance GHC.Classes.Eq Crypto.Proto.RLWE.SampleRLWR.SampleRLWR
+ Crypto.Proto.RLWE.SampleRLWR: instance GHC.Classes.Ord Crypto.Proto.RLWE.SampleRLWR.SampleRLWR
+ Crypto.Proto.RLWE.SampleRLWR: instance GHC.Generics.Constructor Crypto.Proto.RLWE.SampleRLWR.C1_0SampleRLWR
+ Crypto.Proto.RLWE.SampleRLWR: instance GHC.Generics.Datatype Crypto.Proto.RLWE.SampleRLWR.D1SampleRLWR
+ Crypto.Proto.RLWE.SampleRLWR: instance GHC.Generics.Generic Crypto.Proto.RLWE.SampleRLWR.SampleRLWR
+ Crypto.Proto.RLWE.SampleRLWR: instance GHC.Generics.Selector Crypto.Proto.RLWE.SampleRLWR.S1_0_0SampleRLWR
+ Crypto.Proto.RLWE.SampleRLWR: instance GHC.Generics.Selector Crypto.Proto.RLWE.SampleRLWR.S1_0_1SampleRLWR
+ Crypto.Proto.RLWE.SampleRLWR: instance GHC.Show.Show Crypto.Proto.RLWE.SampleRLWR.SampleRLWR
+ Crypto.Proto.RLWE.SampleRLWR: instance Text.ProtocolBuffers.Basic.Default Crypto.Proto.RLWE.SampleRLWR.SampleRLWR
+ Crypto.Proto.RLWE.SampleRLWR: instance Text.ProtocolBuffers.Basic.Mergeable Crypto.Proto.RLWE.SampleRLWR.SampleRLWR
+ Crypto.Proto.RLWE.SampleRLWR: instance Text.ProtocolBuffers.Extensions.GPB Crypto.Proto.RLWE.SampleRLWR.SampleRLWR
+ Crypto.Proto.RLWE.SampleRLWR: instance Text.ProtocolBuffers.Extensions.MessageAPI msg' (msg' -> Crypto.Proto.RLWE.SampleRLWR.SampleRLWR) Crypto.Proto.RLWE.SampleRLWR.SampleRLWR
+ Crypto.Proto.RLWE.SampleRLWR: instance Text.ProtocolBuffers.Reflections.ReflectDescriptor Crypto.Proto.RLWE.SampleRLWR.SampleRLWR
+ Crypto.Proto.RLWE.SampleRLWR: instance Text.ProtocolBuffers.TextMessage.TextMsg Crypto.Proto.RLWE.SampleRLWR.SampleRLWR
+ Crypto.Proto.RLWE.SampleRLWR: instance Text.ProtocolBuffers.TextMessage.TextType Crypto.Proto.RLWE.SampleRLWR.SampleRLWR
+ Crypto.Proto.RLWE.SampleRLWR: instance Text.ProtocolBuffers.WireMessage.Wire Crypto.Proto.RLWE.SampleRLWR.SampleRLWR
- Crypto.Lol.CRTrans: class Ring r => CRTrans r where crtInfo = const Nothing
+ Crypto.Lol.CRTrans: class (Monad mon, Ring r) => CRTrans mon r
- Crypto.Lol.CRTrans: crtInfo :: CRTrans r => Int -> Maybe (CRTInfo r)
+ Crypto.Lol.CRTrans: crtInfo :: (CRTrans mon r, Reflects m Int) => TaggedT m mon (CRTInfo r)
- Crypto.Lol.Cyclotomic.Cyc: cycCRT :: UCyc t m C r -> Cyc t m r
+ Crypto.Lol.Cyclotomic.Cyc: cycCRT :: UCycEC t m r -> Cyc t m r
- Crypto.Lol.Cyclotomic.Cyc: divG :: (Fact m, CElt t r) => Cyc t m r -> Maybe (Cyc t m r)
+ Crypto.Lol.Cyclotomic.Cyc: divG :: (Fact m, CElt t r, IntegralDomain r) => Cyc t m r -> Maybe (Cyc t m r)
- Crypto.Lol.Cyclotomic.Cyc: type CElt t r = UCElt t r
+ Crypto.Lol.Cyclotomic.Cyc: type CElt t r = (UCRTElt t r, ZeroTestable r)
- Crypto.Lol.Cyclotomic.Cyc: uncycCRT :: (Fact m, CElt t r) => Cyc t m r -> UCyc t m C r
+ Crypto.Lol.Cyclotomic.Cyc: uncycCRT :: (Fact m, CElt t r) => Cyc t m r -> UCycEC t m r
- Crypto.Lol.Cyclotomic.Cyc: unzipCyc :: (Tensor t, Fact m) => Cyc t m (a, b) -> (Cyc t m a, Cyc t m b)
+ Crypto.Lol.Cyclotomic.Cyc: unzipCyc :: (Tensor t, Fact m, CElt t (a, b), CElt t a, CElt t b) => Cyc t m (a, b) -> (Cyc t m a, Cyc t m b)
- Crypto.Lol.Cyclotomic.Tensor: class (TElt t Double, TElt t (Complex Double)) => Tensor (t :: Factored -> * -> *) where type family TElt t r :: Constraint
+ Crypto.Lol.Cyclotomic.Tensor: class (TElt t Double, TElt t (Complex Double)) => Tensor t where type family TElt t r :: Constraint
- Crypto.Lol.Cyclotomic.Tensor: crt :: (Tensor t, Fact m, CRTElt t r) => Maybe (t m r -> t m r)
+ Crypto.Lol.Cyclotomic.Tensor: crt :: (CRTrans mon r, Tensor t, Fact m, TElt t r) => mon (t m r -> t m r)
- Crypto.Lol.Cyclotomic.Tensor: crtExtFuncs :: (Tensor t, m `Divides` m', CRTElt t r) => Maybe (t m' r -> t m r, t m r -> t m' r)
+ Crypto.Lol.Cyclotomic.Tensor: crtExtFuncs :: (Tensor t, CRTrans mon r, m `Divides` m', TElt t r) => mon (t m' r -> t m r, t m r -> t m' r)
- Crypto.Lol.Cyclotomic.Tensor: crtFuncs :: (Tensor t, Fact m, CRTElt t r) => Maybe (r -> t m r, t m r -> t m r, t m r -> t m r, t m r -> t m r, t m r -> t m r)
+ Crypto.Lol.Cyclotomic.Tensor: crtFuncs :: (Tensor t, CRTrans mon r, Fact m, TElt t r) => mon (r -> t m r, t m r -> t m r, t m r -> t m r, t m r -> t m r, t m r -> t m r)
- Crypto.Lol.Cyclotomic.Tensor: crtInv :: (Tensor t, Fact m, CRTElt t r) => Maybe (t m r -> t m r)
+ Crypto.Lol.Cyclotomic.Tensor: crtInv :: (CRTrans mon r, Tensor t, Fact m, TElt t r) => mon (t m r -> t m r)
- Crypto.Lol.Cyclotomic.Tensor: divGCRT :: (Tensor t, Fact m, CRTElt t r) => Maybe (t m r -> t m r)
+ Crypto.Lol.Cyclotomic.Tensor: divGCRT :: (CRTrans mon r, Tensor t, Fact m, TElt t r) => mon (t m r -> t m r)
- Crypto.Lol.Cyclotomic.Tensor: embedCRT :: (Tensor t, m `Divides` m', CRTElt t r) => Maybe (t m r -> t m' r)
+ Crypto.Lol.Cyclotomic.Tensor: embedCRT :: (CRTrans mon r, Tensor t, m `Divides` m', TElt t r) => mon (t m r -> t m' r)
- Crypto.Lol.Cyclotomic.Tensor: entailShowT :: Tensor t => Tagged (t m r) ((Show r, Fact m, TElt t r) :- (Show (t m r)))
+ Crypto.Lol.Cyclotomic.Tensor: entailShowT :: Tensor t => Tagged (t m r) ((Show r, Fact m, TElt t r) :- Show (t m r))
- Crypto.Lol.Cyclotomic.Tensor: hasCRTFuncs :: (Tensor t, Fact m, CRTElt t r) => TaggedT (t m r) Maybe ()
+ Crypto.Lol.Cyclotomic.Tensor: hasCRTFuncs :: (CRTrans mon r, Tensor t, Fact m, TElt t r) => TaggedT (t m r) mon ()
- Crypto.Lol.Cyclotomic.Tensor: mulGCRT :: (Tensor t, Fact m, CRTElt t r) => Maybe (t m r -> t m r)
+ Crypto.Lol.Cyclotomic.Tensor: mulGCRT :: (CRTrans mon r, Tensor t, Fact m, TElt t r) => mon (t m r -> t m r)
- Crypto.Lol.Cyclotomic.Tensor: scalarCRT :: (Tensor t, Fact m, CRTElt t r) => Maybe (r -> t m r)
+ Crypto.Lol.Cyclotomic.Tensor: scalarCRT :: (CRTrans mon r, Tensor t, Fact m, TElt t r) => mon (r -> t m r)
- Crypto.Lol.Cyclotomic.Tensor: twCRTs :: (Fact m, CRTrans r) => TaggedT m Maybe (Matrix r)
+ Crypto.Lol.Cyclotomic.Tensor: twCRTs :: (Fact m, CRTrans mon r) => TaggedT m mon (Matrix r)
- Crypto.Lol.Cyclotomic.Tensor: twaceCRT :: (Tensor t, m `Divides` m', CRTElt t r) => Maybe (t m' r -> t m r)
+ Crypto.Lol.Cyclotomic.Tensor: twaceCRT :: (CRTrans mon r, Tensor t, m `Divides` m', TElt t r) => mon (t m' r -> t m r)
- Crypto.Lol.Cyclotomic.Tensor: unzipT :: (Tensor t, Fact m) => t m (a, b) -> (t m a, t m b)
+ Crypto.Lol.Cyclotomic.Tensor: unzipT :: (Tensor t, Fact m, TElt t (a, b), TElt t a, TElt t b) => t m (a, b) -> (t m a, t m b)
- Crypto.Lol.Cyclotomic.UCyc: crtSet :: (m `Divides` m', ZPP r, p ~ CharOf (ZpOf r), mbar ~ PFree p m, m'bar ~ PFree p m', UCElt t r, TElt t (ZpOf r)) => Tagged m [UCyc t m' P r]
+ Crypto.Lol.Cyclotomic.UCyc: crtSet :: (m `Divides` m', ZPP r, p ~ CharOf (ZpOf r), mbar ~ PFree p m, m'bar ~ PFree p m', UCRTElt t r, TElt t (ZpOf r)) => Tagged m [UCyc t m' P r]
- Crypto.Lol.Cyclotomic.UCyc: data UCyc t m rep r
+ Crypto.Lol.Cyclotomic.UCyc: data UCyc t (m :: Factored) rep r
- Crypto.Lol.Cyclotomic.UCyc: divG :: (Tensor t, Fact m, UCElt t r) => UCyc t m rep r -> Maybe (UCyc t m rep r)
+ Crypto.Lol.Cyclotomic.UCyc: divG :: (Tensor t, Fact m, UCRTElt t r, ZeroTestable r, IntegralDomain r) => UCyc t m rep r -> Maybe (UCyc t m rep r)
- Crypto.Lol.Cyclotomic.UCyc: mulG :: (Tensor t, Fact m, UCElt t r) => UCyc t m rep r -> UCyc t m rep r
+ Crypto.Lol.Cyclotomic.UCyc: mulG :: (Tensor t, Fact m, UCRTElt t r) => UCyc t m rep r -> UCyc t m rep r
- Crypto.Lol.Cyclotomic.UCyc: scalarCRT :: (Fact m, UCElt t r) => r -> UCyc t m C r
+ Crypto.Lol.Cyclotomic.UCyc: scalarCRT :: (Fact m, UCRTElt t r) => r -> UCycEC t m r
- Crypto.Lol.Cyclotomic.UCyc: toCRT :: (Fact m, UCElt t r) => UCyc t m rep r -> UCyc t m C r
+ Crypto.Lol.Cyclotomic.UCyc: toCRT :: (Fact m, UCRTElt t r) => UCyc t m rep r -> UCycEC t m r
- Crypto.Lol.Cyclotomic.UCyc: toDec :: (Fact m, UCElt t r) => UCyc t m rep r -> UCyc t m D r
+ Crypto.Lol.Cyclotomic.UCyc: toDec :: (Fact m, UCRTElt t r) => UCyc t m rep r -> UCyc t m D r
- Crypto.Lol.Cyclotomic.UCyc: toPow :: (Fact m, UCElt t r) => UCyc t m rep r -> UCyc t m P r
+ Crypto.Lol.Cyclotomic.UCyc: toPow :: (Fact m, UCRTElt t r) => UCyc t m rep r -> UCyc t m P r
- Crypto.Lol.Factored: pFree :: Prime -> Factored -> Factored
+ Crypto.Lol.Factored: pFree :: PrimeBin -> Factored -> Factored
- Crypto.Lol.Factored: pFreeDivides :: Proxy p -> Proxy m -> Proxy m' -> ((Prim p, m `Divides` m') :- ((PFree p m) `Divides` (PFree p m')))
+ Crypto.Lol.Factored: pFreeDivides :: Proxy p -> Proxy m -> Proxy m' -> ((Prime p, m `Divides` m') :- ((PFree p m) `Divides` (PFree p m')))
- Crypto.Lol.Factored: pSplitTheorems :: Proxy p -> Proxy m -> ((Prim p, Fact m, f ~ PFree p m) :- (f `Divides` m, Coprime (PToF p) f))
+ Crypto.Lol.Factored: pSplitTheorems :: Proxy p -> Proxy m -> ((Prime p, Fact m, f ~ PFree p m) :- (f `Divides` m, Coprime (PToF p) f))
- Crypto.Lol.Factored: pToF :: Prime -> Factored
+ Crypto.Lol.Factored: pToF :: PrimeBin -> Factored
- Crypto.Lol.Factored: pToPP :: Prime -> PrimePower
+ Crypto.Lol.Factored: pToPP :: PrimeBin -> PrimePower
- Crypto.Lol.Factored: primePP :: PrimePower -> Prime
+ Crypto.Lol.Factored: primePP :: PrimePower -> PrimeBin
- Crypto.Lol.Factored: sPToF :: Sing t_aL6X -> Sing (Apply PToFSym0 t_aL6X :: Factored)
+ Crypto.Lol.Factored: sPToF :: Sing t_a1tb4 -> Sing (Apply PToFSym0 t_a1tb4 :: Factored)
- Crypto.Lol.Factored: sPToPP :: Sing t_aL6W -> Sing (Apply PToPPSym0 t_aL6W :: PrimePower)
+ Crypto.Lol.Factored: sPToPP :: Sing t_a1tb3 -> Sing (Apply PToPPSym0 t_a1tb3 :: PrimePower)
- Crypto.Lol.Factored: sPpToF :: Sing t_aL6V -> Sing (Apply PpToFSym0 t_aL6V :: Factored)
+ Crypto.Lol.Factored: sPpToF :: Sing t_a1tb2 -> Sing (Apply PpToFSym0 t_a1tb2 :: Factored)
- Crypto.Lol.Factored: sUnF :: Sing t_aHsk -> Sing (Apply UnFSym0 t_aHsk :: [PrimePower])
+ Crypto.Lol.Factored: sUnF :: Sing t_a1p8A -> Sing (Apply UnFSym0 t_a1p8A :: [PrimePower])
- Crypto.Lol.Factored: sUnPP :: Sing t_aHsl -> Sing (Apply UnPPSym0 t_aHsl :: (Prime, Pos))
+ Crypto.Lol.Factored: sUnPP :: Sing t_a1p8B -> Sing (Apply UnPPSym0 t_a1p8B :: (PrimeBin, Pos))
- Crypto.Lol.Factored: unPP :: PrimePower -> (Prime, Pos)
+ Crypto.Lol.Factored: unPP :: PrimePower -> (PrimeBin, Pos)
- Crypto.Lol.Factored: valuePrime :: Prim p => Tagged p Int
+ Crypto.Lol.Factored: valuePrime :: Prime p => Tagged p Int
- Crypto.Lol.PosBin: data AddPosSym0 (l_avLt :: TyFun Pos (TyFun Pos Pos -> *))
+ Crypto.Lol.PosBin: data AddPosSym0 (l_a199Z :: TyFun Pos (TyFun Pos Pos -> *))
- Crypto.Lol.PosBin: data AddPosSym1 (l_avLw :: Pos) (l_avLv :: TyFun Pos Pos)
+ Crypto.Lol.PosBin: data AddPosSym1 (l_a19a2 :: Pos) (l_a19a1 :: TyFun Pos Pos)
- Crypto.Lol.PosBin: data D0Sym0 (l_axug :: TyFun Bin Bin)
+ Crypto.Lol.PosBin: data D0Sym0 (l_a1aWe :: TyFun Bin Bin)
- Crypto.Lol.PosBin: data D1Sym0 (l_axuj :: TyFun Bin Bin)
+ Crypto.Lol.PosBin: data D1Sym0 (l_a1aWh :: TyFun Bin Bin)
- Crypto.Lol.PosBin: data SSym0 (l_avLa :: TyFun Pos Pos)
+ Crypto.Lol.PosBin: data SSym0 (l_a199G :: TyFun Pos Pos)
- Crypto.Lol.PosBin: data SubPosSym0 (l_avLe :: TyFun Pos (TyFun Pos Pos -> *))
+ Crypto.Lol.PosBin: data SubPosSym0 (l_a199K :: TyFun Pos (TyFun Pos Pos -> *))
- Crypto.Lol.PosBin: data SubPosSym1 (l_avLh :: Pos) (l_avLg :: TyFun Pos Pos)
+ Crypto.Lol.PosBin: data SubPosSym1 (l_a199N :: Pos) (l_a199M :: TyFun Pos Pos)
- Crypto.Lol.PosBin: sAddPos :: Sing t_avOY -> Sing t_avOZ -> Sing (Apply (Apply AddPosSym0 t_avOY) t_avOZ :: Pos)
+ Crypto.Lol.PosBin: sAddPos :: Sing t_a19I1 -> Sing t_a19I2 -> Sing (Apply (Apply AddPosSym0 t_a19I1) t_a19I2 :: Pos)
- Crypto.Lol.PosBin: sSubPos :: Sing t_avOW -> Sing t_avOX -> Sing (Apply (Apply SubPosSym0 t_avOW) t_avOX :: Pos)
+ Crypto.Lol.PosBin: sSubPos :: Sing t_a19HZ -> Sing t_a19I0 -> Sing (Apply (Apply SubPosSym0 t_a19HZ) t_a19I0 :: Pos)
- Crypto.Lol.PosBin: type D0Sym1 (t_axuf :: Bin) = D0 t_axuf
+ Crypto.Lol.PosBin: type D0Sym1 (t_a1aWd :: Bin) = D0 t_a1aWd
- Crypto.Lol.PosBin: type D1Sym1 (t_axui :: Bin) = D1 t_axui
+ Crypto.Lol.PosBin: type D1Sym1 (t_a1aWg :: Bin) = D1 t_a1aWg
- Crypto.Lol.PosBin: type SSym1 (t_avL9 :: Pos) = S t_avL9
+ Crypto.Lol.PosBin: type SSym1 (t_a199F :: Pos) = S t_a199F
- Crypto.Lol.Types.FiniteField: type PrimeField fp = (Enumerable fp, Field fp, Eq fp, ZeroTestable fp, Prim (CharOf fp), IrreduciblePoly fp)
+ Crypto.Lol.Types.FiniteField: type PrimeField fp = (Enumerable fp, Field fp, Eq fp, ZeroTestable fp, Prime (CharOf fp), IrreduciblePoly fp)

Files

CHANGES.md view
@@ -1,6 +1,15 @@ Changelog for lol project ================================ +0.3.0.0+-----+ * Support for protocol-buffers+ * Support for reifying Factored types+ * Support for reals (RR) mod q+ * Replaced C backend with C++ backend+ * Renamed LatticePrelude -> Prelude+ * Added monad argument to CRTrans+ 0.2.0.0 -----  * Added benchmarks
Crypto/Lol.hs view
@@ -1,21 +1,16 @@  -- | Re-exports primary interfaces. -module Crypto.Lol -( module Crypto.Lol.Cyclotomic.Cyc-, module Crypto.Lol.Gadget-, module Crypto.Lol.LatticePrelude--, module Crypto.Lol.Types.ZqBasic-, module Crypto.Lol.Cyclotomic.Tensor.CTensor-, module Crypto.Lol.Cyclotomic.Tensor.RepaTensor-, module Crypto.Lol.Types.IrreducibleChar2) where+module Crypto.Lol+( module X+) where -import Crypto.Lol.Cyclotomic.Cyc-import Crypto.Lol.Gadget-import Crypto.Lol.LatticePrelude+import Crypto.Lol.Cyclotomic.Cyc as X+import Crypto.Lol.Gadget         as X+import Crypto.Lol.Prelude        as X -import Crypto.Lol.Types.ZqBasic-import Crypto.Lol.Cyclotomic.Tensor.CTensor-import Crypto.Lol.Cyclotomic.Tensor.RepaTensor-import Crypto.Lol.Types.IrreducibleChar2+import Crypto.Lol.Cyclotomic.Tensor.CTensor    as X+import Crypto.Lol.Cyclotomic.Tensor.RepaTensor as X+import Crypto.Lol.Types.IrreducibleChar2       as X ()+import Crypto.Lol.Types.RRq                    as X+import Crypto.Lol.Types.ZqBasic                as X
Crypto/Lol/CRTrans.hs view
@@ -1,5 +1,10 @@-{-# LANGUAGE FlexibleContexts, FlexibleInstances, RebindableSyntax,
-             ScopedTypeVariables, TypeFamilies #-}
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE PolyKinds             #-}
+{-# LANGUAGE RebindableSyntax      #-}
+{-# LANGUAGE ScopedTypeVariables   #-}
+{-# LANGUAGE TypeFamilies          #-}
 
 -- | Classes and helper methods for the Chinese remainder transform
 -- and ring extensions.
@@ -7,15 +12,12 @@ module Crypto.Lol.CRTrans
 ( CRTrans(..), CRTEmbed(..)
 , CRTInfo
-, crtInfoFact, crtInfoPPow, crtInfoPrime
-, gEmbPPow, gEmbPrime
 ) where
 
-import Crypto.Lol.LatticePrelude
+import Crypto.Lol.Prelude
+import Crypto.Lol.Reflects
 
 import Control.Arrow
-import Data.Singletons
-import Data.Singletons.Prelude
 
 -- | Information that characterizes the (invertible) Chinese remainder
 -- transformation over a ring @r@, namely:
@@ -32,17 +34,15 @@ 
 -- | The values of 'crtInfo' for different indices @m@ should be
 -- consistent, in the sense that if @omega@, @omega'@ are respectively
--- the values returned for @m@, @m'@ where @m'@ divides @m@, then it
--- should be the case that @omega^(m/m')=omega'@.
+-- the roots of unity used for @m@, @m'@ where @m@ divides @m'@, then
+-- it should be the case that @omega'^(m'/m)=omega@.
 
-class Ring r => CRTrans r where
+class (Monad mon, Ring r) => CRTrans mon r where
 
   -- | 'CRTInfo' for a given index @m@. The method itself may be
   -- slow, but the function it returns should be fast, e.g., via
-  -- internal memoization.  The default implementation returns
-  -- 'Nothing'.
-  crtInfo :: Int -> Maybe (CRTInfo r)
-  crtInfo = const Nothing
+  -- internal memoization.
+  crtInfo :: Reflects m Int => TaggedT m mon (CRTInfo r)
 
 -- | A ring with a ring embedding into some ring @CRTExt r@ that has
 -- an invertible CRT transformation for /every/ positive index @m@.
@@ -54,83 +54,68 @@   -- | Projects from @CRTExt r@ to @r@
   fromExt :: CRTExt r -> r
 
--- CRTrans instance for product rings
-instance (CRTrans a, CRTrans b) => CRTrans (a,b) where
-  crtInfo i = do
-    (apow, aiInv) <- crtInfo i
-    (bpow, biInv) <- crtInfo i
-    return (apow &&& bpow, (aiInv, biInv))
+-- | Product ring
+instance (CRTrans mon a, CRTrans mon b) => CRTrans mon (a,b) where
+  crtInfo = do
+    (fa, inva) <- crtInfo
+    (fb, invb) <- crtInfo
+    return (fa &&& fb, (inva, invb))
 
--- CRTEmbed instance for product rings
+-- | Product ring
 instance (CRTEmbed a, CRTEmbed b) => CRTEmbed (a,b) where
   type CRTExt (a,b) = (CRTExt a, CRTExt b)
   toExt = toExt *** toExt
   fromExt = fromExt *** fromExt
 
-omegaPowC :: (Transcendental a) => Int -> Int -> Complex a
-omegaPowC m i = cis (2*pi*fromIntegral i / fromIntegral m)
-
--- | 'crtInfo' wrapper for 'Fact' types.
-crtInfoFact :: (Fact m, CRTrans r) => TaggedT m Maybe (CRTInfo r)
-crtInfoFact = (tagT . crtInfo) =<< pureT valueFact
-
--- | 'crtInfo' wrapper for 'PPow' types.
-crtInfoPPow :: (PPow pp, CRTrans r) => TaggedT pp Maybe (CRTInfo r)
-crtInfoPPow = (tagT . crtInfo) =<< pureT valuePPow
-
--- | 'crtInfo' wrapper for 'Prime' types.
-crtInfoPrime :: (Prim p, CRTrans r) => TaggedT p Maybe (CRTInfo r)
-crtInfoPrime = (tagT . crtInfo) =<< pureT valuePrime
-
--- | A function that returns the 'i'th embedding of @g_{p^e} = g_p@ for
--- @i@ in @Z*_{p^e}@.
-gEmbPPow :: forall pp r . (PPow pp, CRTrans r) => TaggedT pp Maybe (Int -> r)
-gEmbPPow = tagT $ case (sing :: SPrimePower pp) of
-  (SPP (STuple2 sp _)) -> withWitnessT gEmbPrime sp
+-- | Complex numbers have 'CRTrans' for any index @m@
+instance (Monad mon, Transcendental a) => CRTrans mon (Complex a) where
+  crtInfo = crtInfoC
 
--- | A function that returns the @i@th embedding of @g_p@ for @i@ in @Z*_p@,
--- i.e., @1-omega_p^i@.
-gEmbPrime :: (Prim p, CRTrans r) => TaggedT p Maybe (Int -> r)
-gEmbPrime = do
-  (f, _) <- crtInfoPrime
-  return $ \i -> one - f i      -- not checking that i /= 0 (mod p)
+crtInfoC :: forall mon m a . (Monad mon, Reflects m Int, Transcendental a)
+            => TaggedT m mon (CRTInfo (Complex a))
+crtInfoC = let mval = proxy value (Proxy::Proxy m)
+               mhat = valueHat mval
+           in return (omegaPowC mval, recip $ fromIntegral mhat)
 
--- the complex numbers have roots of unity of any order
-instance (Transcendental a) => CRTrans (Complex a) where
-  crtInfo m = Just (omegaPowC m, recip $ fromIntegral $ valueHat m)
+omegaPowC :: (Transcendental a) => Int -> Int -> Complex a
+omegaPowC m i = cis (2*pi*fromIntegral i / fromIntegral m)
 
--- trivial CRTEmbed instance for complex numbers
+-- | Self-embed
 instance (Transcendental a) => CRTEmbed (Complex a) where
   type CRTExt (Complex a) = Complex a
   toExt = id
   fromExt = id
 
--- Default CRTrans instances for real and integer types, which do
--- not have roots of unity (except in trivial cases). These are needed
--- to use FastCyc with these integer types.
-instance CRTrans Double
-instance CRTrans Int
-instance CRTrans Int64
-instance CRTrans Integer
+-- | Returns 'Nothing'
+instance CRTrans Maybe Double where crtInfo = tagT Nothing
+-- | Returns 'Nothing'
+instance CRTrans Maybe Int where crtInfo = tagT Nothing
+-- | Returns 'Nothing'
+instance CRTrans Maybe Int64 where crtInfo = tagT Nothing
+-- | Returns 'Nothing'
+instance CRTrans Maybe Integer where crtInfo = tagT Nothing
 -- can also do for Int8, Int16, Int32 etc.
 
--- CRTEmbed instances for real and integer types, embedding into
--- Complex.  These are needed to use FastCyc with these integer types.
+-- | Embeds into complex numbers
 instance CRTEmbed Double where
   type CRTExt Double = Complex Double
   toExt = fromReal . realToField
   fromExt = realToField . real
 
+-- | Embeds into complex numbers
 instance CRTEmbed Int where
   type CRTExt Int = Complex Double
   toExt = fromIntegral
   fromExt = fst . roundComplex
 
+-- | Embeds into complex numbers
 instance CRTEmbed Int64 where
   type CRTExt Int64 = Complex Double
   toExt = fromIntegral
   fromExt = fst . roundComplex
 
+-- | Embeds into complex numbers.  (May not have sufficient
+-- precision.)
 instance CRTEmbed Integer where
   -- CJP: sufficient precision?  Not in general.
   type CRTExt Integer = Complex Double
+ Crypto/Lol/Cyclotomic/CRTSentinel.hs view
@@ -0,0 +1,77 @@+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PolyKinds             #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE TypeOperators         #-}++-- | Safely exposes a "sentinel" indicating usage of either CRT basis+-- over a base ring, or over its extension ring.  Exactly one of+-- 'CSentinel' or 'ESentinel' has an externally exposed value.++module Crypto.Lol.Cyclotomic.CRTSentinel+( CSentinel, ESentinel+, crtSentinel, crtCSentinel, crtESentinel+, scalarCRTCS, crtCS, crtInvCS, mulGCRTCS, divGCRTCS+, embedCRTCS, twaceCRTCS+) where++import Data.Functor.Trans.Tagged+import Data.Maybe+import Data.Proxy++import Crypto.Lol.CRTrans+import Crypto.Lol.Cyclotomic.Tensor+import Crypto.Lol.Factored++data CSentinel t m r = CSentinel+data ESentinel t m r = ESentinel++crtSentinel :: (Tensor t, Fact m, CRTrans Maybe r, TElt t r)+               => Either (ESentinel t m r) (CSentinel t m r)+crtSentinel = fromMaybe (Left ESentinel) (Right <$> crtCSentinel)+{-# INLINABLE crtSentinel #-}++crtCSentinel :: forall t m r .+                (Tensor t, Fact m, CRTrans Maybe r, TElt t r)+                => Maybe (CSentinel t m r)+crtCSentinel = proxyT hasCRTFuncs (Proxy::Proxy (t m r)) *>+               pure CSentinel+{-# INLINABLE crtCSentinel #-}++crtESentinel :: (Tensor t, Fact m, CRTrans Maybe r, TElt t r)+                => Maybe (ESentinel t m r)+crtESentinel = case crtSentinel of+  Left  s -> Just s+  Right _ -> Nothing+{-# INLINABLE crtESentinel #-}++scalarCRTCS :: (Tensor t, Fact m, CRTrans Maybe r, TElt t r)+              => CSentinel t m r -> r -> t m r+scalarCRTCS _ = fromJust scalarCRT+{-# INLINABLE scalarCRTCS #-}++crtCS, crtInvCS, mulGCRTCS, divGCRTCS ::+  (Tensor t, Fact m, CRTrans Maybe r, TElt t r)+  => CSentinel t m r -> t m r -> t m r++crtCS     _ = fromJust crt+crtInvCS  _ = fromJust crtInv+mulGCRTCS _ = fromJust mulGCRT+divGCRTCS _ = fromJust divGCRT++{-# INLINABLE crtCS #-}+{-# INLINABLE crtInvCS #-}+{-# INLINABLE mulGCRTCS #-}+{-# INLINABLE divGCRTCS #-}++embedCRTCS :: (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+embedCRTCS _ _ = fromJust embedCRT+{-# INLINABLE embedCRTCS #-}++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 #-}+
Crypto/Lol/Cyclotomic/Cyc.hs view
@@ -1,7 +1,16 @@-{-# LANGUAGE ConstraintKinds, DataKinds, FlexibleContexts,-             FlexibleInstances, GADTs, MultiParamTypeClasses,-             NoImplicitPrelude, PolyKinds, RankNTypes, ScopedTypeVariables,-             TypeFamilies, TypeOperators, UndecidableInstances #-}+{-# LANGUAGE ConstraintKinds       #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE GADTs                 #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoImplicitPrelude     #-}+{-# LANGUAGE PolyKinds             #-}+{-# LANGUAGE RankNTypes            #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE TypeOperators         #-}+{-# LANGUAGE UndecidableInstances  #-}  -- | An implementation of cyclotomic rings that hides the -- internal representations of ring elements (e.g., the choice of@@ -24,8 +33,9 @@ -- * Data type and constraints   Cyc, CElt, U.NFElt -- * Constructors/deconstructors-, cycPow, cycDec, cycCRT, scalarCyc-, uncycPow, uncycDec, uncycCRT, unzipCyc, unzipCElt+, scalarCyc+, cycPow, cycDec, cycCRT, cycCRTC, cycCRTE, cycPC, cycPE+, uncycPow, uncycDec, uncycCRT, unzipCyc -- * Core cyclotomic operations , mulG, divG, gSqNorm, liftCyc, liftPow, liftDec -- * Representation advice@@ -33,7 +43,7 @@ -- * Error sampling , tGaussian, errorRounded, errorCoset -- * Sub/extension rings-, embed, twace, coeffsCyc, powBasis, crtSet+, embed, twace, coeffsCyc, coeffsPow, coeffsDec, powBasis, crtSet -- * Rescaling cyclotomic elements , R.RescaleCyc(..), R.Basis(..) ) where@@ -45,27 +55,29 @@  import Crypto.Lol.Cyclotomic.UCyc hiding (coeffsDec, coeffsPow, crtSet,                                    divG, errorCoset, errorRounded, gSqNorm,-                                   mulG, powBasis, tGaussian, unzipCyc)+                                   mulG, powBasis, tGaussian)  import           Crypto.Lol.CRTrans import qualified Crypto.Lol.Cyclotomic.RescaleCyc as R-import           Crypto.Lol.Cyclotomic.Tensor     (CRTElt, TElt, Tensor)+import           Crypto.Lol.Cyclotomic.Tensor     (TElt, Tensor) import qualified Crypto.Lol.Cyclotomic.UCyc       as U import           Crypto.Lol.Gadget-import           Crypto.Lol.LatticePrelude        as LP+import           Crypto.Lol.Prelude               as LP import           Crypto.Lol.Types.FiniteField+import           Crypto.Lol.Types.Proto import           Crypto.Lol.Types.ZPP  import Control.Applicative    hiding ((*>)) import Control.Arrow import Control.DeepSeq-import Control.Monad.Identity   -- needed for coerce+import Control.Monad.Identity -- GHC warning is wrong: https://ghc.haskell.org/trac/ghc/ticket/12067 import Control.Monad.Random import Data.Coerce import Data.Traversable  import Test.QuickCheck + -- | Represents a cyclotomic ring such as @Z[zeta]@, -- @Zq[zeta]@, and @Q(zeta)@ in an explicit representation: @t@ is the -- 'Tensor' type for storing coefficient tensors; @m@ is the@@ -74,15 +86,15 @@ data Cyc t m r where   Pow :: !(UCyc t m P r) -> Cyc t m r   Dec :: !(UCyc t m D r) -> Cyc t m r-  CRT :: !(UCyc t m C r) -> Cyc t m r+  CRT :: !(UCycEC t m r) -> Cyc t m r   -- super-optimized storage of scalars   Scalar :: !r -> Cyc t m r   -- optimized storage of subring elements   Sub :: (l `Divides` m) => !(Cyc t l r) -> Cyc t m r   -- CJP: someday try to merge the above two --- | Constraints needed for many operations involving 'Cyc' data.-type CElt t r = UCElt t r+-- | Constraints needed for most operations involving 'Cyc' data.+type CElt t r = (UCRTElt t r, ZeroTestable r)  ---------- Constructors / deconstructors ---------- @@ -96,11 +108,31 @@ cycDec = Dec {-# INLINABLE cycDec #-} --- | Wrap a 'UCyc' as a 'Cyc'.-cycCRT :: UCyc t m C r -> Cyc t m r+-- | Wrap a 'UCycEC' as a 'Cyc'.+cycCRT :: UCycEC t m r -> Cyc t m r cycCRT = CRT {-# INLINABLE cycCRT #-} +-- | Wrap a 'UCyc' as a 'Cyc'.+cycCRTC :: UCyc t m C r -> Cyc t m r+cycCRTC = CRT . Right+{-# INLINABLE cycCRTC #-}++-- | Wrap a 'UCyc' as a 'Cyc'.+cycCRTE :: UCyc t m E r -> Cyc t m r+cycCRTE = CRT . Left+{-# INLINABLE cycCRTE #-}++-- | Convenience wrapper.+cycPC :: Either (UCyc t m P r) (UCyc t m C r) -> Cyc t m r+cycPC = either Pow (CRT . Right)+{-# INLINABLE cycPC #-}++-- | Convenience wrapper.+cycPE :: Either (UCyc t m P r) (UCyc t m E r) -> Cyc t m r+cycPE = either Pow (CRT . Left)+{-# INLINABLE cycPE #-}+ -- | Embed a scalar from the base ring as a cyclotomic element. scalarCyc :: r -> Cyc t m r scalarCyc = Scalar@@ -116,8 +148,8 @@ {-# INLINABLE uncycDec #-} uncycDec c = let (Dec u) = toDec' c in u --- | Unwrap a 'Cyc' as a 'UCyc' in CRT-basis representation.-uncycCRT :: (Fact m, CElt t r) => Cyc t m r -> UCyc t m C r+-- | Unwrap a 'Cyc' as a 'UCyc' in a CRT-basis representation.+uncycCRT :: (Fact m, CElt t r) => Cyc t m r -> UCycEC t m r {-# INLINABLE uncycCRT #-} uncycCRT c = let (CRT u) = toCRT' c in u @@ -126,7 +158,8 @@ instance (Fact m, CElt t r) => ZeroTestable.C (Cyc t m r) where   isZero (Pow u) = isZero u   isZero (Dec u) = isZero u-  isZero (CRT u) = isZero u+  isZero (CRT (Right u)) = isZero u+  isZero c@(CRT _) = isZero $ toPow' c   isZero (Scalar c) = isZero c   isZero (Sub c) = isZero c   {-# INLINABLE isZero #-}@@ -136,19 +169,18 @@   (Scalar c1) == (Scalar c2) = c1 == c2   (Pow u1) == (Pow u2) = u1 == u2   (Dec u1) == (Dec u2) = u1 == u2-  (CRT u1) == (CRT u2) = u1 == u2+  (CRT (Right u1)) == (CRT (Right u2)) = u1 == u2   -- compare Subs in compositum+  -- EAC: would like to convert c2 to basis of c1 before embedding   (Sub (c1 :: Cyc t l1 r)) == (Sub (c2 :: Cyc t l2 r)) =     (embed' c1 :: Cyc t (FLCM l1 l2) r) == embed' c2     \\ lcmDivides (Proxy::Proxy l1) (Proxy::Proxy l2)    -- some other relatively efficient comparisons   (Scalar c1) == (Pow u2) = scalarPow c1 == u2-  -- (Scalar c1) == (Dec u2) = scalarDec c1 == u2   (Pow u1) == (Scalar c2) = u1 == scalarPow c2-  -- (Dec u1) == (Scalar c2) = u1 == scalarDec c2 -  -- default: compare in powerful basis+  -- otherwise: compare in powerful basis   c1 == c2 = toPow' c1 == toPow' c2    {-# INLINABLE (==) #-}@@ -168,6 +200,7 @@   (Dec u1) + (Dec u2) = Dec $ u1 + u2   (CRT u1) + (CRT u2) = CRT $ u1 + u2   -- Sub plus Sub: work in compositum+  -- EAC: would like to convert c2 to basis of c1 before embedding   (Sub (c1 :: Cyc t m1 r)) + (Sub (c2 :: Cyc t m2 r)) =     (Sub $ (embed' c1 :: Cyc t (FLCM m1 m2) r) + embed' c2)     \\ lcm2Divides (Proxy::Proxy m1) (Proxy::Proxy m2) (Proxy::Proxy m)@@ -185,6 +218,7 @@   (Sub c1) + (Scalar c2) = Sub $ c1 + Scalar c2    -- SUB PLUS NON-SUB, NON-SCALAR: work in full ring+  -- EAC: would like to convert sub to basis of other before embedding   (Sub c1) + c2 = embed' c1 + c2   c1 + (Sub c2) = c1 + embed' c2 @@ -218,8 +252,8 @@   v1@(Scalar c1) * _ | isZero c1 = v1   _ * v2@(Scalar c2) | isZero c2 = v2 -  -- both CRT-  (CRT u1) * (CRT u2) = CRT $ u1*u2+  -- both CRT: if over C, then convert result to pow for precision reasons+  (CRT u1) * (CRT u2) = either (Pow . toPow) (CRT . Right) $ u1*u2    -- at least one Scalar   (Scalar c1) * (Scalar c2) = Scalar $ c1*c2@@ -242,6 +276,9 @@   -- ELSE: work in appropriate CRT rep   c1 * c2 = toCRT' c1 * toCRT' c2 +-- | @Rp@ is an @F_{p^d}@-module when @d@ divides @phi(m)@, by+-- applying @d@-dimensional @Fp@-linear transform on @d@-dim chunks of+-- powerful basis coeffs instance (GFCtx fp d, Fact m, CElt t fp) => Module.C (GF fp d) (Cyc t m fp) where   -- CJP: optimize for Scalar if we can: r *> (Scalar c) is the tensor   -- that has the coeffs of (r*c), followed by zeros.  (This assumes@@ -277,27 +314,25 @@ {-# INLINABLE mulG #-} mulG (Pow u) = Pow $ U.mulG u mulG (Dec u) = Dec $ U.mulG u-mulG (CRT u) = CRT $ U.mulG u-mulG (Scalar r) = CRT $ U.mulG $ scalarCRT r+mulG (CRT u) = CRT $ either (Left . U.mulG) (Right . U.mulG) u+mulG c@(Scalar _) = mulG $ toCRT' c mulG (Sub c) = mulG $ embed' c   -- must go to full ring  -- | Divide by @g@, returning 'Nothing' if not evenly divisible. -- WARNING: this implementation is not a constant-time algorithm, so -- information about the argument may be leaked through a timing -- channel.-divG :: (Fact m, CElt t r) => Cyc t m r -> Maybe (Cyc t m r)+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 <$> U.divG u-divG (Scalar r) = CRT <$> U.divG (scalarCRT r)+divG (CRT u) = CRT <$> either (fmap Left . U.divG) (fmap Right . U.divG) u+divG c@(Scalar _) = divG $ toCRT' c divG (Sub c) = divG $ embed' c  -- must go to full ring  -- | Sample from the "tweaked" Gaussian error distribution @t*D@ in--- the decoding basis, where @D@ has scaled variance @v@.  (Note: This--- implementation uses Double precision to generate the Gaussian--- sample, which may not be sufficient for rigorous proof-based--- security.)+-- the decoding basis, where @D@ has scaled variance @v@. tGaussian :: (Fact m, OrdFloat q, Random q, Tensor t, TElt t q,               ToRational v, MonadRandom rnd)              => v -> rnd (Cyc t m q)@@ -309,16 +344,15 @@ -- @\hat{m}^{ -1 } \cdot || \sigma(g_m \cdot e) ||^2@ . gSqNorm :: forall t m r . (Fact m, CElt t r) => Cyc t m r -> r {-# INLINABLE gSqNorm #-}-gSqNorm (Pow u) = U.gSqNorm $ toDec u gSqNorm (Dec u) = U.gSqNorm u-gSqNorm (CRT u) = U.gSqNorm $ toDec u--- CJP: this is suboptimal (gSqNorm of scalar 1 is known)--- also workaround scalarDec-gSqNorm (Scalar u) = U.gSqNorm (toDec $ scalarPow u :: UCyc t m D r)-gSqNorm (Sub c) = U.gSqNorm (U.embedDec $ uncycDec c :: UCyc t m D r)+gSqNorm c = gSqNorm $ toDec' c  -- | Generate an LWE error term with given scaled variance, -- deterministically rounded with respect to the decoding basis.+-- (Note: This+-- implementation uses Double precision to generate the Gaussian+-- sample, which may not be sufficient for rigorous proof-based+-- security.) errorRounded :: (ToInteger z, Tensor t, Fact m, TElt t z,                  ToRational v, MonadRandom rnd) => v -> rnd (Cyc t m z) {-# INLINABLE errorRounded #-}@@ -326,7 +360,10 @@  -- | Generate an LWE error term with given scaled variance @* p^2@ over -- the given coset, deterministically rounded with respect to the--- decoding basis.+-- decoding basis. (Note: This+-- implementation uses Double precision to generate the Gaussian+-- sample, which may not be sufficient for rigorous proof-based+-- security.) errorCoset ::   (Mod zp, z ~ ModRep zp, Lift zp z, Fact m,    CElt t zp, TElt t z, ToRational v, MonadRandom rnd)@@ -349,7 +386,7 @@ {-# INLINE embed' #-} embed' (Pow u) = Pow $ embedPow u embed' (Dec u) = Dec $ embedDec u-embed' (CRT u) = either Pow CRT $ embedCRT u+embed' (CRT u) = either (cycPE . embedCRTE) (cycPC . embedCRTC) u embed' (Scalar c) = Scalar c embed' (Sub (c :: Cyc t k r)) = embed' c   \\ transDivides (Proxy::Proxy k) (Proxy::Proxy l) (Proxy::Proxy m)@@ -362,19 +399,27 @@ {-# INLINABLE twace #-} twace (Pow u) = Pow $ U.twacePow u twace (Dec u) = Dec $ U.twaceDec u-twace (CRT u) = either Pow CRT $ twaceCRT u+twace (CRT u) = either (cycPE . twaceCRTE) (cycPC . twaceCRTC) u twace (Scalar u) = Scalar u twace (Sub (c :: Cyc t l r)) = Sub (twace c :: Cyc t (FGCD l m) r)                                \\ gcdDivides (Proxy::Proxy l) (Proxy::Proxy m)  -- | Return the given element's coefficient vector with respect to -- the (relative) powerful/decoding basis of the cyclotomic--- extension @O_m' / O_m@.+-- extension @O_m' / O_m@.  See also 'coeffsPow', 'coeffsDec'. coeffsCyc :: (m `Divides` m', CElt t r) => R.Basis -> Cyc t m' r -> [Cyc t m r] {-# INLINABLE coeffsCyc #-} coeffsCyc R.Pow c' = Pow <$> U.coeffsPow (uncycPow c') coeffsCyc R.Dec c' = Dec <$> U.coeffsDec (uncycDec c') +coeffsPow, coeffsDec :: (m `Divides` m', CElt t r) => Cyc t m' r -> [Cyc t m r]+{-# INLINABLE coeffsPow #-}+{-# INLINABLE coeffsDec #-}+-- | Specialized version of @coeffsCyc@ for powerful basis.+coeffsPow = coeffsCyc R.Pow+-- | Specialized version of @coeffsCyc@ for decoding basis.+coeffsDec = coeffsCyc R.Dec+ -- | The relative powerful basis of @O_m' / O_m@. powBasis :: (m `Divides` m', CElt t r) => Tagged m [Cyc t m' r] powBasis = (Pow <$>) <$> U.powBasis@@ -395,7 +440,7 @@   {-# INLINABLE reduce #-}   reduce (Pow u) = Pow $ reduce u   reduce (Dec u) = Dec $ reduce u-  reduce (CRT u) = Pow $ reduce $ toPow u+  reduce (CRT u) = Pow $ reduce $ either toPow toPow u   reduce (Scalar c) = Scalar $ reduce c   reduce (Sub (c :: Cyc t l a)) = Sub (reduce c :: Cyc t l b) @@ -417,40 +462,27 @@ -- | Lift using the powerful basis. liftPow (Pow u) = Pow $ lift u liftPow (Dec u) = Pow $ lift $ toPow u-liftPow (CRT u) = Pow $ lift $ toPow u+liftPow (CRT u) = Pow $ lift $ either toPow toPow u -- optimized for subrings; these are correct for powerful basis but -- not for decoding liftPow (Scalar c) = Scalar $ lift c liftPow (Sub c) = Sub $ liftPow c  -- | Lift using the decoding basis.-liftDec (Pow u) = Dec $ lift $ toDec u-liftDec (Dec u) = Dec $ lift u-liftDec (CRT u) = Dec $ lift $ toDec u-liftDec (Scalar c) = Dec $ lift $ toDec $ scalarPow c -- workaround scalarDec-liftDec (Sub c) = liftDec $ embed' c+liftDec c = Dec $ lift $ uncycDec c --- | Unzip for unrestricted types.-unzipCyc :: (Tensor t, Fact m) => Cyc t m (a,b) -> (Cyc t m a, Cyc t m b)+-- | Unzip for a pair base ring.+unzipCyc :: (Tensor t, Fact m, CElt t (a,b), CElt t a, CElt t b)+            => Cyc t m (a,b) -> (Cyc t m a, Cyc t m b) {-# INLINABLE unzipCyc #-}-unzipCyc (Pow u) = Pow *** Pow $ U.unzipCyc u-unzipCyc (Dec u) = Dec *** Dec $ U.unzipCyc u-unzipCyc (CRT u) = CRT *** CRT $ U.unzipCyc u+unzipCyc (Pow u) = Pow *** Pow $ U.unzipPow u+unzipCyc (Dec u) = Dec *** Dec $ U.unzipDec u+unzipCyc (CRT u) = either ((cycPE *** cycPE) . unzipCRTE)+                   ((cycPC *** cycPC) . unzipCRTC) u unzipCyc (Scalar c) = Scalar *** Scalar $ c unzipCyc (Sub c) = Sub *** Sub $ unzipCyc c --- | Type-restricted (and potentially more efficient) unzip.-unzipCElt :: (Tensor t, Fact m, CElt t (a,b), CElt t a, CElt t b)-             => Cyc t m (a,b) -> (Cyc t m a, Cyc t m b)-{-# INLINABLE unzipCElt #-}-unzipCElt (Pow u) = Pow *** Pow $ U.unzipUCElt u-unzipCElt (Dec u) = Dec *** Dec $ U.unzipUCElt u-unzipCElt (CRT u) = CRT *** CRT $ U.unzipUCElt u-unzipCElt (Scalar c) = Scalar *** Scalar $ c-unzipCElt (Sub c) = Sub *** Sub $ unzipCElt c---- generic RescaleCyc instance-+-- | generic instance instance {-# OVERLAPS #-} (Rescale a b, CElt t a, TElt t b)     => R.RescaleCyc (Cyc t) a b where @@ -464,7 +496,8 @@   rescaleCyc R.Dec c = Dec $ fmapDec rescale $ uncycDec c   {-# INLINABLE rescaleCyc #-} --- specialized instance for product rings: ~2x faster algorithm+-- | specialized instance for product rings of @Zq@s: ~2x faster+-- algorithm instance (Mod a, Field b, Lift a (ModRep a), Reduce (LiftOf a) b,          CElt t (a,b), CElt t a, CElt t b, CElt t (LiftOf a))          => R.RescaleCyc (Cyc t) (a,b) b where@@ -475,20 +508,19 @@   rescaleCyc R.Pow (Sub c) = Sub $ R.rescalePow c    rescaleCyc bas c = let aval = proxy modulus (Proxy::Proxy a)-                         (a,b) = unzipCElt c+                         (a,b) = unzipCyc c                          z = liftCyc bas a                      in Scalar (recip (reduce aval)) * (b - reduce z)   {-# INLINABLE rescaleCyc #-} -+-- | promoted from base ring instance (Gadget gad zq, Fact m, CElt t zq) => Gadget gad (Cyc t m zq) where   gadget = (scalarCyc <$>) <$> gadget-  -- specialization fo 'encode', done efficiently-  encode s = ((* adviseCRT s) <$>) <$> gadget   {-# INLINABLE gadget #-}-  {-# INLINABLE encode #-} --- promote Decompose, using the powerful basis+  -- CJP: default 'encode' works because mul-by-Scalar is fast++-- | promoted from base ring, using the powerful basis for best geometry instance (Decompose gad zq, Fact m, CElt t zq, CElt t (DecompOf zq))          => Decompose gad (Cyc t m zq) where @@ -511,12 +543,12 @@ fromZL :: TaggedT s ZipList a -> Tagged s [a] fromZL = coerce --- promote Correct, using the decoding basis+-- | promoted from base ring, using the decoding basis for best geometry instance (Correct gad zq, Fact m, CElt t zq) => Correct gad (Cyc t m zq) where   -- sequence: Monad [] and Traversable (UCyc t m D)   -- sequenceA: Applicative (UCyc t m D) and Traversable (TaggedT gad [])   correct bs = Dec *** (Dec <$>) $-               second sequence $ U.unzipCyc $ (correct . pasteT) <$>+               second sequence $ fmap fst &&& fmap snd $ (correct . pasteT) <$>                sequenceA (uncycDec <$> peelT bs)   {-# INLINABLE correct #-} @@ -530,28 +562,28 @@ -- | Force to powerful-basis representation (for internal use only). toPow' c@(Pow _) = c toPow' (Dec u) = Pow $ toPow u-toPow' (CRT u) = Pow $ toPow u+toPow' (CRT u) = Pow $ either toPow toPow u toPow' (Scalar c) = Pow $ scalarPow c toPow' (Sub c) = toPow' $ embed' c  -- | Force to decoding-basis representation (for internal use only). toDec' (Pow u) = Dec $ toDec u toDec' c@(Dec _) = c-toDec' (CRT u) = Dec $ toDec u-toDec' (Scalar c) = Dec $ toDec $ scalarPow c -- workaround scalarDec+toDec' (CRT u) = Dec $ either toDec toDec u+toDec' (Scalar c) = Dec $ toDec $ scalarPow c toDec' (Sub c) = toDec' $ embed' c --- | Force to CRT representation (for internal use only).+-- | Force to a CRT representation (for internal use only). toCRT' (Pow u) = CRT $ toCRT u toCRT' (Dec u) = CRT $ toCRT u toCRT' c@(CRT _) = c toCRT' (Scalar c) = CRT $ scalarCRT c--- CJP: below is the fastest algorithm for when both source and target--- have the same CRTr/CRTe choice.  It is not the fastest when the--- choices are different (it will do an unnecessary CRT if input is--- non-CRT), but this is an unusual case.  Note: both toCRT' are--- necessary in generaly, because embed' may not preserve CRT--- representation!+-- CJP: the following is the fastest algorithm for when both source+-- and target have the same CRTr/CRTe choice.  It is not the fastest+-- when the choices are different (it will do an unnecessary CRT if+-- input is non-CRT), but this is an unusual case.  Note: both calls+-- to toCRT' are necessary in general, because embed' may not preserve+-- CRT representation! toCRT' (Sub c) = toCRT' $ embed' $ toCRT' c  ---------- Utility instances ----------@@ -564,9 +596,9 @@   rnf (Scalar u) = rnf u   rnf (Sub c) = rnf c -instance (Random r, Tensor t, Fact m, CRTElt t r) => Random (Cyc t m r) where+instance (Random r, Tensor t, Fact m, UCRTElt t r) => Random (Cyc t m r) where   random g = let (u,g') = random g-             in (either Pow CRT u, g')+             in (either Pow (CRT . Right) u, g')   {-# INLINABLE random #-}    randomR _ = error "randomR non-sensical for Cyc"@@ -575,9 +607,9 @@   arbitrary = Pow <$> arbitrary   shrink = shrinkNothing -instance (Show r, Show (CRTExt r), Tensor t, Fact m, TElt t r, TElt t (CRTExt r)) => Show (Cyc t m r) where-  show (Scalar c) = "Cyc Scalar: " ++ show c-  show (Pow u) = "Cyc: " ++ show u-  show (Dec u) = "Cyc: " ++ show u-  show (CRT u) = "Cyc: " ++ show u-  show (Sub c) = "Cyc Sub: " ++ show c+instance (Fact m, CElt t r, Protoable (UCyc t m D r))+         => Protoable (Cyc t m r) where+  type ProtoType (Cyc t m r) = ProtoType (UCyc t m D r)+  toProto (Dec uc) = toProto uc+  toProto x = toProto $ toDec' x+  fromProto x = Dec <$> fromProto x
Crypto/Lol/Cyclotomic/Linear.hs view
@@ -1,8 +1,16 @@-{-# LANGUAGE ConstraintKinds, DataKinds, FlexibleContexts,-             GeneralizedNewtypeDeriving, KindSignatures,-             MultiParamTypeClasses, NoImplicitPrelude, RoleAnnotations,-             ScopedTypeVariables, StandaloneDeriving, TypeFamilies,-             TypeOperators, UndecidableInstances #-}+{-# LANGUAGE ConstraintKinds            #-}+{-# LANGUAGE DataKinds                  #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE KindSignatures             #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE NoImplicitPrelude          #-}+{-# LANGUAGE RoleAnnotations            #-}+{-# LANGUAGE ScopedTypeVariables        #-}+{-# LANGUAGE StandaloneDeriving         #-}+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE TypeOperators              #-}+{-# LANGUAGE UndecidableInstances       #-}  -- | Functions from one cyclotomic ring to another that are linear -- over a common subring.@@ -13,7 +21,7 @@ ) where  import Crypto.Lol.Cyclotomic.Cyc-import Crypto.Lol.LatticePrelude+import Crypto.Lol.Prelude  import Algebra.Additive as Additive (C) @@ -66,6 +74,7 @@  type instance LiftOf (Linear t zp e r s) = Linear t (LiftOf zp) e r s +-- | lifts with respect to powerful basis, for best geometry instance (CElt t zp, CElt t z, z ~ LiftOf zp, Lift zp z, Fact s)          => Lift' (Linear t zp e r s) where   lift (RD ys) = RD $ liftCyc Pow <$> ys
Crypto/Lol/Cyclotomic/RescaleCyc.hs view
@@ -1,15 +1,17 @@ {-# LANGUAGE MultiParamTypeClasses #-} +-- | A class and helper functions for rescaling cycltomic ring elements.+ module Crypto.Lol.Cyclotomic.RescaleCyc where  import Crypto.Lol.Factored +-- | Represents the basis used to rescale a cyclotomic ring element. data Basis = Pow | Dec  -- | Represents cyclotomic rings that are rescalable over their base -- rings.  (This is a class because it allows for more efficient -- specialized implementations.)- class RescaleCyc c a b where   -- | Rescale in the given basis.   rescaleCyc :: Fact m => Basis -> c m a -> c m b
Crypto/Lol/Cyclotomic/Tensor.hs view
@@ -1,18 +1,27 @@-{-# LANGUAGE ConstraintKinds, DataKinds, FlexibleContexts,-             NoImplicitPrelude, PolyKinds, RankNTypes, ScopedTypeVariables, -             TupleSections, TypeFamilies, TypeOperators, -             UndecidableInstances #-}+{-# LANGUAGE ConstraintKinds       #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoImplicitPrelude     #-}+{-# LANGUAGE PolyKinds             #-}+{-# LANGUAGE RankNTypes            #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TupleSections         #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE TypeOperators         #-}+{-# LANGUAGE UndecidableInstances  #-}  -- | Interface for cyclotomic tensors, and helper functions for tensor -- indexing.  module Crypto.Lol.Cyclotomic.Tensor-( Tensor(..), CRTElt+( Tensor(..) -- * Top-level CRT functions , hasCRTFuncs , scalarCRT, mulGCRT, divGCRT, crt, crtInv, twaceCRT, embedCRT+-- * Special vectors/matrices+, Matrix, indexM, gCRTM, gInvCRTM, twCRTs -- * Tensor indexing-, Matrix, indexM, twCRTs , zmsToIndexFact , indexInfo , extIndicesPowDec, extIndicesCRT, extIndicesCoeffs@@ -22,7 +31,7 @@ where  import Crypto.Lol.CRTrans-import Crypto.Lol.LatticePrelude as LP hiding (lift, (*>))+import Crypto.Lol.Prelude           as LP hiding (lift, (*>)) import Crypto.Lol.Types.FiniteField  import           Control.Applicative@@ -31,12 +40,9 @@ import           Data.Constraint import           Data.Singletons.Prelude hiding ((:-)) import           Data.Traversable-import           Data.Tuple           (swap)-import qualified Data.Vector          as V-import qualified Data.Vector.Unboxed  as U---- | Synonym for constraints required for CRT-related functions.-type CRTElt t r = (ZeroTestable r, IntegralDomain r, CRTrans r, TElt t r)+import           Data.Tuple              (swap)+import qualified Data.Vector             as V+import qualified Data.Vector.Unboxed     as U  -- | 'Tensor' encapsulates all the core linear transformations needed -- for cyclotomic ring arithmetic.@@ -58,8 +64,7 @@ -- inputs for each method is determined by the linear transform it -- implements. -class (TElt t Double, TElt t (Complex Double))-      => Tensor (t :: Factored -> * -> *) where+class (TElt t Double, TElt t (Complex Double)) => Tensor t where    -- | Constraints needed by @t@ to hold type @r@.   type TElt t r :: Constraint@@ -67,7 +72,7 @@   -- | Properties that hold for any index. Use with '\\'.   entailIndexT :: Tagged (t m r)                   (Fact m :- (Applicative (t m), Traversable (t m)))-  +   -- | Properties that hold for any (legal) fully-applied tensor. Use   -- with '\\'.   entailEqT :: Tagged (t m r)@@ -79,19 +84,13 @@   entailRandomT :: Tagged (t m r)                    ((Random r, Fact m, TElt t r) :- Random (t m r))   entailShowT :: Tagged (t m r)-                 ((Show r, Fact m, TElt t r) :- (Show (t m r)))+                 ((Show r, Fact m, TElt t r) :- Show (t m r))   entailModuleT :: Tagged (GF fp d, t m fp)                    ((GFCtx fp d, Fact m, TElt t fp) :- Module (GF fp d) (t m fp))    -- | Convert a scalar to a tensor in the powerful basis.   scalarPow :: (Additive r, Fact m, TElt t r) => r -> t m r -  {- CJP: suppressed to do annoyingly complicated algorithm--  -- | Convert a scalar to a tensor in the decoding basis.-  scalarDec :: (Additive r, Fact m, TElt t r) => r -> t m r-  -}-   -- | 'l' converts from decoding-basis representation to   -- powerful-basis representation; 'lInv' is its inverse.   l, lInv :: (Additive r, Fact m, TElt t r) => t m r -> t m r@@ -110,12 +109,12 @@   -- use this method directly, but instead call the corresponding   -- top-level functions: the elements of the tuple correpond to the   -- functions 'scalarCRT', 'mulGCRT', 'divGCRT', 'crt', 'crtInv'.-  crtFuncs :: (Fact m, CRTElt t r) =>-              Maybe (    r -> t m r, -- scalarCRT-                     t m r -> t m r, -- mulGCRT-                     t m r -> t m r, -- divGCRT-                     t m r -> t m r, -- crt-                     t m r -> t m r) -- crtInv+  crtFuncs :: (CRTrans mon r, Fact m, TElt t r) =>+              mon (    r -> t m r, -- scalarCRT+                   t m r -> t m r, -- mulGCRT+                   t m r -> t m r, -- divGCRT+                   t m r -> t m r, -- crt+                   t m r -> t m r) -- crtInv    -- | Sample from the "tweaked" Gaussian error distribution @t*D@   -- in the decoding basis, where @D@ has scaled variance @v@.@@ -143,9 +142,9 @@   -- method directly, but instead call the corresponding top-level   -- functions: the elements of the tuple correpond to the functions   -- 'twaceCRT', 'embedCRT'.-  crtExtFuncs :: (m `Divides` m', CRTElt t r) =>-                 Maybe (t m' r -> t m  r, -- twaceCRT-                        t m  r -> t m' r) -- embedCRT+  crtExtFuncs :: (CRTrans mon r, m `Divides` m', TElt t r) =>+                 mon (t m' r -> t m  r, -- twaceCRT+                      t m  r -> t m' r) -- embedCRT    -- | Map a tensor in the powerful\/decoding\/CRT basis, representing   -- an @O_m'@ element, to a vector of tensors representing @O_m@@@ -161,26 +160,30 @@                 TElt t fp)                => Tagged m [t m' fp] -  -- | Potentially optimized version of 'fmap' when the input and-  -- output element types satisfy 'TElt'.+  -- | 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'.+  -- | Potentially optimized zipWith for types that satisfy 'TElt'.   zipWithT :: (Fact m, TElt t a, TElt t b, TElt t c)               => (a -> b -> c) -> t m a -> t m b -> t m c -  -- | Unzip for types that satisfy 'TElt'.-  unzipTElt :: (Fact m, TElt t (a,b), TElt t a, TElt t b) -               => t m (a,b) -> (t m a, t m b)+  -- | Potentially optimized unzip for types that satisfy 'TElt'.+  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.-  unzipT :: (Fact m) => t m (a,b) -> (t m a, t m b)+  unzipTUnrestricted :: (Fact m) => t m (a,b) -> (t m a, t m b)+  -}  -- | Convenience value indicating whether 'crtFuncs' exists.-hasCRTFuncs :: forall t m r . (Tensor t, Fact m, CRTElt t r)-               => TaggedT (t m r) Maybe ()+hasCRTFuncs :: forall t m mon r . (CRTrans mon r, Tensor t, Fact m, TElt t r)+               => TaggedT (t m r) mon () {-# INLINABLE hasCRTFuncs #-} hasCRTFuncs = tagT $ do   (_ :: r -> t m r,_,_,_,_) <- crtFuncs@@ -188,13 +191,12 @@  -- | Yield a tensor for a scalar in the CRT basis.  (This function is -- simply an appropriate entry from 'crtFuncs'.)-scalarCRT :: (Tensor t, Fact m, CRTElt t r) => Maybe (r -> t m r)+scalarCRT :: (CRTrans mon r, Tensor t, Fact m, TElt t r) => mon (r -> t m r) {-# INLINABLE scalarCRT #-} scalarCRT = (\(f,_,_,_,_) -> f) <$> crtFuncs - mulGCRT, divGCRT, crt, crtInv ::-  (Tensor t, Fact m, CRTElt t r) => Maybe (t m r -> t m r)+  (CRTrans mon r, Tensor t, Fact m, TElt t r) => mon (t m r -> t m r) {-# INLINABLE mulGCRT #-} {-# INLINABLE divGCRT #-} {-# INLINABLE crt #-}@@ -217,8 +219,8 @@ -- For cyclotomic indices m | m', -- @Tw(x) = (mhat\/m\'hat) * Tr(g\'\/g * x)@. -- (This function is simply an appropriate entry from 'crtExtFuncs'.)-twaceCRT :: forall t r m m' . (Tensor t, m `Divides` m', CRTElt t r)-            => Maybe (t m' r -> t m r)+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) twaceCRT = proxyT hasCRTFuncs (Proxy::Proxy (t m' r)) *>            proxyT hasCRTFuncs (Proxy::Proxy (t m  r)) *>            (fst <$> crtExtFuncs)@@ -226,8 +228,8 @@ -- | Embed a tensor with index @m@ in the CRT basis to a tensor with -- index @m'@ in the CRT basis. -- (This function is simply an appropriate entry from 'crtExtFuncs'.)-embedCRT :: forall t r m m' . (Tensor t, m `Divides` m', CRTElt t r)-            => Maybe (t m r -> t m' r)+embedCRT :: forall t m m' mon r . (CRTrans mon r, Tensor t, m `Divides` m', TElt t r)+            => mon (t m r -> t m' r) embedCRT = proxyT hasCRTFuncs (Proxy::Proxy (t m' r)) *>            proxyT hasCRTFuncs (Proxy::Proxy (t m  r)) *>            (snd <$> crtExtFuncs)@@ -244,46 +246,89 @@             mat' <- withWitnessT mat spp             return $ MKron rest' mat' +-- | For a prime power @p^e@, converts any matrix @M@ for+-- prime @p@ to @1_(p^{e-1}) \otimes M@, where @1@ denotes the all-1s+-- vector.+ppMatrix :: forall pp r mon . (PPow pp, Monad mon, Ring r)+            => (forall p . (Prime p) => TaggedT p mon (MatrixC r))+            -> TaggedT pp mon (MatrixC r)+ppMatrix mat = tagT $ case (sing :: SPrimePower pp) of+  pp@(SPP (STuple2 sp _)) -> do+    (MC h w f) <- withWitnessT mat sp+    let d = withWitness valuePPow pp `div` withWitness valuePrime sp+    return $ MC (h*d) w (f . (`mod` h))+ -- deeply embedded DSL for Kronecker products of matrices -data MatrixC r = -  MC (Int -> Int -> r)           -- yields element i,j-  Int Int                        -- dims+data MatrixC r =+  MC Int Int                        -- dims+  (Int -> Int -> r)                 -- yields element i,j  -- | A Kronecker product of zero of more matrices over @r@.-data Matrix r = MNil | MKron (Matrix r) (MatrixC r)+data Matrix r = MNil | MKron (Matrix r) (MatrixC r) -- snoc list  -- | Extract the @(i,j)@ element of a 'Matrix'. indexM :: Ring r => Matrix r -> Int -> Int -> r indexM MNil 0 0 = LP.one-indexM (MKron m (MC mc r c)) i j =+indexM (MKron m (MC r c mc)) i j =   let (iq,ir) = i `divMod` r       (jq,jr) = j `divMod` c       in indexM m iq jq * mc ir jr +gCRTM, gInvCRTM :: (Fact m, CRTrans mon r) => TaggedT m mon (Matrix r)+-- | A @tot(m)@-by-1 matrix of the CRT coefficients of @g_m@, for @m@th+-- cyclotomic.+gCRTM = fMatrix gCRTPPow+-- | A @tot(m)@-by-1 matrix of the inverse CRT coefficients of @g_m@, for @m@th+-- cyclotomic.+gInvCRTM = fMatrix gInvCRTPPow+ -- | The "tweaked" CRT^* matrix: @CRT^* . diag(sigma(g_m))@.-twCRTs :: (Fact m, CRTrans r) => TaggedT m Maybe (Matrix r)+twCRTs :: (Fact m, CRTrans mon r) => TaggedT m mon (Matrix r) twCRTs = fMatrix twCRTsPPow  -- | The "tweaked" CRT^* matrix (for prime powers): @CRT^* * diag(sigma(g_p))@.-twCRTsPPow :: (PPow pp, CRTrans r) => TaggedT pp Maybe (MatrixC r)+twCRTsPPow :: (PPow pp, CRTrans mon r) => TaggedT pp mon (MatrixC r) twCRTsPPow = do   phi    <- pureT totientPPow   iToZms <- pureT indexToZmsPPow   jToPow <- pureT indexToPowPPow-  (wPow, _) <- crtInfoPPow-  gEmb <- gEmbPPow+  (wPow, _) <- crtInfo+  (MC _ _ gCRT) <- gCRTPPow -  return $ MC (\j i -> let i' = iToZms i-                       in wPow (jToPow j * negate i') * gEmb i') phi phi+  return $ MC phi phi (\j i -> wPow (jToPow j * negate (iToZms i)) * gCRT i 0) +gCRTPPow, gInvCRTPPow :: (PPow pp, CRTrans mon r) => TaggedT pp mon (MatrixC r)+gCRTPPow = ppMatrix gCRTPrime+gInvCRTPPow = ppMatrix gInvCRTPrime++gCRTPrime, gInvCRTPrime :: (Prime p, CRTrans mon r) => TaggedT p mon (MatrixC r)++-- | A @(p-1)@-by-1 matrix of the CRT coefficients of @g_p@, for @p@th+-- cyclotomic.+gCRTPrime = do+  p <- pureT valuePrime+  (wPow, _) <- crtInfo+  return $ MC (p-1) 1 $ if p == 2 then const $ const one+                        else (\i _ -> one - wPow (i+1))++-- | A @(p-1)@-by-1 matrix of the inverse CRT coefficients of @g_p@,+-- for the @p@th cyclotomic.+gInvCRTPrime = do+  p <- pureT valuePrime+  (wPow, phatinv) <- crtInfo+  return $ MC (p-1) 1 $+    if p == 2 then const $ const one+    else (\i -> const $ phatinv *+                sum [fromIntegral j * wPow ((i+1)*(p-1-j)) | j <- [1..p-1]])+ -- Reindexing functions  -- | Base-p digit reversal; input and output are in @[p^e]@. digitRev :: PP -> Int -> Int digitRev (_,0) 0 = 0 -- CJP: use accumulator to avoid multiple exponentiations?-digitRev (p,e) j +digitRev (p,e) j   | e >= 1 = let (q,r) = j `divMod` p              in r * (p^(e-1)) + digitRev (p,e-1) q @@ -306,13 +351,13 @@ -- element i in @Z_{p^e}^*@. indexToZms :: PP -> Int -> Int indexToZms (p,_) i = let (i1,i0) = i `divMod` (p-1)-                       in p*i1 + i0 + 1 +                       in p*i1 + i0 + 1  -- | Convert a Z_m^* index to a linear tensor index. zmsToIndex :: [PP] -> Int -> Int zmsToIndex [] _ = 0 zmsToIndex (pp:rest) i = zmsToIndexPP pp (i `mod` valuePP pp)-                         + (totientPP pp) * zmsToIndex rest i+                         + totientPP pp * zmsToIndex rest i  -- | Inverse of 'indexToZms'. zmsToIndexPP :: PP -> Int -> Int
Crypto/Lol/Cyclotomic/Tensor/CTensor.hs view
@@ -1,12 +1,12 @@-{-# LANGUAGE ConstraintKinds, DataKinds, GADTs,-             FlexibleContexts, FlexibleInstances, TypeOperators, PolyKinds,-             GeneralizedNewtypeDeriving, InstanceSigs, RoleAnnotations,-             MultiParamTypeClasses, NoImplicitPrelude, StandaloneDeriving,-             ScopedTypeVariables, TupleSections, TypeFamilies, RankNTypes,-             TypeSynonymInstances, UndecidableInstances,-             RebindableSyntax #-}+{-# LANGUAGE ConstraintKinds, DataKinds, FlexibleContexts,+             FlexibleInstances, GADTs, GeneralizedNewtypeDeriving,+             InstanceSigs, MultiParamTypeClasses, NoImplicitPrelude,+             PolyKinds, RankNTypes, RebindableSyntax, RoleAnnotations,+             ScopedTypeVariables, StandaloneDeriving, TupleSections,+             TypeFamilies, TypeOperators, TypeSynonymInstances,+             UndecidableInstances #-} --- | Wrapper for a C implementation of the 'Tensor' interface.+-- | Wrapper for a C++ implementation of the 'Tensor' interface.  module Crypto.Lol.Cyclotomic.Tensor.CTensor ( CT ) where@@ -15,48 +15,57 @@ import Algebra.Module       as Module (C) import Algebra.ZeroTestable as ZeroTestable (C) -import Control.Applicative hiding ((*>))-import Control.Arrow ((***))+import Control.Applicative    hiding ((*>))+import Control.Arrow          ((***)) import Control.DeepSeq-import Control.Monad (liftM)-import Control.Monad.Identity (Identity(..), runIdentity)+import Control.Monad.Except+import Control.Monad.Identity (Identity (..), runIdentity) import Control.Monad.Random-import Control.Monad.Trans (lift)+import Control.Monad.Trans    as T (lift)  import Data.Coerce-import Data.Constraint  hiding ((***))-import Data.Foldable as F+import Data.Constraint              hiding ((***)) import Data.Int import Data.Maybe-import Data.Traversable as T-import Data.Vector.Generic           as V (zip, unzip, fromList, toList)-import Data.Vector.Storable          as SV (Vector, (!), replicate, replicateM, thaw, convert, foldl',-                                            unsafeSlice, mapM, fromList, toList,-                                            generate, foldl1',-                                            unsafeWith, zipWith, map, length, unsafeFreeze, thaw)-import Data.Vector.Storable.Internal (getPtr)-import Data.Vector.Storable.Mutable  as SM hiding (replicate)+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,+                                           replicateM, thaw, thaw, toList,+                                           unsafeFreeze, unsafeSlice,+                                           unsafeWith, zipWith, (!))+import Data.Vector.Storable.Mutable as SM hiding (replicate)  import Foreign.Marshal.Utils (with) import Foreign.Ptr-import Foreign.Storable        (Storable (..))-import Test.QuickCheck         hiding (generate)+import Test.QuickCheck       hiding (generate)  import Crypto.Lol.CRTrans import Crypto.Lol.Cyclotomic.Tensor import Crypto.Lol.Cyclotomic.Tensor.CTensor.Backend import Crypto.Lol.Cyclotomic.Tensor.CTensor.Extension import Crypto.Lol.GaussRandom-import Crypto.Lol.LatticePrelude as LP hiding (replicate, unzip, zip, lift)+import Crypto.Lol.Prelude                             as LP hiding+                                                             (replicate,+                                                             unzip, zip) import Crypto.Lol.Reflects import Crypto.Lol.Types.FiniteField import Crypto.Lol.Types.IZipVector+import Crypto.Lol.Types.Proto+import Crypto.Lol.Types.RRq import Crypto.Lol.Types.ZqBasic +import Crypto.Proto.RLWE.Kq+import Crypto.Proto.RLWE.Rq++import Data.Foldable as F+import Data.Sequence as S (fromList)+ import System.IO.Unsafe (unsafePerformIO)  -- | Newtype wrapper around a Vector.-newtype CT' (m :: Factored) r = CT' { unCT :: Vector r } +newtype CT' (m :: Factored) r = CT' { unCT :: Vector r }                               deriving (Show, Eq, NFData)  -- the first argument, though phantom, affects representation@@ -65,19 +74,65 @@ -- GADT wrapper that distinguishes between Unbox and unrestricted -- element types --- | An implementation of 'Tensor' backed by C code.-data CT (m :: Factored) r where +-- | An implementation of 'Tensor' backed by C++ code.+data CT (m :: Factored) r where   CT :: Storable r => CT' m r -> CT m r   ZV :: IZipVector m r -> CT m r +deriving instance Show r => Show (CT m r)+ instance Eq r => Eq (CT m r) where   (ZV x) == (ZV y) = x == y   (CT x) == (CT y) = x == y   x@(CT _) == y = x == toCT y   y == x@(CT _) = x == toCT y -deriving instance Show r => Show (CT m r)+instance (Fact m, Reflects q Int64) => Protoable (CT m (ZqBasic q Int64)) where+  type ProtoType (CT m (ZqBasic q Int64)) = Rq +  toProto (CT (CT' xs)) =+    let m = fromIntegral $ proxy valueFact (Proxy::Proxy m)+        q = proxy value (Proxy::Proxy q) :: Int64+    in Rq m (fromIntegral q) $ S.fromList $ SV.toList $ SV.map LP.lift xs+  toProto x@(ZV _) = toProto $ toCT x++  fromProto (Rq m' q' xs) =+    let m = proxy valueFact (Proxy::Proxy m) :: Int+        q = proxy value (Proxy::Proxy q) :: Int64+        n = proxy totientFact (Proxy::Proxy m)+        xs' = SV.fromList $ F.toList xs+        len = F.length xs+    in if m == fromIntegral m' && len == n && fromIntegral q == q'+       then return $ CT $ CT' $ SV.map reduce xs'+       else throwError $+            "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 q ++ ", got " ++ show q' ++ "."++instance (Fact m, Reflects q Double) => Protoable (CT m (RRq q Double)) where+  type ProtoType (CT m (RRq q Double)) = Kq++  toProto (CT (CT' xs)) =+    let m = fromIntegral $ proxy valueFact (Proxy::Proxy m)+        q = 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+        n = proxy totientFact (Proxy::Proxy m)+        xs' = SV.fromList $ F.toList xs+        len = F.length xs+    in if m == fromIntegral m' && len == n && q == q'+       then return $ CT $ CT' $ SV.map reduce xs'+       else throwError $+            "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' ++ "."+ toCT :: (Storable r) => CT m r -> CT m r toCT v@(CT _) = v toCT (ZV v) = CT $ zvToCT' v@@ -113,12 +168,11 @@  -- CJP: Additive, Ring are not necessary when we use zipWithT -- EAC: This has performance implications for the CT backend,---      which used a C function for zipWith (*)-+--      which used a (very fast) C function for (*) and (+) instance (Additive r, Storable r, Fact m, Dispatch r)   => Additive.C (CT m r) where-  (CT a@(CT' _)) + (CT b@(CT' _)) = CT $ (untag $ cZipDispatch dadd) a b-  a + b = (toCT a) + (toCT b)+  (CT (CT' a)) + (CT (CT' b)) = CT $ CT' $ SV.zipWith (+) a b+  a + b = toCT a + toCT b   negate (CT (CT' a)) = CT $ CT' $ SV.map negate a -- EAC: This probably should be converted to C code   negate a = negate $ toCT a @@ -134,7 +188,7 @@  instance (ZeroTestable r, Storable r, Fact m)          => ZeroTestable.C (CT m r) where-  --{-# INLINABLE isZero #-} +  --{-# INLINABLE isZero #-}   isZero (CT (CT' a)) = SV.foldl' (\ b x -> b && isZero x) True a   isZero (ZV v) = isZero v @@ -191,11 +245,11 @@   divGDec = wrapM $ Just . untag (basicDispatch dginvdec)    crtFuncs = (,,,,) <$>-    Just (CT . repl) <*>-    (wrap <$> untag (cZipDispatch dmul) <$> untagT gCoeffsCRT) <*>-    (wrap <$> untag (cZipDispatch dmul) <$> untagT gInvCoeffsCRT) <*>+    return (CT . repl) <*>+    (wrap . untag (cZipDispatch dmul) <$> gCRT) <*>+    (wrap . untag (cZipDispatch dmul) <$> gInvCRT) <*>     (wrap <$> untagT ctCRT) <*>-    (wrap <$> untagT ctCRTInv) +    (wrap <$> untagT ctCRTInv)    twacePowDec = wrap $ runIdentity $ coerceTw twacePowDec'   embedPow = wrap $ runIdentity $ coerceEm embedPow'@@ -226,11 +280,8 @@   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) -  unzipTElt (CT (CT' v)) = (CT . CT') *** (CT . CT') $ unzip v-  unzipTElt v = unzipTElt $ toCT v--  unzipT v@(CT _) = unzipT $ toZV v-  unzipT (ZV v) = ZV *** ZV $ unzipIZV v+  unzipT (CT (CT' v)) = (CT . CT') *** (CT . CT') $ unzip v+  unzipT v = unzipT $ toCT v    {-# INLINABLE entailIndexT #-}   {-# INLINABLE entailEqT #-}@@ -258,7 +309,6 @@   {-# INLINABLE fmapT #-}   {-# INLINABLE fmapTM #-}   {-# INLINABLE zipWithT #-}-  {-# INLINABLE unzipTElt #-}   {-# INLINABLE unzipT #-}  @@ -270,13 +320,13 @@  -- | Useful coersion for defining @coeffs@ in the @Tensor@ -- interface. Using 'coerce' alone is insufficient for type inference.-coerceCoeffs :: (Fact m, Fact m') +coerceCoeffs :: (Fact m, Fact m')   => Tagged '(m,m') (Vector r -> [Vector r]) -> CT' m' r -> [CT' m r] coerceCoeffs = coerce  -- | Useful coersion for defining @powBasisPow@ and @crtSetDec@ in the @Tensor@ -- interface. Using 'coerce' alone is insufficient for type inference.-coerceBasis :: +coerceBasis ::   (Fact m, Fact m')   => Tagged '(m,m') [Vector r] -> Tagged m [CT' m' r] coerceBasis = coerce@@ -284,11 +334,12 @@ mulGPow' :: (TElt CT r, Fact m, Additive r) => CT' m r -> CT' m r mulGPow' = untag $ basicDispatch dmulgpow -divGPow' :: forall m r . (TElt CT r, Fact m, IntegralDomain r, ZeroTestable r) => CT' m r -> Maybe (CT' m r)+divGPow' :: (TElt CT r, Fact m, IntegralDomain r, ZeroTestable r)+            => CT' m r -> Maybe (CT' m r) divGPow' = untag $ checkDiv $ basicDispatch dginvpow -withBasicArgs :: forall m r . (Fact m, Storable r) -  => (Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO ()) +withBasicArgs :: forall m r . (Fact m, Storable r)+  => (Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO ())      -> CT' m r -> IO (CT' m r) withBasicArgs f =   let factors = proxy (marshalFactors <$> ppsFact) (Proxy::Proxy m)@@ -301,43 +352,37 @@         f pout totm pfac numFacts))     CT' <$> unsafeFreeze yout -basicDispatch :: forall m r .-     (Storable r, Fact m, Additive r)-      => (Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO ())-         -> Tagged m (CT' m r -> CT' m r)+basicDispatch :: (Storable r, Fact m, Additive r)+                 => (Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO ())+                     -> Tagged m (CT' m r -> CT' m r) basicDispatch f = return $ unsafePerformIO . withBasicArgs f -gSqNormDec' :: forall m r .-     (Storable r, Fact m, Additive r, Dispatch r)-      => Tagged m (CT' m r -> r)+gSqNormDec' :: (Storable r, Fact m, Additive r, Dispatch r)+               => Tagged m (CT' m r -> r) gSqNormDec' = return $ (!0) . unCT . unsafePerformIO . withBasicArgs dnorm -ctCRT :: forall m r . (Storable r, CRTrans r, Dispatch r,-          Fact m)-         => TaggedT m Maybe (CT' m r -> CT' m r)-ctCRT = do -- in TaggedT m Maybe+ctCRT :: (Storable r, CRTrans mon r, Dispatch r, Fact m)+         => TaggedT m mon (CT' m r -> CT' m r)+ctCRT = do   ru' <- ru-  return $ \x -> unsafePerformIO $ +  return $ \x -> unsafePerformIO $     withPtrArray ru' (flip withBasicArgs x . dcrt)  -- CTensor CRT^(-1) functions take inverse rus-ctCRTInv :: (Storable r, CRTrans r, Dispatch r,-          Fact m)-         => TaggedT m Maybe (CT' m r -> CT' m r)-ctCRTInv = do -- in Maybe-  mhatInv <- snd <$> crtInfoFact+ctCRTInv :: (Storable r, CRTrans mon r, Dispatch r, Fact m)+         => TaggedT m mon (CT' m r -> CT' m r)+ctCRTInv = do+  mhatInv <- snd <$> crtInfo   ruinv' <- ruInv-  return $ \x -> unsafePerformIO $ +  return $ \x -> unsafePerformIO $     withPtrArray ruinv' (\ruptr -> with mhatInv (flip withBasicArgs x . dcrtinv ruptr)) -checkDiv :: forall m r . -  (IntegralDomain r, Storable r, ZeroTestable r, -   Fact m)+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 -> +  return $ \x ->     let (CT' y) = f' x     in CT' <$> SV.mapM (`divIfDivis` oddRad') y @@ -367,8 +412,8 @@   totm <- pureT totientFact   m <- pureT valueFact   rad <- pureT radicalFact-  yin <- lift $ realGaussians (var * fromIntegral (m `div` rad)) totm-  return $ unsafePerformIO $ +  yin <- T.lift $ realGaussians (var * fromIntegral (m `div` rad)) totm+  return $ unsafePerformIO $     withPtrArray ruinv' (\ruptr -> withBasicArgs (dgaussdec ruptr) (CT' yin))  instance (Arbitrary r, Fact m, Storable r) => Arbitrary (CT' m r) where@@ -398,25 +443,22 @@ repl = let n = proxy totientFact (Proxy::Proxy m)        in coerce . SV.replicate n -replM :: forall m r mon . (Fact m, Storable r, Monad mon) +replM :: forall m r mon . (Fact m, Storable r, Monad mon)          => mon r -> mon (CT' m r) replM = let n = proxy totientFact (Proxy::Proxy m)         in fmap coerce . SV.replicateM n ---{-# INLINE scalarPow' #-} scalarPow' :: forall m r . (Fact m, Additive r, Storable r) => r -> CT' m r -- constant-term coefficient is first entry wrt powerful basis-scalarPow' = +scalarPow' =   let n = proxy totientFact (Proxy::Proxy m)   in \r -> CT' $ generate n (\i -> if i == 0 then r else zero) -ru, ruInv :: forall r m . -   (CRTrans r, Fact m, Storable r)-   => TaggedT m Maybe [Vector r]---{-# INLINE ru #-}+ru, ruInv :: (CRTrans mon r, Fact m, Storable r)+   => TaggedT m mon [Vector r] ru = do   mval <- pureT valueFact-  wPow <- fst <$> crtInfoFact+  wPow <- fst <$> crtInfo   LP.map     (\(p,e) -> do         let pp = p^e@@ -424,10 +466,9 @@         generate pp (wPow . (*pow))) <$>       pureT ppsFact ---{-# INLINE ruInv #-} ruInv = do   mval <- pureT valueFact-  wPow <- fst <$> crtInfoFact+  wPow <- fst <$> crtInfo   LP.map     (\(p,e) -> do         let pp = p^e@@ -435,33 +476,29 @@         generate pp (\i -> wPow $ -i*pow)) <$>       pureT ppsFact -gCoeffsCRT, gInvCoeffsCRT :: (TElt CT r, CRTrans r, Fact m, ZeroTestable r, IntegralDomain r)-  => TaggedT m Maybe (CT' m r)-gCoeffsCRT = ctCRT <*> return (mulGPow' $ scalarPow' LP.one)--- It's necessary to call 'fromJust' here: otherwise --- sequencing functions in 'crtFuncs' relies on 'divGPow' having an--- implementation in C, which is not true for all types which have a C--- implementation of, e.g. 'crt'. In particular, 'Complex Double' has C support--- for 'crt', but not for 'divGPow'.--- This really breaks the contract of Tensor, so it's probably a bad idea.---   Someone can get the "crt" and can even pull the function "divGCRT" from Tensor,---   but it will fail when they try to apply it.--- As an implementation note if I ever do fix this: the division by rad(m) can be--- tricky for Double/Complex Doubles, so be careful! This is why we have a custom--- Complex wrapper around NP.Complex.-gInvCoeffsCRT = ($ fromJust $ divGPow' $ scalarPow' LP.one) <$> ctCRT+wrapVector :: forall mon m r . (Monad mon, Fact m, Ring r, Storable r)+  => TaggedT m mon (Matrix r) -> mon (CT' m r)+wrapVector v = do+  vmat <- proxyT v (Proxy::Proxy m)+  let n = proxy totientFact (Proxy::Proxy m)+  return $ CT' $ generate n (flip (indexM vmat) 0) --- we can't put this in Extension with the rest of the twace/embed fucntions because it needs access to --- the C backend-twaceCRT' :: forall m m' r .-             (TElt CT r, CRTrans r, m `Divides` m', ZeroTestable r, IntegralDomain r)-             => TaggedT '(m, m') Maybe (Vector r -> Vector r)-twaceCRT' = tagT $ do -- Maybe monad-  (CT' g') <- proxyT gCoeffsCRT (Proxy::Proxy m')-  (CT' gInv) <- proxyT gInvCoeffsCRT (Proxy::Proxy m)+gCRT, gInvCRT :: (Storable r, CRTrans mon r, Fact m)+                 => mon (CT' m r)+gCRT = wrapVector gCRTM+gInvCRT = wrapVector gInvCRTM++-- 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 crtInfoFact (Proxy::Proxy 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)
Crypto/Lol/Cyclotomic/Tensor/CTensor/Backend.hs view
@@ -1,51 +1,51 @@-{-# LANGUAGE ConstraintKinds, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, -             PolyKinds, ScopedTypeVariables, TypeFamilies, UndecidableInstances #-}+{-# LANGUAGE ConstraintKinds, FlexibleContexts, FlexibleInstances,+             MultiParamTypeClasses, PolyKinds, ScopedTypeVariables,+             TypeFamilies, UndecidableInstances #-} +-- | This module contains the functions to transform Haskell types into their+-- C counterpart, and to transform polymorphic Haskell functions into C funtion+-- calls in a type-safe way.+ module Crypto.Lol.Cyclotomic.Tensor.CTensor.Backend-(Dispatch-,dcrt-,dcrtinv-,dgaussdec-,dl-,dlinv-,dnorm-,dmulgpow-,dmulgdec-,dginvpow-,dginvdec-,dadd-,dmul-,marshalFactors-,CPP-,withArray-,withPtrArray+( Dispatch+, dcrt, dcrtinv+, dgaussdec+, dl, dlinv+, dnorm+, dmulgpow, dmulgdec+, dginvpow, dginvdec+, dmul+, marshalFactors+, CPP+, withArray, withPtrArray ) where  import Control.Applicative-import Control.Monad -import Crypto.Lol.LatticePrelude as LP (Complex, Proxy(..), proxy, (++), map, mapM_, PP, Tagged, tag)+import Crypto.Lol.Prelude       as LP (Complex, PP, Proxy (..), Tagged,+                                       map, mapM_, proxy, tag, (++)) import Crypto.Lol.Reflects+import Crypto.Lol.Types.RRq import Crypto.Lol.Types.ZqBasic  import Data.Int-import Data.Vector.Storable          as SV (Vector, (!), replicate, replicateM, thaw, convert, foldl',-                                            unsafeToForeignPtr0, unsafeSlice, mapM, fromList,-                                            generate, foldl1',-                                            unsafeWith, zipWith, map, length, unsafeFreeze, thaw)+import Data.Vector.Storable          as SV (Vector, fromList,+                                            unsafeToForeignPtr0) import Data.Vector.Storable.Internal (getPtr) -import           Foreign.ForeignPtr (touchForeignPtr)-import           Foreign.Marshal.Array (withArray)-import           Foreign.Marshal.Utils (with)-import           Foreign.Ptr (plusPtr, castPtr, Ptr)+import           Foreign.ForeignPtr      (touchForeignPtr)+import           Foreign.Marshal.Array   (withArray)+import           Foreign.Marshal.Utils   (with)+import           Foreign.Ptr             (Ptr, castPtr, plusPtr) import           Foreign.Storable        (Storable (..)) import qualified Foreign.Storable.Record as Store +-- | 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))  -- http://stackoverflow.com/questions/6517387/vector-vector-foo-ptr-ptr-foo-io-a-io-a+-- | Evaluates a C function that takes a @a** ptr@ on a list of Vectors. withPtrArray :: (Storable a) => [Vector a] -> (Ptr (Ptr a) -> IO b) -> IO b withPtrArray v f = do   let vs = LP.map SV.unsafeToForeignPtr0 v@@ -54,6 +54,7 @@   LP.mapM_ (\(fp,_) -> touchForeignPtr fp) vs   return res +-- | 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@@ -73,11 +74,11 @@     show (CPP p e) = "(" LP.++ show p LP.++ "," LP.++ show e LP.++ ")"  instance (Storable a, Storable b,-          CTypeOf a ~ CTypeOf b) -  -- enforces right associativity and that each type of +          CTypeOf a ~ CTypeOf b)+  -- enforces right associativity and that each type of   -- the tuple has the same C repr, so using an array repr is safe   => Storable (a,b) where-  sizeOf _ = (sizeOf (undefined :: a)) + (sizeOf (undefined :: b))+  sizeOf _ = sizeOf (undefined :: a) + sizeOf (undefined :: b)   alignment _ = max (alignment (undefined :: a)) (alignment (undefined :: b))   peek p = do     a <- peek (castPtr p :: Ptr a)@@ -95,6 +96,7 @@ data ComplexD data DoubleD data Int64D+data RRqD  type family CTypeOf x where   CTypeOf (a,b) = CTypeOf a@@ -102,6 +104,7 @@   CTypeOf Double = DoubleD   CTypeOf Int64 = Int64D   CTypeOf (Complex Double) = ComplexD+  CTypeOf (RRq (q :: k) Double) = RRqD  -- returns the modulus as a nested list of moduli class (Tuple a) => ZqTuple a where@@ -112,9 +115,13 @@   type ModPairs (ZqBasic q Int64) = Int64   getModuli = tag $ proxy value (Proxy::Proxy q) +instance (Reflects q r, RealFrac r) => ZqTuple (RRq q r) where+  type ModPairs (RRq q r) = Int64+  getModuli = tag $ round (proxy value (Proxy::Proxy q) :: r)+ instance (ZqTuple a, ZqTuple b) => ZqTuple (a, b) where   type ModPairs (a,b) = (ModPairs a, ModPairs b)-  getModuli = +  getModuli =     let as = proxy getModuli (Proxy::Proxy a)         bs = proxy getModuli (Proxy :: Proxy b)     in tag (as,bs)@@ -127,31 +134,53 @@   numComponents = tag 1  instance (Tuple a, Tuple b) => Tuple (a,b) where-  numComponents = tag $ (proxy numComponents (Proxy::Proxy a)) + (proxy numComponents (Proxy::Proxy b))+  numComponents = tag $ proxy numComponents (Proxy::Proxy a) + proxy numComponents (Proxy::Proxy b) +-- | Single-argument synonym for @Dispatch'@. type Dispatch r = (Dispatch' (CTypeOf r) r)  -- | Class to safely match Haskell types with the appropriate C function. class (repr ~ CTypeOf r) => Dispatch' repr r where+  -- | Equivalent to 'Tensor's @crt@.   dcrt      :: Ptr (Ptr r) ->           Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO ()+  -- | Equivalent to 'Tensor's @crtInv@.   dcrtinv   :: Ptr (Ptr r) -> Ptr r ->  Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO ()+  -- | Equivalent to 'Tensor's @tGaussianDec@.   dgaussdec :: Ptr (Ptr (Complex r)) -> Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO ()-+  -- | Equivalent to 'Tensor's @l@.   dl        :: Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO ()+  -- | Equivalent to 'Tensor's @lInv@.   dlinv     :: Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO ()+  -- | Equivalent to 'Tensor's @gSqNormDec@.   dnorm     :: Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO ()+  -- | Equivalent to 'Tensor's @mulGPow@.   dmulgpow  :: Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO ()+  -- | 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 ()+  -- | Equivalent to 'Tensor's @divGDec@.   dginvdec  :: Ptr r -> Int64 -> Ptr CPP -> Int16 -> IO ()-  -  dadd :: Ptr r -> Ptr r -> Int64 -> IO ()+  -- | Equivalent to @zipWith (*)@   dmul :: Ptr r -> Ptr r -> Int64 -> IO () -instance (ZqTuple r, Storable (ModPairs r),-          CTypeOf r ~ ZqB64D)+instance (ZqTuple r, Storable (ModPairs r), CTypeOf r ~ RRqD)+  => Dispatch' RRqD r where+  dcrt = error "cannot call CT CRT on type RRq"+  dcrtinv = error "cannot call CT CRTInv on type RRq"+  dl = error "cannot call CT L on type RRq (though you probably should be able to)"+  dlinv = error "cannot call CT LInv on type RRq (though you probably should be able to)"+  dnorm = error "cannto call CT normSq on type RRq"+  dmulgpow = error "cannot call CT mulGPow on type RRq"+  dmulgdec = error "cannot call CT mulGDec on type RRq"+  dginvpow = error "cannot call CT divGPow on type RRq"+  dginvdec = error "cannot call CT divGDec on type RRq"+  dmul = error "cannot call CT mul on type RRq"+  dgaussdec = error "cannot call CT gaussianDec on type RRq"++instance (ZqTuple r, Storable (ModPairs r), CTypeOf r ~ ZqB64D)   => Dispatch' ZqB64D r where-  dcrt ruptr pout totm pfac numFacts = +  dcrt ruptr pout totm pfac numFacts =     let qs = proxy getModuli (Proxy::Proxy r)         numPairs = proxy numComponents (Proxy::Proxy r)     in with qs $ \qsptr ->@@ -161,12 +190,12 @@         numPairs = proxy numComponents (Proxy::Proxy r)     in with qs $ \qsptr ->         tensorCRTInvRq numPairs (castPtr pout) totm pfac numFacts (castPtr ruptr) (castPtr minv) (castPtr qsptr)-  dl pout totm pfac numFacts = +  dl pout totm pfac numFacts =     let qs = proxy getModuli (Proxy::Proxy r)         numPairs = proxy numComponents (Proxy::Proxy r)     in with qs $ \qsptr ->         tensorLRq numPairs (castPtr pout) totm pfac numFacts (castPtr qsptr)-  dlinv pout totm pfac numFacts = +  dlinv pout totm pfac numFacts =     let qs = proxy getModuli (Proxy::Proxy r)         numPairs = proxy numComponents (Proxy::Proxy r)     in with qs $ \qsptr ->@@ -192,12 +221,7 @@         numPairs = proxy numComponents (Proxy::Proxy r)     in with qs $ \qsptr ->         tensorGInvDecRq numPairs (castPtr pout) totm pfac numFacts (castPtr qsptr)-  dadd aout bout totm = -    let qs = proxy getModuli (Proxy::Proxy r)-        numPairs = proxy numComponents (Proxy::Proxy r)-    in with qs $ \qsptr ->-        addRq numPairs (castPtr aout) (castPtr bout) totm (castPtr qsptr)-  dmul aout bout totm = +  dmul aout bout totm =     let qs = proxy getModuli (Proxy::Proxy r)         numPairs = proxy numComponents (Proxy::Proxy r)     in with qs $ \qsptr ->@@ -205,64 +229,58 @@   dgaussdec = error "cannot call CT gaussianDec on type ZqBasic"  instance (Tuple r, CTypeOf r ~ ComplexD) => Dispatch' ComplexD r where-  dcrt ruptr pout totm pfac numFacts = +  dcrt ruptr pout totm pfac numFacts =     tensorCRTC (proxy numComponents (Proxy::Proxy r)) (castPtr pout) totm pfac numFacts (castPtr ruptr)-  dcrtinv ruptr minv pout totm pfac numFacts = +  dcrtinv ruptr minv pout totm pfac numFacts =     tensorCRTInvC (proxy numComponents (Proxy::Proxy r)) (castPtr pout) totm pfac numFacts (castPtr ruptr) (castPtr minv)-  dl pout = +  dl pout =     tensorLC (proxy numComponents (Proxy::Proxy r)) (castPtr pout)-  dlinv pout = +  dlinv pout =     tensorLInvC (proxy numComponents (Proxy::Proxy r)) (castPtr pout)   dnorm = error "cannot call CT normSq on type Complex Double"-  dmulgpow pout = +  dmulgpow pout =     tensorGPowC (proxy numComponents (Proxy::Proxy r)) (castPtr pout)   dmulgdec = error "cannot call CT mulGDec on type Complex Double"-  dginvpow pout = +  dginvpow pout =     tensorGInvPowC (proxy numComponents (Proxy::Proxy r)) (castPtr pout)   dginvdec = error "cannot call CT divGDec on type Complex Double"-  dadd aout bout = -    addC (proxy numComponents (Proxy::Proxy r)) (castPtr aout) (castPtr bout)-  dmul aout bout = +  dmul aout bout =     mulC (proxy numComponents (Proxy::Proxy r)) (castPtr aout) (castPtr bout)   dgaussdec = error "cannot call CT gaussianDec on type Comple Double"  instance (Tuple r, CTypeOf r ~ DoubleD) => Dispatch' DoubleD r where   dcrt = error "cannot call CT Crt on type Double"   dcrtinv = error "cannot call CT CrtInv on type Double"-  dl pout = +  dl pout =     tensorLDouble (proxy numComponents (Proxy::Proxy r)) (castPtr pout)-  dlinv pout = +  dlinv pout =     tensorLInvDouble (proxy numComponents (Proxy::Proxy r)) (castPtr pout)-  dnorm = error "cannot call CT normSq on type Double"+  dnorm pout = tensorNormSqD (proxy numComponents (Proxy::Proxy r)) (castPtr pout)   dmulgpow = error "cannot call CT mulGPow on type Double"   dmulgdec = error "cannot call CT mulGDec on type Double"   dginvpow = error "cannot call CT divGPow on type Double"   dginvdec = error "cannot call CT divGDec on type Double"-  dadd aout bout = -    addD (proxy numComponents (Proxy::Proxy r)) (castPtr aout) (castPtr bout)   dmul = error "cannot call CT (*) on type Double"-  dgaussdec ruptr pout totm pfac numFacts = +  dgaussdec ruptr pout totm pfac numFacts =     tensorGaussianDec (proxy numComponents (Proxy::Proxy r)) (castPtr pout) totm pfac numFacts (castPtr ruptr)  instance (Tuple r, CTypeOf r ~ Int64D) => Dispatch' Int64D r where   dcrt = error "cannot call CT Crt on type Int64"   dcrtinv = error "cannot call CT CrtInv on type Int64"-  dl pout = +  dl pout =     tensorLR (proxy numComponents (Proxy::Proxy r)) (castPtr pout)-  dlinv pout = +  dlinv pout =     tensorLInvR (proxy numComponents (Proxy::Proxy r)) (castPtr pout)-  dnorm pout = +  dnorm pout =     tensorNormSqR (proxy numComponents (Proxy::Proxy r)) (castPtr pout)-  dmulgpow pout = +  dmulgpow pout =     tensorGPowR (proxy numComponents (Proxy::Proxy r)) (castPtr pout)-  dmulgdec pout = +  dmulgdec pout =     tensorGDecR (proxy numComponents (Proxy::Proxy r)) (castPtr pout)-  dginvpow pout = +  dginvpow pout =     tensorGInvPowR (proxy numComponents (Proxy::Proxy r)) (castPtr pout)-  dginvdec pout = +  dginvdec pout =     tensorGInvDecR (proxy numComponents (Proxy::Proxy r)) (castPtr pout)-  dadd aout bout = -    addR (proxy numComponents (Proxy::Proxy r)) (castPtr aout) (castPtr bout)   dmul = error "cannot call CT (*) on type Int64"   dgaussdec = error "cannot call CT gaussianDec on type Int64" @@ -276,6 +294,7 @@ foreign import ccall unsafe "tensorLInvC" tensorLInvC :: Int16 -> Ptr (Complex Double) -> Int64 -> Ptr CPP -> Int16          -> IO ()  foreign import ccall unsafe "tensorNormSqR" tensorNormSqR ::     Int16 -> Ptr Int64 -> Int64 -> Ptr CPP -> Int16          -> IO ()+foreign import ccall unsafe "tensorNormSqD" tensorNormSqD ::     Int16 -> Ptr Double -> Int64 -> Ptr CPP -> Int16          -> IO ()  foreign import ccall unsafe "tensorGPowR" tensorGPowR ::         Int16 -> Ptr Int64 -> Int64 -> Ptr CPP -> Int16          -> IO () foreign import ccall unsafe "tensorGPowRq" tensorGPowRq ::       Int16 -> Ptr (ZqBasic q Int64) -> Int64 -> Ptr CPP -> Int16 -> Ptr Int64 -> IO ()@@ -297,8 +316,3 @@  foreign import ccall unsafe "mulRq" mulRq :: Int16 -> Ptr (ZqBasic q Int64) -> Ptr (ZqBasic q Int64) -> Int64 -> Ptr Int64 -> IO () foreign import ccall unsafe "mulC" mulC :: Int16 -> Ptr (Complex Double) -> Ptr (Complex Double) -> Int64 -> IO ()--foreign import ccall unsafe "addRq" addRq :: Int16 -> Ptr (ZqBasic q Int64) -> Ptr (ZqBasic q Int64) -> Int64 -> Ptr Int64 -> IO ()-foreign import ccall unsafe "addR" addR :: Int16 -> Ptr Int64 -> Ptr Int64 -> Int64 -> IO ()-foreign import ccall unsafe "addC" addC :: Int16 -> Ptr (Complex Double) -> Ptr (Complex Double) -> Int64 -> IO ()-foreign import ccall unsafe "addD" addD :: Int16 -> Ptr Double -> Ptr Double -> Int64 -> IO ()
Crypto/Lol/Cyclotomic/Tensor/CTensor/Extension.hs view
@@ -1,6 +1,7 @@-{-# LANGUAGE ConstraintKinds, DataKinds, FlexibleContexts, NoImplicitPrelude, -             PolyKinds, RebindableSyntax, ScopedTypeVariables,-             TypeFamilies, TypeOperators #-}+{-# LANGUAGE ConstraintKinds, DataKinds, FlexibleContexts,+             MultiParamTypeClasses, NoImplicitPrelude, PolyKinds,+             RebindableSyntax, ScopedTypeVariables, TypeFamilies,+             TypeOperators #-}  -- | CT-specific functions for embedding/twacing in various bases @@ -13,21 +14,21 @@ ) where  import Crypto.Lol.CRTrans-import Crypto.Lol.LatticePrelude as LP hiding (null, lift) import Crypto.Lol.Cyclotomic.Tensor as T+import Crypto.Lol.Prelude           as LP hiding (lift, null) import Crypto.Lol.Types.FiniteField import Crypto.Lol.Types.ZmStar-import Crypto.Lol.Reflects + import Control.Applicative hiding (empty) import Control.Monad.Trans (lift)  import           Data.Maybe-import           Data.Reflection (reify)-import qualified Data.Vector         as V-import           Data.Vector.Generic as G (generate, Vector, (!), length)-import qualified Data.Vector.Unboxed as U+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 qualified Data.Vector.Unboxed  as U   -- | /O(n)/ Yield the vector obtained by replacing each element @i@ of the@@ -46,7 +47,7 @@                      => Tagged '(m, m') (v r -> v r) -- | 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 -> +embedPow' = (\indices arr -> generate (U.length indices) $ \idx ->   let (j0,j1) = indices ! idx   in if j0 == 0      then arr ! j1@@ -60,10 +61,10 @@  -- | 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 m m' v r . (CRTrans r, Vector v r, m `Divides` m')-          => TaggedT '(m, m') Maybe (v r -> v r)-embedCRT' = -  (lift (proxyT crtInfoFact (Proxy::Proxy m') :: Maybe (CRTInfo r))) >>+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' =+  (lift (proxyT crtInfo (Proxy::Proxy m') :: mon (CRTInfo r))) >>   (pureT $ backpermute' <$> baseIndicesCRT)  -- | maps a vector in the powerful/decoding basis, representing an@@ -75,7 +76,7 @@           <$> extIndicesCoeffs  -- | The "tweaked trace" function in either the powerful or decoding--- basis of the m'th cyclotomic ring to the mth cyclotomic ring when +-- 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)@@ -92,7 +93,7 @@ powBasisPow' = do   (_, phi, phi', _) <- indexInfo   idxs <- baseIndicesPow-  return $ LP.map (\k -> generate phi' $ \j -> +  return $ LP.map (\k -> generate phi' $ \j ->                            let (j0,j1) = idxs U.! j                           in if j0==k && j1==0 then one else zero)     [0..phi' `div` phi - 1]
− Crypto/Lol/Cyclotomic/Tensor/CTensor/basic.c
@@ -1,175 +0,0 @@-#include "tensorTypes.h"-#ifdef CINTRIN-#include <immintrin.h>-#endif--#ifdef STATS-int mulCtr = 0;-struct timespec mulTime = {0,0};--int addCtr = 0;-struct timespec addTime = {0,0};-#endif--//a = zipWith (*) a b-void mulRq (hShort_t tupSize, hInt_t* a, hInt_t* b, hDim_t totm, hInt_t* qs) {-#ifdef STATS-    mulCtr++;-    struct timespec s1,t1;-    clock_gettime(CLOCK_REALTIME, &s1);-#endif-    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {-        hInt_t q = qs[tupIdx];-        for(int i = 0; i < totm; i++) {-            a[i*tupSize+tupIdx] = (a[i*tupSize+tupIdx]*b[i*tupSize+tupIdx])%q;-        }-    }-#ifdef STATS-    clock_gettime(CLOCK_REALTIME, &t1);-    mulTime = tsAdd(mulTime, tsSubtract(t1,s1));-#endif-}-/*-void mulMq (hShort_t tupSize, hInt_t* a, const hInt_t* b, const hDim_t totm, const hByte_t logr, const hInt_t k, const hInt_t q) {-#ifdef STATS-    mulCtr++;-    struct timespec s1,t1;-    clock_gettime(CLOCK_REALTIME, &s1);-#endif-    hInt_t mask = (1<<logr)-1; // R-1--    for(int i = 0; i < totm; i++) {-        hInt_t x = a[i]*b[i];-        hInt_t s = k*(x & mask);-        hInt_t m = s & mask;-        a[i] = (x+m*q)>>logr;-    }--#ifdef STATS-    clock_gettime(CLOCK_REALTIME, &t1);-    mulTime = tsAdd(mulTime, tsSubtract(t1,s1));-#endif-}-*/-void mulC (hShort_t tupSize, complex_t* a, complex_t* b, hDim_t totm) {-#ifdef STATS-    mulCtr++;-    struct timespec s1,t1;-    clock_gettime(CLOCK_REALTIME, &s1);-#endif-    for(int i = 0; i < totm*tupSize; i++)-    {-        CMPLX_IMUL(a[i],b[i]);-    }-#ifdef STATS-    clock_gettime(CLOCK_REALTIME, &t1);-    mulTime = tsAdd(mulTime, tsSubtract(t1,s1));-#endif-}--//a = zipWith (+) a b-void addRq (hShort_t tupSize, hInt_t* a, const hInt_t* b, const hDim_t totm, const hInt_t* qs) {-#ifdef STATS-    addCtr++;-    struct timespec s1,t1;-    clock_gettime(CLOCK_REALTIME, &s1);-#endif-/*-need to check this code more carefully when tupSize > 1-#ifdef CINTRIN--    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {-        hInt_t q = qs[tupIdx];-        __m128i qss = _mm_set1_epi64x(q);-        for(int i = 0; i < totm; i+=2) {-            __m128i xs = _mm_load_si128((const __m128i*)(a+(i*tupSize+tupIdx)));-            __m128i ys = _mm_load_si128((const __m128i*)(b+(i*tupSize+tupIdx)));-            __m128i zs = _mm_add_epi64(xs,ys);-            zs = _mm_rem_epi64(zs,qss);-            _mm_store_si128((__m128i*)(a+(i*tupSize+tupIdx)),zs);-        }-    }-#else-*/-    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {-        hInt_t q = qs[tupIdx];-        for(int i = 0; i < totm; i++) {-            hInt_t temp = a[i*tupSize+tupIdx]+b[i*tupSize+tupIdx];-            if (temp >= q) a[i*tupSize+tupIdx]=temp-q;-            else a[i*tupSize+tupIdx] = temp;-        }-    }-//#endif-#ifdef STATS-    clock_gettime(CLOCK_REALTIME, &t1);-    addTime = tsAdd(addTime, tsSubtract(t1,s1));-#endif-}-/*-void addMq (hInt_t* a, const hInt_t* b, const hDim_t totm, const hByte_t logr, const hInt_t k, const hInt_t q) {-#ifdef STATS-    addCtr++;-    struct timespec s1,t1;-    clock_gettime(CLOCK_REALTIME, &s1);-#endif-    hInt_t twoq = q<<1;-    for(int i = 0; i < totm; i++) {-        hInt_t temp = (a[i]+b[i]);-        if (temp >= twoq) a[i]=temp-twoq;-        else a[i] = temp;-    }--#ifdef STATS-    clock_gettime(CLOCK_REALTIME, &t1);-    addTime = tsAdd(addTime, tsSubtract(t1,s1));-#endif-}-*/-//a = zipWith (+) a b-void addR (hShort_t tupSize, hInt_t* a, hInt_t* b, hDim_t totm) {-#ifdef STATS-    addCtr++;-    struct timespec s1,t1;-    clock_gettime(CLOCK_REALTIME, &s1);-#endif-    for(int i = 0; i < totm*tupSize; i++)    {-        a[i] += b[i];-    }-#ifdef STATS-    clock_gettime(CLOCK_REALTIME, &t1);-    addTime = tsAdd(addTime, tsSubtract(t1,s1));-#endif-}--void addC (hShort_t tupSize, complex_t* a, complex_t* b, hDim_t totm) {-#ifdef STATS-    addCtr++;-    struct timespec s1,t1;-    clock_gettime(CLOCK_REALTIME, &s1);-#endif-    for(int i = 0; i < totm*tupSize; i++)-    {-        CMPLX_IADD(a[i],b[i]);-    }-#ifdef STATS-    clock_gettime(CLOCK_REALTIME, &t1);-    addTime = tsAdd(addTime, tsSubtract(t1,s1));-#endif-}--void addD (hShort_t tupSize, double* a, double* b, hDim_t totm) {-#ifdef STATS-    addCtr++;-    struct timespec s1,t1;-    clock_gettime(CLOCK_REALTIME, &s1);-#endif-    for(int i = 0; i < totm*tupSize; i++)-    {-        a[i]+=b[i];-    }-#ifdef STATS-    clock_gettime(CLOCK_REALTIME, &t1);-    addTime = tsAdd(addTime, tsSubtract(t1,s1));-#endif-}-
+ Crypto/Lol/Cyclotomic/Tensor/CTensor/common.cpp view
@@ -0,0 +1,18 @@+#include "types.h"
+
+hInt_t Zq::q; // should be in zq.cpp; here due to GHC #12152
+
+hDim_t ipow(hDim_t base, hShort_t exp)
+{
+  hDim_t result = 1;
+  while (exp) {
+    if (exp & 1) {
+      result *= base;
+    }
+    exp >>= 1;
+    base *= base;
+  }
+  return result;
+}
+
+
+ Crypto/Lol/Cyclotomic/Tensor/CTensor/common.h view
@@ -0,0 +1,18 @@+#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);++#endif /* COMMON_H_ */
− Crypto/Lol/Cyclotomic/Tensor/CTensor/crt.c
@@ -1,1386 +0,0 @@-#include "tensorTypes.h"-#include <time.h>-#include <stdlib.h>--// there should be a special cases that do NOT require temp space to be allocated for all primes *smaller* than DFTP_GENERIC_SIZE-#define DFTP_GENERIC_SIZE 11--#ifdef STATS-int crtRqCtr = 0;-int crtInvRqCtr = 0;-int crtCCtr = 0;-int crtInvCCtr = 0;--struct timespec crttime1 = {0,0};-struct timespec crttime2 = {0,0};-struct timespec crttime3 = {0,0};-struct timespec crttime4 = {0,0};--struct timespec crtInvRqTime = {0,0};-struct timespec crtCTime = {0,0};-struct timespec crtInvCTime = {0,0};-#endif--hDim_t bitrev (PrimeExponent pe, hDim_t j) {-    hShort_t e;-    hDim_t p = pe.prime;-    hDim_t tempj = j;-    hDim_t acc = 0;--    for(e = pe.exponent-1; e >= 0; e--) {-        div_t qr = div(tempj,p);-        acc += qr.rem * ipow(p,e);-        tempj = qr.quot;-    }-    return acc;-}--void crtTwiddleRq (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, -                   PrimeExponent pe, hInt_t* ru, hInt_t q)-{-    hDim_t p = pe.prime;-    hShort_t e = pe.exponent;-    -#ifdef DEBUG_MODE-    ASSERT(e != 0);-#endif-    pe.exponent -= 1; // used for an argument to bitrev-    -    if(p == 2)-    {-        hDim_t mprime = 1<<(e-1);-        hDim_t blockDim = rts*mprime; // size of block in block diagonal tensor matrix--        for(hDim_t i0 = 1; i0 < mprime; i0++) // loops over i/(p-1) for i = 0..(m'-1), we can skip i0 = 0-        {-            hDim_t temp2 = i0*rts;-            hInt_t twid = ru[bitrev(pe, i0)*tupSize];--            for(hDim_t blockIdx = 0; blockIdx < lts; blockIdx++)-            {-                hDim_t temp3 = blockIdx*blockDim + temp2;-                for(hDim_t modOffset = 0; modOffset < rts; modOffset++)-                {-                    hDim_t idx = (temp3 + modOffset)*tupSize;-                    y[idx] = (y[idx]*twid) % q;-                }-            }-        }-    }-    else // This loop is faster, probably due to the division in the loop above.-    // cilk also slows it down-    {-        hDim_t mprime = ipow(p,e-1);-        hDim_t blockDim = rts*(p-1)*mprime; // size of block in block diagonal tensor matrix-        -        for(hDim_t i0 = 1; i0 < mprime; i0++) // loops over i/(p-1) for i = 0..(m'-1), we can skip i0 = 0-        {-            hDim_t temp1 = i0*(p-1);-            for(hDim_t i1 = 0; i1 < (p-1); i1++) // loops over i%(p-1) for i = 0..(m'-1)-            {        -                hDim_t temp2 = (temp1+i1)*rts;-                hInt_t twid = ru[bitrev(pe, i0)*(i1+1)*tupSize];--                for(hDim_t blockIdx = 0; blockIdx < lts; blockIdx++)-                {-                    hDim_t temp3 = blockIdx*blockDim + temp2;-                    for(hDim_t modOffset = 0; modOffset < rts; modOffset++)-                    {-                        hDim_t idx = (temp3 + modOffset)*tupSize;-                        y[idx] = (y[idx]*twid) % q;-                    }-                }-            }-        }-    }-}--// dim is power of p-void dftptwidRq (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, -                 PrimeExponent pe, hDim_t dim, hDim_t rustride, hInt_t* ru, hInt_t q)-{-    hDim_t idx;-    hDim_t p = pe.prime;--    pe.exponent -= 1; // used for an argument to bitrev--    if(p == 2) {-        hDim_t mprime = dim>>1; // divides evenly-        hDim_t temp1 = rts*dim; // for use in computing [modified] tensorOffset-        for(hDim_t i0 = 1; i0 < mprime; i0++) // loops over i/p for i = 0..(dim-1), but we skip i0=0-        {-            hDim_t temp3 = rts*(i0*p+1);-            hInt_t twid = ru[bitrev(pe,i0)*rustride*tupSize];--            for(hDim_t blockOffset = 0; blockOffset < lts; blockOffset++)-            {-                hDim_t temp2 = blockOffset*temp1 + temp3;-                for(hDim_t modOffset = 0; modOffset < rts; modOffset++)-                {-                    idx = (temp2 + modOffset)*tupSize;-                    y[idx] = (y[idx]*twid) % q;-                }-            }-        }-    }-    else-    {-        hDim_t mprime = dim/p; // divides evenly-        hDim_t temp1 = rts*dim; // for use in computing [modified] tensorOffset-        for(hDim_t i0 = 1; i0 < mprime; i0++) // loops over i/p for i = 0..(dim-1), but we skip i0=0-        {-            for(hDim_t i1 = 1; i1 < p; i1++) // loops over i%p for i = 0..(dim-1), but we skip i1=0-            {-                hDim_t temp3 = rts*(i0*p+i1);-                hInt_t twid = ru[bitrev(pe,i0)*i1*rustride*tupSize];--                for(hDim_t blockOffset = 0; blockOffset < lts; blockOffset++)-                {-                    hDim_t temp2 = blockOffset*temp1 + temp3;-                    for(hDim_t modOffset = 0; modOffset < rts; modOffset++)-                    {-                        idx = (temp2 + modOffset)*tupSize;-                        y[idx] = (y[idx]*twid) % q;-                    }-                }-            }-        }-    }-}--//implied length of ru is rustride*p-//implied length of tempSpace is p, if p is not a special case-// temp is allowed to be NULL if p < DFTP_GENERIC_SIZE-void dftpRq (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, -             hDim_t p, hDim_t rustride, hInt_t* ru, hInt_t* tempSpace, hInt_t q)-{-    hDim_t tensorOffset;--    if(p == 2)-    {-        hDim_t temp1 = rts<<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;-                hInt_t u = y[tensorOffset*tupSize];-                hInt_t t = y[(tensorOffset+rts)*tupSize];-                y[tensorOffset*tupSize] = (u + t) % q;-                y[(tensorOffset+rts)*tupSize] = (u - t) % q;-            }-        }-    }-    else if(p == 3)-    {-        hInt_t ru1 = ru[rustride*tupSize];-        hInt_t ru2 = ru[(rustride<<1)*tupSize];-        hDim_t temp1 = rts*3;--        for(hDim_t blockOffset = 0; blockOffset < lts; blockOffset++)-        {-            hDim_t temp2 = blockOffset*temp1;-            for(hDim_t modOffset = 0; modOffset < rts; modOffset++)-            {-                tensorOffset = temp2 + modOffset;-                hInt_t y1, y2, y3;-                y1 = y[tensorOffset*tupSize];-                y2 = y[(tensorOffset+rts)*tupSize];-                y3 = y[(tensorOffset+(rts<<1))*tupSize];-                //q is <32 bits, so we can do 3 additions without overflow-                y[tensorOffset*tupSize]          = (y1 + y2 + y3) % q;-                y[(tensorOffset+rts)*tupSize]      = (y1 + ((ru1*y2) % q) + ((ru2*y3) % q)) % q;-                y[(tensorOffset+(rts<<1))*tupSize] = (y1 + ((ru2*y2) % q) + ((ru1*y3) % q)) % q;-            }   -        }--    }-    else if(p == 5)-    {-        hDim_t temp1 = rts*5;-        hInt_t ru1 = ru[rustride*tupSize];-        hInt_t ru2 = ru[(rustride<<1)*tupSize];-        hInt_t ru3 = ru[(rustride*3)*tupSize];-        hInt_t ru4 = ru[(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;-                hInt_t y1, y2, y3, y4, y5;-                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];-                y[tensorOffset*tupSize]          = (y1 + y2 + y3 + y4 + y5) % q;-                y[(tensorOffset+rts)*tupSize]      = (y1 + ((ru1*y2) % q) + ((ru2*y3) % q) + ((ru3*y4) % q) + ((ru4*y5) % q)) % q;-                y[(tensorOffset+(rts<<1))*tupSize] = (y1 + ((ru2*y2) % q) + ((ru4*y3) % q) + ((ru1*y4) % q) + ((ru3*y5) % q)) % q;-                y[(tensorOffset+rts*3)*tupSize]    = (y1 + ((ru3*y2) % q) + ((ru1*y3) % q) + ((ru4*y4) % q) + ((ru2*y5) % q)) % q;-                y[(tensorOffset+(rts<<2))*tupSize] = (y1 + ((ru4*y2) % q) + ((ru3*y3) % q) + ((ru2*y4) % q) + ((ru1*y5) % q)) % q;-            }-        }-    }-    else if(p == 7)-    {-        hDim_t temp1 = rts*7;-        hInt_t ru1 = ru[rustride*tupSize];-        hInt_t ru2 = ru[(rustride<<1)*tupSize];-        hInt_t ru3 = ru[(rustride*3)*tupSize];-        hInt_t ru4 = ru[(rustride<<2)*tupSize];-        hInt_t ru5 = ru[(rustride*5)*tupSize];-        hInt_t ru6 = ru[(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;-                hInt_t y1, y2, y3, y4, y5, y6, y7;-                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];-                y7 = y[(tensorOffset+rts*6)*tupSize];-                y[tensorOffset*tupSize]          = (y1 +     y2 +     y3 +     y4 +     y5 +     y6 +     y7) % q;-                y[(tensorOffset+rts)*tupSize]      = (y1 + ((ru1*y2) % q) + ((ru2*y3) % q) + ((ru3*y4) % q) + ((ru4*y5) % q) + ((ru5*y6) % q) + ((ru6*y7) % q)) % q;-                y[(tensorOffset+(rts<<1))*tupSize] = (y1 + ((ru2*y2) % q) + ((ru4*y3) % q) + ((ru6*y4) % q) + ((ru1*y5) % q) + ((ru3*y6) % q) + ((ru5*y7) % q)) % q;-                y[(tensorOffset+rts*3)*tupSize]    = (y1 + ((ru3*y2) % q) + ((ru6*y3) % q) + ((ru2*y4) % q) + ((ru5*y5) % q) + ((ru1*y6) % q) + ((ru4*y7) % q)) % q;-                y[(tensorOffset+(rts<<2))*tupSize] = (y1 + ((ru4*y2) % q) + ((ru1*y3) % q) + ((ru5*y4) % q) + ((ru2*y5) % q) + ((ru6*y6) % q) + ((ru3*y7) % q)) % q;-                y[(tensorOffset+rts*5)*tupSize]    = (y1 + ((ru5*y2) % q) + ((ru3*y3) % q) + ((ru1*y4) % q) + ((ru6*y5) % q) + ((ru4*y6) % q) + ((ru2*y7) % q)) % q;-                y[(tensorOffset+rts*6)*tupSize]    = (y1 + ((ru6*y2) % q) + ((ru5*y3) % q) + ((ru4*y4) % q) + ((ru3*y5) % q) + ((ru2*y6) % q) + ((ru1*y7) % q)) % q;-            }   -        }-    }-    else-    {-        hDim_t temp1 = rts*p;-        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(hDim_t row = 0; row < p; row++)-                {-                    hInt_t acc = 0;-                    //p is small (<< 30 bits), so we can do p additions of mod-q values without overflow-                    for(hDim_t col = 0; col < p; col++)-                    {-                        acc += ((y[(tensorOffset+col*rts)*tupSize]*ru[((col*row) % p)*rustride*tupSize])%q);-                    }-                    tempSpace[row] = acc % q;-                }-                -                for(hDim_t row = 0; row < p; row++)-                {-                    y[(tensorOffset+rts*row)*tupSize] = tempSpace[row];-                }-            }-        }-    }-}--void crtpRq (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, -             hDim_t p, hDim_t rustride, hInt_t* ru, hInt_t q)-{-    hDim_t tensorOffset;-    if(p == 2)-    {-        return;-    }-    else if(p == 3)-    {-        hDim_t temp1 = rts*2;-        hInt_t ru1 = ru[rustride*tupSize];-        hInt_t ru2 = ru[(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;-                hInt_t y1, y2;-                y1 = y[tensorOffset*tupSize];-                y2 = y[(tensorOffset+rts)*tupSize];-                y[tensorOffset*tupSize]     = (y1 + ((ru1*y2)%q)) % q;-                y[(tensorOffset+rts)*tupSize] = (y1 + ((ru2*y2)%q)) % q;-            }   -        }-    }-    else if(p == 5)-    {-        hDim_t temp1 = rts*4;-        hInt_t ru1 = ru[rustride*tupSize];-        hInt_t ru2 = ru[(rustride<<1)*tupSize];-        hInt_t ru3 = ru[(rustride*3)*tupSize];-        hInt_t ru4 = ru[(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;-                hInt_t y1, y2, y3, y4;-                y1 = y[tensorOffset*tupSize];-                y2 = y[(tensorOffset+rts)*tupSize];-                y3 = y[(tensorOffset+(rts<<1))*tupSize];-                y4 = y[(tensorOffset+3*rts)*tupSize];--                y[tensorOffset*tupSize]          = (y1 + ((ru1*y2) % q) + ((ru2*y3) % q) + ((ru3*y4) % q)) % q;-                y[(tensorOffset+rts)*tupSize]      = (y1 + ((ru2*y2) % q) + ((ru4*y3) % q) + ((ru1*y4) % q)) % q;-                y[(tensorOffset+(rts<<1))*tupSize] = (y1 + ((ru3*y2) % q) + ((ru1*y3) % q) + ((ru4*y4) % q)) % q;-                y[(tensorOffset+rts*3)*tupSize]    = (y1 + ((ru4*y2) % q) + ((ru3*y3) % q) + ((ru2*y4) % q)) % q;-            }   -        }-    }-    else if(p == 7)-    {-        hDim_t temp1 = rts*6;-        hInt_t ru1 = ru[rustride*tupSize];-        hInt_t ru2 = ru[(rustride<<1)*tupSize];-        hInt_t ru3 = ru[(rustride*3)*tupSize];-        hInt_t ru4 = ru[(rustride<<2)*tupSize];-        hInt_t ru5 = ru[(rustride*5)*tupSize];-        hInt_t ru6 = ru[(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;-                hInt_t y1, y2, y3, y4, y5, y6;-                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];-                y[tensorOffset*tupSize]          = (y1 + ((ru1*y2) % q) + ((ru2*y3) % q) + ((ru3*y4) % q) + ((ru4*y5) % q) + ((ru5*y6) % q)) % q;-                y[(tensorOffset+rts)*tupSize]      = (y1 + ((ru2*y2) % q) + ((ru4*y3) % q) + ((ru6*y4) % q) + ((ru1*y5) % q) + ((ru3*y6) % q)) % q;-                y[(tensorOffset+(rts<<1))*tupSize] = (y1 + ((ru3*y2) % q) + ((ru6*y3) % q) + ((ru2*y4) % q) + ((ru5*y5) % q) + ((ru1*y6) % q)) % q;-                y[(tensorOffset+rts*3)*tupSize]    = (y1 + ((ru4*y2) % q) + ((ru1*y3) % q) + ((ru5*y4) % q) + ((ru2*y5) % q) + ((ru6*y6) % q)) % q;-                y[(tensorOffset+(rts<<2))*tupSize] = (y1 + ((ru5*y2) % q) + ((ru3*y3) % q) + ((ru1*y4) % q) + ((ru6*y5) % q) + ((ru4*y6) % q)) % q;-                y[(tensorOffset+rts*5)*tupSize]    = (y1 + ((ru6*y2) % q) + ((ru5*y3) % q) + ((ru4*y4) % q) + ((ru3*y5) % q) + ((ru2*y6) % q)) % q;-            }-        }-    }-    else-    {-        hInt_t* tempSpace = (hInt_t*)malloc((p-1)*sizeof(hInt_t));-        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(hDim_t row = 1; row < p; row++)-                {-                    hInt_t acc = 0;-                    for(hDim_t col = 0; col < p-1; col++)-                    {-                        acc += ((y[(tensorOffset+col*rts)*tupSize]*ru[((col*row) % p)*rustride*tupSize]) % q);-                    }-                    tempSpace[row-1] = acc % q;-                }-                -                for(hDim_t row = 0; row < p-1; row++)-                {-                    y[(tensorOffset+rts*row)*tupSize] = tempSpace[row];-                }-            }-        }-        free(tempSpace);-    }-}--//takes inverse rus-void crtpinvRq (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, -                hDim_t p, hDim_t rustride, hInt_t* ruinv, hInt_t q)-{-    if(p ==2)-    {-        // need this case so that we can divide overall by mhat^(-1)-        return;-    }-    else-    {-        hDim_t tensorOffset,i;-        hInt_t* tempSpace = (hInt_t*)malloc((p-1)*sizeof(hInt_t));-        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++)-                {-                    hInt_t sum = 0;-                    int j;-                    for(j = 0; j < p-1; j++)-                    {-                        int ruIdx = ((j+1)*i) % p;-                        sum += ((y[(tensorOffset+j*rts)*tupSize] * ruinv[ruIdx*rustride*tupSize]) % q);-                    }-                    tempSpace[i] = sum % q;-                }--                hInt_t 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]) % q);-                }--                for(i = 0; i < p-1; i++)-                {-                    y[(tensorOffset+i*rts)*tupSize] = (tempSpace[i] - shift) % q; -                }-            }-        }-    }-}--void ppDFTRq (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, -              PrimeExponent pe, hDim_t rustride, hInt_t* ru, hInt_t q, hInt_t* temp)-{-    hDim_t p = pe.prime;-    hShort_t e = pe.exponent;-    -    if(e == 0)-    {-        return;-    }-    -    hDim_t primeRuStride = rustride*ipow(p,e-1);-    -    hShort_t i;-    -    hDim_t ltsScale = ipow(p,e-1);-    hDim_t rtsScale = 1;-    hDim_t twidRuStride = rustride;-    for(i = 0; i < e; i++)-    {-        hDim_t rtsDim = rts*rtsScale;-        dftpRq (y, tupSize, lts*ltsScale, rtsDim, p, primeRuStride, ru, temp, q);-        dftptwidRq (y, tupSize, lts, rtsDim, pe, ltsScale*p, twidRuStride, ru, q);-        -        ltsScale /= p;-        rtsScale *= p;-        twidRuStride *= p;-        pe.exponent -= 1;-    }-}--void ppDFTInvRq (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, -                 PrimeExponent pe, hDim_t rustride, hInt_t* ru, hInt_t q, hInt_t* temp)-{-    hDim_t p = pe.prime;-    hShort_t e = pe.exponent;-    -    if(e == 0)-    {-        return;-    }-    hDim_t primeRuStride = rustride*ipow(p,e-1);--    hShort_t i;-    -    hDim_t ltsScale = 1;-    hDim_t rtsScale = ipow(p,e-1);-    hDim_t twidRuStride = primeRuStride;-    pe.exponent = 1;-    for(i = 0; i < e; i++)-    {-        hDim_t rtsDim = rts*rtsScale;-        hDim_t ltsScaleP = ltsScale*p;-        dftptwidRq (y, tupSize, lts, rtsDim, pe, ltsScaleP, twidRuStride, ru, q);-        dftpRq (y, tupSize, lts*ltsScale, rtsDim, p, primeRuStride, ru, temp, q);-        -        ltsScale = ltsScaleP;-        rtsScale /= p;-        twidRuStride /= p;-        pe.exponent += 1;-    }-}--void ppcrtRq (void* y, hShort_t tupSize, hDim_t lts, hDim_t rts, -              PrimeExponent pe, void* ru, hInt_t* qs)-{-    hDim_t p = pe.prime;-    hDim_t e = pe.exponent;-#ifdef DEBUG_MODE-    ASSERT(e != 0);-#endif-    hDim_t mprime = ipow(p,e-1);-    -#ifdef DEBUG_MODE-    printf("lts is %" PRId32 "\trts is %" PRId32 "\n", lts, rts);-    printf("rus for p=%" PRId32 ", e=%" PRId16 "\t[", pe.prime, pe.exponent);-    hDim_t i;-    for(i = 0; i < ipow(p,e); i++) {-        printf("%" PRId64 ",", ((hInt_t*)ru)[i*tupSize+tupIdx]);-    }-    printf("]\n");-#endif--    hInt_t* temp = 0;-    if(p >= DFTP_GENERIC_SIZE)-    {-        temp = (hInt_t*)malloc(p*sizeof(hInt_t));-    }-    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {-        hInt_t* z = ((hInt_t*)y)+tupIdx;-        hInt_t q = qs[tupIdx];-        hInt_t* ruOffset = ((hInt_t*)ru)+tupIdx;-        crtpRq (z, tupSize, lts*mprime, rts, p, mprime, ruOffset, q);-        crtTwiddleRq (z, tupSize, lts, rts, pe, ruOffset, q);-        pe.exponent -= 1;-        ppDFTRq (z,  tupSize, lts, rts*(p-1), pe, p, ruOffset, q, temp);-        pe.exponent += 1;-    }--    if(p >= DFTP_GENERIC_SIZE)-    {-        free(temp);-    }-}--void ppcrtinvRq (void* y, hShort_t tupSize, hDim_t lts, hDim_t rts, -                 PrimeExponent pe, void* ru, hInt_t* qs)-{-    hDim_t p = pe.prime;-    hDim_t e = pe.exponent;-#ifdef DEBUG_MODE-    ASSERT(e != 0);-#endif-    hDim_t mprime = ipow(p,e-1);-#ifdef DEBUG_MODE-    printf("lts is %" PRId32 "\trts is %" PRId32 "\n", lts, rts);-    printf("rus for p=%" PRId32 ", e=%" PRId16 "\t[", pe.prime, pe.exponent);-    hDim_t i;-    for(i = 0; i < ipow(p,e); i++) {-        printf("%" PRId64 ",", ((hInt_t*)ru)[i*tupSize+tupIdx]);-    }-    printf("]\n");-#endif--    hInt_t* temp = 0;-    if(p >= DFTP_GENERIC_SIZE)-    {-        temp = (hInt_t*)malloc(p*sizeof(hInt_t));-    }-    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {-        hInt_t* z = ((hInt_t*)y)+tupIdx;-        hInt_t q = qs[tupIdx];-        hInt_t* ruOffset = ((hInt_t*)ru)+tupIdx;--        pe.exponent -= 1;-        ppDFTInvRq (z, tupSize, lts, rts*(p-1), pe, p, ruOffset, q, temp);-        pe.exponent += 1;-        crtTwiddleRq (z, tupSize, lts, rts, pe, ruOffset, q);-        crtpinvRq (z, tupSize, lts*mprime, rts, p, mprime, ruOffset, q);-    }--    if(p >= DFTP_GENERIC_SIZE)-    {-        free(temp);-    }-}--// EAC: Somebody who knows C/C++ should find a better way to handle pointers-to-pointers in a generic way-void tensorCRTRq (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t** ru, hInt_t* qs)-{-    hDim_t i;-#ifdef STATS-    struct timespec s1,s2,s3,s4,t1,t2,t3,t4;--    crtRqCtr++;--    clock_gettime(CLOCK_REALTIME, &s1);-    clock_gettime(CLOCK_MONOTONIC, &s2);-    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &s3);-    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &s4);-#endif-#ifdef DEBUG_MODE-    printf("\n\nEntered tensorCRTRq\ttotm=%" PRId32 "\tnumFacts=%" PRId16 "\ttupSize=%" PRId16 "\n[", totm, sizeOfPE,tupSize);-    for(i = 0; i < tupSize; i++) {-        printf("%" PRId64 ",", qs[i]);-    }-    printf("]\n[");-    for(i = 0; i < totm*tupSize; i++) {-        printf("%" PRId64 ",", y[i]);-    }-    printf("]\n[");-    for(i = 0; i < sizeOfPE; i++) {-        printf("(%" PRId32 ",%" PRId16 "),", peArr[i].prime, peArr[i].exponent);-    }-    printf("]\n");-#endif--    void** rus = (void**)malloc(sizeOfPE*sizeof(void*));-    for(i = 0; i < sizeOfPE; i++)-    {-        rus[i] = (void*) (ru[i]);-    }--  tensorFuserCRT (y, tupSize, ppcrtRq, totm, peArr, sizeOfPE, rus, qs);--    for(i = 0; i < tupSize; i++) {-        hInt_t q = qs[i];-      for(hDim_t j = 0; j < totm; j++)-      {-          if(y[j*tupSize+i]<0)-          {-              y[j*tupSize+i]+=q;-          }-#ifdef DEBUG_MODE-          if(y[j*tupSize+i]<0)-          {-              printf("TENSOR CRT^T INV\n");-          }-#endif-        }-  }--  free(rus);-#ifdef STATS-    clock_gettime(CLOCK_REALTIME, &t1);-    clock_gettime(CLOCK_MONOTONIC, &t2);-    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t3);-    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t4);--    crttime1 = tsAdd(crttime1, tsSubtract(t1,s1));-    crttime2 = tsAdd(crttime2, tsSubtract(t2,s2));-    crttime3 = tsAdd(crttime3, tsSubtract(t3,s3));-    crttime4 = tsAdd(crttime4, tsSubtract(t4,s4));-#endif-}--//takes inverse rus-void tensorCRTInvRq (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, -                    hInt_t** ruinv, hInt_t* mhatInv, hInt_t* qs)-{-  hDim_t i;-#ifdef STATS-    struct timespec s1,t1;-    crtInvRqCtr++;-    clock_gettime(CLOCK_REALTIME, &s1);-#endif-#ifdef DEBUG_MODE-    printf("\n\nEntered tensorCRTInvRq\ttotm=%" PRId32 "\tnumFacts=%" PRId16 "\ttupSize=%" PRId16 "\nqs[", totm, sizeOfPE, tupSize);-    for(i = 0; i < tupSize; i++) {-        printf("%" PRId64 ",", qs[i]);-    }-    printf("]\nmhatInv[");-    for(i = 0; i < tupSize; i++) {-        printf("%" PRId64 ",", mhatInv[i]);-    }-    printf("]\ny[");-    for(i = 0; i < totm*tupSize; i++) {-        printf("%" PRId64 ",", y[i]);-    }-    printf("]\npps[");-    for(i = 0; i < sizeOfPE; i++) {-        printf("(%" PRId32 ",%" PRId16 "),", peArr[i].prime, peArr[i].exponent);-    }-    printf("]\n");-#endif--  void** rus = (void**)malloc(sizeOfPE*sizeof(void*));-    for(i = 0; i < sizeOfPE; i++)-    {-        rus[i] = (void*) (ruinv[i]);-    }-  tensorFuserCRT (y, tupSize, ppcrtinvRq, totm, peArr, sizeOfPE, rus, qs);--    for (i = 0; i < tupSize; i++) {-        hInt_t q = qs[i];-      for (hDim_t j = 0; j < totm; j++)-      {-          y[j*tupSize+i] = (y[j*tupSize+i]*mhatInv[i])%q;-          if(y[j*tupSize+i] < 0)-          {-              y[j*tupSize+i] +=q;-          }-#ifdef DEBUG_MODE-          if(y[j*tupSize+i]<0)-          {-              printf("TENSOR CRT INV\n");-          }-#endif-        }-  }--  free(rus);-#ifdef STATS-    clock_gettime(CLOCK_REALTIME, &t1);-    crtInvRqTime = tsAdd(crtInvRqTime, tsSubtract(t1,s1));-#endif-}-----------------------------------------void crtTwiddleC (complex_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, PrimeExponent pe, complex_t* ru)-{-    hDim_t idx;-    hDim_t p = pe.prime;-    hShort_t e = pe.exponent;-    -#ifdef DEBUG_MODE-    ASSERT(e != 0);-#endif--    pe.exponent -= 1; // used for an argument to bitrev-    -    if(p == 2)-    {-        hDim_t mprime = 1<<(e-1);-        hDim_t blockDim = rts*mprime; // size of block in block diagonal tensor matrix--        for(hDim_t i0 = 1; i0 < mprime; i0++) // loops over i/(p-1) for i = 0..(m'-1), we can skip i0 = 0-        {-            hDim_t temp2 = i0*rts;-            complex_t twid = ru[bitrev(pe,i0)*tupSize];--            for(hDim_t blockIdx = 0; blockIdx < lts; blockIdx++)-            {-                hDim_t temp3 = blockIdx*blockDim + temp2;-                for(hDim_t modOffset = 0; modOffset < rts; modOffset++)-                {-                    idx = temp3 + modOffset;-                    CMPLX_IMUL(y[idx*tupSize],twid);-                }-            }-        }-    }-    else-    {-        hDim_t mprime = ipow(p,e-1);-        hDim_t blockDim = rts*(p-1)*mprime; // size of block in block diagonal tensor matrix--        for(hDim_t i0 = 1; i0 < mprime; i0++) // loops over i/(p-1) for i = 0..(m'-1), we can skip i0 = 0-        {-            hDim_t temp1 = i0*(p-1);-            for(hDim_t i1 = 0; i1 < (p-1); i1++) // loops over i%(p-1) for i = 0..(m'-1)-            {        -                hDim_t temp2 = (temp1+i1)*rts;-                complex_t twid = ru[bitrev(pe,i0)*(i1+1)*tupSize];--                for(hDim_t blockIdx = 0; blockIdx < lts; blockIdx++)-                {-                    hDim_t temp3 = blockIdx*blockDim + temp2;-                    for(hDim_t modOffset = 0; modOffset < rts; modOffset++)-                    {-                        idx = temp3 + modOffset;-                        CMPLX_IMUL(y[idx*tupSize],twid);-                    }-                }-            }-        }-    }-}-    -// dim is power of p-void dftptwidC (complex_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, PrimeExponent pe, hDim_t dim, hDim_t rustride, complex_t* ru)-{-    hDim_t idx;-    hDim_t p = pe.prime;-    pe.exponent -= 1; // used for an argument to bitrev-    -    if(p == 2)-    {-        hDim_t mprime = dim>>1; // divides evenly-        hDim_t temp1 = rts*dim; // for use in computing [modified] tensorOffset-        for(hDim_t i0 = 1; i0 < mprime; i0++) // loops over i/p for i = 0..(dim-1), but we skip i0=0-        {-            hDim_t temp3 = rts*(i0*p+1);-            complex_t twid = ru[bitrev(pe,i0)*rustride*tupSize];--            for(hDim_t blockOffset = 0; blockOffset < lts; blockOffset++)-            {-                hDim_t temp2 = blockOffset*temp1 + temp3;-                for(hDim_t modOffset = 0; modOffset < rts; modOffset++)-                {-                    idx = temp2 + modOffset;-                    CMPLX_IMUL(y[idx*tupSize],twid);-                }-            }-        }-    }-    else-    {-        hDim_t mprime = dim/p; // divides evenly-        hDim_t temp1 = rts*dim; // for use in computing [modified] tensorOffset-        for(hDim_t i0 = 1; i0 < mprime; i0++) // loops over i/p for i = 0..(dim-1), but we skip i0=0-        {-            for(hDim_t i1 = 1; i1 < p; i1++) // loops over i%p for i = 0..(dim-1), but we skip i1=0-            {-                hDim_t temp3 = rts*(i0*p+i1);-                complex_t twid = ru[bitrev(pe,i0)*i1*rustride*tupSize];--                for(hDim_t blockOffset = 0; blockOffset < lts; blockOffset++)-                {-                    hDim_t temp2 = blockOffset*temp1 + temp3;-                    for(hDim_t modOffset = 0; modOffset < rts; modOffset++)-                    {-                        idx = temp2 + modOffset;-                        CMPLX_IMUL(y[idx*tupSize],twid);-                    }-                }-            }-        }-    }-}--//implied length of ru is rustride*p-//implied length of tempSpace is p, if p is not a special case-void dftpC (complex_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p, hDim_t rustride, complex_t* ru, complex_t* tempSpace)-{-    hDim_t blockOffset, modOffset, tensorOffset;-    -    if(p == 2)-    {-        hDim_t temp1 = rts<<1;-        for(blockOffset = 0; blockOffset < lts; blockOffset++)-        {-            hDim_t temp2 = blockOffset*temp1;-            for(modOffset = 0; modOffset < rts; modOffset++)-            {-                tensorOffset = temp2 + modOffset;-                complex_t u = y[tensorOffset*tupSize];-                complex_t t = y[(tensorOffset+rts)*tupSize];-                y[tensorOffset*tupSize] = CMPLX_ADD(u,t);-                y[(tensorOffset+rts)*tupSize] = CMPLX_SUB(u,t);-            }-        }-    }-    else if(p == 3)-    {-        hDim_t temp1 = rts*3;-        complex_t ru1 = ru[rustride*tupSize];-        complex_t ru2 = ru[(rustride<<1)*tupSize];--        for(blockOffset = 0; blockOffset < lts; blockOffset++)-        {-            hDim_t temp2 = blockOffset*temp1;-            for(modOffset = 0; modOffset < rts; modOffset++)-            {-                tensorOffset = temp2 + modOffset;-                complex_t y1, y2, y3;-                y1 = y[tensorOffset*tupSize];-                y2 = y[(tensorOffset+rts)*tupSize];-                y3 = y[(tensorOffset+(rts<<1))*tupSize];-                y[tensorOffset*tupSize]            = CMPLX_ADD3(y1,               y2,                y3);-                y[(tensorOffset+rts)*tupSize]      = CMPLX_ADD3(y1, CMPLX_MUL(ru1,y2), CMPLX_MUL(ru2,y3));-                y[(tensorOffset+(rts<<1))*tupSize] = CMPLX_ADD3(y1, CMPLX_MUL(ru2,y2), CMPLX_MUL(ru1,y3));-            }   -        }-    }-    else if(p == 5)-    {-        hDim_t temp1 = rts*5;-        complex_t ru1 = ru[rustride*tupSize];-        complex_t ru2 = ru[(rustride<<1)*tupSize];-        complex_t ru3 = ru[(rustride*3)*tupSize];-        complex_t ru4 = ru[(rustride<<2)*tupSize];--        for(blockOffset = 0; blockOffset < lts; blockOffset++)-        {-            hDim_t temp2 = blockOffset*temp1;-            for(modOffset = 0; modOffset < rts; modOffset++)-            {-                tensorOffset = temp2 + modOffset;-                complex_t y1, y2, y3, y4, y5;-                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];-                y[tensorOffset*tupSize]          = CMPLX_ADD5(y1,               y2,                y3,                y4,                y5);-                y[(tensorOffset+rts)*tupSize]      = CMPLX_ADD5(y1, CMPLX_MUL(ru1,y2), CMPLX_MUL(ru2,y3), CMPLX_MUL(ru3,y4), CMPLX_MUL(ru4,y5));-                y[(tensorOffset+(rts<<1))*tupSize] = CMPLX_ADD5(y1, CMPLX_MUL(ru2,y2), CMPLX_MUL(ru4,y3), CMPLX_MUL(ru1,y4), CMPLX_MUL(ru3,y5));-                y[(tensorOffset+rts*3)*tupSize]    = CMPLX_ADD5(y1, CMPLX_MUL(ru3,y2), CMPLX_MUL(ru1,y3), CMPLX_MUL(ru4,y4), CMPLX_MUL(ru2,y5));-                y[(tensorOffset+(rts<<2))*tupSize] = CMPLX_ADD5(y1, CMPLX_MUL(ru4,y2), CMPLX_MUL(ru3,y3), CMPLX_MUL(ru2,y4), CMPLX_MUL(ru1,y5));-            }   -        }-    }-    else if(p == 7)-    {-        hDim_t temp1 = rts*7;-        complex_t ru1 = ru[rustride*tupSize];-        complex_t ru2 = ru[(rustride<<1)*tupSize];-        complex_t ru3 = ru[(rustride*3)*tupSize];-        complex_t ru4 = ru[(rustride<<2)*tupSize];-        complex_t ru5 = ru[(rustride*5)*tupSize];-        complex_t ru6 = ru[(rustride*6)*tupSize];--        for(blockOffset = 0; blockOffset < lts; blockOffset++)-        {-            hDim_t temp2 = blockOffset*temp1;-            for(modOffset = 0; modOffset < rts; modOffset++)-            {-                tensorOffset = temp2 + modOffset;-                complex_t y1, y2, y3, y4, y5, y6, y7;-                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];-                y7 = y[(tensorOffset+rts*6)*tupSize];-                y[tensorOffset*tupSize]          = CMPLX_ADD7(y1,               y2,                y3,                y4,                y5,                y6,                y7);-                y[(tensorOffset+rts)*tupSize]      = CMPLX_ADD7(y1, CMPLX_MUL(ru1,y2), CMPLX_MUL(ru2,y3), CMPLX_MUL(ru3,y4), CMPLX_MUL(ru4,y5), CMPLX_MUL(ru5,y6), CMPLX_MUL(ru6,y7));-                y[(tensorOffset+(rts<<1))*tupSize] = CMPLX_ADD7(y1, CMPLX_MUL(ru2,y2), CMPLX_MUL(ru4,y3), CMPLX_MUL(ru6,y4), CMPLX_MUL(ru1,y5), CMPLX_MUL(ru3,y6), CMPLX_MUL(ru5,y7));-                y[(tensorOffset+rts*3)*tupSize]    = CMPLX_ADD7(y1, CMPLX_MUL(ru3,y2), CMPLX_MUL(ru6,y3), CMPLX_MUL(ru2,y4), CMPLX_MUL(ru5,y5), CMPLX_MUL(ru1,y6), CMPLX_MUL(ru4,y7));-                y[(tensorOffset+(rts<<2))*tupSize] = CMPLX_ADD7(y1, CMPLX_MUL(ru4,y2), CMPLX_MUL(ru1,y3), CMPLX_MUL(ru5,y4), CMPLX_MUL(ru2,y5), CMPLX_MUL(ru6,y6), CMPLX_MUL(ru3,y7));-                y[(tensorOffset+rts*5)*tupSize]    = CMPLX_ADD7(y1, CMPLX_MUL(ru5,y2), CMPLX_MUL(ru3,y3), CMPLX_MUL(ru1,y4), CMPLX_MUL(ru6,y5), CMPLX_MUL(ru4,y6), CMPLX_MUL(ru2,y7));-                y[(tensorOffset+rts*6)*tupSize]    = CMPLX_ADD7(y1, CMPLX_MUL(ru6,y2), CMPLX_MUL(ru5,y3), CMPLX_MUL(ru4,y4), CMPLX_MUL(ru3,y5), CMPLX_MUL(ru2,y6), CMPLX_MUL(ru1,y7));-            }   -        }-    }-    else-    {-        hDim_t temp1 = rts*p;-        for(blockOffset = 0; blockOffset < lts; blockOffset++)-        {-            hDim_t temp2 = blockOffset*temp1;-            for(modOffset = 0; modOffset < rts; modOffset++)-            {-                tensorOffset = temp2 + modOffset;-                hDim_t row, col;-                -                for(row = 0; row < p; row++)-                {-                    complex_t acc = ((complex_t){0,0});-                    for(col = 0; col < p; col++)-                    {-                        CMPLX_IADD(acc, CMPLX_MUL(y[(tensorOffset+col*rts)*tupSize], ru[((col*row) % p)*rustride*tupSize]));-                    }-                    tempSpace[row] = acc;-                }-                -                for(row = 0; row < p; row++)-                {-                    y[(tensorOffset+rts*row)*tupSize] = tempSpace[row];   -                }-            }-        }-    }-}--void crtpC (complex_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p, hDim_t rustride, complex_t* ru)-{-    hDim_t blockOffset, modOffset, tensorOffset;-    -    if(p == 2)-    {-        return;-    }-    else if(p == 3)-    {-        hDim_t temp1 = rts*2;-        complex_t ru1 = ru[rustride*tupSize];-        complex_t ru2 = ru[(rustride<<1)*tupSize];--        for(blockOffset = 0; blockOffset < lts; blockOffset++)-        {-            hDim_t temp2 = blockOffset*temp1;-            for(modOffset = 0; modOffset < rts; modOffset++)-            {-                tensorOffset = temp2 + modOffset;-                complex_t y1, y2;-                y1 = y[tensorOffset*tupSize];-                y2 = y[(tensorOffset+rts)*tupSize];-                y[tensorOffset*tupSize]     = CMPLX_ADD(y1, CMPLX_MUL(ru1,y2));-                y[(tensorOffset+rts)*tupSize] = CMPLX_ADD(y1, CMPLX_MUL(ru2,y2));-            }   -        }-    }-    else if(p == 5)-    {-        hDim_t temp1 = rts*4;-        complex_t ru1 = ru[rustride*tupSize];-        complex_t ru2 = ru[(rustride<<1)*tupSize];-        complex_t ru3 = ru[(rustride*3)*tupSize];-        complex_t ru4 = ru[(rustride<<2)*tupSize];--        for(blockOffset = 0; blockOffset < lts; blockOffset++)-        {-            hDim_t temp2 = blockOffset*temp1;-            for(modOffset = 0; modOffset < rts; modOffset++)-            {-                tensorOffset = temp2 + modOffset;-                complex_t y1, y2, y3, y4;-                y1 = y[tensorOffset*tupSize];-                y2 = y[(tensorOffset+rts)*tupSize];-                y3 = y[(tensorOffset+(rts<<1))*tupSize];-                y4 = y[(tensorOffset+3*rts)*tupSize];-                y[tensorOffset*tupSize]          = CMPLX_ADD4(y1, CMPLX_MUL(ru1,y2), CMPLX_MUL(ru2,y3), CMPLX_MUL(ru3,y4));-                y[(tensorOffset+rts)*tupSize]      = CMPLX_ADD4(y1, CMPLX_MUL(ru2,y2), CMPLX_MUL(ru4,y3), CMPLX_MUL(ru1,y4));-                y[(tensorOffset+(rts<<1))*tupSize] = CMPLX_ADD4(y1, CMPLX_MUL(ru3,y2), CMPLX_MUL(ru1,y3), CMPLX_MUL(ru4,y4));-                y[(tensorOffset+rts*3)*tupSize]    = CMPLX_ADD4(y1, CMPLX_MUL(ru4,y2), CMPLX_MUL(ru3,y3), CMPLX_MUL(ru2,y4));-            }   -        }-    }-    else if(p == 7)-    {-        hDim_t temp1 = rts*6;-        complex_t ru1 = ru[rustride*tupSize];-        complex_t ru2 = ru[(rustride<<1)*tupSize];-        complex_t ru3 = ru[(rustride*3)*tupSize];-        complex_t ru4 = ru[(rustride<<2)*tupSize];-        complex_t ru5 = ru[(rustride*5)*tupSize];-        complex_t ru6 = ru[(rustride*6)*tupSize];--        for(blockOffset = 0; blockOffset < lts; blockOffset++)-        {-            hDim_t temp2 = blockOffset*temp1;-            for(modOffset = 0; modOffset < rts; modOffset++)-            {-                tensorOffset = temp2 + modOffset;-                complex_t y1, y2, y3, y4, y5, y6;-                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];-                y[tensorOffset*tupSize]          = CMPLX_ADD6(y1, CMPLX_MUL(ru1,y2), CMPLX_MUL(ru2,y3), CMPLX_MUL(ru3,y4), CMPLX_MUL(ru4,y5), CMPLX_MUL(ru5,y6));-                y[(tensorOffset+rts)*tupSize]      = CMPLX_ADD6(y1, CMPLX_MUL(ru2,y2), CMPLX_MUL(ru4,y3), CMPLX_MUL(ru6,y4), CMPLX_MUL(ru1,y5), CMPLX_MUL(ru3,y6));-                y[(tensorOffset+(rts<<1))*tupSize] = CMPLX_ADD6(y1, CMPLX_MUL(ru3,y2), CMPLX_MUL(ru6,y3), CMPLX_MUL(ru2,y4), CMPLX_MUL(ru5,y5), CMPLX_MUL(ru1,y6));-                y[(tensorOffset+rts*3)*tupSize]    = CMPLX_ADD6(y1, CMPLX_MUL(ru4,y2), CMPLX_MUL(ru1,y3), CMPLX_MUL(ru5,y4), CMPLX_MUL(ru2,y5), CMPLX_MUL(ru6,y6));-                y[(tensorOffset+(rts<<2))*tupSize] = CMPLX_ADD6(y1, CMPLX_MUL(ru5,y2), CMPLX_MUL(ru3,y3), CMPLX_MUL(ru1,y4), CMPLX_MUL(ru6,y5), CMPLX_MUL(ru4,y6));-                y[(tensorOffset+rts*5)*tupSize]    = CMPLX_ADD6(y1, CMPLX_MUL(ru6,y2), CMPLX_MUL(ru5,y3), CMPLX_MUL(ru4,y4), CMPLX_MUL(ru3,y5), CMPLX_MUL(ru2,y6));-            }   -        }-    }-    else-    {-        complex_t* tempSpace = (complex_t*)malloc((p-1)*sizeof(complex_t));-        hDim_t temp1 = rts*(p-1);-        for(blockOffset = 0; blockOffset < lts; blockOffset++)-        {-            hDim_t temp2 = blockOffset*temp1;-            for(modOffset = 0; modOffset < rts; modOffset++)-            {-                tensorOffset = temp2 + modOffset;-                hDim_t row, col;-                -                for(row = 1; row < p; row++)-                {-                    complex_t acc = ((complex_t){0,0});-                    for(col = 0; col < p-1; col++)-                    {-                        CMPLX_IADD(acc, CMPLX_MUL(y[(tensorOffset+col*rts)*tupSize], ru[((col*row) % p)*rustride*tupSize]));-                    }-                    tempSpace[row-1] = acc;-                }-                -                for(row = 0; row < p-1; row++)-                {-                    y[(tensorOffset+rts*row)*tupSize] = tempSpace[row];   -                }-            }-        }-        free(tempSpace);-    }-}--//takes inverse rus-void crtpinvC (complex_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p, hDim_t rustride, complex_t* ruinv)-{-    if(p ==2)-    {-        // need this case so that we can divide overall by mhat^(-1)-        return;-    }-    else-    {-        hDim_t tensorOffset,i;-        complex_t* tempSpace = (complex_t*)malloc(p*sizeof(complex_t));-        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++)-                {-                    complex_t sum = ((complex_t){0,0});-                    int j;-                    for(j = 0; j < p-1; j++)-                    {-                        int ruIdx = (((j+1)*i) % p)*rustride;-                        CMPLX_IADD(sum, CMPLX_MUL(y[(tensorOffset+j*rts)*tupSize],ruinv[ruIdx*tupSize]));-                    }-                    tempSpace[i] = sum;-                }--                complex_t shift = ((complex_t){0,0});-                for(i = 0; i < p-1; i++)-                {-                    // we were given the inverse rus, so we need to negate the indices-                    int ruIdx = p-(i+1);-                    CMPLX_IADD(shift, CMPLX_MUL(y[(tensorOffset+i*rts)*tupSize], ruinv[rustride*ruIdx*tupSize]));-                }--                for(i = 0; i < p-1; i++)-                {-                    y[(tensorOffset+i*rts)*tupSize] = CMPLX_SUB(tempSpace[i], shift); -                }-            }-        }-    }-}--void ppDFTC (complex_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, PrimeExponent pe, hDim_t rustride, complex_t* ru, complex_t* temp)-{-    hDim_t p = pe.prime;-    hShort_t e = pe.exponent;-    -    if(e == 0)-    {-        return;-    }-    -    hDim_t primeRuStride = rustride*ipow(p,e-1);    --    hShort_t i;-    -    hDim_t ltsScale = ipow(p,e-1);-    hDim_t rtsScale = 1;-    hDim_t twidRuStride = rustride;-    for(i = 0; i < e; i++)-    {-        hDim_t rtsDim = rts*rtsScale;-        dftpC (y, tupSize, lts*ltsScale, rtsDim, p, primeRuStride, ru, temp);-        dftptwidC (y, tupSize, lts, rtsDim, pe, ltsScale*p, twidRuStride, ru);-        -        ltsScale /= p;-        rtsScale *= p;-        twidRuStride *= p;-        pe.exponent -= 1;-    }-}--void ppDFTInvC (complex_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, PrimeExponent pe, hDim_t rustride, complex_t* ru, complex_t* temp)-{--    hDim_t p = pe.prime;-    hShort_t e = pe.exponent;-    -    if(e == 0)-    {-        return;-    }-    hDim_t primeRuStride = rustride*ipow(p,e-1);--    hShort_t i;-    -    hDim_t ltsScale = 1;-    hDim_t rtsScale = ipow(p,e-1);-    hDim_t twidRuStride = primeRuStride;-    pe.exponent = 1;-    for(i = 0; i < e; i++)-    {-        hDim_t rtsDim = rts*rtsScale;-        hDim_t ltsScaleP = ltsScale*p;-        dftptwidC (y, tupSize, lts, rtsDim, pe, ltsScaleP, twidRuStride, ru);-        dftpC (y, tupSize, lts*ltsScale, rtsDim, p, primeRuStride, ru, temp);-        -        ltsScale = ltsScaleP;-        rtsScale /= p;-        twidRuStride /= p;-        pe.exponent += 1;-    }-}--void ppcrtC (void* y, hShort_t tupSize, hDim_t lts, hDim_t rts, PrimeExponent pe, void* ru, hInt_t* qs)-{-    hDim_t p = pe.prime;-    hDim_t e = pe.exponent;-#ifdef DEBUG_MODE-    ASSERT(e != 0);-#endif-    hDim_t mprime = ipow(p,e-1);--#ifdef DEBUG_MODE-    printf("rus for p=%" PRId32 ", e=%" PRId16 "\t[", pe.prime, pe.exponent);-    hDim_t i;-    for(i = 0; i < ipow(p,e); i++) {-        printf("(%f,%f),", ((complex_t*)ru)[i].real, ((complex_t*)ru)[i].imag);-    }-    printf("]\n");-#endif--    complex_t* temp = 0;-    if(p >= DFTP_GENERIC_SIZE)-    {-        temp = (complex_t*)malloc(p*sizeof(complex_t));-    }--    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {-        complex_t* z = ((complex_t*)y)+tupIdx;-        complex_t* ruOffset = ((complex_t*)ru)+tupIdx;-        crtpC (z, tupSize, lts*mprime, rts, p, mprime, ruOffset);-        crtTwiddleC (z, tupSize, lts, rts, pe, ruOffset);-        pe.exponent -= 1;-        ppDFTC (z, tupSize, lts, rts*(p-1), pe, p, ruOffset, temp);-        pe.exponent += 1;-    }--    if(p >= DFTP_GENERIC_SIZE)-    {-        free(temp);-    }-}--void ppcrtinvC (void* y, hShort_t tupSize, hDim_t lts, hDim_t rts, PrimeExponent pe, void* ru, hInt_t* qs)-{-    hDim_t p = pe.prime;-    hDim_t e = pe.exponent;-#ifdef DEBUG_MODE-    ASSERT(e != 0);-#endif-    hDim_t mprime = ipow(p,e-1);-    -    complex_t* temp = 0;-    if(p >= DFTP_GENERIC_SIZE)-    {-        temp = (complex_t*)malloc(p*sizeof(complex_t));-    }--    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {-        complex_t* z = ((complex_t*)y)+tupIdx;-        complex_t* ruOffset = ((complex_t*)ru)+tupIdx;-        pe.exponent -= 1;-        ppDFTInvC (z, tupSize, lts, rts*(p-1), pe, p, ruOffset, temp);-        pe.exponent += 1;-        crtTwiddleC (z, tupSize, lts, rts, pe, ruOffset);-        crtpinvC (z, tupSize, lts*mprime, rts, p, mprime, ruOffset);-    }--    if(p >= DFTP_GENERIC_SIZE)-    {-        free(temp);-    }-}--void tensorCRTC (hShort_t tupSize, complex_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, complex_t** ru)-{-#ifdef STATS-    struct timespec s1,t1;-    crtCCtr++;-    clock_gettime(CLOCK_REALTIME, &s1);-#endif-#ifdef DEBUG_MODE-    printf("\n\nEntered tensorCRTC\ttotm=%" PRId32 "\tnumFacts=%" PRId16 "\n[", totm, sizeOfPE);-    hDim_t j;-    for(j = 0; j < totm; j++) {-        printf("(%f,%f),", y[j].real, y[j].imag);-    }-    printf("]\n[");-    for(j = 0; j < sizeOfPE; j++) {-        printf("(%" PRId32 ",%" PRId16 "),", peArr[j].prime, peArr[j].exponent);-    }-    printf("]\n");-#endif-    void** rus = (void**)malloc(sizeOfPE*sizeof(void*));-    hShort_t i;-    for(i = 0; i < sizeOfPE; i++)-    {-        rus[i] = (void*) (ru[i]);-    }-  tensorFuserCRT (y, tupSize, ppcrtC, totm, peArr, sizeOfPE, rus, (hInt_t*)0);-  free(rus);-#ifdef STATS-    clock_gettime(CLOCK_REALTIME, &t1);-    crtCTime = tsAdd(crtCTime, tsSubtract(t1,s1));-#endif-}--//takes inverse rus-void tensorCRTInvC (hShort_t tupSize, complex_t* y, hDim_t totm, PrimeExponent* peArr, -                    hShort_t sizeOfPE, complex_t** ruinv, complex_t* mhatInv)-{-#ifdef STATS-    struct timespec s1,t1;-    crtInvCCtr++;-    clock_gettime(CLOCK_REALTIME, &s1);-#endif-  hDim_t i;-  -  void** rus = (void**)malloc(sizeOfPE*sizeof(void*));-    for(i = 0; i < sizeOfPE; i++)-    {-        rus[i] = (void*) (ruinv[i]);-    }-  -  tensorFuserCRT (y, tupSize, ppcrtinvC, totm, peArr, sizeOfPE, rus, (hInt_t*)0);--    for (i = 0; i < tupSize; i++) {-      for (hDim_t j = 0; j < totm; j++)-      {-          CMPLX_IMUL(y[j*tupSize+i], mhatInv[i]);-      }-    }-  -  free(rus);-#ifdef STATS-    clock_gettime(CLOCK_REALTIME, &t1);-    crtInvCTime = tsAdd(crtInvCTime, tsSubtract(t1,s1));-#endif-}
+ Crypto/Lol/Cyclotomic/Tensor/CTensor/crt.cpp view
@@ -0,0 +1,515 @@+#include "types.h"+#include "tensor.h"+#include "common.h"++// there should be a special cases that do NOT require temp space to be allocated for all primes *smaller* than DFTP_GENERIC_SIZE+#define DFTP_GENERIC_SIZE 11++hDim_t bitrev (PrimeExponent pe, hDim_t j) {+  hShort_t e;+  hDim_t p = pe.prime;+  hDim_t tempj = j;+  hDim_t acc = 0;++  for(e = pe.exponent-1; e >= 0; e--) {+    div_t qr = div(tempj,p);+    acc += qr.rem * ipow(p,e);+    tempj = qr.quot;+  }+  return acc;+}++template <typename ring> void crtTwiddle (ring* y, hShort_t tupSize, hDim_t lts, hDim_t rts,+                   PrimeExponent pe, ring* ru)+{+  hDim_t p = pe.prime;+  hShort_t e = pe.exponent;++  pe.exponent -= 1; // used for an argument to bitrev++  if(p == 2) {+    hDim_t mprime = 1<<(e-1);+    hDim_t blockDim = rts*mprime; // size of block in block diagonal tensor matrix++    for(hDim_t i0 = 1; i0 < mprime; i0++) { // loops over i/(p-1) for i = 0..(m'-1), we can skip i0 = 0+      hDim_t temp2 = i0*rts;+      ring twid = ru[bitrev(pe, i0)*tupSize];++      for(hDim_t blockIdx = 0; blockIdx < lts; blockIdx++) {+        hDim_t temp3 = blockIdx*blockDim + temp2;+        for(hDim_t modOffset = 0; modOffset < rts; modOffset++) {+          hDim_t idx = (temp3 + modOffset)*tupSize;+          y[idx] *= twid;+        }+      }+    }+  }+  else { // This loop is faster, probably due to the division in the loop above.+  // cilk also slows it down+    hDim_t mprime = ipow(p,e-1);+    hDim_t blockDim = rts*(p-1)*mprime; // size of block in block diagonal tensor matrix++    for(hDim_t i0 = 1; i0 < mprime; i0++) { // loops over i/(p-1) for i = 0..(m'-1), we can skip i0 = 0+      hDim_t temp1 = i0*(p-1);+      for(hDim_t i1 = 0; i1 < (p-1); i1++) { // loops over i%(p-1) for i = 0..(m'-1)+        hDim_t temp2 = (temp1+i1)*rts;+        ring twid = ru[bitrev(pe, i0)*(i1+1)*tupSize];++        for(hDim_t blockIdx = 0; blockIdx < lts; blockIdx++) {+          hDim_t temp3 = blockIdx*blockDim + temp2;+          for(hDim_t modOffset = 0; modOffset < rts; modOffset++) {+            hDim_t idx = (temp3 + modOffset)*tupSize;+            y[idx] *= twid;+          }+        }+      }+    }+  }+}++// dim is power of p+template <typename ring> void dftTwiddle (ring* y, hShort_t tupSize, hDim_t lts, hDim_t rts,+                 PrimeExponent pe, hDim_t dim, hDim_t rustride, ring* ru)+{+  hDim_t idx;+  hDim_t p = pe.prime;++  pe.exponent -= 1; // used for an argument to bitrev++  if(p == 2) {+    hDim_t mprime = dim>>1; // divides evenly+    hDim_t temp1 = rts*dim; // for use in computing [modified] tensorOffset+    for(hDim_t i0 = 1; i0 < mprime; i0++) { // loops over i/p for i = 0..(dim-1), but we skip i0=0+      hDim_t temp3 = rts*(i0*p+1);+      ring twid = ru[bitrev(pe,i0)*rustride*tupSize];++      for(hDim_t blockOffset = 0; blockOffset < lts; blockOffset++) {+        hDim_t temp2 = blockOffset*temp1 + temp3;+        for(hDim_t modOffset = 0; modOffset < rts; modOffset++) {+          idx = (temp2 + modOffset)*tupSize;+          y[idx] *= twid;+        }+      }+    }+  }+  else {+    hDim_t mprime = dim/p; // divides evenly+    hDim_t temp1 = rts*dim; // for use in computing [modified] tensorOffset+    for(hDim_t i0 = 1; i0 < mprime; i0++) { // loops over i/p for i = 0..(dim-1), but we skip i0=0+      for(hDim_t i1 = 1; i1 < p; i1++) { // loops over i%p for i = 0..(dim-1), but we skip i1=0+        hDim_t temp3 = rts*(i0*p+i1);+        ring twid = ru[bitrev(pe,i0)*i1*rustride*tupSize];++        for(hDim_t blockOffset = 0; blockOffset < lts; blockOffset++) {+          hDim_t temp2 = blockOffset*temp1 + temp3;+          for(hDim_t modOffset = 0; modOffset < rts; modOffset++) {+            idx = (temp2 + modOffset)*tupSize;+            y[idx] *= twid;+          }+        }+      }+    }+  }+}++//implied length of ru is rustride*p+//implied length of tempSpace is p, if p is not a special case+// temp is allowed to be NULL if p < DFTP_GENERIC_SIZE+template <typename ring> void dftp (ring* y, hShort_t tupSize, hDim_t lts, hDim_t rts,+             hDim_t p, hDim_t rustride, ring* ru, ring* tempSpace)+{+  hDim_t tensorOffset;++  if(p == 2) {+    hDim_t temp1 = rts<<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;+        ring u = y[tensorOffset*tupSize];+        ring t = y[(tensorOffset+rts)*tupSize];+        y[tensorOffset*tupSize] = u + t;+        y[(tensorOffset+rts)*tupSize] = u - t;+      }+    }+  }+  else if(p == 3) {+    ring ru1 = ru[rustride*tupSize];+    ring ru2 = ru[(rustride<<1)*tupSize];+    hDim_t temp1 = rts*3;++    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;+        y1 = y[tensorOffset*tupSize];+        y2 = y[(tensorOffset+rts)*tupSize];+        y3 = y[(tensorOffset+(rts<<1))*tupSize];+        //q is <32 bits, so we can do 3 additions without overflow+        y[tensorOffset*tupSize]           += (y2 + y3);+        y[(tensorOffset+rts)*tupSize]      = y1 + (ru1*y2) + (ru2*y3);+        y[(tensorOffset+(rts<<1))*tupSize] = y1 + (ru2*y2) + (ru1*y3);+      }+    }+  }+  else if(p == 5) {+    hDim_t temp1 = rts*5;+    ring ru1 = ru[rustride*tupSize];+    ring ru2 = ru[(rustride<<1)*tupSize];+    ring ru3 = ru[(rustride*3)*tupSize];+    ring ru4 = ru[(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, y5;+          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];+          y[tensorOffset*tupSize]           += y2 + y3 + y4 + y5;+          y[(tensorOffset+rts)*tupSize]      = y1 + (ru1*y2) + (ru2*y3) + (ru3*y4) + (ru4*y5);+          y[(tensorOffset+(rts<<1))*tupSize] = y1 + (ru2*y2) + (ru4*y3) + (ru1*y4) + (ru3*y5);+          y[(tensorOffset+rts*3)*tupSize]    = y1 + (ru3*y2) + (ru1*y3) + (ru4*y4) + (ru2*y5);+          y[(tensorOffset+(rts<<2))*tupSize] = y1 + (ru4*y2) + (ru3*y3) + (ru2*y4) + (ru1*y5);+      }+    }+  }+  else if(p == 7) {+    hDim_t temp1 = rts*7;+    ring ru1 = ru[rustride*tupSize];+    ring ru2 = ru[(rustride<<1)*tupSize];+    ring ru3 = ru[(rustride*3)*tupSize];+    ring ru4 = ru[(rustride<<2)*tupSize];+    ring ru5 = ru[(rustride*5)*tupSize];+    ring ru6 = ru[(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, y7;+        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];+        y7 = y[(tensorOffset+rts*6)*tupSize];+        y[tensorOffset*tupSize]           += y2 +     y3 +     y4 +     y5 +     y6 +     y7;+        y[(tensorOffset+rts)*tupSize]      = y1 + (ru1*y2) + (ru2*y3) + (ru3*y4) + (ru4*y5) + (ru5*y6) + (ru6*y7);+        y[(tensorOffset+(rts<<1))*tupSize] = y1 + (ru2*y2) + (ru4*y3) + (ru6*y4) + (ru1*y5) + (ru3*y6) + (ru5*y7);+        y[(tensorOffset+rts*3)*tupSize]    = y1 + (ru3*y2) + (ru6*y3) + (ru2*y4) + (ru5*y5) + (ru1*y6) + (ru4*y7);+        y[(tensorOffset+(rts<<2))*tupSize] = y1 + (ru4*y2) + (ru1*y3) + (ru5*y4) + (ru2*y5) + (ru6*y6) + (ru3*y7);+        y[(tensorOffset+rts*5)*tupSize]    = y1 + (ru5*y2) + (ru3*y3) + (ru1*y4) + (ru6*y5) + (ru4*y6) + (ru2*y7);+        y[(tensorOffset+rts*6)*tupSize]    = y1 + (ru6*y2) + (ru5*y3) + (ru4*y4) + (ru3*y5) + (ru2*y6) + (ru1*y7);+      }+    }+  }+  else {+    hDim_t temp1 = rts*p;+    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(hDim_t row = 0; row < p; row++) {+          tempSpace[row] = 0;+          //p is small (<< 30 bits), so we can do p additions of mod-q values without overflow+          for(hDim_t col = 0; col < p; col++) {+            tempSpace[row] += (y[(tensorOffset+col*rts)*tupSize]*ru[((col*row) % p)*rustride*tupSize]);+          }+        }++        for(hDim_t row = 0; row < p; row++) {+          y[(tensorOffset+rts*row)*tupSize] = tempSpace[row];+        }+      }+    }+  }+}++template <typename ring> void crtp (ring* y, hShort_t tupSize, hDim_t lts, hDim_t rts,+             hDim_t p, hDim_t rustride, ring* ru)+{+  hDim_t tensorOffset;+  if(p == 2) {+      return;+  }+  else if(p == 3) {+    hDim_t temp1 = rts*2;+    ring ru1 = ru[rustride*tupSize];+    ring ru2 = ru[(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;+        y1 = y[tensorOffset*tupSize];+        y2 = y[(tensorOffset+rts)*tupSize];+        y[tensorOffset*tupSize]      += (ru1*y2);+        y[(tensorOffset+rts)*tupSize] = y1 + (ru2*y2);+      }+    }+  }+  else if(p == 5) {+    hDim_t temp1 = rts*4;+    ring ru1 = ru[rustride*tupSize];+    ring ru2 = ru[(rustride<<1)*tupSize];+    ring ru3 = ru[(rustride*3)*tupSize];+    ring ru4 = ru[(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;+        y1 = y[tensorOffset*tupSize];+        y2 = y[(tensorOffset+rts)*tupSize];+        y3 = y[(tensorOffset+(rts<<1))*tupSize];+        y4 = y[(tensorOffset+3*rts)*tupSize];++        y[tensorOffset*tupSize]           += ((ru1*y2) + (ru2*y3) + (ru3*y4));+        y[(tensorOffset+rts)*tupSize]      = y1 + (ru2*y2) + (ru4*y3) + (ru1*y4);+        y[(tensorOffset+(rts<<1))*tupSize] = y1 + (ru3*y2) + (ru1*y3) + (ru4*y4);+        y[(tensorOffset+rts*3)*tupSize]    = y1 + (ru4*y2) + (ru3*y3) + (ru2*y4);+      }+    }+  }+  else if(p == 7) {+    hDim_t temp1 = rts*6;+    ring ru1 = ru[rustride*tupSize];+    ring ru2 = ru[(rustride<<1)*tupSize];+    ring ru3 = ru[(rustride*3)*tupSize];+    ring ru4 = ru[(rustride<<2)*tupSize];+    ring ru5 = ru[(rustride*5)*tupSize];+    ring ru6 = ru[(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;+        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];+        y[tensorOffset*tupSize]           += ((ru1*y2) + (ru2*y3) + (ru3*y4) + (ru4*y5) + (ru5*y6));+        y[(tensorOffset+rts)*tupSize]      = y1 + (ru2*y2) + (ru4*y3) + (ru6*y4) + (ru1*y5) + (ru3*y6);+        y[(tensorOffset+(rts<<1))*tupSize] = y1 + (ru3*y2) + (ru6*y3) + (ru2*y4) + (ru5*y5) + (ru1*y6);+        y[(tensorOffset+rts*3)*tupSize]    = y1 + (ru4*y2) + (ru1*y3) + (ru5*y4) + (ru2*y5) + (ru6*y6);+        y[(tensorOffset+(rts<<2))*tupSize] = y1 + (ru5*y2) + (ru3*y3) + (ru1*y4) + (ru6*y5) + (ru4*y6);+        y[(tensorOffset+rts*5)*tupSize]    = y1 + (ru6*y2) + (ru5*y3) + (ru4*y4) + (ru3*y5) + (ru2*y6);+      }+    }+  }+  else {+    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(hDim_t row = 1; row < p; row++) {+          tempSpace[row-1] = 0;+          for(hDim_t col = 0; col < p-1; col++) {+            tempSpace[row-1] += (y[(tensorOffset+col*rts)*tupSize]*ru[((col*row) % p)*rustride*tupSize]);+          }+        }++        for(hDim_t row = 0; row < p-1; row++) {+          y[(tensorOffset+rts*row)*tupSize] = tempSpace[row];+        }+      }+    }+    free(tempSpace);+  }+}++//takes inverse rus+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;+  }+  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; // 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;+        }+      }+    }+  }+}++template <typename ring> void ppDFT (ring* y, hShort_t tupSize, hDim_t lts, hDim_t rts,+              PrimeExponent pe, hDim_t rustride, ring* ru, ring* temp)+{+  hDim_t p = pe.prime;+  hShort_t e = pe.exponent;++  if(e == 0) {+    return;+  }++  hDim_t primeRuStride = rustride*ipow(p,e-1);++  hShort_t i;++  hDim_t ltsScale = ipow(p,e-1);+  hDim_t rtsScale = 1;+  hDim_t twidRuStride = rustride;+  for(i = 0; i < e; i++) {+    hDim_t rtsDim = rts*rtsScale;+    dftp (y, tupSize, lts*ltsScale, rtsDim, p, primeRuStride, ru, temp);+    dftTwiddle (y, tupSize, lts, rtsDim, pe, ltsScale*p, twidRuStride, ru);++    ltsScale /= p;+    rtsScale *= p;+    twidRuStride *= p;+    pe.exponent -= 1;+  }+}++template <typename ring> void ppDFTInv (ring* y, hShort_t tupSize, hDim_t lts, hDim_t rts,+                 PrimeExponent pe, hDim_t rustride, ring* ru, ring* temp)+{+  hDim_t p = pe.prime;+  hShort_t e = pe.exponent;++  if(e == 0) {+    return;+  }+  hDim_t primeRuStride = rustride*ipow(p,e-1);++  hShort_t i;++  hDim_t ltsScale = 1;+  hDim_t rtsScale = ipow(p,e-1);+  hDim_t twidRuStride = primeRuStride;+  pe.exponent = 1;+  for(i = 0; i < e; i++) {+    hDim_t rtsDim = rts*rtsScale;+    hDim_t ltsScaleP = ltsScale*p;+    dftTwiddle (y, tupSize, lts, rtsDim, pe, ltsScaleP, twidRuStride, ru);+    dftp (y, tupSize, lts*ltsScale, rtsDim, p, primeRuStride, ru, temp);++    ltsScale = ltsScaleP;+    rtsScale /= p;+    twidRuStride /= p;+    pe.exponent += 1;+  }+}++template <typename ring> void ppcrt (ring* y, hShort_t tupSize, hDim_t lts, hDim_t rts,+              PrimeExponent pe, ring* ru)+{+  hDim_t p = pe.prime;+  hDim_t e = pe.exponent;+  hDim_t mprime = ipow(p,e-1);+  ring* temp = 0;+  if(p >= DFTP_GENERIC_SIZE) {+    temp = (ring*)malloc(p*sizeof(ring));+  }++  crtp (y, tupSize, lts*mprime, rts, p, mprime, ru);+  crtTwiddle (y, tupSize, lts, rts, pe, ru);+  pe.exponent -= 1;+  ppDFT (y,  tupSize, lts, rts*(p-1), pe, p, ru, temp);+  pe.exponent += 1;++  if(p >= DFTP_GENERIC_SIZE) {+    free(temp);+  }+}++template <typename ring> void ppcrtinv (ring* y, hShort_t tupSize, hDim_t lts, hDim_t rts,+                 PrimeExponent pe, ring* ru)+{+  hDim_t p = pe.prime;+  hDim_t e = pe.exponent;+  hDim_t mprime = ipow(p,e-1);+  ring* temp = 0;+  if(p >= DFTP_GENERIC_SIZE) {+    temp = (ring*)malloc(p*sizeof(ring));+  }++  pe.exponent -= 1;+  ppDFTInv (y, tupSize, lts, rts*(p-1), pe, p, ru, temp);+  pe.exponent += 1;+  crtTwiddle (y, tupSize, lts, rts, pe, ru);+  crtpinv (y, tupSize, lts*mprime, rts, p, mprime, ru);++  if(p >= DFTP_GENERIC_SIZE) {+    free(temp);+  }+}++extern "C" void tensorCRTRq (hShort_t tupSize, Zq* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, Zq** ru, hInt_t* qs)+{+  tensorFuserCRT (y, tupSize, ppcrt, totm, peArr, sizeOfPE, ru, qs);+  canonicalizeZq(y,tupSize,totm,qs);+}++//takes inverse rus+extern "C" void tensorCRTInvRq (hShort_t tupSize, Zq* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE,+                    Zq** ruinv, Zq* mhatInv, hInt_t* qs)+{+  tensorFuserCRT (y, tupSize, ppcrtinv, totm, peArr, sizeOfPE, ruinv, qs);+  for (hShort_t i = 0; i < tupSize; i++) {+    Zq::q = qs[i];+    for (hDim_t j = 0; j < totm; j++) {+      //careful here! I'm not setting the global q, so I can't rely on Zq multiplication+      y[j*tupSize+i] = y[j*tupSize+i]*mhatInv[i];+    }+  }+  canonicalizeZq(y,tupSize,totm,qs);+}++extern "C" void tensorCRTC (hShort_t tupSize, Complex* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, Complex** ru)+{+  tensorFuserCRT (y, tupSize, ppcrt, totm, peArr, sizeOfPE, ru, (hInt_t*)0);+}++//takes inverse rus+extern "C" void tensorCRTInvC (hShort_t tupSize, Complex* y, hDim_t totm, PrimeExponent* peArr,+                    hShort_t sizeOfPE, Complex** ruinv, Complex* mhatInv)+{+  tensorFuserCRT (y, tupSize, ppcrtinv, totm, peArr, sizeOfPE, ruinv, (hInt_t*)0);+  for (hShort_t i = 0; i < tupSize; i++) {+    for (hDim_t j = 0; j < totm; j++) {+      y[j*tupSize+i] *= mhatInv[i];+    }+  }+}
− Crypto/Lol/Cyclotomic/Tensor/CTensor/g.c
@@ -1,828 +0,0 @@-#include "tensorTypes.h"
-
-
-void gPowR (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p)
-{
-  hDim_t tmp1 = rts*(p-1);
-  hDim_t tmp2 = tmp1 - rts;
-  hDim_t blockOffset, modOffset;
-  hDim_t i;
-  for (blockOffset = 0; blockOffset < lts; ++blockOffset)
-  {
-    hDim_t tmp3 = blockOffset * tmp1;
-    for (modOffset = 0; modOffset < rts; ++modOffset)
-    {
-      hDim_t tensorOffset = tmp3 + modOffset;
-      hInt_t last = y[(tensorOffset + tmp2)*tupSize];
-      for (i = p-2; i != 0; --i)
-      {
-        hDim_t idx = tensorOffset + i * rts;
-        y[idx*tupSize] += last - y[(idx-rts)*tupSize];
-      }
-      y[tensorOffset*tupSize] += last;
-    }
-  }
-}
-
-void gPowRq (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p, hInt_t q)
-{
-  hDim_t tmp1 = rts*(p-1);
-  hDim_t tmp2 = tmp1 - rts;
-  hDim_t blockOffset, modOffset;
-  hDim_t i;
-  for (blockOffset = 0; blockOffset < lts; ++blockOffset)
-  {
-    hDim_t tmp3 = blockOffset * tmp1;
-    for (modOffset = 0; modOffset < rts; ++modOffset)
-    {
-      hDim_t tensorOffset = tmp3 + modOffset;
-      hInt_t last = y[(tensorOffset + tmp2)*tupSize];
-      for (i = p-2; i != 0; --i)
-      {
-        hDim_t idx = tensorOffset + i * rts;
-        y[idx*tupSize] = (y[idx*tupSize] + last - y[(idx-rts)*tupSize]) % q;
-      }
-      y[tensorOffset*tupSize] = (y[tensorOffset*tupSize] + last) % q;
-    }
-  }
-}
-
-void gPowC (complex_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p)
-{
-  hDim_t tmp1 = rts*(p-1);
-  hDim_t tmp2 = tmp1 - rts;
-  hDim_t blockOffset, modOffset;
-  hDim_t i;
-  for (blockOffset = 0; blockOffset < lts; ++blockOffset)
-  {
-    hDim_t tmp3 = blockOffset * tmp1;
-    for (modOffset = 0; modOffset < rts; ++modOffset)
-    {
-      hDim_t tensorOffset = tmp3 + modOffset;
-      complex_t last = y[(tensorOffset + tmp2)*tupSize];
-      for (i = p-2; i != 0; --i)
-      {
-        hDim_t idx = tensorOffset + i * rts;
-        CMPLX_IADD(y[idx*tupSize],last);
-        CMPLX_ISUB(y[idx*tupSize],y[(idx-rts)*tupSize]);
-      }
-      CMPLX_IADD(y[tensorOffset*tupSize],last);
-    }
-  }
-}
-
-void ppGPowR (void* y, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs)
-{
-#ifdef DEBUG_MODE
-  ASSERT (q==0);
-#endif
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-     
-    if (p != 2)
-    {
-      for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-        gPowR (((hInt_t*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p);
-      }
-    }
-}
-
-void ppGPowRq (void* y, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs)
-{
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-    if (p != 2)
-    {
-      for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-        gPowRq (((hInt_t*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p, qs[tupIdx]);
-      }
-    }
-}
-
-void ppGPowC (void* y, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs)
-{
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-    if (p != 2)
-    {
-      for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-        gPowC (((complex_t*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p);
-      }
-    }
-}
-
-void gDecR (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p)
-{
-  hDim_t tmp1 = rts*(p-1);
-  hDim_t blockOffset;
-  hDim_t modOffset;
-  hDim_t i;
-
-  for (blockOffset = 0; blockOffset < lts; ++blockOffset)
-  {
-    hDim_t tmp2 = blockOffset * tmp1;
-    for (modOffset = 0; modOffset < rts; ++modOffset)
-    {
-      hDim_t tensorOffset = tmp2 + modOffset;
-      hInt_t acc = y[tensorOffset*tupSize];
-      for (i = p-2; i != 0; --i)
-      {
-        hDim_t idx = tensorOffset + i * rts;
-        acc += y[idx*tupSize];
-        y[idx*tupSize] -= y[(idx-rts)*tupSize];
-      }
-      y[tensorOffset*tupSize] += acc;
-    }
-  }
-}
-
-void gDecRq (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p, hInt_t q)
-{
-  hDim_t tmp1 = rts*(p-1);
-  hDim_t blockOffset;
-  hDim_t modOffset;
-  hDim_t i;
-
-  for (blockOffset = 0; blockOffset < lts; ++blockOffset)
-  {
-    hDim_t tmp2 = blockOffset * tmp1;
-    for (modOffset = 0; modOffset < rts; ++modOffset)
-    {
-      hDim_t tensorOffset = tmp2 + modOffset;
-      hInt_t acc = y[tensorOffset*tupSize];
-      for (i = p-2; i != 0; --i)
-      {
-        hDim_t idx = tensorOffset + i * rts;
-        // acc is at most p*q << 64 bits, so no need to mod
-        acc = acc + y[idx*tupSize];
-        y[idx*tupSize] = (y[idx*tupSize] - y[(idx-rts)*tupSize]) % q;
-      }
-      y[tensorOffset*tupSize] = (y[tensorOffset*tupSize] + acc) % q;
-    }
-  }
-}
-
-void ppGDecR (void* y, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs)
-{
-#ifdef DEBUG_MODE
-  ASSERT (q==0);
-#endif
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-    if (p != 2)
-    {
-      for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-        gDecR (((hInt_t*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p);
-      }
-    }
-}
-
-void ppGDecRq (void* y, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs)
-{
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-    if (p != 2)
-    {
-      for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-        gDecRq (((hInt_t*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p, qs[tupIdx]);
-      }
-    }
-}
-
-
-void gInvPowR (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p)
-{
-  hDim_t tmp1 = rts * (p-1);
-  hDim_t blockOffset, modOffset;
-  hDim_t i;
-
-  for (blockOffset = 0; blockOffset < lts; ++blockOffset)
-  {
-    hDim_t tmp2 = blockOffset * tmp1;
-    for (modOffset = 0; modOffset < rts; ++modOffset)
-    {
-      hDim_t tensorOffset = tmp2 + modOffset;
-      hInt_t lelts = 0;
-      for (i = 0; i < p-1; ++i)
-      {
-        lelts += y[(tensorOffset + i*rts)*tupSize];
-      }
-      hInt_t relts = 0;
-      for (i = p-2; i >= 0; --i)
-      {
-        hDim_t idx = tensorOffset + i*rts;
-        hInt_t z = y[idx*tupSize];
-        y[idx*tupSize] = (p-1-i) * lelts - (i+1)*relts;
-        lelts -= z;
-        relts += z;
-      }
-    }
-  }
-}
-
-void gInvPowRq (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p, hInt_t q)
-{
-  hDim_t tmp1 = rts * (p-1);
-  hDim_t blockOffset, modOffset;
-  hDim_t i;
-
-  for (blockOffset = 0; blockOffset < lts; ++blockOffset)
-  {
-    hDim_t tmp2 = blockOffset * tmp1;
-    for (modOffset = 0; modOffset < rts; ++modOffset)
-    {
-      hDim_t tensorOffset = tmp2 + modOffset;
-      hInt_t lelts = 0;
-      //lelts is at most p*q, so we can mod once at the end
-      for (i = 0; i < p-1; ++i)
-      {
-        lelts = lelts + y[(tensorOffset + i*rts)*tupSize];
-      }
-      lelts = lelts % q;
-      //in the next loop, lelts <= p*q and relts <= p*q
-      //products are <= p*p*q, and diff is <= 2*p*p*q
-      //so we assume 2*p^2 << 31 bits
-      hInt_t relts = 0;
-      for (i = p-2; i >= 0; --i)
-      {
-        hDim_t idx = tensorOffset + i*rts;
-        hInt_t z = y[idx*tupSize];
-        y[idx*tupSize] = (((p-1-i) * lelts) - ((i+1)*relts)) % q;
-        lelts -= z;
-        relts += z;
-      }
-    }
-  }
-}
-
-void gInvPowC (complex_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p)
-{
-  hDim_t tmp1 = rts * (p-1);
-  hDim_t blockOffset, modOffset;
-  hDim_t i;
-
-  for (blockOffset = 0; blockOffset < lts; ++blockOffset)
-  {
-    hDim_t tmp2 = blockOffset * tmp1;
-    for (modOffset = 0; modOffset < rts; ++modOffset)
-    {
-      hDim_t tensorOffset = tmp2 + modOffset;
-      complex_t lelts = ((complex_t){0, 0});;
-      for (i = 0; i < p-1; ++i)
-      {
-        CMPLX_IADD(lelts,y[(tensorOffset + i*rts)*tupSize]);
-      }
-      complex_t relts = ((complex_t){0, 0});;
-      for (i = p-2; i >= 0; --i)
-      {
-        hDim_t idx = tensorOffset + i*rts;
-        complex_t z = y[idx*tupSize];
-
-        complex_t c1 = ((complex_t){p-1-i, 0});
-        complex_t c2 = ((complex_t){i+1, 0});
-        complex_t t1 = CMPLX_MUL(c1, lelts);
-        complex_t t2 = CMPLX_MUL(c2, relts);
-        y[idx*tupSize] = CMPLX_SUB(t1,t2);
-        CMPLX_ISUB(lelts,z);
-        CMPLX_IADD(relts,z);
-      }
-    }
-  }
-}
-
-void ppGInvPowR (void* y, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs)
-{
-#ifdef DEBUG_MODE
-  ASSERT (q==0);
-#endif
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-    if (p != 2)
-    {
-      for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-        gInvPowR (((hInt_t*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p);
-      }
-    }
-}
-
-void ppGInvPowRq (void* y, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs)
-{
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-    if (p != 2)
-    {
-      for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-        gInvPowRq (((hInt_t*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p, qs[tupIdx]);
-      }
-    }
-}
-
-void ppGInvPowC (void* y, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs)
-{
-#ifdef DEBUG_MODE
-  ASSERT (q==0);
-#endif
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-    if (p != 2)
-    {
-      for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-        gInvPowC (((complex_t*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p);
-      }
-    }
-}
-
-//do not call for p=2!
-void gCRTRq (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p, hInt_t* gcoeffs, hInt_t q)
-{
-    hDim_t gindex;
-    hDim_t blockOffset, modOffset, idx;
-    hDim_t temp1 = rts*(p-1);
-    
-    for(gindex = 0; gindex < p-1; gindex++)
-    {
-        hInt_t coeff = gcoeffs[gindex*tupSize];
-        hDim_t temp3 = gindex*rts;
-        for(blockOffset = 0; blockOffset < lts; blockOffset++)
-        {
-            hDim_t temp2 = blockOffset*temp1 + temp3;
-            for(modOffset = 0; modOffset < rts; modOffset++)
-            {
-                idx = temp2 + modOffset;
-                y[idx*tupSize] = (y[idx*tupSize]*coeff)%q;
-            }
-        }
-    }
-}
-
-//do not call for p=2!
-void gCRTC (complex_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p, complex_t* gcoeffs)
-{
-    hDim_t gindex;
-    hDim_t blockOffset, modOffset, idx;
-    hDim_t temp1 = rts*(p-1);
-    
-    for(gindex = 0; gindex < p-1; gindex++)
-    {
-        complex_t coeff = gcoeffs[gindex*tupSize];
-        hDim_t temp3 = gindex*rts;
-        for(blockOffset = 0; blockOffset < lts; blockOffset++)
-        {
-            hDim_t temp2 = blockOffset*temp1 + temp3;
-            for(modOffset = 0; modOffset < rts; modOffset++)
-            {
-                idx = temp2 + modOffset;
-                CMPLX_IMUL(y[idx*tupSize],coeff);
-            }
-        }
-    }
-}
-
-void ppGCRTRq (void* y, hShort_t tupSize, hDim_t lts, hDim_t rts, PrimeExponent pe, void* gcoeffs, hInt_t* qs)
-{
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-    
-#ifdef DEBUG_MODE
-    printf("gcoeffs for p=%" PRId32 ", e=%" PRId16 "\t[", pe.prime, pe.exponent);
-    int i;
-    for(i = 0; i < ((p-1)*ipow(p,e-1)); i++) {
-        printf("%" PRId64 ",", ((hInt_t*)gcoeffs)[i]);
-    }
-    printf("]\n");
-#endif
-    
-    if (p != 2)
-    {
-      for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-        gCRTRq (((hInt_t*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p, ((hInt_t*)gcoeffs)+tupIdx, qs[tupIdx]);
-      }
-    }
-}
-
-void ppGCRTC (void* y, hShort_t tupSize, hDim_t lts, hDim_t rts, PrimeExponent pe, void* gcoeffs, hInt_t* qs)
-{
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-    
-#ifdef DEBUG_MODE
-    printf("gcoeffs for p=%" PRId32 ", e=%" PRId16 "\t[", pe.prime, pe.exponent);
-    int i;
-    for(i = 0; i < ((p-1)*ipow(p,e-1)); i++) {
-        printf("(%f,%f),", ((complex_t*)gcoeffs)[i].real, ((complex_t*)gcoeffs)[i].imag);
-    }
-    printf("]\n");
-#endif
-    
-    if (p != 2)
-    {
-      for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-        gCRTC (((complex_t*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p, ((complex_t*)gcoeffs)+tupIdx);
-      }
-    }
-}
-
-void gInvDecR (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p)
-{
-  hDim_t blockOffset;
-  hDim_t modOffset;
-  hDim_t i;
-  hDim_t tmp1 = rts*(p-1);
-
-  for (blockOffset = 0; blockOffset < lts; ++blockOffset)
-  {
-    hDim_t tmp2 = blockOffset*tmp1;
-    for (modOffset = 0; modOffset < rts; ++modOffset)
-    {
-      hDim_t tensorOffset = tmp2 + modOffset;
-      hInt_t lastOut = 0;
-      for (i=1; i < p; ++i)
-      {
-        lastOut += i * y[(tensorOffset + (i-1)*rts)*tupSize];
-      }
-      hInt_t acc = lastOut / p;
-      ASSERT (acc * p == lastOut);  // this line asserts that lastOut % p == 0, without calling % operator
-      for (i = p-2; i > 0; --i)
-      {
-        hDim_t idx = tensorOffset + i*rts;
-        hInt_t tmp = acc;
-        acc -= y[idx*tupSize]; // we already divided acc by p, do not multiply y[idx] by p
-        y[idx*tupSize] = tmp;
-      }
-      y[tensorOffset*tupSize] = acc;
-    }
-  }
-}
-
-void gInvDecRq (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p, hInt_t q)
-{
-  hDim_t blockOffset;
-  hDim_t modOffset;
-  hDim_t i;
-  hDim_t tmp1 = rts*(p-1);
-  hInt_t reciprocalOfP = reciprocal (q,p);
-
-  for (blockOffset = 0; blockOffset < lts; ++blockOffset)
-  {
-    hDim_t tmp2 = blockOffset*tmp1;
-    for (modOffset = 0; modOffset < rts; ++modOffset)
-    {
-      hDim_t tensorOffset = tmp2 + modOffset;
-      hInt_t lastOut = 0;
-      for (i=1; i < p; ++i)
-      {
-        lastOut += (i * y[(tensorOffset + (i-1)*rts)*tupSize]);
-      }
-      //in the previous loop, |lastOut| <= p*p*q
-      lastOut = lastOut % q;
-      hInt_t acc = (lastOut * reciprocalOfP) % q;
-      // |acc| <= p*q
-      for (i = p-2; i > 0; --i)
-      {
-        hDim_t idx = tensorOffset + i*rts;
-        hInt_t tmp = acc;
-        acc = acc - y[idx*tupSize];
-        y[idx*tupSize] = tmp % q;
-      }
-      y[tensorOffset*tupSize] = acc % q;
-    }
-  }
-}
-
-void ppGInvDecR (void* y, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs)
-{
-#ifdef DEBUG_MODE
-  ASSERT (q==0);
-#endif
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-    if (p != 2)
-    {
-      for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-        gInvDecR (((hInt_t*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p);
-      }
-    }
-}
-
-void ppGInvDecRq (void* y, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs)
-{
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-    if (p != 2)
-    {
-      for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-        gInvDecRq (((hInt_t*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p, qs[tupIdx]);
-      }
-    }
-}
-
-#ifdef STATS
-int gprCtr = 0;
-int gprqCtr = 0;
-int gdrCtr = 0;
-int gdrqCtr = 0;
-int giprCtr = 0;
-int giprqCtr = 0;
-int gidrCtr = 0;
-int gidrqCtr = 0;
-int gcrqCtr = 0;
-int gccCtr = 0;
-int gicrqCtr = 0;
-int giccCtr = 0;
-
-struct timespec gprTime = {0,0};
-struct timespec gprqTime = {0,0};
-struct timespec gdrTime = {0,0};
-struct timespec gdrqTime = {0,0};
-struct timespec giprTime = {0,0};
-struct timespec giprqTime = {0,0};
-struct timespec gidrTime = {0,0};
-struct timespec gidrqTime = {0,0};
-struct timespec gcrqTime = {0,0};
-struct timespec gccTime = {0,0};
-#endif
-
-void tensorGPowR (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
-{
-#ifdef STATS
-    gprCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-  tensorFuser (y, tupSize, ppGPowR, totm, peArr, sizeOfPE, (hInt_t*)0);
-
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    gprTime = tsAdd(gprTime, tsSubtract(t1,s1));
-#endif
-}
-
-void tensorGPowRq (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs)
-{
-#ifdef STATS
-    gprqCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-  tensorFuser (y, tupSize, ppGPowRq, totm, peArr, sizeOfPE, qs);
-
-  hDim_t j;
-  for(int tupIdx = 0; tupIdx<tupSize; tupIdx++) {
-    hInt_t q = qs[tupIdx];
-    for(j = 0; j < totm; j++)
-    {
-        if(y[j*tupSize+tupIdx]<0)
-        {
-            y[j*tupSize+tupIdx]+=q;
-        }
-    }
-  }
-
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    gprqTime = tsAdd(gprqTime, tsSubtract(t1,s1));
-#endif
-}
-
-void tensorGPowC (hShort_t tupSize, complex_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
-{
-#ifdef STATS
-    gpcCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-  tensorFuser (y, tupSize, ppGPowC, totm, peArr, sizeOfPE, (hInt_t*)0);
-
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    gpcTime = tsAdd(gpcTime, tsSubtract(t1,s1));
-#endif
-}
-
-void tensorGDecR (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
-{
-#ifdef STATS
-    gdrCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-  tensorFuser (y, tupSize, ppGDecR, totm, peArr, sizeOfPE, (hInt_t*)0);
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    gdrTime = tsAdd(gdrTime, tsSubtract(t1,s1));
-#endif
-}
-
-void tensorGDecRq (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs)
-{
-#ifdef STATS
-    gdrqCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-  tensorFuser (y, tupSize, ppGDecRq, totm, peArr, sizeOfPE, qs);
-
-  hDim_t j;
-  for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-    hInt_t q = qs[tupIdx];
-    for(j = 0; j < totm; j++)
-    {
-        if(y[j*tupSize+tupIdx]<0)
-        {
-            y[j*tupSize+tupIdx]+=q;
-        }
-    }
-  }
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    gdrqTime = tsAdd(gdrqTime, tsSubtract(t1,s1));
-#endif
-}
-
-void tensorGInvPowR (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
-{
-#ifdef STATS
-    giprCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-  tensorFuser (y, tupSize, ppGInvPowR, totm, peArr, sizeOfPE, (hInt_t*)0);
-
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    giprTime = tsAdd(giprTime, tsSubtract(t1,s1));
-#endif
-}
-
-void tensorGInvPowRq (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs)
-{
-#ifdef STATS
-    giprqCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-  tensorFuser (y, tupSize, ppGInvPowRq, totm, peArr, sizeOfPE, qs);
-
-  hDim_t j;
-  for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-    hInt_t q = qs[tupIdx];
-    for(j = 0; j < totm; j++)
-    {
-        if(y[j*tupSize+tupIdx]<0)
-        {
-            y[j*tupSize+tupIdx]+=q;
-        }
-    }
-  }
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    giprqTime = tsAdd(giprqTime, tsSubtract(t1,s1));
-#endif
-}
-
-void tensorGInvPowC (hShort_t tupSize, complex_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
-{
-#ifdef STATS
-    gipcCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-  tensorFuser (y, tupSize, ppGInvPowC, totm, peArr, sizeOfPE, (hInt_t*)0);
-
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    gipcTime = tsAdd(gipcTime, tsSubtract(t1,s1));
-#endif
-}
-
-void tensorGInvDecR (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
-{
-#ifdef STATS
-    gidrCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-  tensorFuser (y, tupSize, ppGInvDecR, totm, peArr, sizeOfPE, (hInt_t*)0);
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    gidrTime = tsAdd(gidrTime, tsSubtract(t1,s1));
-#endif
-}
-
-void tensorGInvDecRq (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs)
-{
-#ifdef STATS
-    gidrqCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-    tensorFuser (y, tupSize, ppGInvDecRq, totm, peArr, sizeOfPE, qs);
-
-  hDim_t j;
-  for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-    hInt_t q = qs[tupIdx];
-    for(j = 0; j < totm; j++)
-    {
-        if(y[j*tupSize+tupIdx]<0)
-        {
-            y[j*tupSize+tupIdx]+=q;
-        }
-    }
-  }
-
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    gidrqTime = tsAdd(gidrqTime, tsSubtract(t1,s1));
-#endif
-}
-
-void tensorGCRTRq (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t** gcoeffs, hInt_t* qs)
-{
-#ifdef STATS
-    gcrqCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-#ifdef DEBUG_MODE
-    printf("\n\nEntered tensorGCRTRq\ttotm=%" PRId32 "\tnumFacts=%" PRId16 "\tq=%" PRId64 "\n[", totm, sizeOfPE, q);
-    hDim_t j;
-    for(j = 0; j < totm; j++) {
-        printf("%" PRId64 ",", y[j]);
-    }
-    printf("]\n[");
-    for(j = 0; j < sizeOfPE; j++) {
-        printf("(%" PRId32 ",%" PRId16 "),", peArr[j].prime, peArr[j].exponent);
-    }
-    printf("]\n");
-#endif
-    void** vgcoeffs = (void**)malloc(sizeOfPE*sizeof(void*));
-    hDim_t i;
-    for(i = 0; i < sizeOfPE; i++)
-    {
-        vgcoeffs[i] = (void*) (gcoeffs[i]);
-    }
-
-    tensorFuserCRT (y, tupSize, ppGCRTRq, totm, peArr, sizeOfPE, vgcoeffs, qs);
-
-#ifdef DEBUG_MODE
-    for(j = 0; j < totm; j++)
-  {
-      if(y[j]<0)
-      {
-          printf("tensorGCRTRq\n");
-      }
-  }
-#endif
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    gcrqTime = tsAdd(gcrqTime, tsSubtract(t1,s1));
-#endif
-}
-void tensorGCRTC (hShort_t tupSize, complex_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, complex_t** gcoeffs)
-{
-#ifdef STATS
-    gccCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-#ifdef DEBUG_MODE
-    printf("\n\nEntered tensorGCRTC\ttotm=%" PRId32 "\tnumFacts=%" PRId16 "\n[", totm, sizeOfPE);
-    hDim_t j;
-    for(j = 0; j < totm; j++) {
-        printf("(%f,%f),", (y[j]).real, (y[j]).imag);
-    }
-    printf("]\n[");
-    for(j = 0; j < sizeOfPE; j++) {
-        printf("(%" PRId32 ",%" PRId16 "),", peArr[j].prime, peArr[j].exponent);
-    }
-    printf("]\n");
-#endif
-    void** vgcoeffs = (void**)malloc(sizeOfPE*sizeof(void*));
-    hDim_t i;
-    for(i = 0; i < sizeOfPE; i++)
-    {
-        vgcoeffs[i] = (void*) (gcoeffs[i]);
-    }
-
-    tensorFuserCRT (y, tupSize, ppGCRTC, totm, peArr, sizeOfPE, vgcoeffs, (hInt_t*)0);
-
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    gccTime = tsAdd(gccTime, tsSubtract(t1,s1));
-#endif
-}
-void tensorGInvCRTRq (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t** gcoeffs, hInt_t* qs)
-{
-#ifdef STATS
-    gicrqCtr++;
-#endif
-    tensorGCRTRq (tupSize, y, totm, peArr, sizeOfPE, gcoeffs, qs); //output is already shifted
-}
-void tensorGInvCRTC (hShort_t tupSize, complex_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, complex_t** gcoeffs)
-{
-#ifdef STATS
-    giccCtr++;
-#endif
-    tensorGCRTC (tupSize, y, totm, peArr, sizeOfPE, gcoeffs);
-}
-
+ Crypto/Lol/Cyclotomic/Tensor/CTensor/g.cpp view
@@ -0,0 +1,167 @@+#include "types.h"
+#include "tensor.h"
+#include "common.h"
+
+template <typename ring> void gPow (ring* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p)
+{
+  if (p == 2) {return;}
+  hDim_t tmp1 = rts*(p-1);
+  hDim_t tmp2 = tmp1 - rts;
+  hDim_t blockOffset, modOffset;
+  hDim_t i;
+  for (blockOffset = 0; blockOffset < lts; ++blockOffset) {
+    hDim_t tmp3 = blockOffset * tmp1;
+    for (modOffset = 0; modOffset < rts; ++modOffset) {
+      hDim_t tensorOffset = tmp3 + modOffset;
+      ring last = y[(tensorOffset + tmp2)*tupSize];
+      for (i = p-2; i != 0; --i) {
+        hDim_t idx = tensorOffset + i * rts;
+        y[idx*tupSize] += (last - y[(idx-rts)*tupSize]);
+      }
+      y[tensorOffset*tupSize] += last;
+    }
+  }
+}
+
+template <typename ring> void gDec (ring* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p)
+{
+  if (p == 2) {return;}
+  hDim_t tmp1 = rts*(p-1);
+  hDim_t blockOffset;
+  hDim_t modOffset;
+  hDim_t i;
+
+  for (blockOffset = 0; blockOffset < lts; ++blockOffset) {
+    hDim_t tmp2 = blockOffset * tmp1;
+    for (modOffset = 0; modOffset < rts; ++modOffset) {
+      hDim_t tensorOffset = tmp2 + modOffset;
+      ring acc = y[tensorOffset*tupSize];
+      for (i = p-2; i != 0; --i) {
+        hDim_t idx = tensorOffset + i * rts;
+        acc += y[idx*tupSize];
+        y[idx*tupSize] -= y[(idx-rts)*tupSize];
+      }
+      y[tensorOffset*tupSize] += acc;
+    }
+  }
+}
+
+template <typename ring> void gInvPow (ring* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p)
+{
+  if (p == 2) {return;}
+  hDim_t tmp1 = rts * (p-1);
+  hDim_t blockOffset, modOffset;
+  hDim_t i;
+
+  for (blockOffset = 0; blockOffset < lts; ++blockOffset) {
+    hDim_t tmp2 = blockOffset * tmp1;
+    for (modOffset = 0; modOffset < rts; ++modOffset) {
+      hDim_t tensorOffset = tmp2 + modOffset;
+      ring lelts;
+      lelts = 0;
+      for (i = 0; i < p-1; ++i) {
+        lelts += y[(tensorOffset + i*rts)*tupSize];
+      }
+      ring relts;
+      relts = 0;
+      for (i = p-2; i >= 0; --i) {
+        hDim_t idx = tensorOffset + i*rts;
+        ring z = y[idx*tupSize];
+        ring lmul, rmul;
+        lmul = p-1-i;
+        rmul = i+1;
+        y[idx*tupSize] = lmul * lelts - rmul * relts;
+        lelts -= z;
+        relts += z;
+      }
+    }
+  }
+}
+
+template <typename ring> void gInvDec (ring* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p)
+{
+  if (p == 2) {return;}
+  hDim_t blockOffset;
+  hDim_t modOffset;
+  hDim_t i;
+  hDim_t tmp1 = rts*(p-1);
+
+  for (blockOffset = 0; blockOffset < lts; ++blockOffset) {
+    hDim_t tmp2 = blockOffset*tmp1;
+    for (modOffset = 0; modOffset < rts; ++modOffset) {
+      hDim_t tensorOffset = tmp2 + modOffset;
+      ring lastOut;
+      lastOut = 0;
+      for (i=1; i < p; ++i) {
+        ring ri;
+        ri = i;
+        lastOut += (ri * y[(tensorOffset + (i-1)*rts)*tupSize]);
+      }
+      ring rp;
+      rp = p;
+      ring acc = lastOut / rp;
+      ASSERT ((acc * rp) == lastOut);  // this line asserts that lastOut % p == 0, without calling % operator
+      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
+        y[idx*tupSize] = tmp;
+      }
+      y[tensorOffset*tupSize] = acc;
+    }
+  }
+}
+
+extern "C" void tensorGPowR (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
+{
+  tensorFuserPrime (y, tupSize, gPow, totm, peArr, sizeOfPE, (hInt_t*)0);
+}
+
+extern "C" void tensorGPowRq (hShort_t tupSize, Zq* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs)
+{
+  tensorFuserPrime (y, tupSize, gPow, totm, peArr, sizeOfPE, qs);
+  canonicalizeZq(y,tupSize,totm,qs);
+}
+
+extern "C" void tensorGPowC (hShort_t tupSize, Complex* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
+{
+  tensorFuserPrime (y, tupSize, gPow, totm, peArr, sizeOfPE, (hInt_t*)0);
+}
+
+extern "C" void tensorGDecR (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
+{
+  tensorFuserPrime (y, tupSize, gDec, totm, peArr, sizeOfPE, (hInt_t*)0);
+}
+
+extern "C" void tensorGDecRq (hShort_t tupSize, Zq* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs)
+{
+  tensorFuserPrime (y, tupSize, gDec, totm, peArr, sizeOfPE, qs);
+  canonicalizeZq(y,tupSize,totm,qs);
+}
+
+extern "C" void 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);
+}
+
+extern "C" void 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);
+  canonicalizeZq(y,tupSize,totm,qs);
+}
+
+extern "C" void tensorGInvPowC (hShort_t tupSize, Complex* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
+{
+  tensorFuserPrime (y, tupSize, gInvPow, totm, peArr, sizeOfPE, (hInt_t*)0);
+}
+
+extern "C" void 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);
+}
+
+extern "C" void 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);
+  canonicalizeZq(y,tupSize,totm,qs);
+}
− Crypto/Lol/Cyclotomic/Tensor/CTensor/generalfuncs.c
@@ -1,305 +0,0 @@-#include "tensorTypes.h"
-
-hDim_t ipow(hDim_t base, hShort_t exp)
-{
-#ifdef DEBUG_MODE
-    ASSERT(exp >= 0);
-#endif
-	hDim_t result = 1;
-    while (exp)
-    {
-        if (exp & 1)
-        {
-            result *= base;
-        }
-        exp >>= 1;
-        base *= base;
-    }
-    return result;
-}
-
-complex_t cmplxpow(complex_t base, hShort_t exp)
-{
-	complex_t result = (complex_t){1,0};
-    while (exp)
-    {
-        if (exp & 1)
-        {
-            CMPLX_IMUL(result,base);
-        }
-        exp >>= 1;
-        CMPLX_IMUL(base,base);
-    }
-    return result;
-}
-
-hInt_t qpow(hInt_t base, hShort_t exp, hInt_t q)
-{
-	hInt_t result = 1;
-    while (exp)
-    {
-        if (exp & 1)
-        {
-            result = (result*base)%q;
-        }
-        exp >>= 1;
-        base = (base*base)%q;
-    }
-    return result;
-}
-
-// a is the field size. we are looking for reciprocal of b
-hInt_t reciprocal (hInt_t a, hInt_t b)
-{
-	hInt_t fieldSize = a;
-
-	hInt_t y = 1;
-	hInt_t lasty = 0;
-	while (b != 0)
-	{
-		hInt_t quotient = a / b;
-		hInt_t tmp = a % b;
-		a = b;
-		b = tmp;
-		tmp = y;
-		y  = lasty - quotient*y;
-		lasty = tmp;
-	}
-	ASSERT (a==1);  // if this one fails, then b is not invertible mod a
-
-	// this actually returns EITHER the reciprocal OR reciprocal + fieldSize
-	hInt_t res = lasty + fieldSize;
-#ifdef DEBUG_MODE
-	ASSERT (0);
-	ASSERT ((res >= 0) && (res < fieldSize + fieldSize));
-	hInt_t test = res * b % fieldSize;
-	ASSERT (test == 1);
-#endif
-	return res;
-
-}
-
-//for square transforms
-void tensorFuser (void* y, hShort_t tupSize, funcPtr f, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs)
-{
-    hDim_t lts = totm;
-    hDim_t rts = 1;
-    hShort_t i;
-
-    for (i = 0; i < sizeOfPE; ++i)
-    {
-        PrimeExponent pe = peArr[i];
-        hDim_t ipow_pe = ipow(pe.prime, (pe.exponent-1));
-        hDim_t dim = (pe.prime-1) * ipow_pe;  // the totient of pe
-        lts /= dim;
-        (*f) (y, tupSize, pe, lts, rts, qs);
-        rts  *= dim;
-    }
-}
-
-void tensorFuserCRT (void* y, hShort_t tupSize, crtFuncPtr f, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, void** ru, hInt_t* q)
-{
-    hDim_t lts = totm;
-    hDim_t rts = 1;
-    hShort_t i;
-
-    for (i = 0; i < sizeOfPE; ++i)
-    {
-        PrimeExponent pe = peArr[i];
-        hDim_t ipow_pe = ipow(pe.prime, (pe.exponent-1));
-        hDim_t dim = (pe.prime-1) * ipow_pe;  // the totient of pe
-        lts /= dim;
-        (*f) (y, tupSize, lts, rts, pe, ru[i], q);
-        rts  *= dim;
-    }
-}
-
-struct  timespec  tsSubtract (struct  timespec  time1, struct  timespec  time2)
-{    /* Local variables. */
-    struct  timespec  result ;
-
-/* Subtract the second time from the first. */
-
-    if ((time1.tv_sec < time2.tv_sec) ||
-        ((time1.tv_sec == time2.tv_sec) &&
-         (time1.tv_nsec <= time2.tv_nsec))) {		/* TIME1 <= TIME2? */
-        result.tv_sec = result.tv_nsec = 0 ;
-    } else {						/* TIME1 > TIME2 */
-        result.tv_sec = time1.tv_sec - time2.tv_sec ;
-        if (time1.tv_nsec < time2.tv_nsec) {
-            result.tv_nsec = time1.tv_nsec + 1000000000L - time2.tv_nsec ;
-            result.tv_sec-- ;				/* Borrow a second. */
-        } else {
-            result.tv_nsec = time1.tv_nsec - time2.tv_nsec ;
-        }
-    }
-
-    return (result) ;
-}
-
-struct  timespec  tsAdd (struct  timespec  time1, struct  timespec  time2)
-{    /* Local variables. */
-    struct  timespec  result ;
-
-/* Add the two times together. */
-
-    result.tv_sec = time1.tv_sec + time2.tv_sec ;
-    result.tv_nsec = time1.tv_nsec + time2.tv_nsec ;
-    if (result.tv_nsec >= 1000000000L) {		/* Carry? */
-        result.tv_sec++ ;  result.tv_nsec = result.tv_nsec - 1000000000L ;
-    }
-
-    return (result) ;
-}
-
-const  char  *tsShow (struct  timespec  binaryTime, bool  inLocal, const  char  *format)
-{    /* Local variables. */
-    struct  tm  calendarTime ;
-#define  MAX_TIMES  4
-    static  char  asciiTime[MAX_TIMES][64] ;
-    static  int  current = 0 ;
-
-/* Convert the TIMESPEC to calendar time: year, month, day, etc. */
-
-#ifdef VXWORKS
-    if (inLocal)
-        localtime_r ((time_t *) &binaryTime.tv_sec, &calendarTime) ;
-    else
-        gmtime_r ((time_t *) &binaryTime.tv_sec, &calendarTime) ;
-#else
-    if (inLocal)
-        calendarTime = *(localtime ((time_t *) &binaryTime.tv_sec)) ;
-    else
-        calendarTime = *(gmtime ((time_t *) &binaryTime.tv_sec)) ;
-#endif
-
-/* Format the time in ASCII. */
-
-    current = (current + 1) % MAX_TIMES ;
-
-    if (format == NULL) {
-        strftime (asciiTime[current], 64, "%Y-%j-%H:%M:%S", &calendarTime) ;
-        sprintf (asciiTime[current] + strlen (asciiTime[current]),
-                 ".%06ld", (binaryTime.tv_nsec % 1000000000L) / 1000L) ;
-    } else {
-        strftime (asciiTime[current], 64, format, &calendarTime) ;
-        sprintf (asciiTime[current] + strlen (asciiTime[current]),
-                 ".%06ld", (binaryTime.tv_nsec % 1000000000L) / 1000L) ;
-    }
-
-    return (asciiTime[current]);
-}
-
-
-
-const char* timeformat = "%M:%S";
-
-void getStats() { 
-
-#ifdef STATS
-    struct timespec total;
-    printf("CRT Stats:\n");
-    printf("CRT_Rq times: Real:%s\tMono:%s\tProc:%s\tThread:%s\n", tsShow(crttime1, false, timeformat),tsShow(crttime2, false, timeformat),tsShow(crttime3, false, timeformat),tsShow(crttime4, false, timeformat));
-    printf("CTR_Rq: %d\t%s\t%d\t%s\n", crtRqCtr, tsShow(crttime1, false, timeformat), crtInvRqCtr, tsShow(crtInvRqTime, false, timeformat));
-    printf("CTR_C: %d\t%s\t%d\t%s\n", crtCCtr, tsShow(crtCTime, false, timeformat), crtInvCCtr, tsShow(crtInvCTime, false, timeformat));
-    
-    printf("\nG Stats:\n");
-    printf("GPow_R: %d\t%s\t%d\t%s\n", gprCtr, tsShow(gprTime, false, timeformat), giprCtr, tsShow(giprTime, false, timeformat));
-    printf("GPow_Rq: %d\t%s\t%d\t%s\n", gprqCtr, tsShow(gprqTime, false, timeformat), giprqCtr, tsShow(giprqTime, false, timeformat));
-    printf("GPow_C: %d\t%s\t%d\t%s\n", gpcCtr, tsShow(gpcTime, false, timeformat), gipcCtr, tsShow(gipcTime, false, timeformat));
-    printf("GDec_R: %d\t%s\t%d\t%s\n", gdrCtr, tsShow(gdrTime, false, timeformat), gidrCtr, tsShow(gidrTime, false, timeformat));
-    printf("GDec_Rq: %d\t%s\t%d\t%s\n", gdrqCtr, tsShow(gdrqTime, false, timeformat), gidrqCtr, tsShow(gidrqTime, false, timeformat));
-    printf("GCRT_Rq: %d\t%d\t%s\n", gcrqCtr, gicrqCtr, tsShow(gcrqTime, false, timeformat));
-    printf("GCRT_C: %d\t%d\t%s\n", gccCtr, giccCtr, tsShow(gccTime, false, timeformat));
-
-    printf("\nL Stats:\n");
-    printf("L_R: %d\t%s\t%d\t%s\n", lrCtr, tsShow(lrTime, false, timeformat), lirCtr, tsShow(lirTime, false, timeformat));
-    printf("L_Rq: %d\t%s\t%d\t%s\n", lrqCtr, tsShow(lrqTime, false, timeformat), lirqCtr, tsShow(lirqTime, false, timeformat));
-    printf("L_D: %d\t%s\t%d\t%s\n", ldCtr, tsShow(ldTime, false, timeformat), lidCtr, tsShow(lidTime, false, timeformat));
-    printf("L_C: %d\t%s\t%d\t%s\n", lcCtr, tsShow(lcTime, false, timeformat), licCtr, tsShow(licTime, false, timeformat));
-
-    printf("\nNorm Stats:\n");
-    printf("NormSq_R %d\t%s\n", normrCtr, tsShow(normrTime, false, timeformat));
-
-    printf("\nBasic Stats:\n");
-    printf("Mul: %d\t%s\n", mulCtr, tsShow(mulTime, false, timeformat));
-    printf("Add: %d\t%s\n", addCtr, tsShow(addTime, false, timeformat));
-
-    total = tsAdd(norrTime, tsAdd(crttime1, tsAdd(crtInvRqTime, tsAdd(crtCTime, tsAdd(crtInvCTime, tsAdd(gprTime, tsAdd(giprTime, tsAdd(gdrTime, tsAdd(gidrTime, tsAdd(gprqTime, tsAdd(giprqTime, tsAdd(gdrqTime, tsAdd(gidrqTime, tsAdd(gcrqTime, tsAdd(gccTime, tsAdd(lrTime, tsAdd(lirTime, tsAdd(lrqTime, tsAdd(lirqTime, tsAdd(ldTime, tsAdd(lidTime, tsAdd(lcTime, tsAdd(licTime, tsAdd(mulTime,addTime))))))))))))))))))))))));
-
-    printf("\nTotal C Time: %s\n\n", tsShow(total, false, timeformat));
-
-    crtRqCtr = 0;
-    crtInvRqCtr = 0;
-    crtCCtr = 0;
-    crtInvCCtr = 0;
-
-    gprCtr = 0;
-    gpcCtr = 0;
-    gprqCtr = 0;
-    gdrCtr = 0;
-    gdrqCtr = 0;
-    giprCtr = 0;
-    gipcCtr = 0;
-    giprqCtr = 0;
-    gidrCtr = 0;
-    gidrqCtr = 0;
-    gcrqCtr = 0;
-    gccCtr = 0;
-    gicrqCtr = 0;
-    giccCtr = 0;
-
-    lrqCtr = 0;
-    lrCtr = 0;
-    ldCtr = 0;
-    lcCtr = 0;
-    lirqCtr = 0;
-    lirCtr = 0;
-    lidCtr = 0;
-    licCtr = 0;
-
-    normrCtr = 0;
-
-    mulCtr = 0;
-    addCtr = 0;
-
-    mulTime = (struct timespec){0,0};
-    addTime = (struct timespec){0,0};
-
-    lrqTime = (struct timespec){0,0};
-    lrTime = (struct timespec){0,0};
-    ldTime = (struct timespec){0,0};
-    lcTime = (struct timespec){0,0};
-    lirqTime = (struct timespec){0,0};
-    lirTime = (struct timespec){0,0};
-    lidTime = (struct timespec){0,0};
-    licTime = (struct timespec){0,0};
-
-    normrTime = (struct timespec){0,0};
-
-    gprTime = (struct timespec){0,0};
-    gpcTime = (struct timespec){0,0};
-    gprqTime = (struct timespec){0,0};
-    gdrTime = (struct timespec){0,0};
-    gdrqTime = (struct timespec){0,0};
-    giprTime = (struct timespec){0,0};
-    gipcTime = (struct timespec){0,0};
-    giprqTime = (struct timespec){0,0};
-    gidrTime = (struct timespec){0,0};
-    gidrqTime = (struct timespec){0,0};
-    gcrqTime = (struct timespec){0,0};
-    gccTime = (struct timespec){0,0};
-
-    crttime1 = (struct timespec){0,0};
-    crttime2 = (struct timespec){0,0};
-    crttime3 = (struct timespec){0,0};
-    crttime4 = (struct timespec){0,0};
-
-    crtInvRqTime = (struct timespec){0,0};
-    crtCTime = (struct timespec){0,0};
-    crtInvCTime = (struct timespec){0,0};
-#endif
-    fflush(stdout);
-}
-
-
− Crypto/Lol/Cyclotomic/Tensor/CTensor/l.c
@@ -1,434 +0,0 @@-#include "tensorTypes.h"
-
-void lpRq (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p, hInt_t q) {
-  hDim_t blockOffset;
-  hDim_t modOffset;
-  int i;
-  hDim_t tmp1 = rts*(p-1);
-  for (blockOffset = 0; blockOffset < lts; ++blockOffset) {
-    hDim_t tmp2 = blockOffset*tmp1;
-    for (modOffset = 0; modOffset < rts; ++modOffset) {
-      hDim_t idx = tmp2 + modOffset + rts;
-      for (i = 1; i < p-1; ++i) {
-        hInt_t temp = y[(idx-rts)*tupSize] + y[idx*tupSize];
-        if (temp >= q) y[idx*tupSize]=temp-q;
-        else y[idx*tupSize] = temp;
-        idx += rts;
-      }
-    }
-  }
-}
-
-void lpR (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p) {
-  hDim_t blockOffset;
-  hDim_t modOffset;
-  int i;
-
-  hDim_t tmp1 = rts*(p-1);
-  for (blockOffset = 0; blockOffset < lts; ++blockOffset) {
-    hDim_t tmp2 = blockOffset*tmp1;
-    for (modOffset = 0; modOffset < rts; ++modOffset) {
-      hDim_t idx = tmp2 + modOffset + rts;
-      for (i = 1; i < p-1; ++i) {
-        y[idx*tupSize] += y[(idx-rts)*tupSize];
-        idx += rts;
-      }
-    }
-  }
-}
-
-void lpDouble (double* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p) {
-  hDim_t blockOffset;
-  hDim_t modOffset;
-  int i;
-
-  hDim_t tmp1 = rts*(p-1);
-  for (blockOffset = 0; blockOffset < lts; ++blockOffset) {
-    hDim_t tmp2 = blockOffset*tmp1;
-    for (modOffset = 0; modOffset < rts; ++modOffset) {
-      hDim_t idx = tmp2 + modOffset + rts;
-      for (i = 1; i < p-1; ++i) {
-        y[idx*tupSize] += y[(idx-rts)*tupSize];
-        idx += rts;
-      }
-    }
-  }
-}
-
-void lpC (complex_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p) {
-  hDim_t blockOffset;
-  hDim_t modOffset;
-  int i;
-
-  hDim_t tmp1 = rts*(p-1);
-  for (blockOffset = 0; blockOffset < lts; ++blockOffset) {
-    hDim_t tmp2 = blockOffset*tmp1;
-    for (modOffset = 0; modOffset < rts; ++modOffset) {
-      hDim_t idx = tmp2 + modOffset + rts;
-      for (i = 1; i < p-1; ++i) {
-        CMPLX_IADD (y[idx*tupSize], y[(idx-rts)*tupSize]);
-        idx += rts;
-      }
-    }
-  }
-}
-
-void lpInvRq (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p, hInt_t q) {
-  hDim_t blockOffset;
-  hDim_t modOffset;
-  int i;
-
-  hDim_t tmp1 = rts*(p-1);
-  for (blockOffset = 0; blockOffset < lts; ++blockOffset) {
-    hDim_t tmp2 = blockOffset*tmp1;
-    for (modOffset = 0; modOffset < rts; ++ modOffset) {
-      hDim_t tensorOffset = tmp2 + modOffset;
-      hDim_t idx = tensorOffset + (p-2) * rts;
-      for (i = p-2; i != 0; --i) {
-        hInt_t temp = y[idx*tupSize] - y[(idx-rts)*tupSize] + q;
-        if (temp >= q) y[idx*tupSize]=temp-q;
-        else y[idx*tupSize] = temp;
-        idx -= rts;
-      }
-    }
-  }
-}
-
-void lpInvR (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p) {
-  hDim_t blockOffset;
-  hDim_t modOffset;
-  int i;
-
-  hDim_t tmp1 = rts*(p-1);
-  for (blockOffset = 0; blockOffset < lts; ++blockOffset) {
-    hDim_t tmp2 = blockOffset*tmp1;
-    for (modOffset = 0; modOffset < rts; ++ modOffset) {
-      hDim_t tensorOffset = tmp2 + modOffset;
-      hDim_t idx = tensorOffset + (p-2) * rts;
-      for (i = p-2; i != 0; --i) {
-        y[idx*tupSize] -= y[(idx-rts)*tupSize] ;
-        idx -= rts;
-      }
-    }
-  }
-}
-
-void lpInvDouble (double* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p) {
-  hDim_t blockOffset;
-  hDim_t modOffset;
-  int i;
-
-  hDim_t tmp1 = rts*(p-1);
-  for (blockOffset = 0; blockOffset < lts; ++blockOffset) {
-    hDim_t tmp2 = blockOffset*tmp1;
-    for (modOffset = 0; modOffset < rts; ++ modOffset) {
-      hDim_t tensorOffset = tmp2 + modOffset;
-      hDim_t idx = tensorOffset + (p-2) * rts;
-      for (i = p-2; i != 0; --i) {
-        y[idx*tupSize] -= y[(idx-rts)*tupSize] ;
-        idx -= rts;
-      }
-    }
-  }
-}
-
-void lpInvC (complex_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p) {
-  hDim_t blockOffset;
-  hDim_t modOffset;
-  int i;
-
-  hDim_t tmp1 = rts*(p-1);
-  for (blockOffset = 0; blockOffset < lts; ++blockOffset) {
-    hDim_t tmp2 = blockOffset*tmp1;
-    for (modOffset = 0; modOffset < rts; ++ modOffset) {
-      hDim_t tensorOffset = tmp2 + modOffset;
-      hDim_t idx = tensorOffset + (p-2) * rts;
-      for (i = p-2; i != 0; --i) {
-        CMPLX_ISUB (y[idx*tupSize], y[(idx-rts)*tupSize]);
-        idx -= rts;
-      }
-    }
-  }
-}
-
-void ppLRq (void* y, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs) {
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-    if(p == 2) return;
-    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-      lpRq (((hInt_t*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p, qs[tupIdx]);
-    }
-}
-
-void ppLR (void* y, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs) {
-#ifdef DEBUG_MODE
-  ASSERT (q==0);
-#endif
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-    if(p == 2) return;
-    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-      lpR (((hInt_t*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p);
-    }
-}
-
-void ppLDouble (void* y, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs) {
-#ifdef DEBUG_MODE
-  ASSERT (q==0);
-#endif
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-    if(p == 2) return;
-    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-      lpDouble (((double*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p);
-    }
-}
-
-void ppLC (void* y, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs) {
-#ifdef DEBUG_MODE
-  ASSERT (q==0);
-#endif
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-    if(p == 2) return;
-    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-      lpC (((complex_t*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p);
-    }
-}
-
-
-void ppLInvRq (void* y, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs) {
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-    if(p == 2) return;
-    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-      lpInvRq (((hInt_t*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p, qs[tupIdx]);
-    }
-}
-
-void ppLInvR (void* y, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs) {
-#ifdef DEBUG_MODE
-  ASSERT (q==0);
-#endif
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-    if(p == 2) return;
-    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-      lpInvR (((hInt_t*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p);
-    }
-}
-
-void ppLInvDouble (void* y, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs) {
-#ifdef DEBUG_MODE
-  ASSERT (q==0);
-#endif
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-    if(p == 2) return;
-    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-      lpInvDouble (((double*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p);
-    }
-}
-
-void ppLInvC (void* y, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs) {
-#ifdef DEBUG_MODE
-  ASSERT (q==0);
-#endif
-    hDim_t p = pe.prime;
-    hShort_t e = pe.exponent;
-    if(p == 2) return;
-    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
-      lpInvC (((complex_t*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p);
-    }
-}
-
-#ifdef STATS
-int lrqCtr = 0;
-int lrCtr = 0;
-int ldCtr = 0;
-int lcCtr = 0;
-int lirqCtr = 0;
-int lirCtr = 0;
-int lidCtr = 0;
-int licCtr = 0;
-
-struct timespec lrqTime = {0,0};
-struct timespec lrTime = {0,0};
-struct timespec ldTime = {0,0};
-struct timespec lcTime = {0,0};
-struct timespec lirqTime = {0,0};
-struct timespec lirTime = {0,0};
-struct timespec lidTime = {0,0};
-struct timespec licTime = {0,0};
-#endif
-
-
-void tensorLRq (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs) {
-#ifdef STATS
-    lrqCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-#ifdef DEBUG_MODE
-    hDim_t i;
-    printf("\n\nEntered tensorLRq\ttotm=%" PRId32 "\tnumFacts=%" PRId16 "\tq=%" PRId64 "\n[", totm, sizeOfPE, q);
-    /*for(i = 0; i < totm; i++) {
-        printf("%" PRId64 ",", y[i]);
-    }*/
-    printf("]\n[");
-    for(i = 0; i < sizeOfPE; i++) {
-        printf("(%" PRId32 ",%" PRId16 "),", peArr[i].prime, peArr[i].exponent);
-    }
-    printf("]\n");
-#endif
-  tensorFuser (y, tupSize, ppLRq, totm, peArr, sizeOfPE, qs); // don't need to shift here
-#ifdef DEBUG_MODE
-  for(i = 0; i < totm*tupSize; i++) {
-      if(y[i]<0) {
-          printf("tensorLRq\n");
-      }
-  }
-#endif
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    lrqTime = tsAdd(lrqTime, tsSubtract(t1,s1));
-#endif
-}
-
-void tensorLR (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE) {
-#ifdef STATS
-    lrCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-#ifdef DEBUG_MODE
-    printf("\n\nEntered tensorLR\ttotm=%" PRId32 "\tnumFacts=%" PRId16 "\n[", totm, sizeOfPE);
-    hDim_t i;
-    for(i = 0; i < totm; i++) {
-        printf("%" PRId64 ",", y[i]);
-    }
-    printf("]\n[");
-    for(i = 0; i < sizeOfPE; i++) {
-        printf("(%" PRId32 ",%" PRId16 "),", peArr[i].prime, peArr[i].exponent);
-    }
-    printf("]\n");
-#endif
-  tensorFuser (y, tupSize, ppLR, totm, peArr, sizeOfPE, (hInt_t*)0);
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    lrTime = tsAdd(lrTime, tsSubtract(t1,s1));
-#endif
-}
-
-void tensorLDouble (hShort_t tupSize, double* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE) {
-#ifdef STATS
-    ldCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-#ifdef DEBUG_MODE
-    printf("\n\nEntered tensorLDouble\ttotm=%" PRId32 "\tnumFacts=%" PRId16 "\n[", totm, sizeOfPE);
-    hDim_t i;
-    for(i = 0; i < totm; i++) {
-        printf("%f,", y[i]);
-    }
-    printf("]\n[");
-    for(i = 0; i < sizeOfPE; i++) {
-        printf("(%" PRId32 ",%" PRId16 "),", peArr[i].prime, peArr[i].exponent);
-    }
-    printf("]\n");
-#endif
-  tensorFuser (y, tupSize, ppLDouble, totm, peArr, sizeOfPE, (hInt_t*)0);
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    ldTime = tsAdd(ldTime, tsSubtract(t1,s1));
-#endif
-}
-
-void tensorLC (hShort_t tupSize, complex_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE) {
-#ifdef STATS
-    lcCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-#ifdef DEBUG_MODE
-    printf("\n\nEntered tensorLC\ttotm=%" PRId32 "\tnumFacts=%" PRId16 "\n[", totm, sizeOfPE);
-    hDim_t i;
-    for(i = 0; i < totm; i++) {
-        printf("(%f,%f),", y[i].real, y[i].imag);
-    }
-    printf("]\n[");
-    for(i = 0; i < sizeOfPE; i++) {
-        printf("(%" PRId32 ",%" PRId16 "),", peArr[i].prime, peArr[i].exponent);
-    }
-    printf("]\n");
-#endif
-  tensorFuser (y, tupSize, ppLC, totm, peArr, sizeOfPE, (hInt_t*)0);
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    lcTime = tsAdd(lcTime, tsSubtract(t1,s1));
-#endif
-}
-
-void tensorLInvRq (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs) {
-#ifdef STATS
-    lirqCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-  tensorFuser (y, tupSize, ppLInvRq, totm, peArr, sizeOfPE, qs);
-#ifdef DEBUG_MODE
-  hDim_t i;
-  for(i = 0; i < totm*tupSize; i++)
-  {
-      if(y[i]<0)
-      {
-          printf("tensorLInvRq\n");
-      }
-  }
-#endif
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    lirqTime = tsAdd(lirqTime, tsSubtract(t1,s1));
-#endif
-}
-
-void tensorLInvR (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE) {
-#ifdef STATS
-    lirCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-  tensorFuser (y, tupSize, ppLInvR, totm, peArr, sizeOfPE, (hInt_t*)0);
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    lirTime = tsAdd(lirTime, tsSubtract(t1,s1));
-#endif
-}
-
-void tensorLInvDouble (hShort_t tupSize, double* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE) {
-#ifdef STATS
-    lidCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-  tensorFuser (y, tupSize, ppLInvDouble, totm, peArr, sizeOfPE, (hInt_t*)0);
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    lidTime = tsAdd(lidTime, tsSubtract(t1,s1));
-#endif
-}
-
-void tensorLInvC (hShort_t tupSize, complex_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE) {
-#ifdef STATS
-    licCtr++;
-    struct timespec s1,t1;
-    clock_gettime(CLOCK_REALTIME, &s1);
-#endif
-  tensorFuser (y, tupSize, ppLInvC, totm, peArr, sizeOfPE, (hInt_t*)0);
-#ifdef STATS
-    clock_gettime(CLOCK_REALTIME, &t1);
-    licTime = tsAdd(licTime, tsSubtract(t1,s1));
-#endif
-}
-
+ Crypto/Lol/Cyclotomic/Tensor/CTensor/l.cpp view
@@ -0,0 +1,87 @@+#include "types.h"
+#include "tensor.h"
+
+template <typename ring> void lp (ring* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p)
+{
+  hDim_t blockOffset;
+  hDim_t modOffset;
+  int i;
+
+  if(p == 2) {return;}
+
+  hDim_t tmp1 = rts*(p-1);
+  for (blockOffset = 0; blockOffset < lts; ++blockOffset) {
+    hDim_t tmp2 = blockOffset*tmp1;
+    for (modOffset = 0; modOffset < rts; ++modOffset) {
+      hDim_t idx = tmp2 + modOffset + rts;
+      for (i = 1; i < p-1; ++i) {
+        y[idx*tupSize] += y[(idx-rts)*tupSize];
+        idx += rts;
+      }
+    }
+  }
+}
+
+template <typename ring> void lpInv (ring* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p)
+{
+  hDim_t blockOffset;
+  hDim_t modOffset;
+  int i;
+
+  if(p == 2) {return;}
+
+  hDim_t tmp1 = rts*(p-1);
+  for (blockOffset = 0; blockOffset < lts; ++blockOffset) {
+    hDim_t tmp2 = blockOffset*tmp1;
+    for (modOffset = 0; modOffset < rts; ++ modOffset) {
+      hDim_t tensorOffset = tmp2 + modOffset;
+      hDim_t idx = tensorOffset + (p-2) * rts;
+      for (i = p-2; i != 0; --i) {
+        y[idx*tupSize] -= y[(idx-rts)*tupSize] ;
+        idx -= rts;
+      }
+    }
+  }
+}
+
+extern "C" void tensorLRq (hShort_t tupSize, Zq* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs)
+{
+  tensorFuserPrime (y, tupSize, lp, totm, peArr, sizeOfPE, qs);
+  canonicalizeZq(y,tupSize,totm,qs);
+}
+
+extern "C" void tensorLR (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
+{
+  tensorFuserPrime (y, tupSize, lp, totm, peArr, sizeOfPE, (hInt_t*)0);
+}
+
+extern "C" void tensorLDouble (hShort_t tupSize, double* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
+{
+  tensorFuserPrime (y, tupSize, lp, totm, peArr, sizeOfPE, (hInt_t*)0);
+}
+
+extern "C" void tensorLC (hShort_t tupSize, Complex* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
+{
+  tensorFuserPrime (y, tupSize, lp, totm, peArr, sizeOfPE, (hInt_t*)0);
+}
+
+extern "C" void tensorLInvRq (hShort_t tupSize, Zq* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs)
+{
+  tensorFuserPrime (y, tupSize, lpInv, totm, peArr, sizeOfPE, qs);
+  canonicalizeZq(y,tupSize,totm,qs);
+}
+
+extern "C" void tensorLInvR (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
+{
+  tensorFuserPrime (y, tupSize, lpInv, totm, peArr, sizeOfPE, (hInt_t*)0);
+}
+
+extern "C" void tensorLInvDouble (hShort_t tupSize, double* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
+{
+  tensorFuserPrime (y, tupSize, lpInv, totm, peArr, sizeOfPE, (hInt_t*)0);
+}
+
+extern "C" void tensorLInvC (hShort_t tupSize, Complex* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)
+{
+  tensorFuserPrime (y, tupSize, lpInv, totm, peArr, sizeOfPE, (hInt_t*)0);
+}
+ Crypto/Lol/Cyclotomic/Tensor/CTensor/mul.cpp view
@@ -0,0 +1,24 @@+#include "types.h"++template <typename ring> void zipWithStar (ring* a, ring* b, hShort_t tupSize, hDim_t totm, hInt_t* qs)+{+  for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {+    if(qs) {+      Zq::q = qs[tupIdx];+    }+    for(int i = 0; i < totm; i++) {+      a[i*tupSize+tupIdx] *= b[i*tupSize+tupIdx];+    }+  }+}++//a = zipWith (*) a b+extern "C" void mulRq (hShort_t tupSize, Zq* a, Zq* b, hDim_t totm, hInt_t* qs)+{+  zipWithStar(a, b, tupSize, totm, qs);+}++extern "C" void mulC (hShort_t tupSize, Complex* a, Complex* b, hDim_t totm)+{+  zipWithStar(a, b, tupSize, totm, (hInt_t*)0);+}
− Crypto/Lol/Cyclotomic/Tensor/CTensor/norm.c
@@ -1,86 +0,0 @@-#include "tensorTypes.h"--#ifdef STATS-int normrCtr = 0;-struct timespec normrTime = {0,0};-#endif--void pNormSqR (hInt_t* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p) {-  hDim_t blockOffset;-  hDim_t modOffset;-  hDim_t i;--  if(p==2) {-    return;-  }--  hDim_t tmp1 = rts*(p-1);-  for (blockOffset = 0; blockOffset < lts; ++blockOffset) {-    hDim_t tmp2 = blockOffset*tmp1;-    for (modOffset = 0; modOffset < rts; ++modOffset) {-      hDim_t tensorOffset = tmp2 + modOffset;-      hInt_t sum = 0;-      for (i = 0; i < p-1; ++i) {-        sum += y[(tensorOffset + i*rts)*tupSize];-      }-      for (i = 0; i < p-1; ++i) {-        y[(tensorOffset + i*rts)*tupSize] += sum;-      }-    }-  }-}--void ppNormSqR (void* y, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs) {-#ifdef DEBUG_MODE-  ASSERT (q==0);-#endif-    hDim_t p = pe.prime;-    hShort_t e = pe.exponent;-    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {-      pNormSqR (((hInt_t*)y)+tupIdx, tupSize, lts*ipow(p,e-1), rts, p);-    }-}--void tensorNormSqR (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE) {-#ifdef STATS-    normrCtr++;-    struct timespec s1,t1;-    clock_gettime(CLOCK_REALTIME, &s1);-#endif-#ifdef DEBUG_MODE-    printf("\n\nEntered tensorNormSqR\ttotm=%" PRId32 "\tnumFacts=%" PRId16 "\n[", totm, sizeOfPE);-    hDim_t i;-    for(i = 0; i < totm; i++) {-        printf("%" PRId64 ",", y[i]);-    }-    printf("]\n[");-    for(i = 0; i < sizeOfPE; i++) {-        printf("(%" PRId32 ",%" PRId16 "),", peArr[i].prime, peArr[i].exponent);-    }-    printf("]\n");-#endif--  hInt_t* tempSpace = (hInt_t*)malloc(totm*tupSize*sizeof(hInt_t));-  for(hDim_t i = 0; i < totm*tupSize; i++) {-    tempSpace[i]=y[i];-  }--  tensorFuser(y, tupSize, ppNormSqR, totm, peArr, sizeOfPE, (hInt_t*)0);--  //do dot product and return in index 0-  for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {-    hInt_t dotprod = 0;-    for(hDim_t i = 0; i < totm; i++) {-      dotprod += (tempSpace[i*tupSize+tupIdx]*y[i*tupSize+tupIdx]);-    }--    y[tupIdx] = dotprod;-  }--  free(tempSpace);--#ifdef STATS-    clock_gettime(CLOCK_REALTIME, &t1);-    lrTime = tsAdd(normrTime, tsSubtract(t1,s1));-#endif-}
+ Crypto/Lol/Cyclotomic/Tensor/CTensor/norm.cpp view
@@ -0,0 +1,69 @@+#include "types.h"+#include "tensor.h"++template <typename ring> void pNormSq (ring* y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p)+{+  hDim_t blockOffset;+  hDim_t modOffset;+  hDim_t i;++  if(p==2) {return;}++  hDim_t tmp1 = rts*(p-1);+  for (blockOffset = 0; blockOffset < lts; ++blockOffset) {+    hDim_t tmp2 = blockOffset*tmp1;+    for (modOffset = 0; modOffset < rts; ++modOffset) {+      hDim_t tensorOffset = tmp2 + modOffset;+      ring sum = 0;+      for (i = 0; i < p-1; ++i) {+        sum += y[(tensorOffset + i*rts)*tupSize];+      }+      for (i = 0; i < p-1; ++i) {+        y[(tensorOffset + i*rts)*tupSize] += sum;+      }+    }+  }+}++extern "C" void tensorNormSqR (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)+{+  hInt_t* tempSpace = (hInt_t*)malloc(totm*tupSize*sizeof(hInt_t));+  for(hDim_t i = 0; i < totm*tupSize; i++) {+    tempSpace[i]=y[i];+  }++  tensorFuserPrime(y, tupSize, pNormSq, totm, peArr, sizeOfPE, (hInt_t*)0);++  //do dot product and return in index 0+  for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {+    hInt_t dotprod = 0;+    for(hDim_t i = 0; i < totm; i++) {+      dotprod += (tempSpace[i*tupSize+tupIdx]*y[i*tupSize+tupIdx]);+    }++    y[tupIdx] = dotprod;+  }++  free(tempSpace);+}++extern "C" void tensorNormSqD (hShort_t tupSize, double* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE)+{+  double* tempSpace = (double*)malloc(totm*tupSize*sizeof(double));+  for(hDim_t i = 0; i < totm*tupSize; i++) {+    tempSpace[i]=y[i];+  }+  tensorFuserPrime(y, tupSize, pNormSq, totm, peArr, sizeOfPE, (hInt_t*)0);++  //do dot product and return in index 0+  for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {+    double dotprod = 0;+    for(hDim_t i = 0; i < totm; i++) {+      dotprod += (tempSpace[i*tupSize+tupIdx]*y[i*tupSize+tupIdx]);+    }++    y[tupIdx] = dotprod;+  }++  free(tempSpace);+}
− Crypto/Lol/Cyclotomic/Tensor/CTensor/random.c
@@ -1,74 +0,0 @@--#include <math.h>-#include <stdlib.h>-#include "tensorTypes.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_t* ruinv)-{-	if(p == 2)-  {-      return;-  }-  hDim_t blockOffset, modOffset, tensorOffset;-	double *tempSpace = (double*)malloc((p-1)*sizeof(double));-  hDim_t temp1 = rts*(p-1);-  for(blockOffset = 0; blockOffset < lts; blockOffset++)-  {-    hDim_t temp2 = blockOffset*temp1;-    for(modOffset = 0; modOffset < rts; modOffset++)-    {-      tensorOffset = temp2 + modOffset;-      hDim_t row, col;-      -      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];-        }-        for(col = (p>>1)+1; col <= p-1; col++)-        {-          acc += 2 * ruinv[((row*col) % p)*rustride*tupSize].imag * y[(tensorOffset+rts*(col-1))*tupSize];-        }-        tempSpace[row] = acc/sqrt(2);-      }-      -      for(row = 0; row < p-1; row++)-      {-        y[(tensorOffset+rts*row)*tupSize] = tempSpace[row];-      }-    }-  }-  free(tempSpace);-}--void ppD (void *y, hShort_t tupSize, hDim_t lts, hDim_t rts, PrimeExponent pe, void *ruinv, hInt_t* qs)-{-    hDim_t p = pe.prime;-    hDim_t e = pe.exponent;-#ifdef DEBUG_MODE-    ASSERT(e != 0);-#endif-    hDim_t mprime = ipow(p,e-1);-    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {-      primeD (((double*)y)+tupIdx, tupSize, lts*mprime, rts, p, mprime, ((complex_t*)ruinv)+tupIdx);-    }-}--//the contents of y will be destroyed, but should be initialized in Haskell-land to independent Guassians over the reals-void tensorGaussianDec (hShort_t tupSize, double *y, hDim_t totm, PrimeExponent *peArr, hShort_t sizeOfPE, complex_t** ruinv)-{-  void** ruinvs = (void**)malloc(sizeOfPE*sizeof(void*));-  hShort_t i;-  for(i = 0; i < sizeOfPE; i++)-  {-      ruinvs[i] = (void*) (ruinv[i]);-  }-    -	tensorFuserCRT (y, tupSize, ppD, totm, peArr, sizeOfPE, ruinvs, (hInt_t*)0);-	-	free(ruinvs);-}
+ Crypto/Lol/Cyclotomic/Tensor/CTensor/random.cpp view
@@ -0,0 +1,53 @@+#include "types.h"+#include "tensor.h"+#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)+{+	if(p == 2) {+    return;+  }+  hDim_t blockOffset, modOffset, tensorOffset;+	double *tempSpace = (double*)malloc((p-1)*sizeof(double));+  hDim_t temp1 = rts*(p-1);+  for(blockOffset = 0; blockOffset < lts; blockOffset++) {+    hDim_t temp2 = blockOffset*temp1;+    for(modOffset = 0; modOffset < rts; modOffset++) {+      tensorOffset = temp2 + modOffset;+      hDim_t row, col;++      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];+        }+        for(col = (p>>1)+1; col <= p-1; col++) {+          acc += 2 * ruinv[((row*col) % p)*rustride*tupSize].imag * y[(tensorOffset+rts*(col-1))*tupSize];+        }+        tempSpace[row] = acc/sqrt(2);+      }++      for(row = 0; row < p-1; row++) {+        y[(tensorOffset+rts*row)*tupSize] = tempSpace[row];+      }+    }+  }+  free(tempSpace);+}++void ppD (double *y, hShort_t tupSize, hDim_t lts, hDim_t rts, PrimeExponent pe, Complex *ruinv)+{+  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);+}++//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)+{+	tensorFuserCRT (y, tupSize, ppD, totm, peArr, sizeOfPE, ruinv, (hInt_t*)0);+}
+ Crypto/Lol/Cyclotomic/Tensor/CTensor/tensor.h view
@@ -0,0 +1,56 @@+#ifndef TENSOR_CPP_+#define TENSOR_CPP_++#include "types.h"+#include "common.h"+#ifdef __cplusplus+template <typename ring>+using primeFunc = void (*) (ring*, hShort_t, hDim_t, hDim_t, hDim_t);++template <typename ringy, typename ringru>+using primeCRTFunc = void (*) (ringy*, hShort_t, hDim_t, hDim_t, PrimeExponent, ringru*);++//for square transforms+template <typename ring> void tensorFuserPrime (ring* y, hShort_t tupSize, primeFunc<ring> f, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs)+{+  hDim_t lts = totm;+  hDim_t rts = 1;+  hShort_t i;++  for (i = 0; i < sizeOfPE; ++i) {+    PrimeExponent pe = peArr[i];+    hDim_t ipow_pe = ipow(pe.prime, (pe.exponent-1));+    hDim_t dim = (pe.prime-1) * ipow_pe;  // the totient of pe+    lts /= dim;+    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {+      if(qs) {+        Zq::q = qs[tupIdx]; // global update+      }+      (*f) (y+tupIdx, tupSize, lts*ipow_pe, rts, pe.prime);+    }+    rts *= dim;+  }+}++template <typename ringy, typename ringru> void tensorFuserCRT (ringy* y, hShort_t tupSize, primeCRTFunc<ringy,ringru> f, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, ringru** ru, hInt_t* qs)+{+  hDim_t lts = totm;+  hDim_t rts = 1;+  hShort_t i;++  for (i = 0; i < sizeOfPE; ++i) {+    PrimeExponent pe = peArr[i];+    hDim_t ipow_pe = ipow(pe.prime, (pe.exponent-1));+    hDim_t dim = (pe.prime-1) * ipow_pe;  // the totient of pe+    lts /= dim;+    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {+      if(qs) {+        Zq::q = qs[tupIdx]; // global update+      }+      (*f) (y+tupIdx, tupSize, lts, rts, pe, ru[i]+tupIdx);+    }+    rts *= dim;+  }+}+#endif /* __cplusplus */+#endif /* TENSOR_CPP_ */
− Crypto/Lol/Cyclotomic/Tensor/CTensor/tensorTypes.h
@@ -1,231 +0,0 @@-
-#ifndef TENSORTYPES_H_
-#define TENSORTYPES_H_
-
-
-// remove next line for more efficient code
-//#define DEBUG_MODE
-
-
-#include <stdbool.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-
-#define ASSERT(EXP) { \
-	if (!(EXP)) { \
-		fprintf (stderr, "Assertion in file '%s' line %d : " #EXP "  is false\n", __FILE__, __LINE__); \
-		exit(-1); \
-	} \
-}
-
-
-//timers and counters
-#ifdef STATS
-extern int crtRqCtr;
-extern int crtInvRqCtr;
-extern int crtCCtr;
-extern int crtInvCCtr;
-
-extern int gprCtr;
-extern int gpcCtr;
-extern int gprqCtr;
-extern int gdrCtr;
-extern int gdrqCtr;
-extern int giprCtr;
-extern int gipcCtr;
-extern int giprqCtr;
-extern int gidrCtr;
-extern int gidrqCtr;
-extern int gcrqCtr;
-extern int gccCtr;
-extern int gicrqCtr;
-extern int giccCtr;
-
-extern int lrqCtr;
-extern int lrCtr;
-extern int ldCtr;
-extern int lcCtr;
-extern int lirqCtr;
-extern int lirCtr;
-extern int lidCtr;
-extern int licCtr;
-
-extern int normrCtr;
-
-extern int mulCtr;
-extern struct timespec mulTime;
-extern int addCtr;
-extern struct timespec addTime;
-
-extern struct timespec lrqTime;
-extern struct timespec lrTime;
-extern struct timespec ldTime;
-extern struct timespec lcTime;
-extern struct timespec lirqTime;
-extern struct timespec lirTime;
-extern struct timespec lidTime;
-extern struct timespec licTime;
-
-extern struct timespec normrTime;
-
-extern struct timespec crttime1;
-extern struct timespec crttime2;
-extern struct timespec crttime3;
-extern struct timespec crttime4;
-extern struct timespec crtInvRqTime;
-extern struct timespec crtCTime;
-extern struct timespec crtInvCTime;
-
-extern struct timespec gprTime;
-extern struct timespec gpcTime;
-extern struct timespec gprqTime;
-extern struct timespec gdrTime;
-extern struct timespec gdrqTime;
-extern struct timespec giprTime;
-extern struct timespec gipcTime;
-extern struct timespec giprqTime;
-extern struct timespec gidrTime;
-extern struct timespec gidrqTime;
-extern struct timespec gcrqTime;
-extern struct timespec gccTime;
-#endif
-
-typedef int64_t hInt_t ;
-typedef int32_t hDim_t ;
-typedef int16_t hShort_t ;
-typedef int8_t hByte_t ;
-
-typedef struct
-{
-	hDim_t prime;
-	hShort_t exponent;
-}  PrimeExponent;
-
-
-typedef struct
-{
-	double real;
-	double imag;
-} complex_t;
-
-#define CMPLX_ADD(a,b)  ((complex_t){((a).real + (b).real), ((a).imag + (b).imag)})
-#define CMPLX_ADD3(a,b,c)  ((complex_t){((a).real + (b).real + (c).real), ((a).imag + (b).imag + (c).imag)})
-#define CMPLX_ADD4(a,b,c,d)  ((complex_t){((a).real + (b).real + (c).real + (d).real), ((a).imag + (b).imag + (c).imag + (d).imag)})
-#define CMPLX_ADD5(a,b,c,d,e)  ((complex_t){((a).real + (b).real + (c).real + (d).real + (e).real), ((a).imag + (b).imag + (c).imag + (d).imag + (e).imag)})
-#define CMPLX_ADD6(a,b,c,d,e,f)  ((complex_t){((a).real + (b).real + (c).real + (d).real + (e).real + (f).real), ((a).imag + (b).imag + (c).imag + (d).imag + (e).imag + (f).imag)})
-#define CMPLX_ADD7(a,b,c,d,e,f,g)  ((complex_t){((a).real + (b).real + (c).real + (d).real + (e).real + (f).real + (g).real), ((a).imag + (b).imag + (c).imag + (d).imag + (e).imag + (f).imag + (g).imag)})
-
-#define CMPLX_SUB(a,b)  ((complex_t){((a).real - (b).real), ((a).imag - (b).imag)})
-#define CMPLX_MUL(a,b)  ((complex_t){((a).real*(b).real - (a).imag*(b).imag), \
-	                                  (a).real*(b).imag + (a).imag*(b).real})
-#define CMPLX_DIV(a,b)  ((complex_t){((a).real*(b).real + (a).imag*(b).imag)/((b).real*(b).real+(b).imag*(b).imag), \
-                                     ((a).imag*(b).real - (a).real*(b).imag)/((b).real*(b).real+(b).imag*(b).imag)})
-
-// 'inside' operators
-#define CMPLX_IADD(a,b)  { (a).real += (b).real;  (a).imag += (b).imag; }
-#define CMPLX_ISUB(a,b)  { (a).real -= (b).real;  (a).imag -= (b).imag; }
-#define CMPLX_IMUL(a,b)  { double temp = ((a).real*(b).real - (a).imag*(b).imag); \
-	                       (a).imag = ((a).real*(b).imag + (a).imag*(b).real); \
-	                       (a).real = temp; }
-
-// calculates base ** exp
-hDim_t ipow(hDim_t base, hShort_t exp);
-complex_t cmplxpow(complex_t base, hShort_t exp);
-hInt_t qpow(hInt_t base, hShort_t exp, hInt_t q);
-
-hInt_t reciprocal (hInt_t a, hInt_t b);
-
-struct  timespec  tsSubtract (struct  timespec  time1, struct  timespec  time2);
-struct  timespec  tsAdd (struct  timespec  time1, struct  timespec  time2);
-const  char  *tsShow (struct  timespec  binaryTime, bool  inLocal, const  char  *format);
-
-void getStats();
-
-void mulRq (hShort_t tupSize, hInt_t* a, hInt_t* b, hDim_t totm, hInt_t* qs);
-//void mulMq (hInt_t* a, const hInt_t* b, const hDim_t totm, const hByte_t logr, const hInt_t k, const hInt_t q);
-void mulC (hShort_t tupSize, complex_t* a, complex_t* b, hDim_t totm);
-
-void addR (hShort_t tupSize, hInt_t* a, hInt_t* b, hDim_t totm);
-void addRq (hShort_t tupSize, hInt_t* a, const hInt_t* b, const hDim_t totm, const hInt_t* qs);
-//void addMq (hInt_t* a, const hInt_t* b, const hDim_t totm, const hByte_t logr, const hInt_t k, const hInt_t q);
-void addC (hShort_t tupSize, complex_t* a, complex_t* b, hDim_t totm);
-void addD (hShort_t tupSize, double* a, double* b, hDim_t totm);
-
-typedef void (*funcPtr) (void* outputVec, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* qs);
-void tensorFuser (void* y, hShort_t tupSize, funcPtr f, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs);
-
-typedef void (*normFuncPtr) (void* outputVec, hShort_t tupSize, PrimeExponent pe, hDim_t lts, hDim_t rts, hInt_t* output, hInt_t* qs);
-void tensorFuserNorm (void* y, hShort_t tupSize, normFuncPtr f, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* output, hInt_t q);
-
-typedef void (*crtFuncPtr) (void* y, hShort_t tupSize, hDim_t lts, hDim_t rts, PrimeExponent pe, void* ru, hInt_t* q);
-void tensorFuserCRT (void* y, hShort_t tupSize, crtFuncPtr f, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, void** ru, hInt_t* q);
-
-void tensorGPowR (hShort_t tupSize, hInt_t* x, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE);
-
-void tensorGPowRq (hShort_t tupSize, hInt_t* x, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs);
-
-void tensorGPowC (hShort_t tupSize, complex_t* x, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE);
-
-void tensorGDecR (hShort_t tupSize, hInt_t* x, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE);
-
-void tensorGDecRq (hShort_t tupSize, hInt_t* x, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs);
-
-void tensorGInvPowR (hShort_t tupSize, hInt_t* x, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE);
-
-void tensorGInvPowRq (hShort_t tupSize, hInt_t* x, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs);
-
-void tensorGInvPowC (hShort_t tupSize, complex_t* x, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE);
-
-void tensorGInvDecR (hShort_t tupSize, hInt_t* x, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE);
-
-void tensorGInvDecRq (hShort_t tupSize, hInt_t* x, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs);
-
-void tensorGCRTRq (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t** gcoeffs, hInt_t* qs);
-
-void tensorGInvCRTRq (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t** gcoeffs, hInt_t* qs);
-
-void tensorGCRTC (hShort_t tupSize, complex_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, complex_t** gcoeffs);
-
-void tensorGInvCRTC (hShort_t tupSize, complex_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, complex_t** gcoeffs);
-
-
-
-void tensorLRq (hShort_t tupSize, hInt_t* x, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs);
-
-void tensorLR (hShort_t tupSize, hInt_t* x, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE);
-
-void tensorLDouble (hShort_t tupSize, double* x, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE);
-
-void tensorLC (hShort_t tupSize, complex_t* x, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE);
-
-void tensorLInvRq (hShort_t tupSize, hInt_t* x, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t* qs);
-
-void tensorLInvR (hShort_t tupSize, hInt_t* x, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE);
-
-void tensorLInvDouble (hShort_t tupSize, double* x, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE);
-
-void tensorLInvC (hShort_t tupSize, complex_t* x, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE);
-
-
-
-void tensorCRTRq (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t** ru, hInt_t* qs);
-
-void tensorCRTC (hShort_t tupSize, complex_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, complex_t** ru);
-
-void tensorCRTInvRq (hShort_t tupSize, hInt_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, hInt_t** ru, hInt_t* minv, hInt_t* qs);
-
-void tensorCRTInvC (hShort_t tupSize, complex_t* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, complex_t** ru, complex_t* minv);
-
-
-
-void tensorGaussianDec (hShort_t tupSize, double* y, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE, complex_t** ru);
-
-void tensorNormSqR (hShort_t tupSize, hInt_t* x, hDim_t totm, PrimeExponent* peArr, hShort_t sizeOfPE);
-
-
-#endif /* TENSORTYPES_H_ */
-
+ Crypto/Lol/Cyclotomic/Tensor/CTensor/types.h view
@@ -0,0 +1,138 @@+
+#ifndef TENSORTYPES_H_
+#define TENSORTYPES_H_
+
+#include <inttypes.h>
+
+typedef int64_t hInt_t ;
+typedef int32_t hDim_t ;
+typedef int16_t hShort_t ;
+typedef int8_t hByte_t ;
+
+typedef struct
+{
+  hDim_t prime;
+  hShort_t exponent;
+} PrimeExponent;
+
+
+hInt_t reciprocal (hInt_t a, hInt_t b);
+
+//http://stackoverflow.com/questions/37572628
+#ifdef __cplusplus
+//http://stackoverflow.com/a/4421719
+class Zq
+{
+public:
+  hInt_t x;
+
+  static hInt_t q; // declared here, defined in generalfuncs.cpp
+
+  Zq& operator=(const hInt_t& c)
+  {
+    this->x = c % q;
+    return *this;
+  }
+  Zq& operator+=(const Zq& b)
+  {
+    this->x += b.x;
+    this->x %= q;
+    return *this;
+  }
+  Zq& operator-=(const Zq& b)
+  {
+    this->x -= b.x;
+    this->x %= q;
+    return *this;
+  }
+  Zq& operator*=(const Zq& b)
+  {
+    this->x *= b.x;
+    this->x %= q;
+    return *this;
+  }
+  Zq& operator/=(const Zq& b)
+  {
+    Zq binv;
+    binv = reciprocal(q,b.x);
+    *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;
+  return a;
+}
+inline Zq operator-(Zq a, const Zq& b)
+{
+  a -= b;
+  return a;
+}
+inline Zq operator*(Zq a, const Zq& b)
+{
+  a *= b;
+  return a;
+}
+inline Zq operator/(Zq a, const Zq& b)
+{
+  a /= b;
+  return a;
+}
+
+void canonicalizeZq (Zq* y, hShort_t tupSize, hDim_t totm, hInt_t* qs);
+
+class Complex
+{
+public:
+  double real;
+  double imag;
+
+  Complex& operator=(const hInt_t& c)
+  {
+    this->real = c;
+    this->imag = 0;
+    return *this;
+  }
+  Complex& operator+=(const Complex& b)
+  {
+    this->real = this->real+b.real;
+    this->imag = this->imag+b.imag;
+    return *this;
+  }
+  Complex& operator-=(const Complex& b)
+  {
+    this->real = this->real-b.real;
+    this->imag = this->imag-b.imag;
+    return *this;
+  }
+  Complex& operator*=(const Complex& b)
+  {
+    double a = this->real;
+    this->real = (a*b.real)-(this->imag*b.imag);
+    this->imag = (a*b.imag)+(this->imag*b.real);
+    return *this;
+  }
+};
+inline Complex operator+(Complex a, const Complex& b)
+{
+  a += b;
+  return a;
+}
+inline Complex operator-(Complex a, const Complex& b)
+{
+  a -= b;
+  return a;
+}
+inline Complex operator*(Complex a, const Complex& b)
+{
+  a *= b;
+  return a;
+}
+
+#endif /* __cplusplus */
+#endif /* TENSORTYPES_H_ */
+ Crypto/Lol/Cyclotomic/Tensor/CTensor/zq.cpp view
@@ -0,0 +1,36 @@+#include "types.h"+#include "common.h"++// a is the field size. we are looking for reciprocal of b+hInt_t reciprocal (hInt_t a, hInt_t b)+{+  hInt_t fieldSize = a;++  hInt_t y = 1;+  hInt_t lasty = 0;+  while (b != 0) {+    hInt_t quotient = a / b;+    hInt_t tmp = a % b;+    a = b;+    b = tmp;+    tmp = y;+    y  = lasty - quotient*y;+    lasty = tmp;+  }+  ASSERT (a==1);  // if this one fails, then b is not invertible mod a++  // this actually returns EITHER the reciprocal OR reciprocal + fieldSize+  hInt_t res = lasty + fieldSize;+  return res;+}++void canonicalizeZq (Zq* y, hShort_t tupSize, hDim_t totm, hInt_t* qs) {+  for(int tupIdx = 0; tupIdx<tupSize; tupIdx++) {+    hInt_t q = qs[tupIdx];+    for(hDim_t j = 0; j < totm; j++) {+      if(y[j*tupSize+tupIdx].x<0) {+        y[j*tupSize+tupIdx].x+=q;+      }+    }+  }+}
Crypto/Lol/Cyclotomic/Tensor/RepaTensor.hs view
@@ -14,13 +14,19 @@ import Crypto.Lol.Cyclotomic.Tensor.RepaTensor.Dec import Crypto.Lol.Cyclotomic.Tensor.RepaTensor.Extension import Crypto.Lol.Cyclotomic.Tensor.RepaTensor.GL-import Crypto.Lol.Cyclotomic.Tensor.RepaTensor.RTCommon  as RT-import Crypto.Lol.LatticePrelude                         as LP hiding-                                                                ((!!))+import Crypto.Lol.Cyclotomic.Tensor.RepaTensor.RTCommon  as RT hiding+                                                                ((++))+import Crypto.Lol.Prelude                                as LP import Crypto.Lol.Reflects import Crypto.Lol.Types.FiniteField                      as FF import Crypto.Lol.Types.IZipVector+import Crypto.Lol.Types.Proto+import Crypto.Lol.Types.RRq+import Crypto.Lol.Types.ZqBasic +import Crypto.Proto.RLWE.Kq+import Crypto.Proto.RLWE.Rq+ import Algebra.Additive     as Additive (C) import Algebra.Module       as Module (C) import Algebra.ZeroTestable as ZeroTestable (C)@@ -28,14 +34,17 @@ import Control.Applicative  hiding ((*>)) import Control.Arrow        hiding (arr) import Control.DeepSeq      (NFData (rnf))+import Control.Monad.Except (throwError) import Control.Monad.Random import Data.Coerce import Data.Constraint      hiding ((***)) import Data.Foldable        as F import Data.Maybe+import Data.Sequence        as S (fromList) import Data.Traversable     as T-import Data.Vector          as V hiding (force)-import Data.Vector.Unboxed  as U hiding (force)+import Data.Vector          as V hiding (force, (++))+import Data.Vector.Unboxed  as U hiding (force, (++))+ import Test.QuickCheck  -- | An implementation of 'Tensor' backed by repa.@@ -45,6 +54,52 @@  deriving instance Show r => Show (RT m r) +instance (Fact m, Reflects q Int64) => Protoable (RT m (ZqBasic q Int64)) where+  type ProtoType (RT m (ZqBasic q Int64)) = Rq++  toProto (RT (Arr xs)) =+    let m = fromIntegral $ proxy valueFact (Proxy::Proxy m)+        q = proxy value (Proxy::Proxy q) :: Int64+    in Rq m (fromIntegral q) $ S.fromList $ RT.toList $ RT.map lift xs+  toProto x@(ZV _) = toProto $ toRT x++  fromProto (Rq m' q' xs) =+    let m = proxy valueFact (Proxy::Proxy m) :: Int+        q = proxy value (Proxy::Proxy q) :: Int64+        n = proxy totientFact (Proxy::Proxy m)+        xs' = RT.fromList (Z:.n) $ LP.map reduce $ F.toList xs+        len = F.length xs+    in if m == fromIntegral m' && len == n && fromIntegral q == q'+       then return $ RT $ Arr xs'+       else throwError $+            "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 q ++ ", got " ++ show q' ++ "."++instance (Fact m, Reflects q Double) => Protoable (RT m (RRq q Double)) where+  type ProtoType (RT m (RRq q Double)) = Kq++  toProto (RT (Arr xs)) =+    let m = fromIntegral $ proxy valueFact (Proxy::Proxy m)+        q = 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+        n = proxy totientFact (Proxy::Proxy m)+        xs' = RT.fromList (Z:.n) $ LP.map reduce $ F.toList xs+        len = F.length xs+    in if m == fromIntegral m' && len == n && q == q'+       then return $ RT $ Arr xs'+       else throwError $+            "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' ++ "."+ instance Eq r => Eq (RT m r) where   (ZV a) == (ZV b) = a == b   (RT a) == (RT b) = a == b@@ -84,7 +139,6 @@   entailIndexT  = tag $ Sub Dict   entailEqT     = tag $ Sub Dict   entailZTT     = tag $ Sub Dict-  --entailRingT   = tag $ Sub Dict   entailNFDataT = tag $ Sub Dict   entailRandomT = tag $ Sub Dict   entailShowT   = tag $ Sub Dict@@ -138,11 +192,6 @@   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) -  unzipTElt (RT (Arr arr)) = (RT . Arr . fromUnboxed (extent arr)) ***-                             (RT . Arr . fromUnboxed (extent arr)) $-                             U.unzip $ toUnboxed arr-  unzipTElt v = unzipTElt $ toRT v-   unzipT v@(RT _) = unzipT $ toZV v   unzipT (ZV v) = ZV *** ZV $ unzipIZV v @@ -172,7 +221,6 @@   {-# INLINABLE fmapT #-}   {-# INLINABLE fmapTM #-}   {-# INLINABLE zipWithT #-}-  {-# INLINABLE unzipTElt #-}   {-# INLINABLE unzipT #-}  @@ -240,13 +288,15 @@     => Module.C (GF fp d) (RT m fp) where    r *> v = case v of-    RT (Arr arr) -> RT $ Arr $ RT.fromList (extent arr) $ unCoeffs $ r *> Coeffs $ RT.toList arr-    ZV zv -> ZV $ fromJust $ iZipVector $ V.fromList $ unCoeffs $ r *> Coeffs $ V.toList $ unIZipVector zv+    RT (Arr arr) -> RT $ Arr $ RT.fromList (extent arr)+                    $ unCoeffs $ r *> Coeffs $ RT.toList arr+    ZV zv -> ZV $ fromJust $ iZipVector $ V.fromList+             $ unCoeffs $ r *> Coeffs $ V.toList $ unIZipVector zv  ---------- Miscellaneous instances ----------  instance (Unbox r, Random (Arr m r)) => Random (RT m r) where-  random = runRand $ RT <$> (liftRand random)+  random = runRand $ RT <$> liftRand random    randomR = error "randomR nonsensical for RT" 
Crypto/Lol/Cyclotomic/Tensor/RepaTensor/CRT.hs view
@@ -1,5 +1,6 @@-{-# LANGUAGE ConstraintKinds, FlexibleContexts, GADTs, NoImplicitPrelude,-             ScopedTypeVariables #-}+{-# LANGUAGE ConstraintKinds, FlexibleContexts, GADTs,+             MultiParamTypeClasses, NoImplicitPrelude, ScopedTypeVariables+             #-}  -- | Functions to support the chinese remainder transform on Repa arrays @@ -12,17 +13,16 @@  import Crypto.Lol.CRTrans import Crypto.Lol.Cyclotomic.Tensor-import Crypto.Lol.Cyclotomic.Tensor.RepaTensor.GL import Crypto.Lol.Cyclotomic.Tensor.RepaTensor.RTCommon as RT-import Crypto.Lol.LatticePrelude                        as LP+import Crypto.Lol.Prelude                               as LP  import Control.Applicative import Data.Coerce import Data.Singletons.Prelude  -- | Embeds a scalar into the CRT basis (when it exists).-scalarCRT' :: forall m r . (Fact m, CRTrans r, Unbox r)-              => Maybe (r -> Arr m r)+scalarCRT' :: forall mon m r . (Fact m, CRTrans mon r, Unbox r)+              => mon (r -> Arr m r) {-# INLINABLE scalarCRT' #-} scalarCRT'   = let pps = proxy ppsFact (Proxy::Proxy m)@@ -30,52 +30,56 @@     in pure $ Arr . force . fromFunction sz . const  -- | Multiply by @g_m@ in the CRT basis (when it exists).-mulGCRT' :: forall m r . (Fact m, CRTrans r, Unbox r, Elt r)-            => Maybe (Arr m r -> Arr  m r)+mulGCRT' :: (Fact m, CRTrans mon r, Unbox r, Elt r)+            => mon (Arr m r -> Arr  m r) {-# INLINABLE mulGCRT' #-} mulGCRT' = (coerce (\x -> force . RT.zipWith (*) x) `asTypeOf` asTypeOf) <$> gCRT  -- | Divide by @g@ in the CRT basis (when it exists).-divGCRT' :: (Fact m, CRTrans r, IntegralDomain r, ZeroTestable r,-             Unbox r, Elt r) => Maybe (Arr m r -> Arr m r)+divGCRT' :: (Fact m, CRTrans mon r, Unbox r, Elt r) => mon (Arr m r -> Arr m r) {-# INLINABLE divGCRT' #-}-divGCRT' =  (coerce (\x -> force . RT.zipWith (*) x) `asTypeOf` asTypeOf) <$> gInvCRT+divGCRT' = (coerce (\x -> force . RT.zipWith (*) x) `asTypeOf` asTypeOf) <$> gInvCRT --- | The representation of @g@ in the CRT basis (when it exists).-gCRT :: (Fact m, CRTrans r, Unbox r, Elt r) => Maybe (Arr m r)-{-# INLINABLE gCRT #-}-gCRT = fCRT <*> pure (fGPow $ scalarPow' LP.one)+wrapVector :: forall mon m r . (Monad mon, Fact m, Ring r, Unbox r, Elt r)+              => TaggedT m mon (Matrix r) -> mon (Arr m r)+wrapVector v = do+  vmat <- proxyT v (Proxy::Proxy m)+  let n = proxy totientFact (Proxy::Proxy m)+  return $ coerce $ force $ RT.fromFunction (Z:.n)+    (\(Z:.i) -> indexM vmat i 0) --- | The representation of @g^{ -1 }@ in the CRT basis (when it exists).-gInvCRT:: (Fact m, CRTrans r, IntegralDomain r,-           ZeroTestable r, Unbox r, Elt r)-          => Maybe (Arr m r)+gCRT, gInvCRT :: (Fact m, CRTrans mon r, Unbox r, Elt r) => mon (Arr m r)+{-# INLINABLE gCRT #-} {-# INLINABLE gInvCRT #-}-gInvCRT = fCRT <*> fGInvPow (scalarPow' LP.one) +-- | The coefficient vector of @g@ in the CRT basis (when it exists).+gCRT = wrapVector gCRTM+-- | The coefficient vector of @g^{ -1 }@ in the CRT basis (when it exists).+gInvCRT = wrapVector gInvCRTM+ fCRT, fCRTInv ::-  forall m r . (Fact m, CRTrans r, Unbox r, Elt r)-  => Maybe (Arr m r -> Arr m r)+  forall mon m r . (Fact m, CRTrans mon r, Unbox r, Elt r)+  => mon (Arr m r -> Arr m r)  {-# INLINABLE fCRT #-} {-# INLINABLE fCRTInv #-} --- | The chinese remainder transform.--- Exists if and only if crt exists for all prime powers.+-- | The Chinese Remainder Transform.+-- Exists if and only if CRT exists for all prime powers. fCRT = evalM $ fTensor ppCRT  -- divide by mhat after doing crtInv'--- | The inverse chinese remainder transform.--- Exists if and only if crt exists for all prime powers.-fCRTInv = do -- in Maybe-  (_, mhatInv) :: (CRTInfo r) <- proxyT crtInfoFact (Proxy :: Proxy m)+-- | The inverse Chinese Remainder Transform.+-- Exists if and only if CRT exists for all prime powers.+fCRTInv = do+  (_, mhatInv) :: (CRTInfo r) <- proxyT crtInfo (Proxy :: Proxy m)   let totm = proxy totientFact (Proxy :: Proxy m)       divMhat = trans totm $ RT.map (*mhatInv)   evalM $ (divMhat .*) <$> fTensor ppCRTInv'  ppDFT, ppDFTInv', ppCRT, ppCRTInv' ::-  forall pp r . (PPow pp, CRTrans r, Unbox r, Elt r)-  => TaggedT pp Maybe (Trans r)+  forall mon pp r . (PPow pp, CRTrans mon r, Unbox r, Elt r)+  => TaggedT pp mon (Trans r)  {-# INLINABLE ppDFT #-} {-# INLINABLE ppDFTInv' #-}@@ -139,8 +143,8 @@  -- DFT_p, CRT_p, scaled DFT_p^{ -1 } and CRT_p^{ -1 } pDFT, pDFTInv', pCRT, pCRTInv' ::-  forall p r . (Prim p, CRTrans r, Unbox r, Elt r)-  => TaggedT p Maybe (Trans r)+  forall mon p r . (Prime p, CRTrans mon r, Unbox r, Elt r)+  => TaggedT p mon (Trans r)  {-# INLINABLE pDFT #-} {-# INLINABLE pDFTInv' #-}@@ -150,7 +154,7 @@ pDFT = let pval = proxy valuePrime (Proxy::Proxy p)        in if pval == 2           then return butterfly-          else do (omegaPPow, _) <- crtInfoPrime+          else do (omegaPPow, _) <- crtInfo                   return $ trans pval $ mulMat $ force $                          fromFunction (Z :. pval :. pval)                                           (\(Z:.i:.j) -> omegaPPow (i*j))@@ -158,7 +162,7 @@ pDFTInv' = let pval = proxy valuePrime (Proxy::Proxy p)            in if pval == 2               then return butterfly-              else do (omegaPPow, _) <- crtInfoPrime+              else do (omegaPPow, _) <- crtInfo                       return $ trans pval $ mulMat $ force $                              fromFunction (Z :. pval :. pval)                                               (\(Z:.i:.j) -> omegaPPow (-i*j))@@ -166,7 +170,7 @@ pCRT = let pval = proxy valuePrime (Proxy::Proxy p)        in if pval == 2           then return $ Id 1-          else do (omegaPPow, _) <- crtInfoPrime+          else do (omegaPPow, _) <- crtInfo                   return $ trans (pval-1) $ mulMat $ force $                          fromFunction (Z :. pval-1 :. pval-1)                                           (\(Z:.i:.j) -> omegaPPow ((i+1)*j))@@ -176,7 +180,7 @@   let pval = proxy valuePrime (Proxy::Proxy p)   in if pval == 2 then return $ Id 1      else do-       (omegaPPow, _) <- crtInfoPrime+       (omegaPPow, _) <- crtInfo        return $ trans (pval-1) $  mulMat $ force $               fromFunction (Z :. pval-1 :. pval-1)                                (\(Z:.i:.j) -> omegaPPow (negate i*(j+1)) -@@ -184,8 +188,8 @@  -- twiddle factors for DFT_pp and CRT_pp decompositions ppTwid, ppTwidHat ::-  forall pp r . (PPow pp, CRTrans r, Unbox r, Elt r)-  => Bool -> TaggedT pp Maybe (Trans r)+  forall mon pp r . (PPow pp, CRTrans mon r, Unbox r, Elt r)+  => Bool -> TaggedT pp mon (Trans r)  {-# INLINABLE ppTwid #-} {-# INLINABLE ppTwidHat #-}@@ -194,7 +198,7 @@   let pp@(p,e) = proxy ppPPow (Proxy :: Proxy pp)       ppval = valuePP pp   in do-    (omegaPPPow, _) <- crtInfoPPow+    (omegaPPPow, _) <- crtInfo     return $ trans ppval $ mulDiag $ force $                            fromFunction (Z :. ppval)                            (\(Z:.i) -> let (iq,ir) = i `divMod` p@@ -206,7 +210,7 @@   let pp@(p,e) = proxy ppPPow (Proxy :: Proxy pp)       pptot = totientPP pp   in do-    (omegaPPPow, _) <- crtInfoPPow+    (omegaPPPow, _) <- crtInfo     return $ trans pptot $ mulDiag $ force $                            fromFunction (Z :. pptot)                            (\(Z:.i) -> let (iq,ir) = i `divMod` (p-1)
Crypto/Lol/Cyclotomic/Tensor/RepaTensor/Dec.hs view
@@ -8,7 +8,7 @@  import Crypto.Lol.Cyclotomic.Tensor.RepaTensor.RTCommon as R import Crypto.Lol.GaussRandom-import Crypto.Lol.LatticePrelude+import Crypto.Lol.Prelude  import Control.Monad.Random @@ -33,7 +33,7 @@ fE = eval $ fTensor $ ppTensor pE  -- | The @E_p@ transformation for a prime @p@.-pE :: forall p r . (Prim p, Transcendental r, Unbox r, Elt r)+pE :: forall p r . (Prime p, Transcendental r, Unbox r, Elt r)       => Tagged p (Trans r) pE = let pval = proxy valuePrime (Proxy::Proxy p)      in tag $ if pval==2 then Id 1@@ -62,7 +62,7 @@ fGramDec' = eval $ fTensor $ ppTensor pGramDec  -- | Multiply by (scaled) Gram matrix of decoding basis: (I_{p-1} + all-1s).-pGramDec :: forall p r . (Prim p, Ring r, Unbox r, Elt r) => Tagged p (Trans r)+pGramDec :: forall p r . (Prime p, Ring r, Unbox r, Elt r) => Tagged p (Trans r) pGramDec =   let pval = proxy valuePrime (Proxy::Proxy p)   in tag $ if pval==2 then Id 1
Crypto/Lol/Cyclotomic/Tensor/RepaTensor/Extension.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE BangPatterns, ConstraintKinds, DataKinds, FlexibleContexts,              FlexibleInstances, MultiParamTypeClasses, NoImplicitPrelude,-             PolyKinds, ScopedTypeVariables, TemplateHaskell, TypeFamilies,-             TypeOperators #-}+             PolyKinds, ScopedTypeVariables, TemplateHaskell,+             TypeFamilies, TypeOperators #-}  -- | RT-specific functions for embedding/twacing in various bases @@ -10,22 +10,22 @@ , coeffs', powBasisPow', crtSetDec' ) where -import           Crypto.Lol.LatticePrelude              as LP hiding (lift, (!!)) import           Crypto.Lol.CRTrans-import           Crypto.Lol.Reflects-import qualified Crypto.Lol.Cyclotomic.Tensor                      as T+import qualified Crypto.Lol.Cyclotomic.Tensor                     as T import           Crypto.Lol.Cyclotomic.Tensor.RepaTensor.CRT import           Crypto.Lol.Cyclotomic.Tensor.RepaTensor.RTCommon as RT-import           Crypto.Lol.Types.FiniteField-import           Crypto.Lol.Types.ZmStar+import           Crypto.Lol.Prelude                               as LP +import Crypto.Lol.Types.FiniteField+import Crypto.Lol.Types.ZmStar+ import Control.Applicative-import Control.Arrow       (first, (***))+import Control.Arrow       (first, second)  import           Data.Coerce import           Data.Default import           Data.Maybe-import           Data.Reflection (reify)+import           Data.Reflection              (reify) import qualified Data.Vector                  as V import qualified Data.Vector.Unboxed          as U import           Data.Vector.Unboxed.Deriving@@ -41,7 +41,7 @@   [| (Z :.) |]  -- | The "tweaked trace" function in either the powerful or decoding--- basis of the m'th cyclotomic ring to the mth cyclotomic ring when +-- basis of the m'th cyclotomic ring to the mth cyclotomic ring when -- @m | m'@. twacePowDec' :: forall m m' r . (m `Divides` m', Unbox r)                  => Arr m' r -> Arr m r@@ -50,22 +50,21 @@     in coerce $ \ !arr -> force $ backpermute (extent indices) (indices !) arr  -- | The "tweaked trace" function in the CRT--- basis of the m'th cyclotomic ring to the mth cyclotomic ring when +-- basis of the m'th cyclotomic ring to the mth cyclotomic ring when -- @m | m'@.-twaceCRT' :: forall m m' r .-             (m `Divides` m', CRTrans r, IntegralDomain r,-              ZeroTestable r, Unbox r, Elt r)-             => Maybe (Arr m' r -> Arr m r)-twaceCRT' = do           -- Maybe monad+twaceCRT' :: forall mon m m' r .+             (m `Divides` m', CRTrans mon r, Unbox r, Elt r)+             => mon (Arr m' r -> Arr m r)+twaceCRT' = do   g' :: Arr m' r <- gCRT   gInv <- gInvCRT   embed :: Arr m r -> Arr m' r <- embedCRT'-  (_, m'hatinv) <- proxyT crtInfoFact (Proxy::Proxy m')+  (_, m'hatinv) <- proxyT crtInfo (Proxy::Proxy m')   let hatRatioInv = m'hatinv * fromIntegral (proxy valueHatFact (Proxy::Proxy m))       -- tweak = mhat * g' / (m'hat * g)       tweak = (coerce $ \x -> force . RT.map (* hatRatioInv) . RT.zipWith (*) x) (embed gInv) g' :: Arr m' r       indices = proxy extIndicesCRT (Proxy::Proxy '(m, m'))-  return $ +  return $     -- take true trace after mul-by-tweak     coerce (\ !arr -> sumS . backpermute (extent indices) (indices !) . RT.zipWith (*) arr) tweak @@ -92,11 +91,11 @@  -- | Embeds an array in the CRT basis of the the mth cyclotomic ring -- to an array in the CRT basis of the m'th cyclotomic ring when @m | m'@-embedCRT' :: forall m m' r . (m `Divides` m', CRTrans r, Unbox r)-             => Maybe (Arr m r -> Arr m' r)-embedCRT' = do -- in Maybe+embedCRT' :: forall mon m m' r . (m `Divides` m', CRTrans mon r, Unbox r)+             => mon (Arr m r -> Arr m' r)+embedCRT' = do   -- first check existence of CRT transform of index m'-  proxyT crtInfoFact (Proxy::Proxy m') :: Maybe (CRTInfo r)+  _ <- proxyT crtInfo (Proxy::Proxy m') :: mon (CRTInfo r)   let idxs = proxy baseIndicesCRT (Proxy::Proxy '(m,m'))   return $ coerce $ \ !arr -> (force $ backpermute (extent idxs) (idxs !) arr) @@ -114,7 +113,7 @@ -- Outputs a list of arrays in O_m' that are an O_m basis for O_m' powBasisPow' :: forall m m' r . (m `Divides` m', Ring r, Unbox r)                 => Tagged m [Arr m' r]-powBasisPow' = return $  +powBasisPow' = return $   let (_, phi, phi', _) = proxy T.indexInfo (Proxy::Proxy '(m,m'))       idxs = proxy T.baseIndicesPow (Proxy::Proxy '(m,m'))   in LP.map (\k -> Arr $ force $ fromFunction (Z :. phi')@@ -128,7 +127,7 @@               (m `Divides` m', PrimeField fp, Coprime (PToF (CharOf fp)) m',                Unbox fp)               => Tagged m [Arr m' fp]-crtSetDec' = return $ +crtSetDec' = return $   let m'p = Proxy :: Proxy m'       p = proxy valuePrime (Proxy::Proxy (CharOf fp))       phi = proxy totientFact m'p@@ -143,7 +142,7 @@            elt j i = T.indexM twCRTs' j (zmsToIdx i)            trace' = trace :: GF fp d -> fp            cosets = proxy (partitionCosets p) (Proxy::Proxy '(m,m'))-       in LP.map (\is -> Arr $ force $ fromFunction (Z :. phi) +       in LP.map (\is -> Arr $ force $ fromFunction (Z :. phi)                           (\(Z:.j) -> hinv * trace'                                       (sum $ LP.map (elt j) is))) cosets @@ -176,7 +175,7 @@  baseIndicesPow = do   idxs <- T.baseIndicesPow-  return $ fromUnboxed (Z :. U.length idxs) $ U.map (id *** (Z:.)) idxs+  return $ fromUnboxed (Z :. U.length idxs) $ U.map (second (Z:.)) idxs  baseIndicesDec = do   idxs <- T.baseIndicesDec@@ -188,6 +187,6 @@  extIndicesCoeffs :: forall m m' . (m `Divides` m')                     => Tagged '(m, m') (V.Vector (Array U DIM1 DIM1))-extIndicesCoeffs = -  V.map (\arr -> fromUnboxed (Z :. U.length arr) $ +extIndicesCoeffs =+  V.map (\arr -> fromUnboxed (Z :. U.length arr) $                  U.map (Z:.) arr) <$> T.extIndicesCoeffs
Crypto/Lol/Cyclotomic/Tensor/RepaTensor/GL.hs view
@@ -9,7 +9,7 @@ ) where  import Crypto.Lol.Cyclotomic.Tensor.RepaTensor.RTCommon as RT-import Crypto.Lol.LatticePrelude                        as LP+import Crypto.Lol.Prelude                               as LP import Data.Coerce  fL, fLInv, fGPow, fGDec :: (Fact m, Additive r, Unbox r, Elt r)@@ -46,7 +46,7 @@  wrapGInv' :: forall m r .   (Fact m, IntegralDomain r, ZeroTestable r, Unbox r, Elt r)-  => (forall p . Prim p => Tagged p (Trans r))+  => (forall p . Prime p => Tagged p (Trans r))   -> Arr m r -> Maybe (Arr m r) wrapGInv' ginv =   let fGInv = eval $ fTensor $ ppTensor ginv@@ -65,7 +65,7 @@   in if pass then Just out else Nothing {-# INLINABLE divCheck #-} -pWrap :: forall p r . Prim p+pWrap :: forall p r . Prime p          => (forall rep . Source rep r => Int -> Array rep DIM2 r -> Array D DIM2 r)          -> Tagged p (Trans r) pWrap f = let pval = proxy valuePrime (Proxy::Proxy p)@@ -76,10 +76,10 @@ {-# INLINABLE pWrap #-}  -pL, pLInv, pGPow, pGDec :: (Prim p, Additive r, Unbox r, Elt r)+pL, pLInv, pGPow, pGDec :: (Prime p, Additive r, Unbox r, Elt r)   => Tagged p (Trans r) -pGInvPow', pGInvDec' :: (Prim p, Ring r, Unbox r, Elt r)+pGInvPow', pGInvDec' :: (Prime p, Ring r, Unbox r, Elt r)   => Tagged p (Trans r) {-# INLINABLE pL #-} {-# INLINABLE pLInv #-}
Crypto/Lol/Cyclotomic/Tensor/RepaTensor/RTCommon.hs view
@@ -18,14 +18,14 @@ , sumS, sumAllS ) where -import Crypto.Lol.LatticePrelude as LP hiding ((!!))+import Crypto.Lol.Prelude as LP hiding ((!!)) -import Algebra.Additive as Additive (C)-import Algebra.Ring as Ring (C)+import Algebra.Additive     as Additive (C)+import Algebra.Ring         as Ring (C) import Algebra.ZeroTestable as ZeroTestable (C)  import Control.DeepSeq              (NFData (..))-import Control.Monad.Identity+import Control.Monad.Identity       () import Control.Monad.Random import Data.Array.Repa              as R hiding (sumAllP, sumAllS, sumP,                                           sumS, (*^), (+^), (-^), (/^))@@ -34,12 +34,9 @@ import Data.Coerce import Data.Singletons import Data.Singletons.Prelude      hiding ((:.))-import qualified Data.Vector.Unboxed as U+import Data.Vector.Unboxed          as U (replicate, replicateM) import Test.QuickCheck --- just for specialization-import Crypto.Lol.Types.ZqBasic- -- always unboxed (manifest); intermediate calculations can use -- delayed arrays @@ -65,7 +62,7 @@ replM :: forall m r mon . (Fact m, Unbox r, Monad mon)          => mon r -> mon (Arr m r) replM = let n = proxy totientFact (Proxy::Proxy m)-        in liftM (Arr . fromUnboxed (Z:.n)) . U.replicateM n+        in fmap (Arr . fromUnboxed (Z:.n)) . U.replicateM n {-# INLINABLE replM #-}  instance (Fact m, Additive r, Unbox r, Elt r) => Additive.C (Arr m r) where@@ -86,7 +83,7 @@  instance (Fact m, ZeroTestable r, Unbox r, Elt r) => ZeroTestable.C (Arr m r) where   -- not using 'zero' to avoid Additive r constraint-  isZero (Arr a) +  isZero (Arr a)       = isZero $ foldAllS (\ x y -> if isZero x then y else x) (a R.! (Z:.0)) a   {-# INLINABLE isZero #-} @@ -125,7 +122,7 @@ -- | For a prime power p^e, tensors up any function f defined for -- (and tagged by) a prime to @I_(p^{e-1}) \otimes f@ ppTensor :: forall pp r mon . (PPow pp, Monad mon)-            => (forall p . (Prim p) => TaggedT p mon (Trans r))+            => (forall p . (Prime p) => TaggedT p mon (Trans r))             -> TaggedT pp mon (Trans r)  ppTensor func = tagT $ case (sing :: SPrimePower pp) of@@ -200,7 +197,7 @@  -- | Monadic version of 'eval' evalM :: (Unbox r, Monad mon) => TaggedT m mon (Trans r) -> mon (Arr m r -> Arr m r)-evalM = liftM (eval . return) . untagT+evalM = fmap (eval . return) . untagT {-# INLINE evalM #-}  -- | maps the innermost dimension to a 2-dim array with innermost dim d,@@ -234,7 +231,7 @@     in if mcols == vrows then fromFunction (sh :. mrows) f        else error "mulMatVec: mcols != vdim" {-# INLINABLE mulMat #-}-            + -- | multiplication by a diagonal matrix along innermost dim mulDiag :: (Source r1 r, Source r2 r, Ring r, Unbox r, Elt r)            => Array r1 DIM1 r -> Array r2 DIM2 r -> Array D DIM2 r@@ -247,7 +244,7 @@ -- | Embeds a scalar into a powerful-basis representation of a Repa array, -- tagged by the cyclotomic index scalarPow' :: forall m r . (Fact m, Additive r, Unbox r) => r -> Arr m r-scalarPow' = coerce . (go $ proxy totientFact (Proxy::Proxy m))+scalarPow' = coerce . go (proxy totientFact (Proxy::Proxy m))   where go n !r = let fct (Z:.0) = r                       fct _ = LP.zero                   in force $ fromFunction (Z:.n) fct
Crypto/Lol/Cyclotomic/UCyc.hs view
@@ -1,8 +1,18 @@-{-# LANGUAGE ConstraintKinds, DataKinds, FlexibleContexts,-             FlexibleInstances, GADTs, InstanceSigs, MultiParamTypeClasses,-             NoImplicitPrelude, PolyKinds, RankNTypes, RebindableSyntax,-             ScopedTypeVariables, TypeFamilies, TypeOperators,-             UndecidableInstances #-}+{-# LANGUAGE ConstraintKinds       #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE GADTs                 #-}+{-# LANGUAGE InstanceSigs          #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoImplicitPrelude     #-}+{-# LANGUAGE PolyKinds             #-}+{-# LANGUAGE RankNTypes            #-}+{-# LANGUAGE RebindableSyntax      #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE TypeOperators         #-}+{-# LANGUAGE UndecidableInstances  #-}  -- | A low-level implementation of cyclotomic rings that allows (and -- requires) the programmer to control the underlying representation@@ -18,28 +28,29 @@ module Crypto.Lol.Cyclotomic.UCyc ( -- * Data types and constraints-  UCyc, P, D, C, UCElt, NFElt+  UCyc, P, D, C, E, UCycEC, UCRTElt, NFElt -- * Changing representation-, toPow, toDec, toCRT, fmapPow, fmapDec, unzipCyc, unzipUCElt+, toPow, toDec, toCRT, fmapPow, fmapDec+, unzipPow, unzipDec, unzipCRTC, unzipCRTE -- * Scalars-, scalarPow, scalarCRT          -- scalarDec suppressed+, scalarPow, scalarCRT -- * Basic operations , mulG, divG, gSqNorm -- * Error sampling , tGaussian, errorRounded, errorCoset -- * Inter-ring operations and values-, embedPow, embedDec, embedCRT-, twacePow, twaceDec, twaceCRT+, embedPow, embedDec, embedCRTC, embedCRTE+, twacePow, twaceDec, twaceCRTC, twaceCRTE , coeffsPow, coeffsDec, powBasis, crtSet ) where  import Crypto.Lol.Cyclotomic.Tensor hiding (embedCRT, embedDec, embedPow,-                                     scalarCRT, scalarPow, -- scalarDec-                                     twaceCRT)+                                     scalarCRT, scalarPow, twaceCRT)  import           Crypto.Lol.CRTrans-import qualified Crypto.Lol.Cyclotomic.Tensor as T-import           Crypto.Lol.LatticePrelude    as LP+import           Crypto.Lol.Cyclotomic.CRTSentinel+import qualified Crypto.Lol.Cyclotomic.Tensor      as T+import           Crypto.Lol.Prelude                as LP import           Crypto.Lol.Types.FiniteField import           Crypto.Lol.Types.ZPP @@ -51,22 +62,30 @@ import Control.Applicative    as A import Control.Arrow import Control.DeepSeq-import Control.Monad+import Control.Monad.Identity import Control.Monad.Random import Data.Foldable          as F import Data.Maybe import Data.Traversable import Test.QuickCheck +import Crypto.Lol.Types.Proto+ --import qualified Debug.Trace as DT  -- | Nullary index type representing the powerful basis. data P -- | Nullary index type representing the decoding basis. data D--- | Nullary index type representing a CRT basis.+-- | Nullary index type representing the CRT basis over base ring. data C+-- | Nullary index type representing the CRT basis over extension of+-- base ring.+data E +-- | Convenient synonym for either CRT representation.+type UCycEC t m r = Either (UCyc t m E r) (UCyc t m C r)+ -- | Represents a cyclotomic ring such as @Z[zeta]@, -- @Zq[zeta]@, and @Q(zeta)@ in an explicit representation: @t@ is the -- 'Tensor' type for storing coefficient tensors; @m@ is the@@ -75,17 +94,18 @@ -- -- The 'Functor', 'Applicative', 'Foldable' and 'Traversable' -- instances all work coefficient-wise (in the specified basis).-data UCyc t m rep r where+data UCyc t (m :: Factored) rep r where   Pow  :: !(t m r) -> UCyc t m P r   Dec  :: !(t m r) -> UCyc t m D r-  -- Invariant: for a given (t,m,r), exactly one of these two is ever-  -- used: CRTr if crtFuncs exists, otherwise CRTe-  CRTr :: !(t m r) -> UCyc t m C r-  CRTe :: !(t m (CRTExt r)) -> UCyc t m C r+  -- Use CRTSentinel to enforce invariant that exactly one of these+  -- can be created for a given (t,m,r).+  CRTC :: !(CSentinel t m r) -> !(t m r) -> UCyc t m C r+  CRTE :: !(ESentinel t m r) -> !(t m (CRTExt r)) -> UCyc t m E r --- | Constraints needed for many operations involving the 'UCyc' CRT ('C')--- representation.-type UCElt t r = (Tensor t, CRTEmbed r, CRTElt t r, CRTElt t (CRTExt r))+-- | Constraints needed for CRT-related operations on 'UCyc' data.+type UCRTElt t r = (Tensor t, CRTEmbed r,+                    CRTrans Maybe r, TElt t r,+                    CRTrans Identity (CRTExt r), TElt t (CRTExt r))  -- | Convenient synonym for 'deepseq'-able element type. type NFElt r = (NFData r, NFData (CRTExt r))@@ -95,20 +115,11 @@ scalarPow = Pow . T.scalarPow {-# INLINABLE scalarPow #-} -{- CJP: suppressed- -- | Embed a scalar from the base ring.-scalarDec :: (Tensor t, Fact m, Ring r, TElt t r) => r -> UCyc t m D r-scalarDec = Dec . T.scalarDec-{-# INLINABLE scalarDec #-}---}---- | Embed a scalar from the base ring.-scalarCRT :: (Fact m, UCElt t r) => r -> UCyc t m C r-scalarCRT = fromMaybe-               (CRTe . fromJust' "UCyc: no CRT over CRTExt" T.scalarCRT . toExt)-               ((CRTr .) <$> T.scalarCRT)+scalarCRT :: (Fact m, UCRTElt t r) => r -> UCycEC t m r+scalarCRT r = case crtSentinel of+  Right s -> Right $ CRTC s $ scalarCRTCS s r+  Left  s -> Left  $ CRTE s $ runIdentity T.scalarCRT $ toExt r {-# INLINABLE scalarCRT #-}  -- Eq instances@@ -121,12 +132,11 @@   (Dec v1) == (Dec v2) = v1 == v2 \\ witness entailEqT v1   {-# INLINABLE (==) #-} -instance (Eq r, Fact m, UCElt t r) => Eq (UCyc t m C r) where-  (CRTr v1) == (CRTr v2) = v1 == v2 \\ witness entailEqT v1-  -- compare in pow due to precision-  u1 == u2 = toPow u1 == toPow u2+instance (Eq r, Tensor t, Fact m, TElt t r) => Eq (UCyc t m C r) where+  (CRTC _ v1) == (CRTC _ v2) = v1 == v2 \\ witness entailEqT v1   {-# INLINABLE (==) #-} +-- no Eq instance for E due to precision  ---------- Numeric Prelude instances ---------- @@ -142,13 +152,13 @@   isZero (Dec v) = isZero v \\ witness entailZTT v   {-# INLINABLE isZero #-} -instance (ZeroTestable r, Fact m, UCElt t r)+instance (ZeroTestable r, Tensor t, Fact m, TElt t r)     => ZeroTestable.C (UCyc t m C r) where-  isZero (CRTr v) = isZero v \\ witness entailZTT v-  -- use powerful basis due to precision-  isZero u = isZero $ toPow u+  isZero (CRTC _ v) = isZero v \\ witness entailZTT v   {-# INLINABLE isZero #-} +-- no ZT instance for E due to precision+ -- Additive instances  instance (Additive r, Tensor t, Fact m, TElt t r) => Additive.C (UCyc t m P r) where@@ -171,38 +181,39 @@   {-# INLINABLE (-) #-}   {-# INLINABLE negate #-} -instance (Fact m, UCElt t r) => Additive.C (UCyc t m C r) where+-- | only for appropriate CRT representation (otherwise 'zero' would+-- violate internal invariant)+instance (Fact m, UCRTElt t r) => Additive.C (UCycEC t m r) where+   zero = scalarCRT zero    -- CJP: precision OK?  Alternatively, switch to pow and back after   -- adding/subtracting.  Expensive, but necessary given output type.-  (CRTr v1) + (CRTr v2) = CRTr $ zipWithT (+) v1 v2-  (CRTe v1) + (CRTe v2) = CRTe $ zipWithT (+) v1 v2-  _ + _ = error "UCyc (+) internal error: mixed CRTr/CRTe"+  (Right (CRTC s v1)) + (Right (CRTC _ v2)) = Right $ CRTC s $ zipWithT (+) v1 v2+  (Left (CRTE s v1)) + (Left (CRTE _ v2)) = Left $ CRTE s $ zipWithT (+) v1 v2+  _ + _ = error "UCyc (+) internal error: mixed CRTC/CRTE" -  (CRTr v1) - (CRTr v2) = CRTr $ zipWithT (-) v1 v2-  (CRTe v1) - (CRTe v2) = CRTe $ zipWithT (-) v1 v2-  _ - _ = error "UCyc (-) internal error: mixed CRTr/CRTe"+  (Right (CRTC s v1)) - (Right (CRTC _ v2)) = Right $ CRTC s $ zipWithT (-) v1 v2+  (Left (CRTE s v1)) - (Left (CRTE _ v2)) = Left $ CRTE s $ zipWithT (-) v1 v2+  _ - _ = error "UCyc (-) internal error: mixed CRTC/CRTE" -  negate (CRTr v) = CRTr $ fmapT negate v-  negate (CRTe v) = CRTe $ fmapT negate v+  negate (Right (CRTC s v)) = Right $ CRTC s $ fmapT negate v+  negate (Left (CRTE s v)) = Left $ CRTE s $ fmapT negate v    {-# INLINABLE zero #-}   {-# INLINABLE (+) #-}   {-# INLINABLE (-) #-}   {-# INLINABLE negate #-} --- Ring instance: only for CRT+-- | only for appropriate CRT representation+instance (Fact m, UCRTElt t r) => Ring.C (UCycEC t m r) where -instance (Fact m, UCElt t r) => Ring.C (UCyc t m C r) where   one = scalarCRT one   fromInteger c = scalarCRT $ fromInteger c -  -- CJP: precision OK?  Alternatively, switch to pow (and back) after-  -- multiplying.  Expensive, but necessary given output type.-  (CRTr v1) * (CRTr v2) = CRTr $ zipWithT (*) v1 v2-  (CRTe v1) * (CRTe v2) = CRTe $ zipWithT (*) v1 v2-  _ * _ = error "UCyc internal error: mixed CRTr/CRTe"+  (Right (CRTC s v1)) * (Right (CRTC _ v2)) = Right $ CRTC s $ zipWithT (*) v1 v2+  (Left (CRTE s v1)) * (Left (CRTE _ v2)) = Left $ CRTE s $ zipWithT (*) v1 v2+  _ * _ = error "UCyc internal error: mixed CRTC/CRTE"    {-# INLINABLE one #-}   {-# INLINABLE fromInteger #-}@@ -217,12 +228,17 @@   r *> (Dec v) = Dec $ fmapT (r *) v   {-# INLINABLE (*>) #-} -instance (Ring r, Fact m, UCElt t r) => Module.C r (UCyc t m C r) where-  r *> (CRTr v) = CRTr $ fmapT (r *) v-  r *> (CRTe v) = CRTe $ fmapT (toExt r *) v+instance (Ring r, Fact m, UCRTElt t r) => Module.C r (UCycEC t m r) where++  r *> (Right (CRTC s v)) = Right $ CRTC s $ fmapT (r *) v+  r *> (Left (CRTE s v)) = Left $ CRTE s $ fmapT (toExt r *) v   {-# INLINABLE (*>) #-} -instance (GFCtx fp d, Fact m, UCElt t fp) => Module.C (GF fp d) (UCyc t m P fp) where+-- | @Rp@ is an @F_{p^d}@-module when @d@ divides @phi(m)@, by+-- applying @d@-dimensional @Fp@-linear transform on @d@-dim chunks of+-- powerful basis coeffs+instance (GFCtx fp d, Fact m, Tensor t, TElt t fp)+         => Module.C (GF fp d) (UCyc t m P fp) where   -- can use any r-basis to define module mult, but must be   -- consistent.   r *> (Pow v) = Pow $ r LP.*> v \\ witness entailModuleT (r,v)@@ -238,7 +254,8 @@   reduce (Dec v) = Dec $ fmapT reduce v   {-# INLINABLE reduce #-} --- CJP: no Reduce for C rep because we can't efficiently handle CRTe case+-- CJP: no Reduce for C because CRT basis may not exist for target+-- type  type instance LiftOf (UCyc t m P r) = UCyc t m P (LiftOf r) type instance LiftOf (UCyc t m D r) = UCyc t m D (LiftOf r)@@ -253,6 +270,7 @@   lift (Dec v) = Dec $ fmapT lift v   {-# INLINABLE lift #-} +-- CJP: no Lift' for C because CRT basis may not exist for target type  instance (Rescale a b, Tensor t, Fact m, TElt t a, TElt t b)          => Rescale (UCyc t m P a) (UCyc t m P b) where@@ -264,63 +282,88 @@   rescale (Dec v) = Dec $ fmapT rescale v   {-# INLINABLE rescale #-} +-- CJP: no Rescale for C because CRT basis may not exist for target+-- type  -- CJP: we don't instantiate RescaleCyc because it requires changing bases  -- CJP: we don't instantiate Gadget etc., because (1) their methods--- wouldn't be efficient, and (2) their superclasses are not even--- well-defined (e.g., Ring for P rep).+-- wouldn't be efficient, and (2) their superclass constraints are not+-- satisfied anyway (e.g., Ring for P rep).  --- | Type-restricted (and potentially more efficient) map for+-- | Type-restricted (and potentially more efficient) 'fmap' for -- powerful-basis representation. fmapPow :: (Tensor t, Fact m, TElt t a, TElt t b)            => (a -> b) -> UCyc t m P a -> UCyc t m P b fmapPow f (Pow v) = Pow $ fmapT f v {-# INLINABLE fmapPow #-} --- | Type-restricted (and potentially more efficient) map for+-- | Type-restricted (and potentially more efficient) 'fmap' for -- decoding-basis representation. fmapDec :: (Tensor t, Fact m, TElt t a, TElt t b)            => (a -> b) -> UCyc t m D a -> UCyc t m D b fmapDec f (Dec v) = Dec $ fmapT f v {-# INLINABLE fmapDec #-} --- | Unzip for unrestricted types.-unzipCyc :: (Tensor t, Fact m)-            => UCyc t m rep (a,b) -> (UCyc t m rep a, UCyc t m rep b)-{-# INLINABLE unzipCyc #-}-unzipCyc (Pow v) = Pow *** Pow $ unzipT v-unzipCyc (Dec v) = Dec *** Dec $ unzipT v-unzipCyc (CRTr v) = CRTr *** CRTr $ unzipT v-unzipCyc (CRTe v) = CRTe *** CRTe $ unzipT v+-- | Unzip in the powerful basis.+unzipPow :: (Tensor t, Fact m, TElt t (a,b), TElt t a, TElt t b)+            => UCyc t m P (a,b) -> (UCyc t m P a, UCyc t m P b)+{-# INLINABLE unzipPow #-}+unzipPow (Pow v) = Pow *** Pow $ unzipT v --- | Type-restricted (and potentially more efficient) unzip.-unzipUCElt :: (Tensor t, Fact m, UCElt t (a,b), UCElt t a, UCElt t b)-              => UCyc t m rep (a,b) -> (UCyc t m rep a, UCyc t m rep b)-{-# INLINABLE unzipUCElt #-}-unzipUCElt (Pow v) = Pow *** Pow $ unzipTElt v-unzipUCElt (Dec v) = Dec *** Dec $ unzipTElt v-unzipUCElt (CRTr v) = CRTr *** CRTr $ unzipTElt v-unzipUCElt (CRTe v) = CRTe *** CRTe $ unzipTElt v+-- | Unzip in the decoding basis.+unzipDec :: (Tensor t, Fact m, TElt t (a,b), TElt t a, TElt t b)+            => UCyc t m D (a,b) -> (UCyc t m D a, UCyc t m D b)+{-# INLINABLE unzipDec #-}+unzipDec (Dec v) = Dec *** Dec $ unzipT v +-- | Unzip in the CRT basis over the base ring.  The output components+-- are 'Either' because each target base ring may not support 'C'.+unzipCRTC :: (Tensor t, Fact m, UCRTElt t (a,b), UCRTElt t a, UCRTElt t b)+             => 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))+unzipCRTC (CRTC s v)+  = let (ac,bc) = unzipT v+        (ap,bp) = Pow *** Pow $ unzipT $ crtInvCS s v+    in (fromMaybe (Left ap) (Right <$> (CRTC <$> crtCSentinel <*> pure ac)),+        fromMaybe (Left bp) (Right <$> (CRTC <$> crtCSentinel <*> pure bc)))++-- | Unzip in the CRT basis over the extension of the base ring.  The+-- output components are 'Either' because each target base might+-- instead support 'C'.+unzipCRTE :: (Tensor t, Fact m, UCRTElt t (a,b), UCRTElt t a, UCRTElt t b)+             => 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))+unzipCRTE (CRTE _ v)+  = let (ae,be) = unzipT v+        (a',b') = unzipT $ fmapT fromExt $ runIdentity crtInv v+        (ap,bp) = Pow *** Pow $ (a',b')+    in (fromMaybe (Left ap) (Right <$> (CRTE <$> crtESentinel <*> pure ae)),+        fromMaybe (Left bp) (Right <$> (CRTE <$> crtESentinel <*> pure be)))++ -- | Multiply by the special element @g@.-mulG :: (Tensor t, Fact m, UCElt t r) => UCyc t m rep r -> UCyc t m rep r+mulG :: (Tensor t, Fact m, UCRTElt t r) => UCyc t m rep r -> UCyc t m rep r {-# INLINABLE mulG #-} mulG (Pow v) = Pow $ mulGPow v mulG (Dec v) = Dec $ mulGDec v--- fromJust is safe here because we're already in CRTr-mulG (CRTr v) = CRTr $ fromJust' "UCyc.mulG CRTr" mulGCRT v-mulG (CRTe v) = CRTe $ fromJust' "UCyc.mulG CRTe" mulGCRT v+mulG (CRTC s v) = CRTC s $ mulGCRTCS s v+mulG (CRTE s v) = CRTE s $ runIdentity mulGCRT v  -- | Divide by the special element @g@.-divG :: (Tensor t, Fact m, UCElt t r) => UCyc t m rep r -> Maybe (UCyc t m rep r)+-- WARNING: this implementation is not a constant-time algorithm, so+-- information about the argument may be leaked through a timing+-- channel.+divG :: (Tensor t, 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--- fromJust is OK here because we're already in CRTr-divG (CRTr v) = Just $ CRTr $ fromJust' "UCyc.divG CRTr" divGCRT v-divG (CRTe v) = Just $ CRTe $ fromJust' "UCyc.divG CRTe" divGCRT v+divG (CRTC s v) = Just $ CRTC s $ divGCRTCS s v+divG (CRTE s v) = Just $ CRTE s $ runIdentity divGCRT v  -- | Yield the scaled squared norm of @g_m \cdot e@ under -- the canonical embedding, namely,@@ -330,10 +373,7 @@ {-# INLINABLE gSqNorm #-}  -- | Sample from the "tweaked" Gaussian error distribution @t*D@ in--- the decoding basis, where @D@ has scaled variance @v@.  (Note: This--- implementation uses Double precision to generate the Gaussian--- sample, which may not be sufficient for rigorous proof-based--- security.)+-- the decoding basis, where @D@ has scaled variance @v@. tGaussian :: (Tensor t, Fact m, OrdFloat q, Random q, TElt t q,               ToRational v, MonadRandom rnd)              => v -> rnd (UCyc t m D q)@@ -342,7 +382,10 @@  -- | Generate an LWE error term from the "tweaked" Gaussian with given -- scaled variance, deterministically rounded using the decoding--- basis.+-- basis. (Note: This+-- implementation uses Double precision to generate the Gaussian+-- sample, which may not be sufficient for rigorous proof-based+-- security.) errorRounded :: forall v rnd t m z .                 (ToInteger z, Tensor t, Fact m, TElt t z,                  ToRational v, MonadRandom rnd)@@ -353,7 +396,10 @@  -- | Generate an LWE error term from the "tweaked" Gaussian with -- scaled variance @v * p^2@, deterministically rounded to the given--- coset of @R_p@ using the decoding basis.+-- coset of @R_p@ using the decoding basis. (Note: This+-- implementation uses Double precision to generate the Gaussian+-- sample, which may not be sufficient for rigorous proof-based+-- security.) errorCoset :: forall t m zp z v rnd .   (Mod zp, z ~ ModRep zp, Lift zp z, Tensor t, Fact m,    TElt t zp, TElt t z, ToRational v, MonadRandom rnd)@@ -361,7 +407,7 @@ {-# INLINABLE errorCoset #-} errorCoset =   let pval = fromIntegral $ proxy modulus (Proxy::Proxy zp)-  in \ svar c -> do err <- tGaussian (svar*pval*pval) :: rnd (UCyc t m D Double)+  in \ svar c -> do err :: UCyc t m D Double <- tGaussian (svar*pval*pval)                     return $! roundCoset <$> c <*> err  @@ -379,21 +425,28 @@ embedDec (Dec v) = Dec $ T.embedDec v {-# INLINABLE embedDec #-} --- | Embed into an extension ring, for a CRT basis.  (The output is--- an 'Either' because in some cases it is most efficient to preserve--- the 'UCyc' internal invariant by producing output with respect to--- the powerful basis.)-embedCRT :: forall t m m' r . (m `Divides` m', UCElt t r)-            => UCyc t m C r -> Either (UCyc t m' P r) (UCyc t m' C r)-{-# INLINABLE embedCRT #-}-embedCRT x@(CRTr v) = fromMaybe (Left $ embedPow $ toPow x)-                      (Right . CRTr <$> (T.embedCRT <*> pure v))-embedCRT x@(CRTe v) =-    -- preserve invariant: CRTe iff CRTr is invalid for m'-    fromMaybe (Right $ CRTe $ fromJust' "UCyc.embedCRT CRTe" T.embedCRT v)-              (proxyT hasCRTFuncs (Proxy::Proxy (t m r)) A.*>-               pure (Left $ embedPow $ toPow x))+-- | Embed into an extension ring, for the CRT basis.  (The output is+-- an 'Either' because the extension ring might not support 'C'.)+embedCRTC :: (m `Divides` m', UCRTElt t r)+             => UCyc t m C r -> Either (UCyc t m' P r) (UCyc t m' C r)+{-# INLINABLE embedCRTC #-}+embedCRTC x@(CRTC s v) =+  case crtSentinel of+    -- go to CRTC if valid, else go to Pow+    Left  _ -> Left $ embedPow $ toPow x+    Right s' -> Right $ CRTC s' $ embedCRTCS s s' v +-- | Similar to 'embedCRTC'.  (The output is an 'Either' because the+-- extension ring might support 'C', in which case we never use 'E'.)+embedCRTE :: forall m m' t r . (m `Divides` m', UCRTElt t r)+             => UCyc t m E r -> Either (UCyc t m' P r) (UCyc t m' E r)+{-# INLINABLE embedCRTE #-}+embedCRTE x@(CRTE _ v) =+  case crtSentinel of+    -- go to CRTE if valid, else go to Pow+    Left  s -> Right $ CRTE s $ runIdentity T.embedCRT v+    Right _ -> Left $ embedPow $ toPow x+ -- | Twace into a subring, for the powerful basis. twacePow :: (Ring r, Tensor t, m `Divides` m', TElt t r)             => UCyc t m' P r -> UCyc t m P r@@ -406,22 +459,28 @@ twaceDec (Dec v) = Dec $ twacePowDec v {-# INLINABLE twaceDec #-} --- | Twace into a subring, for a CRT basis.  (The output is an--- 'Either' because in some cases it is most efficient to preserve the--- 'UCyc' internal invariant by producing output with respect to the--- powerful basis.)-twaceCRT :: forall t m m' r . (m `Divides` m', UCElt t r)-            => UCyc t m' C r -> Either (UCyc t m P r) (UCyc t m C r)-{-# INLINABLE twaceCRT #-}-twaceCRT x@(CRTr v) =-  -- stay in CRTr only iff it's valid for target, else go to Pow-  fromMaybe (Left $ twacePow $ toPow x) (Right . CRTr <$> (T.twaceCRT <*> pure v))-twaceCRT x@(CRTe v) =-  -- stay in CRTe iff CRTr is invalid for target, else go to Pow-  fromMaybe (Right $ CRTe $ fromJust' "UCyc.twace CRTe" T.twaceCRT v)-            (proxyT hasCRTFuncs (Proxy::Proxy (t m r)) A.*>-             Just (Left $ twacePow $ toPow x))+-- | 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 #-}+twaceCRTC x@(CRTC s' v) =+  case crtSentinel of+    -- go to CRTC if valid for target, else go to Pow+    Left  _ -> Left $ twacePow $ toPow x+    Right s -> Right $ CRTC s $ twaceCRTCS s' s v +-- | Similar to 'twaceCRTC'.  (The output is an 'Either' because the+-- subring might support 'C', in which case we never use 'E'.)+twaceCRTE :: forall t m m' r . (m `Divides` m', UCRTElt t r)+             => UCyc t m' E r -> Either (UCyc t m P r) (UCyc t m E r)+{-# INLINABLE twaceCRTE #-}+twaceCRTE x@(CRTE _ v) =+  case crtSentinel of+    -- go to CRTE if valid for target, else go to Pow+    Left  s -> Right $ CRTE s $ runIdentity T.twaceCRT v+    Right _ -> Left $ twacePow $ toPow x+ -- | Yield the @O_m@-coefficients of an @O_m'@-element, with respect to -- the relative powerful @O_m@-basis. coeffsPow :: (Ring r, Tensor t, m `Divides` m', TElt t r)@@ -448,7 +507,7 @@ crtSet :: forall t m m' r p mbar m'bar .            (m `Divides` m', ZPP r, p ~ CharOf (ZpOf r),             mbar ~ PFree p m, m'bar ~ PFree p m',-            UCElt t r, TElt t (ZpOf r))+            UCRTElt t r, TElt t (ZpOf r))            => Tagged m [UCyc t m' P r] {-# INLINABLE crtSet #-} crtSet =@@ -461,7 +520,7 @@       pm = Proxy::Proxy m       pm' = Proxy::Proxy m'   in retag (fmap (embedPow .-                  (if e > 1 then toPow . (^(p^(e-1))) . toCRT else toPow) .+                  (if e > 1 then toPowCE . (^(p^(e-1))) . toCRT else toPow) .                   Dec . fmapT liftZp) <$>             (crtSetDec :: Tagged mbar [t m'bar (ZpOf r)]))      \\ pFreeDivides pp pm pm' \\ pSplitTheorems pp pm \\ pSplitTheorems pp pm'@@ -470,53 +529,183 @@ --------- 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, UCElt t r) => UCyc t m rep r -> UCyc t m P r+toPow :: (Fact m, UCRTElt t r) => UCyc t m rep r -> UCyc t m P r {-# INLINABLE toPow #-} toPow x@(Pow _) = x toPow (Dec v) = Pow $ l v-toPow (CRTr v) = Pow $ fromJust' "UCyc.toPow CRTr" crtInv v-toPow (CRTe v) =-    Pow $ fmapT fromExt $ fromJust' "UCyc.toPow CRTe" crtInv v+toPow (CRTC s v) = Pow $ crtInvCS s v+toPow (CRTE _ v) = Pow $ fmapT fromExt $ runIdentity crtInv v +-- | Convenient version of 'toPow' for 'Either' CRT basis type.+toPowCE :: (Fact m, UCRTElt t r) => UCycEC t m r -> UCyc t m P r+{-# INLINABLE toPowCE #-}+toPowCE (Left u) = toPow u+toPowCE (Right u) = toPow u+ -- | Convert to decoding-basis representation.-toDec :: (Fact m, UCElt t r) => UCyc t m rep r -> UCyc t m D r+toDec :: (Fact m, UCRTElt t r) => UCyc t m rep r -> UCyc t m D r {-# INLINABLE toDec #-} toDec (Pow v) = Dec $ lInv v toDec x@(Dec _) = x-toDec x@(CRTr _) = toDec $ toPow x-toDec x@(CRTe _) = toDec $ toPow x+toDec x@(CRTC _ _) = toDec $ toPow x+toDec x@(CRTE _ _) = toDec $ toPow x  -- | Convert to a CRT-basis representation.-toCRT :: forall t m rep r . (Fact m, UCElt t r)-         => UCyc t m rep r -> UCyc t m C r+toCRT :: forall t m rep r . (Fact m, UCRTElt t r)+         => UCyc t m rep r -> UCycEC t m r {-# INLINABLE toCRT #-}-toCRT = let crte = CRTe . fromJust' "UCyc.toCRT: no crt for Ext" crt-            crtr = fmap (CRTr .) crt-            fromPow :: t m r -> UCyc t m C r-            fromPow v = fromMaybe (crte $ fmapT toExt v) (crtr <*> Just v)+toCRT = let fromPow :: t m r -> UCycEC t m r+            fromPow = case crtSentinel of+              Right s -> Right . CRTC s . crtCS s+              Left  s -> Left  . CRTE s . runIdentity crt . fmapT toExt         in \x -> case x of-                   (CRTr _) -> x-                   (CRTe _) -> x+                   (CRTC _ _) -> Right x+                   (CRTE _ _) -> Left x                    (Pow v) -> fromPow v                    (Dec v) -> fromPow $ l v   ---------- Category-theoretic instances ---------- --- CJP: no Applicative, Foldable, Traversable for C because types--- (and math) don't work out for the CRTe case.+-- CJP: no instances for E because types (and math) don't make sense. +-- | apply coefficient-wise (with respect to powerful basis) instance (Tensor t, Fact m) => Functor (UCyc t m P) where   -- Functor instance is implied by Applicative laws   {-# INLINABLE fmap #-}   fmap f x = pure f <*> x +-- | apply coefficient-wise (with respect to decoding basis) instance (Tensor t, Fact m) => Functor (UCyc t m D) where   -- Functor instance is implied by Applicative laws   {-# INLINABLE fmap #-}   fmap f x = pure f <*> x +-- CJP: no Functor instance for C, because CRTrans for a doesn't imply+-- it for b.+ instance (Tensor t, Fact m) => Applicative (UCyc t m P) where   pure = Pow . pure \\ proxy entailIndexT (Proxy::Proxy (t m r))   (Pow f) <*> (Pow v) = Pow $ f <*> v \\ witness entailIndexT v@@ -531,6 +720,9 @@   {-# INLINABLE pure #-}   {-# INLINABLE (<*>) #-} +-- CJP: no Applicative instance for C, because 'pure' would circumvent+-- the invariant.  Moreover, having CRTrans for (a -> b) and for a+-- doesn't imply it for b.  instance (Tensor t, Fact m) => Foldable (UCyc t m P) where   {-# INLINABLE foldr #-}@@ -540,7 +732,11 @@   {-# INLINABLE foldr #-}   foldr f b (Dec v) = F.foldr f b v \\ witness entailIndexT v +instance (Tensor t, Fact m) => Foldable (UCyc t m C) where+  {-# INLINABLE foldr #-}+  foldr f b (CRTC _ v) = F.foldr f b v \\ witness entailIndexT v + instance (Tensor t, Fact m) => Traversable (UCyc t m P) where   {-# INLINABLE traverse #-}   traverse f (Pow v) = Pow <$> traverse f v \\ witness entailIndexT v@@ -549,28 +745,38 @@   {-# INLINABLE traverse #-}   traverse f (Dec v) = Dec <$> traverse f v \\ witness entailIndexT v +-- CJP: no Traversable instance for C, because CRTrans for a doesn't+-- imply it for b. + ---------- Utility instances ---------- -instance (Random r, Tensor t, Fact m, CRTElt t r)+instance (Random r, UCRTElt t r, Fact m) => Random (UCyc t m P r) where++  random g = let (v,g') = random g \\ witness entailRandomT v+             in (Pow v, g')++  randomR _ = error "randomR non-sensical for UCyc"++instance (Random r, UCRTElt t r, Fact m) => Random (UCyc t m D r) where++  random g = let (v,g') = random g \\ witness entailRandomT v+             in (Dec v, g')++  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 -  -- create in CRTr basis if possible, otherwise in powerful-  random = let cons = fromMaybe (Left . Pow)-                      (proxyT hasCRTFuncs (Proxy::Proxy (t m r))-                       >> Just (Right . CRTr))+  -- create in CRTC basis if possible, otherwise in powerful+  random = let cons = case crtSentinel of+                 Left  _ -> Left  . Pow+                 Right s -> Right . CRTC s            in \g -> let (v,g') = random g \\ witness entailRandomT v                     in (cons v, g')    randomR _ = error "randomR non-sensical for UCyc" -instance (Show r, Show (CRTExt r), Tensor t, Fact m, TElt t r, TElt t (CRTExt r))-    => Show (UCyc t m rep r) where-  show (Pow  v) = "UCyc Pow: "  ++ show v \\ witness entailShowT v-  show (Dec  v) = "UCyc Dec: "  ++ show v \\ witness entailShowT v-  show (CRTr v) = "UCyc CRTr: " ++ show v \\ witness entailShowT v-  show (CRTe v) = "UCyc CRTe: " ++ show v \\ witness entailShowT v- instance (Arbitrary (t m r)) => Arbitrary (UCyc t m P r) where   arbitrary = Pow <$> arbitrary   shrink = shrinkNothing@@ -579,13 +785,16 @@   arbitrary = Dec <$> arbitrary   shrink = shrinkNothing -instance (Arbitrary (t m r)) => Arbitrary (UCyc t m C r) where-  arbitrary = CRTr <$> arbitrary-  shrink = shrinkNothing+-- no Arbitrary for C or E due to invariant  instance (Tensor t, Fact m, NFElt r, TElt t r, TElt t (CRTExt r))          => NFData (UCyc t m rep r) where-  rnf (Pow x)    = rnf x \\ witness entailNFDataT x-  rnf (Dec x)    = rnf x \\ witness entailNFDataT x-  rnf (CRTr x)   = rnf x \\ witness entailNFDataT x-  rnf (CRTe x)   = rnf x \\ witness entailNFDataT x+  rnf (Pow x)      = rnf x \\ witness entailNFDataT x+  rnf (Dec x)      = rnf x \\ witness entailNFDataT x+  rnf (CRTC _ x)   = rnf x \\ witness entailNFDataT x+  rnf (CRTE _ x)   = rnf x \\ witness entailNFDataT x++instance (Fact m, Protoable (t m r)) => Protoable (UCyc t m D r) where+  type ProtoType (UCyc t m D r) = ProtoType (t m r)+  toProto (Dec t) = toProto t+  fromProto t = Dec <$> fromProto t
Crypto/Lol/FactoredDefs.hs view
@@ -1,7 +1,8 @@ {-# LANGUAGE ConstraintKinds, DataKinds, ExplicitNamespaces, GADTs,              InstanceSigs, KindSignatures, PolyKinds, ScopedTypeVariables,-             TemplateHaskell, TypeFamilies, TypeOperators,+             RankNTypes, TemplateHaskell, TypeFamilies, TypeOperators,              UndecidableInstances #-}+{-# OPTIONS_GHC -fno-warn-unused-binds #-}  -- | This sub-module exists only because we can't define and use -- template Haskell splices in the same module.@@ -9,11 +10,14 @@ module Crypto.Lol.FactoredDefs ( -- * Factored natural numbers-  Factored, SFactored, Fact, fType, fDec+  reifyFact, reifyFactI+, Factored, SFactored, Fact, fType, fDec -- * Prime powers+, reifyPPow, reifyPPowI , PrimePower, SPrimePower, Sing(SPP), PPow, ppType, ppDec -- * Primes-, Prime, SPrime, Prim, pType, pDec+, reifyPrime, reifyPrimeI+, PrimeBin, SPrimeBin, Prime, pType, pDec -- * Constructors , pToPP, sPToPP, PToPP, ppToF, sPpToF, PpToF, pToF, sPToF, PToF -- * Unwrappers@@ -58,21 +62,21 @@             -- something about "escaped type variables"              -- restrict to primes-            newtype Prime = P Bin deriving (Eq,Ord,Show)+            newtype PrimeBin = P Bin deriving (Eq,Ord,Show) -            -- (prime, exponent) -            newtype PrimePower = PP (Prime,Pos) deriving (Eq,Show)+            -- (prime, exponent)+            newtype PrimePower = PP (PrimeBin,Pos) deriving (Eq,Show)              -- Invariant: primes appear in strictly increasing             -- order (no duplicates).             newtype Factored = F [PrimePower] deriving (Eq,Show) -            -- Unwrap 'Prime'-            unP :: Prime -> Bin+            -- Unwrap 'PrimeBin'+            unP :: PrimeBin -> Bin             unP (P p) = p              -- Unwrap 'PrimePower'.-            unPP :: PrimePower -> (Prime,Pos)+            unPP :: PrimePower -> (PrimeBin,Pos)             unPP (PP pp) = pp              -- Unwrap 'Factored'@@ -80,7 +84,7 @@             unF (F pps) = pps              -- Prime component of a 'PrimePower'.-            primePP :: PrimePower -> Prime+            primePP :: PrimePower -> PrimeBin             primePP = fst . unPP              -- Exponent component of a 'PrimePower'.@@ -121,13 +125,13 @@  -- ARITHMETIC OPERATIONS singletons [d|-            pToPP :: Prime -> PrimePower+            pToPP :: PrimeBin -> PrimePower             pToPP p = PP (p, O)              ppToF :: PrimePower -> Factored             ppToF pp = F [pp] -            pToF :: Prime -> Factored+            pToF :: PrimeBin -> Factored             pToF = ppToF . pToPP              fGCD, fLCM :: Factored -> Factored -> Factored@@ -189,7 +193,7 @@  singletons [d|             -- Remove all @p@-factors from a 'Factored'.-            pFree :: Prime -> Factored -> Factored+            pFree :: PrimeBin -> Factored -> Factored             pFree p (F pps) = F (go pps)               where go [] = []                     go (pp@(PP (p',_)) : ps) =@@ -206,7 +210,7 @@ -- convenience aliases: enforce kind, hide SingI  -- | Kind-restricted synonym for 'SingI'.-type Prim (p :: Prime) = SingI p+type Prime (p :: PrimeBin) = SingI p  -- | Kind-restricted synonym for 'SingI'. type PPow (pp :: PrimePower) = SingI pp@@ -214,6 +218,39 @@ -- | Kind-restricted synonym for 'SingI'. type Fact (m :: Factored) = SingI m +-- | Reify a 'PrimeBin' as a singleton.+reifyPrime :: Int -> (forall p . SPrimeBin p -> a) -> a+reifyPrime x _ | not $ prime x = error $ "reifyPrime: non-prime x = " ++ show x+reifyPrime x k = reifyBin x (k . SP)++-- | Reify a 'PrimeBin' for a 'Prime' constraint.+reifyPrimeI :: Int -> (forall p proxy. Prime p => proxy p -> a) -> a+reifyPrimeI n k =+  reifyPrime n (\(p::SPrimeBin p) -> withSingI p $ k (Proxy::Proxy p))++-- | Reify a 'PrimePower' as a singleton.+reifyPPow :: (Int,Int) -> (forall pp . SPrimePower pp -> a) -> a+reifyPPow (p,e) k = reifyPrime p (\sp -> reifyPos e (k . SPP . STuple2 sp))++-- | Reify a 'PrimePower' for a 'PPow' constraint.+reifyPPowI :: (Int,Int) -> (forall pp proxy. PPow pp => proxy pp -> a) -> a+reifyPPowI pp k =+  reifyPPow pp $ (\(p::SPrimePower p) -> withSingI p $ k (Proxy::Proxy p))++-- | Reify a 'Factored' as a singleton.+reifyFact :: Int -> (forall m . SFactored m -> a) -> a+reifyFact m k = let pps = factorize m in reifyPPs pps $ k . SF+  where reifyPPs :: [(Int,Int)]+                    -> (forall (pps :: [PrimePower]) . Sing pps -> a) -> a+        reifyPPs [] c = c SNil+        reifyPPs (pp:pps) c =+          reifyPPow pp (\spp -> reifyPPs pps (\sm' -> c $ SCons spp sm'))++-- | Reify a 'Factored' for a 'Fact' constraint.+reifyFactI :: Int -> (forall m proxy. Fact m => proxy m -> a) -> a+reifyFactI pps k =+  reifyFact pps $ (\(m::SFactored m) -> withSingI m $ k (Proxy::Proxy m))+ -- | Constraint synonym for divisibility of 'Factored' types. type Divides m m' = (Fact m, Fact m', FDivides m m' ~ 'True) @@ -269,21 +306,21 @@ -- if @f@ is @m@ after removing all @p@-factors, then @f|m@ and -- @gcd(f,p)=1@. pSplitTheorems :: forall p m f . Proxy p -> Proxy m ->-                  ((Prim p, Fact m, f ~ PFree p m) :-+                  ((Prime p, Fact m, f ~ PFree p m) :-                    (f `Divides` m, Coprime (PToF p) f)) pSplitTheorems _ m =-  Sub $ withSingI (sPFree (sing :: SPrime p) (sing :: SFactored m))+  Sub $ withSingI (sPFree (sing :: SPrimeBin p) (sing :: SFactored m))   Dict \\ coerceFDivs (Proxy::Proxy f) m   \\ coerceGCD (Proxy::Proxy (PToF p)) (Proxy::Proxy f) (Proxy::Proxy F1)  -- | Entailment for @p@-free division: -- if @m|m'@, then @p-free(m) | p-free(m')@. pFreeDivides :: forall p m m' . Proxy p -> Proxy m -> Proxy m' ->-                ((Prim p, m `Divides` m') :-+                ((Prime p, m `Divides` m') :-                  ((PFree p m) `Divides` (PFree p m'))) pFreeDivides _ _ _ =-  Sub $ withSingI (sPFree (sing :: SPrime p) (sing :: SFactored m)) $-        withSingI (sPFree (sing :: SPrime p) (sing :: SFactored m')) $+  Sub $ withSingI (sPFree (sing :: SPrimeBin p) (sing :: SFactored m)) $+        withSingI (sPFree (sing :: SPrimeBin p) (sing :: SFactored m')) $         Dict \\ coerceFDivs (Proxy::Proxy (PFree p m)) (Proxy::Proxy (PFree p m'))  -- | Type synonym for @(prime, exponent)@ pair.@@ -327,9 +364,9 @@ -- | The totient of a 'PrimePower' type's value. totientPPow = totientPP <$> ppPPow --- | The value of a 'Prime' type.-valuePrime :: forall p . Prim p => Tagged p Int-valuePrime = tag $ binToInt $ unP $ fromSing (sing :: SPrime p)+-- | 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@@ -366,11 +403,11 @@ oddRadicalPPs = product . map oddRadicalPP  --- | Template Haskell splice for the 'Prime' type corresponding to a+-- | 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 -- arguments.)  This is the preferred (and only) way of constructing a--- concrete 'Prime' type (and is used to define the @Primep@ type+-- concrete 'PrimeBin' type (and is used to define the @Primep@ type -- synonyms). pType :: Int -> TypeQ pType p@@ -392,10 +429,10 @@ -- small-to-moderate-sized arguments (any reasonable cyclotomic index -- should be OK). fType :: Int -> TypeQ-fType n = conT 'F `appT` (foldr (\pp -> appT (promotedConsT `appT` ppType pp)) +fType n = conT 'F `appT` (foldr (\pp -> appT (promotedConsT `appT` ppType pp))                                 promotedNilT $ factorize n) --- | Template Haskell splice that defines the 'Prime' type synonym+-- | Template Haskell splice that defines the 'PrimeBin' type synonym -- @Primep@ for a positive prime integer @p@. pDec :: Int -> DecQ pDec p = tySynD (mkName $ "Prime" ++ show p) [] $ pType p@@ -411,16 +448,16 @@ fDec n = tySynD (mkName $ 'F' : show n) [] $ fType n  -- | Factorize a positive integer into an ordered list of its prime--- divisors, with multiplicities.  First argument is infinite list of--- primes left to consider.+-- divisors, with possible duplicates.  First argument is infinite+-- list of primes left to consider. factorize' :: [Int] -> Int -> [Int] factorize' _ 1 = []-factorize' ds@(d:ds') n +factorize' ds@(d:ds') n   | n > 1 = if d * d > n then [n]             else let (q,r) = n `divMod` d                  in if r == 0 then d : factorize' ds q                     else factorize' ds' n-  | otherwise = error "can only factorize positive integers"+factorize' _ n = error $ "can't factorize non-positive n = " ++ show n  -- | Factorize a positive integer into a list of (prime,exponent) -- pairs, in strictly increasing order by prime.
Crypto/Lol/Gadget.hs view
@@ -1,7 +1,14 @@-{-# LANGUAGE ConstraintKinds, DataKinds, FlexibleContexts,-             FlexibleInstances, MultiParamTypeClasses, NoImplicitPrelude,-             PolyKinds, ScopedTypeVariables, TupleSections, TypeFamilies,-             UndecidableInstances #-}+{-# LANGUAGE ConstraintKinds       #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoImplicitPrelude     #-}+{-# LANGUAGE PolyKinds             #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TupleSections         #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE UndecidableInstances  #-}  -- | Interfaces for "gadgets," decomposition, and error correction. @@ -10,7 +17,7 @@ , TrivGad, BaseBGad ) where -import Crypto.Lol.LatticePrelude+import Crypto.Lol.Prelude  import Control.Applicative import Control.Arrow@@ -51,18 +58,19 @@   correct :: Tagged gad [u] -> (u, [LiftOf u])  --- instances for products-+-- | Product ring: concatenate gadgets over component rings instance (Gadget gad a, Gadget gad b) => Gadget gad (a,b) where    gadget = (++) <$> (map (,zero) <$> gadget) <*> (map (zero,) <$> gadget) +-- | Product ring: concatenate decompositions for component rings instance (Decompose gad a, Decompose gad b, DecompOf a ~ DecompOf b)          => Decompose gad (a,b) where    type DecompOf (a,b) = DecompOf a   decompose (a,b) = (++) <$> decompose a <*> decompose b +-- | Product ring instance (Correct gad a, Correct gad b,           Mod a, Mod b, Field a, Field b, Lift' a, Lift' b,           ToInteger (LiftOf a), ToInteger (LiftOf b))
Crypto/Lol/GaussRandom.hs view
@@ -5,10 +5,11 @@ module Crypto.Lol.GaussRandom ( realGaussian, realGaussians ) where -import Crypto.Lol.LatticePrelude+import Crypto.Lol.Prelude  import qualified Data.Vector.Generic as V +import Control.Applicative import Control.Monad import Control.Monad.Random @@ -44,8 +45,8 @@     (ToRational svar, OrdFloat i, Random i, V.Vector v i, MonadRandom m)     => svar -> Int -> m (v i) realGaussians var n-    | odd n = liftM V.tail (realGaussians var (n+1)) -- O(1) tail-    | otherwise = liftM (V.fromList . uncurry (++) . unzip) $+    | odd n = V.tail <$> realGaussians var (n+1) -- O(1) tail+    | otherwise = (V.fromList . uncurry (++) . unzip) <$>                   replicateM (n `div` 2) (realGaussian var)  @@ -63,7 +64,7 @@ -- | Analogue of @('Prelude.until')@ -- Yields the result of applying f until p holds. iterateUntilM :: (Monad m) => (a -> Bool) -> (a -> m a) -> a -> m a-iterateUntilM p f v +iterateUntilM p f v     | p v       = return v     | otherwise = f v >>= iterateUntilM p f 
− Crypto/Lol/LatticePrelude.hs
@@ -1,276 +0,0 @@-{-# LANGUAGE ConstraintKinds, DataKinds, FlexibleContexts,-             FlexibleInstances, FunctionalDependencies,-             GeneralizedNewtypeDeriving, MultiParamTypeClasses,-             NoImplicitPrelude, PolyKinds, RankNTypes, RebindableSyntax,-             ScopedTypeVariables, StandaloneDeriving, TemplateHaskell,-             TypeFamilies, TypeOperators, UndecidableInstances #-}---- | A substitute for the Prelude that is more suitable for Lol.  This--- module exports most of the Numeric Prelude and other frequently--- used modules, plus some low-level classes, missing instances, and--- assorted utility functions.--module Crypto.Lol.LatticePrelude-(--- * Classes and families-  Enumerable(..)-, Mod(..)-, Reduce(..), LiftOf, Lift, Lift'(..), Rescale(..), Encode(..), msdToLSD-, CharOf--- * Numeric-, module Crypto.Lol.Types.Numeric--- * Complex-, module Crypto.Lol.Types.Complex--- * Factored-, module Crypto.Lol.Factored--- * Miscellaneous-, rescaleMod, roundCoset-, fromJust', pureT, peelT, pasteT, withWitness, withWitnessT-, module Data.Functor.Trans.Tagged-, module Data.Proxy-) where--import Crypto.Lol.Factored-import Crypto.Lol.Types.Complex-import Crypto.Lol.Types.Numeric--import Algebra.Field          as Field (C)-import Algebra.IntegralDomain as IntegralDomain (C)-import Algebra.Ring           as Ring (C)--import Control.Applicative-import Control.Arrow-import Control.DeepSeq-import Control.Monad.Identity-import Control.Monad.Random-import Data.Coerce-import Data.Default-import Data.Functor.Trans.Tagged-import Data.Maybe-import Data.Proxy-import Data.Singletons---- for Unbox instance of Maybe a-import qualified Data.Vector.Unboxed          as U-import           Data.Vector.Unboxed.Deriving--instance NFData (Proxy (a :: k)) where rnf Proxy = ()--deriving instance NFData (m a) => NFData (TaggedT s m a)-deriving instance (MonadRandom m) => MonadRandom (TaggedT (tag :: k) m)--derivingUnbox "Maybe"-  [t| forall a . (Default a, U.Unbox a) => Maybe a -> (Bool, a) |]-  [| maybe (False, def) (\ x -> (True, x)) |]-  [| \ (b, x) -> if b then Just x else Nothing |]--instance Default Bool where def = False---- | The characteristic of a ring, represented as a type.-type family CharOf fp :: k---- | Poor man's 'Enum'.-class Enumerable a where-  values :: [a]---- | Represents a quotient group modulo some integer.-class (ToInteger (ModRep a), Additive a) => Mod a where-  type ModRep a-  modulus :: Tagged a (ModRep a)---- | Represents that @b@ is a quotient group of @a@.-class (Additive a, Additive b) => Reduce a b where-  reduce :: a -> b---- | Represents that @b@ can be lifted to a "short" @a@ congruent to @b@.-type Lift b a = (Lift' b, LiftOf b ~ a)---- | The type of representatives of @b@.-type family LiftOf b---- | Fun-dep version of Lift.-class (Reduce (LiftOf b) b) => Lift' b where-  lift :: b -> LiftOf b---- | Represents that @a@ can be rescaled to @b@, as an "approximate"--- additive homomorphism.-class (Additive a, Additive b) => Rescale a b where-  rescale :: a -> b---- | Represents that the target ring can "noisily encode" values from--- the source ring, in either "most significant digit" (MSD) or "least--- significant digit" (LSD) encodings, and provides conversion factors--- between the two types of encodings.--class (Field src, Field tgt) => Encode src tgt where-    -- | The factor that converts an element from LSD to MSD encoding-    -- in the target field, with associated scale factor to apply to-    -- correct the resulting encoded value.-    lsdToMSD :: (src, tgt)---- | Inverted entries of 'lsdToMSD'.-msdToLSD :: (Encode src tgt) => (src, tgt)-msdToLSD = (recip *** recip) lsdToMSD-{-# INLINABLE msdToLSD #-}---- | A default implementation of rescaling for 'Mod' types.-rescaleMod :: forall a b .-              (Mod a, Mod b, (ModRep a) ~ (ModRep b),-               Lift a (ModRep b), Ring b)-              => a -> b-{-# INLINABLE rescaleMod #-}-rescaleMod =-    let qval = proxy modulus (Proxy :: Proxy a)-        q'val = proxy modulus (Proxy :: Proxy b)-    in \x -> let (quot',_) = divModCent (q'val * lift x) qval-             in fromIntegral quot'---- | Deterministically round to a nearby value in the desired coset-roundCoset :: forall zp z r .-              (Mod zp, z ~ ModRep zp, Lift zp z, RealField r) => zp -> r -> z-{-# INLINABLE roundCoset #-}-roundCoset = let pval = proxy modulus (Proxy::Proxy zp)-             in \ zp x -> let rep = lift zp-                          in rep + roundMult pval (x - fromIntegral rep)------------ Instances for product groups/rings ------------type instance LiftOf (a,b) = Integer--instance (Mod a, Mod b, Lift' a, Lift' b, Reduce Integer (a,b),-          ToInteger (LiftOf a), ToInteger (LiftOf b))-         => Lift' (a,b) where--  {-# INLINABLE lift #-}-  lift (a,b) =-    let moda = toInteger $ proxy modulus (Proxy::Proxy a)-        modb = toInteger $ proxy modulus (Proxy::Proxy b)-        q = moda * modb-        ainv = fromMaybe (error "Lift' (a,b): moduli not coprime") $ moda `modinv` modb-        lifta = toInteger $ lift a-        liftb = toInteger $ lift b-        -- put in [-q/2, q/2)-        (_,r) = (moda * (liftb - lifta) * ainv + lifta) `divModCent` q-    in r----- NP should define Ring and Field instances for pairs, but doesn't.--- So we do it here.-instance (Ring r1, Ring r2) => Ring.C (r1, r2) where-  (x1, x2) * (y1, y2) = (x1*y1, x2*y2)-  one = (one,one)-  fromInteger x = (fromInteger x, fromInteger x)--  {-# INLINABLE (*) #-}-  {-# INLINABLE one #-}-  {-# INLINABLE fromInteger #-}--instance (Field f1, Field f2) => Field.C (f1, f2) where-  (x1, x2) / (y1, y2) = (x1 / y1, x2 / y2)-  recip = recip *** recip-  {-# INLINABLE (/) #-}-  {-# INLINABLE recip #-}--instance (IntegralDomain a, IntegralDomain b) => IntegralDomain.C (a,b) where-  (a1,b1) `divMod` (a2,b2) =-    let (da,ra) = (a1 `divMod` a2)-        (db,rb) = (b1 `divMod` b2)-    in ((da,db), (ra,rb))-  {-# INLINABLE divMod #-}--instance (Mod a, Mod b) => Mod (a,b) where-  type ModRep (a,b) = Integer--  modulus = tag $ fromIntegral (proxy modulus (Proxy::Proxy a)) *-            fromIntegral (proxy modulus (Proxy::Proxy b))-  {-# INLINABLE modulus #-}--instance (Reduce a b1, Reduce a b2) => Reduce a (b1, b2) where-  reduce x = (reduce x, reduce x)-  {-# INLINABLE reduce #-}---- instances of Rescale for a product-instance (Mod a, Field b, Lift a (ModRep a), Reduce (LiftOf a) b)-         => Rescale (a,b) b where-  rescale = let q1val = proxy modulus (Proxy::Proxy a)-                q1inv = recip $ reduce q1val-            in \(x1,x2) -> q1inv * (x2 - reduce (lift x1))-  {-# INLINABLE rescale #-}--instance (Mod b, Field a, Lift b (ModRep b), Reduce (LiftOf b) a)-         => Rescale (a,b) a where-  rescale = let q2val = proxy modulus (Proxy::Proxy b)-                q2inv = recip $ reduce q2val-            in \(x1,x2) -> q2inv * (x1 - reduce (lift x2))-  {-# INLINABLE rescale #-}---- some multi-step scaledowns; could do this forever-instance (Rescale (a,(b,c)) (b,c), Rescale (b,c) c)-         => Rescale (a,(b,c)) c where-  rescale = (rescale :: (b,c) -> c) . rescale-  {-# INLINABLE rescale #-}--instance (Rescale ((a,b),c) (a,b), Rescale (a,b) a)-         => Rescale ((a,b),c) a where-  rescale = (rescale :: (a,b) -> a) . rescale-  {-# INLINABLE rescale #-}---- scaling up to a product-instance (Ring a, Mod b, Reduce (ModRep b) a) => Rescale a (a,b) where-  -- multiply by q2-  rescale = let q2val = reduce $ proxy modulus (Proxy::Proxy b)-            in \x -> (q2val * x, zero)-  {-# INLINABLE rescale #-}--instance (Ring b, Mod a, Reduce (ModRep a) b) => Rescale b (a,b) where-  -- multiply by q1-  rescale = let q1val = reduce $ proxy modulus (Proxy::Proxy a)-            in \x -> (zero, q1val * x)-  {-# INLINABLE rescale #-}---- Instance of 'Encode' for product ring.-instance (Encode s t1, Encode s t2, Field (t1, t2)) => Encode s (t1, t2) where-  {-# INLINABLE lsdToMSD #-}-  lsdToMSD = let (s1, t1conv) = lsdToMSD-                 (s2, t2conv) = lsdToMSD-             in (negate s1 * s2, (t1conv,t2conv))---- Random could have defined this instance, but didn't, so we do it--- here.-instance (Random a, Random b) => Random (a,b) where-  {-# INLINABLE random #-}-  random g = let (a,g') = random g-                 (b, g'') = random g'-             in ((a,b), g'')--  {-# INLINABLE randomR #-}-  randomR ((loa,lob), (hia,hib)) g = let (a,g') = randomR (loa,hia) g-                                         (b,g'') = randomR (lob,hib) g'-                                     in ((a,b),g'')---- | Version of 'fromJust' with an error message.-fromJust' :: String -> Maybe a -> a-fromJust' str = fromMaybe (error str)---- | Apply any applicative to a Tagged value.-pureT :: Applicative f => TaggedT t Identity a -> TaggedT t f a-pureT = mapTaggedT (pure . runIdentity)---- | Expose the monad of a tagged value.-peelT :: Tagged t (f a) -> TaggedT t f a-peelT = coerce---- | Hide the monad of a tagged value.-pasteT :: TaggedT t f a -> Tagged t (f a)-pasteT = coerce---- | Use a singleton as a witness to extract a value from a tagged value.-withWitness :: forall n r . (SingI n => Tagged n r) -> Sing n -> r-withWitness t wit = withSingI wit $ proxy t (Proxy::Proxy n)-{-# INLINABLE withWitness #-}---- | Transformer version of 'withWitness'.-withWitnessT :: forall n mon r .-                (SingI n => TaggedT n mon r) -> Sing n -> mon r-withWitnessT t wit = withSingI wit $ proxyT t (Proxy::Proxy n)-{-# INLINABLE withWitnessT #-}
Crypto/Lol/PosBinDefs.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE ConstraintKinds, DataKinds, GADTs, InstanceSigs,-             KindSignatures, NoImplicitPrelude, PolyKinds,+             KindSignatures, NoImplicitPrelude, PolyKinds, RankNTypes,              RebindableSyntax, ScopedTypeVariables, TemplateHaskell,              TypeFamilies, UndecidableInstances #-} @@ -10,10 +10,12 @@ ( -- * Positive naturals in Peano representation   Pos(..), Sing(SO, SS), SPos, PosC , posToInt, addPos, sAddPos, AddPos, subPos, sSubPos, SubPos+, reifyPos, reifyPosI , posType, posDec , OSym0, SSym0, SSym1, AddPosSym0, AddPosSym1, SubPosSym0, SubPosSym1   -- * Positive naturals in binary representation , Bin(..), Sing(SB1, SD0, SD1), SBin, BinC+, reifyBin, reifyBinI , binToInt, binType, binDec , B1Sym0, D0Sym0, D0Sym1, D1Sym0, D1Sym1   -- * Miscellaneous@@ -95,6 +97,27 @@  -- | Kind-restricted synonym for 'SingI'. type BinC (b :: Bin) = SingI b++-- | Reify a 'Pos' as a singleton.+reifyPos :: Int -> (forall p . SPos p -> a) -> a+reifyPos x _ | x < 1 = error $ "reifyPos: non-positive x = " ++ show x+reifyPos 1 k = k SO+reifyPos n k = reifyPos (n-1) (k . SS)++-- | Reify a 'Pos' for a 'SingI' constraint.+reifyPosI :: Int -> (forall p proxy . PosC p => proxy p -> a) -> a+reifyPosI n k = reifyPos n (\(p::SPos p) -> withSingI p $ k (Proxy::Proxy p))++-- | Reify a 'Bin' as a singleton.+reifyBin :: Int -> (forall b . SBin b -> a) -> a+reifyBin x _ | x < 1  = error $ "reifyBin: non-positive x = " ++ show x+reifyBin 1 k          = k SB1+reifyBin x k | even x = reifyBin (x `div` 2) (k . SD0)+reifyBin x k          = reifyBin (x `div` 2) (k . SD1)++-- | Reify a 'Bin' for a 'SingI' constraint.+reifyBinI :: Int -> (forall b proxy . BinC b => proxy b -> a) -> a+reifyBinI n k = reifyBin n (\(b::SBin b) -> withSingI b $ k (Proxy::Proxy b))  -- | Template Haskell splice for the 'Pos' type -- representing a given 'Int', e.g., @$(posType 8)@.
+ Crypto/Lol/Prelude.hs view
@@ -0,0 +1,299 @@+{-# LANGUAGE ConstraintKinds            #-}+{-# LANGUAGE DataKinds                  #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE FunctionalDependencies     #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE NoImplicitPrelude          #-}+{-# LANGUAGE PolyKinds                  #-}+{-# LANGUAGE RankNTypes                 #-}+{-# LANGUAGE RebindableSyntax           #-}+{-# LANGUAGE ScopedTypeVariables        #-}+{-# LANGUAGE StandaloneDeriving         #-}+{-# LANGUAGE TemplateHaskell            #-}+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE TypeOperators              #-}+{-# LANGUAGE UndecidableInstances       #-}++-- | A substitute for the Prelude that is more suitable for Lol.  This+-- module exports most of the Numeric Prelude and other frequently+-- used modules, plus some low-level classes, missing instances, and+-- assorted utility functions.++module Crypto.Lol.Prelude+(+-- * Classes and families+  Enumerable(..)+, Mod(..)+, Subgroup(..)+, Reduce(..), LiftOf, Lift, Lift'(..), Rescale(..), Encode(..), msdToLSD+, CharOf+-- * Numeric+, module Crypto.Lol.Types.Numeric+-- * Complex+, module Crypto.Lol.Types.Complex+-- * Factored+, module Crypto.Lol.Factored+-- * Miscellaneous+, rescaleMod, roundCoset+, fromJust', pureT, peelT, pasteT, withWitness, withWitnessT+, module Data.Functor.Trans.Tagged+, module Data.Proxy+) where++import Crypto.Lol.Factored+import Crypto.Lol.Types.Complex+import Crypto.Lol.Types.Numeric++import Algebra.Field          as Field (C)+import Algebra.IntegralDomain as IntegralDomain (C)+import Algebra.Ring           as Ring (C)++import Control.Applicative+import Control.Arrow+import Control.DeepSeq+import Control.Monad.Identity+import Control.Monad.Random+import Data.Coerce+import Data.Default+import Data.Functor.Trans.Tagged+import Data.Maybe+import Data.Proxy+import Data.Singletons++-- for Unbox instance of Maybe a+import qualified Data.Vector.Unboxed          as U+import           Data.Vector.Unboxed.Deriving++instance NFData (Proxy (a :: k)) where rnf Proxy = ()++deriving instance NFData (m a) => NFData (TaggedT s m a)+deriving instance (MonadRandom m) => MonadRandom (TaggedT (tag :: k) m)++derivingUnbox "Maybe"+  [t| forall a . (Default a, U.Unbox a) => Maybe a -> (Bool, a) |]+  [| maybe (False, def) (\ x -> (True, x)) |]+  [| \ (b, x) -> if b then Just x else Nothing |]++instance Default Bool where def = False++-- | The characteristic of a ring, represented as a type.+type family CharOf fp :: k++-- | Poor man's 'Enum'.+class Enumerable a where+  values :: [a]++-- | Represents a quotient group modulo some integer.+class (ToInteger (ModRep a), Additive a) => Mod a where+  type ModRep a+  modulus :: Tagged a (ModRep a)++-- | Represents that @a@ is a subgroup of @b@.+class (Additive a, Additive b) => Subgroup a b where+  fromSubgroup :: a -> b++-- | Represents that @b@ is a quotient group of @a@.+class (Additive a, Additive b) => Reduce a b where+  reduce :: a -> b++-- | Represents that @b@ can be lifted to a "short" @a@ congruent to @b@.+type Lift b a = (Lift' b, LiftOf b ~ a)++-- | The type of representatives of @b@.+type family LiftOf b++-- | Fun-dep version of Lift.+class (Reduce (LiftOf b) b) => Lift' b where+  lift :: b -> LiftOf b++-- | Represents that @a@ can be rescaled to @b@, as an "approximate"+-- additive homomorphism.+class (Additive a, Additive b) => Rescale a b where+  rescale :: a -> b++-- | Represents that the target ring can "noisily encode" values from+-- the source ring, in either "most significant digit" (MSD) or "least+-- significant digit" (LSD) encodings, and provides conversion factors+-- between the two types of encodings.++class (Field src, Field tgt) => Encode src tgt where+    -- | The factor that converts an element from LSD to MSD encoding+    -- in the target field, with associated scale factor to apply to+    -- correct the resulting encoded value.+    lsdToMSD :: (src, tgt)++-- | Inverted entries of 'lsdToMSD'.+msdToLSD :: (Encode src tgt) => (src, tgt)+msdToLSD = (recip *** recip) lsdToMSD+{-# INLINABLE msdToLSD #-}++-- | A default implementation of rescaling for 'Mod' types.+rescaleMod :: forall a b .+              (Mod a, Mod b, (ModRep a) ~ (ModRep b),+               Lift a (ModRep b), Ring b)+              => a -> b+{-# INLINABLE rescaleMod #-}+rescaleMod =+    let qval = proxy modulus (Proxy :: Proxy a)+        q'val = proxy modulus (Proxy :: Proxy b)+    in \x -> let (quot',_) = divModCent (q'val * lift x) qval+             in fromIntegral quot'++-- | Deterministically round to a nearby value in the desired coset+roundCoset :: forall zp z r .+              (Mod zp, z ~ ModRep zp, Lift zp z, RealField r) => zp -> r -> z+{-# INLINABLE roundCoset #-}+roundCoset = let pval = proxy modulus (Proxy::Proxy zp)+             in \ zp x -> let rep = lift zp+                          in rep + roundMult pval (x - fromIntegral rep)++---------- Instances for product groups/rings ----------++type instance LiftOf (a,b) = Integer++-- | Lift product ring of @Zq@s to 'Integer'+instance (Mod a, Mod b, Lift' a, Lift' b, Reduce Integer (a,b),+          ToInteger (LiftOf a), ToInteger (LiftOf b))+         => Lift' (a,b) where++  {-# INLINABLE lift #-}+  lift (a,b) =+    let moda = toInteger $ proxy modulus (Proxy::Proxy a)+        modb = toInteger $ proxy modulus (Proxy::Proxy b)+        q = moda * modb+        ainv = fromMaybe (error "Lift' (a,b): moduli not coprime") $ moda `modinv` modb+        lifta = toInteger $ lift a+        liftb = toInteger $ lift b+        -- put in [-q/2, q/2)+        (_,r) = (moda * (liftb - lifta) * ainv + lifta) `divModCent` q+    in r+++-- | Pair as product ring+instance (Ring r1, Ring r2) => Ring.C (r1, r2) where+  (x1, x2) * (y1, y2) = (x1*y1, x2*y2)+  one = (one,one)+  fromInteger x = (fromInteger x, fromInteger x)++  {-# INLINABLE (*) #-}+  {-# INLINABLE one #-}+  {-# INLINABLE fromInteger #-}++-- | Product ring as an (almost) field+instance (Field f1, Field f2) => Field.C (f1, f2) where+  (x1, x2) / (y1, y2) = (x1 / y1, x2 / y2)+  recip = recip *** recip+  {-# INLINABLE (/) #-}+  {-# INLINABLE recip #-}++-- | Product ring as an (almost) integral domain+instance (IntegralDomain a, IntegralDomain b) => IntegralDomain.C (a,b) where+  (a1,b1) `divMod` (a2,b2) =+    let (da,ra) = (a1 `divMod` a2)+        (db,rb) = (b1 `divMod` b2)+    in ((da,db), (ra,rb))+  {-# INLINABLE divMod #-}++-- | Product ring of @Zq@s as a @Zq@ (with 'Integer' modulus)+instance (Mod a, Mod b) => Mod (a,b) where+  type ModRep (a,b) = Integer++  modulus = tag $ fromIntegral (proxy modulus (Proxy::Proxy a)) *+            fromIntegral (proxy modulus (Proxy::Proxy b))+  {-# INLINABLE modulus #-}++-- | Reduce into product ring.+instance (Reduce a b1, Reduce a b2) => Reduce a (b1, b2) where+  reduce x = (reduce x, reduce x)+  {-# INLINABLE reduce #-}++-- | Rescale a product ring of @Zq@s+instance (Mod a, Field b, Lift a (ModRep a), Reduce (LiftOf a) b)+         => Rescale (a,b) b where+  rescale = let q1val = proxy modulus (Proxy::Proxy a)+                q1inv = recip $ reduce q1val+            in \(x1,x2) -> q1inv * (x2 - reduce (lift x1))+  {-# INLINABLE rescale #-}++-- | Rescale a product ring of @Zq@s+instance (Mod b, Field a, Lift b (ModRep b), Reduce (LiftOf b) a)+         => Rescale (a,b) a where+  rescale = let q2val = proxy modulus (Proxy::Proxy b)+                q2inv = recip $ reduce q2val+            in \(x1,x2) -> q2inv * (x1 - reduce (lift x2))+  {-# INLINABLE rescale #-}++-- | Rescale a (multi-)product ring of @Zq@s+instance (Rescale (a,(b,c)) (b,c), Rescale (b,c) c)+         => Rescale (a,(b,c)) c where+  rescale = (rescale :: (b,c) -> c) . rescale+  {-# INLINABLE rescale #-}++-- | Rescale a (multi-)product ring of @Zq@s+instance (Rescale ((a,b),c) (a,b), Rescale (a,b) a)+         => Rescale ((a,b),c) a where+  rescale = (rescale :: (a,b) -> a) . rescale+  {-# INLINABLE rescale #-}++-- | Rescale /up/ to a product ring of @Zq@s+instance (Ring a, Mod b, Reduce (ModRep b) a) => Rescale a (a,b) where+  -- multiply by q2+  rescale = let q2val = reduce $ proxy modulus (Proxy::Proxy b)+            in \x -> (q2val * x, zero)+  {-# INLINABLE rescale #-}++-- | Rescale /up/ to a product ring of @Zq@s+instance (Ring b, Mod a, Reduce (ModRep a) b) => Rescale b (a,b) where+  -- multiply by q1+  rescale = let q1val = reduce $ proxy modulus (Proxy::Proxy a)+            in \x -> (zero, q1val * x)+  {-# INLINABLE rescale #-}++-- | Encode for a product ring+instance (Encode s t1, Encode s t2, Field (t1, t2)) => Encode s (t1, t2) where+  {-# INLINABLE lsdToMSD #-}+  lsdToMSD = let (s1, t1conv) = lsdToMSD+                 (s2, t2conv) = lsdToMSD+             in (negate s1 * s2, (t1conv,t2conv))++-- Random could have defined this instance, but didn't, so we do it+-- here.+instance (Random a, Random b) => Random (a,b) where+  {-# INLINABLE random #-}+  random g = let (a,g') = random g+                 (b, g'') = random g'+             in ((a,b), g'')++  {-# INLINABLE randomR #-}+  randomR ((loa,lob), (hia,hib)) g = let (a,g') = randomR (loa,hia) g+                                         (b,g'') = randomR (lob,hib) g'+                                     in ((a,b),g'')++-- | Version of 'fromJust' with an error message.+fromJust' :: String -> Maybe a -> a+fromJust' str = fromMaybe (error str)++-- | Apply any applicative to a Tagged value.+pureT :: Applicative f => Tagged t a -> TaggedT t f a+pureT = mapTaggedT (pure . runIdentity)++-- | Expose the monad of a tagged value.+peelT :: Tagged t (f a) -> TaggedT t f a+peelT = coerce++-- | Hide the monad of a tagged value.+pasteT :: TaggedT t f a -> Tagged t (f a)+pasteT = coerce++-- | Use a singleton as a witness to extract a value from a tagged value.+withWitness :: forall n r . (SingI n => Tagged n r) -> Sing n -> r+withWitness t wit = withSingI wit $ proxy t (Proxy::Proxy n)+{-# INLINABLE withWitness #-}++-- | Transformer version of 'withWitness'.+withWitnessT :: forall n mon r .+                (SingI n => TaggedT n mon r) -> Sing n -> mon r+withWitnessT t wit = withSingI wit $ proxyT t (Proxy::Proxy n)+{-# INLINABLE withWitnessT #-}
+ Crypto/Lol/RLWE/Continuous.hs view
@@ -0,0 +1,68 @@+{-# LANGUAGE ConstraintKinds, FlexibleContexts, MultiParamTypeClasses,+             NoImplicitPrelude, RebindableSyntax, ScopedTypeVariables #-}++-- | Functions and types for working with continuous ring-LWE samples.++module Crypto.Lol.RLWE.Continuous where++import Crypto.Lol.Cyclotomic.Cyc    as C+import Crypto.Lol.Cyclotomic.Tensor (TElt)+import Crypto.Lol.Cyclotomic.UCyc   as U+import Crypto.Lol.Prelude++import Control.Applicative+import Control.Monad.Random++-- | A continuous RLWE sample @(a,b) \in R_q \times K/qR@.  (The+-- second component is a 'UCyc' because the base type @rrq@+-- representing @RR/qZ@, the reals modulo @qZ@, is an additive group+-- but not a ring, so we can't usefully work with a 'Cyc' over it.)+type Sample t m zq rrq = (Cyc t m zq, UCyc t m D rrq)++-- | Common constraints for working with continuous RLWE.+type RLWECtx t m zq rrq =+  (Fact m, Ring zq, CElt t zq, Subgroup zq rrq, Lift' rrq,+   TElt t rrq, TElt t (LiftOf rrq))++-- | A continuous RLWE sample with the given scaled variance and+-- secret.+sample :: forall rnd v t m zq rrq .+  (RLWECtx t m zq rrq, Random zq, Random (LiftOf rrq), OrdFloat (LiftOf rrq),+   MonadRandom rnd, ToRational v)+  => v -> Cyc t m zq -> rnd (Sample t m zq rrq)+{-# INLINABLE sample #-}+sample svar s = let s' = adviseCRT s in do+  a <- getRandom+  e :: UCyc t m D (LiftOf rrq) <- U.tGaussian svar+  let as = fmapDec fromSubgroup $ uncycDec $ a * s' :: UCyc t m D rrq+  return (a, as + reduce e)++-- | The error term of an RLWE sample, given the purported secret.+errorTerm :: (RLWECtx t m zq rrq)+             => Cyc t m zq -> Sample t m zq rrq -> UCyc t m D (LiftOf rrq)+{-# INLINABLE errorTerm #-}+errorTerm s = let s' = adviseCRT s+              in \(a,b) -> lift $ b - fmapDec fromSubgroup (uncycDec $ a * s')++-- | The 'gSqNorm' of the error term of an RLWE sample, given the+-- purported secret.+errorGSqNorm :: (RLWECtx t m zq rrq, Ring (LiftOf rrq))+                => Cyc t m zq -> Sample t m zq rrq -> LiftOf rrq+{-# INLINABLE errorGSqNorm #-}+errorGSqNorm s = U.gSqNorm . errorTerm s++-- | A bound such that the 'gSqNorm' of a continuous error generated+-- by 'tGaussian' with scaled variance @v@ (over the @m@th cyclotomic+-- field) is less than the bound except with probability approximately+-- @eps@.+errorBound :: (Ord v, Transcendental v, Fact m)+              => v              -- ^ the scaled variance+              -> v              -- ^ @eps@+              -> Tagged m v+errorBound v eps = do+  n <- fromIntegral <$> totientFact+  mhat <- fromIntegral <$> valueHatFact+  let stabilize x =+        let x' = (1/2 + log (2 * pi * x)/2 - log eps/n)/pi+        in if x'-x < 0.0001 then x' else stabilize x'+  return $ mhat * n * v * stabilize (1/(2*pi))
+ Crypto/Lol/RLWE/Discrete.hs view
@@ -0,0 +1,64 @@+{-# LANGUAGE ConstraintKinds, FlexibleContexts, MultiParamTypeClasses,+             NoImplicitPrelude, RebindableSyntax, ScopedTypeVariables #-}++-- | Functions and types for working with discretized ring-LWE samples.++module Crypto.Lol.RLWE.Discrete where++import Crypto.Lol.Cyclotomic.Cyc+import Crypto.Lol.Prelude+import Crypto.Lol.RLWE.Continuous as C (errorBound)++import Control.Applicative+import Control.Monad.Random++-- | A discrete RLWE sample @(a,b) \in R_q \times R_q@.+type Sample t m zq = (Cyc t m zq, Cyc t m zq)++-- | Common constraints for working with discrete RLWE.+type RLWECtx t m zq =+  (Fact m, Ring zq, Lift' zq, ToInteger (LiftOf zq),+   CElt t zq, CElt t (LiftOf zq))++-- | A discrete RLWE sample with the given scaled variance and+-- secret.+sample :: forall rnd v t m zq .+  (RLWECtx t m zq, Random zq, MonadRandom rnd, ToRational v)+  => v -> Cyc t m zq -> rnd (Sample t m zq)+{-# INLINABLE sample #-}+sample svar s = let s' = adviseCRT s in do+  a <- getRandom+  e :: Cyc t m (LiftOf zq) <- errorRounded svar+  return (a, a * s' + reduce e)++-- | The error term of an RLWE sample, given the purported secret.+errorTerm :: (RLWECtx t m zq)+             => Cyc t m zq -> Sample t m zq -> Cyc t m (LiftOf zq)+{-# INLINABLE errorTerm #-}+errorTerm s = let s' = adviseCRT s+              in \(a,b) -> liftDec $ b - a * s'++-- | The 'gSqNorm' of the error term of an RLWE sample, given the+-- purported secret.+errorGSqNorm :: (RLWECtx t m zq, Ring (LiftOf zq))+                => Cyc t m zq -> Sample t m zq -> LiftOf zq+{-# INLINABLE errorGSqNorm #-}+errorGSqNorm s = gSqNorm . errorTerm s++-- | A bound such that the 'gSqNorm' of a discretized error term+-- generated by 'errorRounded' with scaled variance @v@ (over the @m@th+-- cyclotomic field) is less than the bound except with probability+-- approximately @eps@.+errorBound :: (RealRing v, Transcendental v, Fact m)+              => v              -- ^ the scaled variance+              -> v              -- ^ @eps@+              -> Tagged m Int64+errorBound v eps = do+  n <- fromIntegral <$> totientFact+  cont <- C.errorBound v eps -- continuous bound+  ps <- filter (/= 2) . fmap fst <$> ppsFact -- odd primes dividing m+  let stabilize x =+        let x' = (1/2 + log(2 * pi * x)/2 - log eps)/pi+        in if x'-x < 0.0001 then x' else stabilize x'+  return $ ceiling $ (2 ^ length ps) * n * stabilize (1/(2*pi)) + cont+
+ Crypto/Lol/RLWE/RLWR.hs view
@@ -0,0 +1,31 @@+{-# LANGUAGE ConstraintKinds, FlexibleContexts, MultiParamTypeClasses,+             NoImplicitPrelude, ScopedTypeVariables #-}++-- | Functions and types for working with ring-LWR samples.++module Crypto.Lol.RLWE.RLWR where++import Crypto.Lol++import Control.Monad.Random++-- | An RLWR sample @(a,b) \in R_q \times R_p@.+type Sample t m zq zp = (Cyc t m zq, Cyc t m zp)++-- | Common constraints for working with RLWR.+type RLWRCtx t m zq zp =+  (Fact m, Ring zq, RescaleCyc (Cyc t) zq zp, CElt t zq, CElt t zp)++-- | An RLWR sample with the given secret.+sample :: (RLWRCtx t m zq zp, Random zq, MonadRandom rnd)+          => Cyc t m zq -> rnd (Sample t m zq zp)+sample s = let s' = adviseCRT s in do+  a <- getRandom+  return (a, roundedProd s' a)++-- | The @b@ component of an RLWR sample for secret @s@ and given @a@,+-- produced by rounding @a*s@ in the decoding basis.+roundedProd :: (RLWRCtx t m zq zp) => Cyc t m zq -> Cyc t m zq -> Cyc t m zp+{-# INLINABLE roundedProd #-}+roundedProd s = let s' = adviseCRT s in \a -> rescaleCyc Dec $ a * s'+
Crypto/Lol/Reflects.hs view
@@ -5,10 +5,11 @@ -- | Generic interface for reflecting types to values.  module Crypto.Lol.Reflects-( Reflects(..)+( Reflects(..), ) where  import Algebra.ToInteger as ToInteger+import Algebra.Ring as Ring import NumericPrelude  import Crypto.Lol.Factored@@ -40,18 +41,15 @@  -} --- CJP: need reflections for Prime and PrimePower types because we use--- them with ZqBasic--instance (Prim p, ToInteger.C i) => Reflects p i where+instance (Prime p, ToInteger.C i) => Reflects p i where   value = fromIntegral <$> valuePrime  instance (PPow pp, ToInteger.C i) => Reflects pp i where   value = fromIntegral <$> valuePPow --- CJP: need this for Types.ZmStar, where we use ZqBasic m Int instance (Fact m, ToInteger.C i) => Reflects m i where   value = fromIntegral <$> valueFact -instance {-# OVERLAPS #-} (Reifies rei a) => Reflects (rei :: *) a where-  value = tag $ reflect (Proxy::Proxy rei)+instance (Reifies q i, ToInteger.C i, Ring.C r)+  => Reflects (q :: *) r where+  value = tag $ fromIntegral $ reflect (Proxy::Proxy q)
Crypto/Lol/Types/Complex.hs view
@@ -1,8 +1,15 @@-{-# LANGUAGE DataKinds, FlexibleContexts, FlexibleInstances,-             GeneralizedNewtypeDeriving, MultiParamTypeClasses,-             NoImplicitPrelude, RebindableSyntax, ScopedTypeVariables,-             StandaloneDeriving, TemplateHaskell, TypeFamilies,-             UndecidableInstances #-}+{-# LANGUAGE DataKinds                  #-}+{-# LANGUAGE DeriveGeneric              #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE NoImplicitPrelude          #-}+{-# LANGUAGE RebindableSyntax           #-}+{-# LANGUAGE ScopedTypeVariables        #-}+{-# LANGUAGE StandaloneDeriving         #-}+{-# LANGUAGE TemplateHaskell            #-}+{-# LANGUAGE TypeFamilies               #-}  -- | Data type, functions, and instances for complex numbers. @@ -31,19 +38,18 @@  -- | Newtype wrapper (with slightly different instances) for -- <https://hackage.haskell.org/package/numeric-prelude-0.4.2/docs/Number-Complex.html numeric-prelude Complex>.-newtype Complex a = Complex (C.T a) deriving (Additive.C, Ring.C, ZeroTestable.C, Field.C, Storable, Eq, Show, Arbitrary)+newtype Complex a = Complex (C.T a)+    deriving (Additive.C, Ring.C, ZeroTestable.C, Field.C, Storable, Eq, Show, Arbitrary)  derivingUnbox "Complex"   [t| forall a . (Unbox a) => Complex a -> (a, a) |]   [| \ (Complex x) -> (C.real x, C.imag x) |]   [| \ (r, i) -> Complex $ r C.+: i |] --- a custom IntegralDomain instance, replacing the one provided by NP.--- it always returns 0 as the remainder of a division.  If we were to--- use the NP instance, sometimes precision issues yield nonzero--- remainders, which makes, e.g., 'divGPow' think that division has--- failed, when it has not.  This in turn causes 'divGCRT' to yield--- Nothing, among other problems.+-- | Custom instance replacing the one provided by numeric prelude: it+-- always returns 0 as the remainder of a division.  (The NP instance+-- sometimes has precision issues, because it yields nonzero+-- remainders, which is a problem for 'divG' methods.) instance (Field a) => IntegralDomain.C (Complex a) where   (Complex a) `divMod` (Complex b) = (Complex $ a / b, LP.zero) 
Crypto/Lol/Types/FiniteField.hs view
@@ -1,8 +1,16 @@-{-# LANGUAGE ConstraintKinds, DataKinds, FlexibleContexts,-             GeneralizedNewtypeDeriving, MultiParamTypeClasses,-             NoImplicitPrelude, PolyKinds, RebindableSyntax,-             RoleAnnotations, ScopedTypeVariables, TypeFamilies,-             UndecidableInstances #-}+{-# LANGUAGE ConstraintKinds            #-}+{-# LANGUAGE DataKinds                  #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE InstanceSigs               #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE NoImplicitPrelude          #-}+{-# LANGUAGE PolyKinds                  #-}+{-# LANGUAGE RebindableSyntax           #-}+{-# LANGUAGE RoleAnnotations            #-}+{-# LANGUAGE ScopedTypeVariables        #-}+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE UndecidableInstances       #-}  -- CJP: need PolyKinds to allow d to have non-* kind @@ -18,7 +26,7 @@  import Crypto.Lol.CRTrans import Crypto.Lol.Factored-import Crypto.Lol.LatticePrelude+import Crypto.Lol.Prelude import Crypto.Lol.Reflects  import Algebra.Additive     as Additive (C)@@ -44,9 +52,11 @@ -- the second argument, though phantom, affects representation type role GF representational representational +-- | Constraint synonym for a prime field. type PrimeField fp = (Enumerable fp, Field fp, Eq fp, ZeroTestable fp,-                      Prim (CharOf fp), IrreduciblePoly fp)+                      Prime (CharOf fp), IrreduciblePoly fp) +-- | Constraint synonym for a finite field. type GFCtx fp d = (PrimeField fp, Reflects d Int)  instance (GFCtx fp d) => Enumerable (GF fp d) where@@ -69,26 +79,35 @@           in \(GF f) -> let (_,(a,_)) = extendedGCD f g                            in GF a -instance (GFCtx fp d) => CRTrans (GF fp d) where+instance (GFCtx fp d) => CRTrans Maybe (GF fp d) where -  crtInfo m = (,) <$> omegaPow <*> scalarInv+  crtInfo :: forall m . (Reflects m Int) => TaggedT m Maybe (CRTInfo (GF fp d))+  crtInfo = tagT $ (,) <$> omegaPow <*> scalarInv     where+      omegaPow :: Maybe (Int -> GF fp d)       omegaPow =         let size' = proxy size (Proxy :: Proxy (GF fp d))-            (q,r) = (size'-1) `quotRem` m+            mval = proxy value (Proxy :: Proxy m)+            (q,r) = (size'-1) `quotRem` mval             gen = head $ filter isPrimitive values             omega = gen^q-            omegaPows = V.iterateN m (*omega) one+            omegaPows = V.iterateN mval (*omega) one         in if r == 0-           then Just $ (omegaPows V.!) . (`mod` m)+           then Just $ (omegaPows V.!) . (`mod` mval)            else Nothing-      scalarInv = Just $ recip $ fromIntegral $ valueHat m+      scalarInv :: Maybe (GF fp d)+      scalarInv = Just $ recip $ fromIntegral $ valueHat+                    (proxy value (Proxy::Proxy m) :: Int) +-- | This wrapper for a list of coefficients is used to define a+-- @GF(p^d)@-module structure for tensors over @F_p@ of dimension @n@, where+-- @d | n@. newtype TensorCoeffs a = Coeffs {unCoeffs :: [a]} deriving (Additive.C)+ instance (Additive fp, Ring (GF fp d), Reflects d Int)   => Module.C (GF fp d) (TensorCoeffs fp) where -  r *> (Coeffs fps) = +  r *> (Coeffs fps) =     let dval = proxy value (Proxy::Proxy d)         n = length fps     in if n `mod` dval /= 0 then@@ -103,18 +122,18 @@   | otherwise = error "chunksOf: non-positive n"  -- | Yield a list of length exactly @d@ (i.e., including trailing zeros)--- of the @fp@-coefficients with respect to the power basis+-- of the @fp@-coefficients with respect to the power basis. toList :: forall fp d . (Reflects d Int, Additive fp) => GF fp d -> [fp] toList = let dval = proxy value (Proxy::Proxy d)          in \(GF p) -> let l = coeffs p-                       in l ++ (replicate (dval - length l) zero)+                       in l ++ replicate (dval - length l) zero  -- | Yield a field element given up to @d@ coefficients with respect -- to the power basis. fromList :: forall fp d . (Reflects d Int) => [fp] -> GF fp d fromList = let dval = proxy value (Proxy::Proxy d)            in \cs -> if length cs <= dval then GF $ fromCoeffs cs-                     else error $ "FiniteField.fromList: length " ++ +                     else error $ "FiniteField.fromList: length " ++                               show (length cs) ++ " > degree " ++ show dval  sizePP :: forall fp d . (GFCtx fp d) => Tagged (GF fp d) PP@@ -148,7 +167,7 @@   --          ", d = " ++ show (proxy value (Proxy::Proxy d) :: Int)) $   let d = proxy value (Proxy :: Proxy d)   in tag $ map trace' $ take d $-     iterate (* (GF (X ^^ 1))) (one :: GF fp d)+     iterate (* GF (X ^^ 1)) (one :: GF fp d)  -- helper that computes trace via brute force: sum frobenius -- automorphisms
Crypto/Lol/Types/IZipVector.hs view
@@ -16,8 +16,10 @@ import Control.DeepSeq import Data.Data import Data.Functor.Trans.Tagged-import Data.Vector               as V +import Data.Vector as V++ -- | Indexed Zip Vector: a wrapper around a (boxed) 'Vector' that has -- zip-py 'Applicative' behavior, analogous to -- 'Control.Applicative.ZipList' for lists.  The index @m@ enforces@@ -28,8 +30,7 @@                unIZipVector :: Vector a}   -- not deriving Read, Monoid, Alternative, Monad[Plus], IsList   -- because of different semantics and/or length restriction-  deriving (Show, Eq, NFData, Functor,-            Foldable, Traversable, ZeroTestable.C)+  deriving (Show, Eq, NFData, Functor, Foldable, Traversable, ZeroTestable.C)  -- the first argument, though phantom, affects representation type role IZipVector representational representational@@ -42,6 +43,7 @@                        then Just $ IZipVector vec                        else Nothing +-- | Unzip an IZipVector. unzipIZV :: IZipVector m (a,b) -> (IZipVector m a, IZipVector m b) unzipIZV (IZipVector v) = let (va,vb) = V.unzip v                           in (IZipVector va, IZipVector vb)
Crypto/Lol/Types/IrreducibleChar2.hs view
@@ -6,62 +6,165 @@  module Crypto.Lol.Types.IrreducibleChar2 () where -import Crypto.Lol.LatticePrelude+import Crypto.Lol.Prelude hiding (lookup) import Crypto.Lol.Reflects-import Crypto.Lol.Types.FiniteField---- | Convenience function.-taggedProxy :: Tagged s (Proxy s)-taggedProxy = tag Proxy+import Crypto.Lol.Types.FiniteField hiding (fromList) --- CJP: we should perhaps prefer ternary (or 5-ary) polynomials over--- Conway polynomials, because we don't use the special properties of--- Conways, and reduction modulo sparse polynomials should be faster.+import Data.Map hiding (map)+import Data.Maybe (fromMaybe) --- conway---generate in Python (or choose any irreducible polynomial)--- to generate with Sage, start sage and type:---      conway_polynomial(p,e)--- then copy and paste instance (CharOf a ~ Prime2, Field a) => IrreduciblePoly a where   irreduciblePoly = do-    pn <- taggedProxy-    let n = proxy value pn :: Int-    return $ case n of-      1 -> X^^1 + 1-      2 -> X^^2 + X^^1 + 1-      3 -> X^^3 + X^^1 + 1-      4 -> X^^4 + X^^1 + 1-      5 -> X^^5 + X^^2 + 1-      6 -> X^^6 + X^^4 + X^^3 + X^^1 + 1-      7 -> X^^7 + X^^1 + 1-      8 -> X^^8 + X^^4 + X^^3 + X^^2 + 1-      9 -> X^^9 + X^^4 + 1-      10 -> X^^10 + X^^6 + X^^5 + X^^3 + X^^2 + X^^1 + 1-      11 -> X^^11 + X^^2 + 1-      12 -> X^^12 + X^^7 + X^^6 + X^^5 + X^^3 + X^^1 + 1-      13 -> X^^13 + X^^4 + X^^3 + X^^1 + 1-      14 -> X^^14 + X^^7 + X^^5 + X^^3 + 1-      15 -> X^^15 + X^^5 + X^^4 + X^^2 + 1-      16 -> X^^16 + X^^5 + X^^3 + X^^2 + 1-      17 -> X^^17 + X^^3 + 1-      18 -> X^^18 + X^^12 + X^^10 + X^^1 + 1-      19 -> X^^19 + X^^5 + X^^2 + X^^1 + 1-      20 -> X^^20 + X^^10 + X^^9 + X^^7 + X^^6 + X^^5 + X^^4 + X^^1 + 1-      21 -> X^^21 + X^^6 + X^^5 + X^^2 + 1-      22 -> X^^22 + X^^12 + X^^11 + X^^10 + X^^9 + X^^8 + X^^6 + X^^5 + 1-      23 -> X^^23 + X^^5 + 1-      24 -> X^^24 + X^^16 + X^^15 + X^^14 + X^^13 + X^^10 + X^^9 + X^^7 + X^^5 + X^^3 + 1-      25 -> X^^25 + X^^8 + X^^6 + X^^2 + 1-      26 -> X^^26 + X^^14 + X^^10 + X^^8 + X^^7 + X^^6 + X^^4 + X^^1 + 1-      27 -> X^^27 + X^^12 + X^^10 + X^^9 + X^^7 + X^^5 + X^^3 + X^^2 + 1-      28 -> X^^28 + X^^13 + X^^7 + X^^6 + X^^5 + X^^2 + 1-      29 -> X^^29 + X^^2 + 1-      30 -> X^^30 + X^^17 + X^^16 + X^^13 + X^^11 + X^^7 + X^^5 + X^^3 + X^^2 + X^^1 + 1-      31 -> X^^31 + X^^3 + 1-      32 -> X^^32 + X^^15 + X^^9 + X^^7 + X^^4 + X^^3 + 1-      _ ->-        error $ "The IrreduciblePoly instance for N2 included with the library (and exported by Crypto.Lol) only contains " ++-                "irreducible polynomials for characteristic-2 fields up to GF(2^^32). You need a polynomial " ++-                "for GF(2^^" ++ (show n) ++ "). Define your own instance of IrreduciblePoly and do " ++-                "not import Crypto.Lol."+    n <- value+    return $ flip fromMaybe (lookup n polyMap) $+      error $+        "The IrreduciblePoly instance for N2 included with the library " +++        "(and exported by Crypto.Lol) only contains irreducible polynomials " +++        "for characteristic-2 fields up to GF(2^^32). You need a polynomial " +++        "for GF(2^^" ++ show n ++ "). Define your own instance of " +++        "IrreduciblePoly and do not import Crypto.Lol."++polyMap :: (Ring fp) => Map Int (Polynomial fp)+polyMap = fromList $ map (\xs -> (head xs, coeffsToPoly xs)) coeffs++coeffsToPoly :: (Ring fp) => [Int] -> Polynomial fp+coeffsToPoly [a,b] = X^^a + X^^b + 1+coeffsToPoly [a,b,c,d] = X^^a + X^^b + X^^c + X^^d + 1++-- The list below is small portion of the table+-- "Table of Low-Weight binary Irreducible Polynomials" at+-- http://www.hpl.hp.com/techreports/98/HPL-98-135.pdf?jumpid=reg_R1002_USEN+-- The lists are coefficients of minimal polynomials:+--   [a,b] is the irreducible trinomial X^a + X^b + 1+--   [a,b,c,d] is the irreducible pentanomial X^a + X^b + X^c + X^d + 1+coeffs :: [[Int]]+coeffs = [+  [1,1],+  [2,1],+  [3,1],+  [4,1],+  [5,2],+  [6,1],+  [7,1],+  [8,4,3,1],+  [9,1],+  [10,3],+  [11,2],+  [12,3],+  [13,4,3,1],+  [14,5],+  [15,1],+  [16,5,3,1],+  [17,3],+  [18,3],+  [19,5,2,1],+  [20,3],+  [21,2],+  [22,1],+  [23,5],+  [24,4,3,1],+  [25,3],+  [26,4,3,1],+  [27,5,2,1],+  [28,1],+  [29,2],+  [30,1],+  [31,3],+  [32,7,3,2],+  [33,10],+  [34,7],+  [35,2],+  [36,9],+  [37,6,4,1],+  [38,6,5,1],+  [39,4],+  [40,5,4,3],+  [41,3],+  [42,7],+  [43,6,4,3],+  [44,5],+  [45,4,3,1],+  [46,1],+  [47,5],+  [48,5,3,2],+  [49,9],+  [50,4,3,2],+  [51,6,3,1],+  [52,3],+  [53,6,2,1],+  [54,9],+  [55,7],+  [56,7,4,2],+  [57,4],+  [58,19],+  [59,7,4,2],+  [60,1],+  [61,5,2,1],+  [62,29],+  [63,1],+  [64,4,3,1],+  [65,18],+  [66,3],+  [67,5,2,1],+  [68,9],+  [69,6,5,2],+  [70,5,3,1],+  [71,6],+  [72,10,9,3],+  [73,25],+  [74,35],+  [75,6,3,1],+  [76,21],+  [77,6,5,2],+  [78,6,5,3],+  [79,9],+  [80,9,4,2],+  [81,4],+  [82,8,3,1],+  [83,7,4,2],+  [84,5],+  [85,8,2,1],+  [86,21],+  [87,13],+  [88,7,6,2],+  [89,38],+  [90,27],+  [91,8,5,1],+  [92,21],+  [93,2],+  [94,21],+  [95,11],+  [96,10,9,6],+  [97,6],+  [98,11],+  [99,6,3,1],+  [100,15],+  [101,7,6,1],+  [102,29],+  [103,9],+  [104,4,3,1],+  [105,4],+  [106,15],+  [107,9,7,4],+  [108,17],+  [109,5,4,2],+  [110,33],+  [111,10],+  [112,5,4,3],+  [113,9],+  [114,5,3,2],+  [115,8,7,5],+  [116,4,2,1],+  [117,5,2,1],+  [118,33],+  [119,8],+  [120,4,3,1],+  [121,18],+  [122,6,2,1],+  [123,2],+  [124,19],+  [125,7,6,5],+  [126,21],+  [127,1],+  [128,7,2,1]+  ]
Crypto/Lol/Types/Numeric.hs view
@@ -131,7 +131,7 @@ -- | Sane synonym for 'MathObj.Polynomial.T'. type Polynomial a = MathObj.Polynomial.T a --- | IntegralDomain instance for Double+-- IntegralDomain instance for Double instance Algebra.IntegralDomain.C Double where     _ `div` 0 = error "cannot divide Double by 0\n"     a `div` b = a / b@@ -204,7 +204,7 @@               => i              -- ^ dividend @a@               -> i              -- ^ divisor @b@               -> (i,i)          -- ^ (quotient, remainder)-divModCent = flip (\b -> +divModCent = flip (\b ->              let shift = b `div` 2              in \a -> let (q,r) = (a+shift) `divMod` b                       in (q,r-shift))
+ Crypto/Lol/Types/Proto.hs view
@@ -0,0 +1,50 @@+{-# LANGUAGE FlexibleContexts, FlexibleInstances, PolyKinds,+             ScopedTypeVariables, TypeFamilies #-}++-- | Convenient interfaces for serialization with protocol buffers.++module Crypto.Lol.Types.Proto where++import Control.Monad.Except+import Data.ByteString.Lazy hiding (map)+import Data.Foldable (toList)+import Data.Sequence (fromList)++import Text.ProtocolBuffers        (messageGet, messagePut)+import Text.ProtocolBuffers.Header++-- | Conversion between Haskell types and their protocol buffer representations.+class Protoable a where+  -- | The protocol buffer type for @a@.+  type ProtoType a++  -- | Convert from a type to its protocol buffer representation.+  toProto :: a -> ProtoType a+  -- | Convert from a protocol buffer representation.+  fromProto :: MonadError String m => ProtoType a -> m a++instance (Protoable a) => Protoable [a] where+  type ProtoType [a] = Seq (ProtoType a)+  toProto = fromList . map toProto+  fromProto = mapM fromProto . toList++instance (Protoable a, Protoable b) => Protoable (a,b) where+  type ProtoType (a,b) = (ProtoType a, ProtoType b)+  toProto (a,b) = (toProto a, toProto b)+  fromProto (a,b) = do+    a' <- fromProto a+    b' <- fromProto b+    return (a',b')++-- | Serialize a Haskell type to its protocol buffer 'ByteString'.+msgPut :: (ReflectDescriptor (ProtoType a), Wire (ProtoType a), Protoable a)+          => a -> ByteString+msgPut = messagePut . toProto++-- | Read a protocol buffer 'ByteString' to a Haskell type.+msgGet :: (ReflectDescriptor (ProtoType a), Wire (ProtoType a), Protoable a)+          => ByteString -> Either String (a, ByteString)+msgGet bs = do+  (msg, bs') <- messageGet bs+  p <- fromProto msg+  return (p, bs')
+ Crypto/Lol/Types/RRq.hs view
@@ -0,0 +1,112 @@+{-# LANGUAGE ConstraintKinds, FlexibleContexts, FlexibleInstances,+             GeneralizedNewtypeDeriving, MultiParamTypeClasses,+             NoImplicitPrelude, PolyKinds, RebindableSyntax,+             ScopedTypeVariables, TypeFamilies, UndecidableInstances #-}++-- | An implementation of the additive quotient group @RR/qZ@, where @RR@+-- denotes the real numbers.++module Crypto.Lol.Types.RRq+( RRq+) where++import Algebra.Additive     as Additive (C)+import Algebra.ZeroTestable as ZeroTestable (C)++import Control.Applicative+import Control.DeepSeq++import Crypto.Lol.Prelude+import Crypto.Lol.Reflects+import Crypto.Lol.Types.ZqBasic++-- for the Elt instance+import qualified Data.Array.Repa.Eval as E++-- for the Unbox instances+import qualified Data.Vector.Generic         as G+import qualified Data.Vector.Generic.Mutable as M+import qualified Data.Vector.Unboxed         as U++import Foreign.Storable++-- invariant: 0 <= x < q+-- | The ring @RR_q@ of reals modulo 'q', using underlying floating+-- type 'r'.+newtype RRq q r = RRq r+    deriving (Eq, Ord, ZeroTestable.C, E.Elt, Show, NFData, Storable)++{-# INLINABLE reduce' #-}+reduce' :: forall q r . (Reflects q r, RealField r) => r -> RRq q r+reduce' = let q = proxy value (Proxy::Proxy q)+          in \x -> RRq $ x - q * floor (x / q)++-- puts value in range [-q/2, q/2)+decode' :: forall q r . (Reflects q r, Ord r, Additive r, Ring r)+           => RRq q r -> r+decode' = let qval = proxy value (Proxy::Proxy q)+          in \(RRq x) -> if x + x < qval then x else x - qval++instance (Reflects q r, RealField r, Additive (RRq q r))+  => Reduce r (RRq q r) where+  reduce = reduce'++type instance LiftOf (RRq q r) = r++instance (Reflects q r, Reduce r (RRq q r), Ord r, Ring r)+  => Lift' (RRq q r) where+  lift = decode'++-- instance of Additive+instance (Reflects q r, RealField r, Ord r) => Additive.C (RRq q r) where++  {-# INLINABLE zero #-}+  zero = RRq zero++  {-# INLINABLE (+) #-}+  (+) = let qval = proxy value (Proxy::Proxy q)+        in \ (RRq x) (RRq y) ->+        let z = x + y+        in RRq (if z >= qval then z - qval else z)++  {-# INLINABLE negate #-}+  negate (RRq x) = reduce' $ negate x++instance (ToInteger i, RealField r, Reflects q i, Reflects q r)+  => Subgroup (ZqBasic q i) (RRq q r) where+  fromSubgroup = reduce' . fromIntegral . lift++-- CJP: restored manual Unbox instances, until we have a better way+-- (NewtypeDeriving or TH)++newtype instance U.MVector s (RRq q r) = MV_RRq (U.MVector s r)+newtype instance U.Vector (RRq q r) = V_RRq (U.Vector r)++-- Unbox, when underlying representation is+instance U.Unbox r => U.Unbox (RRq q r)++{- purloined and tweaked from code in `vector` package that defines+types as unboxed -}+instance U.Unbox r => M.MVector U.MVector (RRq q r) where+  basicLength (MV_RRq v) = M.basicLength v+  basicUnsafeSlice z n (MV_RRq v) = MV_RRq $ M.basicUnsafeSlice z n v+  basicOverlaps (MV_RRq v1) (MV_RRq v2) = M.basicOverlaps v1 v2+  basicInitialize (MV_RRq v) = M.basicInitialize v+  basicUnsafeNew n = MV_RRq <$> M.basicUnsafeNew n+  basicUnsafeReplicate n (RRq x) = MV_RRq <$> M.basicUnsafeReplicate n x+  basicUnsafeRead (MV_RRq v) z = RRq <$> M.basicUnsafeRead v z+  basicUnsafeWrite (MV_RRq v) z (RRq x) = M.basicUnsafeWrite v z x+  basicClear (MV_RRq v) = M.basicClear v+  basicSet (MV_RRq v) (RRq x) = M.basicSet v x+  basicUnsafeCopy (MV_RRq v1) (MV_RRq v2) = M.basicUnsafeCopy v1 v2+  basicUnsafeMove (MV_RRq v1) (MV_RRq v2) = M.basicUnsafeMove v1 v2+  basicUnsafeGrow (MV_RRq v) n = MV_RRq <$> M.basicUnsafeGrow v n++instance U.Unbox r => G.Vector U.Vector (RRq q r) where+  basicUnsafeFreeze (MV_RRq v) = V_RRq <$> G.basicUnsafeFreeze v+  basicUnsafeThaw (V_RRq v) = MV_RRq <$> G.basicUnsafeThaw v+  basicLength (V_RRq v) = G.basicLength v+  basicUnsafeSlice z n (V_RRq v) = V_RRq $ G.basicUnsafeSlice z n v+  basicUnsafeIndexM (V_RRq v) z = RRq <$> G.basicUnsafeIndexM v z+  basicUnsafeCopy (MV_RRq mv) (V_RRq v) = G.basicUnsafeCopy mv v+  elemseq _ = seq
Crypto/Lol/Types/Random.hs view
@@ -1,44 +1,35 @@-{-# LANGUAGE GeneralizedNewtypeDeriving, PackageImports #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-} --- | Defines a newtype wrapper for crypto-api's 'CryptoRandomGen', and a corresponding 'RandomGen' instance.---   'CryptoRandomGen' generators can only be used to get 'ByteString's; the 'RandomGen' instance allows them---   to be used to generate any 'Random' type. Typical usage is with Control.Monad.Random's 'RandT' monad.+-- | Defines a newtype wrapper 'CryptoRand' for crypto-api's+-- 'CryptoRandomGen', and a corresponding 'RandomGen' wrapper+-- instance.  These are needed because 'CryptoRandomGen' generators+-- can only be used to get 'ByteString's; the 'RandomGen' wrapper+-- instance allows them to be used to generate any 'Random' type. -module Crypto.Lol.Types.Random (CryptoRand) where+module Crypto.Lol.Types.Random (CryptoRand, evalCryptoRandIO) where -import "crypto-api" Crypto.Random-import Data.Binary.Get-import Data.ByteString hiding (pack)-import Data.ByteString.Lazy (pack)+import Control.Arrow+import Control.Monad.CryptoRandom+import Control.Monad.IO.Class+import Control.Monad.Random       (RandT, evalRandT)+import Crypto.Random import System.Random +-- | Turns a 'CryptoRandomGen' @g@ into a standard 'RandomGen'. newtype CryptoRand g = CryptoRand g deriving (CryptoRandomGen) -intBytes = -  let bits = intLog 2 $ (1 + (fromIntegral (maxBound :: Int)) - (fromIntegral (minBound :: Int)) :: Integer)-  in if (bits `mod` 8) == 0 then bits `div` 8 else error "invalid Int bits in `intBytes`"--bytesToInt :: ByteString -> Int-bytesToInt bs = case intBytes of-  4 -> fromIntegral $ runGet getWord32host $ pack $ unpack bs-  8 -> fromIntegral $ runGet getWord64host $ pack $ unpack bs-  _ -> error "Unsupported Int size in `bytesToInt`"---- | Yield @log_b(n)@ when it is a non-negative integer (otherwise--- error).-intLog :: (Integral i) => i -> i -> Int-intLog _ 1 = 0--- correct because ceil (lg (x)) == ceil (log (ceil (x)))-intLog b n | (n `mod` b) == 0 = 1 + intLog b (n `div` b)-           | otherwise = error "invalid arguments to intLog"+-- | Evaluate a 'RandT' computation using a cryptographic generator+-- @g@, seeded by system entropy.  Note that the updated generator is+-- not returned.+evalCryptoRandIO :: (CryptoRandomGen g, MonadIO io) => RandT g io a -> io a+evalCryptoRandIO x = do+  gen <- liftIO newGenIO -- uses system entropy+  evalRandT x gen +-- "standard" RNG interface wrapper for a cryptographic RNG instance (CryptoRandomGen g) => RandomGen (CryptoRand g) where-  next (CryptoRand g) = case genBytes intBytes g of-    Right (bs, g') -> (bytesToInt bs, CryptoRand g')-    Left err -> error $ "Next error: " ++ show err--  genRange _ = (minBound, maxBound)+  -- use 'CRandom' instance for 'Int'+  next (CryptoRand g) = either (error . show) (second CryptoRand) $ crandom g -  split (CryptoRand g) = case splitGen g of-    Right (g1, g2) -> (CryptoRand g1, CryptoRand g2)-    Left err -> error $ "Split error: " ++ show err+  split (CryptoRand g) =+    either (error . show) (CryptoRand *** CryptoRand) $ splitGen g
Crypto/Lol/Types/ZPP.hs view
@@ -6,7 +6,7 @@ ( ZPP(..) ) where -import Crypto.Lol.LatticePrelude+import Crypto.Lol.Prelude import Crypto.Lol.Types.FiniteField  -- | Represents integers modulo a prime power.
Crypto/Lol/Types/ZmStar.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE ConstraintKinds, DataKinds, FlexibleContexts,-             NoImplicitPrelude, PolyKinds, RebindableSyntax,-             ScopedTypeVariables, TypeFamilies, TypeOperators, -             UndecidableInstances #-}+             MultiParamTypeClasses, NoImplicitPrelude, PolyKinds,+             RebindableSyntax, ScopedTypeVariables, TypeFamilies,+             TypeOperators, UndecidableInstances #-}  -- | A collection of helper functions for working with @Z_m^*@ @@ -10,7 +10,7 @@ ) where  import Crypto.Lol.Factored-import Crypto.Lol.LatticePrelude as LP hiding (null)+import Crypto.Lol.Prelude       as LP hiding (null) import Crypto.Lol.Reflects import Crypto.Lol.Types.ZqBasic @@ -26,8 +26,8 @@   let mval = proxy value (Proxy::Proxy m)   in if gcd p mval /= 1      then error "p and m not coprime"-     else 1 + (length $ takeWhile (/= one) $-               tail $ iterate (* (fromIntegral p)) (one :: ZqBasic m Int))+     else 1 + length (takeWhile (/= one) $+                      tail $ iterate (* fromIntegral p) (one :: ZqBasic m Int))  -- given p, returns the cosets of Z_m^* / <p> cosets :: forall zm . (Mod zm, ModRep zm ~ Int, Ord zm, Ring zm)
Crypto/Lol/Types/ZqBasic.hs view
@@ -2,17 +2,22 @@              FlexibleInstances, GeneralizedNewtypeDeriving,
              MultiParamTypeClasses, NoImplicitPrelude, PolyKinds,
              RebindableSyntax, RoleAnnotations, ScopedTypeVariables,
-             StandaloneDeriving, TypeFamilies, UndecidableInstances #-}
+             TypeFamilies, UndecidableInstances #-}
 
--- | An implementation of modular arithmetic, i.e., the ring Zq.
+-- | An implementation of the quotient ring Zq = Z/qZ.
 
+-- EAC: It may help GHC do specialization at higher levels of the library
+-- if we "simplify" constraints in this module. For example, replace the
+-- (Additive (ZqBasic q z)) constraint on the Reduce instance with
+-- (Additive z)
+
 module Crypto.Lol.Types.ZqBasic
 ( ZqBasic -- export the type, but not the constructor (for safety)
 ) where
 
 import Crypto.Lol.CRTrans
 import Crypto.Lol.Gadget
-import Crypto.Lol.LatticePrelude    as LP
+import Crypto.Lol.Prelude           as LP
 import Crypto.Lol.Reflects
 import Crypto.Lol.Types.FiniteField
 import Crypto.Lol.Types.ZPP
@@ -49,7 +54,7 @@ -- | The ring @Z_q@ of integers modulo 'q', using underlying integer
 -- type 'z'.
 newtype ZqBasic q z = ZqB z
-                    deriving (Eq, Ord, ZeroTestable.C, E.Elt, Show, NFData, Storable)
+    deriving (Eq, Ord, ZeroTestable.C, E.Elt, Show, NFData, Storable)
 
 -- the q argument, though phantom, matters for safety
 type role ZqBasic nominal representational
@@ -58,25 +63,20 @@ --deriving instance (U.Unbox i) => M.MVector U.MVector (ZqBasic q i)
 --deriving instance (U.Unbox i) => U.Unbox (ZqBasic q i)
 
--- convenience synonym for many instances
-type ReflectsTI q z = (Reflects q z, ToInteger z)
-
 {-# INLINABLE reduce' #-}
-reduce' :: forall q z . (ReflectsTI q z) => z -> ZqBasic q z
+reduce' :: forall q z . (Reflects q z, ToInteger z) => z -> ZqBasic q z
 reduce' = ZqB . (`mod` proxy value (Proxy::Proxy q))
 
 -- puts value in range [-q/2, q/2)
-decode' :: forall q z . (ReflectsTI q z) => ZqBasic q z -> z
+decode' :: forall q z . (Reflects q z, ToInteger z) => ZqBasic q z -> z
 decode' = let qval = proxy value (Proxy::Proxy q)
-          in \(ZqB x) -> if 2 * x < qval
-                         then x
-                         else x - qval
+          in \(ZqB x) -> if 2 * x < qval then x else x - qval
 
-instance (ReflectsTI q z, Enum z) => Enumerable (ZqBasic q z) where
+instance (Reflects q z, ToInteger z, Enum z) => Enumerable (ZqBasic q z) where
   values = let qval :: z = proxy value (Proxy::Proxy q)
            in coerce [0..(qval-1)]
 
-instance (ReflectsTI q z) => Mod (ZqBasic q z) where
+instance (Reflects q z, ToInteger z) => Mod (ZqBasic q z) where
   type ModRep (ZqBasic q z) = z
 
   modulus = retag (value :: Tagged q z)
@@ -92,79 +92,78 @@   modulusZPP = retag (ppPPow :: Tagged pp PP)
   liftZp = coerce
 
-instance (ReflectsTI q z) => Reduce z (ZqBasic q z) where
+instance (Reflects q z, ToInteger z) => Reduce z (ZqBasic q z) where
   reduce = reduce'
 
-instance (Reflects q z, Ring (ZqBasic q z)) => Reduce Integer (ZqBasic q z) where
+instance (Reflects q z, ToInteger z, Additive (ZqBasic q z)) => Reduce Integer (ZqBasic q z) where
   reduce = fromInteger
 
 type instance LiftOf (ZqBasic q z) = z
 
-instance (ReflectsTI q z) => Lift' (ZqBasic q z) where
+instance (Reflects q z, ToInteger z) => Lift' (ZqBasic q z) where
   lift = decode'
 
-instance (ReflectsTI q z, ReflectsTI q' z, Ring z)
+instance (Reflects q z, ToInteger z, Reflects q' z, Ring z)
          => Rescale (ZqBasic q z) (ZqBasic q' z) where
 
-    rescale = rescaleMod
+  rescale = rescaleMod
 
-instance (Reflects p z, ReflectsTI q z,
-          Field (ZqBasic p z), Field (ZqBasic q z))
+instance (Reflects p z, Reflects q z, ToInteger z, Field (ZqBasic q z), Field (ZqBasic p z))
          => Encode (ZqBasic p z) (ZqBasic q z) where
 
-    lsdToMSD = let pval :: z = proxy value (Proxy::Proxy p)
-                   negqval :: z = negate $ proxy value (Proxy::Proxy q)
-               in (reduce' negqval, recip $ reduce' pval)
+  lsdToMSD = let pval :: z = proxy value (Proxy::Proxy p)
+                 negqval :: z = negate $ proxy value (Proxy::Proxy q)
+             in (reduce' negqval, recip $ reduce' pval)
 
 -- | Yield a /principal/ @m@th root of unity @omega_m \in @Z_q^*@.
 -- The implementation requires @q@ to be prime.  It works by finding a
 -- generator of @Z_q^*@ and raising it to the @(q-1)/m@ power.
 -- Therefore, outputs for different values of @m@ are consistent,
 -- i.e., @omega_{m'}^(m'/m) = omega_m@.
-
-principalRootUnity :: forall q z . (ReflectsTI q z, Enumerable (ZqBasic q z))
-                      => Int -> Maybe (Int -> ZqBasic q z)
+principalRootUnity ::
+    forall m q z . (Reflects m Int, Reflects q z, ToInteger z, Enumerable (ZqBasic q z))
+               => TaggedT m Maybe (Int -> ZqBasic q z)
 principalRootUnity =        -- use Integers for all intermediate calcs
-    let qval = fromIntegral $ (proxy value (Proxy::Proxy q) :: z)
-        -- order of Zq^* (assuming q prime)
-        order = qval-1
-        -- the primes dividing the order of Zq^*
-        pfactors = fst <$> factorise order
-        -- the powers we need to check
-        exps = div order <$> pfactors
-        -- whether an element is a generator of Zq^*
-        isGen x = (x^order == one) && all (\e -> x^e /= one) exps
-        -- for simplicity, require q to be prime
-    in if isPrime qval
-       then \m -> let (mq,mr) = order `divMod` fromIntegral m
-                  in if mr == 0
-                     then let omega = head (filter isGen values) ^ mq
-                              omegaPows = V.iterateN m (*omega) one
-                          in Just $ (omegaPows V.!) . (`mod` m)
-                     else Nothing
-       else const Nothing       -- fail if q composite
+  let qval = fromIntegral (proxy value (Proxy::Proxy q) :: z)
+      mval = proxy value (Proxy::Proxy m)
+      -- order of Zq^* (assuming q prime)
+      order = qval-1
+      -- the primes dividing the order of Zq^*
+      pfactors = fst <$> factorise order
+      -- the powers we need to check
+      exps = div order <$> pfactors
+      -- whether an element is a generator of Zq^*
+      isGen x = (x^order == one) && all (\e -> x^e /= one) exps
+  in tagT $ if isPrime qval -- for simplicity, require q to be prime
+            then let (mq,mr) = order `divMod` fromIntegral mval
+                 in if mr == 0
+                    then let omega = head (filter isGen values) ^ mq
+                             omegaPows = V.iterateN mval (*omega) one
+                         in Just $ (omegaPows V.!) . (`mod` mval)
+                    else Nothing
+            else Nothing       -- fail if q composite
 
+mhatInv :: forall m q z . (Reflects m Int, Reflects q z, ToInteger z, PID z)
+           => TaggedT m Maybe (ZqBasic q z)
+mhatInv = let qval = proxy value (Proxy::Proxy q)
+          in peelT $ (fmap reduce' . (`modinv` qval) . fromIntegral) <$>
+                 valueHat <$> (value :: Tagged m Int)
 
 -- instance of CRTrans
-instance (ReflectsTI q z, PID z, Enumerable (ZqBasic q z))
-         => CRTrans (ZqBasic q z) where
+instance (Reflects q z, ToInteger z, PID z, Enumerable (ZqBasic q z))
+         => CRTrans Maybe (ZqBasic q z) where
 
-  crtInfo =
-    --DT.trace ("ZqBasic.crtInfo: q = " ++
-    --          show (proxy value (Proxy::Proxy q) :: z)) $
-    let qval :: z = proxy value (Proxy::Proxy q)
-    in \m -> (,) <$> principalRootUnity m <*>
-                     (reduce' <$> fromIntegral (valueHat m) `modinv` qval)
+  crtInfo = (,) <$> principalRootUnity <*> mhatInv
 
--- instance of CRTEmbed
-instance (ReflectsTI q z, Ring (ZqBasic q z)) => CRTEmbed (ZqBasic q z) where
+-- | Embeds into complex numbers
+instance (Reflects q z, ToInteger z, Ring (ZqBasic q z)) => CRTEmbed (ZqBasic q z) where
   type CRTExt (ZqBasic q z) = Complex Double
 
   toExt (ZqB x) = fromReal $ fromIntegral x
   fromExt x = reduce' $ NP.round $ real x
 
 -- instance of Additive
-instance (ReflectsTI q z, Additive z) => Additive.C (ZqBasic q z) where
+instance (Reflects q z, ToInteger z, Additive z) => Additive.C (ZqBasic q z) where
 
   {-# INLINABLE zero #-}
   zero = ZqB zero
@@ -179,10 +178,10 @@   negate (ZqB x) = reduce' $ negate x
 
 -- instance of Ring
-instance (ReflectsTI q z, Ring z) => Ring.C (ZqBasic q z) where
+instance (Reflects q z, ToInteger z, Ring z) => Ring.C (ZqBasic q z) where
   {-# INLINABLE (*) #-}
   (ZqB x) * (ZqB y) = reduce' $ x * y
-    
+
   {-# INLINABLE fromInteger #-}
   fromInteger =
     let qval = toInteger (proxy value (Proxy::Proxy q) :: z)
@@ -190,7 +189,7 @@     in \x -> ZqB $ fromInteger $ x `mod` qval
 
 -- instance of Field
-instance (ReflectsTI q z, PID z, Show z) => Field.C (ZqBasic q z) where
+instance (Reflects q z, ToInteger z, PID z, Show z) => Field.C (ZqBasic q z) where
 
   {-# INLINABLE recip #-}
   recip = let qval = proxy value (Proxy::Proxy q)
@@ -200,18 +199,18 @@                          show x ++ "\t" ++ show qval) $ modinv x qval
 
 -- (canonical) instance of IntegralDomain, needed for Cyclotomics
-instance (Field (ZqBasic q z)) => IntegralDomain.C (ZqBasic q z) where
+instance (Reflects q z, ToInteger z, Field (ZqBasic q z)) => IntegralDomain.C (ZqBasic q z) where
   divMod a b = (a/b, zero)
 
 -- Gadget-related instances
-instance (ReflectsTI q z, Additive z) => Gadget TrivGad (ZqBasic q z) where
+instance (Reflects q z, ToInteger z, Additive z) => Gadget TrivGad (ZqBasic q z) where
   gadget = tag [one]
 
-instance (ReflectsTI q z, Ring z) => Decompose TrivGad (ZqBasic q z) where
+instance (Reflects q z, ToInteger z, Ring z) => Decompose TrivGad (ZqBasic q z) where
   type DecompOf (ZqBasic q z) = z
   decompose x = tag [lift x]
 
-instance (ReflectsTI q z, Ring z) => Correct TrivGad (ZqBasic q z) where
+instance (Reflects q z, ToInteger z, Ring z) => Correct TrivGad (ZqBasic q z) where
   correct a = case untag a of
     [b] -> (b, [zero])
     _ -> error "Correct TrivGad: wrong length"
@@ -220,21 +219,21 @@ 
 gadlen :: (RealIntegral z) => z -> z -> Int
 gadlen _ q | isZero q = 0
-gadlen b q = 1 + (gadlen b $ q `div` b)
+gadlen b q = 1 + gadlen b (q `div` b)
 
 -- | The base-@b@ gadget for modulus @q@, over integers (not mod
 -- anything).
 gadgetZ :: (RealIntegral z) => z -> z -> [z]
 gadgetZ b q = take (gadlen b q) $ iterate (*b) one
 
-instance (ReflectsTI q z, RealIntegral z, Reflects b z)
+instance (Reflects q z, ToInteger z, RealIntegral z, Reflects b z)
          => Gadget (BaseBGad b) (ZqBasic q z) where
 
   gadget = let qval = proxy value (Proxy :: Proxy q)
                bval = proxy value (Proxy :: Proxy b)
            in tag $ reduce' <$> gadgetZ bval qval
 
-instance (ReflectsTI q z, Ring z, ZeroTestable z, Reflects b z)
+instance (Reflects q z, ToInteger z, Ring z, ZeroTestable z, Reflects b z)
     => Decompose (BaseBGad b) (ZqBasic q z) where
   type DecompOf (ZqBasic q z) = z
   decompose = let qval = proxy value (Proxy :: Proxy q)
@@ -244,7 +243,7 @@               in tag . decomp radices . lift
 
 -- | Yield the error vector for a noisy multiple of the gadget (all
--- over the integers). 
+-- over the integers).
 correctZ :: forall z . (RealIntegral z)
             => z                   -- ^ modulus @q@
             -> z                   -- ^ base @b@
@@ -254,7 +253,7 @@   let gadZ = gadgetZ b q
       k = length gadZ
       gadlast = last gadZ
-  in \v -> 
+  in \v ->
     if length v /= k
     then error $ "correctZ: wrong length: was " ++ show (length v) ++", expected " ++ show k
     else let (w, x) = barBtRnd (q `div` b) v
@@ -266,7 +265,7 @@       -- | Yield @w = round(\bar{B}^t \cdot v / q)@, along with the inner
       -- product of @w@ with the top row of @q \bar{D}@.
       barBtRnd :: z -> [z] -> ([z], z)
-      barBtRnd _ (_:[]) = ([], zero)
+      barBtRnd _ [_] = ([], zero)
       barBtRnd q' (v1:vs@(v2:_)) = let quo = fst $ divModCent (b*v1-v2) q
                                    in (quo:) *** (quo*q' +) $
                                       barBtRnd (q' `div` b) vs
@@ -282,7 +281,7 @@       subLast [v0] [v'0] = let y = v0-v'0 in ([y], y)
       subLast (v0:vs) (v'0:v's) = first ((v0-v'0):) $ subLast vs v's
 
-instance (ReflectsTI q z, Ring z, Reflects b z)
+instance (Reflects q z, ToInteger z, Ring z, Reflects b z)
     => Correct (BaseBGad b) (ZqBasic q z) where
 
   correct =
@@ -294,7 +293,7 @@               in (head v - reduce (head es), es)
 
 -- instance of Random
-instance (ReflectsTI q z, Random z) => Random (ZqBasic q z) where
+instance (Reflects q z, ToInteger z, Random z) => Random (ZqBasic q z) where
   random = let high = proxy value (Proxy::Proxy q) - 1
            in \g -> let (x,g') = randomR (0,high) g
                     in (ZqB x, g')
@@ -302,7 +301,7 @@   randomR _ = error "randomR non-sensical for Zq types"
 
 -- instance of Arbitrary
-instance (ReflectsTI q z, Random z) => Arbitrary (ZqBasic q z) where
+instance (Reflects q z, ToInteger z, Random z) => Arbitrary (ZqBasic q z) where
   arbitrary =
     let qval :: z = proxy value (Proxy::Proxy q)
     in fromIntegral <$> choose (0, qval-1)
+ Crypto/Proto/RLWE.hs view
@@ -0,0 +1,23 @@+{-# LANGUAGE BangPatterns, DeriveDataTypeable, DeriveGeneric, FlexibleInstances, MultiParamTypeClasses #-}+{-# OPTIONS_GHC  -fno-warn-unused-imports #-}+module Crypto.Proto.RLWE (protoInfo, fileDescriptorProto) where+import Prelude ((+), (/))+import qualified Prelude as Prelude'+import qualified Data.Typeable as Prelude'+import qualified GHC.Generics as Prelude'+import qualified Data.Data as Prelude'+import qualified Text.ProtocolBuffers.Header as P'+import Text.DescriptorProtos.FileDescriptorProto (FileDescriptorProto)+import Text.ProtocolBuffers.Reflections (ProtoInfo)+import qualified Text.ProtocolBuffers.WireMessage as P' (wireGet,getFromBS)++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 []}"++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")
+ Crypto/Proto/RLWE/Kq.hs view
@@ -0,0 +1,95 @@+{-# LANGUAGE BangPatterns, DeriveDataTypeable, DeriveGeneric, FlexibleInstances, MultiParamTypeClasses #-}+{-# OPTIONS_GHC  -fno-warn-unused-imports #-}+module Crypto.Proto.RLWE.Kq (Kq(..)) where+import Prelude ((+), (/))+import qualified Prelude as Prelude'+import qualified Data.Typeable as Prelude'+import qualified GHC.Generics as Prelude'+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)}+        deriving (Prelude'.Show, Prelude'.Eq, Prelude'.Ord, Prelude'.Typeable, Prelude'.Data, Prelude'.Generic)++instance P'.Mergeable Kq where+  mergeAppend (Kq x'1 x'2 x'3) (Kq y'1 y'2 y'3) = Kq (P'.mergeAppend x'1 y'1) (P'.mergeAppend x'2 y'2) (P'.mergeAppend x'3 y'3)++instance P'.Default Kq where+  defaultValue = Kq P'.defaultValue P'.defaultValue P'.defaultValue++instance P'.Wire Kq where+  wireSize ft' self'@(Kq x'1 x'2 x'3)+   = case ft' of+       10 -> calc'Size+       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)+  wirePut ft' self'@(Kq x'1 x'2 x'3)+   = case ft' of+       10 -> put'Fields+       11 -> do+               P'.putSize (P'.wireSize 10 self')+               put'Fields+       _ -> P'.wirePutErr ft' self'+    where+        put'Fields+         = do+             P'.wirePutReq 8 13 x'1+             P'.wirePutReq 17 1 x'2+             P'.wirePutRep 25 1 x'3+  wireGet ft'+   = case ft' of+       10 -> P'.getBareMessageWith update'Self+       11 -> P'.getMessageWith update'Self+       _ -> P'.wireGetErr ft'+    where+        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)+             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++instance P'.MessageAPI msg' (msg' -> Kq) Kq where+  getVal m' f' = f' m'++instance P'.GPB Kq++instance P'.ReflectDescriptor Kq where+  getMessageInfo _ = P'.GetMessageInfo (P'.fromDistinctAscList [8, 17]) (P'.fromDistinctAscList [8, 17, 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}"++instance P'.TextType Kq where+  tellT = P'.tellSubMessage+  getT = P'.getSubMessage++instance P'.TextMsg Kq where+  textPut msg+   = do+       P'.tellT "m" (m msg)+       P'.tellT "q" (q msg)+       P'.tellT "xs" (xs msg)+  textGet+   = do+       mods <- P'.sepEndBy (P'.choice [parse'm, parse'q, parse'xs]) P'.spaces+       Prelude'.return (Prelude'.foldl (\ v f -> f v) P'.defaultValue mods)+    where+        parse'm+         = P'.try+            (do+               v <- P'.getT "m"+               Prelude'.return (\ o -> o{m = v}))+        parse'q+         = P'.try+            (do+               v <- P'.getT "q"+               Prelude'.return (\ o -> o{q = v}))+        parse'xs+         = P'.try+            (do+               v <- P'.getT "xs"+               Prelude'.return (\ o -> o{xs = P'.append (xs o) v}))
+ Crypto/Proto/RLWE/Rq.hs view
@@ -0,0 +1,95 @@+{-# LANGUAGE BangPatterns, DeriveDataTypeable, DeriveGeneric, FlexibleInstances, MultiParamTypeClasses #-}+{-# OPTIONS_GHC  -fno-warn-unused-imports #-}+module Crypto.Proto.RLWE.Rq (Rq(..)) where+import Prelude ((+), (/))+import qualified Prelude as Prelude'+import qualified Data.Typeable as Prelude'+import qualified GHC.Generics as Prelude'+import qualified Data.Data as Prelude'+import qualified Text.ProtocolBuffers.Header as P'++data Rq = Rq{m :: !(P'.Word32), q :: !(P'.Word64), xs :: !(P'.Seq P'.Int64)}+        deriving (Prelude'.Show, Prelude'.Eq, Prelude'.Ord, Prelude'.Typeable, Prelude'.Data, Prelude'.Generic)++instance P'.Mergeable Rq where+  mergeAppend (Rq x'1 x'2 x'3) (Rq y'1 y'2 y'3) = Rq (P'.mergeAppend x'1 y'1) (P'.mergeAppend x'2 y'2) (P'.mergeAppend x'3 y'3)++instance P'.Default Rq where+  defaultValue = Rq P'.defaultValue P'.defaultValue P'.defaultValue++instance P'.Wire Rq where+  wireSize ft' self'@(Rq x'1 x'2 x'3)+   = case ft' of+       10 -> calc'Size+       11 -> P'.prependMessageSize calc'Size+       _ -> P'.wireSizeErr ft' self'+    where+        calc'Size = (P'.wireSizeReq 1 13 x'1 + P'.wireSizeReq 1 4 x'2 + P'.wireSizeRep 1 18 x'3)+  wirePut ft' self'@(Rq x'1 x'2 x'3)+   = case ft' of+       10 -> put'Fields+       11 -> do+               P'.putSize (P'.wireSize 10 self')+               put'Fields+       _ -> P'.wirePutErr ft' self'+    where+        put'Fields+         = do+             P'.wirePutReq 8 13 x'1+             P'.wirePutReq 16 4 x'2+             P'.wirePutRep 24 18 x'3+  wireGet ft'+   = case ft' of+       10 -> P'.getBareMessageWith update'Self+       11 -> P'.getMessageWith update'Self+       _ -> P'.wireGetErr ft'+    where+        update'Self wire'Tag old'Self+         = case wire'Tag of+             8 -> Prelude'.fmap (\ !new'Field -> old'Self{m = new'Field}) (P'.wireGet 13)+             16 -> Prelude'.fmap (\ !new'Field -> old'Self{q = new'Field}) (P'.wireGet 4)+             24 -> Prelude'.fmap (\ !new'Field -> old'Self{xs = P'.append (xs old'Self) new'Field}) (P'.wireGet 18)+             26 -> Prelude'.fmap (\ !new'Field -> old'Self{xs = P'.mergeAppend (xs old'Self) new'Field}) (P'.wireGetPacked 18)+             _ -> let (field'Number, wire'Type) = P'.splitWireTag wire'Tag in P'.unknown field'Number wire'Type old'Self++instance P'.MessageAPI msg' (msg' -> Rq) Rq where+  getVal m' f' = f' m'++instance P'.GPB Rq++instance P'.ReflectDescriptor Rq where+  getMessageInfo _ = P'.GetMessageInfo (P'.fromDistinctAscList [8, 16]) (P'.fromDistinctAscList [8, 16, 24, 26])+  reflectDescriptorInfo _+   = Prelude'.read+      "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}"++instance P'.TextType Rq where+  tellT = P'.tellSubMessage+  getT = P'.getSubMessage++instance P'.TextMsg Rq where+  textPut msg+   = do+       P'.tellT "m" (m msg)+       P'.tellT "q" (q msg)+       P'.tellT "xs" (xs msg)+  textGet+   = do+       mods <- P'.sepEndBy (P'.choice [parse'm, parse'q, parse'xs]) P'.spaces+       Prelude'.return (Prelude'.foldl (\ v f -> f v) P'.defaultValue mods)+    where+        parse'm+         = P'.try+            (do+               v <- P'.getT "m"+               Prelude'.return (\ o -> o{m = v}))+        parse'q+         = P'.try+            (do+               v <- P'.getT "q"+               Prelude'.return (\ o -> o{q = v}))+        parse'xs+         = P'.try+            (do+               v <- P'.getT "xs"+               Prelude'.return (\ o -> o{xs = P'.append (xs o) v}))
+ Crypto/Proto/RLWE/SampleCont.hs view
@@ -0,0 +1,88 @@+{-# LANGUAGE BangPatterns, DeriveDataTypeable, DeriveGeneric, FlexibleInstances, MultiParamTypeClasses #-}+{-# OPTIONS_GHC  -fno-warn-unused-imports #-}+module Crypto.Proto.RLWE.SampleCont (SampleCont(..)) where+import Prelude ((+), (/))+import qualified Prelude as Prelude'+import qualified Data.Typeable as Prelude'+import qualified GHC.Generics as Prelude'+import qualified Data.Data as Prelude'+import qualified Text.ProtocolBuffers.Header as P'+import qualified Crypto.Proto.RLWE.Kq as RLWE (Kq)+import qualified Crypto.Proto.RLWE.Rq as RLWE (Rq)++data SampleCont = SampleCont{a :: !(RLWE.Rq), b :: !(RLWE.Kq)}+                deriving (Prelude'.Show, Prelude'.Eq, Prelude'.Ord, Prelude'.Typeable, Prelude'.Data, Prelude'.Generic)++instance P'.Mergeable SampleCont where+  mergeAppend (SampleCont x'1 x'2) (SampleCont y'1 y'2) = SampleCont (P'.mergeAppend x'1 y'1) (P'.mergeAppend x'2 y'2)++instance P'.Default SampleCont where+  defaultValue = SampleCont P'.defaultValue P'.defaultValue++instance P'.Wire SampleCont where+  wireSize ft' self'@(SampleCont x'1 x'2)+   = case ft' of+       10 -> calc'Size+       11 -> P'.prependMessageSize calc'Size+       _ -> P'.wireSizeErr ft' self'+    where+        calc'Size = (P'.wireSizeReq 1 11 x'1 + P'.wireSizeReq 1 11 x'2)+  wirePut ft' self'@(SampleCont x'1 x'2)+   = case ft' of+       10 -> put'Fields+       11 -> do+               P'.putSize (P'.wireSize 10 self')+               put'Fields+       _ -> P'.wirePutErr ft' self'+    where+        put'Fields+         = do+             P'.wirePutReq 10 11 x'1+             P'.wirePutReq 18 11 x'2+  wireGet ft'+   = case ft' of+       10 -> P'.getBareMessageWith update'Self+       11 -> P'.getMessageWith update'Self+       _ -> P'.wireGetErr ft'+    where+        update'Self wire'Tag old'Self+         = case wire'Tag of+             10 -> Prelude'.fmap (\ !new'Field -> old'Self{a = P'.mergeAppend (a old'Self) (new'Field)}) (P'.wireGet 11)+             18 -> Prelude'.fmap (\ !new'Field -> old'Self{b = P'.mergeAppend (b old'Self) (new'Field)}) (P'.wireGet 11)+             _ -> let (field'Number, wire'Type) = P'.splitWireTag wire'Tag in P'.unknown field'Number wire'Type old'Self++instance P'.MessageAPI msg' (msg' -> SampleCont) SampleCont where+  getVal m' f' = f' m'++instance P'.GPB SampleCont++instance P'.ReflectDescriptor SampleCont where+  getMessageInfo _ = P'.GetMessageInfo (P'.fromDistinctAscList [10, 18]) (P'.fromDistinctAscList [10, 18])+  reflectDescriptorInfo _+   = Prelude'.read+      "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}"++instance P'.TextType SampleCont where+  tellT = P'.tellSubMessage+  getT = P'.getSubMessage++instance P'.TextMsg SampleCont where+  textPut msg+   = do+       P'.tellT "a" (a msg)+       P'.tellT "b" (b msg)+  textGet+   = do+       mods <- P'.sepEndBy (P'.choice [parse'a, parse'b]) P'.spaces+       Prelude'.return (Prelude'.foldl (\ v f -> f v) P'.defaultValue mods)+    where+        parse'a+         = P'.try+            (do+               v <- P'.getT "a"+               Prelude'.return (\ o -> o{a = v}))+        parse'b+         = P'.try+            (do+               v <- P'.getT "b"+               Prelude'.return (\ o -> o{b = v}))
+ Crypto/Proto/RLWE/SampleDisc.hs view
@@ -0,0 +1,87 @@+{-# LANGUAGE BangPatterns, DeriveDataTypeable, DeriveGeneric, FlexibleInstances, MultiParamTypeClasses #-}+{-# OPTIONS_GHC  -fno-warn-unused-imports #-}+module Crypto.Proto.RLWE.SampleDisc (SampleDisc(..)) where+import Prelude ((+), (/))+import qualified Prelude as Prelude'+import qualified Data.Typeable as Prelude'+import qualified GHC.Generics as Prelude'+import qualified Data.Data as Prelude'+import qualified Text.ProtocolBuffers.Header as P'+import qualified Crypto.Proto.RLWE.Rq as RLWE (Rq)++data SampleDisc = SampleDisc{a :: !(RLWE.Rq), b :: !(RLWE.Rq)}+                deriving (Prelude'.Show, Prelude'.Eq, Prelude'.Ord, Prelude'.Typeable, Prelude'.Data, Prelude'.Generic)++instance P'.Mergeable SampleDisc where+  mergeAppend (SampleDisc x'1 x'2) (SampleDisc y'1 y'2) = SampleDisc (P'.mergeAppend x'1 y'1) (P'.mergeAppend x'2 y'2)++instance P'.Default SampleDisc where+  defaultValue = SampleDisc P'.defaultValue P'.defaultValue++instance P'.Wire SampleDisc where+  wireSize ft' self'@(SampleDisc x'1 x'2)+   = case ft' of+       10 -> calc'Size+       11 -> P'.prependMessageSize calc'Size+       _ -> P'.wireSizeErr ft' self'+    where+        calc'Size = (P'.wireSizeReq 1 11 x'1 + P'.wireSizeReq 1 11 x'2)+  wirePut ft' self'@(SampleDisc x'1 x'2)+   = case ft' of+       10 -> put'Fields+       11 -> do+               P'.putSize (P'.wireSize 10 self')+               put'Fields+       _ -> P'.wirePutErr ft' self'+    where+        put'Fields+         = do+             P'.wirePutReq 10 11 x'1+             P'.wirePutReq 18 11 x'2+  wireGet ft'+   = case ft' of+       10 -> P'.getBareMessageWith update'Self+       11 -> P'.getMessageWith update'Self+       _ -> P'.wireGetErr ft'+    where+        update'Self wire'Tag old'Self+         = case wire'Tag of+             10 -> Prelude'.fmap (\ !new'Field -> old'Self{a = P'.mergeAppend (a old'Self) (new'Field)}) (P'.wireGet 11)+             18 -> Prelude'.fmap (\ !new'Field -> old'Self{b = P'.mergeAppend (b old'Self) (new'Field)}) (P'.wireGet 11)+             _ -> let (field'Number, wire'Type) = P'.splitWireTag wire'Tag in P'.unknown field'Number wire'Type old'Self++instance P'.MessageAPI msg' (msg' -> SampleDisc) SampleDisc where+  getVal m' f' = f' m'++instance P'.GPB SampleDisc++instance P'.ReflectDescriptor SampleDisc where+  getMessageInfo _ = P'.GetMessageInfo (P'.fromDistinctAscList [10, 18]) (P'.fromDistinctAscList [10, 18])+  reflectDescriptorInfo _+   = Prelude'.read+      "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}"++instance P'.TextType SampleDisc where+  tellT = P'.tellSubMessage+  getT = P'.getSubMessage++instance P'.TextMsg SampleDisc where+  textPut msg+   = do+       P'.tellT "a" (a msg)+       P'.tellT "b" (b msg)+  textGet+   = do+       mods <- P'.sepEndBy (P'.choice [parse'a, parse'b]) P'.spaces+       Prelude'.return (Prelude'.foldl (\ v f -> f v) P'.defaultValue mods)+    where+        parse'a+         = P'.try+            (do+               v <- P'.getT "a"+               Prelude'.return (\ o -> o{a = v}))+        parse'b+         = P'.try+            (do+               v <- P'.getT "b"+               Prelude'.return (\ o -> o{b = v}))
+ Crypto/Proto/RLWE/SampleRLWR.hs view
@@ -0,0 +1,87 @@+{-# LANGUAGE BangPatterns, DeriveDataTypeable, DeriveGeneric, FlexibleInstances, MultiParamTypeClasses #-}+{-# OPTIONS_GHC  -fno-warn-unused-imports #-}+module Crypto.Proto.RLWE.SampleRLWR (SampleRLWR(..)) where+import Prelude ((+), (/))+import qualified Prelude as Prelude'+import qualified Data.Typeable as Prelude'+import qualified GHC.Generics as Prelude'+import qualified Data.Data as Prelude'+import qualified Text.ProtocolBuffers.Header as P'+import qualified Crypto.Proto.RLWE.Rq as RLWE (Rq)++data SampleRLWR = SampleRLWR{a :: !(RLWE.Rq), b :: !(RLWE.Rq)}+                deriving (Prelude'.Show, Prelude'.Eq, Prelude'.Ord, Prelude'.Typeable, Prelude'.Data, Prelude'.Generic)++instance P'.Mergeable SampleRLWR where+  mergeAppend (SampleRLWR x'1 x'2) (SampleRLWR y'1 y'2) = SampleRLWR (P'.mergeAppend x'1 y'1) (P'.mergeAppend x'2 y'2)++instance P'.Default SampleRLWR where+  defaultValue = SampleRLWR P'.defaultValue P'.defaultValue++instance P'.Wire SampleRLWR where+  wireSize ft' self'@(SampleRLWR x'1 x'2)+   = case ft' of+       10 -> calc'Size+       11 -> P'.prependMessageSize calc'Size+       _ -> P'.wireSizeErr ft' self'+    where+        calc'Size = (P'.wireSizeReq 1 11 x'1 + P'.wireSizeReq 1 11 x'2)+  wirePut ft' self'@(SampleRLWR x'1 x'2)+   = case ft' of+       10 -> put'Fields+       11 -> do+               P'.putSize (P'.wireSize 10 self')+               put'Fields+       _ -> P'.wirePutErr ft' self'+    where+        put'Fields+         = do+             P'.wirePutReq 10 11 x'1+             P'.wirePutReq 18 11 x'2+  wireGet ft'+   = case ft' of+       10 -> P'.getBareMessageWith update'Self+       11 -> P'.getMessageWith update'Self+       _ -> P'.wireGetErr ft'+    where+        update'Self wire'Tag old'Self+         = case wire'Tag of+             10 -> Prelude'.fmap (\ !new'Field -> old'Self{a = P'.mergeAppend (a old'Self) (new'Field)}) (P'.wireGet 11)+             18 -> Prelude'.fmap (\ !new'Field -> old'Self{b = P'.mergeAppend (b old'Self) (new'Field)}) (P'.wireGet 11)+             _ -> let (field'Number, wire'Type) = P'.splitWireTag wire'Tag in P'.unknown field'Number wire'Type old'Self++instance P'.MessageAPI msg' (msg' -> SampleRLWR) SampleRLWR where+  getVal m' f' = f' m'++instance P'.GPB SampleRLWR++instance P'.ReflectDescriptor SampleRLWR where+  getMessageInfo _ = P'.GetMessageInfo (P'.fromDistinctAscList [10, 18]) (P'.fromDistinctAscList [10, 18])+  reflectDescriptorInfo _+   = Prelude'.read+      "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}"++instance P'.TextType SampleRLWR where+  tellT = P'.tellSubMessage+  getT = P'.getSubMessage++instance P'.TextMsg SampleRLWR where+  textPut msg+   = do+       P'.tellT "a" (a msg)+       P'.tellT "b" (b msg)+  textGet+   = do+       mods <- P'.sepEndBy (P'.choice [parse'a, parse'b]) P'.spaces+       Prelude'.return (Prelude'.foldl (\ v f -> f v) P'.defaultValue mods)+    where+        parse'a+         = P'.try+            (do+               v <- P'.getT "a"+               Prelude'.return (\ o -> o{a = v}))+        parse'b+         = P'.try+            (do+               v <- P'.getT "b"+               Prelude'.return (\ o -> o{b = v}))
− Setup.hs
@@ -1,2 +0,0 @@-import Distribution.Simple-main = defaultMain
benchmarks/CycBenches.hs view
@@ -1,12 +1,12 @@-{-# LANGUAGE DataKinds, FlexibleContexts, -             NoImplicitPrelude, RebindableSyntax, -             ScopedTypeVariables, TypeFamilies, +{-# LANGUAGE DataKinds, FlexibleContexts,+             NoImplicitPrelude, RebindableSyntax,+             ScopedTypeVariables, TypeFamilies,              TypeOperators, UndecidableInstances #-}  module CycBenches (cycBenches) where +import Apply.Cyc import Benchmarks-import Harness.Cyc import Utils  import Control.Monad.Random@@ -16,27 +16,38 @@ import Crypto.Random.DRBG  import Data.Singletons-import Data.Promotion.Prelude.List import Data.Promotion.Prelude.Eq-import Data.Singletons.TypeRepStar+import Data.Singletons.TypeRepStar () -cycBenches :: (MonadRandom m) => m Benchmark+cycBenches :: IO Benchmark cycBenches = benchGroup "Cyc" [-  benchGroup "*"      $ applyBasic (Proxy::Proxy AllParams) $ hideArgs bench_mul,-  benchGroup "crt"    $ applyBasic (Proxy::Proxy AllParams) $ hideArgs bench_crt,-  benchGroup "crtInv" $ applyBasic (Proxy::Proxy AllParams) $ hideArgs bench_crtInv,-  benchGroup "l"      $ applyBasic (Proxy::Proxy AllParams) $ hideArgs bench_l,-  benchGroup "*g Pow" $ applyBasic (Proxy::Proxy AllParams) $ hideArgs bench_mulgPow,-  benchGroup "*g CRT" $ applyBasic (Proxy::Proxy AllParams) $ hideArgs bench_mulgCRT,-  benchGroup "lift"   $ applyLift  (Proxy::Proxy LiftParams) $ hideArgs bench_liftPow,-  benchGroup "error"  $ applyError (Proxy::Proxy ErrorParams) $ hideArgs $ bench_errRounded 0.1,-  benchGroup "twace"  $ applyTwoIdx (Proxy::Proxy TwoIdxParams) $ hideArgs bench_twacePow,-  benchGroup "embed"  $ applyTwoIdx (Proxy::Proxy TwoIdxParams) $ hideArgs bench_embedPow+  benchGroup "unzipCycPow" $ applyBasic  allParams    $ hideArgs bench_unzipCycPow,+  benchGroup "unzipCycCRT" $ applyBasic  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   ] +bench_unzipCycPow :: (BasicCtx t m r, BasicCtx t m (r,r)) => Cyc t m (r,r) -> Bench '(t,m,r)+bench_unzipCycPow a =+  let a' = advisePow a+  in bench unzipCyc a'++bench_unzipCycCRT :: (BasicCtx t m r, BasicCtx t m (r,r)) => Cyc t m (r,r) -> Bench '(t,m,r)+bench_unzipCycCRT a =+  let a' = adviseCRT a+  in bench unzipCyc a'+ -- no CRT conversion, just coefficient-wise multiplication bench_mul :: (BasicCtx t m r) => Cyc t m r -> Cyc t m r -> Bench '(t,m,r)-bench_mul a b = +bench_mul a b =   let a' = adviseCRT a       b' = adviseCRT b   in bench (a' *) b'@@ -66,50 +77,58 @@ bench_mulgCRT x = let y = adviseCRT x in bench mulG y  -- generate a rounded error term-bench_errRounded :: forall t m r gen . (ErrorCtx t m r gen) +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) (Cyc t m (LiftOf r))) gen -bench_twacePow :: forall t m m' r . (TwoIdxCtx t m m' r) +bench_twacePow :: forall t m m' r . (TwoIdxCtx t m m' r)   => Cyc t m' r -> Bench '(t,m,m',r)-bench_twacePow x = -  let y = advisePow x +bench_twacePow x =+  let y = advisePow 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) +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 +bench_embedPow x =+  let y = advisePow x   in bench (embed :: Cyc t m r -> Cyc t m' r) y  type Tensors = '[CT,RT]-type MM'RCombos = -  '[ '(F4, F128, Zq 257),-     '(F1, PToF Prime281, Zq 563),-     '(F12, F32 * F9, Zq 512),-     '(F12, F32 * F9, Zq 577),-     '(F12, F32 * F9, Zq (577 ** 1153)),-     '(F12, F32 * F9, Zq (577 ** 1153 ** 2017)),-     '(F12, F32 * F9, Zq (577 ** 1153 ** 2017 ** 2593)),-     '(F12, F32 * F9, Zq (577 ** 1153 ** 2017 ** 2593 ** 3169)),-     '(F12, F32 * F9, Zq (577 ** 1153 ** 2017 ** 2593 ** 3169 ** 3457)),-     '(F12, F32 * F9, Zq (577 ** 1153 ** 2017 ** 2593 ** 3169 ** 3457 ** 6337)),-     '(F12, F32 * F9, Zq (577 ** 1153 ** 2017 ** 2593 ** 3169 ** 3457 ** 6337 ** 7489)),-     '(F12, F32 * F9 * F25, Zq 14401)+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) <*> (Nub (Map RemoveM MM'RCombos))+allParams :: Proxy AllParams+allParams = Proxy+ type LiftParams = ( '(,) <$> Tensors) <*> (Nub (Filter Liftable (Map RemoveM MM'RCombos)))+liftParams :: Proxy LiftParams+liftParams = Proxy+ type TwoIdxParams = ( '(,) <$> Tensors) <*> MM'RCombos+twoIdxParams :: Proxy TwoIdxParams+twoIdxParams = Proxy  type ErrorParams = ( '(,) <$> '[HashDRBG]) <*> LiftParams+errorParams :: Proxy ErrorParams+errorParams = Proxy  data Liftable :: TyFun (Factored, *) Bool -> * type instance Apply Liftable '(m',r) = Int64 :== (LiftOf r)  data RemoveM :: TyFun (Factored, Factored, *) (Factored, *) -> * type instance Apply RemoveM '(m,m',r) = '(m',r)--
benchmarks/Main.hs view
@@ -1,12 +1,15 @@  import CycBenches+import TensorBenches+import UCycBenches import ZqBenches  import Criterion.Main-import Control.Monad  main :: IO ()-main = defaultMain =<< (sequence [+main = defaultMain =<< sequence [   zqBenches,+  tensorBenches,+  ucycBenches,   cycBenches-  ])+  ]
+ benchmarks/TensorBenches.hs view
@@ -0,0 +1,27 @@+{-# LANGUAGE DataKinds, FlexibleContexts,+             NoImplicitPrelude, RebindableSyntax,+             ScopedTypeVariables, TypeFamilies,+             TypeOperators, UndecidableInstances #-}++module TensorBenches (tensorBenches) where++import Apply.Cyc+import Benchmarks+import Utils++import Crypto.Lol+import Crypto.Lol.Cyclotomic.Tensor++tensorBenches :: IO Benchmark+tensorBenches = benchGroup "Tensor" [+  benchGroup "l" $ applyBasic (Proxy::Proxy QuickParams) $ hideArgs bench_l]++-- 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 = bench l++type QuickTest = '[ '(F128, Zq 257),+                    '(F32 * F9, Zq 577),+                    '(F32 * F9, Int64) ]+type Tensors = '[CT,RT]+type QuickParams = ( '(,) <$> Tensors) <*> QuickTest
+ benchmarks/UCycBenches.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE DataKinds, FlexibleContexts,+             NoImplicitPrelude, RebindableSyntax,+             ScopedTypeVariables, TypeFamilies,+             TypeOperators, UndecidableInstances #-}++module UCycBenches (ucycBenches) where++import Apply.Cyc+import Benchmarks+import Utils++import Crypto.Lol+import Crypto.Lol.Cyclotomic.UCyc++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+  ]++-- 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++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_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++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
benchmarks/ZqBenches.hs view
@@ -10,27 +10,27 @@ import Control.Monad.Random import qualified Data.Vector.Unboxed as U import qualified Data.Array.Repa as R-import GHC.TypeLits  import Utils-import Gen+import GenArgs import Benchmarks  type Arr = R.Array R.U R.DIM1 -zqBenches :: MonadRandom rnd => rnd Benchmark+zqBenches :: IO Benchmark zqBenches = benchGroup "ZqBasic" [   hideArgs bench_mul_unb (Proxy::Proxy (Zq 577)),-  hideArgs bench_mul_repa $ (Proxy::Proxy (Zq 577))+  hideArgs bench_mul_repa (Proxy::Proxy (Zq 577))   ]  bench_mul_repa :: (Ring zq, U.Unbox zq) => Arr zq -> Arr zq -> Bench zq-bench_mul_repa a b = bench (R.computeUnboxedS . R.zipWith (*) a) b+bench_mul_repa a = bench (R.computeUnboxedS . R.zipWith (*) a)  bench_mul_unb :: (Ring zq, U.Unbox zq) => U.Vector zq -> U.Vector zq -> Bench zq-bench_mul_unb a b = bench (U.zipWith (*) a) b+bench_mul_unb a = bench (U.zipWith (*) a) -vecLen = 100 :: Int+vecLen :: Int+vecLen = 100  instance (U.Unbox zq, Random zq, MonadRandom rnd) => Generatable rnd (Arr zq) where   genArg = R.fromListUnboxed (R.Z R.:. vecLen) <$> replicateM vecLen getRandom
lol.cabal view
@@ -1,11 +1,11 @@ name:                lol--- The package version.  See the Haskell package versioning policy (PVP) +-- The package version.  See the Haskell package versioning policy (PVP) -- for standards guiding when and how versions should be incremented. -- http://www.haskell.org/haskellwiki/Package_versioning_policy -- PVP summary:      +-+------- breaking API changes --                   | | +----- non-breaking API additions --                   | | | +--- code changes with no API change-version:             0.2.0.1+version:             0.3.0.0 synopsis:            A library for lattice cryptography. homepage:            https://github.com/cpeikert/Lol Bug-Reports:         https://github.com/cpeikert/Lol/issues@@ -19,22 +19,27 @@ build-type:          Simple extra-source-files:  README, CHANGES.md,                      benchmarks/CycBenches.hs,+                     benchmarks/TensorBenches.hs,+                     benchmarks/UCycBenches.hs,                      benchmarks/ZqBenches.hs,                      tests/CycTests.hs,-                     tests/ZqTests.hs,                      tests/TensorTests.hs,+                     tests/ZqTests.hs,                      utils/Apply.hs,+                     utils/Apply/Cyc.hs,+                     utils/Apply/Zq.hs,                      utils/Benchmarks.hs,-                     utils/Gen.hs,+                     utils/GenArgs.hs,+                     utils/GenArgs/Zq.hs,                      utils/Tests.hs,                      utils/TestTypes.hs,                      utils/Utils.hs,-                     utils/Harness/Cyc.hs,-                     Crypto/Lol/Cyclotomic/Tensor/CTensor/tensorTypes.h+                     Crypto/Lol/Cyclotomic/Tensor/CTensor/*.h,+                     Crypto/Lol/Cyclotomic/Tensor/CTensor/*.cpp cabal-version:       >= 1.10-description:         +description:     Λ ○ λ (Lol) is a general-purpose library for ring-based lattice cryptography.-    For a detailed description of interfaces and functionality, see +    For a detailed description of interfaces and functionality, see     <https://eprint.iacr.org/2015/1134 Λ ○ λ: A Functional Library for Lattice Cryptography>.     For example cryptographic applications, see <https://hackage.haskell.org/package/lol-apps lol-apps>. source-repository head@@ -43,74 +48,83 @@  -- For information on compiling C with cabal: http://blog.ezyang.com/2010/06/setting-up-cabal-the-ffi-and-c2hs/ -Flag useICC-  Description: Use ICC instead of GCC to compile C backend.-  Default:     False- Flag llvm   Description:  Compile via LLVM. This produces much better object code,                 but you need to have the LLVM compiler installed.-+  -- If you enable this and get errors like "Error: can't resolve `.rodata' {.rodata section}"+  -- then GHC doesn't like your version of LLVM!   Default:      False  Flag opt   Description: Turn on library optimizations   Default:     True-  Manual:      False  library-  Include-dirs: Crypto/Lol/Cyclotomic/Tensor/CTensor-  C-sources: Crypto/Lol/Cyclotomic/Tensor/CTensor/basic.c,-             Crypto/Lol/Cyclotomic/Tensor/CTensor/crt.c,-             Crypto/Lol/Cyclotomic/Tensor/CTensor/g.c,-             Crypto/Lol/Cyclotomic/Tensor/CTensor/generalfuncs.c,-             Crypto/Lol/Cyclotomic/Tensor/CTensor/l.c,-             Crypto/Lol/Cyclotomic/Tensor/CTensor/norm.c,-             Crypto/Lol/Cyclotomic/Tensor/CTensor/random.c-  Includes: Crypto/Lol/Cyclotomic/Tensor/CTensor/tensorTypes.h   default-language:   Haskell2010--  if flag(useICC)-    ghc-options: -pgml icc -optc-O3 -    cc-options: -std=gnu99 -Wall -DSTATS -DCINTRIN-  else-    ghc-options: -pgml gcc -fPIC -optc-O3 -    cc-options: -std=gnu99 -fPIC -Wall+  ghc-options: -fwarn-dodgy-imports+  cc-options: -std=c++11+  Include-dirs: Crypto/Lol/Cyclotomic/Tensor/CTensor+  -- Due to #12152, the file containing the definition of `Zq::q` must be linked first,+  -- otherwise dynamic linking (`cabal repl` or `stack ghci`) results in the error:+  -- "Loading temp shared object failed: /tmp/ghc54651_0/libghc_1.so: undefined symbol _ZN2Zq1qE"+  -- For `cabal repl`, we can simply reorder the list so that the file that should be linked+  -- first comes first in the list. However `stack ghci` always links alphabetically,+  -- so we really just have to define `Zq::q` in the first file alphabetically.+  C-sources: Crypto/Lol/Cyclotomic/Tensor/CTensor/common.cpp,+             Crypto/Lol/Cyclotomic/Tensor/CTensor/crt.cpp,+             Crypto/Lol/Cyclotomic/Tensor/CTensor/g.cpp,+             Crypto/Lol/Cyclotomic/Tensor/CTensor/l.cpp,+             Crypto/Lol/Cyclotomic/Tensor/CTensor/mul.cpp,+             Crypto/Lol/Cyclotomic/Tensor/CTensor/norm.cpp,+             Crypto/Lol/Cyclotomic/Tensor/CTensor/random.cpp,+             Crypto/Lol/Cyclotomic/Tensor/CTensor/zq.cpp    if flag(llvm)     ghc-options: -fllvm -optlo-O3    -- ghc optimizations   if flag(opt)-    ghc-options: -O3 -Odph -funbox-strict-fields -fwarn-dodgy-imports -rtsopts-    ghc-options: -fno-liberate-case -funfolding-use-threshold1000 -funfolding-keeness-factor1000+    ghc-options: -O3 -Odph -funbox-strict-fields -fno-liberate-case -funfolding-use-threshold1000 -funfolding-keeness-factor1000 -  exposed-modules: +  exposed-modules:     Crypto.Lol     Crypto.Lol.PosBin     Crypto.Lol.Factored     Crypto.Lol.Reflects     Crypto.Lol.CRTrans     Crypto.Lol.Gadget-    Crypto.Lol.LatticePrelude+    Crypto.Lol.Prelude      Crypto.Lol.Cyclotomic.Cyc     Crypto.Lol.Cyclotomic.UCyc     Crypto.Lol.Cyclotomic.RescaleCyc     Crypto.Lol.Cyclotomic.Linear +    Crypto.Lol.RLWE.Continuous+    Crypto.Lol.RLWE.Discrete+    Crypto.Lol.RLWE.RLWR+     Crypto.Lol.Cyclotomic.Tensor     Crypto.Lol.Cyclotomic.Tensor.CTensor     Crypto.Lol.Cyclotomic.Tensor.RepaTensor-    +     Crypto.Lol.Types.Random     Crypto.Lol.Types.FiniteField     Crypto.Lol.Types.IrreducibleChar2+    Crypto.Lol.Types.Proto+    Crypto.Lol.Types.RRq     Crypto.Lol.Types.ZPP     Crypto.Lol.Types.ZqBasic +    Crypto.Proto.RLWE+    Crypto.Proto.RLWE.Rq+    Crypto.Proto.RLWE.Kq+    Crypto.Proto.RLWE.SampleCont+    Crypto.Proto.RLWE.SampleDisc+    Crypto.Proto.RLWE.SampleRLWR+   other-modules:-        +     Crypto.Lol.FactoredDefs     Crypto.Lol.PosBinDefs     Crypto.Lol.GaussRandom@@ -118,6 +132,7 @@     Crypto.Lol.Types.Complex     Crypto.Lol.Types.Numeric     Crypto.Lol.Types.IZipVector+    Crypto.Lol.Cyclotomic.CRTSentinel     Crypto.Lol.Cyclotomic.Tensor.RepaTensor.CRT     Crypto.Lol.Cyclotomic.Tensor.RepaTensor.Extension     Crypto.Lol.Cyclotomic.Tensor.RepaTensor.Dec@@ -134,21 +149,24 @@     constraints,     containers >= 0.5.6.2 && < 0.6,     crypto-api,-    data-default >= 0.3.0 && < 0.6,+    data-default >= 0.3.0 && < 0.8,     deepseq >= 1.4.1.1 && <1.5,+    monadcryptorandom,     MonadRandom >= 0.2 && < 0.5,     mtl >= 2.2.1 && < 2.3,     numeric-prelude >= 0.4.2 && < 0.5,     QuickCheck >= 2.8 && < 2.9,+    protocol-buffers,+    protocol-buffers-descriptor,     random >= 1.1 && < 1.2,     reflection >= 1.5.1 && < 2.2,     repa==3.4.*,-    singletons >= 1.1.2.1 && < 2.1,+    singletons >= 1.1.2.1 && < 2.2,     storable-record >= 0.0.3 && < 0.1,-    th-desugar >= 1.5.4 && < 1.6,+    th-desugar >= 1.5.4 && < 1.7,     tagged-transformer >= 0.7 && < 0.9,     template-haskell  >=  2.2.0.0,-    transformers >= 0.4.2.0 && < 0.5,+    transformers >= 0.4.2.0 && < 0.6,     vector==0.11.*,     vector-th-unbox >= 0.2.1.0 && < 0.3 @@ -184,9 +202,10 @@   default-language:   Haskell2010   main-is:            Main.hs -  -- if flag(llvm)-  --   ghc-options: -fllvm -optlo-O3-  ghc-options: -threaded -rtsopts+  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 @@ -201,4 +220,4 @@     singletons,     transformers,     vector,-    repa                        +    repa
tests/CycTests.hs view
@@ -7,38 +7,39 @@ import Crypto.Lol import Crypto.Lol.Types.ZPP -import Test.Framework (buildTest)- import Utils-import Harness.Cyc+import Apply.Cyc import Tests +import qualified Test.Framework as TF++cycTests :: [TF.Test] cycTests = [-  testGroupM "coeffsPow" $ applyTwoIdx (Proxy::Proxy '[])      $ hideArgs prop_coeffsBasis,-  testGroupM "mulGPow" $ applyBasic (Proxy::Proxy AllParams)   $ hideArgs prop_mulgPow,-  testGroupM "mulGDec" $ applyBasic (Proxy::Proxy AllParams)   $ hideArgs prop_mulgDec,-  testGroupM "mulGCRT" $ applyBasic (Proxy::Proxy AllParams)   $ hideArgs prop_mulgCRT,-  testGroupM "crtSet"  $ applyBasis (Proxy::Proxy BasisParams) $ hideArgs prop_crtSet_pairs+  testGroupM "mulGPow"   $ applyBasic allParams    $ hideArgs prop_mulgPow,+  testGroupM "mulGDec"   $ applyBasic allParams    $ hideArgs prop_mulgDec,+  testGroupM "mulGCRT"   $ applyBasic allParams    $ hideArgs prop_mulgCRT,+  testGroupM "crtSet"    $ applyBasis basisParams  $ hideArgs prop_crtSet_pairs,+  testGroupM "coeffsPow" $ applyTwoIdx basisParams $ hideArgs prop_coeffsBasis   ] -prop_mulgPow :: (CElt t r, Fact m, Eq r) => Cyc t m r -> Test '(t,m,r)+prop_mulgPow :: (CElt t r, Fact m, Eq r, IntegralDomain r) => Cyc t m r -> Test '(t,m,r) prop_mulgPow x =   let y = advisePow x   in test $ y == (fromJust' "prop_mulgPow failed divisibility!" $ divG $ mulG y) -prop_mulgDec :: (CElt t r, Fact m, Eq r) => Cyc t m r -> Test '(t,m,r)-prop_mulgDec x = +prop_mulgDec :: (CElt t r, Fact m, Eq r, IntegralDomain r) => Cyc t m r -> Test '(t,m,r)+prop_mulgDec x =   let y = adviseDec x   in test $ y == (fromJust' "prop_mulgDec failed divisibility!" $ divG $ mulG y) -prop_mulgCRT :: (CElt t r, Fact m, Eq r) => Cyc t m r -> Test '(t,m,r)-prop_mulgCRT x = +prop_mulgCRT :: (CElt t r, Fact m, Eq r, IntegralDomain r) => Cyc t m r -> Test '(t,m,r)+prop_mulgCRT x =   let y = adviseCRT x   in test $ y == (fromJust' "prop_mulgCRT failed divisibility!" $ divG $ mulG y)  prop_coeffsBasis :: forall t m m' r . (m `Divides` m', CElt t r, Eq r)   => Cyc t m' r -> Test '(t,m,m',r)-prop_coeffsBasis x = +prop_coeffsBasis x =   let xs = map embed (coeffsCyc Pow x :: [Cyc t m r])       bs = proxy powBasis (Proxy::Proxy m)   in test $ (sum $ zipWith (*) xs bs) == x@@ -47,13 +48,13 @@ -- necessary (but not sufficient) condition prop_crtSet_pairs :: forall t m m' r . (m `Divides` m', ZPP r, Eq r, CElt t r, CElt t (ZpOf r))   => Test '(t,m,m',r)-prop_crtSet_pairs = +prop_crtSet_pairs =   let crtset = proxy crtSet (Proxy::Proxy m) :: [Cyc t m' r]       pairs = join (liftM2 (,)) crtset   in test $ and $ map (\(a,b) -> if a == b then a*b == a else a*b == zero) pairs  type Tensors = '[CT,RT]-type MRCombos = +type MRCombos =   '[ '(F7, Zq 29),      '(F7, Zq 32),      '(F12, Zq 2148249601),@@ -75,18 +76,9 @@   ]  type AllParams = ( '(,) <$> Tensors) <*> MRCombos-type BasisParams = ( '(,) <$> Tensors) <*> MM'RCombos---- for crtSet, take all pairwise products --- if elts are equal, id--- if not, zero---- also do a cardinality check+allParams :: Proxy AllParams+allParams = Proxy --- checks cardinality of the CRT set-{--prop_crtSet_card pm _-  let inferLen = length $ (proxy crtSetDec pm :: [t m' r])-      expectLen = -  in  --}+type BasisParams = ( '(,) <$> Tensors) <*> MM'RCombos+basisParams :: Proxy BasisParams+basisParams = Proxy
tests/Main.hs view
@@ -6,7 +6,7 @@ import Test.Framework  main :: IO ()-main = do+main =   flip defaultMainWithArgs ["--threads=1","--maximum-generated-tests=100"]     [ testGroup "Tensor Tests" tensorTests      ,testGroup "Cyc Tests" cycTests
tests/TensorTests.hs view
@@ -1,10 +1,10 @@-{-# LANGUAGE ConstraintKinds, FlexibleContexts, DataKinds, NoImplicitPrelude, +{-# LANGUAGE ConstraintKinds, FlexibleContexts, DataKinds, NoImplicitPrelude,              RebindableSyntax, ScopedTypeVariables, TypeFamilies, TypeOperators,              UndecidableInstances #-}  module TensorTests (tensorTests) where -import Harness.Cyc+import Apply.Cyc import Tests import Utils @@ -15,24 +15,24 @@ import Crypto.Lol.Cyclotomic.Tensor  import Control.Applicative-import Control.Monad.Random  import Data.Maybe  import Data.Singletons-import Data.Promotion.Prelude.List import Data.Promotion.Prelude.Eq-import Data.Singletons.TypeRepStar+import Data.Singletons.TypeRepStar () -tensorTests = -  [testGroupM "fmapT comparison" $ applyBasic (Proxy::Proxy TMRParams) $ hideArgs prop_fmapT,-   testGroupM "fmap comparison"  $ applyBasic (Proxy::Proxy TMRParams) $ hideArgs prop_fmap,+import qualified Test.Framework as TF++tensorTests :: [TF.Test]+tensorTests =+  [testGroupM "fmapT comparison" $ applyBasic tmrParams $ hideArgs prop_fmapT,+   testGroupM "fmap comparison"  $ applyBasic tmrParams $ hideArgs prop_fmap,    testGroup  "GInv.G == id"       gInvGTests,-   testGroupM "CRTInv.CRT == id" $ applyBasic (Proxy::Proxy TMRParams) $ hideArgs prop_crt_inv,-   testGroupM "LInv.L == id"     $ applyBasic (Proxy::Proxy TMRParams) $ hideArgs prop_l_inv,-   testGroupM "Scalar"           $ applyBasic (Proxy::Proxy TMRParams) $ hideArgs prop_scalar_crt,+   testGroupM "CRTInv.CRT == id" $ applyBasic tmrParams $ hideArgs prop_crt_inv,+   testGroupM "LInv.L == id"     $ applyBasic tmrParams $ hideArgs prop_l_inv,+   testGroupM "Scalar"           $ applyBasic tmrParams $ hideArgs prop_scalar_crt,    testGroup  "G commutes with L"  gCommuteTests,-   testGroupM "Extension Mult"   $ applyBasic (Proxy::Proxy ExtParams) $ hideArgs prop_mul_ext,    testGroupM "GSqNormDec"       $ applyLift (Proxy::Proxy NormParams) $ hideArgs prop_gsqnorm,    testGroup  "Tw.Em == id"        tremTests,    testGroup  "Em commutes with L" embedCommuteTests,@@ -47,35 +47,36 @@ prop_fmap x = test $ (fmap id x) == x \\ witness entailEqT x \\ witness entailIndexT x  -- divG . mulG == id in Pow basis-prop_ginv_pow :: (Tensor t, TElt t r, Fact m, Eq r, Ring r, ZeroTestable r, IntegralDomain r) +prop_ginv_pow :: (Tensor t, TElt t r, Fact m, Eq r, Ring r, ZeroTestable r, IntegralDomain r)   => t m r -> Test '(t,m,r)-prop_ginv_pow x = test $ (fromMaybe (error "could not divide by G in prop_ginv_pow") $ +prop_ginv_pow x = test $ (fromMaybe (error "could not divide by G in prop_ginv_pow") $   divGPow $ mulGPow x) == x \\ witness entailEqT x  -- divG . mulG == id in Dec basis-prop_ginv_dec :: (Tensor t, TElt t r, Fact m, Eq r, Ring r, ZeroTestable r, IntegralDomain r) +prop_ginv_dec :: (Tensor t, TElt t r, Fact m, Eq r, Ring r, ZeroTestable r, IntegralDomain r)   => t m r -> Test '(t,m,r)-prop_ginv_dec x = test $ (fromMaybe (error "could not divide by G in prop_ginv_dec") $ +prop_ginv_dec x = test $ (fromMaybe (error "could not divide by G in prop_ginv_dec") $   divGDec $ mulGDec x) == x \\ witness entailEqT x  -- divG . mulG == id in CRT basis-prop_ginv_crt :: (Tensor t, TElt t r, Fact m, Eq r, ZeroTestable r, IntegralDomain r, CRTrans r) +prop_ginv_crt :: (Tensor t, TElt t r, Fact m, Eq r, CRTrans Maybe r)   => t m r -> Test '(t,m,r) prop_ginv_crt x = test $ fromMaybe (error "no CRT in prop_ginv_crt") $ do   divGCRT' <- divGCRT   mulGCRT' <- mulGCRT   return $ (divGCRT' $ mulGCRT' x) == x \\ witness entailEqT x +gInvGTests :: [TF.Test] gInvGTests =  [-  testGroupM "Pow basis" $ applyBasic (Proxy::Proxy TMRParams) $ hideArgs prop_ginv_pow,-  testGroupM "Dec basis" $ applyBasic (Proxy::Proxy TMRParams) $ hideArgs prop_ginv_dec,-  testGroupM "CRT basis" $ applyBasic (Proxy::Proxy TMRParams) $ hideArgs prop_ginv_crt]+  testGroupM "Pow basis" $ applyBasic tmrParams $ hideArgs prop_ginv_pow,+  testGroupM "Dec basis" $ applyBasic tmrParams $ hideArgs prop_ginv_dec,+  testGroupM "CRT basis" $ applyBasic tmrParams $ hideArgs prop_ginv_crt]  -- mulGDec == lInv. mulGPow . l prop_g_dec :: (Tensor t, Ring r, Fact m, TElt t r, Eq r) => t m r -> Test '(t,m,r) prop_g_dec x = test $ (mulGDec x) == (lInv $ mulGPow $ l x) \\ witness entailEqT x -prop_g_crt :: (Tensor t, TElt t r, Fact m, Eq r, ZeroTestable r, IntegralDomain r, CRTrans r) +prop_g_crt :: (Tensor t, TElt t r, Fact m, Eq r, CRTrans Maybe r)   => t m r -> Test '(t,m,r) prop_g_crt x = test $ fromMaybe (error "no CRT in prop_g_crt") $ do   mulGCRT' <- mulGCRT@@ -83,12 +84,13 @@   crtInv' <- crtInv   return $ (mulGCRT' x) == (crt' $ mulGPow $ crtInv' x) \\ witness entailEqT x +gCommuteTests :: [TF.Test] gCommuteTests =  [-  testGroupM "Dec basis" $ applyBasic (Proxy::Proxy TMRParams) $ hideArgs prop_g_dec,-  testGroupM "CRT basis" $ applyBasic (Proxy::Proxy TMRParams) $ hideArgs prop_g_crt]+  testGroupM "Dec basis" $ applyBasic tmrParams $ hideArgs prop_g_dec,+  testGroupM "CRT basis" $ applyBasic tmrParams $ hideArgs prop_g_crt]  -- crtInv . crt == id-prop_crt_inv :: (Tensor t, TElt t r, Fact m, Eq r, ZeroTestable r, IntegralDomain r, CRTrans r) +prop_crt_inv :: (Tensor t, TElt t r, Fact m, Eq r, CRTrans Maybe r)   => t m r -> Test '(t,m,r) prop_crt_inv x = test $ fromMaybe (error "no CRT in prop_crt_inv") $ do   crt' <- crt@@ -100,7 +102,7 @@ prop_l_inv x = test $ (lInv $ l x) == x \\ witness entailEqT x  -- scalarCRT = crt . scalarPow-prop_scalar_crt :: forall t m r . (Tensor t, TElt t r, Fact m, Eq r, ZeroTestable r, IntegralDomain r, CRTrans r)+prop_scalar_crt :: forall t m r . (Tensor t, TElt t r, Fact m, Eq r, CRTrans Maybe r)                 => r -> Test '(t,m,r) prop_scalar_crt r = test $ fromMaybe (error "no CRT in prop_scalar_crt") $ do   scalarCRT' <- scalarCRT@@ -108,30 +110,16 @@   return $ (scalarCRT' r :: t m r) == (crt' $ scalarPow r)   \\ proxy entailEqT (Proxy::Proxy (t m r)) ----- tests that multiplication in the extension ring matches CRT multiplication-prop_mul_ext :: forall t m r . (Tensor t, Fact m, TElt t r, TElt t (CRTExt r), CRTrans r, CRTEmbed r, Ring r, Eq r)-  => t m r -> t m r -> Test '(t,m,r)-prop_mul_ext x y = test $-  let m = proxy valueFact (Proxy::Proxy m)-  in case (crtInfo m :: Maybe (CRTInfo r)) of-       Nothing -> error "mul have a CRT to call prop_mul_ext"-       Just _ -> (let z = zipWithT (*) x y-                      z' = fmapT fromExt $ zipWithT (*) (fmapT toExt x) (fmapT toExt y)-                  in z == z') \\ witness entailEqT x -                              \\ witness entailIndexT x--type NormCtx t m r = (TElt t r, TElt t (LiftOf r), -  Fact m, Lift' r, CRTrans r, Eq (LiftOf r),+type NormCtx t m r = (TElt t r, TElt t (LiftOf r),+  Fact m, Lift' r, CRTrans Maybe r, Eq (LiftOf r),   ZeroTestable r, Ring (LiftOf r), Ring r, IntegralDomain r)  type NormWrapCtx m r = (NormCtx CT m r, NormCtx RT m r)  -- tests that gSqNormDec of two "random-looking" vectors agrees for RT and CT -- t is a dummy param-prop_gsqnorm :: forall t m r . -  (NormWrapCtx m r, NormCtx t m r) +prop_gsqnorm :: forall t m r .+  (NormWrapCtx m r, NormCtx t m r)   => r -> Test '(t,m,r) prop_gsqnorm x = test $   let crtCT = fromJust crt@@ -142,15 +130,16 @@   in gSqNormDec ct == gSqNormDec rt  -type TMM'RCtx t m m' r = -  (Tensor t, m `Divides` m', TElt t r, Ring r, -   CRTrans r, Eq r, ZeroTestable r, IntegralDomain r)+type TMM'RCtx t m m' r =+  (Tensor t, m `Divides` m', TElt t r, Ring r,+   CRTrans Maybe r, Eq r, ZeroTestable r, IntegralDomain r)  -- groups related tests+tremTests :: [TF.Test] tremTests = [-  testGroupM "Pow basis" $ applyTwoIdx (Proxy::Proxy TrEmParams) $ hideArgs prop_trem_pow,-  testGroupM "Dec basis" $ applyTwoIdx (Proxy::Proxy TrEmParams) $ hideArgs prop_trem_dec,-  testGroupM "CRT basis" $ applyTwoIdx (Proxy::Proxy TrEmParams) $ hideArgs prop_trem_crt]+  testGroupM "Pow basis" $ applyTwoIdx tremParams $ hideArgs prop_trem_pow,+  testGroupM "Dec basis" $ applyTwoIdx tremParams $ hideArgs prop_trem_dec,+  testGroupM "CRT basis" $ applyTwoIdx tremParams $ hideArgs prop_trem_crt]  -- tests that twace . embed == id in the Pow basis prop_trem_pow :: forall t m m' r . (TMM'RCtx t m m' r)@@ -169,14 +158,14 @@   (x==) <$> (twaceCRT <*> (embedCRT <*> pure x :: Maybe (t m' r))) \\ witness entailEqT x  -+embedCommuteTests :: [TF.Test] embedCommuteTests = [-  testGroupM "Dec basis" $ applyTwoIdx (Proxy::Proxy TrEmParams) $ hideArgs prop_embed_dec,-  testGroupM "CRT basis" $ applyTwoIdx (Proxy::Proxy TrEmParams) $ hideArgs prop_embed_crt]+  testGroupM "Dec basis" $ applyTwoIdx tremParams $ hideArgs prop_embed_dec,+  testGroupM "CRT basis" $ applyTwoIdx tremParams $ hideArgs prop_embed_crt]  -- embedDec == lInv . embedPow . l prop_embed_dec :: forall t m m' r . (TMM'RCtx t m m' r) => t m r -> Test '(t,m,m',r)-prop_embed_dec x = test $ (embedDec x :: t m' r) == (lInv $ embedPow $ l x) +prop_embed_dec x = test $ (embedDec x :: t m' r) == (lInv $ embedPow $ l x)   \\ proxy entailEqT (Proxy::Proxy (t m' r))  -- embedCRT = crt . embedPow . crtInv@@ -185,12 +174,13 @@   crt' <- crt   crtInv' <- crtInv   embedCRT' <- embedCRT-  return $ (embedCRT' x :: t m' r) == (crt' $ embedPow $ crtInv' x) +  return $ (embedCRT' x :: t m' r) == (crt' $ embedPow $ crtInv' x)     \\ proxy entailEqT (Proxy::Proxy (t m' r)) +twaceCommuteTests :: [TF.Test] twaceCommuteTests = [-  testGroupM "Dec basis" $ applyTwoIdx (Proxy::Proxy TrEmParams) $ hideArgs prop_twace_dec,-  testGroupM "CRT basis" $ applyTwoIdx (Proxy::Proxy TrEmParams) $ hideArgs prop_twace_crt]+  testGroupM "Dec basis" $ applyTwoIdx tremParams $ hideArgs prop_twace_dec,+  testGroupM "CRT basis" $ applyTwoIdx tremParams $ hideArgs prop_twace_crt]  -- twacePowDec = lInv . twacePowDec . l prop_twace_dec :: forall t m m' r . (TMM'RCtx t m m' r) => t m' r -> Test '(t,m,m',r)@@ -206,26 +196,27 @@   return $ (twaceCRT' x :: t m r) == (crt' $ twacePowDec $ crtInv' x)     \\ proxy entailEqT (Proxy::Proxy (t m r)) +twaceInvarTests :: [TF.Test] twaceInvarTests = [-  testGroupM "Tw and Em ID for equal indices" $ applyBasic (Proxy::Proxy TMRParams) $ hideArgs prop_twEmID,-  testGroupM "Invar1 Pow basis" $ applyTwoIdx (Proxy::Proxy TrEmParams) $ hideArgs prop_twace_invar1_pow,-  testGroupM "Invar1 Dec basis" $ applyTwoIdx (Proxy::Proxy TrEmParams) $ hideArgs prop_twace_invar1_dec,-  testGroupM "Invar1 CRT basis" $ applyTwoIdx (Proxy::Proxy TrEmParams) $ hideArgs prop_twace_invar1_crt,-  testGroupM "Invar2 Pow/Dec basis" $ applyTwoIdx (Proxy::Proxy TrEmParams) $ hideArgs prop_twace_invar2_powdec,-  testGroupM "Invar2 CRT basis" $ applyTwoIdx (Proxy::Proxy TrEmParams) $ hideArgs prop_twace_invar2_crt+  testGroupM "Tw and Em ID for equal indices" $ applyBasic tmrParams $ hideArgs prop_twEmID,+  testGroupM "Invar1 Pow basis" $ applyTwoIdx tremParams $ hideArgs prop_twace_invar1_pow,+  testGroupM "Invar1 Dec basis" $ applyTwoIdx tremParams $ hideArgs prop_twace_invar1_dec,+  testGroupM "Invar1 CRT basis" $ applyTwoIdx tremParams $ hideArgs prop_twace_invar1_crt,+  testGroupM "Invar2 Pow/Dec basis" $ applyTwoIdx tremParams $ hideArgs prop_twace_invar2_powdec,+  testGroupM "Invar2 CRT basis" $ applyTwoIdx tremParams $ hideArgs prop_twace_invar2_crt   ] -prop_twEmID :: forall t m r . (Tensor t, TElt t r, CRTrans r, Fact m, m `Divides` m, Eq r, ZeroTestable r, IntegralDomain r) +prop_twEmID :: forall t m r . (Tensor t, TElt t r, CRTrans Maybe r, Fact m, m `Divides` m, Eq r, ZeroTestable r, IntegralDomain r)   => t m r -> Test '(t,m,r)-prop_twEmID x = test $ +prop_twEmID x = test $   ((twacePowDec x) == x) &&-   (((fromMaybe (error "twemid_crt") twaceCRT) x) == x) &&-   ((embedPow x) == x) &&-   ((embedDec x) == x) &&-   (((fromMaybe (error "twemid_crt") embedCRT) x) == x) \\ witness entailEqT x+  (((fromMaybe (error "twemid_crt") twaceCRT) x) == x) &&+  ((embedPow x) == x) &&+  ((embedDec x) == x) &&+  (((fromMaybe (error "twemid_crt") embedCRT) x) == x) \\ witness entailEqT x  -- twace mhat'/g' = mhat*totm'/totm/g (Pow basis)-prop_twace_invar1_pow :: forall t m m' r . (TMM'RCtx t m m' r) +prop_twace_invar1_pow :: forall t m m' r . (TMM'RCtx t m m' r)   => Test '(t,m,m',r) prop_twace_invar1_pow = test $ fromMaybe (error "could not divide by G in prop_twace_invar1_pow") $ do   let mhat = proxy valueHatFact (Proxy::Proxy m)@@ -279,10 +270,6 @@       output = scalarCRT2 one :: t m r   return $ (twacePowDec input) == output \\ proxy entailEqT (Proxy::Proxy (t m r)) ---- type Tensors = '[CT,RT] type MRCombos = '[   '(F7, Zq 29),@@ -305,7 +292,7 @@  -- we can't include a large modulus here because there is not enough -- precision in Doubles to handle the error-type MRExtCombos = '[+{-type MRExtCombos = '[   '(F7, Zq 29),   '(F1, Zq 17),   '(F2, Zq 17),@@ -316,7 +303,7 @@   '(F42, ZQ1),   '(F42, ZQ2),   '(F89, Zq 179)-  ]+  ]-}  type MM'RCombos = '[   '(F1, F7, Zq 29),@@ -335,8 +322,14 @@   ]  type TMRParams = ( '(,) <$> Tensors) <*> MRCombos-type ExtParams = ( '(,) <$> Tensors) <*> MRExtCombos+tmrParams :: Proxy TMRParams+tmrParams = Proxy++--type ExtParams = ( '(,) <$> Tensors) <*> MRExtCombos type TrEmParams = ( '(,) <$> Tensors) <*> MM'RCombos+tremParams :: Proxy TrEmParams+tremParams = Proxy+ type NormParams = ( '(,) <$> '[RT]) <*> (Filter Liftable MRCombos)  data Liftable :: TyFun (Factored, *) Bool -> *
tests/ZqTests.hs view
@@ -1,56 +1,47 @@-{-# LANGUAGE NoImplicitPrelude, RebindableSyntax, ScopedTypeVariables, DataKinds, TypeOperators, PolyKinds, FlexibleContexts, RankNTypes, KindSignatures, MultiParamTypeClasses #-}+{-# LANGUAGE DataKinds, FlexibleContexts, NoImplicitPrelude,+             ScopedTypeVariables, TypeOperators #-}  module ZqTests (zqTests) where -import Crypto.Lol.Types.ZqBasic-import Crypto.Lol.LatticePrelude hiding (Nat)-import Crypto.Lol.Reflects--import Control.Monad--import GHC.TypeLits--import Test.Framework-import Test.Framework.Providers.QuickCheck2-import Test.QuickCheck---prop_add :: forall (q :: Nat) . (Reflects q Int, KnownNat q) => Proxy q -> Int -> Int -> Bool-prop_add _ x y = (fromIntegral $ x + y) == ((fromIntegral x) + (fromIntegral y :: ZqBasic q Int))+import Apply.Zq+import Tests+import Utils -prop_mul :: forall (q :: Nat) . (Reflects q Int, KnownNat q) => Proxy q -> Int -> Int -> Bool-prop_mul _ x y = (fromIntegral $ x * y) == ((fromIntegral x) * (fromIntegral y :: ZqBasic q Int))+import Crypto.Lol+import Crypto.Lol.CRTrans -prop_recip :: forall (q :: Nat) . (Reflects q Int, KnownNat q) => Proxy q -> Int -> Bool-prop_recip _ x = let qval = proxy value (Proxy::Proxy q)-                     y = fromIntegral x :: ZqBasic q Int-                 in if (x `mod` qval) == 0-                    then True-                    else (fromIntegral (1::Int)) == (y * (recip y))+import qualified Test.Framework as TF -type ZqModuli = '[7, 13, 17, 11, 13, 29]+zqTests :: [TF.Test]+zqTests = [+  testGroupM "(+)" $ applyBasic zqTypes $ hideArgs prop_add,+  testGroupM "(*)" $ applyBasic zqTypes $ hideArgs prop_mul,+  testGroupM "^-1" $ applyBasic zqTypes $ hideArgs prop_recip,+  testGroupM "extension ring (*)" $ applyBasic zqTypes $ hideArgs prop_mul_ext+  ] -class CallZqProp xs where-  callProp :: Proxy xs -> Gen Int -> (forall (q :: Nat) . (Reflects q Int, KnownNat q) => Proxy q -> Int -> Int -> Bool) -> [Test]+prop_add :: forall r . (Ring r, Eq r) => LiftedMod r -> LiftedMod r -> Test r+prop_add (LMod x) (LMod y) = test $ fromIntegral (x + y) == (fromIntegral x + fromIntegral y :: r) -  callProp2 :: Proxy xs -                -> Gen Int -                -> (forall (q :: Nat) . (Reflects q Int, KnownNat q) => Proxy q -> Int -> Bool)-                -> [Test]+prop_mul :: forall r . (Ring r, Eq r) => LiftedInvertible r -> LiftedInvertible r -> Test r+prop_mul (LInv x) (LInv y) = test $ fromIntegral (x * y) == (fromIntegral x * fromIntegral y :: r) -instance CallZqProp '[] where-  callProp _ _ _ = []-  callProp2 _ _ _ = []+prop_recip :: forall r . (Field r, Eq r) => Invertible r -> Test r+prop_recip (Invertible x) = test $ one == (x * recip x) -instance (CallZqProp qs, KnownNat q) => CallZqProp (q ': qs) where-  callProp _ gen f = (testProperty ("q = " ++ (show $ (proxy value (Proxy::Proxy q) :: Int))) $ property $ liftM2 (f (Proxy::Proxy q)) gen gen) : (callProp (Proxy::Proxy qs) gen f)-  callProp2 _ gen f = (testProperty ("q = " ++ (show $ (proxy value (Proxy::Proxy q) :: Int))) $ property $ liftM (f (Proxy::Proxy q)) gen) : (callProp2 (Proxy::Proxy qs) gen f)+-- tests that multiplication in the extension ring matches CRT multiplication+prop_mul_ext :: forall r . (CRTEmbed r, Ring r, Eq r)+  => Invertible r -> Invertible r -> Test r+prop_mul_ext (Invertible x) (Invertible y) = test $+  let z = x * y+      z' = fromExt $ toExt x * toExt y+  in z == z' -zqModuli :: Proxy ZqModuli-zqModuli = Proxy+type ZqTypes = [+  Zq 3,+  Zq 7,+  Zq (3 ** 5),+  Zq (3 ** 5 ** 7)] -zqTests :: [Test]-zqTests = -  [testGroup "ZqBasic +" $ callProp zqModuli (choose (-100,100)) prop_add,-   testGroup "ZqBasic *" $ callProp zqModuli (choose (-100,100)) prop_mul,-   testGroup "ZqBasic recip" $ callProp2 zqModuli (choose (-100,100)) prop_recip]+zqTypes :: Proxy ZqTypes+zqTypes = Proxy
utils/Apply.hs view
@@ -1,17 +1,17 @@-{-# LANGUAGE DataKinds, FlexibleInstances, MultiParamTypeClasses, PolyKinds, +{-# LANGUAGE DataKinds, FlexibleInstances, MultiParamTypeClasses, PolyKinds,              TypeFamilies, TypeOperators #-}  -- applies functions to proxy arguments module Apply where -class (params :: [k]) `Satisfy` (ctx :: *)  where-  data ArgsCtx ctx+-- not associated due to the generic instance below:+-- any definition of ArgsCtx would conflict with specific instances+data family ArgsCtx ctx +class (params :: [k]) `Satisfy` (ctx :: *)  where   run :: proxy params-            -> (ArgsCtx ctx -> rnd res) +            -> (ArgsCtx ctx -> rnd res)             -> [rnd res]  instance '[] `Satisfy` ctx  where-  -- any implementation of ArgsCtx would conflict with concrete instances,-  -- so skip     run _ _ = []
+ utils/Apply/Cyc.hs view
@@ -0,0 +1,109 @@+{-# LANGUAGE ConstraintKinds       #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE GADTs                 #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoImplicitPrelude     #-}+{-# LANGUAGE PolyKinds             #-}+{-# LANGUAGE RankNTypes            #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE TypeOperators         #-}+{-# LANGUAGE UndecidableInstances  #-}++module Apply.Cyc where++import Control.DeepSeq+import Control.Monad.Random++import Crypto.Lol+import Crypto.Lol.Cyclotomic.Tensor+import Crypto.Lol.Types.ZPP+import Crypto.Random.DRBG++import Apply+import GenArgs+import Utils++data BasicCtxD+type BasicCtx t m r =+  (CElt t r, Fact m, IntegralDomain r, Random r, Eq r, NFElt r, ShowType '(t,m,r), Random (t m r), m `Divides` m, NFData (t m r))+data instance ArgsCtx BasicCtxD where+    BC :: (BasicCtx t m r, BasicCtx t m (r,r)) => Proxy '(t,m,r) -> ArgsCtx BasicCtxD+instance (params `Satisfy` BasicCtxD, BasicCtx t m r, BasicCtx t m (r,r))+  => ( '(t, '(m,r)) ': params) `Satisfy` BasicCtxD where+  run _ f = f (BC (Proxy::Proxy '(t,m,r))) : run (Proxy::Proxy params) f++applyBasic :: (params `Satisfy` BasicCtxD, MonadRandom rnd) =>+  Proxy params+  -> (forall t m r . (BasicCtx t m r, BasicCtx t m (r,r), Generatable rnd r, Generatable rnd (t m r))+       => Proxy '(t,m,r) -> rnd res)+  -> [rnd res]+applyBasic params g = run params $ \(BC p) -> g p++-- r is Liftable+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))+data instance ArgsCtx LiftCtxD where+    LC :: (LiftCtx t m r) => Proxy '(t,m,r) -> ArgsCtx LiftCtxD+instance (params `Satisfy` LiftCtxD, LiftCtx t m r)+  => ( '(t, '(m,r)) ': params) `Satisfy` LiftCtxD  where+  run _ f = f (LC (Proxy::Proxy '(t,m,r))) : run (Proxy::Proxy params) f++applyLift :: (params `Satisfy` LiftCtxD, MonadRandom rnd) =>+  Proxy params+  -> (forall t m r . (LiftCtx t m r, Generatable rnd r) => Proxy '(t,m,r) -> rnd res)+  -> [rnd res]+applyLift params g = run params $ \(LC p) -> g p++-- similar to LiftCtxD, but with a `gen` param+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)+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)+  => ( '(gen, '(t, '(m,r))) ': params) `Satisfy` ErrorCtxD  where+  run _ f = f (EC (Proxy::Proxy '(t,m,r,gen))) : run (Proxy::Proxy params) f++applyError :: (params `Satisfy` ErrorCtxD, Monad rnd) =>+  Proxy params+  -> (forall t m r gen . (ErrorCtx t m r gen) => Proxy '(t,m,r,gen) -> rnd res)+  -> [rnd res]+applyError params g = run params $ \(EC p) -> g p+++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))+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)+  => ( '(t, '(m,m',r)) ': params) `Satisfy` TwoIdxCtxD where+  run _ f = f (TI (Proxy::Proxy '(t,m,m',r))) : run (Proxy::Proxy params) f++applyTwoIdx :: (params `Satisfy` TwoIdxCtxD, MonadRandom rnd) =>+  Proxy params+  -> (forall t m m' r . (TwoIdxCtx t m m' r, Generatable rnd (t m r), Generatable rnd (t m' r))+        => Proxy '(t,m,m',r) -> rnd res)+  -> [rnd res]+applyTwoIdx params g = run params $ \(TI p) -> g p++-- similar to TwoIdxCtxD, but r must be a prime-power+data BasisCtxD+type BasisCtx t m m' r = (m `Divides` m', Eq r, ZPP r, CElt t r, CElt t (ZpOf r), ShowType '(t,m,m',r))+data instance ArgsCtx BasisCtxD where+    BsC :: (BasisCtx t m m' r) => Proxy '(t,m,m',r) -> ArgsCtx BasisCtxD+instance (params `Satisfy` BasisCtxD, BasisCtx t m m' r)+  => ( '(t, '(m,m',r)) ': params) `Satisfy` BasisCtxD where+  run _ f = f (BsC (Proxy::Proxy '(t,m,m',r))) : run (Proxy::Proxy params) f++applyBasis :: (params `Satisfy` BasisCtxD) =>+  Proxy params+  -> (forall t m m' r . (BasisCtx t m m' r) => Proxy '(t,m,m',r) -> rnd res)+  -> [rnd res]+applyBasis params g = run params $ \(BsC p) -> g p
+ utils/Apply/Zq.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE ConstraintKinds, DataKinds, FlexibleContexts, FlexibleInstances,+             GADTs, MultiParamTypeClasses, NoImplicitPrelude, RankNTypes,+             RebindableSyntax, ScopedTypeVariables, TypeFamilies, TypeOperators,+             UndecidableInstances #-}++module Apply.Zq+(applyBasic+,LiftedMod(..)+,LiftedInvertible(..)+,Invertible(..)) where++import Apply+import GenArgs+import GenArgs.Zq+import Utils++import Control.Monad.Random++import Crypto.Lol+import Crypto.Lol.CRTrans++data BasicCtxD+type BasicCtx r =+  (Field r, Eq r, Random r, Random (ModRep r), ToInteger (ModRep r),+   PID (ModRep r), ShowType r, CRTEmbed r, Mod r)+data instance ArgsCtx BasicCtxD where+    BC :: (BasicCtx r) => Proxy r -> ArgsCtx BasicCtxD+instance (params `Satisfy` BasicCtxD, BasicCtx r)+  => ( r ': params) `Satisfy` BasicCtxD where+  run _ f = f (BC (Proxy::Proxy r)) : run (Proxy::Proxy params) f++applyBasic :: (params `Satisfy` BasicCtxD, MonadRandom rnd) =>+  Proxy params+  -> (forall r . (BasicCtx r, Generatable rnd r, Generatable rnd (Invertible r))+       => Proxy r -> rnd res)+  -> [rnd res]+applyBasic params g = run params $ \(BC p) -> g p
utils/Benchmarks.hs view
@@ -1,7 +1,7 @@-{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, +{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses,              PolyKinds, RankNTypes, ScopedTypeVariables, TypeFamilies #-} -module Benchmarks +module Benchmarks (Benchmarks.bench ,benchIO ,benchGroup@@ -10,12 +10,10 @@ ,Benchmark ,NFData) where -import Gen+import GenArgs import Utils  import Control.DeepSeq-import Control.Monad.Random-import Control.Monad.State import Criterion as C  import Data.Proxy@@ -28,11 +26,11 @@ benchIO :: NFData b => IO b -> Bench params benchIO = Bench . nfIO --- wrapper for Criterion's +-- wrapper for Criterion's benchGroup :: (Monad rnd) => String -> [rnd Benchmark] -> rnd Benchmark benchGroup str = (bgroup str <$>) . sequence --- normalizes any function resulting in a Benchmark to +-- normalizes any function resulting in a Benchmark to -- one that takes a proxy for its arguments hideArgs :: (GenArgs rnd bnch, Monad rnd, ShowType a,              ResultOf bnch ~ Bench a)
− utils/Gen.hs
@@ -1,27 +0,0 @@-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, TypeFamilies #-}---- generates arguments to functions-module Gen where--import Control.Monad.Random---- bnch represents a function whose arguments can be generated,--- resulting in a "NFValue"-class GenArgs rnd bnch where-  type ResultOf bnch-  genArgs :: bnch -> rnd (ResultOf bnch)--instance (Generatable rnd a, GenArgs rnd b, -          Monad rnd, ResultOf b ~ ResultOf (a -> b)) -  => GenArgs rnd (a -> b) where-  type ResultOf (a -> b) = ResultOf b-  genArgs f = do-    x <- genArg-    genArgs $ f x---- a parameter that can be generated using a particular monad-class Generatable rnd arg where-  genArg :: rnd arg--instance {-# Overlappable #-} (Random a, MonadRandom rnd) => Generatable rnd a where-  genArg = getRandom
+ utils/GenArgs.hs view
@@ -0,0 +1,31 @@+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, TypeFamilies #-}++-- generates arguments to functions+module GenArgs where++import Control.Monad.Random+import Data.Proxy++-- bnch represents a function whose arguments can be generated,+-- resulting in a "NFValue"+class GenArgs rnd bnch where+  type ResultOf bnch+  genArgs :: bnch -> rnd (ResultOf bnch)++instance (Generatable rnd a, GenArgs rnd b,+          Monad rnd, ResultOf b ~ ResultOf (a -> b))+  => GenArgs rnd (a -> b) where+  type ResultOf (a -> b) = ResultOf b+  genArgs f = do+    x <- genArg+    genArgs $ f x++-- a parameter that can be generated using a particular monad+class Generatable rnd arg where+  genArg :: rnd arg++instance {-# Overlappable #-} (Random a, MonadRandom rnd) => Generatable rnd a where+  genArg = getRandom++instance (Monad rnd) => Generatable rnd (Proxy a) where+  genArg = return Proxy
+ utils/GenArgs/Zq.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE FlexibleContexts, FlexibleInstances, GADTs, MultiParamTypeClasses,+             NoImplicitPrelude, RebindableSyntax, ScopedTypeVariables,+             UndecidableInstances #-}++module GenArgs.Zq where++import GenArgs++import Control.Applicative+import Control.Monad.Random++import Crypto.Lol++data LiftedMod r where+  LMod :: (ToInteger (ModRep r)) => ModRep r -> LiftedMod r++data LiftedInvertible r where+  LInv :: (ToInteger (ModRep r)) => ModRep r -> LiftedInvertible r++newtype Invertible r = Invertible r++instance (MonadRandom rnd, Mod r, Random (ModRep r), ToInteger (ModRep r))+  => Generatable rnd (LiftedMod r) where+  genArg =+    let q = proxy modulus (Proxy::Proxy r)+    in LMod <$> getRandomR (0,q-1)++instance (MonadRandom rnd, Mod r, Random (ModRep r), PID (ModRep r), ToInteger (ModRep r))+  => Generatable rnd (LiftedInvertible r) where+  genArg =+    let q = proxy modulus (Proxy::Proxy r)+        go = do+          x <- getRandomR (1,q-1)+          if gcd x q == 1+          then return $ LInv x+          else go+    in go++instance (MonadRandom rnd, Generatable rnd (LiftedInvertible r), Ring r)+  => Generatable rnd (Invertible r) where+  genArg = do+    (LInv x) :: LiftedInvertible r <- genArg+    return $ Invertible $ fromIntegral x
− utils/Harness/Cyc.hs
@@ -1,102 +0,0 @@-{-# LANGUAGE ConstraintKinds, DataKinds, FlexibleContexts, FlexibleInstances, -             GADTs, MultiParamTypeClasses, NoImplicitPrelude, PolyKinds, RankNTypes, -             ScopedTypeVariables, TypeFamilies, TypeOperators, UndecidableInstances #-}--module Harness.Cyc where--import Control.Applicative-import Control.Monad.Random--import Crypto.Lol-import Crypto.Lol.Cyclotomic.Tensor-import Crypto.Lol.Types.ZPP-import Crypto.Random.DRBG--import Data.Vector.Storable--import Utils-import Gen-import Apply--data BasicCtxD-type BasicCtx t m r = -  (CElt t r, Fact m, Random r, Eq r, NFElt r, ShowType '(t,m,r), Random (t m r), m `Divides` m)-instance (params `Satisfy` BasicCtxD, BasicCtx t m r) -  => ( '(t, '(m,r)) ': params) `Satisfy` BasicCtxD where-  data ArgsCtx BasicCtxD where-    BC :: (BasicCtx t m r) => Proxy '(t,m,r) -> ArgsCtx BasicCtxD-  run _ f = (f $ BC (Proxy::Proxy '(t,m,r))) : (run (Proxy::Proxy params) f)--applyBasic :: (params `Satisfy` BasicCtxD, MonadRandom rnd) =>-  Proxy params -  -> (forall t m r . (BasicCtx t m r, Generatable rnd r, Generatable rnd (t m r)) -       => Proxy '(t,m,r) -> rnd res)-  -> [rnd res]-applyBasic params g = run params $ \(BC p) -> g p---- r is Liftable-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))-instance (params `Satisfy` LiftCtxD, LiftCtx t m r) -  => ( '(t, '(m,r)) ': params) `Satisfy` LiftCtxD  where-  data ArgsCtx LiftCtxD where-    LC :: (LiftCtx t m r) => Proxy '(t,m,r) -> ArgsCtx LiftCtxD-  run _ f = (f $ LC (Proxy::Proxy '(t,m,r))) : (run (Proxy::Proxy params) f)--applyLift :: (params `Satisfy` LiftCtxD, MonadRandom rnd) =>-  Proxy params -  -> (forall t m r . (LiftCtx t m r, Generatable rnd r) => Proxy '(t,m,r) -> rnd res) -  -> [rnd res]-applyLift params g = run params $ \(LC p) -> g p---- similar to LiftCtxD, but with a `gen` param-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)-instance (params `Satisfy` ErrorCtxD, ErrorCtx t m r gen) -  => ( '(gen, '(t, '(m,r))) ': params) `Satisfy` ErrorCtxD  where-  data ArgsCtx ErrorCtxD where-    EC :: (ErrorCtx t m r gen) => Proxy '(t,m,r,gen) -> ArgsCtx ErrorCtxD-  run _ f = (f $ EC (Proxy::Proxy '(t,m,r,gen))) : (run (Proxy::Proxy params) f)--applyError :: (params `Satisfy` ErrorCtxD, Monad rnd) =>-  Proxy params -  -> (forall t m r gen . (ErrorCtx t m r gen) => Proxy '(t,m,r,gen) -> rnd res) -  -> [rnd res]-applyError params g = run params $ \(EC p) -> g p---data TwoIdxCtxD-type TwoIdxCtx t m m' r = (m `Divides` m', CElt t r, Eq r, Random r, NFElt r, ShowType '(t,m,m',r), Random (t m r), Random (t m' r))--instance (params `Satisfy` TwoIdxCtxD, TwoIdxCtx t m m' r) -  => ( '(t, '(m,m',r)) ': params) `Satisfy` TwoIdxCtxD where-  data ArgsCtx TwoIdxCtxD where-    TI :: (TwoIdxCtx t m m' r) => Proxy '(t,m,m',r) -> ArgsCtx TwoIdxCtxD-  run _ f = (f $ TI (Proxy::Proxy '(t,m,m',r))) : (run (Proxy::Proxy params) f)--applyTwoIdx :: (params `Satisfy` TwoIdxCtxD, MonadRandom rnd) =>-  Proxy params -  -> (forall t m m' r . (TwoIdxCtx t m m' r, Generatable rnd (t m r), Generatable rnd (t m' r)) -        => Proxy '(t,m,m',r) -> rnd res) -  -> [rnd res]-applyTwoIdx params g = run params $ \(TI p) -> g p---- similar to TwoIdxCtxD, but r must be a prime-power-data BasisCtxD-type BasisCtx t m m' r = (m `Divides` m', Eq r, ZPP r, CElt t r, CElt t (ZpOf r), ShowType '(t,m,m',r))--instance (params `Satisfy` BasisCtxD, BasisCtx t m m' r)-  => ( '(t, '(m,m',r)) ': params) `Satisfy` BasisCtxD where-  data ArgsCtx BasisCtxD where-    BsC :: (BasisCtx t m m' r) => Proxy '(t,m,m',r) -> ArgsCtx BasisCtxD-  run _ f = (f $ BsC (Proxy::Proxy '(t,m,m',r))) : (run (Proxy::Proxy params) f)--applyBasis :: (params `Satisfy` BasisCtxD) =>-  Proxy params-  -> (forall t m m' r . (BasisCtx t m m' r) => Proxy '(t,m,m',r) -> rnd res)-  -> [rnd res]-applyBasis params g = run params $ \(BsC p) -> g p
utils/TestTypes.hs view
@@ -1,18 +1,17 @@ {-# LANGUAGE ConstraintKinds, DataKinds, FlexibleContexts,-             FlexibleInstances, KindSignatures, MultiParamTypeClasses,+             FlexibleInstances, MultiParamTypeClasses,              NoImplicitPrelude, PolyKinds, RankNTypes, RebindableSyntax,              ScopedTypeVariables, TypeFamilies, TypeOperators #-} -module TestTypes (--SmoothZQ1, SmoothZQ2, SmoothZQ3-, Zq, ZQ1, ZQ2, ZQ3) where+module TestTypes+(SmoothQ1, SmoothQ2, SmoothQ3+,SmoothZQ1, SmoothZQ2, SmoothZQ3+,Zq+,ZQ1,ZQ2,ZQ3) where -import Control.Monad import Control.Monad.Random  import Crypto.Lol-import Crypto.Lol.Reflects  import Utils 
utils/Tests.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE FlexibleContexts, FlexibleInstances, GADTs, MultiParamTypeClasses, +{-# LANGUAGE FlexibleContexts, FlexibleInstances, GADTs, MultiParamTypeClasses,              PolyKinds, RankNTypes, ScopedTypeVariables, TypeFamilies #-} module Tests (test@@ -8,17 +8,15 @@ ,hideArgs ,Test(..)) where -import Gen+import GenArgs import Utils  import Control.Monad.Random-import Control.Monad.State  import Data.Proxy  import qualified Test.Framework as TF import Test.Framework.Providers.QuickCheck2-import Test.QuickCheck  test :: Bool -> Test params test = Test@@ -29,7 +27,7 @@ testGroupM :: String -> [IO TF.Test] -> TF.Test testGroupM str = TF.buildTest . (TF.testGroup str <$>) . sequence --- normalizes any function resulting in a Benchmark to +-- normalizes any function resulting in a Benchmark to -- one that takes a proxy for its arguments hideArgs :: (GenArgs rnd bnch, MonadRandom rnd, ShowType a,              ResultOf bnch ~ Test a)
utils/Utils.hs view
@@ -1,10 +1,9 @@-{-# LANGUAGE DataKinds, FlexibleContexts, FlexibleInstances, GADTs,-             GeneralizedNewtypeDeriving, MultiParamTypeClasses, -             PolyKinds, RankNTypes, ConstraintKinds, ScopedTypeVariables, -             KindSignatures,-             TypeFamilies, TypeOperators, UndecidableInstances #-}+{-# LANGUAGE ConstraintKinds, DataKinds, FlexibleContexts, FlexibleInstances,+             GADTs, KindSignatures, MultiParamTypeClasses, PolyKinds,+             RankNTypes, ScopedTypeVariables, TypeFamilies, TypeOperators,+             UndecidableInstances #-} -module Utils +module Utils (Zq ,type (**) ,type (<$>)@@ -15,13 +14,7 @@ ,showType ,ShowType) where -import Control.Monad.Random-import Control.Monad (liftM)-import Control.Monad.State--import Control.DeepSeq--import Crypto.Lol (Int64,Fact,Factored,valueFact,Mod(..), Proxy(..), proxy, Cyc, RT, CT, LiftOf, TrivGad, BaseBGad)+import Crypto.Lol (Int64,Fact,valueFact,Mod(..), Proxy(..), proxy, RT, CT, TrivGad, BaseBGad) import Crypto.Lol.Reflects import Crypto.Lol.Types.ZqBasic import Crypto.Random.DRBG@@ -78,10 +71,10 @@   show _ = "HashDRBG"  instance (Fact m) => Show (ArgType m) where-  show _ = "F" ++ (show $ proxy valueFact (Proxy::Proxy m))+  show _ = "F" ++ show (proxy valueFact (Proxy::Proxy m))  instance (Mod (ZqBasic q i), Show i) => Show (ArgType (ZqBasic q i)) where-  show _ = "Q" ++ (show $ proxy modulus (Proxy::Proxy (ZqBasic q i)))+  show _ = "Q" ++ show (proxy modulus (Proxy::Proxy (ZqBasic q i)))  instance Show (ArgType RT) where   show _ = "RT"@@ -96,38 +89,38 @@   show _ = "TrivGad"  instance (Reflects b Integer) => Show (ArgType (BaseBGad (b :: k))) where-  show _ = "Base" ++ (show $ (proxy value (Proxy::Proxy b) :: Integer)) ++ "Gad"+  show _ = "Base" ++ show (proxy value (Proxy::Proxy b) :: Integer) ++ "Gad"  -- for RNS-style moduli instance (Show (ArgType a), Show (ArgType b)) => Show (ArgType (a,b)) where-  show _ = (show (AT :: ArgType a)) ++ "*" ++ (show (AT :: ArgType b))+  show _ = show (AT :: ArgType a) ++ "*" ++ show (AT :: ArgType b)  -- we use tuples rather than lists because types in a list must have the same kind, -- but tuples permit different kinds-instance (Show (ArgType a), Show (ArgType b)) +instance (Show (ArgType a), Show (ArgType b))   => Show (ArgType '(a,b)) where-  show _ = (show (AT :: ArgType a)) ++ " " ++ (show (AT :: ArgType b))+  show _ = show (AT :: ArgType a) ++ " " ++ show (AT :: ArgType b) -instance (Show (ArgType a), Show (ArgType '(b,c))) +instance (Show (ArgType a), Show (ArgType '(b,c)))   => Show (ArgType '(a,b,c)) where-  show _ = (show (AT :: ArgType a)) ++ " " ++ (show (AT :: ArgType '(b,c)))+  show _ = show (AT :: ArgType a) ++ " " ++ show (AT :: ArgType '(b,c)) -instance (Show (ArgType a), Show (ArgType '(b,c,d))) +instance (Show (ArgType a), Show (ArgType '(b,c,d)))   => Show (ArgType '(a,b,c,d)) where-  show _ = (show (AT :: ArgType a)) ++ " " ++ (show (AT :: ArgType '(b,c,d)))+  show _ = show (AT :: ArgType a) ++ " " ++ show (AT :: ArgType '(b,c,d)) -instance (Show (ArgType a), Show (ArgType '(b,c,d,e))) +instance (Show (ArgType a), Show (ArgType '(b,c,d,e)))   => Show (ArgType '(a,b,c,d,e)) where-  show _ = (show (AT :: ArgType a)) ++ " " ++ (show (AT :: ArgType '(b,c,d,e)))+  show _ = show (AT :: ArgType a) ++ " " ++ show (AT :: ArgType '(b,c,d,e)) -instance (Show (ArgType a), Show (ArgType '(b,c,d,e,f))) +instance (Show (ArgType a), Show (ArgType '(b,c,d,e,f)))   => Show (ArgType '(a,b,c,d,e,f)) where-  show _ = (show (AT :: ArgType a)) ++ " " ++ (show (AT :: ArgType '(b,c,d,e,f)))+  show _ = show (AT :: ArgType a) ++ " " ++ show (AT :: ArgType '(b,c,d,e,f)) -instance (Show (ArgType a), Show (ArgType '(b,c,d,e,f,g))) +instance (Show (ArgType a), Show (ArgType '(b,c,d,e,f,g)))   => Show (ArgType '(a,b,c,d,e,f,g)) where-  show _ = (show (AT :: ArgType a)) ++ " " ++ (show (AT :: ArgType '(b,c,d,e,f,g)))+  show _ = show (AT :: ArgType a) ++ " " ++ show (AT :: ArgType '(b,c,d,e,f,g)) -instance (Show (ArgType a), Show (ArgType '(b,c,d,e,f,g,h))) +instance (Show (ArgType a), Show (ArgType '(b,c,d,e,f,g,h)))   => Show (ArgType '(a,b,c,d,e,f,g,h)) where-  show _ = (show (AT :: ArgType a)) ++ " " ++ (show (AT :: ArgType '(b,c,d,e,f,g,h)))+  show _ = show (AT :: ArgType a) ++ " " ++ show (AT :: ArgType '(b,c,d,e,f,g,h))