package paillier import ( "math/big" "xdx.jelly/xgcl/gmath" ) // HomomorphicAdd set c = Enc(m1+m2) where c1 = Enc(m1) and c2 = Enc(m2) func (c *Cipher) HomomorphicAdd(c1 *Cipher, c2 *Cipher, pk *PublicKey) *Cipher { if c.D == nil { c.D = new(big.Int) } c.D.Mul(c1.D, c2.D) c.D.Mod(c.D, pk.N2) return c } // HomomorphicAddInt set c = Enc(m1 + m) where c1 = Enc(m1) and m < N. // // Becareful, if the adversary knows c1, c, and m(or m1), then he can computes m1(or m). // So, using HomomorphicAddInt if you know what you're doing, // otherwise, you should use like this: // c2, err := pk.Encrypt(m, rnd) // c.HomomorphicAdd(c1, c2, pk) func (c *Cipher) HomomorphicAddInt(c1 *Cipher, m *big.Int, pk *PublicKey) *Cipher { d := new(big.Int) c.D = d.Mul(pk.N, m).Add(d, gmath.BigInt1).Mod(d, pk.N2).Mul(d, c1.D).Mod(d, pk.N2) return c } // HomomorphicScalarMul if c1 = Enc(a), then HomomorphicScalarMul computes c = Enc(ka) // if ka < n^2. func (c *Cipher) HomomorphicScalarMul(a *Cipher, k *big.Int, pk *PublicKey) *Cipher { if c.D == nil { c.D = new(big.Int) } c.D.Exp(a.D, k, pk.N2) return c } // Neg negates the plaintext mod n, i.e., if c = Enc(m), then c.Neg() = Enc(n-m). func (c *Cipher) Neg(pk *PublicKey) *Cipher { c.D.ModInverse(c.D, pk.N2) return c }