From b2d17e0eb651e1f821314fc0e2d2755291ba8fda Mon Sep 17 00:00:00 2001 From: didier amyot Date: Sat, 29 Nov 2014 23:29:34 -0800 Subject: [PATCH] removed dependency to old code --- thresholdkey.go | 4 +-- thresholdkey_generator.go | 8 ++--- thresholdkey_generator_test.go | 18 ---------- utils.go | 36 ++++++++++++++++++++ utils_test.go | 60 ++++++++++++++++++++++++++++++++++ 5 files changed, 100 insertions(+), 26 deletions(-) diff --git a/thresholdkey.go b/thresholdkey.go index 1cd1c6d..30b966d 100644 --- a/thresholdkey.go +++ b/thresholdkey.go @@ -6,8 +6,6 @@ import ( "errors" "io" "math/big" - - "bitbucket.org/ustraca/crypto" ) type ThresholdKey struct { @@ -26,7 +24,7 @@ func (this *ThresholdKey) CombineSharesConstant() *big.Int { // returns the factorial of the number of TotalNumberOfDecryptionServers func (this *ThresholdKey) Delta() *big.Int { - return crypto.Factorial(this.TotalNumberOfDecryptionServers) + return Factorial(this.TotalNumberOfDecryptionServers) } func (this *ThresholdKey) MakeVerificationBeforeCombiningPartialDecryptions(shares []*PartialDecryption) error { diff --git a/thresholdkey_generator.go b/thresholdkey_generator.go index bee27b0..8ef0f61 100644 --- a/thresholdkey_generator.go +++ b/thresholdkey_generator.go @@ -4,8 +4,6 @@ import ( "crypto/rand" "io" "math/big" - - "bitbucket.org/ustraca/crypto" ) type ThresholdKeyGenerator struct { @@ -48,7 +46,7 @@ func GetThresholdKeyGenerator(nbits, TotalNumberOfDecryptionServers, Threshold i } func (this *ThresholdKeyGenerator) GenerateSafePrimes() (*big.Int, *big.Int, error) { - return crypto.GenerateSafePrimes(this.nbits, this.Random) + return GenerateSafePrimes(this.nbits, this.Random) } func (this *ThresholdKeyGenerator) InitPandP1() error { @@ -99,7 +97,7 @@ func (this *ThresholdKeyGenerator) InitPsAndQs() error { func (this *ThresholdKeyGenerator) ComputeV() error { var err error - this.v, err = crypto.GetRandomGeneratorOfTheQuadraticResidue(this.nSquare, this.Random) + this.v, err = GetRandomGeneratorOfTheQuadraticResidue(this.nSquare, this.Random) return err } @@ -152,7 +150,7 @@ func (this *ThresholdKeyGenerator) CreateShares() []*big.Int { } func (this *ThresholdKeyGenerator) Delta() *big.Int { - return crypto.Factorial(this.TotalNumberOfDecryptionServers) + return Factorial(this.TotalNumberOfDecryptionServers) } func (this *ThresholdKeyGenerator) CreateViArray(shares []*big.Int) (viArray []*big.Int) { diff --git a/thresholdkey_generator_test.go b/thresholdkey_generator_test.go index fbc3e1f..07aa413 100644 --- a/thresholdkey_generator_test.go +++ b/thresholdkey_generator_test.go @@ -11,24 +11,6 @@ var MockGenerateSafePrimes = func() (*big.Int, *big.Int, error) { return big.NewInt(887), big.NewInt(443), nil } -func AreSafePrimes(p, q *big.Int, expectedLength int, t *testing.T) { - if l := p.BitLen(); l != expectedLength { - t.Error("p does not have the good length. ", l) - } - if l := q.BitLen(); l != expectedLength-1 { - t.Error("q does not have the good length. ", l) - } - if !p.ProbablyPrime(100) { - t.Error("p is not a probable prime :(") - } - if !q.ProbablyPrime(100) { - t.Error("q is not a probable prime :(") - } - if p.Int64() != 2*q.Int64()+1 { - t.Error("p does not equals 2 * q + 1") - } -} - func TestGenerateSafePrimesOfThresholdKeyGenerator(t *testing.T) { tkh := new(ThresholdKeyGenerator) tkh.nbits = 10 diff --git a/utils.go b/utils.go index f3d9572..c25ff3a 100644 --- a/utils.go +++ b/utils.go @@ -11,6 +11,31 @@ var ONE = big.NewInt(1) var TWO = big.NewInt(2) var FOUR = big.NewInt(4) +// returns n! = n*(n-1)*(n-2)...3*2*1 +func Factorial(n int) *big.Int { + ret := big.NewInt(1) + for i := 1; i <= n; i++ { + ret = new(big.Int).Mul(ret, big.NewInt(int64(i))) + } + return ret +} + +// Returns 2 primes such that p = 2 * q + 1 and that the length of +// p is nbits. `p` is called a safe prime +func GenerateSafePrimes(nbits int, random io.Reader) (p, q *big.Int, err error) { + for { + q, err = rand.Prime(random, nbits-1) + if err != nil { + return + } + p = (new(big.Int)).Mul(q, big.NewInt(2)) + p = p.Add(p, big.NewInt(1)) + if p.ProbablyPrime(50) { //a probability of 2**-100 of not being prime + return + } + } +} + // Generate a random element in the group of all the elements in Z/nZ that // has a multiplicative inverse. func GetRandomNumberInMultiplicativeGroup(n *big.Int, random io.Reader) (*big.Int, error) { @@ -26,3 +51,14 @@ func GetRandomNumberInMultiplicativeGroup(n *big.Int, random io.Reader) (*big.In return r, nil } + +// Return a random generator of RQn with high probability. THIS METHOD +// ONLY WORKS IF N IS THE PRODUCT OF TWO SAFE PRIMES! This heuristic is used +// threshold signature paper in the Victor Shoup +func GetRandomGeneratorOfTheQuadraticResidue(n *big.Int, rand io.Reader) (*big.Int, error) { + r, err := GetRandomNumberInMultiplicativeGroup(n, rand) + if err != nil { + return nil, err + } + return new(big.Int).Mod(new(big.Int).Mul(r, r), n), nil +} diff --git a/utils_test.go b/utils_test.go index 43e4721..759e21a 100644 --- a/utils_test.go +++ b/utils_test.go @@ -51,5 +51,65 @@ func TestGetRandomNumberInMultiplicativeGroup(t *testing.T) { t.Fail() } } +} + +func TestFactorial(t *testing.T) { + if delta := Factorial(6); 720 != delta.Int64() { + t.Error("Delta is not 720 but", delta) + } +} + +func AreSafePrimes(p, q *big.Int, expectedLength int, t *testing.T) { + if l := p.BitLen(); l != expectedLength { + t.Error("p does not have the good length. ", l) + } + if l := q.BitLen(); l != expectedLength-1 { + t.Error("q does not have the good length. ", l) + } + if !p.ProbablyPrime(100) { + t.Error("p is not a probable prime :(") + } + if !q.ProbablyPrime(100) { + t.Error("q is not a probable prime :(") + } + if p.Int64() != 2*q.Int64()+1 { + t.Error("p does not equals 2 * q + 1") + } +} + +func GetEntireRQn(n int) map[int]bool { + ret := make(map[int]bool) + for i := 1; i < n; i++ { + if areRelativelyPrime(i, n) { + ret[i] = true + } + } + return ret +} + +func TestGenerateSafePrimes(t *testing.T) { + for i := 0; i < 10; i++ { + p, q, err := GenerateSafePrimes(20, rand.Reader) + if err != nil { + t.Error(err) + } + AreSafePrimes(p, q, 20, t) + } +} + +func TestGetRandomGeneratorOfTheQuadraticResidue(t *testing.T) { + tooSmallPrime1, tooSmallPrime2 := b(347), b(359) + m := new(big.Int).Mul(tooSmallPrime1, tooSmallPrime2) + RQn := GetEntireRQn(n(m)) + for i := 0; i < 100; i++ { + elm, err := GetRandomGeneratorOfTheQuadraticResidue(m, rand.Reader) + if err != nil { + t.Error(err) + return + } + if _, ok := RQn[n(elm)]; !ok { + t.Fail() + } + } }