42
42
complete:
43
43
}
44
44
45
-
45
+ #define macro MODEXP() = takes (3) returns (1) {
46
+ dup1
47
+ iszero MODULUS_ZERO jumpi // Compare it to zero
48
+ MODULUS_NOT_ZERO jump
49
+
50
+ MODULUS_NOT_ZERO:
51
+ // Setting up correct memory layout
52
+ 0x20 0x00 mstore // Store length of base (32 bytes) at memory 0x00
53
+ 0x20 0x20 mstore // Store length of exponent (32 bytes) at memory 0x40
54
+ 0x20 0x40 mstore // Store length of modulus (32 bytes) at memory 0x80
55
+
56
+ swap2 // Bring 'base' to top
57
+ 0x60 mstore // Store 'base' at memory 0x20
58
+ swap1 // Bring 'exponent' to top
59
+ 0x80 mstore // Store 'exponent' at memory 0x60
60
+ 0xa0 mstore // Store 'modulus' at memory 0xa0
61
+
62
+ // Prepare staticcall to precompiled contract
63
+ gas // Provide all available gas for the call
64
+ 0x05 // Address of the modexp precompiled contract (0x05)
65
+ 0x00 0xc0 // Start of input data in memory (0x00) and input data size (192 bytes)
66
+ 0x00 0x20 // Start of output data in memory (0x00) and output data size (32 bytes)
67
+ staticcall
68
+
69
+ // Verify the call success
70
+ iszero STATIC_CALL_FAILED jump // Check if the staticcall was successful
71
+ CALL_SUCCESSFUL jump // If staticcall returned 0 (failure), revert
72
+
73
+ MODULUS_ZERO:
74
+ 0x00 0x00 revert // Revert if modulus is zero
75
+
76
+ STATIC_CALL_FAILED:
77
+ 0x00 0x00 revert // Revert if staticcall failed
78
+
79
+ // Label for call success
80
+ CALL_SUCCESSFUL:
81
+ 0x00 mload // Load the result from memory location 0x00
82
+ END jump // Jump to the end of the macro
83
+
84
+ END:
85
+ // The result of base^exponent % modulus is now on top of the stack
86
+ }
0 commit comments