Files
tss-lib/common/random.go
Gustavo Frederico 1e02560e7e Merging the branch that has CGGMP21 Oct changes onto the master branch. Resolving conflicts (listed below). In general, file versions of CGGMP21 Oct were chosen and security patches or small recent improvements from the master branch were copied over.
Merge branch 'master' into feature/cggmp21oct-tss-lib-tmp-merge

# Conflicts:
#	.github/workflows/test.yml
#	Makefile
#	README.md
#	crypto/ckd/child_key_derivation.go
#	crypto/ecpoint.go
#	crypto/mta/proofs.go
#	crypto/mta/range_proof.go
#	crypto/mta/share_protocol.go
#	crypto/mta/share_protocol_test.go
#	crypto/paillier/paillier.go
#	crypto/vss/feldman_vss.go
#	ecdsa/keygen/ecdsa-keygen.pb.go
#	ecdsa/keygen/local_party.go
#	ecdsa/keygen/local_party_test.go
#	ecdsa/keygen/messages.go
#	ecdsa/keygen/prepare.go
#	ecdsa/keygen/round_1.go
#	ecdsa/keygen/round_2.go
#	ecdsa/keygen/round_3.go
#	ecdsa/keygen/round_4.go
#	ecdsa/keygen/save_data.go
#	ecdsa/resharing/ecdsa-resharing.pb.go
#	ecdsa/resharing/local_party_test.go
#	ecdsa/resharing/messages.go
#	ecdsa/resharing/round_1_old_step_1.go
#	ecdsa/resharing/round_4_new_step_2.go
#	ecdsa/signing/ecdsa-signing.pb.go
#	ecdsa/signing/finalize.go
#	ecdsa/signing/key_derivation_util.go
#	ecdsa/signing/local_party.go
#	ecdsa/signing/local_party_test.go
#	ecdsa/signing/messages.go
#	ecdsa/signing/prepare.go
#	ecdsa/signing/round_1.go
#	ecdsa/signing/round_2.go
#	ecdsa/signing/round_3.go
#	ecdsa/signing/round_4.go
#	ecdsa/signing/round_5.go
#	ecdsa/signing/round_6.go
#	ecdsa/signing/round_7.go
#	ecdsa/signing/rounds.go
#	eddsa/keygen/eddsa-keygen.pb.go
#	eddsa/keygen/local_party.go
#	eddsa/keygen/local_party_test.go
#	eddsa/keygen/messages.go
#	eddsa/keygen/round_1.go
#	eddsa/keygen/round_2.go
#	eddsa/keygen/round_3.go
#	eddsa/keygen/save_data.go
#	eddsa/keygen/test_utils.go
#	eddsa/resharing/eddsa-resharing.pb.go
#	eddsa/resharing/local_party.go
#	eddsa/resharing/local_party_test.go
#	eddsa/resharing/messages.go
#	eddsa/resharing/round_1_old_step_1.go
#	eddsa/resharing/round_4_new_step_2.go
#	eddsa/signing/eddsa-signing.pb.go
#	eddsa/signing/finalize.go
#	eddsa/signing/local_party.go
#	eddsa/signing/local_party_test.go
#	eddsa/signing/messages.go
#	eddsa/signing/prepare.go
#	eddsa/signing/round_1.go
#	eddsa/signing/round_2.go
#	eddsa/signing/round_3.go
#	eddsa/signing/rounds.go
#	eddsa/signing/utils.go
#	go.mod
#	go.sum
#	protob/ecdsa-keygen.proto
#	protob/ecdsa-resharing.proto
#	protob/ecdsa-signing.proto
#	protob/eddsa-keygen.proto
#	protob/eddsa-resharing.proto
#	protob/eddsa-signing.proto
#	protob/message.proto
#	protob/signature.proto
#	test/_ecdsa_fixtures/keygen_data_0.json
#	test/_ecdsa_fixtures/keygen_data_1.json
#	test/_ecdsa_fixtures/keygen_data_2.json
#	test/_ecdsa_fixtures/keygen_data_3.json
#	test/_ecdsa_fixtures/keygen_data_4.json
#	test/_eddsa_fixtures/keygen_data_0.json
#	test/_eddsa_fixtures/keygen_data_1.json
#	test/_eddsa_fixtures/keygen_data_2.json
#	test/_eddsa_fixtures/keygen_data_3.json
#	test/_eddsa_fixtures/keygen_data_4.json
#	test/config.go
#	tss/message.pb.go
#	tss/params.go
#	tss/party.go
#	tss/wire.go
2021-12-17 16:03:49 -05:00

112 lines
2.7 KiB
Go

// Copyright © 2019 Binance
//
// This file is part of Binance. The full Binance copyright notice, including
// terms governing use, modification, and redistribution, is contained in the
// file LICENSE at the root of the source code distribution tree.
package common
import (
"crypto/rand"
"fmt"
"math/big"
"github.com/pkg/errors"
)
const (
mustGetRandomIntMaxBits = 5000
)
// MustGetRandomInt panics if it is unable to gather entropy from `rand.Reader` or when `bits` is <= 0
func MustGetRandomInt(bits int) *big.Int {
if bits <= 0 || mustGetRandomIntMaxBits < bits {
panic(fmt.Errorf("MustGetRandomInt: bits should be positive, non-zero and less than %d", mustGetRandomIntMaxBits))
}
// Max random value e.g. 2^256 - 1
max := new(big.Int)
max = max.Exp(two, big.NewInt(int64(bits)), nil).Sub(max, one)
// Generate cryptographically strong pseudo-random int between 0 - max
n, err := rand.Int(rand.Reader, max)
if err != nil {
panic(errors.Wrap(err, "rand.Int failure in MustGetRandomInt!"))
}
return n
}
func GetRandomPositiveInt(upper *big.Int) *big.Int {
if upper == nil || zero.Cmp(upper) != -1 {
return nil
}
var try *big.Int
for {
try = MustGetRandomInt(upper.BitLen())
if try.Cmp(upper) < 0 && try.Cmp(zero) >= 0 {
break
}
}
return try
}
func GetRandomPrimeInt(bits int) *big.Int {
if bits <= 0 {
return nil
}
try, err := rand.Prime(rand.Reader, bits)
if err != nil ||
try.Cmp(zero) == 0 {
// fallback to older method
for {
try = MustGetRandomInt(bits)
if probablyPrime(try) {
break
}
}
}
return try
}
// Generate a random element in the group of all the elements in Z/nZ that
// has a multiplicative inverse.
func GetRandomPositiveRelativelyPrimeInt(n *big.Int) *big.Int {
if n == nil || zero.Cmp(n) != -1 {
return nil
}
var try *big.Int
for {
try = MustGetRandomInt(n.BitLen())
if IsNumberInMultiplicativeGroup(n, try) {
break
}
}
return try
}
func IsNumberInMultiplicativeGroup(n, v *big.Int) bool {
if n == nil || v == nil || zero.Cmp(n) != -1 {
return false
}
gcd := big.NewInt(0)
return v.Cmp(n) < 0 && v.Cmp(one) >= 0 &&
gcd.GCD(nil, nil, v, n).Cmp(one) == 0
}
// Return a random generator of RQn with high probability.
// THIS METHOD ONLY WORKS IF N IS THE PRODUCT OF TWO SAFE PRIMES!
// https://github.com/didiercrunch/paillier/blob/d03e8850a8e4c53d04e8016a2ce8762af3278b71/utils.go#L39
func GetRandomGeneratorOfTheQuadraticResidue(n *big.Int) *big.Int {
f := GetRandomPositiveRelativelyPrimeInt(n)
fSq := new(big.Int).Mul(f, f)
return fSq.Mod(fSq, n)
}
func GetRandomQuandraticNonResidue(n *big.Int) *big.Int {
for {
w := GetRandomPositiveInt(n)
if big.Jacobi(w, n) == -1 {
return w
}
}
}