func generateRelativelyPrimeInt(n *big.Int) (*big.Int, error) {
	for {
		randR, err := rand.Int(rand.Reader, n)
		if err != nil {
			return nil, err
		}
		x, y, z := new(big.Int), new(big.Int), new(big.Int)
		z.GCD(x, y, n, randR)
		if z.Cmp(one) == 0 {
			return randR, nil
		}
	}
}
Generates an Int that is relatively prime with the input Int. Relative primeness is defined by gcd(r, n) = 1.
So we enter an infinite loop to generate r's until this is true. It is very unlikely that we will ever iterate
through this loop more than once since our search space is so large.
package gaillier
import (
	"crypto/rand"
	"errors"
	"io"
	"math/big"
)
var ErrLongMessage = errors.New("message should be smaller than choosen public key size")
var one = big.NewInt(1)
type PubKey struct {
	Len int
	N   *big.Int  
	G   *big.Int  
	Nsq *big.Int  
}
type PrivKey struct {
	Len int
	PubKey
	L *big.Int  
	U *big.Int  
}
func GenerateKeyPair(random io.Reader, bits int) (*PubKey, *PrivKey, error) {
	p, err := rand.Prime(random, bits/2)
	if err != nil {
		return nil, nil, err
	}
	q, err := rand.Prime(random, bits/2)
	if err != nil {
		return nil, nil, err
	}
	n := new(big.Int).Mul(p, q)
	nSquared := new(big.Int).Mul(n, n)
	g := new(big.Int).Add(n, one)
	pMin := new(big.Int).Sub(p, one)
	qMin := new(big.Int).Sub(q, one)
	l := new(big.Int).Mul(pMin, qMin)
	u := new(big.Int).ModInverse(l, n)
	pub := &PubKey{Len: bits, N: n, Nsq: nSquared, G: g}
	return pub, &PrivKey{PubKey: *pub, Len: bits, L: l, U: u}, nil
}
func Encrypt(pubkey *PubKey, message []byte) ([]byte, error) {
	r, err := generateRelativelyPrimeInt(pubkey.N)
	if err != nil {
		return nil, err
	}
	m := new(big.Int).SetBytes(message)
	if pubkey.N.Cmp(m) < 1 {
		return nil, ErrLongMessage
	}
	gm := new(big.Int).Exp(pubkey.G, m, pubkey.Nsq)
	rn := new(big.Int).Exp(r, pubkey.N, pubkey.Nsq)
	prod := new(big.Int).Mul(gm, rn)
	c := new(big.Int).Mod(prod, pubkey.Nsq)
	return c.Bytes(), nil
}
func Decrypt(privkey *PrivKey, cipher []byte) ([]byte, error) {
	c := new(big.Int).SetBytes(cipher)
	if privkey.Nsq.Cmp(c) < 1 {
		return nil, ErrLongMessage
	}
	a := new(big.Int).Exp(c, privkey.L, privkey.Nsq)
	l := new(big.Int).Div(new(big.Int).Sub(a, one), privkey.N)
	m := new(big.Int).Mod(new(big.Int).Mul(l, privkey.U), privkey.N)
	return m.Bytes(), nil
}
func Add(pubkey *PubKey, c1, c2 []byte) []byte {
	a := new(big.Int).SetBytes(c1)
	b := new(big.Int).SetBytes(c2)
	res := new(big.Int).Mod(new(big.Int).Mul(a, b), pubkey.Nsq)
	return res.Bytes()
}
func AddConstant(pubkey *PubKey, cipher, constant []byte) []byte {
	c := new(big.Int).SetBytes(cipher)
	k := new(big.Int).SetBytes(constant)
	res := new(big.Int).Mod(
		new(big.Int).Mul(c, new(big.Int).Exp(pubkey.G, k, pubkey.Nsq)), pubkey.Nsq)
	return res.Bytes()
}
func Mul(pubkey *PubKey, cipher, constant []byte) []byte {
	c := new(big.Int).SetBytes(cipher)
	k := new(big.Int).SetBytes(constant)
	res := new(big.Int).Exp(c, k, pubkey.Nsq)
	return res.Bytes()
}