forked from xJonathanLEI/starknet-rs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: add C++ example with cxx (xJonathanLEI#328)
- Loading branch information
1 parent
bbdba91
commit fc64165
Showing
11 changed files
with
170 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
/examples/starknet-cxx/build/ | ||
/target/ | ||
/.idea |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
cmake_minimum_required(VERSION 3.21) | ||
|
||
project(starknet_rs_in_cpp CXX) | ||
|
||
include(FetchContent) | ||
|
||
set(CMAKE_EXPORT_COMPILE_COMMANDS true) | ||
set(CMAKE_CXX_STANDARD 17) | ||
|
||
FetchContent_Declare( | ||
Corrosion | ||
GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git | ||
GIT_TAG master | ||
) | ||
FetchContent_MakeAvailable(Corrosion) | ||
|
||
add_subdirectory(starknet-cxx) | ||
|
||
add_executable(main main.cpp) | ||
target_link_libraries(main PRIVATE starknet_cxx_bridge) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# Example usage of starknet-rs from C++ | ||
|
||
This is a quick demo on exposing `starknet-crypto` to C++ with the [cxx](https://github.com/dtolnay/cxx) bridge and [corrosion](https://github.com/corrosion-rs/corrosion). | ||
|
||
## **WARNING** | ||
|
||
As noted in the [`starknet-crypto` page](../../starknet-crypto/), you're advised to use high-level constructs exposed through `starknet-core` instead if you're not familiar with cryptographic primitives. `starknet-crypto` is chosen here considering that the C++ audience might prefer low-level libraries, but it's possible to wrap `starknet-core` as well. | ||
|
||
## Note | ||
|
||
This wrapper crate expose functions that operate on strings, which is bad and probably hurts performance. It's possible to make the C++ side create `FieldElement` instances and operate on those instead, which is much more idiomatic. That said, this demo wrapper crate seems to already offer decent performance. | ||
|
||
Moreover, this crate does not implement error handling and always just panics on error, which is likely not what you want in production. | ||
|
||
However, the goal of this crate is just to demonstrate using the library from C++, _NOT_ to create idiomatic bindings, which is way too much work to maintain as an example, and should be a project of its own. | ||
|
||
## Running the example | ||
|
||
With necessary toolings installed: | ||
|
||
```console | ||
$ mkdir build && cd build | ||
$ cmake -DCMAKE_BUILD_TYPE=Release .. | ||
$ make | ||
``` | ||
|
||
It everything goes well, you should now have a `main` executable: | ||
|
||
```console | ||
$ ./main | ||
pedersen_hash(): | ||
0x030e480bed5fe53fa909cc0f8c4d99b8f9f2c016be4c41e13a4848797979c662 | ||
ecdsa_sign(): | ||
0x0411494b501a98abd8262b0da1351e17899a0c4ef23dd2f96fec5ba847310b200405c3191ab3883ef2b763af35bc5f5d15b3b4e99461d70e84c654a351a7c81b | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#include "starknet_cxx_bridge/lib.h" | ||
#include <iostream> | ||
|
||
int main() { | ||
auto hash = pedersen_hash( | ||
"0x3d937c035c878245caf64531a5756109c53068da139362728feb561405371cb", | ||
"0x208a0a10250e382e1e4bbe2880906c2791bf6275695e02fbbc6aeff9cd8b31a" | ||
); | ||
|
||
// WARNING: DO NOT hard code the k value in real code!! Doing so would expose the private key. | ||
auto signature = ecdsa_sign( | ||
"0x1", | ||
"0x2", | ||
"0x3" | ||
); | ||
|
||
std::cout << "pedersen_hash():" << "\n" | ||
<< " " << hash.c_str() << "\n" | ||
<< "ecdsa_sign():" << "\n" | ||
<< " " << signature.c_str() << "\n"; | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
corrosion_import_crate(MANIFEST_PATH Cargo.toml) | ||
corrosion_add_cxxbridge(starknet_cxx_bridge CRATE starknet-cxx MANIFEST_PATH starknet-cxx FILES lib.rs) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
[package] | ||
name = "starknet-cxx" | ||
version = "0.1.0" | ||
authors = ["Jonathan LEI <[email protected]>"] | ||
edition = "2021" | ||
|
||
[dependencies] | ||
cxx = "1.0" | ||
|
||
# Using path dependency here to make development easier. However, you probably want to fetch the | ||
# crate from crates.io instead, which means changing the next line to: | ||
# | ||
# starknet-crypto = "0.4.2" | ||
starknet-crypto = { version = "0.4.2", path = "../../../starknet-crypto" } | ||
|
||
[build-dependencies] | ||
cxx-build = "1.0" | ||
|
||
[lib] | ||
crate-type = ["staticlib"] | ||
|
||
[profile.dev] | ||
panic = "abort" | ||
|
||
[profile.release] | ||
panic = "abort" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
//! This is a quick demo on exposing `starknet-crypto` to C++ with the cxx bridge: | ||
//! https://github.com/xJonathanLEI/starknet-rs/issues/325 | ||
//! | ||
//! This wrapper crate expose functions that operate on strings, which is bad and probably hurts | ||
//! performance. It's possible to make the C++ side create `FieldElement` instances and operate on | ||
//! those instead, which is much more idiomatic. That said, this demo wrapper crate seems to already | ||
//! offer decent performance. | ||
//! | ||
//! Moreover, this crate does not implement error handling and always just panics on error, which | ||
//! is likely not what you want in production. | ||
//! | ||
//! However, the goal of this crate is just to demonstrate using the library from C++, NOT to | ||
//! create idiomatic bindings, which is way too much work to maintain as an example, and should be | ||
//! a project of its own. | ||
use starknet_crypto::{FieldElement, Signature}; | ||
|
||
#[cxx::bridge] | ||
mod ffi { | ||
extern "Rust" { | ||
fn pedersen_hash(x: &str, y: &str) -> String; | ||
|
||
fn ecdsa_sign(private_key: &str, message: &str, k: &str) -> String; | ||
} | ||
} | ||
|
||
pub fn pedersen_hash(x: &str, y: &str) -> String { | ||
// WARNING: no error handling here | ||
let x = FieldElement::from_hex_be(x).unwrap(); | ||
let y = FieldElement::from_hex_be(y).unwrap(); | ||
|
||
format!("{:#064x}", starknet_crypto::pedersen_hash(&x, &y)) | ||
} | ||
|
||
fn ecdsa_sign(private_key: &str, message: &str, k: &str) -> String { | ||
// WARNING: no error handling here | ||
let private_key = FieldElement::from_hex_be(private_key).unwrap(); | ||
let message = FieldElement::from_hex_be(message).unwrap(); | ||
let k = FieldElement::from_hex_be(k).unwrap(); | ||
|
||
let signature: Signature = starknet_crypto::sign(&private_key, &message, &k) | ||
// WARNING: no error handling here | ||
.unwrap() | ||
.into(); | ||
|
||
format!("0x{signature}") | ||
} |