Skip to content

Commit 9b24014

Browse files
committed
Manage to compile without via-ir
1 parent c6a86d9 commit 9b24014

File tree

2 files changed

+56
-41
lines changed

2 files changed

+56
-41
lines changed

contracts/utils/cryptography/P256.sol

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -164,36 +164,37 @@ library P256 {
164164
}
165165

166166
/**
167-
* @dev Point addition on the jacobian coordinates
167+
* @dev Point addition on the jacobian coordinates.
168+
*
169+
* Computation is assisted by Solidity's memory. It takes x1 and y1 arguments from the scratch space
170+
* and returns x' and y' to the scratch space.
171+
*
168172
* Reference: https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-add-1998-cmo-2
169173
*/
170-
function _jAdd(
171-
uint256 x1,
172-
uint256 y1,
173-
uint256 z1,
174-
uint256 x2,
175-
uint256 y2,
176-
uint256 z2
177-
) private pure returns (uint256 rx, uint256 ry, uint256 rz) {
174+
function _jAddMemoryAssisted(uint256 z1, uint256 x2, uint256 y2, uint256 z2) private pure returns (uint256 rz) {
178175
assembly ("memory-safe") {
179176
let p := P
177+
180178
let zz1 := mulmod(z1, z1, p) // zz1 = z1²
181179
let zz2 := mulmod(z2, z2, p) // zz2 = z2²
182-
let u1 := mulmod(x1, zz2, p) // u1 = x1*z2²
180+
let u1 := mulmod(mload(0x00), zz2, p) // u1 = x1*z2²
183181
let u2 := mulmod(x2, zz1, p) // u2 = x2*z1²
184-
let s1 := mulmod(y1, mulmod(zz2, z2, p), p) // s1 = y1*z2³
182+
let s1 := mulmod(mload(0x20), mulmod(zz2, z2, p), p) // s1 = y1*z2³
185183
let s2 := mulmod(y2, mulmod(zz1, z1, p), p) // s2 = y2*z1³
186184
let h := addmod(u2, sub(p, u1), p) // h = u2-u1
185+
rz := mulmod(h, mulmod(z1, z2, p), p)
187186
let hh := mulmod(h, h, p) // h²
188187
let hhh := mulmod(h, hh, p) // h³
189188
let r := addmod(s2, sub(p, s1), p) // r = s2-s1
190189

191190
// x' = r²-h³-2*u1*h²
192-
rx := addmod(addmod(mulmod(r, r, p), sub(p, hhh), p), sub(p, mulmod(2, mulmod(u1, hh, p), p)), p)
191+
mstore(0x00, addmod(addmod(mulmod(r, r, p), sub(p, hhh), p), sub(p, mulmod(2, mulmod(u1, hh, p), p)), p))
192+
193193
// y' = r*(u1*h²-x')-s1*h³
194-
ry := addmod(mulmod(r, addmod(mulmod(u1, hh, p), sub(p, rx), p), p), sub(p, mulmod(s1, hhh, p)), p)
195-
// z' = h*z1*z2
196-
rz := mulmod(h, mulmod(z1, z2, p), p)
194+
mstore(
195+
0x20,
196+
addmod(mulmod(r, addmod(mulmod(u1, hh, p), sub(p, mload(0)), p), p), sub(p, mulmod(s1, hhh, p)), p)
197+
)
197198
}
198199
}
199200

@@ -244,7 +245,9 @@ library P256 {
244245
if (z == 0) {
245246
(x, y, z) = (points[pos].x, points[pos].y, points[pos].z);
246247
} else {
247-
(x, y, z) = _jAdd(x, y, z, points[pos].x, points[pos].y, points[pos].z);
248+
_toScratchMemory(x, y);
249+
(z) = _jAddMemoryAssisted(z, points[pos].x, points[pos].y, points[pos].z);
250+
(x, y) = _fromScratchMemory();
248251
}
249252
}
250253
u1 <<= 2;
@@ -287,12 +290,27 @@ library P256 {
287290
}
288291

289292
function _jAddPoint(JPoint memory p1, JPoint memory p2) private pure returns (JPoint memory) {
290-
(uint256 x, uint256 y, uint256 z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);
293+
_toScratchMemory(p1.x, p1.y);
294+
uint256 z = _jAddMemoryAssisted(p1.z, p2.x, p2.y, p2.z);
295+
(uint256 x, uint256 y) = _fromScratchMemory();
291296
return JPoint(x, y, z);
292297
}
293298

294299
function _jDoublePoint(JPoint memory p) private pure returns (JPoint memory) {
295300
(uint256 x, uint256 y, uint256 z) = _jDouble(p.x, p.y, p.z);
296301
return JPoint(x, y, z);
297302
}
303+
304+
function _toScratchMemory(uint256 x, uint256 y) private pure {
305+
assembly ("memory-safe") {
306+
mstore(0x00, x)
307+
mstore(0x20, y)
308+
}
309+
}
310+
function _fromScratchMemory() private pure returns (uint256 x, uint256 y) {
311+
assembly ("memory-safe") {
312+
x := mload(0x00)
313+
y := mload(0x20)
314+
}
315+
}
298316
}

hardhat.config.js

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
/// ENVVAR
2-
// - COMPILER: compiler version (default: 0.8.20)
3-
// - SRC: contracts folder to compile (default: contracts)
4-
// - RUNS: number of optimization runs (default: 200)
5-
// - IR: enable IR compilation (default: false)
6-
// - UNLIMITED: allow deployment of contracts larger than 24k (default: false)
7-
// - COVERAGE: enable coverage report (default: false)
8-
// - GAS: enable gas report (default: false)
9-
// - COINMARKETCAP: coinmarketcap api key for USD value in gas report
10-
// - CI: output gas report to file instead of stdout
2+
// - COMPILE_VERSION: compiler version (default: 0.8.20)
3+
// - SRC: contracts folder to compile (default: contracts)
4+
// - COMPILE_MODE: production modes enables optimizations (default: development)
5+
// - IR: enable IR compilation (default: false)
6+
// - COVERAGE: enable coverage report
7+
// - ENABLE_GAS_REPORT: enable gas report
8+
// - COINMARKETCAP: coinmarkercat api key for USD value in gas report
9+
// - CI: output gas report to file instead of stdout
1110

1211
const fs = require('fs');
1312
const path = require('path');
@@ -26,10 +25,11 @@ const { argv } = require('yargs/yargs')()
2625
type: 'string',
2726
default: 'contracts',
2827
},
29-
runs: {
30-
alias: 'optimizationRuns',
31-
type: 'number',
32-
default: 200,
28+
mode: {
29+
alias: 'compileMode',
30+
type: 'string',
31+
choices: ['production', 'development'],
32+
default: 'development',
3333
},
3434
ir: {
3535
alias: 'enableIR',
@@ -41,11 +41,6 @@ const { argv } = require('yargs/yargs')()
4141
type: 'string',
4242
default: 'cancun',
4343
},
44-
unlimited: {
45-
alias: 'allowUnlimitedContractSize',
46-
type: 'boolean',
47-
default: false,
48-
},
4944
// Extra modules
5045
coverage: {
5146
type: 'boolean',
@@ -74,6 +69,9 @@ for (const f of fs.readdirSync(path.join(__dirname, 'hardhat'))) {
7469
require(path.join(__dirname, 'hardhat', f));
7570
}
7671

72+
const withOptimizations = argv.gas || argv.coverage || argv.compileMode === 'production';
73+
const allowUnlimitedContractSize = argv.gas || argv.coverage || argv.compileMode === 'development';
74+
7775
/**
7876
* @type import('hardhat/config').HardhatUserConfig
7977
*/
@@ -82,12 +80,11 @@ module.exports = {
8280
version: argv.compiler,
8381
settings: {
8482
optimizer: {
85-
enabled: true,
86-
runs: argv.runs,
87-
details: { yul: true },
83+
enabled: withOptimizations,
84+
runs: 200,
8885
},
8986
evmVersion: argv.evm,
90-
viaIR: argv.ir,
87+
viaIR: withOptimizations && argv.ir,
9188
outputSelection: { '*': { '*': ['storageLayout'] } },
9289
},
9390
},
@@ -97,7 +94,7 @@ module.exports = {
9794
'initcode-size': 'off',
9895
},
9996
'*': {
100-
'code-size': true,
97+
'code-size': withOptimizations,
10198
'unused-param': !argv.coverage, // coverage causes unused-param warnings
10299
'transient-storage': false,
103100
default: 'error',
@@ -106,7 +103,7 @@ module.exports = {
106103
networks: {
107104
hardhat: {
108105
hardfork: argv.evm,
109-
allowUnlimitedContractSize: argv.gas || argv.coverage || argv.unlimited,
106+
allowUnlimitedContractSize,
110107
initialBaseFeePerGas: argv.coverage ? 0 : undefined,
111108
},
112109
},

0 commit comments

Comments
 (0)