imported from https://bitbucket.org/ustraca/crypto
This commit is contained in:
1 parent
ca20730438
commit
8a9743f08e
11 files changed
+1805
No files matched your search
@@ -0,0 +1,200 @@
|
||||
package paillier
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"math/big"
|
||||
|
||||
"bitbucket.org/ustraca/crypto"
|
||||
)
|
||||
|
||||
type ThresholdKeyGenerator struct {
|
||||
nbits int
|
||||
TotalNumberOfDecryptionServers int
|
||||
Threshold int
|
||||
Random io.Reader
|
||||
|
||||
//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
|
||||
n *big.Int // n=p*q
|
||||
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
|
||||
d *big.Int
|
||||
|
||||
// A generator of QR in Z_{n^2}
|
||||
v *big.Int
|
||||
|
||||
// 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
|
||||
func GetThresholdKeyGenerator(nbits, TotalNumberOfDecryptionServers, Threshold int, random io.Reader) *ThresholdKeyGenerator {
|
||||
ret := new(ThresholdKeyGenerator)
|
||||
ret.nbits = nbits
|
||||
ret.TotalNumberOfDecryptionServers = TotalNumberOfDecryptionServers
|
||||
ret.Threshold = Threshold
|
||||
ret.Random = random
|
||||
return ret
|
||||
}
|
||||
|
||||
func (this *ThresholdKeyGenerator) GenerateSafePrimes() (*big.Int, *big.Int, error) {
|
||||
return crypto.GenerateSafePrimes(this.nbits, this.Random)
|
||||
}
|
||||
|
||||
func (this *ThresholdKeyGenerator) InitPandP1() error {
|
||||
var err error
|
||||
this.p, this.p1, err = this.GenerateSafePrimes()
|
||||
return err
|
||||
}
|
||||
|
||||
func (this *ThresholdKeyGenerator) InitQandQ1() error {
|
||||
var err error
|
||||
this.q, this.q1, err = this.GenerateSafePrimes()
|
||||
return err
|
||||
}
|
||||
|
||||
func (this *ThresholdKeyGenerator) InitShortcuts() {
|
||||
this.n = new(big.Int).Mul(this.p, this.q)
|
||||
this.m = new(big.Int).Mul(this.p1, this.q1)
|
||||
this.nSquare = new(big.Int).Mul(this.n, this.n)
|
||||
this.nm = new(big.Int).Mul(this.n, this.m)
|
||||
|
||||
}
|
||||
|
||||
func (this *ThresholdKeyGenerator) ArePsAndQsGood() bool {
|
||||
if this.p.Cmp(this.q) == 0 {
|
||||
return false
|
||||
}
|
||||
if this.p.Cmp(this.q1) == 0 {
|
||||
return false
|
||||
}
|
||||
if this.p1.Cmp(this.q) == 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *ThresholdKeyGenerator) InitPsAndQs() error {
|
||||
if err := this.InitPandP1(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := this.InitQandQ1(); err != nil {
|
||||
return err
|
||||
}
|
||||
if !this.ArePsAndQsGood() {
|
||||
return this.InitPsAndQs()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *ThresholdKeyGenerator) ComputeV() error {
|
||||
var err error
|
||||
this.v, err = crypto.GetRandomGeneratorOfTheQuadraticResidue(this.nSquare, this.Random)
|
||||
return err
|
||||
}
|
||||
|
||||
// Choose d such that d=0 mod m and d=1 mod n, using Chinese remainder thm
|
||||
// we can find d using Chinese remainder thm note that $d=(m. (m^-1 mod n))$
|
||||
func (this *ThresholdKeyGenerator) InitD() {
|
||||
mInverse := new(big.Int).ModInverse(this.m, this.n)
|
||||
this.d = new(big.Int).Mul(mInverse, this.m)
|
||||
}
|
||||
|
||||
func (this *ThresholdKeyGenerator) InitNumerialValues() error {
|
||||
if err := this.InitPsAndQs(); err != nil {
|
||||
return err
|
||||
}
|
||||
this.InitShortcuts()
|
||||
this.InitD()
|
||||
return this.ComputeV()
|
||||
}
|
||||
|
||||
func (this *ThresholdKeyGenerator) GenerateHidingPolynomial() error {
|
||||
this.polynomialCoefficients = make([]*big.Int, this.Threshold)
|
||||
this.polynomialCoefficients[0] = this.d
|
||||
var err error
|
||||
for i := 1; i < this.Threshold; i++ {
|
||||
this.polynomialCoefficients[i], err = rand.Int(this.Random, this.nm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *ThresholdKeyGenerator) ComputeShare(index int) *big.Int {
|
||||
share := big.NewInt(0)
|
||||
for i := 0; i < this.Threshold; i++ {
|
||||
a := this.polynomialCoefficients[i]
|
||||
b := new(big.Int).Exp(big.NewInt(int64(index+1)), big.NewInt(int64(i)), nil)
|
||||
tmp := new(big.Int).Mul(a, b)
|
||||
share = new(big.Int).Add(share, tmp)
|
||||
}
|
||||
return new(big.Int).Mod(share, this.nm)
|
||||
}
|
||||
|
||||
func (this *ThresholdKeyGenerator) CreateShares() []*big.Int {
|
||||
shares := make([]*big.Int, this.TotalNumberOfDecryptionServers)
|
||||
for i := 0; i < this.TotalNumberOfDecryptionServers; i++ {
|
||||
shares[i] = this.ComputeShare(i)
|
||||
}
|
||||
return shares
|
||||
}
|
||||
|
||||
func (this *ThresholdKeyGenerator) Delta() *big.Int {
|
||||
return crypto.Factorial(this.TotalNumberOfDecryptionServers)
|
||||
}
|
||||
|
||||
func (this *ThresholdKeyGenerator) CreateViArray(shares []*big.Int) (viArray []*big.Int) {
|
||||
viArray = make([]*big.Int, len(shares))
|
||||
delta := this.Delta()
|
||||
for i, share := range shares {
|
||||
tmp := new(big.Int).Mul(share, delta)
|
||||
viArray[i] = new(big.Int).Exp(this.v, tmp, this.nSquare)
|
||||
}
|
||||
return viArray
|
||||
}
|
||||
|
||||
func (this *ThresholdKeyGenerator) CreatePrivateKey(i int, share *big.Int, viArray []*big.Int) *ThresholdPrivateKey {
|
||||
ret := new(ThresholdPrivateKey)
|
||||
ret.N = this.n
|
||||
ret.G = new(big.Int).Add(ret.N, ONE)
|
||||
ret.V = this.v
|
||||
|
||||
ret.TotalNumberOfDecryptionServers = this.TotalNumberOfDecryptionServers
|
||||
ret.Threshold = this.Threshold
|
||||
ret.Share = share
|
||||
ret.Id = i + 1
|
||||
ret.Vi = viArray
|
||||
return ret
|
||||
}
|
||||
|
||||
func (this *ThresholdKeyGenerator) CreatePrivateKeys() []*ThresholdPrivateKey {
|
||||
shares := this.CreateShares()
|
||||
viArray := this.CreateViArray(shares)
|
||||
ret := make([]*ThresholdPrivateKey, this.TotalNumberOfDecryptionServers)
|
||||
for i := 0; i < this.TotalNumberOfDecryptionServers; i++ {
|
||||
ret[i] = this.CreatePrivateKey(i, shares[i], viArray)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (this *ThresholdKeyGenerator) Generate() ([]*ThresholdPrivateKey, error) {
|
||||
if err := this.InitNumerialValues(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := this.GenerateHidingPolynomial(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.CreatePrivateKeys(), nil
|
||||
}
|
||||
Reference in new issue
Block a user