Improved performance of the safe prime generator #9

Merged
pdyraga merged 17 commits from master into master 2018-08-02 06:47:13 -04:00
Showing only changes of commit 82f050d7b2 - Show all commits
+4 -17
View File
@@ -74,7 +74,6 @@ func GenerateSafePrime(
defer close(primeChan) defer close(primeChan)
defer close(errChan) defer close(errChan)
mutex := &sync.Mutex{}
waitGroup := &sync.WaitGroup{} waitGroup := &sync.WaitGroup{}
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
@@ -82,28 +81,22 @@ func GenerateSafePrime(
for i := 0; i < concurrencyLevel; i++ { for i := 0; i < concurrencyLevel; i++ {
waitGroup.Add(1) waitGroup.Add(1)
runGenPrimeRoutine( runGenPrimeRoutine(
ctx, primeChan, errChan, mutex, waitGroup, random, bitLen, ctx, primeChan, errChan, waitGroup, random, bitLen,
) )
} }
// Cancel after the specified timeout. // Cancel after the specified timeout.
go func() { go func() {
time.Sleep(timeout) time.Sleep(timeout)
mutex.Lock()
cancel() cancel()
mutex.Unlock()
}() }()
select { select {
case result := <-primeChan: case result := <-primeChan:
mutex.Lock()
cancel() cancel()
mutex.Unlock()
p, q, err = result.p, result.q, nil p, q, err = result.p, result.q, nil
case err := <-errChan: case err := <-errChan:
mutex.Lock()
cancel() cancel()
mutex.Unlock()
p, q, err = nil, nil, err p, q, err = nil, nil, err
case <-ctx.Done(): case <-ctx.Done():
p, q, err = nil, nil, fmt.Errorf("generator timed out after %v", timeout) p, q, err = nil, nil, fmt.Errorf("generator timed out after %v", timeout)
@@ -157,7 +150,6 @@ func runGenPrimeRoutine(
ctx context.Context, ctx context.Context,
primeChan chan safePrime, primeChan chan safePrime,
errChan chan error, errChan chan error,
mutex *sync.Mutex,
waitGroup *sync.WaitGroup, waitGroup *sync.WaitGroup,
rand io.Reader, rand io.Reader,
pBitLen int, pBitLen int,
@@ -175,10 +167,11 @@ func runGenPrimeRoutine(
bigMod := new(big.Int) bigMod := new(big.Int)
go func() { go func() {
defer waitGroup.Done()
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
waitGroup.Done()
return return
default: default:
_, err := io.ReadFull(rand, bytes) _, err := io.ReadFull(rand, bytes)
@@ -266,13 +259,7 @@ func runGenPrimeRoutine(
isPocklingtonCriterionSatisfied(p) && isPocklingtonCriterionSatisfied(p) &&
q.BitLen() == qBitLen { q.BitLen() == qBitLen {
mutex.Lock() primeChan <- safePrime{p, q}
if ctx.Err() == nil {
primeChan <- safePrime{p, q}
}
mutex.Unlock()
waitGroup.Done()
return return
} }
} }