Skip to content

Commit

Permalink
deserialize g1 compressed
Browse files Browse the repository at this point in the history
  • Loading branch information
hujw77 committed Nov 24, 2023
1 parent a4e2c33 commit d523ec2
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 37 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ clean :; @forge clean
test :; @forge test
# deploy :; @forge script script/Deploy.s.sol:Deploy --chain ${chain-id} --broadcast --verify
deploy :; @forge script script/Deploy.s.sol:Deploy --rpc-url http://192.168.132.159:9944 --broadcast
e2e-test:; @forge script script/Deploy.s.sol:Deploy --sig "test_import_finalized_header()" --rpc-url http://192.168.132.159:9944 --broadcast --skip-simulation
e2e-test:; @forge script script/Deploy.s.sol:Deploy --sig "test_import_finalized_header()" --rpc-url http://192.168.132.159:9944 --broadcast

salt :; @create3 -s 000000000000
sync :; @git submodule update --recursive
Expand Down
50 changes: 25 additions & 25 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,31 @@ contract Deploy is Common, BeaconLightClientUpdate {
// super.setUp();
}

function run() public broadcast {
uint64 slot = 7825376;
uint64 proposer_index = 550054;
bytes32 parent_root = 0x43fcc72d547536eeaf4e43454fbc82fbd3d475dbe2890f96281c5d004312ce3e;
bytes32 state_root = 0xcea628f2339d80944daece5214c61effee317f8d9bf71ec21625e98d3c76d022;
bytes32 body_root = 0x4e45b5935b52b809daba32f1ba9faae64af12d3f9d6847db393021c593c904c4;
uint256 block_number = 18633272;
bytes32 merkle_root = 0xf4036d4b1a025802e88b41881d098fd2b63a95f74d961713c2756b253a0391c6;
bytes32 sync_committee_hash = 0x4e6ce20e67e1c347266408d0d58de1dba560025e2b60536d376d9b7af91fed24;
bytes32 genesis_validators_root = 0xd8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078;
new EthereumMessageRootOracle(
slot,
proposer_index,
parent_root,
state_root,
body_root,
block_number,
merkle_root,
sync_committee_hash,
genesis_validators_root
);
// bytes memory byteCode = type(EthereumMessageRootOracle).creationCode;
// address addr = _deploy3(SALT, abi.encodePacked(byteCode, args()));
// require(addr == ADDR, "!addr");
}
// function run() public broadcast {
// uint64 slot = 7825376;
// uint64 proposer_index = 550054;
// bytes32 parent_root = 0x43fcc72d547536eeaf4e43454fbc82fbd3d475dbe2890f96281c5d004312ce3e;
// bytes32 state_root = 0xcea628f2339d80944daece5214c61effee317f8d9bf71ec21625e98d3c76d022;
// bytes32 body_root = 0x4e45b5935b52b809daba32f1ba9faae64af12d3f9d6847db393021c593c904c4;
// uint256 block_number = 18633272;
// bytes32 merkle_root = 0xf4036d4b1a025802e88b41881d098fd2b63a95f74d961713c2756b253a0391c6;
// bytes32 sync_committee_hash = 0x4e6ce20e67e1c347266408d0d58de1dba560025e2b60536d376d9b7af91fed24;
// bytes32 genesis_validators_root = 0xd8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078;
// new EthereumMessageRootOracle(
// slot,
// proposer_index,
// parent_root,
// state_root,
// body_root,
// block_number,
// merkle_root,
// sync_committee_hash,
// genesis_validators_root
// );
// // bytes memory byteCode = type(EthereumMessageRootOracle).creationCode;
// // address addr = _deploy3(SALT, abi.encodePacked(byteCode, args()));
// // require(addr == ADDR, "!addr");
// }

function args() internal pure returns (bytes memory) {
uint64 slot = 7825376;
Expand Down
1 change: 1 addition & 0 deletions src/bls12381/BLS.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ library BLS {
bytes memory g1 = keys[i];
agg_g1 = agg_g1.add(BLS12G1Affine.deserialize(g1));
}
require(!agg_g1.is_infinity(), "infinity");
return agg_g1;
}

Expand Down
111 changes: 111 additions & 0 deletions src/bls12381/Fp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ library BLS12FP {
);
}

function b() internal pure returns (Bls12Fp memory) {
return Bls12Fp(0, 4);
}

/// @dev (q+1)/4
function qr() internal pure returns (Bls12Fp memory) {
return Bls12Fp(
0x680447a8e5ff9a692c6e9ed90d2eb35, 0xd91dd2e13ce144afd9cc34a83dac3d8907aaffffac54ffffee7fbfffffffeaab
);
}

/// @dev Returns the additive identity element of Bls12Fp.
/// @return Bls12Fp(0, 0)
function zero() internal pure returns (Bls12Fp memory) {
Expand All @@ -45,6 +56,13 @@ library BLS12FP {
return gt(q(), self);
}

/// @dev Returns `true` if `self` is equal or larger than r.
/// @param self Bls12Fp.
/// @return Result of check.
function is_geq_modulus(Bls12Fp memory self) internal pure returns (bool) {
return (eq(self, q()) || gt(self, q()));
}

/// @dev Returns `true` if `x` is equal to `y`.
/// @param x Bls12Fp.
/// @param y Bls12Fp.
Expand Down Expand Up @@ -83,6 +101,22 @@ library BLS12FP {
}
}

/// @dev Returns the result of `(x + y) % p`.
/// @param x Bw6Fp.
/// @param y Bw6Fp.
/// @return z `(x + y) % p`.
function add(Bls12Fp memory x, Bls12Fp memory y) internal pure returns (Bls12Fp memory z) {
z = add_nomod(x, y);
z = subtract_modulus_to_norm(z);
}

function subtract_modulus_to_norm(Bls12Fp memory self) internal pure returns (Bls12Fp memory z) {
z = self;
if (is_geq_modulus(self)) {
z = sub(self, q());
}
}

/// @dev Returns the result of `(x - y) % p`.
/// @param x Bls12Fp.
/// @param y Bls12Fp.
Expand Down Expand Up @@ -129,4 +163,81 @@ library BLS12FP {
}
return Bls12Fp(output[0], output[1]);
}

/// @dev base^base % modulus
/// @param base Bls12Fp.
/// @param exp Bls12Fp.
/// @param modulus Bls12Fp.
/// @return Result of mod_exp.
function mod_exp(
Bls12Fp memory base,
Bls12Fp memory exp,
Bls12Fp memory modulus
)
internal
view
returns (Bls12Fp memory)
{
uint256[9] memory input;
input[0] = 0x40;
input[1] = 0x40;
input[2] = 0x40;
input[3] = base.a;
input[4] = base.b;
input[5] = exp.a;
input[6] = exp.b;
input[7] = modulus.a;
input[8] = modulus.b;
uint256[2] memory output;

assembly ("memory-safe") {
if iszero(staticcall(gas(), MOD_EXP, input, 288, output, 64)) {
let p := mload(0x40)
returndatacopy(p, 0, returndatasize())
revert(p, returndatasize())
}
}

return Bls12Fp(output[0], output[1]);
}

/// @dev base^base % modulus
/// @param base Bls12Fp.
/// @param exp uint256.
/// @param modulus Bls12Fp.
/// @return Result of mod_exp.
function mod_exp(Bls12Fp memory base, uint256 exp, Bls12Fp memory modulus) internal view returns (Bls12Fp memory) {
uint256[8] memory input;
input[0] = 0x40;
input[1] = 0x40;
input[2] = 0x40;
input[3] = base.a;
input[4] = base.b;
input[5] = exp;
input[6] = modulus.a;
input[7] = modulus.b;
uint256[2] memory output;

assembly ("memory-safe") {
if iszero(staticcall(gas(), MOD_EXP, input, 256, output, 64)) {
let p := mload(0x40)
returndatacopy(p, 0, returndatasize())
revert(p, returndatasize())
}
}

return Bls12Fp(output[0], output[1]);
}

// using quadratic residue
function find_y(Bls12Fp memory x) internal view returns (Bls12Fp memory) {
Bls12Fp memory y_square = add(mod_exp(x, 3, q()), b());
Bls12Fp memory y = mod_exp(y_square, qr(), q());
return y;
}

// pow(y, 2, q) == (x**3 + b.n) % q:
function is_on_curve(Bls12Fp memory x, Bls12Fp memory y) internal view returns (bool) {
return eq(mod_exp(y, 2, q()), add(mod_exp(x, 3, q()), b()));
}
}
31 changes: 20 additions & 11 deletions src/bls12381/G1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ library BLS12G1Affine {
/// @dev BLS12_377_G1ADD precompile address.
uint256 private constant G1_ADD = 0x0c;

bytes1 private constant COMPRESION_FLAG = bytes1(0x80);
bytes1 private constant INFINITY_FLAG = bytes1(0x40);
bytes1 private constant Y_FLAG = bytes1(0x20);

/// @dev Negative G1 generator
/// @return Negative G1 generator
function neg_generator() internal pure returns (Bls12G1 memory) {
Expand Down Expand Up @@ -98,20 +94,33 @@ library BLS12G1Affine {
}

// Take a 96 byte array and convert to a G1 point (x, y)
function deserialize(bytes memory g1) internal pure returns (Bls12G1 memory) {
require(g1.length == 96, "!g1");
function deserialize(bytes memory g1) internal view returns (Bls12G1 memory) {
require(g1.length == 48, "!g1");
bytes1 byt = g1[0];
require(byt & COMPRESION_FLAG == 0, "compressed");
require(byt & INFINITY_FLAG == 0, "infinity");
require(byt & Y_FLAG == 0, "y_flag");
bool c_flag = (byt >> 7) & 0x01 == 0x01;
bool b_flag = (byt >> 6) & 0x01 == 0x01;
bool a_flag = (byt >> 5) & 0x01 == 0x01;
if (a_flag && (!c_flag || b_flag)) {
revert("!flag");
}
require(c_flag, "uncompressed");

// Zero flags
g1[0] = byt & 0x1f;
Bls12Fp memory x = Bls12Fp(g1.slice_to_uint(0, 16), g1.slice_to_uint(16, 48));
Bls12Fp memory y = Bls12Fp(g1.slice_to_uint(48, 64), g1.slice_to_uint(64, 96));
if (b_flag) {
require(x.is_zero(), "!zero");
return zero();
}

Bls12Fp memory y = x.find_y();

// Require elements less than field modulus
require(x.is_valid() && y.is_valid(), "!pnt");
require(x.is_valid() && y.is_valid(), "!fp");

if (y.add(y).gt(BLS12FP.q()) != a_flag) {
y = BLS12FP.q().sub(y);
}

// Convert to G1
Bls12G1 memory p = Bls12G1(x, y);
Expand Down

0 comments on commit d523ec2

Please sign in to comment.