pow模块解耦合完成

This commit is contained in:
tsosunchia
2023-06-01 14:46:52 +08:00
parent 4d7831fd29
commit 6476c3aff3
6 changed files with 9 additions and 285 deletions

3
go.mod
View File

@@ -7,8 +7,9 @@ require (
github.com/google/gopacket v1.1.19
github.com/oschwald/maxminddb-golang v1.10.0
github.com/spf13/viper v1.15.0
github.com/stretchr/testify v1.8.1
github.com/stretchr/testify v1.8.4
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
github.com/tsosunchia/powclient v0.1.0
golang.org/x/net v0.10.0
golang.org/x/sync v0.2.0
)

5
go.sum
View File

@@ -186,8 +186,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
@@ -199,6 +200,8 @@ github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tsosunchia/powclient v0.1.0 h1:yUCa1Zd0KENOCiWJ3NOYhV1uVWUjy1ujy4w8gap3j4M=
github.com/tsosunchia/powclient v0.1.0/go.mod h1:Pm4MP3QqN74SfNskPpFIEyT+NQrcABGoXkkeRwjlMEE=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=

View File

@@ -1,45 +0,0 @@
package pow
import (
"math/big"
)
func gcd(a, b *big.Int) *big.Int {
return new(big.Int).GCD(nil, nil, a, b)
}
func abs(a *big.Int) *big.Int {
return new(big.Int).Abs(a)
}
func rho(N *big.Int) *big.Int {
two := big.NewInt(2)
if new(big.Int).Mod(N, two).Cmp(big.NewInt(0)) == 0 {
return two
}
x := big.NewInt(0).Set(N)
y := big.NewInt(0).Set(N)
c := big.NewInt(1)
g := big.NewInt(1)
for g.Cmp(big.NewInt(1)) == 0 {
x.Mul(x, x).Add(x, c).Mod(x, N)
y.Mul(y, y).Add(y, c).Mod(y, N)
y.Mul(y, y).Add(y, c).Mod(y, N)
g = gcd(abs(new(big.Int).Sub(x, y)), N)
}
return g
}
func factors(N *big.Int) []*big.Int {
one := big.NewInt(1)
if N.Cmp(one) == 0 {
return []*big.Int{}
}
factor := rho(N)
if factor.Cmp(N) == 0 {
return []*big.Int{N}
}
return append(factors(factor), factors(new(big.Int).Div(N, factor))...)
}

View File

@@ -1,51 +0,0 @@
package pow
import (
"fmt"
"math/big"
"strings"
"testing"
"time"
)
func TestFactors(t *testing.T) {
p1 := big.NewInt(24801309629)
p2 := big.NewInt(34244502967)
input := (new(big.Int).Mul(p1, p2)).String()
input = strings.TrimSuffix(input, "\n")
N := new(big.Int)
N.SetString(input, 10)
// Start timer
start := time.Now()
// Calculation
factorsList := factors(N)
// End timer
elapsed := time.Since(start)
// Output results
for _, factor := range factorsList {
fmt.Println(factor)
}
fmt.Printf("Elapsed time: %s\n", elapsed)
expected := []*big.Int{
p1,
p2,
}
if !equalSlices(factorsList, expected) {
t.Errorf("factorsList does not match expected values")
}
}
func equalSlices(slice1, slice2 []*big.Int) bool {
if len(slice1) != len(slice2) {
return false
}
for i := range slice1 {
if slice1[i].Cmp(slice2[i]) != 0 {
return false
}
}
return true
}

View File

@@ -2,6 +2,7 @@ package pow
import (
"fmt"
"github.com/tsosunchia/powclient"
"github.com/xgadget-lab/nexttrace/config"
"net/url"
"os"
@@ -13,7 +14,7 @@ const (
)
func GetToken(fastIp string, host string, port string) (string, error) {
getTokenParams := NewGetTokenParams()
getTokenParams := powclient.NewGetTokenParams()
u := url.URL{Scheme: "https", Host: fastIp + ":" + port, Path: baseURL}
getTokenParams.BaseUrl = u.String()
getTokenParams.SNI = host
@@ -22,7 +23,7 @@ func GetToken(fastIp string, host string, port string) (string, error) {
var err error
// 尝试三次RetToken如果都失败了异常退出
for i := 0; i < 3; i++ {
token, err := RetToken(getTokenParams)
token, err := powclient.RetToken(getTokenParams)
if err != nil {
continue
}

View File

@@ -1,185 +0,0 @@
package pow
import (
"bytes"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"math/big"
"net/http"
"time"
)
//TODO: 在这里要实现优选IP
type Challenge struct {
RequestID string `json:"request_id"`
Challenge string `json:"challenge"`
}
type RequestResponse struct {
Challenge Challenge `json:"challenge"`
RequestTime int64 `json:"request_time"`
}
type SubmitRequest struct {
Challenge Challenge `json:"challenge"`
Answer []string `json:"answer"`
RequestTime int64 `json:"request_time"`
}
type SubmitResponse struct {
Token string `json:"token"`
}
type GetTokenParams struct {
TimeoutSec time.Duration
BaseUrl string
RequestPath string
SubmitPath string
UserAgent string
SNI string
Host string
}
func NewGetTokenParams() *GetTokenParams {
return &GetTokenParams{
TimeoutSec: 5 * time.Second, // 你的默认值
BaseUrl: "http://127.0.0.1:55000",
RequestPath: "/request_challenge",
SubmitPath: "/submit_answer",
UserAgent: "POW client",
SNI: "",
Host: "",
}
}
func RetToken(getTokenParams *GetTokenParams) (string, error) {
// Get challenge
challengeResponse, err := requestChallenge(getTokenParams)
if err != nil {
return "", err
}
//fmt.Println(challengeResponse.Challenge.Challenge)
// Solve challenge and submit answer
token, err := submitAnswer(getTokenParams, challengeResponse)
if err != nil {
return "", err
}
return token, nil
}
func requestChallenge(getTokenParams *GetTokenParams) (*RequestResponse, error) {
client := &http.Client{
Timeout: getTokenParams.TimeoutSec,
}
if getTokenParams.SNI != "" {
client = &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
ServerName: getTokenParams.SNI,
},
},
}
}
req, err := http.NewRequest("GET", getTokenParams.BaseUrl+getTokenParams.RequestPath, nil)
if err != nil {
return nil, err
}
req.Header.Add("User-Agent", getTokenParams.UserAgent)
//req.Header.Add("Host", getTokenParams.Host)
req.Host = getTokenParams.Host
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
fmt.Println(err)
}
}(resp.Body)
var challengeResponse RequestResponse
err = json.NewDecoder(resp.Body).Decode(&challengeResponse)
if err != nil {
return nil, err
}
return &challengeResponse, nil
}
func submitAnswer(getTokenParams *GetTokenParams, challengeResponse *RequestResponse) (string, error) {
client := &http.Client{
Timeout: getTokenParams.TimeoutSec,
}
if getTokenParams.SNI != "" {
client = &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
ServerName: getTokenParams.SNI,
},
},
}
}
requestTime := challengeResponse.RequestTime
challenge := challengeResponse.Challenge.Challenge
requestId := challengeResponse.Challenge.RequestID
N := new(big.Int)
N.SetString(challenge, 10)
factorsList := factors(N)
if len(factorsList) != 2 {
return "", errors.New("factors function did not return exactly two factors")
}
p1 := factorsList[0]
p2 := factorsList[1]
if p1.Cmp(p2) > 0 { // if p1 > p2
p1, p2 = p2, p1 // swap p1 and p2
}
submitRequest := SubmitRequest{
Challenge: Challenge{RequestID: requestId},
Answer: []string{p1.String(), p2.String()},
RequestTime: requestTime,
}
requestBody, err := json.Marshal(submitRequest)
if err != nil {
return "", err
}
req, err := http.NewRequest("POST", getTokenParams.BaseUrl+getTokenParams.SubmitPath, bytes.NewBuffer(requestBody))
if err != nil {
return "", err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Add("User-Agent", getTokenParams.UserAgent)
//req.Header.Add("Host", getTokenParams.Host)
req.Host = getTokenParams.Host
resp, err := client.Do(req)
if err != nil {
return "", err
}
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
fmt.Println(err)
}
}(resp.Body)
if resp.StatusCode != http.StatusOK {
bodyBytes, _ := ioutil.ReadAll(resp.Body)
return "", errors.New(string(bodyBytes))
}
var submitResponse SubmitResponse
err = json.NewDecoder(resp.Body).Decode(&submitResponse)
if err != nil {
return "", err
}
return submitResponse.Token, nil
}