From ad44ab64cbe194708c9e6b6cfe704693b809a8e1 Mon Sep 17 00:00:00 2001 From: Piotr Dyraga Date: Fri, 25 May 2018 12:28:02 +0200 Subject: [PATCH] Added documentation to the threshold Paillier key generator --- thresholdkey_generator.go | 49 +++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/thresholdkey_generator.go b/thresholdkey_generator.go index 9ecc895..0451674 100644 --- a/thresholdkey_generator.go +++ b/thresholdkey_generator.go @@ -6,21 +6,32 @@ import ( "math/big" ) +// Generates a threshold Paillier key with an algorithm based on [DJN 10], +// section 5.1, "Key generation". +// +// Bear in mind that the algorithm assumes an existence of a trusted dealer +// to generate and distribute the keys. +// +// +// [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 ThresholdKeyGenerator struct { nbits int TotalNumberOfDecryptionServers int Threshold int Random io.Reader - //Both p1 and q1 are primes of length nbits - 1 + // Both p1 and q1 are primes of length nbits - 1 p1 *big.Int q1 *big.Int - p *big.Int //p is prime and p=2*p1+1 - q *big.Int //q is prime and q=2*q1+1 + p *big.Int // p is prime and p=2*p1+1 + q *big.Int // q is prime and q=2*q1+1 n *big.Int // n=p*q - m *big.Int //m = p1*q1 - nSquare *big.Int //nSquare = n*n + m *big.Int // m = p1*q1 + nSquare *big.Int // nSquare = n*n nm *big.Int // nm = n*m // As specified in the paper, d must satify d=1 mod n and d=0 mod m @@ -29,13 +40,14 @@ type ThresholdKeyGenerator struct { // A generator of QR in Z_{n^2} v *big.Int - // the polynomial coefficients to hide a secret. See Shamir. + // The polynomial coefficients to hide a secret. See Shamir. polynomialCoefficients []*big.Int } -// preferable way to counstruct the ThresholdKeyGenerator. No verification -// is done on the input values. You need to bu sure that nbits is big enough -// and that Threshold > TotalNumberOfDecryptionServers / 2 +// Preferable way to construct the ThresholdKeyGenerator. No verification +// is done on the input values. You need to be sure that nbits is big enough +// and that Threshold > TotalNumberOfDecryptionServers / 2. +// The plaintext space for the key will be Z_n. func GetThresholdKeyGenerator(nbits, TotalNumberOfDecryptionServers, Threshold int, random io.Reader) *ThresholdKeyGenerator { ret := new(ThresholdKeyGenerator) ret.nbits = nbits @@ -95,6 +107,7 @@ func (this *ThresholdKeyGenerator) InitPsAndQs() error { return nil } +// v generates a cyclic group of squares in Zn^2. func (this *ThresholdKeyGenerator) ComputeV() error { var err error this.v, err = GetRandomGeneratorOfTheQuadraticResidue(this.nSquare, this.Random) @@ -102,7 +115,6 @@ func (this *ThresholdKeyGenerator) ComputeV() error { } // Choose d such that d=0 (mod m) and d=1 (mod n). -// See [DJN 10], section 5.1, "Key generation" // // From Chinese Remainder Theorem: // x = a1 (mod n1) @@ -140,6 +152,12 @@ func (this *ThresholdKeyGenerator) InitNumerialValues() error { return this.ComputeV() } +// f(X) = a_0 X^0 + a_1 X^1 + ... + a_(w-1) X^(w-1) +// +// where: +// `w` - threshold +// `a_i` - random value from {0, ... nm - 1} for 0