https://github.com/yacovm/ZKAT-VDP
Tip revision: 721f52b1b74f8e0aa60799bd1436865f8020258e authored by yacovm on 14 August 2023, 13:43:45 UTC
Create README.md
Create README.md
Tip revision: 721f52b
elgamal.go
package elgamal
import (
"crypto/rand"
"golang.org/x/crypto/blake2b"
"io"
"math/big"
"github.com/consensys/gnark-crypto/ecc/bn254/fr"
"github.com/consensys/gnark-crypto/ecc/bn254/twistededwards"
)
const (
sizeFr = fr.Bytes
//sizePublicKey = sizeFr
//sizeSignature = 2 * sizeFr
//sizePrivateKey = 2*sizeFr + 32
)
var MessageMap = make(map[twistededwards.PointAffine]big.Int)
// PublicKey eddsa signature object
// cf https://en.wikipedia.org/wiki/EdDSA for notation
type PublicKey struct {
A twistededwards.PointAffine
}
// PrivateKey private key of an eddsa instance
type PrivateKey struct {
PublicKey PublicKey // copy of the associated public key
scalar [sizeFr]byte // secret scalar, in big Endian
randSrc [32]byte // source
}
func MessageMapInit() {
c := twistededwards.GetEdwardsCurve()
for i := 1; i < 100; i++ {
P := &twistededwards.PointAffine{}
P.ScalarMul(&c.Base, big.NewInt(int64(i)))
MessageMap[*P] = *big.NewInt(int64(i))
}
}
// GenerateKey generates a public and private key pair.
func GenerateKey(r io.Reader) (*PrivateKey, error) {
c := twistededwards.GetEdwardsCurve()
var pub PublicKey
var priv PrivateKey
// hash(h) = private_key || random_source, on 32 bytes each
seed := make([]byte, 32)
_, err := r.Read(seed)
if err != nil {
return nil, err
}
h := blake2b.Sum512(seed[:])
for i := 0; i < 32; i++ {
priv.randSrc[i] = h[i+32]
}
// prune the key
// https://tools.ietf.org/html/rfc8032#section-5.1.5, key generation
h[0] &= 0xF8
h[31] &= 0x7F
h[31] |= 0x40
// reverse first bytes because setBytes interpret stream as big endian
// but in eddsa specs s is the first 32 bytes in little endian
for i, j := 0, sizeFr-1; i < sizeFr; i, j = i+1, j-1 {
priv.scalar[i] = h[j]
}
var bScalar big.Int
bScalar.SetBytes(priv.scalar[:])
pub.A.ScalarMul(&c.Base, &bScalar)
priv.PublicKey = pub
return &priv, nil
}
// GenScalar returns a random scalar <= p.Order
func GenScalar(order *big.Int) *big.Int {
r, _ := rand.Int(rand.Reader, order)
return r
}
// Encrypt encrypts a message based on elgamal encryption.
// pubkey is Alice's public key used for encrypting the message. r is random scalar Bob generates.
func Encrypt(pubkey PublicKey, r *big.Int, msg *big.Int) (K, Ciph twistededwards.PointAffine) {
curve := twistededwards.GetEdwardsCurve()
var M, S twistededwards.PointAffine
//msgBig := big.NewInt(int64(message))
M.ScalarMul(&curve.Base, msg)
// ElGamal-encrypt the point to produce ciphertext (K,C).
K.ScalarMul(&curve.Base, r) // K = r * Base - Public key
S.ScalarMul(&pubkey.A, r) // S = k*A
Ciph.Add(&S, &M) // C = S + M
return
}
// Decrypt decrypts cipher C using Alice's private key prive, and Bob's value K
func Decrypt(priv PrivateKey, K, C twistededwards.PointAffine) (msg big.Int) {
var M, S twistededwards.PointAffine
var bScalar big.Int
bScalar.SetBytes(priv.scalar[:])
// ElGamal-decrypt the ciphertext (K,C) to reproduce the message.
S.ScalarMul(&K, &bScalar)
S.Neg(&S)
M.Add(&C, &S)
msg = MessageMap[M]
return
}
