Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,11 @@ you can supply arguments the most common prefixes i.e. n= -n= --n=

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

this command opportunistically makes use of the following tools to perform factorization:

- gmp-ecm
- pari-gp

for example:
```bash
$ ret factor -n=1807415580361109435231633835400969
Expand Down
75 changes: 74 additions & 1 deletion commands/factor.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"ret/util"
"strings"
"sync"
"time"
)

var (
Expand Down Expand Up @@ -37,6 +38,10 @@ func FactorHelp() string {
"you can supply arguments the most common prefixes i.e. " + theme.ColorBlue + "n= -n= --n= " + theme.ColorReset + "\n\n" +
"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" +

"this command opportunistically makes use of the following tools to perform factorization:\n\n" +
" - gmp-ecm\n" +
" - pari-gp\n\n" +

"for example:\n" +
"```bash\n" +
theme.ColorGray + "$ " + theme.ColorBlue + "ret factor -n=1807415580361109435231633835400969\n" + theme.ColorReset +
Expand All @@ -63,6 +68,8 @@ func parseFactorArgs(args []string) {
}

func Factor(args []string) {
startTime := time.Now()

parseFactorArgs(args)

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

go func() {
defer wg.Done()

factors, url, err := util.FactorDB(n)
if err != nil {
log.Fatalf("💥 "+theme.ColorRed+" error"+theme.ColorReset+": %v\n", err)
Expand All @@ -85,9 +93,74 @@ func Factor(args []string) {
return
}

fmt.Printf("%v\n%v\n", factors, url)
diff := time.Now().Sub(startTime)

fmt.Printf(theme.ColorGreen+"🪓 [factordb]"+theme.ColorReset+" in "+
theme.ColorYellow+"%v"+theme.ColorGray+" %v"+theme.ColorReset+"\n"+"%v\n\n",
diff, url, factors)
}()
}

if util.CheckIfECMInstalled() {

for _, n := range N {
wg.Add(1)

go func() {
defer wg.Done()

factors, cmdStr, err := util.FactorWithECM(n)
if err != nil {
log.Fatalf("💥 "+theme.ColorRed+" error"+theme.ColorReset+": %v\n", err)
}

if factors == nil {
return
}

if len(factors) == 0 {
return
}

diff := time.Now().Sub(startTime)

fmt.Printf(theme.ColorGreen+"🪓 [ecm]"+theme.ColorReset+" in "+
theme.ColorYellow+"%v"+theme.ColorGray+" %v"+theme.ColorReset+"\n"+"%v\n\n",
diff, cmdStr, factors)
}()
}
}

if util.CheckIfPariInstalled() {

for _, n := range N {
wg.Add(1)

go func() {
defer wg.Done()

factors, cmdStr, err := util.FactorWithPari(n)
if err != nil {
log.Fatalf("💥 "+theme.ColorRed+" error"+theme.ColorReset+": %v\n", err)
}

if factors == nil {
return
}

if len(factors) == 0 {
return
}

diff := time.Now().Sub(startTime)

fmt.Printf(theme.ColorGreen+"🪓 [gp-pari]"+theme.ColorReset+" in "+
theme.ColorYellow+"%v"+theme.ColorGray+" %v"+theme.ColorReset+"\n"+"%v\n\n",
diff, cmdStr, factors)
}()
}

}

wg.Wait()
}
60 changes: 6 additions & 54 deletions rsa/factor_with_ecm.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package rsa

import (
"bufio"
"fmt"
"log"
"math/big"
"os/exec"
"ret/theme"
"strings"
"ret/util"
"sync"
)

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

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

stdout, err := cmd.StdoutPipe()
if err != nil {
log.Printf("💥 "+theme.ColorRed+" error"+theme.ColorReset+": %v\n", err)
return
}

factors := make([]*big.Int, 0)

cofactor := new(big.Int).Set(n)

stdin.Write([]byte(fmt.Sprintf("%s\n", cofactor)))

cmd.Start()

scanner := bufio.NewScanner(stdout)

for scanner.Scan() {
line := scanner.Text()

splits := strings.Split(line, " ")

if strings.Contains(line, "Found prime factor of ") {
factor, _ := new(big.Int).SetString(splits[len(splits)-1], 10)
factors = append(factors, factor)
continue
}

if strings.Contains(line, "Composite cofactor") {
cofactor.SetString(splits[2], 10)
stdin.Write([]byte(fmt.Sprintf("%s\n", cofactor)))
continue
}

if strings.Contains(line, "Prime cofactor") {
factor, _ := new(big.Int).SetString(splits[2], 10)
factors = append(factors, factor)
break
}
}

if len(factors) == 2 {
// special case for N = p * q where p and q and two distinct primes
p := factors[0]
Expand All @@ -135,7 +92,7 @@ func factorWithECM(strategy *Strategy, n *big.Int) {
continue
}

scriptFactorECM(cmd.String(), p, q, n, e, c, mBytes)
scriptFactorECM(cmdStr, p, q, n, e, c, mBytes)
}
}
} else {
Expand All @@ -156,20 +113,15 @@ func factorWithECM(strategy *Strategy, n *big.Int) {
continue
}

scriptFactorECMManyFactors(cmd.String(), factors, n, e, c, mBytes)
scriptFactorECMManyFactors(cmdStr, factors, n, e, c, mBytes)
}
}
}
}

func StrategyFactorWithECM(strategy *Strategy) {
// check that ecm is installed
cmd := exec.Command("/usr/bin/ecm", "--help")

err := cmd.Run()
if err != nil {
fmt.Printf("😰"+theme.ColorGray+" \""+theme.ColorReset+"%v"+theme.ColorGray+"\""+theme.ColorYellow+
" failed"+theme.ColorReset+"! consider installing "+theme.ColorCyan+"gmp-ecm"+theme.ColorReset+"\n", cmd.String())
installed := util.CheckIfECMInstalled()
if installed != true {
return
}

Expand Down
57 changes: 6 additions & 51 deletions rsa/factor_with_pari.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
package rsa

import (
"bufio"
"fmt"
"log"
"math/big"
"os"
"os/exec"
"ret/theme"
"strconv"
"strings"
"ret/util"
"sync"
)

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

fmt.Fprintf(file, "print(factorint(%s))\n", n)

file.Close()

cmd := exec.Command("/usr/bin/gp", "--stacksize", "1073741824", "--fast", "--quiet", file.Name())

stdout, err := cmd.StdoutPipe()
if err != nil {
log.Printf("💥 "+theme.ColorRed+" error"+theme.ColorReset+": %v\n", err)
return
}

factors := make([]*big.Int, 0)

cmd.Start()

scanner := bufio.NewScanner(stdout)

if !scanner.Scan() {
return
}

line := scanner.Text()
splits := strings.Split(line[1:len(line)-1], ";")

for _, split := range splits {
nums := strings.Split(split, ",")

count, err := strconv.Atoi(strings.TrimSpace(nums[1]))
if err != nil {
log.Printf("💥 "+theme.ColorRed+" error"+theme.ColorReset+": %v\n", err)
return
}

factor, _ := new(big.Int).SetString(strings.TrimSpace(nums[0]), 10)

for range count {
factors = append(factors, factor)
}
}

if len(factors) == 2 {
// special case for N = p * q where p and q and two distinct primes
p := factors[0]
Expand All @@ -132,7 +92,7 @@ func factorWithPari(strategy *Strategy, n *big.Int) {
continue
}

scriptFactorPari(cmd.String(), p, q, n, e, c, mBytes)
scriptFactorPari(cmdStr, p, q, n, e, c, mBytes)
}
}
} else {
Expand All @@ -153,20 +113,15 @@ func factorWithPari(strategy *Strategy, n *big.Int) {
continue
}

scriptFactorPariManyFactors(cmd.String(), factors, n, e, c, mBytes)
scriptFactorPariManyFactors(cmdStr, factors, n, e, c, mBytes)
}
}
}
}

func StrategyFactorWithPari(strategy *Strategy) {
// check that pari-gp is installed
cmd := exec.Command("/usr/bin/gp", "-v")

err := cmd.Run()
if err != nil {
fmt.Printf("😰"+theme.ColorGray+" \""+theme.ColorReset+"%v"+theme.ColorGray+"\""+theme.ColorYellow+
" failed"+theme.ColorReset+"! consider installing "+theme.ColorCyan+"pari-gp"+theme.ColorReset+"\n", cmd.String())
installed := util.CheckIfPariInstalled()
if installed != true {
return
}

Expand Down
Loading