{-# LANGUAGE UndecidableInstances #-}

module ZkFold.Base.Protocol.Plonkup.Input where

import           Data.Function                           (($))
import           Data.Functor                            (Functor, (<$>))
import           Data.Functor.Classes                    (Show1)
import           Data.List                               ((++))
import           Test.QuickCheck                         (Arbitrary (..))
import           Text.Show                               (Show, show)

import           ZkFold.Base.Algebra.Basic.Class
import           ZkFold.Base.Algebra.EllipticCurve.Class (CyclicGroup (..))
import           ZkFold.Symbolic.Compiler                ()

newtype PlonkupInput l g = PlonkupInput { forall (l :: Type -> Type) g.
PlonkupInput l g -> l (ScalarFieldOf g)
unPlonkupInput :: l (ScalarFieldOf g) }

instance (Show1 l, Show (ScalarFieldOf g)) => Show (PlonkupInput l g) where
    show :: PlonkupInput l g -> String
show (PlonkupInput l (ScalarFieldOf g)
v) = String
"Plonkup Input: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ l (ScalarFieldOf g) -> String
forall a. Show a => a -> String
show l (ScalarFieldOf g)
v

instance (Arbitrary (l (ScalarFieldOf g))) => Arbitrary (PlonkupInput l g) where
    arbitrary :: Gen (PlonkupInput l g)
arbitrary = l (ScalarFieldOf g) -> PlonkupInput l g
forall (l :: Type -> Type) g.
l (ScalarFieldOf g) -> PlonkupInput l g
PlonkupInput (l (ScalarFieldOf g) -> PlonkupInput l g)
-> Gen (l (ScalarFieldOf g)) -> Gen (PlonkupInput l g)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (l (ScalarFieldOf g))
forall a. Arbitrary a => Gen a
arbitrary

plonkupVerifierInput ::
  (Functor l, Field (ScalarFieldOf g)) => l (ScalarFieldOf g) -> PlonkupInput l g
plonkupVerifierInput :: forall (l :: Type -> Type) g.
(Functor l, Field (ScalarFieldOf g)) =>
l (ScalarFieldOf g) -> PlonkupInput l g
plonkupVerifierInput l (ScalarFieldOf g)
input = l (ScalarFieldOf g) -> PlonkupInput l g
forall (l :: Type -> Type) g.
l (ScalarFieldOf g) -> PlonkupInput l g
PlonkupInput (l (ScalarFieldOf g) -> PlonkupInput l g)
-> l (ScalarFieldOf g) -> PlonkupInput l g
forall a b. (a -> b) -> a -> b
$ ScalarFieldOf g -> ScalarFieldOf g
forall a. AdditiveGroup a => a -> a
negate (ScalarFieldOf g -> ScalarFieldOf g)
-> l (ScalarFieldOf g) -> l (ScalarFieldOf g)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> l (ScalarFieldOf g)
input