Skip to content

Commit 0776892

Browse files
authored
Merge pull request #308 from dmur1/add-ecm-to-factor-command
Add ecm to factor command
2 parents 85227c7 + cd1de51 commit 0776892

File tree

6 files changed

+235
-106
lines changed

6 files changed

+235
-106
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,11 @@ you can supply arguments the most common prefixes i.e. n= -n= --n=
282282

283283
multiple values can be supplied as a list or with multiple argument prefixes e.g. -n=1,2,3 or -n=1 -n=2 -n=3
284284

285+
this command opportunistically makes use of the following tools to perform factorization:
286+
287+
- gmp-ecm
288+
- pari-gp
289+
285290
for example:
286291
```bash
287292
$ ret factor -n=1807415580361109435231633835400969

commands/factor.go

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"ret/util"
99
"strings"
1010
"sync"
11+
"time"
1112
)
1213

1314
var (
@@ -37,6 +38,10 @@ func FactorHelp() string {
3738
"you can supply arguments the most common prefixes i.e. " + theme.ColorBlue + "n= -n= --n= " + theme.ColorReset + "\n\n" +
3839
"multiple values can be supplied as a list or with multiple argument prefixes e.g. " + theme.ColorBlue + "-n=1,2,3 or -n=1 -n=2 -n=3" + theme.ColorReset + "\n\n" +
3940

41+
"this command opportunistically makes use of the following tools to perform factorization:\n\n" +
42+
" - gmp-ecm\n" +
43+
" - pari-gp\n\n" +
44+
4045
"for example:\n" +
4146
"```bash\n" +
4247
theme.ColorGray + "$ " + theme.ColorBlue + "ret factor -n=1807415580361109435231633835400969\n" + theme.ColorReset +
@@ -63,6 +68,8 @@ func parseFactorArgs(args []string) {
6368
}
6469

6570
func Factor(args []string) {
71+
startTime := time.Now()
72+
6673
parseFactorArgs(args)
6774

6875
var wg sync.WaitGroup
@@ -72,6 +79,7 @@ func Factor(args []string) {
7279

7380
go func() {
7481
defer wg.Done()
82+
7583
factors, url, err := util.FactorDB(n)
7684
if err != nil {
7785
log.Fatalf("💥 "+theme.ColorRed+" error"+theme.ColorReset+": %v\n", err)
@@ -85,9 +93,74 @@ func Factor(args []string) {
8593
return
8694
}
8795

88-
fmt.Printf("%v\n%v\n", factors, url)
96+
diff := time.Now().Sub(startTime)
97+
98+
fmt.Printf(theme.ColorGreen+"🪓 [factordb]"+theme.ColorReset+" in "+
99+
theme.ColorYellow+"%v"+theme.ColorGray+" %v"+theme.ColorReset+"\n"+"%v\n\n",
100+
diff, url, factors)
89101
}()
90102
}
91103

104+
if util.CheckIfECMInstalled() {
105+
106+
for _, n := range N {
107+
wg.Add(1)
108+
109+
go func() {
110+
defer wg.Done()
111+
112+
factors, cmdStr, err := util.FactorWithECM(n)
113+
if err != nil {
114+
log.Fatalf("💥 "+theme.ColorRed+" error"+theme.ColorReset+": %v\n", err)
115+
}
116+
117+
if factors == nil {
118+
return
119+
}
120+
121+
if len(factors) == 0 {
122+
return
123+
}
124+
125+
diff := time.Now().Sub(startTime)
126+
127+
fmt.Printf(theme.ColorGreen+"🪓 [ecm]"+theme.ColorReset+" in "+
128+
theme.ColorYellow+"%v"+theme.ColorGray+" %v"+theme.ColorReset+"\n"+"%v\n\n",
129+
diff, cmdStr, factors)
130+
}()
131+
}
132+
}
133+
134+
if util.CheckIfPariInstalled() {
135+
136+
for _, n := range N {
137+
wg.Add(1)
138+
139+
go func() {
140+
defer wg.Done()
141+
142+
factors, cmdStr, err := util.FactorWithPari(n)
143+
if err != nil {
144+
log.Fatalf("💥 "+theme.ColorRed+" error"+theme.ColorReset+": %v\n", err)
145+
}
146+
147+
if factors == nil {
148+
return
149+
}
150+
151+
if len(factors) == 0 {
152+
return
153+
}
154+
155+
diff := time.Now().Sub(startTime)
156+
157+
fmt.Printf(theme.ColorGreen+"🪓 [gp-pari]"+theme.ColorReset+" in "+
158+
theme.ColorYellow+"%v"+theme.ColorGray+" %v"+theme.ColorReset+"\n"+"%v\n\n",
159+
diff, cmdStr, factors)
160+
}()
161+
}
162+
163+
}
164+
92165
wg.Wait()
93166
}

rsa/factor_with_ecm.go

Lines changed: 6 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
package rsa
22

33
import (
4-
"bufio"
54
"fmt"
65
"log"
76
"math/big"
8-
"os/exec"
97
"ret/theme"
10-
"strings"
8+
"ret/util"
119
"sync"
1210
)
1311

@@ -71,54 +69,13 @@ func scriptFactorECMManyFactors(cmd string, factors []*big.Int, n *big.Int, e *b
7169
fmt.Print(script)
7270
}
7371
func factorWithECM(strategy *Strategy, n *big.Int) {
74-
cmd := exec.Command("/usr/bin/ecm", "-c", "1000000000", "-one", "2000")
72+
factors, cmdStr, err := util.FactorWithECM(n)
7573

76-
stdin, err := cmd.StdinPipe()
7774
if err != nil {
7875
log.Printf("💥 "+theme.ColorRed+" error"+theme.ColorReset+": %v\n", err)
7976
return
8077
}
8178

82-
stdout, err := cmd.StdoutPipe()
83-
if err != nil {
84-
log.Printf("💥 "+theme.ColorRed+" error"+theme.ColorReset+": %v\n", err)
85-
return
86-
}
87-
88-
factors := make([]*big.Int, 0)
89-
90-
cofactor := new(big.Int).Set(n)
91-
92-
stdin.Write([]byte(fmt.Sprintf("%s\n", cofactor)))
93-
94-
cmd.Start()
95-
96-
scanner := bufio.NewScanner(stdout)
97-
98-
for scanner.Scan() {
99-
line := scanner.Text()
100-
101-
splits := strings.Split(line, " ")
102-
103-
if strings.Contains(line, "Found prime factor of ") {
104-
factor, _ := new(big.Int).SetString(splits[len(splits)-1], 10)
105-
factors = append(factors, factor)
106-
continue
107-
}
108-
109-
if strings.Contains(line, "Composite cofactor") {
110-
cofactor.SetString(splits[2], 10)
111-
stdin.Write([]byte(fmt.Sprintf("%s\n", cofactor)))
112-
continue
113-
}
114-
115-
if strings.Contains(line, "Prime cofactor") {
116-
factor, _ := new(big.Int).SetString(splits[2], 10)
117-
factors = append(factors, factor)
118-
break
119-
}
120-
}
121-
12279
if len(factors) == 2 {
12380
// special case for N = p * q where p and q and two distinct primes
12481
p := factors[0]
@@ -135,7 +92,7 @@ func factorWithECM(strategy *Strategy, n *big.Int) {
13592
continue
13693
}
13794

138-
scriptFactorECM(cmd.String(), p, q, n, e, c, mBytes)
95+
scriptFactorECM(cmdStr, p, q, n, e, c, mBytes)
13996
}
14097
}
14198
} else {
@@ -156,20 +113,15 @@ func factorWithECM(strategy *Strategy, n *big.Int) {
156113
continue
157114
}
158115

159-
scriptFactorECMManyFactors(cmd.String(), factors, n, e, c, mBytes)
116+
scriptFactorECMManyFactors(cmdStr, factors, n, e, c, mBytes)
160117
}
161118
}
162119
}
163120
}
164121

165122
func StrategyFactorWithECM(strategy *Strategy) {
166-
// check that ecm is installed
167-
cmd := exec.Command("/usr/bin/ecm", "--help")
168-
169-
err := cmd.Run()
170-
if err != nil {
171-
fmt.Printf("😰"+theme.ColorGray+" \""+theme.ColorReset+"%v"+theme.ColorGray+"\""+theme.ColorYellow+
172-
" failed"+theme.ColorReset+"! consider installing "+theme.ColorCyan+"gmp-ecm"+theme.ColorReset+"\n", cmd.String())
123+
installed := util.CheckIfECMInstalled()
124+
if installed != true {
173125
return
174126
}
175127

rsa/factor_with_pari.go

Lines changed: 6 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
package rsa
22

33
import (
4-
"bufio"
54
"fmt"
65
"log"
76
"math/big"
8-
"os"
9-
"os/exec"
107
"ret/theme"
11-
"strconv"
12-
"strings"
8+
"ret/util"
139
"sync"
1410
)
1511

@@ -73,49 +69,13 @@ func scriptFactorPariManyFactors(cmd string, factors []*big.Int, n *big.Int, e *
7369
fmt.Print(script)
7470
}
7571
func factorWithPari(strategy *Strategy, n *big.Int) {
76-
file, err := os.CreateTemp("", "ret_rsa_factorme")
72+
factors, cmdStr, err := util.FactorWithPari(n)
7773

78-
fmt.Fprintf(file, "print(factorint(%s))\n", n)
79-
80-
file.Close()
81-
82-
cmd := exec.Command("/usr/bin/gp", "--stacksize", "1073741824", "--fast", "--quiet", file.Name())
83-
84-
stdout, err := cmd.StdoutPipe()
8574
if err != nil {
8675
log.Printf("💥 "+theme.ColorRed+" error"+theme.ColorReset+": %v\n", err)
8776
return
8877
}
8978

90-
factors := make([]*big.Int, 0)
91-
92-
cmd.Start()
93-
94-
scanner := bufio.NewScanner(stdout)
95-
96-
if !scanner.Scan() {
97-
return
98-
}
99-
100-
line := scanner.Text()
101-
splits := strings.Split(line[1:len(line)-1], ";")
102-
103-
for _, split := range splits {
104-
nums := strings.Split(split, ",")
105-
106-
count, err := strconv.Atoi(strings.TrimSpace(nums[1]))
107-
if err != nil {
108-
log.Printf("💥 "+theme.ColorRed+" error"+theme.ColorReset+": %v\n", err)
109-
return
110-
}
111-
112-
factor, _ := new(big.Int).SetString(strings.TrimSpace(nums[0]), 10)
113-
114-
for range count {
115-
factors = append(factors, factor)
116-
}
117-
}
118-
11979
if len(factors) == 2 {
12080
// special case for N = p * q where p and q and two distinct primes
12181
p := factors[0]
@@ -132,7 +92,7 @@ func factorWithPari(strategy *Strategy, n *big.Int) {
13292
continue
13393
}
13494

135-
scriptFactorPari(cmd.String(), p, q, n, e, c, mBytes)
95+
scriptFactorPari(cmdStr, p, q, n, e, c, mBytes)
13696
}
13797
}
13898
} else {
@@ -153,20 +113,15 @@ func factorWithPari(strategy *Strategy, n *big.Int) {
153113
continue
154114
}
155115

156-
scriptFactorPariManyFactors(cmd.String(), factors, n, e, c, mBytes)
116+
scriptFactorPariManyFactors(cmdStr, factors, n, e, c, mBytes)
157117
}
158118
}
159119
}
160120
}
161121

162122
func StrategyFactorWithPari(strategy *Strategy) {
163-
// check that pari-gp is installed
164-
cmd := exec.Command("/usr/bin/gp", "-v")
165-
166-
err := cmd.Run()
167-
if err != nil {
168-
fmt.Printf("😰"+theme.ColorGray+" \""+theme.ColorReset+"%v"+theme.ColorGray+"\""+theme.ColorYellow+
169-
" failed"+theme.ColorReset+"! consider installing "+theme.ColorCyan+"pari-gp"+theme.ColorReset+"\n", cmd.String())
123+
installed := util.CheckIfPariInstalled()
124+
if installed != true {
170125
return
171126
}
172127

0 commit comments

Comments
 (0)