Improved performance of the safe prime generator #9
+4
-17
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user