Skip to content

Instantly share code, notes, and snippets.

@lionello
Last active March 17, 2022 13:07
Show Gist options
  • Save lionello/ee285ea220dc64517499c971ff92a2a5 to your computer and use it in GitHub Desktop.
Save lionello/ee285ea220dc64517499c971ff92a2a5 to your computer and use it in GitHub Desktop.
Solidity wrapper for Ethereum Byzantium's BigInt `modexp` built-in contract 0x5
pragma solidity ^0.4.17;
contract ModExp {
// Wrapper for built-in bigint_modexp (contract 0x5) as described here https://github.com/ethereum/EIPs/pull/198
function modexp(bytes memory _base, bytes memory _exp, bytes memory _mod) public view returns(bytes memory ret) {
uint256 bl = _base.length;
uint256 el = _exp.length;
uint256 ml = _mod.length;
assembly {
// Free memory pointer is always stored at 0x40
let freemem := mload(0x40)
// arg[0] = base.length @ +0
mstore(freemem, bl)
// arg[1] = exp.length @ +32
mstore(add(freemem,32), el)
// arg[2] = mod.length @ +64
mstore(add(freemem,64), ml)
// arg[3] = base.bits @ + 96
// Use identity built-in (contract 0x4) as a cheap memcpy
let success := call(450, 0x4, 0, add(_base,32), bl, add(freemem,96), bl)
// arg[4] = exp.bits @ +96+base.length
let size := add(96, bl)
success := call(450, 0x4, 0, add(_exp,32), el, add(freemem,size), el)
// arg[5] = mod.bits @ +96+base.length+exp.length
size := add(size,el)
success := call(450, 0x4, 0, add(_mod,32), ml, add(freemem,size), ml)
// Total size of input = 96+base.length+exp.length+mod.length
size := add(size,ml)
// Invoke contract 0x5, put return value right after mod.length, @ +96
success := call(sub(gas, 1350), 0x5, 0, freemem, size, add(96,freemem), ml)
// Return the location of the return value (length, bits)
ret := add(64,freemem)
}
}
}
@riordant
Copy link

+1.

@riordant
Copy link

you have to deallocate the freemem pointer at the end when using this function in the context of other functions which modify memory. I have appended this change in the fork I made.

@adolfommoyano
Copy link

Do you have this contract for new solidity versions? It keeps me logging errors in compiler. Thanks

@lionello
Copy link
Author

Do you have this contract for new solidity versions? It keeps me logging errors in compiler. Thanks

@adolfommoyano Have you checked @riordant 's fork?

@adolfommoyano
Copy link

Do you have this contract for new solidity versions? It keeps me logging errors in compiler. Thanks

@adolfommoyano Have you checked @riordant 's fork?

Hi, why is it important mod exp contract? I just need to verify sepc256r1 signatures in solidity. However I still dont know how. Can you please help me? Thanks

@lionello
Copy link
Author

@adolfommoyano Sorry, I haven't looked into Solidity for years, and am not really interested in doing so ever again. I suggest you join the Gitter channel https://gitter.im/ethereum/solidity/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment