1

I am wondering how the precompiled contract at address 5 (introduced by EIP-198) can actually be used to do RSA signature verification in Solidity, i.e., how it can be called by another contract (implemented in Solidity) with big integers (larger than 32 byte), e.g., a 4096-bit RSA modulus.

I am aware of the code provided in https://ethereum.stackexchange.com/a/71590. However, the solution focuses on modular exponentiation in which each component (base, exponent, modulus) can be represented with a variable of type uint256. With the RSA modulus typically being of size 1,024 or 2,048 or 4,096 (bits), this solution does not seem to be sufficient to do RSA signature verification. Hence, I am wondering how the solution can be extended to send and receive big integers (represented as bytes) to the precompiled contract. (Note: As RSA verification in practice usually uses an exponent of 3 or 65537, the exponent does not need to be of type bytes)

I would imagine a function for modular exponentation with a 4,096-bit RSA modulus to look (more or less) like this:

function modExp(bytes memory _b, uint _e, bytes memory _m) public returns (bytes memory result) {
 assembly {
    // Free memory pointer
    let pointer := mload(0x40)

    // Define length of base, exponent and modulus. Exponent = 32 bytes (0x20), base and modulus = 4096 bit (0x1000)
    mstore(pointer, 0x1000)
    mstore(add(pointer, 0x20), 0x20)
    mstore(add(pointer, 0x40), 0x1000)

    // Define variables base, exponent and modulus
    mstore(add(pointer, 0x60), _b)
    mstore(add(pointer, 0x1060), _e) //position increments by 0x1000 as _b is of size 0x1000
    mstore(add(pointer, 0x1080), _m) //position increments by 0x20 as _e is of size 0x20

    // Store the result
    let value := mload(0x2080) //position increments by 0x1000 as _m is of size 0x1000

    // Call the precompiled contract 0x05 = bigModExp
    if iszero(call(not(0), 0x05, 0, pointer, 0xc0, value, 0x20)) {
        revert(0, 0)
    }

    result := mload(value)
}

}

Thanks!

DavidK
  • 11
  • 1

1 Answers1

0

you can use the library implementation here to do what you want, it also has RSA signature verification examples:

https://github.com/firoorg/solidity-BigNumber

riordant
  • 89
  • 10