# Gnosis sqrt function vs Uniswap sqrt function

The Uniswap sqrt function makes sense to me. I can input `100` and it returns `10`. Gnosis on the other hand has a gnarly 368 lines of code expressing the same function (I think) but the return value is very odd i.e., inputting `100` returns `21888242871839275222246405745257275088696311157297823662689037894645226208573`.

What's happening under the hood with Gnosis?

Uniswap example:

``````    /* Derived from UniSwapV2 code base */
/* https://github.com/Uniswap/v2-core/blob/v1.0.1/contracts/libraries/Math.sol */
function sqrtUniswap(uint y) public pure returns (uint256 z) {
if (y > 3) {
z = y;
uint x = y / 2 + 1;
while (x < z) {
z = x;
x = (y / x + x) / 2;
}
} else if (y != 0) {
z = 1;
}

return z;
}
``````

Gnosis example:

``````    /* Derived from Gnosis code base */
/* https://github.com/gnosis/conditional-tokens-contracts/blob/master/contracts/CTHelpers.sol */
function sqrtGnosis(uint x) public pure returns (uint y) {
uint p = 21888242871839275222246405745257275088696311157297823662689037894645226208583;

// solium-disable-next-line security/no-inline-assembly
assembly {
// add chain generated via https://crypto.stackexchange.com/q/27179/71252
// and transformed to the following program:

// x=1; y=x+x; z=y+y; z=z+z; y=y+z; x=x+y; y=y+x; z=y+y; t=z+z; t=z+t; t=t+t;
// t=t+t; z=z+t; x=x+z; z=x+x; z=z+z; y=y+z; z=y+y; z=z+z; z=z+z; z=y+z; x=x+z;
// z=x+x; z=z+z; z=z+z; z=x+z; y=y+z; x=x+y; z=x+x; z=z+z; y=y+z; z=y+y; t=z+z;
// t=t+t; t=t+t; z=z+t; x=x+z; y=y+x; z=y+y; z=z+z; z=z+z; x=x+z; z=x+x; z=z+z;
// z=x+z; z=z+z; z=z+z; z=x+z; y=y+z; z=y+y; t=z+z; t=t+t; t=z+t; t=y+t; t=t+t;
// t=t+t; t=t+t; t=t+t; z=z+t; x=x+z; z=x+x; z=x+z; y=y+z; z=y+y; z=y+z; z=z+z;
// t=z+z; t=z+t; w=t+t; w=w+w; w=w+w; w=w+w; w=w+w; t=t+w; z=z+t; x=x+z; y=y+x;
// z=y+y; x=x+z; y=y+x; x=x+y; y=y+x; x=x+y; z=x+x; z=x+z; z=z+z; y=y+z; z=y+y;
// z=z+z; x=x+z; y=y+x; z=y+y; z=y+z; x=x+z; y=y+x; x=x+y; y=y+x; z=y+y; z=z+z;
// z=y+z; x=x+z; z=x+x; z=x+z; y=y+z; x=x+y; y=y+x; x=x+y; y=y+x; z=y+y; z=y+z;
// z=z+z; x=x+z; y=y+x; z=y+y; z=y+z; z=z+z; x=x+z; z=x+x; t=z+z; t=t+t; t=z+t;
// t=x+t; t=t+t; t=t+t; t=t+t; t=t+t; z=z+t; y=y+z; x=x+y; y=y+x; x=x+y; z=x+x;
// z=x+z; z=z+z; z=z+z; z=z+z; z=x+z; y=y+z; z=y+y; z=y+z; z=z+z; x=x+z; z=x+x;
// z=x+z; y=y+z; x=x+y; z=x+x; z=z+z; y=y+z; x=x+y; z=x+x; y=y+z; x=x+y; y=y+x;
// z=y+y; z=y+z; x=x+z; y=y+x; z=y+y; z=y+z; z=z+z; z=z+z; x=x+z; z=x+x; z=z+z;
// z=z+z; z=x+z; y=y+z; x=x+y; z=x+x; t=x+z; t=t+t; t=t+t; z=z+t; y=y+z; z=y+y;
// x=x+z; y=y+x; x=x+y; y=y+x; x=x+y; y=y+x; z=y+y; t=y+z; z=y+t; z=z+z; z=z+z;
// z=t+z; x=x+z; y=y+x; x=x+y; y=y+x; x=x+y; z=x+x; z=x+z; y=y+z; x=x+y; x=x+x;
// x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x;
// x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x;
// x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x;
// x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x;
// x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x;
// x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x;
// x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x;
// x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x;
// x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x;
// x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x;
// x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x;
// x=x+x; x=x+x; x=x+x; x=x+x; res=y+x
// res == (P + 1) // 4

y := mulmod(x, x, p)
{
let z := mulmod(y, y, p)
z := mulmod(z, z, p)
y := mulmod(y, z, p)
x := mulmod(x, y, p)
y := mulmod(y, x, p)
z := mulmod(y, y, p)
{
let t := mulmod(z, z, p)
t := mulmod(z, t, p)
t := mulmod(t, t, p)
t := mulmod(t, t, p)
z := mulmod(z, t, p)
x := mulmod(x, z, p)
z := mulmod(x, x, p)
z := mulmod(z, z, p)
y := mulmod(y, z, p)
z := mulmod(y, y, p)
z := mulmod(z, z, p)
z := mulmod(z, z, p)
z := mulmod(y, z, p)
x := mulmod(x, z, p)
z := mulmod(x, x, p)
z := mulmod(z, z, p)
z := mulmod(z, z, p)
z := mulmod(x, z, p)
y := mulmod(y, z, p)
x := mulmod(x, y, p)
z := mulmod(x, x, p)
z := mulmod(z, z, p)
y := mulmod(y, z, p)
z := mulmod(y, y, p)
t := mulmod(z, z, p)
t := mulmod(t, t, p)
t := mulmod(t, t, p)
z := mulmod(z, t, p)
x := mulmod(x, z, p)
y := mulmod(y, x, p)
z := mulmod(y, y, p)
z := mulmod(z, z, p)
z := mulmod(z, z, p)
x := mulmod(x, z, p)
z := mulmod(x, x, p)
z := mulmod(z, z, p)
z := mulmod(x, z, p)
z := mulmod(z, z, p)
z := mulmod(z, z, p)
z := mulmod(x, z, p)
y := mulmod(y, z, p)
z := mulmod(y, y, p)
t := mulmod(z, z, p)
t := mulmod(t, t, p)
t := mulmod(z, t, p)
t := mulmod(y, t, p)
t := mulmod(t, t, p)
t := mulmod(t, t, p)
t := mulmod(t, t, p)
t := mulmod(t, t, p)
z := mulmod(z, t, p)
x := mulmod(x, z, p)
z := mulmod(x, x, p)
z := mulmod(x, z, p)
y := mulmod(y, z, p)
z := mulmod(y, y, p)
z := mulmod(y, z, p)
z := mulmod(z, z, p)
t := mulmod(z, z, p)
t := mulmod(z, t, p)
{
let w := mulmod(t, t, p)
w := mulmod(w, w, p)
w := mulmod(w, w, p)
w := mulmod(w, w, p)
w := mulmod(w, w, p)
t := mulmod(t, w, p)
}
z := mulmod(z, t, p)
x := mulmod(x, z, p)
y := mulmod(y, x, p)
z := mulmod(y, y, p)
x := mulmod(x, z, p)
y := mulmod(y, x, p)
x := mulmod(x, y, p)
y := mulmod(y, x, p)
x := mulmod(x, y, p)
z := mulmod(x, x, p)
z := mulmod(x, z, p)
z := mulmod(z, z, p)
y := mulmod(y, z, p)
z := mulmod(y, y, p)
z := mulmod(z, z, p)
x := mulmod(x, z, p)
y := mulmod(y, x, p)
z := mulmod(y, y, p)
z := mulmod(y, z, p)
x := mulmod(x, z, p)
y := mulmod(y, x, p)
x := mulmod(x, y, p)
y := mulmod(y, x, p)
z := mulmod(y, y, p)
z := mulmod(z, z, p)
z := mulmod(y, z, p)
x := mulmod(x, z, p)
z := mulmod(x, x, p)
z := mulmod(x, z, p)
y := mulmod(y, z, p)
x := mulmod(x, y, p)
y := mulmod(y, x, p)
x := mulmod(x, y, p)
y := mulmod(y, x, p)
z := mulmod(y, y, p)
z := mulmod(y, z, p)
z := mulmod(z, z, p)
x := mulmod(x, z, p)
y := mulmod(y, x, p)
z := mulmod(y, y, p)
z := mulmod(y, z, p)
z := mulmod(z, z, p)
x := mulmod(x, z, p)
z := mulmod(x, x, p)
t := mulmod(z, z, p)
t := mulmod(t, t, p)
t := mulmod(z, t, p)
t := mulmod(x, t, p)
t := mulmod(t, t, p)
t := mulmod(t, t, p)
t := mulmod(t, t, p)
t := mulmod(t, t, p)
z := mulmod(z, t, p)
y := mulmod(y, z, p)
x := mulmod(x, y, p)
y := mulmod(y, x, p)
x := mulmod(x, y, p)
z := mulmod(x, x, p)
z := mulmod(x, z, p)
z := mulmod(z, z, p)
z := mulmod(z, z, p)
z := mulmod(z, z, p)
z := mulmod(x, z, p)
y := mulmod(y, z, p)
z := mulmod(y, y, p)
z := mulmod(y, z, p)
z := mulmod(z, z, p)
x := mulmod(x, z, p)
z := mulmod(x, x, p)
z := mulmod(x, z, p)
y := mulmod(y, z, p)
x := mulmod(x, y, p)
z := mulmod(x, x, p)
z := mulmod(z, z, p)
y := mulmod(y, z, p)
x := mulmod(x, y, p)
z := mulmod(x, x, p)
y := mulmod(y, z, p)
x := mulmod(x, y, p)
y := mulmod(y, x, p)
z := mulmod(y, y, p)
z := mulmod(y, z, p)
x := mulmod(x, z, p)
y := mulmod(y, x, p)
z := mulmod(y, y, p)
z := mulmod(y, z, p)
z := mulmod(z, z, p)
z := mulmod(z, z, p)
x := mulmod(x, z, p)
z := mulmod(x, x, p)
z := mulmod(z, z, p)
z := mulmod(z, z, p)
z := mulmod(x, z, p)
y := mulmod(y, z, p)
x := mulmod(x, y, p)
z := mulmod(x, x, p)
t := mulmod(x, z, p)
t := mulmod(t, t, p)
t := mulmod(t, t, p)
z := mulmod(z, t, p)
y := mulmod(y, z, p)
z := mulmod(y, y, p)
x := mulmod(x, z, p)
y := mulmod(y, x, p)
x := mulmod(x, y, p)
y := mulmod(y, x, p)
x := mulmod(x, y, p)
y := mulmod(y, x, p)
z := mulmod(y, y, p)
t := mulmod(y, z, p)
z := mulmod(y, t, p)
z := mulmod(z, z, p)
z := mulmod(z, z, p)
z := mulmod(t, z, p)
}
x := mulmod(x, z, p)
y := mulmod(y, x, p)
x := mulmod(x, y, p)
y := mulmod(y, x, p)
x := mulmod(x, y, p)
z := mulmod(x, x, p)
z := mulmod(x, z, p)
y := mulmod(y, z, p)
}
x := mulmod(x, y, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
x := mulmod(x, x, p)
y := mulmod(y, x, p)
}
}
``````
• That Gnosis function does not look like a normal square root at all. My guess is that it's a square root over some finite field, not integers. If you're just looking for a good sqrt implementation you can check OpenZeppelin of Paul Berg's library github.com/paulrberg/prb-math
– kfx
Dec 10, 2022 at 16:49