diff --git a/contracts/certificate/signers/CECDSASHA2Signer.sol b/contracts/certificate/signers/CECDSASHA2Signer.sol index fefbae1..163375a 100644 --- a/contracts/certificate/signers/CECDSASHA2Signer.sol +++ b/contracts/certificate/signers/CECDSASHA2Signer.sol @@ -45,6 +45,8 @@ contract CECDSASHA2Signer is ICertificateSigner, Initializable { (inputs.r, inputs.s) = U384.init2(icaoMemberSignature_); (inputs.x, inputs.y) = U384.init2(icaoMemberKey_); + uint256 p = hex"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF" + .init(); // secp384r1 parameters Parameters memory params = Parameters({ a: hex"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC" @@ -55,13 +57,12 @@ contract CECDSASHA2Signer is ICertificateSigner, Initializable { .init(), gy: hex"3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f" .init(), - p: hex"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF" - .init(), + p: p, n: hex"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973" .init(), lowSmax: hex"7fffffffffffffffffffffffffffffffffffffffffffffffe3b1a6c0fa1b96efac0d06d9245853bd76760cb5666294b9" .init(), - call: U384.initCall(), + call: U384.initCall(p), three: U384.init(3) }); @@ -127,15 +128,15 @@ contract CECDSASHA2Signer is ICertificateSigner, Initializable { return false; } - uint256 LHS = U384.modexp(call, y, 2, p); - uint256 RHS = U384.modexp(call, x, 3, p); + uint256 LHS = U384.modexp(call, y, 2); + uint256 RHS = U384.modexp(call, x, 3); if (!U384.eqInteger(a, 0)) { - RHS = U384.modadd(call, RHS, U384.modmul(call, x, a, p), p); // x^3 + a*x + RHS = U384.modadd(call, RHS, U384.modmul(call, x, a)); // x^3 + a*x } if (!U384.eqInteger(b, 0)) { - RHS = U384.modadd(call, RHS, b, p); // x^3 + a*x + b + RHS = U384.modadd(call, RHS, b); // x^3 + a*x + b } return U384.eq(LHS, RHS); @@ -259,42 +260,42 @@ contract CECDSASHA2Signer is ICertificateSigner, Initializable { return (U384.init(0), U384.init(1), U384.init(0)); // zero proj } - uint256 u = U384.modmul(call, y0, z0, p); - U384.modshl1Assign(call, u, p); + uint256 u = U384.modmul(call, y0, z0); + U384.modshl1Assign(call, u); - x1 = U384.modmul(call, u, x0, p); - U384.modmulAssign(call, x1, y0, p); - U384.modshl1Assign(call, x1, p); + x1 = U384.modmul(call, u, x0); + U384.modmulAssign(call, x1, y0); + U384.modshl1Assign(call, x1); - x0 = U384.modexp(call, x0, 2, p); + x0 = U384.modexp(call, x0, 2); - y1 = U384.modmul(call, x0, three, p); + y1 = U384.modmul(call, x0, three); - z0 = U384.modexp(call, z0, 2, p); - U384.modmulAssign(call, z0, a, p); - U384.modaddAssign(call, y1, z0, p); + z0 = U384.modexp(call, z0, 2); + U384.modmulAssign(call, z0, a); + U384.modaddAssign(call, y1, z0); - z1 = U384.modexp(call, y1, 2, p); - U384.modshl1AssignTo(call, x0, x1, p); + z1 = U384.modexp(call, y1, 2); + U384.modshl1AssignTo(call, x0, x1); uint256 diff = U384.sub(p, x0); - U384.modaddAssign(call, z1, diff, p); + U384.modaddAssign(call, z1, diff); U384.subAssignTo(diff, p, z1); - U384.modaddAssignTo(call, x0, x1, diff, p); - U384.modmulAssign(call, x0, y1, p); + U384.modaddAssignTo(call, x0, x1, diff); + U384.modmulAssign(call, x0, y1); - y0 = U384.modmul(call, y0, u, p); - U384.modexpAssign(call, y0, 2, p); - U384.modshl1Assign(call, y0, p); + y0 = U384.modmul(call, y0, u); + U384.modexpAssign(call, y0, 2); + U384.modshl1Assign(call, y0); U384.subAssignTo(diff, p, y0); - U384.modaddAssignTo(call, y1, x0, diff, p); + U384.modaddAssignTo(call, y1, x0, diff); - U384.modmulAssignTo(call, x1, u, z1, p); + U384.modmulAssignTo(call, x1, u, z1); - U384.modexpAssignTo(call, z1, u, 2, p); - U384.modmulAssign(call, z1, u, p); + U384.modexpAssignTo(call, z1, u, 2); + U384.modmulAssign(call, z1, u); } } @@ -321,10 +322,10 @@ contract CECDSASHA2Signer is ICertificateSigner, Initializable { return (x0, y0, z0); } - x2 = U384.modmul(call, y0, z1, p); - y2 = U384.modmul(call, y1, z0, p); - z2 = U384.modmul(call, x0, z1, p); - y1 = U384.modmul(call, x1, z0, p); + x2 = U384.modmul(call, y0, z1); + y2 = U384.modmul(call, y1, z0); + z2 = U384.modmul(call, x0, z1); + y1 = U384.modmul(call, x1, z0); if (U384.eq(z2, y1)) { if (U384.eq(x2, y2)) { @@ -334,7 +335,7 @@ contract CECDSASHA2Signer is ICertificateSigner, Initializable { } } - a = U384.modmul(call, z0, z1, p); + a = U384.modmul(call, z0, z1); return _addProj2(call, a, z2, p, y1, y2, x2); } @@ -354,35 +355,35 @@ contract CECDSASHA2Signer is ICertificateSigner, Initializable { ) internal view returns (uint256 x2, uint256 y2, uint256 z2) { unchecked { uint256 diff = U384.sub(p, t1); - y2 = U384.modadd(call, t0, diff, p); + y2 = U384.modadd(call, t0, diff); U384.subAssignTo(diff, p, u1); - x2 = U384.modadd(call, u0, diff, p); - uint256 u2 = U384.modexp(call, x2, 2, p); + x2 = U384.modadd(call, u0, diff); + uint256 u2 = U384.modexp(call, x2, 2); - z2 = U384.modexp(call, y2, 2, p); + z2 = U384.modexp(call, y2, 2); - U384.modmulAssign(call, z2, v, p); - u1 = U384.modadd(call, u1, u0, p); - U384.modmulAssign(call, u1, u2, p); + U384.modmulAssign(call, z2, v); + u1 = U384.modadd(call, u1, u0); + U384.modmulAssign(call, u1, u2); U384.subAssignTo(diff, p, u1); - U384.modaddAssign(call, z2, diff, p); + U384.modaddAssign(call, z2, diff); - uint256 u3 = U384.modmul(call, u2, x2, p); + uint256 u3 = U384.modmul(call, u2, x2); - U384.modmulAssign(call, x2, z2, p); + U384.modmulAssign(call, x2, z2); - u0 = U384.modmul(call, u0, u2, p); + u0 = U384.modmul(call, u0, u2); U384.subAssignTo(diff, p, z2); - U384.modaddAssign(call, u0, diff, p); - U384.modmulAssign(call, y2, u0, p); - t0 = U384.modmul(call, t0, u3, p); + U384.modaddAssign(call, u0, diff); + U384.modmulAssign(call, y2, u0); + t0 = U384.modmul(call, t0, u3); U384.subAssignTo(diff, p, t0); - U384.modaddAssign(call, y2, diff, p); + U384.modaddAssign(call, y2, diff); - U384.modmulAssignTo(call, z2, u3, v, p); + U384.modmulAssignTo(call, z2, u3, v); } } } diff --git a/contracts/utils/U384.sol b/contracts/utils/U384.sol index d4f0716..95a9376 100644 --- a/contracts/utils/U384.sol +++ b/contracts/utils/U384.sol @@ -4,7 +4,12 @@ pragma solidity 0.8.16; library U384 { uint256 private constant SHORT_ALLOCATION = 64; uint256 private constant LONG_ALLOCATION = 96; - uint256 private constant CALL_ALLOCATION = 288; + uint256 private constant CALL_ALLOCATION = 5 * 288; + + uint256 private constant MUL_OFFSET = 288; + uint256 private constant ADD_OFFSET = 2 * 288; + uint256 private constant EXP_OFFSET = 3 * 288; + uint256 private constant SHL1_OFFSET = 4 * 288; function init(uint256 from_) internal pure returns (uint256 handler_) { unchecked { @@ -72,9 +77,46 @@ library U384 { } } - function initCall() internal pure returns (uint256 handler_) { + function initCall(uint256 m_) internal pure returns (uint256 handler_) { unchecked { - return _allocate(CALL_ALLOCATION); + handler_ = _allocate(CALL_ALLOCATION); + + assembly { + let call_ := add(handler_, MUL_OFFSET) + + mstore(call_, 0x60) + mstore(add(0x20, call_), 0x20) + mstore(add(0x40, call_), 0x40) + mstore(add(0xC0, call_), 0x01) + mstore(add(0xE0, call_), mload(m_)) + mstore(add(0x0100, call_), mload(add(m_, 0x20))) + + call_ := add(handler_, ADD_OFFSET) + + mstore(call_, 0x40) + mstore(add(0x20, call_), 0x20) + mstore(add(0x40, call_), 0x40) + mstore(add(0xA0, call_), 0x01) + mstore(add(0xC0, call_), mload(m_)) + mstore(add(0xE0, call_), mload(add(m_, 0x20))) + + call_ := add(handler_, EXP_OFFSET) + + mstore(call_, 0x40) + mstore(add(0x20, call_), 0x20) + mstore(add(0x40, call_), 0x40) + mstore(add(0xC0, call_), mload(m_)) + mstore(add(0xE0, call_), mload(add(m_, 0x20))) + + call_ := add(handler_, SHL1_OFFSET) + + mstore(call_, 0x40) + mstore(add(0x20, call_), 0x20) + mstore(add(0x40, call_), 0x40) + mstore(add(0xA0, call_), 0x01) + mstore(add(0xC0, call_), mload(m_)) + mstore(add(0xE0, call_), mload(add(m_, 0x20))) + } } } @@ -165,21 +207,17 @@ library U384 { function modexp( uint256 call_, uint256 b_, - uint256 eInteger_, - uint256 m_ + uint256 eInteger_ ) internal view returns (uint256 r_) { unchecked { r_ = _allocate(SHORT_ALLOCATION); assembly { - mstore(call_, 0x40) - mstore(add(0x20, call_), 0x20) - mstore(add(0x40, call_), 0x40) + call_ := add(call_, EXP_OFFSET) + mstore(add(0x60, call_), mload(b_)) mstore(add(0x80, call_), mload(add(b_, 0x20))) mstore(add(0xA0, call_), eInteger_) - mstore(add(0xC0, call_), mload(m_)) - mstore(add(0xE0, call_), mload(add(m_, 0x20))) pop(staticcall(gas(), 0x5, call_, 0x0100, r_, 0x40)) } @@ -188,16 +226,13 @@ library U384 { } } - function modexpAssign(uint256 call_, uint256 b_, uint256 eInteger_, uint256 m_) internal view { + function modexpAssign(uint256 call_, uint256 b_, uint256 eInteger_) internal view { assembly { - mstore(call_, 0x40) - mstore(add(0x20, call_), 0x20) - mstore(add(0x40, call_), 0x40) + call_ := add(call_, EXP_OFFSET) + mstore(add(0x60, call_), mload(b_)) mstore(add(0x80, call_), mload(add(b_, 0x20))) mstore(add(0xA0, call_), eInteger_) - mstore(add(0xC0, call_), mload(m_)) - mstore(add(0xE0, call_), mload(add(m_, 0x20))) pop(staticcall(gas(), 0x5, call_, 0x0100, b_, 0x40)) } @@ -207,41 +242,27 @@ library U384 { uint256 call_, uint256 to_, uint256 b_, - uint256 eInteger_, - uint256 m_ + uint256 eInteger_ ) internal view { assembly { - mstore(call_, 0x40) - mstore(add(0x20, call_), 0x20) - mstore(add(0x40, call_), 0x40) + call_ := add(call_, EXP_OFFSET) + mstore(add(0x60, call_), mload(b_)) mstore(add(0x80, call_), mload(add(b_, 0x20))) mstore(add(0xA0, call_), eInteger_) - mstore(add(0xC0, call_), mload(m_)) - mstore(add(0xE0, call_), mload(add(m_, 0x20))) pop(staticcall(gas(), 0x5, call_, 0x0100, to_, 0x40)) } } - function modadd( - uint256 call_, - uint256 a_, - uint256 b_, - uint256 m_ - ) internal view returns (uint256 r_) { + function modadd(uint256 call_, uint256 a_, uint256 b_) internal view returns (uint256 r_) { unchecked { r_ = _allocate(SHORT_ALLOCATION); - _add(a_, b_, call_ + 0x60); + _add(a_, b_, call_ + ADD_OFFSET + 0x60); assembly { - mstore(call_, 0x40) - mstore(add(0x20, call_), 0x20) - mstore(add(0x40, call_), 0x40) - mstore(add(0xA0, call_), 0x01) - mstore(add(0xC0, call_), mload(m_)) - mstore(add(0xE0, call_), mload(add(m_, 0x20))) + call_ := add(call_, ADD_OFFSET) pop(staticcall(gas(), 0x5, call_, 0x0100, r_, 0x40)) } @@ -250,54 +271,30 @@ library U384 { } } - function modaddAssign(uint256 call_, uint256 a_, uint256 b_, uint256 m_) internal view { + function modaddAssign(uint256 call_, uint256 a_, uint256 b_) internal view { unchecked { - _add(a_, b_, call_ + 0x60); + _add(a_, b_, call_ + ADD_OFFSET + 0x60); assembly { - mstore(call_, 0x40) - mstore(add(0x20, call_), 0x20) - mstore(add(0x40, call_), 0x40) - mstore(add(0xA0, call_), 0x01) - mstore(add(0xC0, call_), mload(m_)) - mstore(add(0xE0, call_), mload(add(m_, 0x20))) + call_ := add(call_, ADD_OFFSET) pop(staticcall(gas(), 0x5, call_, 0x0100, a_, 0x40)) } } } - function modaddAssignTo( - uint256 call_, - uint256 to_, - uint256 a_, - uint256 b_, - uint256 m_ - ) internal view { + function modaddAssignTo(uint256 call_, uint256 to_, uint256 a_, uint256 b_) internal view { unchecked { - _add(a_, b_, call_ + 0x60); + _add(a_, b_, call_ + ADD_OFFSET + 0x60); assembly { - mstore(call_, 0x40) - mstore(add(0x20, call_), 0x20) - mstore(add(0x40, call_), 0x40) - mstore(add(0xA0, call_), 0x01) - mstore(add(0xC0, call_), mload(m_)) - mstore(add(0xE0, call_), mload(add(m_, 0x20))) + call_ := add(call_, ADD_OFFSET) pop(staticcall(gas(), 0x5, call_, 0x0100, to_, 0x40)) } } } - function mod(uint256 call_, uint256 a_, uint256 m_) internal view returns (uint256 r_) { - unchecked { - r_ = modexp(call_, a_, 1, m_); - - return r_; - } - } - function modsub( uint256 call_, uint256 a_, @@ -324,24 +321,14 @@ library U384 { } } - function modmul( - uint256 call_, - uint256 a_, - uint256 b_, - uint256 m_ - ) internal view returns (uint256 r_) { + function modmul(uint256 call_, uint256 a_, uint256 b_) internal view returns (uint256 r_) { unchecked { r_ = _allocate(SHORT_ALLOCATION); - _mul(a_, b_, call_ + 0x60); + _mul(a_, b_, call_ + MUL_OFFSET + 0x60); assembly { - mstore(call_, 0x60) - mstore(add(0x20, call_), 0x20) - mstore(add(0x40, call_), 0x40) - mstore(add(0xC0, call_), 0x01) - mstore(add(0xE0, call_), mload(m_)) - mstore(add(0x0100, call_), mload(add(m_, 0x20))) + call_ := add(call_, MUL_OFFSET) pop(staticcall(gas(), 0x5, call_, 0x0120, r_, 0x40)) } @@ -350,93 +337,30 @@ library U384 { } } - function modmulAssign(uint256 call_, uint256 a_, uint256 b_, uint256 m_) internal view { + function modmulAssign(uint256 call_, uint256 a_, uint256 b_) internal view { unchecked { - _mul(a_, b_, call_ + 0x60); + _mul(a_, b_, call_ + MUL_OFFSET + 0x60); assembly { - mstore(call_, 0x60) - mstore(add(0x20, call_), 0x20) - mstore(add(0x40, call_), 0x40) - mstore(add(0xC0, call_), 0x01) - mstore(add(0xE0, call_), mload(m_)) - mstore(add(0x0100, call_), mload(add(m_, 0x20))) + call_ := add(call_, MUL_OFFSET) pop(staticcall(gas(), 0x5, call_, 0x0120, a_, 0x40)) } } } - function modmulAssignTo( - uint256 call_, - uint256 to_, - uint256 a_, - uint256 b_, - uint256 m_ - ) internal view { + function modmulAssignTo(uint256 call_, uint256 to_, uint256 a_, uint256 b_) internal view { unchecked { - _mul(a_, b_, call_ + 0x60); + _mul(a_, b_, call_ + MUL_OFFSET + 0x60); assembly { - mstore(call_, 0x60) - mstore(add(0x20, call_), 0x20) - mstore(add(0x40, call_), 0x40) - mstore(add(0xC0, call_), 0x01) - mstore(add(0xE0, call_), mload(m_)) - mstore(add(0x0100, call_), mload(add(m_, 0x20))) + call_ := add(call_, MUL_OFFSET) pop(staticcall(gas(), 0x5, call_, 0x0120, to_, 0x40)) } } } - function modinv(uint256 call_, uint256 b_, uint256 m_) internal view returns (uint256 r_) { - unchecked { - r_ = _allocate(SHORT_ALLOCATION); - - _sub(m_, init(2), call_ + 0xA0); - - assembly { - mstore(call_, 0x40) - mstore(add(0x20, call_), 0x40) - mstore(add(0x40, call_), 0x40) - mstore(add(0x60, call_), mload(b_)) - mstore(add(0x80, call_), mload(add(b_, 0x20))) - mstore(add(0xE0, call_), mload(m_)) - mstore(add(0x0100, call_), mload(add(m_, 0x20))) - - pop(staticcall(gas(), 0x5, call_, 0x0120, r_, 0x40)) - } - } - } - - function moddiv( - uint256 call_, - uint256 a_, - uint256 b_, - uint256 m_ - ) internal view returns (uint256 r_) { - unchecked { - r_ = _allocate(SHORT_ALLOCATION); - - _sub(m_, init(2), call_ + 0xA0); - - assembly { - mstore(call_, 0x40) - mstore(add(0x20, call_), 0x40) - mstore(add(0x40, call_), 0x40) - mstore(add(0x60, call_), mload(b_)) - mstore(add(0x80, call_), mload(add(b_, 0x20))) - mstore(add(0xE0, call_), mload(m_)) - mstore(add(0x0100, call_), mload(add(m_, 0x20))) - - pop(staticcall(gas(), 0x5, call_, 0x0120, r_, 0x40)) - } - - return modmul(call_, a_, r_, m_); - } - } - function add(uint256 a_, uint256 b_) internal pure returns (uint256 r_) { unchecked { r_ = _allocate(SHORT_ALLOCATION); @@ -479,53 +403,38 @@ library U384 { } } - function modshl1(uint256 call_, uint256 a_, uint256 m_) internal view returns (uint256 r_) { + function modshl1(uint256 call_, uint256 a_) internal view returns (uint256 r_) { unchecked { r_ = _allocate(SHORT_ALLOCATION); - _shl1(a_, call_ + 0x60); + _shl1(a_, call_ + SHL1_OFFSET + 0x60); assembly { - mstore(call_, 0x40) - mstore(add(0x20, call_), 0x20) - mstore(add(0x40, call_), 0x40) - mstore(add(0xA0, call_), 0x01) - mstore(add(0xC0, call_), mload(m_)) - mstore(add(0xE0, call_), mload(add(m_, 0x20))) + call_ := add(call_, SHL1_OFFSET) pop(staticcall(gas(), 0x5, call_, 0x0100, r_, 0x40)) } } } - function modshl1Assign(uint256 call_, uint256 a_, uint256 m_) internal view { + function modshl1Assign(uint256 call_, uint256 a_) internal view { unchecked { - _shl1(a_, call_ + 0x60); + _shl1(a_, call_ + SHL1_OFFSET + 0x60); assembly { - mstore(call_, 0x40) - mstore(add(0x20, call_), 0x20) - mstore(add(0x40, call_), 0x40) - mstore(add(0xA0, call_), 0x01) - mstore(add(0xC0, call_), mload(m_)) - mstore(add(0xE0, call_), mload(add(m_, 0x20))) + call_ := add(call_, SHL1_OFFSET) pop(staticcall(gas(), 0x5, call_, 0x0100, a_, 0x40)) } } } - function modshl1AssignTo(uint256 call_, uint256 to_, uint256 a_, uint256 m_) internal view { + function modshl1AssignTo(uint256 call_, uint256 to_, uint256 a_) internal view { unchecked { - _shl1(a_, call_ + 0x60); + _shl1(a_, call_ + SHL1_OFFSET + 0x60); assembly { - mstore(call_, 0x40) - mstore(add(0x20, call_), 0x20) - mstore(add(0x40, call_), 0x40) - mstore(add(0xA0, call_), 0x01) - mstore(add(0xC0, call_), mload(m_)) - mstore(add(0xE0, call_), mload(add(m_, 0x20))) + call_ := add(call_, SHL1_OFFSET) pop(staticcall(gas(), 0x5, call_, 0x0100, to_, 0x40)) } @@ -637,6 +546,71 @@ library U384 { } } + function moddiv( + uint256 call_, + uint256 a_, + uint256 b_, + uint256 m_ + ) internal view returns (uint256 r_) { + unchecked { + r_ = modinv(call_, b_, m_); + + _mul(a_, r_, call_ + 0x60); + + assembly { + mstore(call_, 0x60) + mstore(add(0x20, call_), 0x20) + mstore(add(0x40, call_), 0x40) + mstore(add(0xC0, call_), 0x01) + mstore(add(0xE0, call_), mload(m_)) + mstore(add(0x0100, call_), mload(add(m_, 0x20))) + + pop(staticcall(gas(), 0x5, call_, 0x0120, r_, 0x40)) + } + } + } + + function modinv(uint256 call_, uint256 b_, uint256 m_) internal view returns (uint256 r_) { + unchecked { + r_ = _allocate(SHORT_ALLOCATION); + + _sub(m_, init(2), call_ + 0xA0); + + assembly { + mstore(call_, 0x40) + mstore(add(0x20, call_), 0x40) + mstore(add(0x40, call_), 0x40) + mstore(add(0x60, call_), mload(b_)) + mstore(add(0x80, call_), mload(add(b_, 0x20))) + mstore(add(0xE0, call_), mload(m_)) + mstore(add(0x0100, call_), mload(add(m_, 0x20))) + + pop(staticcall(gas(), 0x5, call_, 0x0120, r_, 0x40)) + } + } + } + + function mod(uint256 call_, uint256 a_, uint256 m_) internal view returns (uint256 r_) { + unchecked { + r_ = _allocate(SHORT_ALLOCATION); + + assembly { + mstore(call_, 0x40) + mstore(add(0x20, call_), 0x20) + mstore(add(0x40, call_), 0x40) + mstore(add(0x60, call_), mload(a_)) + mstore(add(0x80, call_), mload(add(a_, 0x20))) + mstore(add(0xA0, call_), 0x01) + mstore(add(0xC0, call_), mload(m_)) + mstore(add(0xE0, call_), mload(add(m_, 0x20))) + + pop(staticcall(gas(), 0x5, call_, 0x0100, r_, 0x40)) + } + + return r_; + } + } + function _allocate(uint256 bytes_) private pure returns (uint256 handler_) { unchecked { assembly {