module TestPairing where import Protolude import TestFields () -- for its Arbitrary instances import Pairing.Group import Pairing.Pairing import Pairing.Point import Pairing.Fq (Fq(..)) import Pairing.Fq2 (Fq2(..)) import Pairing.Fq12 (Fq12(..)) import qualified Pairing.Fq12 as Fq12 import Test.QuickCheck import Test.Tasty.HUnit -- Random points in G1, G2 as generated by libff. inpG1 :: G1 inpG1 = Point (Fq 1368015179489954701390400359078579693043519447331113978918064868415326638035) (Fq 9918110051302171585080402603319702774565515993150576347155970296011118125764) inpG2 :: G2 inpG2 = Point (Fq2 (Fq 2725019753478801796453339367788033689375851816420509565303521482350756874229) (Fq 7273165102799931111715871471550377909735733521218303035754523677688038059653) ) (Fq2 (Fq 2512659008974376214222774206987427162027254181373325676825515531566330959255) (Fq 957874124722006818841961785324909313781880061366718538693995380805373202866) ) beforeExponentiation :: Fq12 beforeExponentiation = Fq12.new [ 10244919957345566208036224388367387294947954375520342002142038721148536068658 , 20520725903107462730350108147804326707908059028221039276493719519842949720531 , 6086095302240468555411758663466251351417777262748587710512082696159022563215 , 3498483043828007000664704983384438380014626741459095899124517210966193962189 , 9839947403899670326057934148290729066991318244952536153418081752510541932805 , 9202072764973620760720243946210007480782851719144203914690329192926361472509 , 10396963991176748371570893144856868074352236348257264320828640725417622807401 , 16918234646064442383576265933863121396979541666923405352165222603555475148795 , 1146287855099517708899800840204495527878843746533321795244252048321172986641 , 15272723827732170058231690870045992172379497733734277515700990114389642596090 , 6026541190208646112995382377707652888403252171847993766999540977939986078453 , 4033750506662808934164561353819561401109395743946249795674228367029912558059 ] afterExponentiation :: Fq12 afterExponentiation = Fq12.new [ 7297928317524675251652102644847406639091474940444702627333408876432772026640 , 18010865284024443253481973710158529446817119443459787454101328040744995455319 , 14179125828660221708486990054318233868908974550229474018509093903907472063156 , 19672547343219696395323430329000470270122259521813831378125910505067755316037 , 10811020225621941034352015694422164943041584464746963243431262955968538467312 , 18591344525433923700278298641693487837785792806011751060570085671866249379154 , 18214296718386486500838507024306049626571830525675768493345345883297201451077 , 19227311731387426597265504864999881769743583647552324796732605660514141916117 , 15463354980731838106439887363063618463783317416732018231077874458188347926701 , 3765441250413579779915094051038487360437654739171671492016287185303087270469 , 21029416079740174485345021549306749850075185576152640151652655104272393297142 , 19736982780723093346009254617143639137054958583796054069884522103959451721163 ] -- Sanity check test inputs unit_inpG1_valid :: Assertion unit_inpG1_valid = assertBool "inpG1 does not satisfy curve equation" $ isOnCurveG1 inpG1 unit_inpG2_valid :: Assertion unit_inpG2_valid = assertBool "inpG2 does not satisfy curve equation" $ isOnCurveG2 inpG2 -- Test our pairing ouput against that of libff. unit_pairingLibff_0 :: Assertion unit_pairingLibff_0 = beforeExponentiation @=? atePairing inpG1 inpG2 unit_pairingLibff_1 :: Assertion unit_pairingLibff_1 = afterExponentiation @=? reducedPairing inpG1 inpG2 pairingTestCount :: Int pairingTestCount = 10 prop_pairingBilinear :: Property prop_pairingBilinear = withMaxSuccess pairingTestCount prop where prop :: G1 -> G2 -> Integer -> Integer -> Bool prop e1 e2 preExp1 preExp2 = reducedPairing (gMul e1 exp1) (gMul e2 exp2) == (reducedPairing e1 e2)^(exp1 * exp2) where -- Quickcheck might give us negative integers or 0, so we -- take the absolute values instead and add one. exp1 = abs preExp1 + 1 exp2 = abs preExp2 + 1 prop_pairingNonDegenerate :: Property prop_pairingNonDegenerate = withMaxSuccess pairingTestCount prop where prop :: G1 -> G2 -> Bool prop e1 e2 = or [ e1 == Infinity , e2 == Infinity , reducedPairing e1 e2 /= Fq12.fq12one ] -- Output of the pairing to the power _r should be the unit of GT. prop_pairingPowerTest :: Property prop_pairingPowerTest = withMaxSuccess pairingTestCount prop where prop :: G1 -> G2 -> Bool prop e1 e2 = isInGT (reducedPairing e1 e2) prop_frobeniusFq12Correct :: Fq12 -> Bool prop_frobeniusFq12Correct f = frobeniusNaive 1 f == Fq12.fq12frobenius 1 f prop_finalExponentiationCorrect :: Property prop_finalExponentiationCorrect = withMaxSuccess 10 prop where prop :: Fq12 -> Bool prop f = finalExponentiation f == finalExponentiationNaive f