func (djProof *DisjunctiveProof) Bytes() []byte {
	var buf bytes.Buffer
	WriteECPoint(&buf, djProof.T1)
	WriteECPoint(&buf, djProof.T2)
	WriteBigInt(&buf, djProof.C)
	WriteBigInt(&buf, djProof.C1)
	WriteBigInt(&buf, djProof.C2)
	WriteBigInt(&buf, djProof.S1)
	WriteBigInt(&buf, djProof.S2)
	return buf.Bytes()
}
Bytes returns a byte slice with a serialized representation of DisjunctiveProof proof
package zksigma
import (
	"bytes"
	"crypto/rand"
	"fmt"
	"math/big"
)
type DisjunctiveProof struct {
	T1 ECPoint
	T2 ECPoint
	C  *big.Int
	C1 *big.Int
	C2 *big.Int
	S1 *big.Int
	S2 *big.Int
}
func NewDisjunctiveProof(
	zkpcp ZKPCurveParams, Base1, Result1, Base2, Result2 ECPoint, x *big.Int, option Side) (*DisjunctiveProof, error) {
	modValue := new(big.Int).Mod(x, zkpcp.C.Params().N)
	var ProveBase, ProveResult, OtherBase, OtherResult ECPoint
	if option == Left {
		ProveBase = Base1
		ProveResult = Result1
		OtherBase = Base2
		OtherResult = Result2
	} else if option == Right {  
		ProveBase = Base2
		ProveResult = Result2
		OtherBase = Base1
		OtherResult = Result1
	} else {  
		return &DisjunctiveProof{}, &errorProof{"DisjunctiveProve", "invalid side provided"}
	}
	if !zkpcp.Mult(ProveBase, x).Equal(ProveResult) {
		return &DisjunctiveProof{}, &errorProof{"DisjunctiveProve", "Base and Result to be proved not related by x"}
	}
	u1, err := rand.Int(rand.Reader, zkpcp.C.Params().N)
	if err != nil {
		return nil, err
	}
	u2, err := rand.Int(rand.Reader, zkpcp.C.Params().N)
	if err != nil {
		return nil, err
	}
	u3, err := rand.Int(rand.Reader, zkpcp.C.Params().N)
	if err != nil {
		return nil, err
	}
	u3Neg := new(big.Int).Neg(u3)
	u3Neg.Mod(u3Neg, zkpcp.C.Params().N)
	T1 := zkpcp.Mult(ProveBase, u1)
	temp := zkpcp.Mult(OtherBase, u2)
	temp2 := zkpcp.Mult(OtherResult, u3Neg)
	T2 := zkpcp.Add(temp, temp2)
	var Challenge *big.Int
	if option == 0 {
		Challenge = GenerateChallenge(zkpcp, Base1.Bytes(), Result1.Bytes(),
			Base2.Bytes(), Result2.Bytes(),
			T1.Bytes(), T2.Bytes())
	} else {
		Challenge = GenerateChallenge(zkpcp, Base1.Bytes(), Result1.Bytes(),
			Base2.Bytes(), Result2.Bytes(),
			T2.Bytes(), T1.Bytes())  
	}
	deltaC := new(big.Int).Sub(Challenge, u3)
	deltaC.Mod(deltaC, zkpcp.C.Params().N)
	s := new(big.Int).Add(u1, new(big.Int).Mul(deltaC, modValue))
	if option == Left {
		return &DisjunctiveProof{
			T1,
			T2,
			Challenge,
			deltaC,
			u3,
			s,
			u2}, nil
	}
	return &DisjunctiveProof{
		T2,
		T1,
		Challenge,
		u3,
		deltaC,
		u2,
		s}, nil
}
func (djProof *DisjunctiveProof) Verify(
	zkpcp ZKPCurveParams, Base1, Result1, Base2, Result2 ECPoint) (bool, error) {
	if djProof == nil {
		return false, &errorProof{"DisjunctiveProof.Verify", fmt.Sprintf("passed proof is nil")}
	}
	T1 := djProof.T1
	T2 := djProof.T2
	C := djProof.C
	C1 := djProof.C1
	C2 := djProof.C2
	S1 := djProof.S1
	S2 := djProof.S2
	checkC := GenerateChallenge(zkpcp, Base1.Bytes(), Result1.Bytes(),
		Base2.Bytes(), Result2.Bytes(),
		T1.Bytes(), T2.Bytes())
	if checkC.Cmp(C) != 0 {
		return false, &errorProof{"DisjunctiveVerify", "checkC does not agree with proofC"}
	}
	totalC := new(big.Int).Add(C1, C2)
	totalC.Mod(totalC, zkpcp.C.Params().N)
	if totalC.Cmp(C) != 0 {
		return false, &errorProof{"DisjunctiveVerify", "totalC does not agree with proofC"}
	}
	c1A := zkpcp.Mult(Result1, C1)
	checks1G := zkpcp.Add(T1, c1A)
	s1G := zkpcp.Mult(Base1, S1)
	if !checks1G.Equal(s1G) {
		return false, &errorProof{"DisjunctiveVerify", "s1G not equal to T1 + c1A"}
	}
	c2A := zkpcp.Mult(Result2, C2)
	checks2G := zkpcp.Add(c2A, T2)
	s2G := zkpcp.Mult(Base2, S2)
	if !checks2G.Equal(s2G) {
		return false, &errorProof{"DisjunctiveVerify", "s2G not equal to T2 + c2B"}
	}
	return true, nil
}