{-# 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 (EllipticCurve (..))
import           ZkFold.Symbolic.Compiler                ()

newtype PlonkupInput l c = PlonkupInput { forall {k} (l :: Type -> Type) (c :: k).
PlonkupInput l c -> l (ScalarField c)
unPlonkupInput :: l (ScalarField c) }

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

instance (Arbitrary (l (ScalarField c))) => Arbitrary (PlonkupInput l c) where
    arbitrary :: Gen (PlonkupInput l c)
arbitrary = l (ScalarField c) -> PlonkupInput l c
forall {k} (l :: Type -> Type) (c :: k).
l (ScalarField c) -> PlonkupInput l c
PlonkupInput (l (ScalarField c) -> PlonkupInput l c)
-> Gen (l (ScalarField c)) -> Gen (PlonkupInput l c)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (l (ScalarField c))
forall a. Arbitrary a => Gen a
arbitrary

plonkupVerifierInput ::
  (Functor l, Field (ScalarField c)) => l (ScalarField c) -> PlonkupInput l c
plonkupVerifierInput :: forall {k} (l :: Type -> Type) (c :: k).
(Functor l, Field (ScalarField c)) =>
l (ScalarField c) -> PlonkupInput l c
plonkupVerifierInput l (ScalarField c)
input = l (ScalarField c) -> PlonkupInput l c
forall {k} (l :: Type -> Type) (c :: k).
l (ScalarField c) -> PlonkupInput l c
PlonkupInput (l (ScalarField c) -> PlonkupInput l c)
-> l (ScalarField c) -> PlonkupInput l c
forall a b. (a -> b) -> a -> b
$ ScalarField c -> ScalarField c
forall a. AdditiveGroup a => a -> a
negate (ScalarField c -> ScalarField c)
-> l (ScalarField c) -> l (ScalarField c)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> l (ScalarField c)
input