Skip to content

Commit

Permalink
added mod optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
dovgopoly committed Nov 8, 2024
1 parent c813f13 commit 10bd47f
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 93 deletions.
32 changes: 16 additions & 16 deletions contracts/certificate/signers/CECDSASHA2Signer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,11 @@ contract CECDSASHA2Signer is ICertificateSigner, Initializable {
uint256 RHS = U384.modexp(call, x, 3, p);

if (!U384.eqInteger(a, 0)) {
RHS = U384.modadd(call, RHS, U384.modmul(call, x, a, p), p); // x^3 + a*x
RHS = U384.modadd(RHS, U384.modmul(call, x, a, p), p); // x^3 + a*x
}

if (!U384.eqInteger(b, 0)) {
RHS = U384.modadd(call, RHS, b, p); // x^3 + a*x + b
RHS = U384.modadd(RHS, b, p); // x^3 + a*x + b
}

return U384.eq(LHS, RHS);
Expand Down Expand Up @@ -237,36 +237,36 @@ contract CECDSASHA2Signer is ICertificateSigner, Initializable {
}

uint256 u = U384.modmul(call, y0, z0, p);
U384.modshl1Assign(call, u, p);
U384.modshl1Assign(u, p);

x1 = U384.modmul(call, u, x0, p);
U384.modmulAssign(call, x1, y0, p);
U384.modshl1Assign(call, x1, p);
U384.modshl1Assign(x1, p);

x0 = U384.modexp(call, x0, 2, p);

y1 = U384.modmul(call, x0, three, p);

z0 = U384.modexp(call, z0, 2, p);
U384.modmulAssign(call, z0, a, p);
U384.modaddAssign(call, y1, z0, p);
U384.modaddAssign(y1, z0, p);

z1 = U384.modexp(call, y1, 2, p);
U384.modshl1AssignTo(call, x0, x1, p);
U384.modshl1AssignTo(x0, x1, p);

uint256 diff = U384.sub(p, x0);
U384.modaddAssign(call, z1, diff, p);
U384.modaddAssign(z1, diff, p);

U384.subAssignTo(diff, p, z1);
U384.modaddAssignTo(call, x0, x1, diff, p);
U384.modaddAssignTo(x0, x1, diff, p);
U384.modmulAssign(call, x0, y1, p);

y0 = U384.modmul(call, y0, u, p);
U384.modexpAssign(call, y0, 2, p);
U384.modshl1Assign(call, y0, p);
U384.modshl1Assign(y0, p);

U384.subAssignTo(diff, p, y0);
U384.modaddAssignTo(call, y1, x0, diff, p);
U384.modaddAssignTo(y1, x0, diff, p);

U384.modmulAssignTo(call, x1, u, z1, p);

Expand Down Expand Up @@ -331,19 +331,19 @@ 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(t0, diff, p);

U384.subAssignTo(diff, p, u1);
x2 = U384.modadd(call, u0, diff, p);
x2 = U384.modadd(u0, diff, p);
uint256 u2 = U384.modexp(call, x2, 2, p);

z2 = U384.modexp(call, y2, 2, p);

U384.modmulAssign(call, z2, v, p);
u1 = U384.modadd(call, u1, u0, p);
u1 = U384.modadd(u1, u0, p);
U384.modmulAssign(call, u1, u2, p);
U384.subAssignTo(diff, p, u1);
U384.modaddAssign(call, z2, diff, p);
U384.modaddAssign(z2, diff, p);

uint256 u3 = U384.modmul(call, u2, x2, p);

Expand All @@ -352,12 +352,12 @@ contract CECDSASHA2Signer is ICertificateSigner, Initializable {
u0 = U384.modmul(call, u0, u2, p);

U384.subAssignTo(diff, p, z2);
U384.modaddAssign(call, u0, diff, p);
U384.modaddAssign(u0, diff, p);
U384.modmulAssign(call, y2, u0, p);
t0 = U384.modmul(call, t0, u3, p);

U384.subAssignTo(diff, p, t0);
U384.modaddAssign(call, y2, diff, p);
U384.modaddAssign(y2, diff, p);

U384.modmulAssignTo(call, z2, u3, v, p);
}
Expand Down
141 changes: 64 additions & 77 deletions contracts/utils/U384.sol
Original file line number Diff line number Diff line change
Expand Up @@ -224,68 +224,36 @@ library U384 {
}
}

function modadd(
uint256 call_,
uint256 a_,
uint256 b_,
uint256 m_
) internal view returns (uint256 r_) {
function modadd(uint256 a_, uint256 b_, uint256 m_) internal view returns (uint256 r_) {
unchecked {
r_ = _allocate(SHORT_ALLOCATION);

_add(a_, b_, call_ + 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)))
_add(a_, b_, r_);

pop(staticcall(gas(), 0x5, call_, 0x0100, r_, 0x40))
if (cmp(r_, m_) >= 0) {
_subFrom(r_, m_);
}

return r_;
}
}

function modaddAssign(uint256 call_, uint256 a_, uint256 b_, uint256 m_) internal view {
function modaddAssign(uint256 a_, uint256 b_, uint256 m_) internal view {
unchecked {
_add(a_, b_, call_ + 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)))
_addTo(a_, b_);

pop(staticcall(gas(), 0x5, call_, 0x0100, a_, 0x40))
if (cmp(a_, m_) >= 0) {
return _subFrom(a_, m_);
}
}
}

function modaddAssignTo(
uint256 call_,
uint256 to_,
uint256 a_,
uint256 b_,
uint256 m_
) internal view {
function modaddAssignTo(uint256 to_, uint256 a_, uint256 b_, uint256 m_) internal view {
unchecked {
_add(a_, b_, call_ + 0x60);
_add(a_, b_, to_);

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)))

pop(staticcall(gas(), 0x5, call_, 0x0100, to_, 0x40))
if (cmp(to_, m_) >= 0) {
return _subFrom(to_, m_);
}
}
}
Expand Down Expand Up @@ -479,55 +447,36 @@ library U384 {
}
}

function modshl1(uint256 call_, uint256 a_, uint256 m_) internal view returns (uint256 r_) {
function modshl1(uint256 a_, uint256 m_) internal view returns (uint256 r_) {
unchecked {
r_ = _allocate(SHORT_ALLOCATION);

_shl1(a_, call_ + 0x60);
_shl1(a_, r_);

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)))

pop(staticcall(gas(), 0x5, call_, 0x0100, r_, 0x40))
if (cmp(r_, m_) >= 0) {
_subFrom(r_, m_);
}

return r_;
}
}

function modshl1Assign(uint256 call_, uint256 a_, uint256 m_) internal view {
function modshl1Assign(uint256 a_, uint256 m_) internal view {
unchecked {
_shl1(a_, call_ + 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)))
_shl1To(a_);

pop(staticcall(gas(), 0x5, call_, 0x0100, a_, 0x40))
if (cmp(a_, m_) >= 0) {
_subFrom(a_, m_);
}
}
}

function modshl1AssignTo(uint256 call_, uint256 to_, uint256 a_, uint256 m_) internal view {
function modshl1AssignTo(uint256 to_, uint256 a_, uint256 m_) internal view {
unchecked {
_shl1(a_, call_ + 0x60);
_shl1(a_, to_);

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)))

pop(staticcall(gas(), 0x5, call_, 0x0100, to_, 0x40))
if (cmp(to_, m_) >= 0) {
_subFrom(to_, m_);
}
}
}
Expand All @@ -542,6 +491,16 @@ library U384 {
}
}

function _shl1To(uint256 a_) internal pure {
assembly {
let a0_ := mload(a_)
let a1_ := mload(add(a_, 0x20))

mstore(a_, or(shl(1, a0_), shr(255, a1_)))
mstore(add(a_, 0x20), shl(1, a1_))
}
}

function _add(uint256 a_, uint256 b_, uint256 r_) private pure {
assembly {
let aWord_ := mload(add(a_, 0x20))
Expand Down Expand Up @@ -570,6 +529,34 @@ library U384 {
}
}

function _subFrom(uint256 a_, uint256 b_) private pure {
assembly {
let aWord_ := mload(add(a_, 0x20))
let diff_ := sub(aWord_, mload(add(b_, 0x20)))

mstore(add(a_, 0x20), diff_)

diff_ := gt(diff_, aWord_)
diff_ := sub(sub(mload(a_), mload(b_)), diff_)

mstore(a_, diff_)
}
}

function _addTo(uint256 a_, uint256 b_) private pure {
assembly {
let aWord_ := mload(add(a_, 0x20))
let sum_ := add(aWord_, mload(add(b_, 0x20)))

mstore(add(a_, 0x20), sum_)

sum_ := gt(aWord_, sum_)
sum_ := add(sum_, add(mload(a_), mload(b_)))

mstore(a_, sum_)
}
}

function _mul(uint256 a_, uint256 b_, uint256 r_) private view {
assembly {
let a0_ := mload(a_)
Expand Down

0 comments on commit 10bd47f

Please sign in to comment.