init: v1.0.0
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
package elgamal
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"io"
|
||||
"math/big"
|
||||
|
||||
"xdx.jelly/xgcl/grand"
|
||||
)
|
||||
|
||||
var Reader = grand.Reader
|
||||
|
||||
type Params struct {
|
||||
isMont bool // Is Montgomery represent
|
||||
p *big.Int
|
||||
q *big.Int
|
||||
g *big.Int
|
||||
pMont *big.Int
|
||||
qMont *big.Int
|
||||
gMont *big.Int
|
||||
}
|
||||
|
||||
func (p *Params) P() *big.Int {
|
||||
return p.p
|
||||
}
|
||||
func (p *Params) Q() *big.Int {
|
||||
return p.q
|
||||
}
|
||||
func (p *Params) G() *big.Int {
|
||||
return p.g
|
||||
}
|
||||
|
||||
type PublicKey struct {
|
||||
y big.Int
|
||||
Params *Params
|
||||
}
|
||||
|
||||
type PrivateKey struct {
|
||||
x big.Int
|
||||
PublicKey
|
||||
}
|
||||
type Cipher struct {
|
||||
u big.Int
|
||||
v big.Int
|
||||
}
|
||||
|
||||
func GenerateKey(rnd io.Reader, params *Params) (*PrivateKey, *PublicKey, error) {
|
||||
x, err := rand.Int(rnd, params.q)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
y := new(big.Int).Exp(params.g, x, params.p)
|
||||
sk := &PrivateKey{
|
||||
x: *x,
|
||||
PublicKey: PublicKey{
|
||||
y: *y,
|
||||
Params: P1024,
|
||||
},
|
||||
}
|
||||
pk := &sk.PublicKey
|
||||
return sk, pk, nil
|
||||
}
|
||||
|
||||
// m = g^M mod p for some M
|
||||
// rnd can be nil, io.Reader or []byte
|
||||
func (pk *PublicKey) Encryption(m *big.Int, rnd any) (*Cipher, error) {
|
||||
var r *big.Int
|
||||
var err error
|
||||
p := pk.Params.p
|
||||
q := pk.Params.q
|
||||
g := pk.Params.g
|
||||
|
||||
switch rnd := rnd.(type) {
|
||||
case nil:
|
||||
rnd = Reader
|
||||
case io.Reader:
|
||||
r, err = rand.Int(rnd, q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case []byte:
|
||||
r = new(big.Int).SetBytes(rnd)
|
||||
if r.Cmp(q) >= 0 {
|
||||
return nil, errors.New("random bytes too large")
|
||||
}
|
||||
default:
|
||||
return nil, errors.New("rnd must be io.Reader or []bytes")
|
||||
}
|
||||
|
||||
c := &Cipher{}
|
||||
c.u.Exp(g, r, p)
|
||||
c.v.Exp(&pk.y, r, p)
|
||||
c.v.Mul(&c.v, m)
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (sk *PrivateKey) Decryption(c *Cipher) (*big.Int, error) {
|
||||
p := sk.PublicKey.Params.p
|
||||
u := &c.u
|
||||
v := &c.v
|
||||
z := new(big.Int)
|
||||
z.Exp(u, &sk.x, p)
|
||||
z.ModInverse(z, p)
|
||||
z.Mul(z, v)
|
||||
z.Mod(z, p)
|
||||
return z, nil
|
||||
}
|
||||
|
||||
func (c *Cipher) HomoMap(c1 *Cipher, c2 *Cipher) (*Cipher, error) {
|
||||
c.u.Mul(&c1.u, &c2.u)
|
||||
c.v.Mul(&c1.v, &c2.v)
|
||||
return c, nil
|
||||
}
|
||||
Reference in New Issue
Block a user