Skip to content

Commit

Permalink
fix: bls deposit verification works
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeday committed Feb 28, 2025
1 parent 8e0c82c commit 15350e5
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 34 deletions.
16 changes: 8 additions & 8 deletions contracts/0.8.25/lib/BLS.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ library BLS {
/// @notice PRECOMPILED CONTRACT ADDRESSES
address constant MOD_EXP = address(0x05);
// forge
address constant BLS12_G2ADD = address(0x0e);
address constant BLS12_PAIRING_CHECK = address(0x10);
address constant BLS12_MAP_FP2_TO_G2 = address(0x13);
address constant BLS12_G2ADD = 0x000000000000000000000000000000000000000E;
address constant BLS12_PAIRING_CHECK = 0x0000000000000000000000000000000000000011;
address constant BLS12_MAP_FP2_TO_G2 = 0x0000000000000000000000000000000000000013;

// revm
// address constant BLS12_G2ADD = address(0x0d);
// address constant BLS12_PAIRING_CHECK = address(0x0f);
// address constant BLS12_MAP_FP2_TO_G2 = address(0x11);
// address constant BLS12_G2ADD = 0x000000000000000000000000000000000000000B;
// address constant BLS12_PAIRING_CHECK = 0x000000000000000000000000000000000000000F;
// address constant BLS12_MAP_FP2_TO_G2 = 0x0000000000000000000000000000000000000011;

// TODO make constant
function NEGATED_G1_GENERATOR() internal pure returns (G1Point memory) {
Expand Down Expand Up @@ -276,8 +276,8 @@ library BLS {
G1Point[] memory g1Points = new BLS.G1Point[](2);
G2Point[] memory g2Points = new BLS.G2Point[](2);

g1Points[0] = pubkeyG1;
g1Points[1] = NEGATED_G1_GENERATOR();
g1Points[0] = NEGATED_G1_GENERATOR();
g1Points[1] = pubkeyG1;

g2Points[0] = msgG2;
g2Points[1] = signatureG2;
Expand Down
12 changes: 7 additions & 5 deletions test/0.8.25/vaults/BLS.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,16 @@ import { ether } from "lib";

import { computeDepositMessageRoot } from "./ssz-utils";

const BLS_TEST_KEY = "18f020b98eb798752a50ed0563b079c125b0db5dd0b1060d1c1b47d4a193e1e4";

const STATIC_DEPOSIT = {
amount: ether("1"),
testPrivateKey: "0x18f020b98eb798752a50ed0563b079c125b0db5dd0b1060d1c1b47d4a193e1e4",
withdrawalCredentials: "0xf3d93f9fbc6a229f3b11340b4b52ae53833813efab76e812d1d014163259ef1f",
};

describe("BLS.sol", () => {
it("can create a deposit from test key", async () => {
// deposit message
const privateKey = SecretKey.fromHex(BLS_TEST_KEY);
const privateKey = SecretKey.fromHex(STATIC_DEPOSIT.testPrivateKey);
const pubkey = privateKey.toPublicKey();
const pubkeyCompressed = pubkey.toHex(true);

Expand All @@ -41,7 +40,8 @@ describe("BLS.sol", () => {
// second Fp is 48 bytes before first one
const sigY_c1 = Buffer.from(signature.toBytes(false).slice(96, 96 + 48)).toString("hex");

console.log({
// Mock data for forge test
const depositTestObject = {
pubkey: pubkeyCompressed,
withdrawalCredentials: withdrawalCredentials,
amount: amount.toString(),
Expand All @@ -53,6 +53,8 @@ describe("BLS.sol", () => {
c1: sigY_c1,
},
messageHex,
});
};

expect(depositTestObject).to.not.be.undefined;
});
});
77 changes: 56 additions & 21 deletions test/0.8.25/vaults/contracts/BLS.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import {StdAssertions} from "forge-std/StdAssertions.sol";

import {BLS, SSZ} from "contracts/0.8.25/lib/BLS.sol";

contract BLSHarness {
contract BLSHarness is StdUtils {
function verifyDepositMessage(
bytes calldata pubkey,
bytes32 withdrawal,
uint64 amount,
uint256 amount,
bytes memory signature,
BLS.Fp memory pubkeyYComponent,
BLS.Fp2 memory signatureYComponent
Expand All @@ -31,7 +31,7 @@ contract BLSHarness {
function depositMessageSigningRoot(
bytes calldata pubkey,
bytes32 withdrawal,
uint64 amount
uint256 amount
) public view returns (bytes32) {
return SSZ.depositMessageSigningRoot(pubkey, withdrawal, amount);
}
Expand All @@ -52,6 +52,10 @@ contract BLSHarness {
) public view returns (BLS.G2Point memory) {
return BLS.hashToCurveG2(SSZ.depositMessageSigningRoot(pubkey, withdrawal, amount));
}

function NEGATED_G1_GENERATOR() public pure returns (BLS.G1Point memory) {
return BLS.NEGATED_G1_GENERATOR();
}
}

struct PrecomputedDepositMessage {
Expand All @@ -71,33 +75,35 @@ contract BLSVerifyingKeyTest is Test {
harness = new BLSHarness();
}

function test_verifySigningRoot() external view {
PrecomputedDepositMessage memory deposit = STATIC_DEPOSIT_MESSAGE();
bytes32 root = harness.depositMessageSigningRoot(deposit.pubkey, deposit.withdrawal, deposit.amount);
StdAssertions.assertEq(root, deposit.validMsgHash);
}

function test_verifyDeposit() external view {
PrecomputedDepositMessage memory deposit = STATIC_DEPOSIT_MESSAGE();
harness.verifyDepositMessage(
deposit.pubkey,
deposit.withdrawal,
uint64(deposit.amount),
deposit.amount,
deposit.signature,
deposit.pubkeyYComponent,
deposit.signatureYComponent
);
}

function test_depositMessageHashTreeRoot() public view {
PrecomputedDepositMessage memory deposit = STATIC_DEPOSIT_MESSAGE();
bytes32 root = harness.depositMessageSigningRoot(deposit.pubkey, deposit.withdrawal, uint64(deposit.amount));
StdAssertions.assertEq32(root, deposit.validMsgHash);
}

function wrapFp(bytes memory data) internal pure returns (BLS.Fp memory) {
require(data.length == 48, "Invalid Fp length");
uint256 a = BLS.sliceToUint(data, 0, 16);
uint256 b = BLS.sliceToUint(data, 16, 48);
return BLS.Fp(a, b);
}

function wrapFp2(bytes memory x, bytes memory y) internal pure returns (BLS.Fp2 memory) {
return BLS.Fp2(wrapFp(x), wrapFp(y));
function test_revertOnInCorrectDeposit() external {
PrecomputedDepositMessage memory deposit = CORRUPTED_STATIC_DEPOSIT_MESSAGE();
vm.expectRevert();
harness.verifyDepositMessage(
deposit.pubkey,
deposit.withdrawal,
deposit.amount,
deposit.signature,
deposit.pubkeyYComponent,
deposit.signatureYComponent
);
}

function STATIC_DEPOSIT_MESSAGE() internal pure returns (PrecomputedDepositMessage memory) {
Expand All @@ -111,10 +117,39 @@ contract BLSVerifyingKeyTest is Test {
hex"19b71bd2a9ebf09809b6c380a1d1de0c2d9286a8d368a2fc75ad5ccc8aec572efdff29d50b68c63e00f6ce017c24e083"
),
wrapFp2(
hex"10d96c5dcc6e32bcd43e472317e18ad94dde89c9361d79bec5378c72214083ea40f3dc43ee759025eb4c25150e1943bf",
hex"160f8d804d277c7a079f451bce224fd42397e75676d965a1ebe79e53beeb2cb48be01f4dc93c0bad8ae7560c3e8048fb"
hex"160f8d804d277c7a079f451bce224fd42397e75676d965a1ebe79e53beeb2cb48be01f4dc93c0bad8ae7560c3e8048fb",
hex"10d96c5dcc6e32bcd43e472317e18ad94dde89c9361d79bec5378c72214083ea40f3dc43ee759025eb4c25150e1943bf"
),
0xa0ea5aa96388d0375c9181eac29fa198cea873c818efe7442bd49c03948f2a69
);
}

function CORRUPTED_STATIC_DEPOSIT_MESSAGE() internal pure returns (PrecomputedDepositMessage memory) {
return
PrecomputedDepositMessage(
hex"b79902f435d268d6d37ac3ab01f4536a86c192fa07ba5b63b5f8e4d0e05755cfeab9d35fbedb9c02919fe02a81f8b06d",
0xf3d93f9fbc6a229f3b11340b4b52ae53833813efab76e812d1d014163259ef1f,
1 ether,
hex"b357f146f53de27ae47d6d4bff5e8cc8342d94996143b2510452a3565701c3087a0ba04bed41d208eb7d2f6a50debeac09bf3fcf5c28d537d0fe4a52bb976d0c19ea37a31b6218f321a308f8017e5fd4de63df270f37df58c059c75f0f98f980",
wrapFp(
hex"19b71bd219ebf09809b6c380a1d1de0c2d9286a8d368a2fc75ad5ccc8aec572efdff29d50b68c63e00f6ce017c24e083"
),
wrapFp2(
hex"160f8d8000077c7a079f451bce224fd42397e75676d965a1ebe79e53beeb2cb48be01f4dc93c0bad8ae7560c3e8048fb",
hex"10d96c5dcc6e32bcd43e472317e18ad94dde89c9361d79bec5378c72214083ea40f3dc43ee759025eb4c25150e1943bf"
),
0xa0ea5aa96388d0375c9181eac29fa198cea873c818efe7442bd49c03948f2a69
);
}

function wrapFp(bytes memory data) internal pure returns (BLS.Fp memory) {
require(data.length == 48, "Invalid Fp length");
uint256 a = BLS.sliceToUint(data, 0, 16);
uint256 b = BLS.sliceToUint(data, 16, 48);
return BLS.Fp(a, b);
}

function wrapFp2(bytes memory x, bytes memory y) internal pure returns (BLS.Fp2 memory) {
return BLS.Fp2(wrapFp(x), wrapFp(y));
}
}

0 comments on commit 15350e5

Please sign in to comment.