Botched Challenge 6
This commit is contained in:
parent
12e4ff4060
commit
2eb6717724
5 changed files with 276 additions and 80 deletions
|
@ -1,10 +1,10 @@
|
|||
package set1
|
||||
|
||||
const Base64Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||
const Base64PaddingCharacter = "="
|
||||
const Base64PaddingCharacter = '='
|
||||
|
||||
func HexDecode(hex string) (value []byte, success bool) {
|
||||
size := len(hex)
|
||||
func HexDecode(block []byte) (value []byte, success bool) {
|
||||
size := len(block)
|
||||
|
||||
var hexValues = map[byte]byte{
|
||||
'0': 0,
|
||||
|
@ -32,8 +32,8 @@ func HexDecode(hex string) (value []byte, success bool) {
|
|||
buffer := make([]byte, 0, size/2)
|
||||
|
||||
for i := 0; i < size; i += 2 {
|
||||
first := hexValues[hex[i]] << 4
|
||||
second := hexValues[hex[i+1]]
|
||||
first := hexValues[block[i]] << 4
|
||||
second := hexValues[block[i+1]]
|
||||
|
||||
buffer = append(buffer, first^second)
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ const AlphabeticCharactersByFrequency = "zjqxkvbpgwyfmculdhrsnioate"
|
|||
|
||||
const SomeShakespeare = "That can I, At least, the whisper goes so: our last king, Whose image even but now appeared to us, Was, as you know, by Fortinbras of Norway, Thereto pricked on by a most emulate pride, Dared to the combat, in which our valiant Hamlet - For so this side of our known world esteemed him - Did slay this Fortinbras, who by a sealed compact, Well ratified by law and heraldry, Did forfeit, with his life, all those his lands Which he stood seized on to the conqueror: Against the which, a moiety competent Was gaged by our king, which had returned To the inheritance of Fortinbras, Had he been vanquisher, as, by the same cov'nant, And carriage of the article designed, His fell to Hamlet. Now, sir, young Fortinbras, Of unimprovèd mettle hot and full, Hath in the skirts of Norway here and there Sharked up a list of landless resolutes For food and diet to some enterprise That hath a stomach in't, which is no other - And it doth well appear unto our state - But to recover of us, by strong hand And terms compulsative, those foresaid lands So by his father lost: and this, I take it, Is the main motive of our preparations, The source of this our watch and the chief head Of this post-haste and rummage in the land."
|
||||
|
||||
func XORDecodeHex(hexString string, passChar byte) []byte {
|
||||
decoded, success := HexDecode(hexString)
|
||||
func XORDecodeHex(block []byte, passChar byte) []byte {
|
||||
decoded, success := HexDecode(block)
|
||||
|
||||
if !success {
|
||||
return []byte{}
|
||||
|
@ -39,10 +39,10 @@ func FindCharacterFrequency(char byte) (freq int) {
|
|||
}
|
||||
}
|
||||
|
||||
return -1
|
||||
return 0
|
||||
}
|
||||
|
||||
func ScoreTextByCharacterFrequency(text string) (score int) {
|
||||
func ScoreTextByAlphabeticFrequency(text []byte) (score int) {
|
||||
for i := 0; i < len(text); i++ {
|
||||
score += FindCharacterFrequency(text[i])
|
||||
}
|
||||
|
@ -50,16 +50,17 @@ func ScoreTextByCharacterFrequency(text string) (score int) {
|
|||
return
|
||||
}
|
||||
|
||||
func BruteForceXORSingleCharacterEncodedString(hexString string) (score int, result []byte) {
|
||||
func BruteForceXORSingleCharacterHexEncodedBlock(block []byte) (score int, key byte, result []byte) {
|
||||
|
||||
bytes, _ := HexDecode(hexString)
|
||||
bytes, _ := HexDecode(block)
|
||||
|
||||
for i := 0; i < 256; i++ {
|
||||
decoded := XORDecodePlain(bytes, byte(i))
|
||||
decodedScore := ScoreTextByCharacterFrequency(string(decoded))
|
||||
decodedScore := ScoreTextByAlphabeticFrequency(decoded)
|
||||
|
||||
if decodedScore > score {
|
||||
score = decodedScore
|
||||
key = byte(i)
|
||||
result = decoded
|
||||
}
|
||||
}
|
||||
|
|
170
set1/challenge_6.go
Normal file
170
set1/challenge_6.go
Normal file
|
@ -0,0 +1,170 @@
|
|||
package set1
|
||||
|
||||
import (
|
||||
"os"
|
||||
"slices"
|
||||
)
|
||||
|
||||
// 00aaaaaa 00aabbbb 00bbbbcc 00cccccc
|
||||
// aaaaaaaa bbbbbbbb cccccccc
|
||||
func Base64Decode(block []byte) (decoded []byte) {
|
||||
|
||||
base64Mapping := map[byte]byte{}
|
||||
|
||||
for i, b := range Base64Alphabet {
|
||||
base64Mapping[byte(b)] = byte(i)
|
||||
}
|
||||
|
||||
decoded = []byte{}
|
||||
|
||||
for i := 0; i < len(block); i += 4 {
|
||||
decodedBytes := []byte{0b00000000, 0b00000000, 0b00000000}
|
||||
|
||||
encodedBytes := block[i : i+4]
|
||||
|
||||
for i, b := range encodedBytes {
|
||||
if b == Base64PaddingCharacter {
|
||||
encodedBytes[i] = 0b00000000
|
||||
} else {
|
||||
encodedBytes[i] = base64Mapping[b]
|
||||
}
|
||||
}
|
||||
|
||||
decodedBytes[0] = (encodedBytes[0] << 2) | (encodedBytes[1] >> 4)
|
||||
decodedBytes[1] = (encodedBytes[1] << 4) | (encodedBytes[2] >> 2)
|
||||
decodedBytes[2] = (encodedBytes[2] << 6) | encodedBytes[3]
|
||||
|
||||
for _, b := range decodedBytes {
|
||||
if b != 0b00000000 {
|
||||
decoded = append(decoded, b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return decoded
|
||||
}
|
||||
|
||||
func BruteForceXORSingleCharacterPlainEncodedBlock(block []byte) (score int, key byte, result []byte) {
|
||||
for i := 0; i < 256; i++ {
|
||||
decoded := XORDecodePlain(block, byte(i))
|
||||
decodedScore := ScoreTextByAlphabeticFrequency(decoded)
|
||||
|
||||
if decodedScore > score {
|
||||
score = decodedScore
|
||||
key = byte(i)
|
||||
result = decoded
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func HammingDistance(str1, str2 []byte) (distance int) {
|
||||
for i := 0; i < len(str1); i++ {
|
||||
if i >= len(str2) {
|
||||
distance += CountBits(str1[i])
|
||||
} else {
|
||||
distance += CountBits(str1[i] ^ str2[i])
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 1111
|
||||
|
||||
// 1111 -1 = 1110
|
||||
// 1111 & 1110 = 1110
|
||||
|
||||
// 1110 -1 = 1101
|
||||
// 1110 & 1101 = 1100
|
||||
|
||||
// 1100 -1 = 1011
|
||||
// 1100 & 1011 = 1000
|
||||
|
||||
// 1000 -1 = 0111
|
||||
// 0111 & 1000 = 0000
|
||||
|
||||
// ------------------
|
||||
|
||||
// 1010
|
||||
|
||||
// 1010 -1 = 1001
|
||||
// 1010 & 1001 = 1000
|
||||
|
||||
// 1000 -1 = 0111
|
||||
// 1000 & 0111 = 0000
|
||||
|
||||
func CountBits(x byte) (count int) {
|
||||
// This does as many iterations as there are 1 bits in a bitset. Magic.
|
||||
for x != 0 {
|
||||
x &= x - 1
|
||||
count++
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func ReadChallenge6CipherFromFile() (cipher []byte) {
|
||||
file, err := os.ReadFile("./res/set-1-challenge-6.txt")
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return file
|
||||
}
|
||||
|
||||
func NormalizedHammingDistance(strings ...[]byte) (normalizedDistance float32) {
|
||||
for i := 1; i < len(strings); i++ {
|
||||
normalizedDistance += float32(HammingDistance(strings[i-1], strings[i]))
|
||||
}
|
||||
|
||||
normalizedDistance = normalizedDistance / float32(len(strings[0])) / float32(len(strings))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type KeySizeRank struct {
|
||||
Size int
|
||||
Rank float32
|
||||
}
|
||||
|
||||
func RankKeySizeCandidates(minSize, maxSize int, cipher []byte) (keySizeCandidates []KeySizeRank) {
|
||||
keySizes := []KeySizeRank{}
|
||||
|
||||
for keySize := minSize; keySize <= maxSize; keySize++ {
|
||||
keySizes = append(keySizes, KeySizeRank{
|
||||
Size: keySize,
|
||||
Rank: NormalizedHammingDistance(
|
||||
cipher[0:keySize],
|
||||
cipher[keySize:keySize*2],
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
slices.SortFunc(keySizes, func(ksr1 KeySizeRank, ksr2 KeySizeRank) int {
|
||||
if ksr1.Rank > ksr2.Rank {
|
||||
return 1
|
||||
} else if ksr1.Rank == ksr2.Rank {
|
||||
return 0
|
||||
} else {
|
||||
return -1
|
||||
}
|
||||
})
|
||||
|
||||
return keySizes
|
||||
}
|
||||
|
||||
func XORDecrypt(key []byte, cipher []byte) (result []byte) {
|
||||
for i := 0; i < len(cipher); i += len(key) {
|
||||
cipherBlock := cipher[i : i+len(key)]
|
||||
|
||||
for ib, b := range cipherBlock {
|
||||
result = append(result, b^key[ib])
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
}
|
|
@ -1,64 +1 @@
|
|||
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
|
|
@ -37,9 +37,9 @@ func Test_Challenge2(t *testing.T) {
|
|||
func Test_Challenge3(t *testing.T) {
|
||||
const encodedString = "1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736"
|
||||
|
||||
score, bytes := set1.BruteForceXORSingleCharacterEncodedString(encodedString)
|
||||
score, key, bytes := set1.BruteForceXORSingleCharacterHexEncodedBlock([]byte(encodedString))
|
||||
|
||||
t.Logf("Result: '%s' with score %d", string(bytes), score)
|
||||
t.Logf("Result: '%s' with score %d and key %v", string(bytes), score, key)
|
||||
}
|
||||
|
||||
func Test_Challenge4(t *testing.T) {
|
||||
|
@ -56,18 +56,20 @@ func Test_Challenge4(t *testing.T) {
|
|||
|
||||
bestScore := math.MinInt32
|
||||
bestResult := ""
|
||||
bestKey := byte(0)
|
||||
|
||||
for scanner.Scan() {
|
||||
original := scanner.Text()
|
||||
score, result := set1.BruteForceXORSingleCharacterEncodedString(original)
|
||||
score, key, result := set1.BruteForceXORSingleCharacterHexEncodedBlock([]byte(original))
|
||||
|
||||
if score > bestScore {
|
||||
bestScore = score
|
||||
bestResult = string(result)
|
||||
bestKey = key
|
||||
}
|
||||
}
|
||||
|
||||
t.Logf("Result: '%s' with score %d", bestResult, bestScore)
|
||||
t.Logf("Result: '%s' with score %d with key %v", bestResult, bestScore, bestKey)
|
||||
|
||||
}
|
||||
|
||||
|
@ -84,3 +86,89 @@ func Test_Challenge5(t *testing.T) {
|
|||
t.Fatalf("Result '%s' is not the same as expected '%s'", result, expectedCypher)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Challenge6_CalcHammingDistance(t *testing.T) {
|
||||
first := []byte("this is a test")
|
||||
second := []byte("wokka wokka!!!")
|
||||
|
||||
hammingDistance := set1.HammingDistance(first, second)
|
||||
|
||||
if hammingDistance != 37 {
|
||||
t.Fatalf("Result %d is not the same as expected %d", hammingDistance, 37)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Challenge6_FindTop3KeySizes(t *testing.T) {
|
||||
base64Cipher := set1.ReadChallenge6CipherFromFile()
|
||||
|
||||
cipher := set1.Base64Decode(base64Cipher)
|
||||
|
||||
keySizes := set1.RankKeySizeCandidates(2, 40, cipher)
|
||||
|
||||
t.Log(keySizes)
|
||||
}
|
||||
|
||||
func Test_Challenge6_BreakTheCipher(t *testing.T) {
|
||||
base64Cipher := set1.ReadChallenge6CipherFromFile()
|
||||
|
||||
t.Logf("First 10 bytes base64 cipher: %08b ", base64Cipher[0:10])
|
||||
|
||||
cipher := set1.Base64Decode(base64Cipher)
|
||||
|
||||
t.Logf("First 10 bytes cipher: %08b", cipher[0:10])
|
||||
t.Logf("Last 10 bytes cipher: %08b", cipher[len(cipher)-10:])
|
||||
|
||||
// TODO: PROBLEM: This does not rank key sizes correctly. Because I cheated I know the key is of size "24".
|
||||
keySizeCandidates := set1.RankKeySizeCandidates(2, 40, cipher)
|
||||
|
||||
keySize := keySizeCandidates[0].Size
|
||||
|
||||
t.Logf("Best candidate key size is %d", keySize)
|
||||
|
||||
transposed := make([][]byte, keySize)
|
||||
|
||||
for i, b := range cipher {
|
||||
column := i % keySize
|
||||
|
||||
if transposed[column] == nil {
|
||||
transposed[column] = []byte{}
|
||||
}
|
||||
|
||||
transposed[column] = append(transposed[column], b)
|
||||
}
|
||||
|
||||
cipherKey := []byte{}
|
||||
transposedResult := make([][]byte, keySize)
|
||||
|
||||
// TODO: PROBLEM: The below code does not properly deduce the key.
|
||||
for i, column := range transposed {
|
||||
var score int
|
||||
var key byte
|
||||
var result []byte
|
||||
|
||||
for i := 0; i < 256; i++ {
|
||||
decoded := set1.XORDecodePlain(column, byte(i))
|
||||
decodedScore := set1.ScoreTextByAlphabeticFrequency(decoded)
|
||||
|
||||
if decodedScore > score {
|
||||
score = decodedScore
|
||||
key = byte(i)
|
||||
result = decoded
|
||||
}
|
||||
}
|
||||
|
||||
// score, key, result := set1.BruteForceXORSingleCharacterPlainEncodedBlock(column)
|
||||
|
||||
t.Logf("Found key '%c' with score %d", key, score)
|
||||
|
||||
cipherKey = append(cipherKey, key)
|
||||
|
||||
transposedResult[i] = result
|
||||
}
|
||||
|
||||
t.Logf("The key is %s", cipherKey)
|
||||
|
||||
// deciphered := set1.XORDecrypt(cipherKey, cipher)
|
||||
|
||||
// t.Logf("First 100 bytes deciphered: %s", transposedResult)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue