func (s *Paillier) DeriveKey(masterSecKey data.Vector, y data.Vector) (*big.Int, error) {
	if s.Params.BoundY != nil {
		if err := y.CheckBound(s.Params.BoundY); err != nil {
			return nil, err
		}
	}
	return masterSecKey.Dot(y)
}
DeriveKey accepts master secret key masterSecKey and input vector y, and derives a
functional encryption key for the inner product with y.
In case of malformed secret key or input vector that violates the configured
bound, it returns an error.
package fullysec
import (
	"crypto/rand"
	"fmt"
	"math/big"
	"github.com/fentec-project/gofe/data"
	"github.com/fentec-project/gofe/internal"
	"github.com/fentec-project/gofe/internal/keygen"
	"github.com/fentec-project/gofe/sample"
)
type PaillierParams struct {
	L       int         
	N       *big.Int    
	NSquare *big.Int    
	BoundX  *big.Int    
	BoundY  *big.Int    
	Sigma   *big.Float  
	LSigma  *big.Int    
	Lambda  int         
	G       *big.Int    
}
type Paillier struct {
	Params *PaillierParams
}
func NewPaillier(l, lambda, bitLen int, boundX, boundY *big.Int) (*Paillier, error) {
	p, err := keygen.GetSafePrime(bitLen)
	if err != nil {
		return nil, err
	}
	q, err := keygen.GetSafePrime(bitLen)
	if err != nil {
		return nil, err
	}
	n := new(big.Int).Mul(p, q)
	nSquare := new(big.Int).Mul(n, n)
	if boundX != nil && boundY != nil {
		xSquareL := new(big.Int).Mul(boundX, boundX)
		xSquareL.Mul(xSquareL, big.NewInt(int64(2*l)))
		ySquareL := new(big.Int).Mul(boundY, boundY)
		ySquareL.Mul(ySquareL, big.NewInt(int64(2*l)))
		if n.Cmp(xSquareL) < 1 {
			return nil, fmt.Errorf("parameters generation failed," +
				"boundX and l too big for bitLen")
		}
		if n.Cmp(ySquareL) < 1 {
			return nil, fmt.Errorf("parameters generation failed," +
				"boundY and l too big for bitLen")
		}
	}
	gPrime, err := rand.Int(rand.Reader, nSquare)
	if err != nil {
		return nil, err
	}
	g := new(big.Int).Exp(gPrime, n, nSquare)
	g.Exp(g, big.NewInt(2), nSquare)
	if check := new(big.Int).ModInverse(g, nSquare); check == nil {
		return nil, fmt.Errorf("parameters generation failed," +
			"unexpected event of generator g is not invertible")
	}
	nTo5 := new(big.Int).Exp(n, big.NewInt(5), nil)
	sigma := new(big.Float).SetInt(nTo5)
	sigma.Mul(sigma, big.NewFloat(float64(lambda)))
	sigma.Sqrt(sigma)
	sigma.Add(sigma, big.NewFloat(2))
	lSigmaF := new(big.Float).Quo(sigma, sample.SigmaCDT)
	lSigma, _ := lSigmaF.Int(nil)
	lSigma.Add(lSigma, big.NewInt(1))
	sigma.Mul(sample.SigmaCDT, lSigmaF)
	return &Paillier{
		Params: &PaillierParams{
			L:       l,
			N:       n,
			NSquare: nSquare,
			BoundX:  boundX,
			BoundY:  boundY,
			Sigma:   sigma,
			LSigma:  lSigma,
			Lambda:  lambda,
			G:       g,
		},
	}, nil
}
func NewPaillierFromParams(params *PaillierParams) *Paillier {
	return &Paillier{
		Params: params,
	}
}
func (s *Paillier) GenerateMasterKeys() (data.Vector, data.Vector, error) {
	sampler := sample.NewNormalDoubleConstant(s.Params.LSigma)
	secKey, err := data.NewRandomVector(s.Params.L, sampler)
	if err != nil {
		return nil, nil, err
	}
	pubKey := secKey.Apply(func(x *big.Int) *big.Int {
		return internal.ModExp(s.Params.G, x, s.Params.NSquare)
	})
	return secKey, pubKey, nil
}