{-| Module : Crypto.Lol.Tests.CycTests Description : Tests for the 'Cyc' interface. Copyright : (c) Eric Crockett, 2011-2017 Chris Peikert, 2011-2017 License : GPL-3 Maintainer : ecrockett0@email.com Stability : experimental Portability : POSIX Tests for the 'Cyc' interface. -} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE PartialTypeSignatures #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# OPTIONS_GHC -fno-warn-partial-type-signatures #-} module Crypto.Lol.Tests.CycTests (cycTests1, cycTests2) where import Control.Applicative import Control.Monad (join, liftM2) import Crypto.Lol import Crypto.Lol.Utils.ShowType import Crypto.Lol.Utils.Tests (Gen, Test, testGroup, testWithGen, testWithoutGen) -- | Tests for single-index 'Cyc' operations. There must be a CRT basis for \(O_m\) over @r@. cycTests1 :: forall t m r . (Fact m, _) => Gen (Cyc t m r) -> Test cycTests1 cycGen = let ptmr = Proxy :: Proxy '(t,m,r) in testGroup (showType ptmr) $ ($ cycGen) <$> [ testWithGen "mulGPow" prop_mulgPow, testWithGen "mulGDec" prop_mulgDec, testWithGen "mulGCRT" prop_mulgCRT] -- | Tests for inter-ring 'Cyc' operations. There must be a CRT basis for \(O_{m'}\) over @r@. cycTests2 :: forall t m m' r . _ => Proxy '(t,m,m',r) -> Gen (Cyc t m' r) -> Test cycTests2 _ cycGen = let ptmmr = Proxy::Proxy '(t,m,m',r) in testGroup (showType ptmmr) [ testWithoutGen "crtSet" (prop_crtSet_pairs ptmmr), testWithGen "coeffsPow" (prop_coeffsPow ptmmr) cycGen] prop_mulgPow :: _ => Cyc t m r -> Bool prop_mulgPow x = let y = advisePow x in y == fromJust' "prop_mulgPow failed divisibility!" (divG $ mulG y) prop_mulgDec :: _ => Cyc t m r -> Bool prop_mulgDec x = let y = adviseDec x in y == fromJust' "prop_mulgDec failed divisibility!" (divG $ mulG y) prop_mulgCRT :: _ => Cyc t m r -> Bool prop_mulgCRT x = let y = adviseCRT x in y == fromJust' "prop_mulgCRT failed divisibility!" (divG $ mulG y) prop_coeffsPow :: forall t m m' r . _ => Proxy '(t,m,m',r) -> Cyc t m' r -> Bool prop_coeffsPow _ x = let xs = map embed (coeffsPow x :: [Cyc t m r]) bs = proxy powBasis (Proxy::Proxy m) in sum (zipWith (*) xs bs) == x -- verifies that CRT set elements satisfy c_i * c_j = delta_ij * c_i -- necessary (but not sufficient) condition prop_crtSet_pairs :: forall (t :: Factored -> * -> *) m (m' :: Factored) (r :: *) . _ => Proxy '(t,m,m',r) -> Bool prop_crtSet_pairs _ = let crtset = proxy crtSet (Proxy::Proxy m) :: [Cyc t m' r] pairs = join (liftM2 (,)) crtset in all (\(a,b) -> if a == b then a*b == a else a*b == zero) pairs