Skip to content

Commit

Permalink
Merge pull request #5 from anoma/alberto/anoma-interface
Browse files Browse the repository at this point in the history
Anoma-Risc0 interface
  • Loading branch information
Acentelles authored Nov 3, 2024
2 parents b704b49 + 3e586c1 commit 72310b6
Show file tree
Hide file tree
Showing 28 changed files with 570 additions and 493 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
Cargo.lock
methods/guest/Cargo.lock
target/
_build/
deps/
.vscode/
5 changes: 5 additions & 0 deletions anoma-interface/.formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Used by "mix format"
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"],
line_length: 78
]
File renamed without changes.
61 changes: 61 additions & 0 deletions anoma-interface/lib/risc0.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
defmodule Risc0 do
@spec prove(list(byte()), list(byte())) ::
list(byte()) | {:error, term()}
defdelegate prove(env_bytes, elf),
to: Risc0.Risc0Prover,
as: :prove

@spec verify(list(byte()), list(byte())) ::
boolean() | {:error, term()}
defdelegate verify(receipt_bytes, elf),
to: Risc0.Risc0Prover,
as: :verify


@spec generate_resource(
list(byte()),
list(byte()),
list(byte()),
list(byte()),
list(boolean()),
list(byte()),
list(byte()),
list(byte())) ::
list(byte()) | {:error, term()}
defdelegate generate_resource(
label,
nonce,
quantity,
value,
eph,
nsk,
image_id,
rseed),
to: Risc0.Risc0Prover,
as: :generate_resource

@spec generate_compliance_circuit(
list(byte()),
list(byte()),
list(byte()),
list(byte()),
list(byte())
) :: list(byte()) | {:error, term()}
defdelegate generate_compliance_circuit(
input_resource,
output_resource,
rcv,
merkle_path,
nsk
), to: Risc0.Risc0Prover, as: :generate_compliance_circuit

@spec random_32() :: list(byte()) | {:error, term()}
defdelegate random_32(), to: Risc0.Risc0Prover, as: :random_32

@spec generate_merkle_path_32() :: list(byte()) | {:error, term()}
defdelegate generate_merkle_path_32(), to: Risc0.Risc0Prover, as: :generate_merkle_path_32

@spec generate_nsk() :: list(byte()) | {:error, term()}
defdelegate generate_nsk(), to: Risc0.Risc0Prover, as: :generate_nsk

end
62 changes: 62 additions & 0 deletions anoma-interface/lib/risc0/risc0.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
defmodule Risc0.Risc0Prover do
use Rustler, otp_app: :risc0, crate: :risc0_prover

@moduledoc """
Provides NIF functions for Risc0 proof generation, verification, and related cryptographic operations.
"""

@typedoc "Result type for NIF functions that can return errors"
@type nif_result(t) :: t | {:error, term()}

@spec prove(list(byte()), list(byte())) ::
nif_result({list(byte())})
def prove(_env_bytes, _elf), do: error()

@spec verify(list(byte()), list(byte())) :: nif_result(boolean())
def verify(_receipt_bytes, _elf), do: error()

@spec generate_resource(
list(byte()),
list(byte()),
list(byte()),
list(byte()),
list(boolean()),
list(byte()),
list(byte()),
list(byte())) :: nif_result(list(byte()))
def generate_resource(
_label,
_nonce,
_quantity,
_value,
_eph,
_nsk,
_image_id,
_rseed
), do: error()

@spec generate_compliance_circuit(
list(byte()),
list(byte()),
list(byte()),
list(byte()),
list(byte())) :: nif_result(list(byte()))
def generate_compliance_circuit(
_input_resource,
_output_resource,
_rcv,
_merkle_path,
_nsk
), do: error()

@spec random_32() :: nif_result(list(byte()))
def random_32(), do: error()

@spec generate_merkle_path_32() :: nif_result(list(byte()))
def generate_merkle_path_32(), do: error()

@spec generate_nsk() :: nif_result(list(byte()))
def generate_nsk(), do: error()

defp error, do: :erlang.nif_error(:nif_not_loaded)
end
88 changes: 88 additions & 0 deletions anoma-interface/mix.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
defmodule Cairo.MixProject do
use Mix.Project

def project do
[
app: :risc0,
version: "0.1.0",
elixir: "~> 1.15",
start_permanent: Mix.env() == :prod,
deps: deps(),
docs: docs()
]
end

# Run "mix help compile.app" to learn about applications.
def application do
[
extra_applications: [:logger]
]
end

# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:dialyxir, "~> 1.3", only: [:dev], runtime: false},
{:typed_struct, "~> 0.3.0"},
{:ex_doc, "~> 0.31", only: [:dev], runtime: false},
{:rustler, "~> 0.31.0"}
# {:dep_from_hexpm, "~> 0.3.0"},
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
]
end

defp docs do
[
before_closing_body_tag: &docs_before_closing_body_tag/1
]
end

defp docs_before_closing_body_tag(:html) do
# https://hexdocs.pm/ex_doc/readme.html#extensions
"""
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/mermaid.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
mermaid.initialize({
startOnLoad: false,
theme: document.body.className.includes("dark") ? "dark" : "default"
});
let id = 0;
for (const codeEl of document.querySelectorAll("pre code.mermaid")) {
const preEl = codeEl.parentElement;
const graphDefinition = codeEl.textContent;
const graphEl = document.createElement("div");
const graphId = "mermaid-graph-" + id++;
mermaid.render(graphId, graphDefinition).then(({svg, bindFunctions}) => {
graphEl.innerHTML = svg;
bindFunctions?.(graphEl);
preEl.insertAdjacentElement("afterend", graphEl);
preEl.remove();
});
}
});
</script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
for (const codeEl of document.querySelectorAll("pre code.vega-lite")) {
try {
const preEl = codeEl.parentElement;
const spec = JSON.parse(codeEl.textContent);
const plotEl = document.createElement("div");
preEl.insertAdjacentElement("afterend", plotEl);
vegaEmbed(plotEl, spec);
preEl.remove();
} catch (error) {
console.log("Failed to render Vega-Lite plot: " + error)
}
}
});
</script>
"""
end

defp docs_before_closing_body_tag(_), do: ""
end
14 changes: 14 additions & 0 deletions anoma-interface/mix.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
%{
"dialyxir": {:hex, :dialyxir, "1.4.4", "fb3ce8741edeaea59c9ae84d5cec75da00fa89fe401c72d6e047d11a61f65f70", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "cd6111e8017ccd563e65621a4d9a4a1c5cd333df30cebc7face8029cacb4eff6"},
"earmark_parser": {:hex, :earmark_parser, "1.4.41", "ab34711c9dc6212dda44fcd20ecb87ac3f3fce6f0ca2f28d4a00e4154f8cd599", [:mix], [], "hexpm", "a81a04c7e34b6617c2792e291b5a2e57ab316365c2644ddc553bb9ed863ebefa"},
"erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"},
"ex_doc": {:hex, :ex_doc, "0.34.2", "13eedf3844ccdce25cfd837b99bea9ad92c4e511233199440488d217c92571e8", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "5ce5f16b41208a50106afed3de6a2ed34f4acfd65715b82a0b84b49d995f95c1"},
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
"makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"},
"makeup_erlang": {:hex, :makeup_erlang, "1.0.1", "c7f58c120b2b5aa5fd80d540a89fdf866ed42f1f3994e4fe189abebeab610839", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "8a89a1eeccc2d798d6ea15496a6e4870b75e014d1af514b1b71fa33134f57814"},
"nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"},
"rustler": {:hex, :rustler, "0.31.0", "7e5eefe61e6e6f8901e5aa3de60073d360c6320d9ec363027b0197297b80c46a", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:toml, "~> 0.6", [hex: :toml, repo: "hexpm", optional: false]}], "hexpm", "99e378459bfb9c3bda6d3548b2b3bc6f9ad97f728f76bdbae7bf5c770a4f8abd"},
"toml": {:hex, :toml, "0.7.0", "fbcd773caa937d0c7a02c301a1feea25612720ac3fa1ccb8bfd9d30d822911de", [:mix], [], "hexpm", "0690246a2478c1defd100b0c9b89b4ea280a22be9a7b313a8a058a2408a2fa70"},
"typed_struct": {:hex, :typed_struct, "0.3.0", "939789e3c1dca39d7170c87f729127469d1315dcf99fee8e152bb774b17e7ff7", [:mix], [], "hexpm", "c50bd5c3a61fe4e198a8504f939be3d3c85903b382bde4865579bc23111d1b6d"},
}
5 changes: 5 additions & 0 deletions anoma-interface/native/risc0_prover/.cargo/config.toml
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",
]
23 changes: 23 additions & 0 deletions anoma-interface/native/risc0_prover/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "risc0_prover"
version = "0.1.0"
authors = []
edition = "2021"

[lib]
name = "risc0_prover"
path = "src/lib.rs"
crate-type = ["cdylib"]

[dependencies]
rustler = "0.31.0"
bincode = "1.3"
serde_bytes = "0.11"
serde = { version = "1.0.160", features = ["derive"] }
risc0-zkvm = { version = "1.1.2", features = ["prove"]}
borsh = "1.5.1"
serde_json = "1.0.120"
rand = "0.8"
aarm-core = { path = "../../../compliance-circuit/core" }
methods = { path = "../../../compliance-circuit/methods" }

23 changes: 23 additions & 0 deletions anoma-interface/native/risc0_prover/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# NIF for Elixir.Risc0

## To build the NIF module:

- Your NIF will now build along with your project.

## To load the NIF:

```elixir
defmodule Risc0.Risc0Prover do
use Rustler, otp_app: :risc0, crate: :risc0_prover

# When your NIF is loaded, it will override this function.
def prove(_arg1, _arg2), do: :erlang.nif_error(:nif_not_loaded)
def verify(_arg1, _arg2), do: :erlang.nif_error(:nif_not_loaded)
end
```

## To test the NIF:

- You must have the risc0-zkvm toolchain installed.
- If you are on macOS, you must have XCode installed. To build with the `prove` flag on macOS, you'll need to have the full version of XCode installed, which includes the 'metal' compiler. We need the `prove` feature flag to have the proving happen in the same process. Otherwise, with `default` feature flags, the prover will try to launch a `r0vm` server process to perform the actual proving. If you're calling this from some other environment, it will throw a "No child processses" error.
- You can run the tests with `mix test`.
Loading

0 comments on commit 72310b6

Please sign in to comment.