func (v *RepresentationVerifier) SetChallenge(challenge *big.Int) {
	v.challenge = challenge
}
SetChallenge is used when Fiat-Shamir is used - when challenge is generated using hash by the prover.
package qr
import (
	"fmt"
	"math/big"
	"github.com/xlab-si/emmy/crypto/common"
)
type RepresentationProver struct {
	group      *RSASpecial
	secParam   int  
	secrets    []*big.Int
	bases      []*big.Int
	randomVals []*big.Int
	y          *big.Int
}
func NewRepresentationProver(qrSpecialRSA *RSASpecial,
	secParam int, secrets, bases []*big.Int, y *big.Int) *RepresentationProver {
	return &RepresentationProver{
		group:    qrSpecialRSA,
		secParam: secParam,
		secrets:  secrets,
		bases:    bases,
		y:        y,
	}
}
func (p *RepresentationProver) GetProofRandomData(alsoNeg bool) *big.Int {
	nLen := p.group.N.BitLen()
	exp := big.NewInt(int64(nLen + p.secParam))
	b := new(big.Int).Exp(big.NewInt(2), exp, nil)
	t := big.NewInt(1)
	var randomVals = make([]*big.Int, len(p.bases))
	for i, _ := range randomVals {
		var r *big.Int
		if alsoNeg {
			r = common.GetRandomIntAlsoNeg(b)
		} else {
			r = common.GetRandomInt(b)
		}
		randomVals[i] = r
		f := p.group.Exp(p.bases[i], r)
		t = p.group.Mul(t, f)
	}
	p.randomVals = randomVals
	return t
}
func (p *RepresentationProver) GetProofRandomDataGivenBoundaries(boundariesBitLength []int,
	alsoNeg bool) (*big.Int, error) {
	if len(boundariesBitLength) != len(p.bases) {
		return nil, fmt.Errorf("the length of boundariesBitLength should be the same as the number of bases")
	}
	t := big.NewInt(1)
	var randomVals = make([]*big.Int, len(p.bases))
	for i, _ := range randomVals {
		exp := big.NewInt(int64(boundariesBitLength[i]))
		b := new(big.Int).Exp(big.NewInt(2), exp, nil)
		var r *big.Int
		if alsoNeg {
			r = common.GetRandomIntAlsoNeg(b)
		} else {
			r = common.GetRandomInt(b)
		}
		randomVals[i] = r
		f := p.group.Exp(p.bases[i], r)
		t = p.group.Mul(t, f)
	}
	p.randomVals = randomVals
	return t, nil
}
func (p *RepresentationProver) GetProofData(challenge *big.Int) []*big.Int {
	var proofData = make([]*big.Int, len(p.bases))
	for i, _ := range proofData {
		z_i := new(big.Int).Mul(challenge, p.secrets[i])
		z_i.Add(z_i, p.randomVals[i])
		proofData[i] = z_i
	}
	return proofData
}
type RepresentationProof struct {
	ProofRandomData *big.Int
	Challenge       *big.Int
	ProofData       []*big.Int
}
func NewRepresentationProof(proofRandomData, challenge *big.Int,
	proofData []*big.Int) *RepresentationProof {
	return &RepresentationProof{
		ProofRandomData: proofRandomData,
		Challenge:       challenge,
		ProofData:       proofData,
	}
}
type RepresentationVerifier struct {
	group              *RSASpecial
	challengeSpaceSize int
	challenge          *big.Int
	bases              []*big.Int
	y                  *big.Int
	proofRandomData    *big.Int
}
func NewRepresentationVerifier(qrSpecialRSA *RSASpecial,
	challengeSpaceSize int) *RepresentationVerifier {
	return &RepresentationVerifier{
		group:              qrSpecialRSA,
		challengeSpaceSize: challengeSpaceSize,
	}
}
func (v *RepresentationVerifier) SetProofRandomData(proofRandomData *big.Int, bases []*big.Int,
	y *big.Int) {
	v.proofRandomData = proofRandomData
	v.bases = bases
	v.y = y
}
func (v *RepresentationVerifier) GetChallenge() *big.Int {
	exp := big.NewInt(int64(v.challengeSpaceSize))
	b := new(big.Int).Exp(big.NewInt(2), exp, nil)
	challenge := common.GetRandomInt(b)
	v.challenge = challenge
	return challenge
}