pairing-0.4.2: tests/TestFields.hs
module TestFields where
import Protolude
import GaloisField
import ExtensionField
import Pairing.Fq
import Pairing.Fr
import Pairing.ByteRepr
import Test.Tasty
import Test.Tasty.HUnit
import Test.Tasty.QuickCheck
import qualified Test.QuickCheck.Monadic as TQM (monadicIO, assert, run)
import TestCommon
-------------------------------------------------------------------------------
-- Laws of field operations
-------------------------------------------------------------------------------
testFieldLaws
:: forall a . (Num a, Fractional a, Eq a, Arbitrary a, Show a)
=> Proxy a
-> TestName
-> TestTree
testFieldLaws _ descr
= testGroup ("Test field laws of " <> descr)
[ testProperty "commutativity of addition"
$ commutes ((+) :: a -> a -> a)
, testProperty "commutativity of multiplication"
$ commutes ((*) :: a -> a -> a)
, testProperty "associativity of addition"
$ associates ((+) :: a -> a -> a)
, testProperty "associativity of multiplication"
$ associates ((*) :: a -> a -> a)
, testProperty "additive identity"
$ isIdentity ((+) :: a -> a -> a) 0
, testProperty "multiplicative identity"
$ isIdentity ((*) :: a -> a -> a) 1
, testProperty "additive inverse"
$ isInverse ((+) :: a -> a -> a) negate 0
, testProperty "multiplicative inverse"
$ \x -> (x /= (0 :: a)) ==> isInverse ((*) :: a -> a -> a) recip 1 x
, testProperty "multiplication distributes over addition"
$ distributes ((*) :: a -> a -> a) (+)
]
-------------------------------------------------------------------------------
-- Fq
-------------------------------------------------------------------------------
test_fieldLaws_Fq :: TestTree
test_fieldLaws_Fq = testFieldLaws (Proxy :: Proxy Fq) "Fq"
-------------------------------------------------------------------------------
-- Fq2
-------------------------------------------------------------------------------
test_fieldLaws_Fq2 :: TestTree
test_fieldLaws_Fq2 = testFieldLaws (Proxy :: Proxy Fq2) "Fq2"
-- Defining property for Fq2 as an extension over Fq: u^2 = -1
unit_uRoot :: Assertion
unit_uRoot = u^2 @=? -1
where
u = toField [0, 1] :: Fq2
unit_fq2Pow :: Assertion
unit_fq2Pow = do
fq2 :: Fq2 <- rnd
let pow5 = ((fq2 ^ 2) ^ 2) * fq2
pow5 @=? fq2 ^ 5
let pow10 = ((((fq2 ^ 2) ^ 2) ^ 2) * fq2) * fq2
pow10 @=? fq2 ^ 10
unit_fq2Sqrt :: Assertion
unit_fq2Sqrt = do
fq2 :: Fq2 <- rnd
let sq = fq2 ^ 2
let (Just rt) = fq2Sqrt sq
sq @=? rt ^ 2
-------------------------------------------------------------------------------
-- Fq6
-------------------------------------------------------------------------------
test_fieldLaws_Fq6 :: TestTree
test_fieldLaws_Fq6 = testFieldLaws (Proxy :: Proxy Fq6) "Fq6"
-- Defining property for Fq6 as an extension over Fq2: v^3 = 9 + u
unit_vRoot :: Assertion
unit_vRoot = v^3 @=? 9 + u
where
v = toField [0, 1] :: Fq6
u = toField [toField [0, 1]]
-------------------------------------------------------------------------------
-- Fq12
-------------------------------------------------------------------------------
test_fieldLaws_Fq12 :: TestTree
test_fieldLaws_Fq12 = testFieldLaws (Proxy :: Proxy Fq12) "Fq12"
-- Defining property for Fq12 as an extension over Fq6: w^2 = v
unit_wRoot :: Assertion
unit_wRoot = w^2 @=? v
where
w = toField [0, 1] :: Fq12
v = toField [toField [0, 1]]
-------------------------------------------------------------------------------
-- Fr
-------------------------------------------------------------------------------
test_fieldLaws_Fr :: TestTree
test_fieldLaws_Fr = testFieldLaws (Proxy :: Proxy Fr) "Fr"
-------------------------------------------------------------------------------
-- Byte Representation
-------------------------------------------------------------------------------
primeFieldByteRepresentationTest :: Fq -> Assertion
primeFieldByteRepresentationTest f = do
byteReprTest f MostSignificantFirst 32
byteReprTest f LeastSignificantFirst 32
byteReprTest f MostSignificantFirst 64
byteReprTest f LeastSignificantFirst 64
extensionFieldByteRepresentationTest :: (Show a, Eq a, ByteRepr (ExtensionField a b)) => ExtensionField a b -> Assertion
extensionFieldByteRepresentationTest f = case fromField f of
[] -> pure ()
_ -> do
byteReprTest f MostSignificantFirst 32
byteReprTest f LeastSignificantFirst 32
byteReprTest f MostSignificantFirst 64
byteReprTest f LeastSignificantFirst 64
byteReprTest :: (Show a, Eq a, ByteRepr a) => a -> Pairing.ByteRepr.ByteOrder -> Int -> Assertion
byteReprTest f bo sz = do
let t = mkRepr (ByteOrderLength bo sz) f
assertBool ("mkRepr " <> show f) (isJust t)
let Just bs = t
let d = fromRepr (ByteOrderLength bo sz) f bs
assertBool ("fromRepr " <> show f) (isJust d)
(Just f) @=? d
prop_fqByteRepr :: Fq -> Property
prop_fqByteRepr a = TQM.monadicIO $ TQM.run $ primeFieldByteRepresentationTest a
prop_fq2ByteRepr :: Fq2 -> Property
prop_fq2ByteRepr a = TQM.monadicIO $ TQM.run $ extensionFieldByteRepresentationTest a
prop_fq6ByteRepr :: Fq6 -> Property
prop_fq6ByteRepr a = TQM.monadicIO $ TQM.run $ extensionFieldByteRepresentationTest a
prop_fq12ByteRepr :: Fq12 -> Property
prop_fq12ByteRepr a = TQM.monadicIO $ TQM.run $ extensionFieldByteRepresentationTest a