Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,19 @@ jobs:
with:
submodules: recursive

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1

- name: Install hardhat
- name: Install dependencies
run: |
yarn add --dev hardhat
id: hardhat-install
npm install
id: install-deps

- name: Show Forge version
run: |
Expand All @@ -38,6 +44,9 @@ jobs:
run: |
forge fmt --check
id: fmt

- name: Install soldeer dependencies
run: forge soldeer install

- name: Run Forge build
run: |
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,7 @@ broadcast

# Deployments
script/json/Deployment_input.json
flat/
flat/

# Soldeer
/dependencies
9 changes: 0 additions & 9 deletions .gitmodules

This file was deleted.

12 changes: 9 additions & 3 deletions foundry.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
libs = ["lib", "dependencies"]
optimizer = true
optimizer_runs = 200
solc_version = '0.8.28'
optimizer_runs = 20
solc_version = '0.8.30'
gas_reports = ["*"]
fs_permissions = [{ access = "read-write", path = "./script/json"}]

Expand All @@ -26,4 +26,10 @@ gas_reports = ["*"]
via_ir = true
no_match_coverage = "(script|test)"

[dependencies]
forge-std = "1.10.0"
"@openzeppelin-contracts-upgradeable" = "5.4.0"
"@openzeppelin-contracts" = "5.4.0"
bls-solidity = { version = "0.3.0", url = "https://github.com/randa-mu/bls-solidity/archive/refs/tags/v0.3.0.zip" }

# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
4 changes: 2 additions & 2 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import "@nomicfoundation/hardhat-toolbox";

const config: HardhatUserConfig = {
solidity: {
version: "0.8.28",
version: "0.8.30",
settings: {
optimizer: {
enabled: true,
runs: 200
runs: 20
}
}
},
Expand Down
1 change: 0 additions & 1 deletion lib/forge-std
Submodule forge-std deleted from 77041d
1 change: 0 additions & 1 deletion lib/openzeppelin-contracts
Submodule openzeppelin-contracts deleted from e4f702
1 change: 0 additions & 1 deletion lib/openzeppelin-contracts-upgradeable
Submodule openzeppelin-contracts-upgradeable deleted from 60b305
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
},
"scripts": {
"build": "npm run build:forge && npm run build:hardhat",
"build:forge": "FOUNDRY_PROFILE=build forge install && FOUNDRY_PROFILE=build forge build",
"build:forge": "FOUNDRY_PROFILE=build forge soldeer install && FOUNDRY_PROFILE=build forge build",
"build:hardhat": "npx hardhat compile",
"test": "npm run test:forge && npm run test:hardhat",
"test:forge": "FOUNDRY_PROFILE=test forge test --gas-report",
Expand Down
8 changes: 4 additions & 4 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@forge-std/=lib/forge-std/src/
@ds-test/=lib/forge-std/lib/ds-test/src/

@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/
@openzeppelin/contracts-upgradeable/=dependencies/@openzeppelin-contracts-upgradeable-5.4.0/
@openzeppelin/contracts/=dependencies/@openzeppelin-contracts-5.4.0/
bls-solidity-0.3.0/=dependencies/bls-solidity-0.3.0/
forge-std/=dependencies/forge-std-1.10.0/src/
27 changes: 27 additions & 0 deletions soldeer.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[[dependencies]]
name = "@openzeppelin-contracts"
version = "5.4.0"
url = "https://soldeer-revisions.s3.amazonaws.com/@openzeppelin-contracts/5_4_0_19-07-2025_08:59:41_contracts.zip"
checksum = "3dd38f17610dba4602bd008ee2cb551e51e97d7b4ce04e1ffdf853da832942fa"
integrity = "4eb0ef219d10ab5a5708adaae1132dc0a93ab6a193378486e842d606c989ff3e"

[[dependencies]]
name = "@openzeppelin-contracts-upgradeable"
version = "5.4.0"
url = "https://soldeer-revisions.s3.amazonaws.com/@openzeppelin-contracts-upgradeable/5_4_0_19-07-2025_08:59:45_contracts-upgradeable.zip"
checksum = "bc405f98749d27dc19e747f1e797f3df59ccf6c9781ab39369892eaf700ac40b"
integrity = "eeb22da11d2b7a8202e43a3a91978f0d9e6cdabfe006cf799f57282065267a1a"

[[dependencies]]
name = "bls-solidity"
version = "0.3.0"
url = "https://github.com/randa-mu/bls-solidity/archive/refs/tags/v0.3.0.zip"
checksum = "d533bb18a246cc73b11ca14fb5950c7bc50525e4ac39882c7c04601a3cca1c58"
integrity = "6c9c930aa29d8bec92df355a27e76a1e26298576c3157604ba5344ce99584b3d"

[[dependencies]]
name = "forge-std"
version = "1.10.0"
url = "https://soldeer-revisions.s3.amazonaws.com/forge-std/1_10_0_02-08-2025_06:50:35_forge-std-1.10.zip"
checksum = "8cc59e92a7762c170c15f2102c4f3718106dfc78239978fe87c64f316740cc09"
integrity = "3fd441e2499c5cf04ef9b4126f52150a50dcef9cac1645ff7a955345e947cd04"
56 changes: 56 additions & 0 deletions src/blocklock/BlocklockCryptoLib.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8;

import {TypesLib} from "../libraries/TypesLib.sol";
import {BLS} from "../libraries/BLS.sol";

library BlocklockCryptoLib {
/// @notice Decrypts a ciphertext into plaintext using a decryption key
/// @param ciphertext The ciphertext to decrypt, containing the necessary data for decryption
/// @param decryptionKey The decryption key used to decrypt the ciphertext
/// @return The decrypted message (plaintext) as a `bytes` array
/// @dev This function performs the decryption process using a series of cryptographic operations:
/// - It first XORs the decryption key with part of the ciphertext to generate a candidate value.
/// - Then it decrypts the message using another XOR operation with a mask derived from the candidate value.
/// - The function verifies the validity of the decryption key and ciphertext by checking the consistency of a derived ephemeral keypair.
/// @dev Throws an error if:
/// - The decryption key length is incorrect.
/// - The message length is unsupported.
/// - The decryption key and ciphertext do not match (validation failure).
function decrypt(
TypesLib.Ciphertext calldata ciphertext,
bytes calldata decryptionKey,
bytes memory DST_H3,
bytes memory DST_H4
) public view returns (bytes memory) {
require(ciphertext.v.length != 256, "invalid decryption key length");
require(ciphertext.w.length < 256, "message of unsupported length");

// \sigma' \gets V \xor decryptionKey
bytes memory sigma2 = ciphertext.v;
for (uint256 i = 0; i < decryptionKey.length; i++) {
sigma2[i] ^= decryptionKey[i];
}

// Decrypt the message
// 4: M' \gets W \xor H_4(\sigma')
bytes memory m2 = ciphertext.w;
bytes memory mask = BLS.expandMsg(DST_H4, sigma2, uint8(ciphertext.w.length));
for (uint256 i = 0; i < ciphertext.w.length; i++) {
m2[i] ^= mask[i];
}

// Derive the ephemeral keypair with the candidate \sigma'
// 5: r \gets H_3(\sigma, M)
uint256 r = BLS.hashToFieldSingle(DST_H3, bytes.concat(sigma2, m2));

// Verify that \sigma' is consistent with the message and ephemeral public key
// 6: if U = [r]G_2 then return M' else return \bot
BLS.PointG1 memory rG1 = BLS.scalarMulG1Base(r);
(bool equal, bool success) = BLS.verifyEqualityG1G2(rG1, ciphertext.u);
// Decryption fails if a bad decryption key / ciphertext was provided
require(equal == success == true, "invalid decryption key / ciphertext registered");

return m2;
}
}
31 changes: 31 additions & 0 deletions src/blocklock/BlocklockDSTLib.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8;

import {BytesLib} from "../libraries/BytesLib.sol";

/// @title BlocklockDSTLib library
/// @notice Library for Domain Separation Tag (DST) initialization
/// @dev Extracts DST creation logic to reduce contract size
library BlocklockDSTLib {
using BytesLib for bytes32;

/// @notice Initializes all Domain Separation Tags for the blocklock scheme
/// @param chainId The chain ID to include in DST generation
/// @return dst_h1_g1 The DST for H1 operations
/// @return dst_h2 The DST for H2 operations
/// @return dst_h3 The DST for H3 operations
/// @return dst_h4 The DST for H4 operations
function initializeDSTs(uint256 chainId)
external
pure
returns (bytes memory dst_h1_g1, bytes memory dst_h2, bytes memory dst_h3, bytes memory dst_h4)
{
string memory chainIdHexStr = bytes32(chainId).toHexString();
bytes memory chainIdHex = bytes(chainIdHexStr);

dst_h1_g1 = abi.encodePacked("BLOCKLOCK_BN254G1_XMD:KECCAK-256_SVDW_RO_H1_", chainIdHex, "_");
dst_h2 = abi.encodePacked("BLOCKLOCK_BN254_XMD:KECCAK-256_H2_", chainIdHex, "_");
dst_h3 = abi.encodePacked("BLOCKLOCK_BN254_XMD:KECCAK-256_H3_", chainIdHex, "_");
dst_h4 = abi.encodePacked("BLOCKLOCK_BN254_XMD:KECCAK-256_H4_", chainIdHex, "_");
}
}
Loading
Loading