Documentation improvements, code cleaned up #2
+38
-4
@@ -8,6 +8,20 @@ import (
|
||||
"math/big"
|
||||
)
|
||||
|
||||
// Public key for a threshold Paillier scheme.
|
||||
//
|
||||
// `V` is a generator in the cyclic group of squares Z_n^2 and is used to
|
||||
// execute a zero-knowledge proof of a received share decryption.
|
||||
//
|
||||
// `Vi` is an array of verification keys for each decryption server `i`.
|
||||
//
|
||||
// Key generation, encryption, share decryption and combining for the threshold
|
||||
// Paillier scheme has been described in [DJN 10], section 5.1.
|
||||
//
|
||||
// [DJN 10]: Ivan Damgard, Mads Jurik, Jesper Buus Nielsen, (2010)
|
||||
// A Generalization of Paillier’s Public-Key System
|
||||
// with Applications to Electronic Voting
|
||||
// Aarhus University, Dept. of Computer Science, BRICS
|
||||
type ThresholdKey struct {
|
||||
PublicKey
|
||||
TotalNumberOfDecryptionServers int
|
||||
@@ -16,17 +30,23 @@ type ThresholdKey struct {
|
||||
Vi []*big.Int
|
||||
}
|
||||
|
||||
// returns the value of (4*delta**2)** -1 mod n
|
||||
// Returns the value of [(4*delta^2)]^-1 mod n.
|
||||
// It is a constant value for the given `ThresholdKey` and is used in the last
|
||||
// step of share combining.
|
||||
func (this *ThresholdKey) combineSharesConstant() *big.Int {
|
||||
tmp := new(big.Int).Mul(FOUR, new(big.Int).Mul(this.delta(), this.delta()))
|
||||
return (&big.Int{}).ModInverse(tmp, this.N)
|
||||
}
|
||||
|
||||
// returns the factorial of the number of TotalNumberOfDecryptionServers
|
||||
// Returns the factorial of the number of `TotalNumberOfDecryptionServers`.
|
||||
// It is a contant value for the given `ThresholdKey`.
|
||||
func (this *ThresholdKey) delta() *big.Int {
|
||||
return Factorial(this.TotalNumberOfDecryptionServers)
|
||||
}
|
||||
|
||||
// Checks if the number of received, unique shares is less than the
|
||||
// required threshold.
|
||||
// This method does not execute ZKP on received shares.
|
||||
func (this *ThresholdKey) makeVerificationBeforeCombiningPartialDecryptions(shares []*PartialDecryption) error {
|
||||
if len(shares) < this.Threshold {
|
||||
return errors.New("Threshold not meet")
|
||||
@@ -47,6 +67,8 @@ func (this *ThresholdKey) updateLambda(share1, share2 *PartialDecryption, lambda
|
||||
return new(big.Int).Div(num, denom)
|
||||
}
|
||||
|
||||
// Evaluates lambda parameter for each decrypted share. See second figure in the
|
||||
// "Share combining" paragraph in [DJK 10], section 5.2.
|
||||
func (this *ThresholdKey) computeLambda(share *PartialDecryption, shares []*PartialDecryption) *big.Int {
|
||||
lambda := this.delta()
|
||||
for _, share2 := range shares {
|
||||
@@ -64,6 +86,7 @@ func (this *ThresholdKey) updateCprime(cprime, lambda *big.Int, share *PartialDe
|
||||
return new(big.Int).Mod(ret, this.GetNSquare())
|
||||
}
|
||||
|
||||
// TODO: unused? kill?
|
||||
func (this *ThresholdKey) divide(a, b *big.Int) *big.Int {
|
||||
if a.Cmp(ZERO) == -1 {
|
||||
if b.Cmp(ZERO) == -1 {
|
||||
@@ -83,11 +106,18 @@ func (this *ThresholdKey) exp(a, b, c *big.Int) *big.Int {
|
||||
|
||||
}
|
||||
|
||||
// Executes the last step of message decryption. Takes `cprime` value computed
|
||||
// from valid shares provided by decryption servers and multiplies this value
|
||||
// by `combineSharesContant` which is specific to the given public `ThresholdKey`.
|
||||
func (this *ThresholdKey) computeDecryption(cprime *big.Int) *big.Int {
|
||||
l := L(cprime, this.N)
|
||||
return new(big.Int).Mod(new(big.Int).Mul(this.combineSharesConstant(), l), this.N)
|
||||
}
|
||||
|
||||
// Combines partial decryptions provided by decryption servers and returns
|
||||
// decrypted message.
|
||||
// This function does not verify zero knowledge proofs. Returned message can be
|
||||
// incorrectly decrypted if an adversary corrupted partial decryption.
|
||||
func (this *ThresholdKey) CombinePartialDecryptions(shares []*PartialDecryption) (*big.Int, error) {
|
||||
if err := this.makeVerificationBeforeCombiningPartialDecryptions(shares); err != nil {
|
||||
return nil, err
|
||||
@@ -102,6 +132,10 @@ func (this *ThresholdKey) CombinePartialDecryptions(shares []*PartialDecryption)
|
||||
return this.computeDecryption(cprime), nil
|
||||
}
|
||||
|
||||
// Combines partial decryptions provided by decription servers and returns
|
||||
// decrypted message.
|
||||
// Function verifies zero knowledge proofs and filters out all shares that failed
|
||||
// verification.
|
||||
func (this *ThresholdKey) CombinePartialDecryptionsZKP(shares []*PartialDecryptionZKP) (*big.Int, error) {
|
||||
ret := make([]*PartialDecryption, 0)
|
||||
for _, share := range shares {
|
||||
@@ -157,7 +191,7 @@ func (this *ThresholdPrivateKey) copyVi() []*big.Int {
|
||||
return ret
|
||||
}
|
||||
|
||||
func (this *ThresholdPrivateKey) GetThresholdKey() *ThresholdKey {
|
||||
func (this *ThresholdPrivateKey) getThresholdKey() *ThresholdKey {
|
||||
ret := new(ThresholdKey)
|
||||
ret.Threshold = this.Threshold
|
||||
ret.TotalNumberOfDecryptionServers = this.TotalNumberOfDecryptionServers
|
||||
@@ -184,7 +218,7 @@ func (this *ThresholdPrivateKey) computeHash(a, b, c4, ci2 *big.Int) *big.Int {
|
||||
|
||||
func (this *ThresholdPrivateKey) DecryptAndProduceZNP(c *big.Int, random io.Reader) (*PartialDecryptionZKP, error) {
|
||||
pd := new(PartialDecryptionZKP)
|
||||
pd.Key = this.GetThresholdKey()
|
||||
pd.Key = this.getThresholdKey()
|
||||
pd.C = c
|
||||
pd.Id = this.Id
|
||||
pd.Decryption = this.Decrypt(c).Decryption
|
||||
|
||||
Reference in new issue
Block a user