Simplify bitmask creation

Separate clearnet and onion tests
This commit is contained in:
y a t s
2026-06-03 12:30:57 -04:00
parent 66e6f74a4b
commit 840a63f727
4 changed files with 53 additions and 46 deletions
+7 -12
View File
@@ -13,8 +13,7 @@ import (
type Challenge struct { type Challenge struct {
Salt string // Challenge salt from server. Salt string // Challenge salt from server.
Diff uint32 // Difficulty level. Diff uint32 // Difficulty level.
Steps int8 // Each step consists of a Challenge and a Solution. More than 1 may be required. Steps uint8 // 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.
host *url.URL 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. 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. 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. // Check bounds for the loops found below.
@@ -63,15 +67,6 @@ func checkZeros(diff uint32, hash []byte) bool {
return true 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 return hash[nbytes]&mask == 0x0
} }
+44 -32
View File
@@ -33,33 +33,32 @@ func solveTest(ctx context.Context, hc http.Client, host string) error {
connType = "tor" connType = "tor"
} }
steps := int8(1) log.Printf("Fetching new %s challenge...", connType)
c, err := NewChallenge(ctx, hc, host)
for steps > 0 { if err != nil {
log.Printf("Fetching new %s challenge...", connType) return err
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("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 return nil
} }
@@ -73,7 +72,7 @@ func newProxyTransport() *http.Transport {
return tr return tr
} }
func TestSubmit(t *testing.T) { func TestSolve(t *testing.T) {
ctx := t.Context() ctx := t.Context()
jar, err := cookiejar.New(nil) jar, err := cookiejar.New(nil)
@@ -87,16 +86,29 @@ func TestSubmit(t *testing.T) {
t.Error(err) t.Error(err)
return return
} }
}
var dnsErr *net.DNSError func TestOnionSolve(t *testing.T) {
err = solveTest(ctx, http.Client{Transport: newProxyTransport()}, _TEST_ONION) ctx := t.Context()
jar, err := cookiejar.New(nil)
if err != 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("Unable to resolve .onion domain. Make sure ALL_PROXY is set and tor is running.")
log.Println("Skipping...") log.Println("Skipping...")
} else { return
t.Error(err)
} }
t.Error(err)
} }
} }
+1 -1
View File
@@ -1,6 +1,6 @@
module gitgud.io/yats/cerberus module gitgud.io/yats/cerberus
go 1.25.6 go 1.26.1
require ( require (
github.com/minio/sha256-simd v1.0.1 github.com/minio/sha256-simd v1.0.1
+1 -1
View File
@@ -147,7 +147,7 @@ func parseTags(r io.Reader) (Challenge, error) {
if err != nil { if err != nil {
return c, ErrParseFailed return c, ErrParseFailed
} }
c.Steps = int8(steps) c.Steps = uint8(steps)
} }
} }
} }