diff --git a/cerberus.go b/cerberus.go index 63f7a23..866e349 100644 --- a/cerberus.go +++ b/cerberus.go @@ -13,8 +13,7 @@ import ( type Challenge struct { Salt string // Challenge salt from server. Diff uint32 // Difficulty level. - Steps int8 // Each step consists of a Challenge and a Solution. More than 1 may be required. - // Stored as a signed int to get past underflow issues later on. + Steps uint8 // Each step consists of a Challenge and a Solution. More than 1 may be required. host *url.URL } @@ -44,7 +43,12 @@ func checkZeros(diff uint32, hash []byte) bool { rem = diff % 8 // Remainder after dividing diff (given in bits) to bytes. nbytes = (diff - rem) / 8 // Amount of 0x0 bytes we can divide difficulty bits into. - mask uint8 // Mask to check remaining bits. + // Bitmask by setting a 1 bit (on LHS) for each remaining bit to check. + mask uint8 = ^((1 << (8 - rem)) - 1) + // Example (rem = 3): mask = ^((1 << (8 - 3)) - 1) + // = ^(00100000 - 1) + // = ^(00011111) + // = 11100000 ) // Check bounds for the loops found below. @@ -63,15 +67,6 @@ func checkZeros(diff uint32, hash []byte) bool { return true } - // Create bitmask by setting a bit to 1 for each remaining bit to check. - // The mask is built from right-to-left and then shifted to the LHS of the octet. - for range rem { - mask <<= 1 - mask += 1 - } - // Shift 1s we just added to the LHS of the octet. - mask <<= 8 - rem - return hash[nbytes]&mask == 0x0 } diff --git a/cerberus_test.go b/cerberus_test.go index d56f69b..fc65297 100644 --- a/cerberus_test.go +++ b/cerberus_test.go @@ -33,33 +33,32 @@ func solveTest(ctx context.Context, hc http.Client, host string) error { connType = "tor" } - steps := int8(1) - - for steps > 0 { - log.Printf("Fetching new %s challenge...", connType) - c, err := NewChallenge(ctx, hc, host) - if err != nil { - return err - } - log.Printf("Challenge: %s, Difficulty: %d, Steps: %d\n", c.Salt, c.Diff, c.Steps) - steps = c.Steps - - s, err := Solve(ctx, c) - if err != nil { - return err - } - log.Printf("Solution hash: %x, nonce: %d\n", s.Hash, s.Nonce) - - resp, err := Submit(ctx, hc, s, "") - if err != nil { - return err - } - - b, err := io.ReadAll(resp.Body) - log.Printf("Response: %s\n\n", b[:60]) - - resp.Body.Close() + log.Printf("Fetching new %s challenge...", connType) + c, err := NewChallenge(ctx, hc, host) + if err != nil { + return err } + log.Printf("Challenge: %s, Difficulty: %d, Steps: %d\n", c.Salt, c.Diff, c.Steps) + + s, err := Solve(ctx, c) + if err != nil { + return err + } + log.Printf("Solution hash: %x, nonce: %d\n", s.Hash, s.Nonce) + + resp, err := Submit(ctx, hc, s, "") + if err != nil { + return err + } + defer resp.Body.Close() + + cookies := resp.Cookies() + for _, ck := range cookies { + log.Printf("Cookie: %s\n", ck.String()) + } + log.Print("Response: ") + io.CopyN(log.Writer(), resp.Body, 128) + fmt.Print("\n...\n") return nil } @@ -73,7 +72,7 @@ func newProxyTransport() *http.Transport { return tr } -func TestSubmit(t *testing.T) { +func TestSolve(t *testing.T) { ctx := t.Context() jar, err := cookiejar.New(nil) @@ -87,16 +86,29 @@ func TestSubmit(t *testing.T) { t.Error(err) return } +} - var dnsErr *net.DNSError - err = solveTest(ctx, http.Client{Transport: newProxyTransport()}, _TEST_ONION) +func TestOnionSolve(t *testing.T) { + ctx := t.Context() + + jar, err := cookiejar.New(nil) if err != nil { - if errors.As(err, &dnsErr) { + t.Error(err) + return + } + + err = solveTest(ctx, http.Client{ + Jar: jar, + Transport: newProxyTransport(), + }, _TEST_ONION) + if err != nil { + if _, ok := errors.AsType[*net.DNSError](err); ok { log.Println("Unable to resolve .onion domain. Make sure ALL_PROXY is set and tor is running.") log.Println("Skipping...") - } else { - t.Error(err) + return } + + t.Error(err) } } diff --git a/go.mod b/go.mod index 9b37f82..61390b9 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module gitgud.io/yats/cerberus -go 1.25.6 +go 1.26.1 require ( github.com/minio/sha256-simd v1.0.1 diff --git a/http.go b/http.go index 2e996b6..26dbaf5 100644 --- a/http.go +++ b/http.go @@ -147,7 +147,7 @@ func parseTags(r io.Reader) (Challenge, error) { if err != nil { return c, ErrParseFailed } - c.Steps = int8(steps) + c.Steps = uint8(steps) } } }