Compare commits
No commits in common. "ccd2f2ef03870c497e39fcb3a17f3c6048e80446" and "f628fac964ab9bb3695206a3f4710bac6a9bb7da" have entirely different histories.
ccd2f2ef03
...
f628fac964
|
@ -1,3 +0,0 @@
|
||||||
.env
|
|
||||||
Cargo.lock
|
|
||||||
/target
|
|
12
Cargo.toml
12
Cargo.toml
|
@ -1,12 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "meca"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
ethers = "2.0.11"
|
|
||||||
tokio = { version = "1.35.0", features = ["full", "rt-multi-thread"] }
|
|
||||||
dotenv = "0.15"
|
|
||||||
ecies = {version = "0.2.7", default-features = false, features = ["xchacha20"]}
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2024 David E. Perez Negron R.
|
Copyright (c) 2024 p1r0
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
|
16
README.md
16
README.md
|
@ -1,19 +1,3 @@
|
||||||
# MECA
|
# MECA
|
||||||
|
|
||||||
Make Ethereum Cypherpunk Again: Asymmetric Encryption using an EOA, by using the ECIES on ECDSA
|
Make Ethereum Cypherpunk Again: Asymmetric Encryption using an EOA, by using the ECIES on ECDSA
|
||||||
|
|
||||||
## Use Case Example
|
|
||||||
1. Bob and Alice publish their ecdsa key paired with his public address in a smart contract
|
|
||||||
2. Alice gets Bob public address and ecdsa key.
|
|
||||||
3. Alice writes a message to Bob.
|
|
||||||
4. Alice encrypts the message using ecies with ecdsa bobs public address
|
|
||||||
5. Alice stores the encrypted message in IPFS and gets an CID.
|
|
||||||
6. Alice signs an push a transaction with the encrypted message CID using Bobs public ethereum address
|
|
||||||
7. Bob verifies signature and get the CID file fetching it from IPFS.
|
|
||||||
8. Bob decripts the CID fetche message using his ecdsa private key.
|
|
||||||
|
|
||||||
## References
|
|
||||||
|
|
||||||
1. https://eips.ethereum.org/EIPS/eip-5630
|
|
||||||
2. https://docs.rs/ecies/0.2.7/ecies/index.html
|
|
||||||
3. https://ethereum.stackexchange.com/questions/56253/where-does-ethereum-store-eoas-and-public-keys
|
|
||||||
|
|
29
env.example
29
env.example
|
@ -1,29 +0,0 @@
|
||||||
# Deploy
|
|
||||||
PROVIDER_URL="HTTP://127.0.0.1:8545"
|
|
||||||
CHAIN_ID=31337
|
|
||||||
SC_ADDR="0x5FbDB2315678afecb367f032d93F642f64180aa3"
|
|
||||||
|
|
||||||
# Anvil Accounts
|
|
||||||
ACC0="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
|
|
||||||
ACC1="0x70997970C51812dc3A010C7d01b50e0d17dc79C8"
|
|
||||||
ACC2="0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC"
|
|
||||||
ACC3="0x90F79bf6EB2c4f870365E785982E1f101E93b906"
|
|
||||||
ACC4="0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65"
|
|
||||||
ACC5="0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc"
|
|
||||||
ACC6="0x976EA74026E726554dB657fA54763abd0C3a0aa9"
|
|
||||||
ACC7="0x14dC79964da2C08b23698B3D3cc7Ca32193d9955"
|
|
||||||
ACC8="0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f"
|
|
||||||
ACC9="0xa0Ee7A142d267C1f36714E4a8F75612F20a79720"
|
|
||||||
|
|
||||||
# Anvil Private Keys
|
|
||||||
PK0="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
|
|
||||||
PK1="0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"
|
|
||||||
PK2="0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a"
|
|
||||||
PK3="0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6"
|
|
||||||
PK4="0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a"
|
|
||||||
PK5="0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba"
|
|
||||||
PK6="0x92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e"
|
|
||||||
PK7="0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356"
|
|
||||||
PK8="0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97"
|
|
||||||
PK9="0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6"
|
|
||||||
|
|
87
src/main.rs
87
src/main.rs
|
@ -1,87 +0,0 @@
|
||||||
use ethers::core::k256::ecdsa::VerifyingKey;
|
|
||||||
use ethers::prelude::*;
|
|
||||||
use ethers::utils;
|
|
||||||
use ecies;
|
|
||||||
use dotenv::dotenv;
|
|
||||||
use std::env;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
// Until now we just do a Proof of concept of ecdsa_ecies encryption/decryption.
|
|
||||||
|
|
||||||
// 1. Alice and Bob exchange their public address and ecdsa key.
|
|
||||||
// 2. Alice writes a message to Bob.
|
|
||||||
// 3. Alice encrypts the message using ecies with ecdsa bobs public address
|
|
||||||
// 4. Bob decripts the using his ecdsa private key.
|
|
||||||
|
|
||||||
// Alice = account 1
|
|
||||||
// Bob = account 2
|
|
||||||
|
|
||||||
// ToDo. Add the signature section to verify the message
|
|
||||||
|
|
||||||
// Step 1: Fetch ecdsa Private Keys (Ethereum Private Keys from .env)
|
|
||||||
dotenv().ok();
|
|
||||||
let private_key_1: String = env::var("PK0").unwrap().parse()
|
|
||||||
.expect("error fetching the env variable PK0");
|
|
||||||
let private_key_2: String = env::var("PK1").unwrap().parse()
|
|
||||||
.expect("error fetching the env variable PK0");
|
|
||||||
|
|
||||||
// Create a wallets from the private key
|
|
||||||
let wallet_1: LocalWallet = private_key_1.parse().unwrap();
|
|
||||||
let wallet_2: LocalWallet = private_key_2.parse().unwrap();
|
|
||||||
|
|
||||||
// Private Keys as non zero scalar
|
|
||||||
println!("Signer1 Private Key is: {}", wallet_1.signer().as_nonzero_scalar());
|
|
||||||
println!("Signer2 Private Key is: {}", wallet_2.signer().as_nonzero_scalar());
|
|
||||||
|
|
||||||
// Access the full ecdsa public key
|
|
||||||
// NOTE: this is public key is the required for ECIES to provide
|
|
||||||
// asymmetric encryption
|
|
||||||
let ecdsa_public_key_1 = wallet_1.signer().verifying_key();
|
|
||||||
let ecdsa_public_key_2 = wallet_2.signer().verifying_key();
|
|
||||||
|
|
||||||
// Print the full uncompressed ECDSA public key
|
|
||||||
println!("Full Public Key of signer 1: {}", ecdsa_public_key_1.to_encoded_point(false));
|
|
||||||
println!("Full Public Key of signer 2: {}", ecdsa_public_key_2.to_encoded_point(false));
|
|
||||||
|
|
||||||
// Print Full Public Address (without checksum) 32 Bytes keccak256 digest
|
|
||||||
// Ethereum Wallet Conversion public key 1
|
|
||||||
println!("Account1 eth address(full keccak256 digest): {:?}", public_key_to_full_address(ecdsa_public_key_1));
|
|
||||||
println!("Account2 eth address(full keccak256 digest): {:?}", public_key_to_full_address(ecdsa_public_key_2));
|
|
||||||
// TODO verify checksum
|
|
||||||
// https://github.com/ethereum/ercs/blob/master/ERCS/erc-55.md
|
|
||||||
|
|
||||||
// Print Ethereum address (unsure if has checksum)
|
|
||||||
let address_1 = utils::public_key_to_address(ecdsa_public_key_1);
|
|
||||||
let address_2 = utils::public_key_to_address(ecdsa_public_key_2);
|
|
||||||
println!("Address 1: {:?}", address_1);
|
|
||||||
println!("Address 2: {:?}", address_2);
|
|
||||||
|
|
||||||
// Step 2: Encrypt a message using ECIES with public key of address2
|
|
||||||
let message = b"Bob. Lets make Ethereum Cypherpunk Again!";
|
|
||||||
let encrypted_message = ecies::encrypt(&ecdsa_public_key_2
|
|
||||||
.to_encoded_point(false)
|
|
||||||
.as_bytes()[1..], message)
|
|
||||||
.expect("Encryption failed");
|
|
||||||
println!("Encrypted message: {:?}", encrypted_message);
|
|
||||||
|
|
||||||
let signer_2_private_key=wallet_2.signer().as_nonzero_scalar().to_bytes();
|
|
||||||
// Step 4: Decrypt the message using private key of address2
|
|
||||||
let decrypted_message = ecies::decrypt(&signer_2_private_key, &encrypted_message)
|
|
||||||
.expect("Decryption failed");
|
|
||||||
|
|
||||||
println!("Decrypted message: {:?}", std::str::from_utf8(&decrypted_message).unwrap());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn public_key_to_full_address(pubkey: &VerifyingKey) -> H256 {
|
|
||||||
let pubkey = pubkey.to_encoded_point(false);
|
|
||||||
let pubkey = &pubkey.as_bytes()[1..];
|
|
||||||
assert_eq!(pubkey.len(), 64, "raw public key must be 64 bytes");
|
|
||||||
let digest = utils::keccak256(pubkey);
|
|
||||||
H256::from_slice(&digest)
|
|
||||||
}
|
|
||||||
|
|
||||||
//ToDo
|
|
||||||
//pub fn ecdsa_pk_to_ecies(pubkey: &VerifyingKey) -> [u8] {
|
|
||||||
//}
|
|
||||||
|
|
Loading…
Reference in New Issue