47 lines
1.3 KiB
Go
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
|
|
}
|