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 +9/−0
- Crypto/Lol.hs +11/−16
- Crypto/Lol/CRTrans.hs +45/−60
- Crypto/Lol/Cyclotomic/CRTSentinel.hs +77/−0
- Crypto/Lol/Cyclotomic/Cyc.hs +127/−95
- Crypto/Lol/Cyclotomic/Linear.hs +15/−6
- Crypto/Lol/Cyclotomic/RescaleCyc.hs +3/−1
- Crypto/Lol/Cyclotomic/Tensor.hs +107/−62
- Crypto/Lol/Cyclotomic/Tensor/CTensor.hs +145/−108
- Crypto/Lol/Cyclotomic/Tensor/CTensor/Backend.hs +91/−77
- Crypto/Lol/Cyclotomic/Tensor/CTensor/Extension.hs +17/−16
- Crypto/Lol/Cyclotomic/Tensor/CTensor/basic.c +0/−175
- Crypto/Lol/Cyclotomic/Tensor/CTensor/common.cpp +18/−0
- Crypto/Lol/Cyclotomic/Tensor/CTensor/common.h +18/−0
- Crypto/Lol/Cyclotomic/Tensor/CTensor/crt.c +0/−1386
- Crypto/Lol/Cyclotomic/Tensor/CTensor/crt.cpp +515/−0
- Crypto/Lol/Cyclotomic/Tensor/CTensor/g.c +0/−828
- Crypto/Lol/Cyclotomic/Tensor/CTensor/g.cpp +167/−0
- Crypto/Lol/Cyclotomic/Tensor/CTensor/generalfuncs.c +0/−305
- Crypto/Lol/Cyclotomic/Tensor/CTensor/l.c +0/−434
- Crypto/Lol/Cyclotomic/Tensor/CTensor/l.cpp +87/−0
- Crypto/Lol/Cyclotomic/Tensor/CTensor/mul.cpp +24/−0
- Crypto/Lol/Cyclotomic/Tensor/CTensor/norm.c +0/−86
- Crypto/Lol/Cyclotomic/Tensor/CTensor/norm.cpp +69/−0
- Crypto/Lol/Cyclotomic/Tensor/CTensor/random.c +0/−74
- Crypto/Lol/Cyclotomic/Tensor/CTensor/random.cpp +53/−0
- Crypto/Lol/Cyclotomic/Tensor/CTensor/tensor.h +56/−0
- Crypto/Lol/Cyclotomic/Tensor/CTensor/tensorTypes.h +0/−231
- Crypto/Lol/Cyclotomic/Tensor/CTensor/types.h +138/−0
- Crypto/Lol/Cyclotomic/Tensor/CTensor/zq.cpp +36/−0
- Crypto/Lol/Cyclotomic/Tensor/RepaTensor.hs +65/−15
- Crypto/Lol/Cyclotomic/Tensor/RepaTensor/CRT.hs +44/−40
- Crypto/Lol/Cyclotomic/Tensor/RepaTensor/Dec.hs +3/−3
- Crypto/Lol/Cyclotomic/Tensor/RepaTensor/Extension.hs +27/−28
- Crypto/Lol/Cyclotomic/Tensor/RepaTensor/GL.hs +5/−5
- Crypto/Lol/Cyclotomic/Tensor/RepaTensor/RTCommon.hs +11/−14
- Crypto/Lol/Cyclotomic/UCyc.hs +377/−168
- Crypto/Lol/FactoredDefs.hs +67/−30
- Crypto/Lol/Gadget.hs +15/−7
- Crypto/Lol/GaussRandom.hs +5/−4
- Crypto/Lol/LatticePrelude.hs +0/−276
- Crypto/Lol/PosBinDefs.hs +24/−1
- Crypto/Lol/Prelude.hs +299/−0
- Crypto/Lol/RLWE/Continuous.hs +68/−0
- Crypto/Lol/RLWE/Discrete.hs +64/−0
- Crypto/Lol/RLWE/RLWR.hs +31/−0
- Crypto/Lol/Reflects.hs +6/−8
- Crypto/Lol/Types/Complex.hs +18/−12
- Crypto/Lol/Types/FiniteField.hs +37/−18
- Crypto/Lol/Types/IZipVector.hs +5/−3
- Crypto/Lol/Types/IrreducibleChar2.hs +157/−54
- Crypto/Lol/Types/Numeric.hs +2/−2
- Crypto/Lol/Types/Proto.hs +50/−0
- Crypto/Lol/Types/RRq.hs +112/−0
- Crypto/Lol/Types/Random.hs +25/−34
- Crypto/Lol/Types/ZPP.hs +1/−1
- Crypto/Lol/Types/ZmStar.hs +6/−6
- Crypto/Lol/Types/ZqBasic.hs +71/−72
- Crypto/Proto/RLWE.hs +23/−0
- Crypto/Proto/RLWE/Kq.hs +95/−0
- Crypto/Proto/RLWE/Rq.hs +95/−0
- Crypto/Proto/RLWE/SampleCont.hs +88/−0
- Crypto/Proto/RLWE/SampleDisc.hs +87/−0
- Crypto/Proto/RLWE/SampleRLWR.hs +87/−0
- Setup.hs +0/−2
- benchmarks/CycBenches.hs +59/−40
- benchmarks/Main.hs +6/−3
- benchmarks/TensorBenches.hs +27/−0
- benchmarks/UCycBenches.hs +47/−0
- benchmarks/ZqBenches.hs +7/−7
- lol.cabal +63/−44
- tests/CycTests.hs +22/−30
- tests/Main.hs +1/−1
- tests/TensorTests.hs +69/−76
- tests/ZqTests.hs +35/−44
- utils/Apply.hs +6/−6
- utils/Apply/Cyc.hs +109/−0
- utils/Apply/Zq.hs +37/−0
- utils/Benchmarks.hs +5/−7
- utils/Gen.hs +0/−27
- utils/GenArgs.hs +31/−0
- utils/GenArgs/Zq.hs +43/−0
- utils/Harness/Cyc.hs +0/−102
- utils/TestTypes.hs +6/−7
- utils/Tests.hs +3/−5
- utils/Utils.hs +24/−31
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))