{-# OPTIONS_GHC -fno-warn-orphans #-}
module Pairing.Group
( CyclicGroup(..)
, G1
, G2
, GT
, b1
, b2
, g1
, g2
, groupFromX
, hashToG1
, isInGT
, isOnCurveG1
, isOnCurveG2
, fromByteStringG1
, fromByteStringG2
, fromByteStringGT
) where
import Protolude
import Control.Monad.Random (MonadRandom)
import Data.Semigroup ((<>))
import ExtensionField (fromList)
import GaloisField (GaloisField(..))
import PrimeField (toInt)
import Test.QuickCheck (Arbitrary(..), Gen)
import Pairing.CyclicGroup
import Pairing.Fq
import Pairing.Hash
import Pairing.Params
import Pairing.Point
import Pairing.Serialize.Types
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
random = randomG1
instance Validate G1 where
isValidElement = isOnCurveG1
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
random = randomG2
instance Validate G2 where
isValidElement = isOnCurveG2
instance Monoid GT where
mappend = (*)
mempty = 1
instance CyclicGroup GT where
generator = panic "not implemented."
order = panic "not implemented."
expn a b = pow a (asInteger b)
inverse = recip
random = rnd
instance Validate GT where
isValidElement = isInGT
g1 :: G1
g1 = Point 1 2
g2 :: G2
g2 = Point x y
where
x = fromList
[ 10857046999023057135944570762232829481370756359578518086990519993285655852781
, 11559732032986387107991004021392285783925812861821192530917403151452391805634 ]
y = fromList
[ 8495653923123431417604973247489272438418190587263600148770280649306958101930
, 4082367875863433681332203403145435568316851327593401208105741076214120093531 ]
isOnCurveG1 :: G1 -> Bool
isOnCurveG1 Infinity = True
isOnCurveG1 (Point x y) = pow y 2 == pow x 3 + fromInteger _b
isOnCurveG2 :: G2 -> Bool
isOnCurveG2 Infinity = True
isOnCurveG2 (Point x y) = pow y 2 == pow x 3 + fromList [fromInteger _b] / xi
isInGT :: GT -> Bool
isInGT f = pow f _r == 1
b1 :: Fq
b1 = fromInteger _b
b2 :: Fq2
b2 = fromList [b1] / xi
instance Arbitrary G1 where
arbitrary = gMul g1 . abs <$> (arbitrary :: Gen Integer)
instance Arbitrary G2 where
arbitrary = gMul g2 . abs <$> (arbitrary :: Gen Integer)
hashToG1 :: MonadRandom m => ByteString -> m (Maybe G1)
hashToG1 = swEncBN
randomG1 :: forall m . MonadRandom m => m G1
randomG1 = expn generator <$> (rnd :: m Fq)
randomG2 :: forall m . MonadRandom m => m G2
randomG2 = expn generator <$> (rnd :: m Fq)
groupFromX :: (Validate (Point a), FromX a) => (a -> a -> a) -> a -> Maybe (Point a)
groupFromX checkF x = do
y <- yFromX x checkF
if isValidElement (Point x y) then Just (Point x y) else Nothing
fromByteStringG1 :: (FromSerialisedForm u) => u -> LByteString -> Either Text G1
fromByteStringG1 unser = unserializePoint unser g1 . toSL
fromByteStringG2 :: (FromSerialisedForm u) => u -> LByteString -> Either Text G2
fromByteStringG2 unser = unserializePoint unser g2 . toSL
fromByteStringGT :: (FromUncompressedForm u) => u -> LByteString -> Either Text GT
fromByteStringGT unser = unserialize unser 1 . toSL