module Pairing.Curve
(
Fq
, Fq2
, Fq6
, Fq12
, Fr
, G1
, G2
, G2'
, GT
, gG1
, gG2
, gGT
, rG1
, rG2
, rGT
, _a
, _a'
, _b
, _b'
, _k
, _nqr
, _q
, _r
, _t
, _xi
, conj
, getYfromX
, scale
, mulXi
, fq12Frobenius
, isRootOfUnity
, isPrimitiveRootOfUnity
, primitiveRootOfUnity
, precompRootOfUnity
) where
import Protolude
import Curve (Curve(..))
import qualified Curve.Weierstrass.BN254 as BN254
import qualified Curve.Weierstrass.BN254T as BN254T
import ExtensionField (ExtensionField, IrreducibleMonic, fromField, toField)
import GaloisField (GaloisField(..))
import qualified Group.Field.BN254TF as BN254TF
type Fq = BN254.Fq
type Fq2 = BN254T.Fq2
type Fq6 = BN254TF.Fq6
type Fq12 = BN254TF.Fq12
type Fr = BN254.Fr
type G1 = BN254.PA
type G2 = BN254T.PA
type G2' = BN254T.PJ
type GT = BN254TF.P
gG1 :: G1
gG1 = BN254.gA
gG2 :: G2
gG2 = BN254T.gA
gGT :: GT
gGT = BN254TF.g_
rG1 :: Integer
rG1 = BN254._r
rG2 :: Integer
rG2 = BN254T._r
rGT :: Integer
rGT = BN254TF._r
_a :: Fq
_a = BN254._a
_a' :: Fq2
_a' = BN254T._a
_b :: Fq
_b = BN254._b
_b' :: Fq2
_b' = BN254T._b
_k :: Integer
_k = 12
_nqr :: Integer
_nqr = 21888242871839275222246405745257275088696311157297823662689037894645226208582
_q :: Integer
_q = BN254._q
_r :: Integer
_r = BN254._r
_t :: Integer
_t = 4965661367192848881
_xi :: Fq2
_xi = toField [9, 1]
conj :: forall k im . IrreducibleMonic k im
=> ExtensionField k im -> ExtensionField k im
conj x
| deg x /= 2 * deg (witness :: k) = panic "conj: extension degree is not two."
| otherwise = case fromField x of
[y, z] -> toField [y, negate z]
[y] -> toField [y]
[] -> 0
_ -> panic "conj: unreachable."
{-# INLINABLE conj #-}
getYfromX :: Curve f c e q r => Point f c e q r -> (q -> q -> q) -> q -> Maybe q
getYfromX curve choose x = choose <*> negate <$> yX curve x
{-# INLINABLE getYfromX #-}
scale :: IrreducibleMonic k im => k -> ExtensionField k im -> ExtensionField k im
scale = (*) . toField . return
{-# INLINABLE scale #-}
mulXi :: Fq6 -> Fq6
mulXi w = case fromField w of
[x, y, z] -> toField [z * _xi, x, y]
[x, y] -> toField [0, x, y]
[x] -> toField [0, x]
[] -> toField []
_ -> panic "mulXi: not exhaustive."
{-# INLINE mulXi #-}
fq12Frobenius :: Int -> Fq12 -> Fq12
fq12Frobenius i a
| i == 0 = a
| i == 1 = fastFrobenius a
| i > 1 = let prev = fq12Frobenius (i - 1) a in fastFrobenius prev
| otherwise = panic "fq12Frobenius: not defined for negative values of i."
{-# INLINABLE fq12Frobenius #-}
fastFrobenius :: Fq12 -> Fq12
fastFrobenius = coll . conv [[0,2,4],[1,3,5]] . cong
where
cong :: Fq12 -> [[Fq2]]
cong = map (map conj . fromField) . fromField
conv :: [[Integer]] -> [[Fq2]] -> [[Fq2]]
conv = zipWith (zipWith (\x y -> pow _xi ((x * (_q - 1)) `div` 6) * y))
coll :: [[Fq2]] -> Fq12
coll = toField . map toField
{-# INLINABLE fastFrobenius #-}
isRootOfUnity :: Integer -> Fr -> Bool
isRootOfUnity n x
| n > 0 = pow x n == 1
| otherwise = panic "isRootOfUnity: negative powers not supported."
{-# INLINABLE isRootOfUnity #-}
isPrimitiveRootOfUnity :: Integer -> Fr -> Bool
isPrimitiveRootOfUnity n x
| n > 0 = isRootOfUnity n x && all (\m -> not $ isRootOfUnity m x) [1 .. n - 1]
| otherwise = panic "isPrimitiveRootOfUnity: negative powers not supported."
{-# INLINABLE isPrimitiveRootOfUnity #-}
primitiveRootOfUnity :: Int -> Fr
primitiveRootOfUnity k
| 0 <= k && k <= 28 = 5^((_r - 1) `div` (2^k))
| otherwise = panic "primitiveRootOfUnity: no primitive root for given power of 2."
{-# INLINABLE primitiveRootOfUnity #-}
precompRootOfUnity :: Int -> Fr
precompRootOfUnity 0 = 1
precompRootOfUnity 1 = 21888242871839275222246405745257275088548364400416034343698204186575808495616
precompRootOfUnity 2 = 21888242871839275217838484774961031246007050428528088939761107053157389710902
precompRootOfUnity 3 = 19540430494807482326159819597004422086093766032135589407132600596362845576832
precompRootOfUnity 4 = 14940766826517323942636479241147756311199852622225275649687664389641784935947
precompRootOfUnity 5 = 4419234939496763621076330863786513495701855246241724391626358375488475697872
precompRootOfUnity 6 = 9088801421649573101014283686030284801466796108869023335878462724291607593530
precompRootOfUnity 7 = 10359452186428527605436343203440067497552205259388878191021578220384701716497
precompRootOfUnity 8 = 3478517300119284901893091970156912948790432420133812234316178878452092729974
precompRootOfUnity 9 = 6837567842312086091520287814181175430087169027974246751610506942214842701774
precompRootOfUnity 10 = 3161067157621608152362653341354432744960400845131437947728257924963983317266
precompRootOfUnity 11 = 1120550406532664055539694724667294622065367841900378087843176726913374367458
precompRootOfUnity 12 = 4158865282786404163413953114870269622875596290766033564087307867933865333818
precompRootOfUnity 13 = 197302210312744933010843010704445784068657690384188106020011018676818793232
precompRootOfUnity 14 = 20619701001583904760601357484951574588621083236087856586626117568842480512645
precompRootOfUnity 15 = 20402931748843538985151001264530049874871572933694634836567070693966133783803
precompRootOfUnity 16 = 421743594562400382753388642386256516545992082196004333756405989743524594615
precompRootOfUnity 17 = 12650941915662020058015862023665998998969191525479888727406889100124684769509
precompRootOfUnity 18 = 11699596668367776675346610687704220591435078791727316319397053191800576917728
precompRootOfUnity 19 = 15549849457946371566896172786938980432421851627449396898353380550861104573629
precompRootOfUnity 20 = 17220337697351015657950521176323262483320249231368149235373741788599650842711
precompRootOfUnity 21 = 13536764371732269273912573961853310557438878140379554347802702086337840854307
precompRootOfUnity 22 = 12143866164239048021030917283424216263377309185099704096317235600302831912062
precompRootOfUnity 23 = 934650972362265999028062457054462628285482693704334323590406443310927365533
precompRootOfUnity 24 = 5709868443893258075976348696661355716898495876243883251619397131511003808859
precompRootOfUnity 25 = 19200870435978225707111062059747084165650991997241425080699860725083300967194
precompRootOfUnity 26 = 7419588552507395652481651088034484897579724952953562618697845598160172257810
precompRootOfUnity 27 = 2082940218526944230311718225077035922214683169814847712455127909555749686340
precompRootOfUnity 28 = 19103219067921713944291392827692070036145651957329286315305642004821462161904
precompRootOfUnity _ = panic "precompRootOfUnity: exponent too big for Fr / negative"
{-# INLINABLE precompRootOfUnity #-}