forked from therealmik/batchgcd
/
basic_pairwise.go
52 lines (45 loc) · 1.08 KB
/
basic_pairwise.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package batchgcd
import (
"github.com/ncw/gmp"
"runtime"
"sync"
)
func BasicPairwiseGCD(moduli []*gmp.Int, collisions chan<- Collision) {
var wg sync.WaitGroup
nThreads := runtime.NumCPU()
wg.Add(nThreads)
for i := 0; i < nThreads; i++ {
go pairwiseThread(i, nThreads, &wg, moduli, collisions)
}
wg.Wait()
close(collisions)
}
func pairwiseThread(start, step int, wg *sync.WaitGroup, moduli []*gmp.Int, collisions chan<- Collision) {
gcd := gmp.NewInt(0)
for i := start; i < len(moduli); i += step {
for j := i + 1; j < len(moduli); j++ {
m1 := moduli[i]
m2 := moduli[j]
if m1.Cmp(m2) == 0 {
collisions <- Collision{Modulus: m1}
} else if gcd.GCD(nil, nil, m1, m2).BitLen() != 1 { // There's only one number with a BitLen of 1
q := gmp.NewInt(0)
q.Quo(m1, gcd)
collisions <- Collision{
Modulus: m1,
P: gcd,
Q: q,
}
q = gmp.NewInt(0)
q.Quo(m2, gcd)
collisions <- Collision{
Modulus: m2,
P: gcd,
Q: q,
}
gcd = gmp.NewInt(0) // Old gcd var can't be overwritten
}
}
}
wg.Done()
}