Few things make me feel as nerdy as bitwise operations. And I think that’s a good thing.

But for some backstory. Circom is used for implementing ZKPs, and that’s what we’re using on the BoTHS project. However, Circom comes with some peculiar quirks. It’s not a fully-fledged programming language, so some things we take for granted don’t really exist. We’ve only got two datatypes, three if you’re being generous:

With this humble arsenal, you’d be surprised at the amazing things we can build.

Why bother about typing variables, when they’re all going to be numbers. Functions like max, min or even sum aren’t natively implemented. So you’ll generally look at the official library of standard components to see if they have what you’re looking for. In my case, that was the max function. We need to check that a chess piece can not somehow wander of the board, by having a really large position coordinate. It would be really easy to ‘clamp’ this value in other programming languages, but here, we have to implement almost everything ourselves.

Enter bitwise magic! Let’s just cut to the chase. You can find below the circuit I finally came up with to determine the maximum of two numbers using bitwise operations

template Max() {
    signal input a;
    signal input b;
    signal output out;

    var BITSIZE = 64;
 
    // Use some bitwise magic to extract the sign bit
    var z = (a - b);
    var i = ( z >> BITSIZE-1) & 1;
 
    // Find the maximum number
    out <== a - (i * z);
}

The real magic happens with the

( z >> BITSIZE-1)

which we use to extract the sign bit of the difference between the two numbers.

Now our chess pieces won’t fall off the board :)