Files
xgcl/he/paillier/paillier_op.go
T
2026-05-27 23:03:00 +08:00

47 lines
1.3 KiB
Go

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
}