Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Anoma-Risc0 interface #5

Merged
merged 40 commits into from
Nov 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
9409ca6
init the complaince circuit
XuyangSong Sep 9, 2024
fe5f26a
Add compliance circuit
Acentelles Sep 12, 2024
091994c
Add rcv to delta
Acentelles Sep 12, 2024
fc1958d
Implement compliant circuit
Acentelles Sep 14, 2024
ecd4577
Add default compliance resource logic
Acentelles Sep 22, 2024
592e0e6
Change Cargo.toml
Acentelles Sep 22, 2024
38c23d1
Small changes
Acentelles Sep 26, 2024
de63c66
Remove ambiguous constant
Acentelles Sep 27, 2024
8c60fb6
Include methods as dependency
Acentelles Sep 27, 2024
90843e3
Remove outdated methods
Acentelles Sep 27, 2024
d63b0e1
Fix methods cargo file
Acentelles Sep 27, 2024
4b21710
Initial anoma elixir boilerplate
Acentelles Sep 27, 2024
298c164
Merge branch 'xuyang/compliance_circuit' of github.com:anoma/aarm-ris…
Acentelles Sep 30, 2024
d2b8ffb
Initial work on risc0_prover
Acentelles Oct 11, 2024
a2ac342
Run benchmarks
Acentelles Oct 16, 2024
72976fa
Merge branch 'xuyang/compliance_circuit' of github.com:anoma/aarm-ris…
Acentelles Oct 18, 2024
1c485eb
Remove warning unused variables
Acentelles Oct 18, 2024
c553f70
Merge branch 'xuyang/compliance_circuit' of github.com:anoma/aarm-ris…
Acentelles Oct 18, 2024
fe958dd
Address feedback
Acentelles Oct 21, 2024
276b406
Cargo fmt
Acentelles Oct 21, 2024
56f3881
Fix warnings
Acentelles Oct 21, 2024
96b7968
Merge branch 'xuyang/compliance_circuit' of github.com:anoma/aarm-ris…
Acentelles Oct 21, 2024
ad15258
Add interface prove and verify
Acentelles Oct 21, 2024
bcd1ff7
Fix interfaces
Acentelles Oct 21, 2024
e4fcc75
Test compliance circuit on elixir
Acentelles Oct 22, 2024
62cc5ce
Implement ScalarWrapper for BorshSeriliaze
Acentelles Oct 23, 2024
02cfd7c
Implement generate resources
Acentelles Oct 23, 2024
ff17608
Update interface
Acentelles Oct 23, 2024
450c583
Add test helpers
Acentelles Oct 23, 2024
0e1c134
Run test
Acentelles Oct 23, 2024
31108c4
Cleanup
Acentelles Oct 23, 2024
56915ad
Debug elixir test
Acentelles Oct 29, 2024
7d15361
Minor change
Acentelles Oct 29, 2024
2167350
Cleanup
Acentelles Oct 29, 2024
189490c
Add prove feature flag
Acentelles Oct 31, 2024
6a19baf
Change serialisation
Acentelles Nov 1, 2024
00a89aa
Fix env_bytes
Acentelles Nov 3, 2024
e9dbe3a
Add to gitignore
Acentelles Nov 3, 2024
3db49fd
Update readme
Acentelles Nov 3, 2024
3e586c1
Remove old folder host-old
Acentelles Nov 3, 2024
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
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