DEV Community

Cover image for Fixed XOR
Stefan Alfbo
Stefan Alfbo

Posted on

Fixed XOR

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
    }
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

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, ^.

References

Top comments (0)