mirror of
https://github.com/luxfi/threshold.git
synced 2026-10-30 15:15:53 +00:00
96 lines
3.4 KiB
Go
96 lines
3.4 KiB
Go
package mta
|
|
|
|
import (
|
|
"crypto/rand"
|
|
|
|
"github.com/cronokirby/saferith"
|
|
"github.com/luxfi/threshold/pkg/hash"
|
|
"github.com/luxfi/threshold/pkg/math/curve"
|
|
"github.com/luxfi/threshold/pkg/math/sample"
|
|
"github.com/luxfi/threshold/pkg/paillier"
|
|
"github.com/luxfi/threshold/pkg/pedersen"
|
|
zkaffg "github.com/luxfi/threshold/pkg/zk/affg"
|
|
zkaffp "github.com/luxfi/threshold/pkg/zk/affp"
|
|
)
|
|
|
|
// ProveAffG returns the necessary messages for the receiver of the
|
|
// h is a hash function initialized with the sender's ID.
|
|
// - senderSecretShare = aᵢ
|
|
// - senderSecretSharePoint = Aᵢ = aᵢ⋅G
|
|
// - receiverEncryptedShare = Encⱼ(bⱼ)
|
|
// The elements returned are :
|
|
// - Beta = β
|
|
// - D = (aⱼ ⊙ Bᵢ) ⊕ encᵢ(- β, s)
|
|
// - F = encⱼ(-β, r)
|
|
// - Proof = zkaffg proof of correct encryption.
|
|
func ProveAffG(group curve.Curve, h *hash.Hash,
|
|
senderSecretShare *saferith.Int, senderSecretSharePoint curve.Point, receiverEncryptedShare *paillier.Ciphertext,
|
|
sender *paillier.SecretKey, receiver *paillier.PublicKey, verifier *pedersen.Parameters) (Beta *saferith.Int, D, F *paillier.Ciphertext, Proof *zkaffg.Proof) {
|
|
D, F, S, R, BetaNeg := newMta(senderSecretShare, receiverEncryptedShare, sender, receiver)
|
|
Proof = zkaffg.NewProof(group, h, zkaffg.Public{
|
|
Kv: receiverEncryptedShare,
|
|
Dv: D,
|
|
Fp: F,
|
|
Xp: senderSecretSharePoint,
|
|
Prover: sender.PublicKey,
|
|
Verifier: receiver,
|
|
Aux: verifier,
|
|
}, zkaffg.Private{
|
|
X: senderSecretShare,
|
|
Y: BetaNeg,
|
|
S: S,
|
|
R: R,
|
|
})
|
|
Beta = BetaNeg.Neg(1)
|
|
return
|
|
}
|
|
|
|
// ProveAffP generates a proof for the a specified verifier.
|
|
// This function is specified as to make clear which parameters must be input to zkaffg.
|
|
// h is a hash function initialized with the sender's ID.
|
|
// - senderSecretShare = aᵢ
|
|
// - senderSecretSharePoint = Aᵢ = Encᵢ(aᵢ)
|
|
// - receiverEncryptedShare = Encⱼ(bⱼ)
|
|
// The elements returned are :
|
|
// - Beta = β
|
|
// - D = (aⱼ ⊙ Bᵢ) ⊕ encᵢ(-β, s)
|
|
// - F = encⱼ(-β, r)
|
|
// - Proof = zkaffp proof of correct encryption.
|
|
func ProveAffP(group curve.Curve, h *hash.Hash,
|
|
senderSecretShare *saferith.Int, senderEncryptedShare *paillier.Ciphertext, senderEncryptedShareNonce *saferith.Nat,
|
|
receiverEncryptedShare *paillier.Ciphertext,
|
|
sender *paillier.SecretKey, receiver *paillier.PublicKey, verifier *pedersen.Parameters) (Beta *saferith.Int, D, F *paillier.Ciphertext, Proof *zkaffp.Proof) {
|
|
D, F, S, R, BetaNeg := newMta(senderSecretShare, receiverEncryptedShare, sender, receiver)
|
|
Proof = zkaffp.NewProof(group, h, zkaffp.Public{
|
|
Kv: receiverEncryptedShare,
|
|
Dv: D,
|
|
Fp: F,
|
|
Xp: senderEncryptedShare,
|
|
Prover: sender.PublicKey,
|
|
Verifier: receiver,
|
|
Aux: verifier,
|
|
}, zkaffp.Private{
|
|
X: senderSecretShare,
|
|
Y: BetaNeg,
|
|
S: S,
|
|
Rx: senderEncryptedShareNonce,
|
|
R: R,
|
|
})
|
|
Beta = BetaNeg.Neg(1)
|
|
|
|
return
|
|
}
|
|
|
|
func newMta(senderSecretShare *saferith.Int, receiverEncryptedShare *paillier.Ciphertext,
|
|
sender *paillier.SecretKey, receiver *paillier.PublicKey) (D, F *paillier.Ciphertext, S, R *saferith.Nat, BetaNeg *saferith.Int) {
|
|
BetaNeg = sample.IntervalLPrime(rand.Reader)
|
|
|
|
F, R = sender.Enc(BetaNeg) // F = encᵢ(-β, r)
|
|
|
|
D, S = receiver.Enc(BetaNeg)
|
|
tmp := receiverEncryptedShare.Clone().Mul(receiver, senderSecretShare) // tmp = aᵢ ⊙ Bⱼ
|
|
D.Add(receiver, tmp) // D = encⱼ(-β;s) ⊕ (aᵢ ⊙ Bⱼ) = encⱼ(aᵢ•bⱼ-β)
|
|
|
|
return
|
|
}
|