pairing-0.3.1: src/Pairing/Group.hs
{-# LANGUAGE FlexibleInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
-- | Definitions of the groups the pairing is defined on
module Pairing.Group (
CyclicGroup(..),
G1,
G2,
GT,
isOnCurveG1,
isOnCurveG2,
isInGT,
g1,
g2,
b1,
b2,
hashToG1,
groupFromX,
fromByteStringG1,
fromByteStringG2,
fromByteStringGT
) where
import Protolude
import Data.Semigroup
import Pairing.Fq as Fq
import Pairing.Fq2 as Fq2
import Pairing.Fq12 as Fq12
import Pairing.Fr as Fr
import Pairing.Point
import Pairing.Params
import Pairing.CyclicGroup
import Test.QuickCheck
import Pairing.Hash
import Crypto.Random (MonadRandom)
import Pairing.Modular
import System.Random
import Pairing.Serialize
import Pairing.ByteRepr
-- | G1 is E(Fq) defined by y^2 = x^3 + b
type G1 = Point Fq
-- | G2 is E'(Fq2) defined by y^2 = x^3 + b / xi
type G2 = Point Fq2
-- | GT is subgroup of _r-th roots of unity of the multiplicative
-- group of Fq12
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 ToCompressedForm G1 where
serializeCompressed = fmap toS . toCompressedForm
instance ToUncompressedForm G1 where
serializeUncompressed = fmap toS . toUncompressedForm
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 ToCompressedForm G2 where
serializeCompressed = fmap toS . toCompressedForm
instance ToUncompressedForm G2 where
serializeUncompressed = fmap toS . toUncompressedForm
instance Monoid GT where
mappend = (*)
mempty = 1
instance CyclicGroup GT where
generator = notImplemented -- this should be the _r-th primitive root of unity
order = notImplemented -- should be a factor of _r
expn a b = a ^ asInteger b
inverse = recip
random _ = Fq12.random
instance ToUncompressedForm GT where
serializeUncompressed = fmap toS . elementToUncompressedForm
instance Validate GT where
isValidElement = isInGT
-- | Generator for G1
g1 :: G1
g1 = Point 1 2
-- | Generator for G2
g2 :: G2
g2 = Point x y
where
x = Fq2
10857046999023057135944570762232829481370756359578518086990519993285655852781
11559732032986387107991004021392285783925812861821192530917403151452391805634
y = Fq2
8495653923123431417604973247489272438418190587263600148770280649306958101930
4082367875863433681332203403145435568316851327593401208105741076214120093531
-- | Test whether a value in G1 satisfies the corresponding curve
-- equation
isOnCurveG1 :: G1 -> Bool
isOnCurveG1 Infinity
= True
isOnCurveG1 (Point x y)
= (y `fqPow` 2 == x `fqPow` 3 + Fq _b)
-- | Test whether a value in G2 satisfies the corresponding curve
-- equation
isOnCurveG2 :: G2 -> Bool
isOnCurveG2 Infinity
= True
isOnCurveG2 (Point x y)
= y `fq2pow` 2 == x `fq2pow` 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
-- | Test whether a value is an _r-th root of unity
isInGT :: GT -> Bool
isInGT f = f ^ _r == Fq12.fq12one
-- | Parameter for curve on Fq
b1 :: Fq
b1 = Fq.new _b
-- | Parameter for twisted curve over Fq2
b2 :: Fq2
b2 = Fq2 b1 0 / Fq2.xi
-------------------------------------------------------------------------------
-- Generators
-------------------------------------------------------------------------------
instance Arbitrary (Point Fq) where -- G1
arbitrary = gMul g1 . abs <$> (arbitrary :: Gen Integer)
instance Arbitrary (Point Fq2) where -- G2
arbitrary = gMul g2 . abs <$> (arbitrary :: Gen Integer)
hashToG1 :: MonadRandom m => ByteString -> m (Maybe G1)
hashToG1 = swEncBN
randomG1 :: (MonadRandom m) => m G1
randomG1 = do
Fq r <- Fq.random
pure (gMul g1 r)
randomG2 :: (MonadRandom m) => m G2
randomG2 = do
Fq r <- Fq.random
pure (gMul g2 r)
groupFromX :: (Validate (Point a), FromX a) => Bool -> a -> Maybe (Point a)
groupFromX largestY x = do
y <- yFromX x largestY
if isValidElement (Point x y) then Just (Point x y) else Nothing
fromByteStringG1 :: ByteString -> Either Text G1
fromByteStringG1 = pointFromByteString fqOne . toSL
fromByteStringG2 :: ByteString -> Either Text G2
fromByteStringG2 = pointFromByteString fq2one . toSL
fromByteStringGT :: ByteString -> Either Text GT
fromByteStringGT = elementReadUncompressed fq12one . toSL