mirror of
https://github.com/luxfi/threshold.git
synced 2026-10-30 15:15:53 +00:00
81 lines
1.5 KiB
Go
81 lines
1.5 KiB
Go
package elgamal
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"io"
|
|
|
|
"github.com/luxfi/threshold/pkg/math/curve"
|
|
"github.com/luxfi/threshold/pkg/math/sample"
|
|
)
|
|
|
|
type (
|
|
PublicKey = curve.Point
|
|
Nonce = curve.Scalar
|
|
)
|
|
|
|
type Ciphertext struct {
|
|
// L = nonce⋅G
|
|
L curve.Point
|
|
// M = message⋅G + nonce⋅public
|
|
M curve.Point
|
|
}
|
|
|
|
// Encrypt returns the encryption of `message` as (L=nonce⋅G, M=message⋅G + nonce⋅public), as well as the `nonce`.
|
|
func Encrypt(public PublicKey, message curve.Scalar) (*Ciphertext, Nonce) {
|
|
group := public.Curve()
|
|
nonce := sample.Scalar(rand.Reader, group)
|
|
L := nonce.ActOnBase()
|
|
M := message.ActOnBase().Add(nonce.Act(public))
|
|
return &Ciphertext{
|
|
L: L,
|
|
M: M,
|
|
}, nonce
|
|
}
|
|
|
|
// Valid returns true if the ciphertext passes basic validation.
|
|
func (c *Ciphertext) Valid() bool {
|
|
if c == nil || c.L == nil || c.L.IsIdentity() ||
|
|
c.M == nil || c.M.IsIdentity() {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func Empty(group curve.Curve) *Ciphertext {
|
|
return &Ciphertext{
|
|
L: group.NewPoint(),
|
|
M: group.NewPoint(),
|
|
}
|
|
}
|
|
|
|
func (c *Ciphertext) WriteTo(w io.Writer) (int64, error) {
|
|
var total int64
|
|
var n int
|
|
|
|
buf, err := c.L.MarshalBinary()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
n, err = w.Write(buf)
|
|
total += int64(n)
|
|
if err != nil {
|
|
return total, err
|
|
}
|
|
|
|
buf, err = c.M.MarshalBinary()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
n, err = w.Write(buf)
|
|
total += int64(n)
|
|
if err != nil {
|
|
return total, err
|
|
}
|
|
|
|
return total, nil
|
|
}
|
|
|
|
func (Ciphertext) Domain() string {
|
|
return "ElGamal Ciphertext"
|
|
}
|