Skip to content

Instantly share code, notes, and snippets.

@dchest
Created July 3, 2011 09:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dchest/1062092 to your computer and use it in GitHub Desktop.
Save dchest/1062092 to your computer and use it in GitHub Desktop.
Example of meet-in-the-middle attack
// Written by Dmitry Chestnykh. Public domain.
package main
import (
"crypto/blowfish"
"fmt"
"time"
)
func encrypt(key uint8, src string) string {
c, _ := blowfish.NewCipher([]byte{key, 0, 0, 0})
b := make([]byte, 8)
c.Encrypt(b, []byte(src))
return string(b)
}
func decrypt(key uint8, src string) string {
c, _ := blowfish.NewCipher([]byte{key, 0, 0, 0})
b := make([]byte, 8)
c.Decrypt(b, []byte(src))
return string(b)
}
func doubleEncrypt(key []uint8, src string) string {
return encrypt(key[1], encrypt(key[0], src))
}
func encryptWithAllKeys(plaintext string) (r map[string]uint8) {
r = make(map[string]uint8, 256)
for i := 0; i < 256; i++ {
s := encrypt(uint8(i), plaintext)
r[s] = uint8(i)
}
return
}
const (
reportFmt = "Key: \"%c%c\"\tOperations: %d\n"
notFoundFmt = "No keys founds in %d operations\n"
)
func bruteforce(plaintext, ciphertext string) {
op := 0
for i := 0; i < 256; i++ {
s1 := decrypt(uint8(i), ciphertext)
for j := 0; j < 256; j++ {
op++
if decrypt(uint8(j), s1) == plaintext {
fmt.Printf(reportFmt, j, i, op)
return
}
}
}
fmt.Printf(notFoundFmt, op)
}
func meetInTheMiddle(plaintext, ciphertext string) {
ekp := encryptWithAllKeys(plaintext)
op := len(ekp)
for i := 0; i < 256; i++ {
s := decrypt(uint8(i), ciphertext)
op++
if k, ok := ekp[s]; ok {
fmt.Printf(reportFmt, k, i, op)
return
}
}
fmt.Printf(notFoundFmt, op)
}
func measure(name string, f func()) {
t := time.Nanoseconds()
f()
fmt.Printf("%s: %.2f sec\n\n", name, float64(time.Nanoseconds()-t)/1.0e9)
}
func main() {
plaintext := "Dear Bob" // must be exactly 8 bytes
key := []byte("Go") // must be exactly 2 bytes
ciphertext := doubleEncrypt(key, plaintext)
fmt.Printf("Plain-text: %q\n", plaintext)
fmt.Printf("Ciphertext: %q\n\n", ciphertext)
measure("Bruteforce", func() {
bruteforce(plaintext, ciphertext)
})
measure("Meet-in-the-middle", func() {
meetInTheMiddle(plaintext, ciphertext)
})
}
@dchest
Copy link
Author

dchest commented Jul 3, 2011

Meet-in-the-middle attack on a 16-bit cipher derived from a 8-bit cipher by encrypting text with two 8-bit keys keys.
See http://en.wikipedia.org/wiki/Meet-in-the-middle_attack

@dchest
Copy link
Author

dchest commented Jul 3, 2011

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment