Skip to content
Merged
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
437 changes: 102 additions & 335 deletions Cargo.lock

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ resolver = "2"
members = ["lgn-auth", "lgn-messages", "lgn-provers", "lgn-worker"]

[workspace.dependencies]
groth16_framework = { git = "https://github.com/Lagrange-Labs/mapreduce-plonky2.git", rev = "2.1.1" }
mp2_common = { git = "https://github.com/Lagrange-Labs/mapreduce-plonky2.git", rev = "2.1.1" }
mp2_v1 = { git = "https://github.com/Lagrange-Labs/mapreduce-plonky2.git", rev = "2.1.1" }
parsil = { git = "https://github.com/Lagrange-Labs/mapreduce-plonky2.git", rev = "2.1.1" }
verifiable-db = { git = "https://github.com/Lagrange-Labs/mapreduce-plonky2.git", rev = "2.1.1" }
groth16_framework = { git = "https://github.com/Lagrange-Labs/mapreduce-plonky2.git", branch = "main" }
mp2_common = { git = "https://github.com/Lagrange-Labs/mapreduce-plonky2.git", branch = "main" }
mp2_v1 = { git = "https://github.com/Lagrange-Labs/mapreduce-plonky2.git", branch = "main" }
parsil = { git = "https://github.com/Lagrange-Labs/mapreduce-plonky2.git", branch = "main" }
verifiable-db = { git = "https://github.com/Lagrange-Labs/mapreduce-plonky2.git", branch = "main" }

alloy = { version = "0.15", features = [ "serde" ] }
alloy = { version = "1.0", features = [ "serde" ] }
futures = { version = "0.3" }
anyhow = { version = "1.0" }
backtrace = { version = "0.3" }
base64 = { version = "0.22" }
Expand All @@ -20,8 +21,6 @@ clap = { version = "4.5", default-features = false }
config = { version = "0.15", default-features = false }
derive-debug-plus = { version = "0.5" }
elliptic-curve = { version = "0.13", default-features = false }
ethers = { version = "2.0" }
ethers-core = { git = "https://github.com/Lagrange-Labs/ethers-rs", branch = "get-proof-0x", default-features = false }
generic-array = { version = "0.14", default-features = false }
hex = { version = "0.4" }
jwt = { version = "0.16" }
Expand All @@ -44,6 +43,7 @@ semver = { version = "1.0.26" }
serde = { version = "1.0", features = ["derive"] }
serde_derive = { version = "1.0" }
serde_json = { version = "1.0" }
serde_with = { version = "3.12" }
thiserror = { version = "2" }
tokio = { version = "1.44" }
tokio-stream = { version = "0.1" }
Expand Down
4 changes: 2 additions & 2 deletions devenv.nix
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ in
pull = [];
};

packages = [ pkgs.perl pkgs.git pkgs.openssl pkgs.pkg-config pkgs.protobuf ]
packages = [ pkgs.perl pkgs.git pkgs.openssl pkgs.pkg-config pkgs.protobuf pkgs.rustup ]
++ lib.optionals pkgs.stdenv.targetPlatform.isDarwin [
pkgs.libiconv
pkgs.darwin.apple_sdk.frameworks.SystemConfiguration
Expand Down Expand Up @@ -84,7 +84,7 @@ in
languages = {
go.enable = true;
rust = {
enable = true;
enable = false;
channel = "nightly";
};
};
Expand Down
4 changes: 2 additions & 2 deletions lgn-auth/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ edition = "2021"
anyhow = { workspace = true }
base64 = { workspace = true }
elliptic-curve = { workspace = true }
ethers = { git = "https://github.com/Lagrange-Labs/ethers-rs", default-features = false, features = [ "rustls" ], branch = "get-proof-0x" }
ethers-core = { workspace = true }
alloy = { workspace = true }
generic-array = { workspace = true }
hex = { workspace = true }
jwt = { workspace = true }
rand = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
serde_with = { workspace = true }
47 changes: 23 additions & 24 deletions lgn-auth/src/jwt.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,45 @@
//! JWT authorization logic used in both worker and gateway
use alloy::primitives::eip191_hash_message;
use alloy::primitives::Signature;
use alloy::signers::k256::ecdsa::RecoveryId;
use alloy::signers::k256::ecdsa::Signature as RecoverableSignature;
use alloy::signers::k256::ecdsa::Signature as K256Signature;
use alloy::signers::k256::ecdsa::SigningKey;
use alloy::signers::k256::ecdsa::VerifyingKey;
use alloy::signers::k256::PublicKey;
use alloy::signers::local::LocalSigner;
use alloy::signers::SignerSync;
use anyhow::Result;
use base64::prelude::BASE64_URL_SAFE_NO_PAD;
use base64::Engine;
use elliptic_curve::consts::U32;
use elliptic_curve::sec1::ToEncodedPoint;
use ethers::prelude::LocalWallet;
use ethers::prelude::Signature;
use ethers_core::k256::ecdsa::RecoveryId;
use ethers_core::k256::ecdsa::Signature as RecoverableSignature;
use ethers_core::k256::ecdsa::Signature as K256Signature;
use ethers_core::k256::ecdsa::VerifyingKey;
use ethers_core::k256::PublicKey;
use ethers_core::utils::hash_message;
use generic_array::GenericArray;
use jwt::Claims;
use jwt::ToBase64;
use serde::Deserialize;
use serde::Serialize;
use serde_with::serde_as;
use serde_with::DisplayFromStr;

#[serde_as]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct JWTAuth {
claims: Claims,
#[serde_as(as = "DisplayFromStr")]
signature: Signature,
}

impl JWTAuth {
/// Create a new instance and sign with the wallet.
pub fn new(
claims: Claims,
wallet: &LocalWallet,
wallet: &LocalSigner<SigningKey>,
) -> Result<Self> {
let msg = claims.to_base64()?;

// `sign_message` is an async function:
// <https://github.com/gakonst/ethers-rs/blob/master/ethers-signers/src/wallet/mod.rs#L85>
// Seems not make sense, so copy the code here.
let message_hash = hash_message(msg.as_bytes());
let signature = wallet.sign_hash(message_hash)?;
let signature = wallet.sign_message_sync(msg.as_bytes())?;

Ok(Self { claims, signature })
}
Expand Down Expand Up @@ -66,7 +68,7 @@ impl JWTAuth {
/// Recovers the Lagrange public key which was used to sign the claims.
pub fn recover_public_key(&self) -> Result<String> {
let msg = self.claims.to_base64()?;
let message_hash = hash_message(msg.as_bytes());
let message_hash = eip191_hash_message(msg.as_bytes());

let (recoverable_sig, recovery_id) = self.as_signature()?;
let verifying_key = VerifyingKey::recover_from_prehash(
Expand Down Expand Up @@ -94,12 +96,10 @@ impl JWTAuth {
/// Copied from ethers-rs since it's private:
/// <https://github.com/gakonst/ethers-rs/blob/master/ethers-core/src/types/signature.rs#L129>
fn as_signature(&self) -> Result<(RecoverableSignature, RecoveryId)> {
let mut recovery_id = self.signature.recovery_id()?;
let mut recovery_id = self.signature.recid();
let mut signature = {
let mut r_bytes = [0u8; 32];
let mut s_bytes = [0u8; 32];
self.signature.r.to_big_endian(&mut r_bytes);
self.signature.s.to_big_endian(&mut s_bytes);
let r_bytes: [_; 32] = self.signature.r().to_be_bytes();
let s_bytes: [_; 32] = self.signature.s().to_be_bytes();
let gar: &GenericArray<u8, U32> = GenericArray::from_slice(&r_bytes);
let gas: &GenericArray<u8, U32> = GenericArray::from_slice(&s_bytes);
K256Signature::from_scalars(*gar, *gas)?
Expand All @@ -125,15 +125,14 @@ mod tests {

use elliptic_curve::sec1::Coordinates;
use jwt::RegisteredClaims;
use rand::thread_rng;

use super::*;

/// Test the JWT authorization process.
#[test]
fn test_middleware_jwt_auth_process() -> Result<()> {
// Create a random wallet.
let wallet = LocalWallet::new(&mut thread_rng());
let wallet = LocalSigner::random();
let expected_public_key = get_public_key_by_wallet(&wallet);

// Encode the JWT auth.
Expand All @@ -150,8 +149,8 @@ mod tests {
}

/// Get the public key from wallet.
fn get_public_key_by_wallet(wallet: &LocalWallet) -> String {
let public_key = wallet.signer().verifying_key().to_encoded_point(false);
fn get_public_key_by_wallet(wallet: &LocalSigner<SigningKey>) -> String {
let public_key = wallet.credential().verifying_key().to_encoded_point(false);

// We use another method (different with `recover_public_key`) to get
// the coordinates of public key, then combine the big-endian bytes.
Expand Down
1 change: 0 additions & 1 deletion lgn-messages/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ edition = "2021"
[dependencies]
alloy.workspace = true
derive-debug-plus = { workspace = true }
ethers = { workspace = true }
mp2_common = { workspace = true }
mp2_v1 = { workspace = true }
object_store = { workspace = true }
Expand Down
4 changes: 2 additions & 2 deletions lgn-messages/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use ethers::types::H256;
use alloy::primitives::FixedBytes;

pub mod routing;
pub mod types;
Expand All @@ -18,4 +18,4 @@ pub type KeyedPayload = (String, Vec<u8>);
///
/// This type is versioned by the block number, since a node that stores data for
/// a slot `X` can be modified through out the contract's lifetime.
pub type MptNodeVersion = (BlockNr, H256);
pub type MptNodeVersion = (BlockNr, FixedBytes<32>);
18 changes: 9 additions & 9 deletions lgn-messages/src/types/v1/preprocessing/ext_tasks.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use alloy::primitives::Address;
use alloy::primitives::FixedBytes;
use alloy::primitives::U256;
use derive_debug_plus::Dbg;
use ethers::types::H256;
use ethers::utils::rlp;
use mp2_common::eth::node_type;
use mp2_common::eth::NodeType;
use mp2_v1::api::TableRow;
use mp2_v1::final_extraction::OffChainRootOfTrust;
use mp2_v1::indexing::cell::Cell;
Expand Down Expand Up @@ -41,15 +42,15 @@ pub enum ExtractionType {
pub struct Mpt {
pub table_hash: TableHash,
pub block_nr: BlockNr,
pub node_hash: H256,
pub node_hash: FixedBytes<32>,
pub mpt_type: MptType,
}

impl Mpt {
pub fn new(
table_hash: TableId,
block_nr: BlockNr,
node_hash: H256,
node_hash: FixedBytes<32>,
mpt_type: MptType,
) -> Self {
Self {
Expand Down Expand Up @@ -204,13 +205,12 @@ impl MPTExtractionType {
node: &[u8],
i: usize,
) -> Self {
let list: Vec<Vec<_>> = rlp::decode_list(node);
match list.len() {
match node_type(node).unwrap() {
// assuming the first node in the path is the leaf
2 if i == 0 => MPTExtractionType::Leaf,
2 => MPTExtractionType::Extension,
NodeType::Leaf if i == 0 => MPTExtractionType::Leaf,
NodeType::Leaf | NodeType::Extension => MPTExtractionType::Extension,
// assuming all nodes are valid so branch is the only choice left
_ => MPTExtractionType::Branch,
NodeType::Branch => MPTExtractionType::Branch,
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions lgn-messages/src/types/v1/preprocessing/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use alloy::primitives::Address;
use alloy::primitives::FixedBytes;
use alloy::primitives::U256;
use ethers::prelude::H256;
use ext_tasks::FinalExtractionType;
use mp2_common::types::HashOutput;
use mp2_v1::values_extraction::gadgets::column_info::ColumnInfo;
Expand Down Expand Up @@ -78,7 +78,7 @@ impl WorkerTaskType {
pub fn ext_variable_leaf(
table_hash: TableHash,
block_nr: BlockNr,
node_hash: H256,
node_hash: FixedBytes<32>,
node: Vec<u8>,
slot: u8,
evm_word: u32,
Expand All @@ -97,7 +97,7 @@ impl WorkerTaskType {
pub fn ext_variable_branch(
table_hash: TableHash,
block_nr: BlockNr,
node_hash: H256,
node_hash: FixedBytes<32>,
node: Vec<u8>,
children: Vec<MptNodeVersion>,
) -> WorkerTaskType {
Expand All @@ -113,7 +113,7 @@ impl WorkerTaskType {
pub fn ext_mapping_leaf(
table_hash: TableHash,
block_nr: BlockNr,
node_hash: H256,
node_hash: FixedBytes<32>,
key: Vec<u8>,
node: Vec<u8>,
slot: u8,
Expand All @@ -134,7 +134,7 @@ impl WorkerTaskType {
pub fn ext_mapping_branch(
table_hash: TableHash,
block_nr: BlockNr,
node_hash: H256,
node_hash: FixedBytes<32>,
node: Vec<u8>,
children: Vec<MptNodeVersion>,
) -> WorkerTaskType {
Expand Down
2 changes: 1 addition & 1 deletion lgn-provers/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ anyhow = { workspace = true }
bincode = { workspace = true }
blake3.workspace = true
bytes = { workspace = true }
ethers = { workspace = true }
futures = { workspace = true }
groth16_framework = { workspace = true }
mp2_common = { workspace = true }
mp2_v1 = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion lgn-provers/src/params/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use anyhow::bail;
use anyhow::ensure;
use anyhow::Context;
use bytes::Bytes;
use ethers::providers::StreamExt;
use futures::StreamExt;
use reqwest::StatusCode;
use tokio::fs::File;
use tokio::io::AsyncWriteExt;
Expand Down
15 changes: 8 additions & 7 deletions lgn-provers/src/provers/v1/preprocessing/euclid_prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::collections::HashMap;
use alloy::primitives::Address;
use alloy::primitives::U256;
use anyhow::bail;
use ethers::utils::rlp::Prototype;
use ethers::utils::rlp::Rlp;
use mp2_common::eth::node_type;
use mp2_common::eth::NodeType;
use mp2_common::poseidon::empty_poseidon_hash_as_vec;
use mp2_common::types::HashOutput;
use mp2_v1::api::generate_proof;
Expand Down Expand Up @@ -99,23 +99,24 @@ impl PreprocessingEuclidProver {
node: Vec<u8>,
child_proofs: Vec<Vec<u8>>,
) -> anyhow::Result<Vec<u8>> {
let rlp = Rlp::new(&node);
match rlp.prototype()? {
Prototype::List(2) => {
let node_type = node_type(&node)?;

match node_type {
NodeType::Extension => {
let input = ValuesExtraction(values_extraction::CircuitInput::new_extension(
node,
child_proofs[0].to_owned(),
));
generate_proof(&self.params, input)
},
Prototype::List(17) => {
NodeType::Branch => {
let input = ValuesExtraction(values_extraction::CircuitInput::new_branch(
node,
child_proofs,
));
generate_proof(&self.params, input)
},
_ => bail!("Invalid RLP item count"),
NodeType::Leaf => bail!("unexpected NodeType::Leaf"),
}
}

Expand Down
3 changes: 1 addition & 2 deletions lgn-worker/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,14 @@ name = "one-shot"
path = "src/one-shot.rs"

[dependencies]
alloy = { workspace = true, features = ["signers", "signer-local", "signer-keystore"] }
anyhow = { workspace = true }
backtrace = { workspace = true }
bincode.workspace = true
blake3 = { workspace = true }
clap = { workspace = true, features = ["derive", "env", "help", "std", "suggestions"] }
config = { workspace = true, features = ["toml"] }
elliptic-curve = { workspace = true }
# The ethers macro `abigen` needs to import ethers as a crate.
ethers = { git = "https://github.com/Lagrange-Labs/ethers-rs", default-features = false, features = [ "rustls" ], branch = "get-proof-0x" }
groth16_framework.workspace = true
hex = { workspace = true }
jwt = { workspace = true }
Expand Down
Loading
Loading