{-# LANGUAGE FlexibleInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Pairing.Group (
CyclicGroup(..),
G1,
G2,
GT,
isOnCurveG1,
isOnCurveG2,
isInGT,
g1,
g2,
b1,
b2,
hashToG1,
randomG1,
randomG2
) where
import Protolude
import Data.Semigroup
import Pairing.Fq as Fq
import Pairing.Fq2 as Fq2
import Pairing.Fq12 as Fq12
import Pairing.Point
import Pairing.Params
import Pairing.CyclicGroup
import Test.QuickCheck
import Pairing.Hash
import Crypto.Random (MonadRandom)
type G1 = Point Fq
type G2 = Point Fq2
type GT = Fq12
instance Semigroup G1 where
(<>) = gAdd
instance Semigroup G2 where
(<>) = gAdd
instance Semigroup GT where
(<>) = (*)
instance Monoid G1 where
mappend = gAdd
mempty = Infinity
instance CyclicGroup G1 where
generator = g1
order _ = _r
expn a b = gMul a (asInteger b)
inverse = gNeg
instance Monoid G2 where
mappend = gAdd
mempty = Infinity
instance CyclicGroup G2 where
generator = g2
order _ = _r
expn a b = gMul a (asInteger b)
inverse = gNeg
instance Monoid GT where
mappend = (*)
mempty = 1
instance CyclicGroup GT where
generator = notImplemented
order = notImplemented
expn a b = a ^ asInteger b
inverse = recip
g1 :: G1
g1 = Point 1 2
g2 :: G2
g2 = Point x y
where
x = Fq2
10857046999023057135944570762232829481370756359578518086990519993285655852781
11559732032986387107991004021392285783925812861821192530917403151452391805634
y = Fq2
8495653923123431417604973247489272438418190587263600148770280649306958101930
4082367875863433681332203403145435568316851327593401208105741076214120093531
isOnCurveG1 :: G1 -> Bool
isOnCurveG1 Infinity
= True
isOnCurveG1 (Point x y)
= (y ^ 2 == x ^ 3 + Fq _b)
isOnCurveG2 :: G2 -> Bool
isOnCurveG2 Infinity
= True
isOnCurveG2 (Point x y)
= (y ^ 2 == x ^ 3 + (Fq2 (b * inv_xi_a) (b * inv_xi_b)))
where
(Fq2 inv_xi_a inv_xi_b) = Fq2.fq2inv Fq2.xi
b = Fq _b
isInGT :: GT -> Bool
isInGT f = f ^ _r == Fq12.fq12one
b1 :: Fq
b1 = Fq.new _b
b2 :: Fq2
b2 = Fq2 b1 0 / Fq2.xi
instance Arbitrary (Point Fq) where
arbitrary = gMul g1 . abs <$> (arbitrary :: Gen Integer)
instance Arbitrary (Point Fq2) where
arbitrary = gMul g2 . abs <$> (arbitrary :: Gen Integer)
hashToG1 :: (MonadIO m, MonadRandom m) => ByteString -> m G1
hashToG1 = swEncBN
randomG1 :: (MonadIO m, MonadRandom m) => m G1
randomG1 = do
Fq r <- Fq.random
pure (gMul g1 r)
randomG2 :: (MonadIO m, MonadRandom m) => m G2
randomG2 = do
Fq r <- Fq.random
pure (gMul g2 r)