Skip to content

Commit

Permalink
Manage to compile without via-ir
Browse files Browse the repository at this point in the history
  • Loading branch information
ernestognw committed Jun 25, 2024
1 parent c6a86d9 commit 9b24014
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 41 deletions.
52 changes: 35 additions & 17 deletions contracts/utils/cryptography/P256.sol
Original file line number Diff line number Diff line change
Expand Up @@ -164,36 +164,37 @@ library P256 {
}

/**
* @dev Point addition on the jacobian coordinates
* @dev Point addition on the jacobian coordinates.
*
* Computation is assisted by Solidity's memory. It takes x1 and y1 arguments from the scratch space
* and returns x' and y' to the scratch space.
*
* Reference: https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-add-1998-cmo-2
*/
function _jAdd(
uint256 x1,
uint256 y1,
uint256 z1,
uint256 x2,
uint256 y2,
uint256 z2
) private pure returns (uint256 rx, uint256 ry, uint256 rz) {
function _jAddMemoryAssisted(uint256 z1, uint256 x2, uint256 y2, uint256 z2) private pure returns (uint256 rz) {
assembly ("memory-safe") {
let p := P

let zz1 := mulmod(z1, z1, p) // zz1 = z1²
let zz2 := mulmod(z2, z2, p) // zz2 = z2²
let u1 := mulmod(x1, zz2, p) // u1 = x1*z2²
let u1 := mulmod(mload(0x00), zz2, p) // u1 = x1*z2²
let u2 := mulmod(x2, zz1, p) // u2 = x2*z1²
let s1 := mulmod(y1, mulmod(zz2, z2, p), p) // s1 = y1*z2³
let s1 := mulmod(mload(0x20), mulmod(zz2, z2, p), p) // s1 = y1*z2³
let s2 := mulmod(y2, mulmod(zz1, z1, p), p) // s2 = y2*z1³
let h := addmod(u2, sub(p, u1), p) // h = u2-u1
rz := mulmod(h, mulmod(z1, z2, p), p)
let hh := mulmod(h, h, p) // h²
let hhh := mulmod(h, hh, p) // h³
let r := addmod(s2, sub(p, s1), p) // r = s2-s1

// x' = r²-h³-2*u1*h²
rx := addmod(addmod(mulmod(r, r, p), sub(p, hhh), p), sub(p, mulmod(2, mulmod(u1, hh, p), p)), p)
mstore(0x00, addmod(addmod(mulmod(r, r, p), sub(p, hhh), p), sub(p, mulmod(2, mulmod(u1, hh, p), p)), p))

// y' = r*(u1*h²-x')-s1*h³
ry := addmod(mulmod(r, addmod(mulmod(u1, hh, p), sub(p, rx), p), p), sub(p, mulmod(s1, hhh, p)), p)
// z' = h*z1*z2
rz := mulmod(h, mulmod(z1, z2, p), p)
mstore(
0x20,
addmod(mulmod(r, addmod(mulmod(u1, hh, p), sub(p, mload(0)), p), p), sub(p, mulmod(s1, hhh, p)), p)
)
}
}

Expand Down Expand Up @@ -244,7 +245,9 @@ library P256 {
if (z == 0) {
(x, y, z) = (points[pos].x, points[pos].y, points[pos].z);
} else {
(x, y, z) = _jAdd(x, y, z, points[pos].x, points[pos].y, points[pos].z);
_toScratchMemory(x, y);
(z) = _jAddMemoryAssisted(z, points[pos].x, points[pos].y, points[pos].z);
(x, y) = _fromScratchMemory();
}
}
u1 <<= 2;
Expand Down Expand Up @@ -287,12 +290,27 @@ library P256 {
}

function _jAddPoint(JPoint memory p1, JPoint memory p2) private pure returns (JPoint memory) {
(uint256 x, uint256 y, uint256 z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);
_toScratchMemory(p1.x, p1.y);
uint256 z = _jAddMemoryAssisted(p1.z, p2.x, p2.y, p2.z);
(uint256 x, uint256 y) = _fromScratchMemory();
return JPoint(x, y, z);
}

function _jDoublePoint(JPoint memory p) private pure returns (JPoint memory) {
(uint256 x, uint256 y, uint256 z) = _jDouble(p.x, p.y, p.z);
return JPoint(x, y, z);
}

function _toScratchMemory(uint256 x, uint256 y) private pure {
assembly ("memory-safe") {
mstore(0x00, x)
mstore(0x20, y)
}
}
function _fromScratchMemory() private pure returns (uint256 x, uint256 y) {
assembly ("memory-safe") {
x := mload(0x00)
y := mload(0x20)
}
}
}
45 changes: 21 additions & 24 deletions hardhat.config.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
/// ENVVAR
// - COMPILER: compiler version (default: 0.8.20)
// - SRC: contracts folder to compile (default: contracts)
// - RUNS: number of optimization runs (default: 200)
// - IR: enable IR compilation (default: false)
// - UNLIMITED: allow deployment of contracts larger than 24k (default: false)
// - COVERAGE: enable coverage report (default: false)
// - GAS: enable gas report (default: false)
// - COINMARKETCAP: coinmarketcap api key for USD value in gas report
// - CI: output gas report to file instead of stdout
// - COMPILE_VERSION: compiler version (default: 0.8.20)
// - SRC: contracts folder to compile (default: contracts)
// - COMPILE_MODE: production modes enables optimizations (default: development)
// - IR: enable IR compilation (default: false)
// - COVERAGE: enable coverage report
// - ENABLE_GAS_REPORT: enable gas report
// - COINMARKETCAP: coinmarkercat api key for USD value in gas report
// - CI: output gas report to file instead of stdout

const fs = require('fs');
const path = require('path');
Expand All @@ -26,10 +25,11 @@ const { argv } = require('yargs/yargs')()
type: 'string',
default: 'contracts',
},
runs: {
alias: 'optimizationRuns',
type: 'number',
default: 200,
mode: {
alias: 'compileMode',
type: 'string',
choices: ['production', 'development'],
default: 'development',
},
ir: {
alias: 'enableIR',
Expand All @@ -41,11 +41,6 @@ const { argv } = require('yargs/yargs')()
type: 'string',
default: 'cancun',
},
unlimited: {
alias: 'allowUnlimitedContractSize',
type: 'boolean',
default: false,
},
// Extra modules
coverage: {
type: 'boolean',
Expand Down Expand Up @@ -74,6 +69,9 @@ for (const f of fs.readdirSync(path.join(__dirname, 'hardhat'))) {
require(path.join(__dirname, 'hardhat', f));
}

const withOptimizations = argv.gas || argv.coverage || argv.compileMode === 'production';
const allowUnlimitedContractSize = argv.gas || argv.coverage || argv.compileMode === 'development';

/**
* @type import('hardhat/config').HardhatUserConfig
*/
Expand All @@ -82,12 +80,11 @@ module.exports = {
version: argv.compiler,
settings: {
optimizer: {
enabled: true,
runs: argv.runs,
details: { yul: true },
enabled: withOptimizations,
runs: 200,
},
evmVersion: argv.evm,
viaIR: argv.ir,
viaIR: withOptimizations && argv.ir,
outputSelection: { '*': { '*': ['storageLayout'] } },
},
},
Expand All @@ -97,7 +94,7 @@ module.exports = {
'initcode-size': 'off',
},
'*': {
'code-size': true,
'code-size': withOptimizations,
'unused-param': !argv.coverage, // coverage causes unused-param warnings
'transient-storage': false,
default: 'error',
Expand All @@ -106,7 +103,7 @@ module.exports = {
networks: {
hardhat: {
hardfork: argv.evm,
allowUnlimitedContractSize: argv.gas || argv.coverage || argv.unlimited,
allowUnlimitedContractSize,
initialBaseFeePerGas: argv.coverage ? 0 : undefined,
},
},
Expand Down

0 comments on commit 9b24014

Please sign in to comment.