Added documentation to the threshold Paillier key generator
This commit is contained in:
1 file changed
+39
-10
+39
-10
@@ -6,21 +6,32 @@ import (
|
|||||||
"math/big"
|
"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 {
|
type ThresholdKeyGenerator struct {
|
||||||
nbits int
|
nbits int
|
||||||
TotalNumberOfDecryptionServers int
|
TotalNumberOfDecryptionServers int
|
||||||
Threshold int
|
Threshold int
|
||||||
Random io.Reader
|
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
|
p1 *big.Int
|
||||||
q1 *big.Int
|
q1 *big.Int
|
||||||
|
|
||||||
p *big.Int //p is prime and p=2*p1+1
|
p *big.Int // p is prime and p=2*p1+1
|
||||||
q *big.Int //q is prime and q=2*q1+1
|
q *big.Int // q is prime and q=2*q1+1
|
||||||
n *big.Int // n=p*q
|
n *big.Int // n=p*q
|
||||||
m *big.Int //m = p1*q1
|
m *big.Int // m = p1*q1
|
||||||
nSquare *big.Int //nSquare = n*n
|
nSquare *big.Int // nSquare = n*n
|
||||||
nm *big.Int // nm = n*m
|
nm *big.Int // nm = n*m
|
||||||
|
|
||||||
// As specified in the paper, d must satify d=1 mod n and d=0 mod 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}
|
// A generator of QR in Z_{n^2}
|
||||||
v *big.Int
|
v *big.Int
|
||||||
|
|
||||||
// the polynomial coefficients to hide a secret. See Shamir.
|
// The polynomial coefficients to hide a secret. See Shamir.
|
||||||
polynomialCoefficients []*big.Int
|
polynomialCoefficients []*big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
// preferable way to counstruct the ThresholdKeyGenerator. No verification
|
// Preferable way to construct the ThresholdKeyGenerator. No verification
|
||||||
// is done on the input values. You need to bu sure that nbits is big enough
|
// is done on the input values. You need to be sure that nbits is big enough
|
||||||
// and that Threshold > TotalNumberOfDecryptionServers / 2
|
// 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 {
|
func GetThresholdKeyGenerator(nbits, TotalNumberOfDecryptionServers, Threshold int, random io.Reader) *ThresholdKeyGenerator {
|
||||||
ret := new(ThresholdKeyGenerator)
|
ret := new(ThresholdKeyGenerator)
|
||||||
ret.nbits = nbits
|
ret.nbits = nbits
|
||||||
@@ -95,6 +107,7 @@ func (this *ThresholdKeyGenerator) InitPsAndQs() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// v generates a cyclic group of squares in Zn^2.
|
||||||
func (this *ThresholdKeyGenerator) ComputeV() error {
|
func (this *ThresholdKeyGenerator) ComputeV() error {
|
||||||
var err error
|
var err error
|
||||||
this.v, err = GetRandomGeneratorOfTheQuadraticResidue(this.nSquare, this.Random)
|
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).
|
// 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:
|
// From Chinese Remainder Theorem:
|
||||||
// x = a1 (mod n1)
|
// x = a1 (mod n1)
|
||||||
@@ -140,6 +152,12 @@ func (this *ThresholdKeyGenerator) InitNumerialValues() error {
|
|||||||
return this.ComputeV()
|
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<i<w
|
||||||
|
// `a_0` is always equal `d`
|
||||||
func (this *ThresholdKeyGenerator) GenerateHidingPolynomial() error {
|
func (this *ThresholdKeyGenerator) GenerateHidingPolynomial() error {
|
||||||
this.polynomialCoefficients = make([]*big.Int, this.Threshold)
|
this.polynomialCoefficients = make([]*big.Int, this.Threshold)
|
||||||
this.polynomialCoefficients[0] = this.d
|
this.polynomialCoefficients[0] = this.d
|
||||||
@@ -153,6 +171,8 @@ func (this *ThresholdKeyGenerator) GenerateHidingPolynomial() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The secred share of the i'th authority is `f(i)`, where `f` is
|
||||||
|
// the polynomial we generated in `GenerateHidingPolynomial` function.
|
||||||
func (this *ThresholdKeyGenerator) ComputeShare(index int) *big.Int {
|
func (this *ThresholdKeyGenerator) ComputeShare(index int) *big.Int {
|
||||||
share := big.NewInt(0)
|
share := big.NewInt(0)
|
||||||
for i := 0; i < this.Threshold; i++ {
|
for i := 0; i < this.Threshold; i++ {
|
||||||
@@ -176,6 +196,15 @@ func (this *ThresholdKeyGenerator) Delta() *big.Int {
|
|||||||
return Factorial(this.TotalNumberOfDecryptionServers)
|
return Factorial(this.TotalNumberOfDecryptionServers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generates verification keys for actions of decryption servers.
|
||||||
|
//
|
||||||
|
// For each decryption server `i`, we generate
|
||||||
|
// v_i = v^(l! s_i) mod n^2
|
||||||
|
//
|
||||||
|
// where:
|
||||||
|
// `l` is the number of decryption servers
|
||||||
|
// `s_i` is a secret share for server `i`.
|
||||||
|
// Secret shares were previously generated in the `CrateShares` function.
|
||||||
func (this *ThresholdKeyGenerator) CreateViArray(shares []*big.Int) (viArray []*big.Int) {
|
func (this *ThresholdKeyGenerator) CreateViArray(shares []*big.Int) (viArray []*big.Int) {
|
||||||
viArray = make([]*big.Int, len(shares))
|
viArray = make([]*big.Int, len(shares))
|
||||||
delta := this.Delta()
|
delta := this.Delta()
|
||||||
|
|||||||
Reference in new issue
Block a user