// strAttack.go
package timeAttack
import (
"fmt"
"math/rand"
"sort"
"time"
)
const SECRET = "s3cr3t_k3y"
// Use a sink variable — prevents compiler from optimizing away the work loop
var sink int
func vulnerableCheck(input string) bool {
if len(input) != len(SECRET) {
return false
}
for i := 0; i < len(SECRET); i++ {
if input[i] != SECRET[i] {
return false
}
// sink prevents dead-code elimination by the compiler
for j := 0; j < 1000; j++ {
sink += j
}
}
return true
}
func measureTime(input string, trialsCount int) time.Duration {
samples := make([]int64, trialsCount)
for i := 0; i < trialsCount; i++ {
start := time.Now()
vulnerableCheck(input)
samples[i] = time.Since(start).Nanoseconds()
}
sort.Slice(samples, func(i, j int) bool { return samples[i] < samples[j] })
// lower quartile — stable against GC/scheduler spikes
return time.Duration(samples[trialsCount/4])
}
func Attack(guessedLength int) string {
const trials = 3_000
charset := "abcdefghijklmnopqrstuvwxyz0123456789_!ABCDEFGHIJKLMNOPQRSTUVWXYZ"
recovered := make([]byte, guessedLength)
for i := range recovered {
recovered[i] = 'a'
}
for index := 0; index < guessedLength; index++ {
fmt.Printf("Cracking position %d... ", index)
bestChar := charset[0]
bestTime := time.Duration(0)
first := true
// Shuffle charset order to avoid positional bias
order := rand.Perm(len(charset))
for _, ci := range order {
recovered[index] = charset[ci]
elapsed := measureTime(string(recovered), trials)
if first || elapsed > bestTime {
bestTime = elapsed
bestChar = charset[ci]
first = false
}
}
recovered[index] = bestChar
fmt.Printf("found '%c' (signal: %v) → recovered so far: %s\n",
bestChar, bestTime, string(recovered[:index+1]))
}
return string(recovered)
}
// main.go
package main
import (
"fmt"
"practice/timeAttack"
)
func main() {
fmt.Println("=== Timing Attack Demo ===")
for i := 1; i < 11; i++ {
fmt.Printf("Secret length is known (or guessed): %d\n\n", i)
result := timeAttack.Attack(i)
fmt.Println()
if result == timeAttack.SECRET {
fmt.Printf(":) Secret recovered: \"%s\"\n", result)
break
} else {
fmt.Printf(":( Got: \"%s\" (close but timing noise interfered)\n", result)
fmt.Println(" Run again — noise can cause misses on a busy system.")
}
}
}