-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from hexanova/rustler_init
- Loading branch information
Showing
13 changed files
with
924 additions
and
5 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
Large diffs are not rendered by default.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
defmodule Hexpds.K256 do | ||
use Rustler, otp_app: :hexpds, crate: "hexpds_k256" | ||
def create_public_key(private_key), do: :erlang.nif_error(:nif_not_loaded) | ||
end |
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,64 @@ | ||
defmodule RecordConverter do | ||
alias Hexpds.CID, as: CID | ||
|
||
# Converts a record to a JSON-compatible format. | ||
def record_to_json(record) do | ||
cond do | ||
is_list(record) -> | ||
Enum.map(record, &record_to_json/1) | ||
|
||
is_map(record) -> | ||
Enum.reduce(record, %{}, fn {k, v}, acc -> | ||
Map.put(acc, k, record_to_json(v)) | ||
end) | ||
|
||
# Assuming CID module exists with an encode function | ||
record.__struct__ == CID -> | ||
%{"$link" => CID.encode(record, "base32")} | ||
|
||
is_binary(record) -> | ||
raise ArgumentError, "can't represent bytes as JSON" | ||
|
||
true -> | ||
record | ||
end | ||
end | ||
|
||
# Enumerates CIDs within a record. | ||
def enumerate_record_cids(record) do | ||
cond do | ||
is_list(record) -> | ||
Enum.flat_map(record, &enumerate_record_cids/1) | ||
|
||
is_map(record) -> | ||
Enum.flat_map(record, fn {_k, v} -> enumerate_record_cids(v) end) | ||
|
||
record.__struct__ == CID -> | ||
[record] | ||
|
||
true -> | ||
[] | ||
end | ||
end | ||
|
||
# Converts JSON data to a record format. | ||
def json_to_record(data) do | ||
cond do | ||
is_list(data) -> | ||
Enum.map(data, &json_to_record/1) | ||
|
||
is_map(data) -> | ||
if Kernel.map_size(data) == 1 and Map.has_key?(data, "$link") do | ||
# Assuming CID module exists with a decode function | ||
CID.decode(data["$link"]) | ||
else | ||
Enum.reduce(data, %{}, fn {k, v}, acc -> | ||
Map.put(acc, k, json_to_record(v)) | ||
end) | ||
end | ||
|
||
true -> | ||
data | ||
end | ||
end | ||
end |
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,5 @@ | ||
[target.'cfg(target_os = "macos")'] | ||
rustflags = [ | ||
"-C", "link-arg=-undefined", | ||
"-C", "link-arg=dynamic_lookup", | ||
] |
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,14 @@ | ||
# Generated by Cargo | ||
# will have compiled files and executables | ||
debug/ | ||
target/ | ||
|
||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries | ||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html | ||
Cargo.lock | ||
|
||
# These are backup files generated by rustfmt | ||
**/*.rs.bk | ||
|
||
# MSVC Windows builds of rustc generate these, which store debugging information | ||
*.pdb |
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,17 @@ | ||
[package] | ||
name = "hexpds_k256" | ||
version = "0.1.0" | ||
authors = [ "NetWatchInc" ] | ||
edition = "2021" | ||
|
||
[lib] | ||
name = "hexpds_k256" | ||
path = "src/lib.rs" | ||
crate-type = ["cdylib"] | ||
|
||
[dependencies] | ||
atoms = "2.2.3" | ||
elliptic-curve = "0.13.8" | ||
hex = "0.4.3" | ||
k256 = "0.10.1" | ||
rustler = "0.30.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,20 @@ | ||
# NIF for Elixir.Hexpds.k256 | ||
|
||
## To build the NIF module: | ||
|
||
- Your NIF will now build along with your project. | ||
|
||
## To load the NIF: | ||
|
||
```elixir | ||
defmodule Hexpds.K256 do | ||
use Rustler, otp_app: :hexpds, crate: "hexpds_k256" | ||
|
||
# When your NIF is loaded, it will override this function. | ||
def create_public_key(private_key), do: :erlang.nif_error(:nif_not_loaded) | ||
end | ||
``` | ||
|
||
## Examples | ||
|
||
[This](https://github.com/rusterlium/NifIo) is a complete example of a NIF written in Rust. |
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,32 @@ | ||
use rustler::{Encoder, Env, Term}; | ||
use k256::{elliptic_curve::sec1::ToEncodedPoint, SecretKey}; | ||
use hex; | ||
|
||
mod atoms { | ||
rustler::atoms! { | ||
ok, | ||
error, | ||
} | ||
} | ||
|
||
#[rustler::nif] | ||
fn create_public_key(env: Env, private_key: String) -> Term { | ||
let private_key_bytes = match hex::decode(&private_key) { | ||
Ok(bytes) => bytes, | ||
Err(e) => return (atoms::error(), format!("Failed to decode hex string: {}", e)).encode(env), | ||
}; | ||
|
||
let secret_key = match SecretKey::from_be_bytes(&private_key_bytes) { | ||
Ok(key) => key, | ||
Err(e) => return (atoms::error(), format!("Failed to create secret key: {}", e)).encode(env), | ||
}; | ||
|
||
let public_key = secret_key.public_key(); | ||
|
||
let public_key_hex = hex::encode(public_key.to_encoded_point(false).as_bytes()); | ||
|
||
(atoms::ok(), public_key_hex).encode(env) | ||
} | ||
|
||
rustler::init!("Elixir.Hexpds.K256", [create_public_key]); | ||
|
Binary file not shown.