This is the second crypto challenge in set 1 from cryptopals, which is the qualifying set.
The difficulty level is relatively easy, to solve this problem I have used the programming language Go.
Problem description
Write a function that takes two equal-length buffers and produces their XOR combination.
The input string is,
1c0111001f010100061a024b53535009181c
and should be XOR'd (after hex decoding) against,
686974207468652062756c6c277320657965
which then should produce the following result,
746865206b696420646f6e277420706c6179
Solution
We can reuse ideas from the previous challenge when working with the hexadecimal strings.
input1 := "1c0111001f010100061a024b53535009181c"
buffer1, err := hex.DecodeString(input1)
if err != nil {
fmt.Println("Error decoding input 1:", err)
return
}
input2 := "686974207468652062756c6c277320657965"
buffer2, err := hex.DecodeString(input2)
if err != nil {
fmt.Println("Error decoding input 2:", err)
return
}
The Go programming language has a XOR arithmetic operator, ^
, that should work great in this case. The bitwise logical and shift operators apply to integers only which will work nicely with our byte buffers created above.
To do this we will create a function where we can loop through our buffers and xor them together.
func xor(buffer1, buffer2 []byte) ([]byte, error) {
if len(buffer1) != len(buffer2) {
return nil, fmt.Errorf("buffers must have equal length")
}
result := make([]byte, len(buffer1))
for i := 0; i < len(buffer1); i++ {
result[i] = buffer1[i] ^ buffer2[i]
}
return result, nil
}
Now we only need to print the output and see if the result equals the expected value. This is how we could put all the pieces together.
package main
import (
"encoding/hex"
"fmt"
)
func xor(buffer1, buffer2 []byte) ([]byte, error) {
if len(buffer1) != len(buffer2) {
return nil, fmt.Errorf("buffers must have equal length")
}
result := make([]byte, len(buffer1))
for i := 0; i < len(buffer1); i++ {
result[i] = buffer1[i] ^ buffer2[i]
}
return result, nil
}
func main() {
input1 := "1c0111001f010100061a024b53535009181c"
buffer1, err := hex.DecodeString(input1)
if err != nil {
fmt.Println("Error decoding input 1:", err)
return
}
input2 := "686974207468652062756c6c277320657965"
buffer2, err := hex.DecodeString(input2)
if err != nil {
fmt.Println("Error decoding input 2:", err)
return
}
result, err := xor(buffer1, buffer2)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("%x\n", result)
}
Conclusion
This is all about knowing what tools your programming languages has to offer, and in this case all we needed was a for
loop and the bitwise XOR operator, ^
.