Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

Solid Reverse

Crypto in reverse??

Solution

From the contract, we need to figure out the key, and flag is just xor of key and goal.

Check the key function:

modifier checker(bytes16 key) {
    require(bytes8(key) == 0x3492800100670155, "Wrong key!");
    require(uint64(uint128(key)) == uint32(uint128(key)), "Wrong key!");
    require(magic1(uint128(key), 16) == 0x1964, "Wrong key!");
    require(magic2(uint64(uint128(key))) == 16, "Wrong key!");
    _;
}

In Solidity, when type casting bytes16 to bytes8, it will only take the first 8 bytes. So we know the first 8 bytes of key is 0x3492800100670155.

On the other hand, uint casting take the lower bits. Given uint64 and uint32 of cast are equal, we know the first 4 bytes of lower half of key is 0x00000000.

Reading source code, we know magic1(x, n) will get the last n bits of x, so last 2 bytes of key is 0x1964. We also know magic2(x) returns the index of the first 1 bit, because it is 16, we come to know key[12:14] = 0x0001. (0x0000 will yield 15, and 0x0010 will yield 17.)

The whole key is 0x34928001006701550000000000011964. We now know the flag: 0x34928001006701550000000000011964 ^ 0x57e4e375661c72654c31645f78455d19 = 0x63766374667b73304c31645f7844447d, or cvctf{s0L1d_xDD}.