Skip to content

Commit

Permalink
rm wip
Browse files Browse the repository at this point in the history
  • Loading branch information
juped authored and mariari committed Dec 20, 2023
1 parent 5a2c40e commit c037be9
Show file tree
Hide file tree
Showing 13 changed files with 490 additions and 168 deletions.
38 changes: 36 additions & 2 deletions hoon/anoma.hoon
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
!.
=~ %909
~% %k.909 ~ ~
:: layer 0: version stub (+3)
:: layer 0: version stub (+7)
|%
++ anoma +
--
:: layer 1: basic arithmetic (+1)
:: layer 1: basic arithmetic (+3)
~% %one + ~
|%
++ dec :: +342
Expand Down Expand Up @@ -76,4 +76,38 @@
?< =(0 b)
(sub a (mul b (div a b)))
--
:: layer 2: fancy arithmetic (+1)
|%
++ modulo :: name this 'mod' and rename 'mod' to 'rem'?
|_ modulus=@
++ reduce
|= a=@
^- @
(mod a modulus)
++ congruent
|= [a=@ b=@]
.= (reduce a) (reduce b)
++ add
|= [a=@ b=@]
^- @
(reduce (^add a b))
++ sub
|= [a=@ b=@]
^- @
(reduce (^sub (^add modulus a) (reduce b)))
++ mul
|= [a=@ b=@]
^- @
(reduce (^mul a b))
++ neg
|= a=@
^- @
(^sub modulus (reduce a))
++ inv :: only works in prime fields
!!
++ div :: only works in prime fields
|= [a=@ b=@]
(mul a (inv b))
--
--
==
15 changes: 15 additions & 0 deletions lib/anoma/delta.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
defmodule Anoma.Delta do
@moduledoc false

@type t() :: %{binary() => non_neg_integer()}

def add(d1, d2) do
Map.merge(d1, d2, fn _k, v1, v2 -> v1 + v2 end)
|> Map.reject(fn {_k, v} -> v == 0 end)
end

def sub(d1, d2) do
Map.merge(d1, d2, fn _k, v1, v2 -> v1 - v2 end)
|> Map.reject(fn {_k, v} -> v == 0 end)
end
end
10 changes: 10 additions & 0 deletions lib/anoma/proof.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
defmodule Anoma.Proof do
@moduledoc false

use TypedStruct

# a transparent resource logic proof is just the resource
typedstruct enforce: true do
field(:resource, Anoma.Resource.t())
end
end
20 changes: 20 additions & 0 deletions lib/anoma/proof_record.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
defmodule Anoma.ProofRecord do
@moduledoc false

alias __MODULE__
use TypedStruct

alias Anoma.Proof

typedstruct enforce: true do
field(:proof, Anoma.Proof.t(), default: nil)
end

def prove(resource) do
%ProofRecord{
proof: %Proof{
resource: resource
}
}
end
end
170 changes: 137 additions & 33 deletions lib/anoma/resource.ex
Original file line number Diff line number Diff line change
@@ -1,61 +1,165 @@
defmodule Anoma.Resource do
@moduledoc """
Ι represent a resource
Ι represent a resource.
Do not create with `%Anoma.Resource{}` directly, instead use
`%{Anoma.Resource.new | ...}` for random nonce and seed.
"""

alias __MODULE__
use TypedStruct

typedstruct do
# TODO Should we make this a sexp or a logic?
field(:logic, Anoma.Logic.t(), default: 0)
field(:quantity, integer(), enforce: true)
field(:value, binary(), default: <<>>)
# also known as dynamic data
field(:suffix, binary(), default: <<>>)
# also known as static data
field(:prefix, binary(), default: <<>>)
field(:data, any(), default: <<>>)
alias Anoma.Sign

typedstruct enforce: true do
# resource logic
field(:logic, Noun.t(), default: [[1 | 0], 0 | 0])
# fungibility label
field(:label, binary(), default: <<>>)
# quantity
field(:quantity, non_neg_integer(), default: 0)
# arbitrary data
field(:data, binary(), default: <<>>)
# ephemerality flag
field(:eph, bool(), default: false)
# resource nonce
field(:nonce, <<_::256>>, default: <<0::256>>)
# nullifier public key
field(:npk, Sign.ed25519_public(), default: <<0::256>>)
# random seed
field(:rseed, <<_::256>>, default: <<0::256>>)
end

@doc "New blank resource. Randomized nonce and seed."
def new do
nonce = :crypto.strong_rand_bytes(32)
rseed = :crypto.strong_rand_bytes(32)
%Resource{nonce: nonce, rseed: rseed}
end

@doc """
Helper to pass in the npk for initializing a valid but meaningless
resource.
"""
def new_with_npk(npk) do
%{new() | npk: npk}
end

@doc "A commitment to the given resource."
def commitment(resource = %Resource{}) do
"committo" <> :erlang.term_to_binary(resource)
end

@doc """
The nullifier of the given resource.
(It's up to the caller to use the right secret.)
"""
def nullifier(resource = %Resource{}, secret) do
("annullo" <> :erlang.term_to_binary(resource))
|> Sign.sign(secret)
end

@spec denomination(t()) :: binary()
def denomination(denom) do
Anoma.Serializer.serialize([denom.logic, denom.prefix])
@doc """
The kind of the given resource (labelled logic).
"""
def kind(resource = %Resource{}) do
:erlang.term_to_binary(resource.logic) <> :erlang.term_to_binary(resource.label)
end

@doc """
Create an empty resource with a given quantity
The delta of the given resource (kind and quantity).
"""
@spec new(integer()) :: t()
def new(num) do
%Resource{quantity: num}
def delta(resource = %Resource{}) do
%{kind(resource) => resource.quantity}
end

def transparent_committed_resource(commitment) do
with "committo" <> committed_resource_bytes <- commitment do
{:ok, :erlang.binary_to_term(committed_resource_bytes)}
else
_ -> :error
end
end

@doc """
Whether a commitment commits to a given resource.
"""
def commits_to(commitment, resource) do
with {:ok, committed_resource} <- transparent_committed_resource(commitment) do
committed_resource == resource
else
_ -> false
end
end

I help create a completely empty resource, with a given term as the
suffix.
def commits_to_any(commitment, resources) do
Enum.any?(resources, fn r -> commitment |> commits_to(r) end)
end

This is mainly helpful in testing, as we can create unique empty
resources.
@doc """
Whether a nullifier nullifies a given resource.
"""
def nullifies(nullifier, resource) do
with {:ok, verified_nullifier} <- Sign.verify(nullifier, resource.npk),
"annullo" <> nullified_resource_bytes <- verified_nullifier do
:erlang.binary_to_term(nullified_resource_bytes) == resource
else
_ -> false
end
end

## Parameters
def nullifies_any(nullifier, resources) do
Enum.any?(resources, fn r -> nullifier |> nullifies(r) end)
end

- `suffix` - any term that will be turned into a binary for testing
def run_resource_logic(transaction, resource) do
logic = resource.logic
result = Nock.nock(logic, [9, 2, 0 | 1])
IO.inspect(result, label: "nock result")

## Output
case result do
{:ok, 0} ->
true

- The empty resource
_ ->
false
end
end

@doc """
The resource as a noun.
"""
@spec make_empty(term()) :: t()
def make_empty(suffix) do
%Resource{quantity: 0, suffix: :erlang.term_to_binary(suffix)}
def to_noun(resource = %Resource{}) do
[
resource.logic,
Noun.atom_binary_to_integer(resource.label),
resource.quantity,
Noun.atom_binary_to_integer(resource.data),
if resource.eph do
0
else
1
end,
Noun.atom_binary_to_integer(resource.nonce),
Noun.atom_binary_to_integer(resource.npk)
| Noun.atom_binary_to_integer(resource.rseed)
]
end
end

defimpl Anoma.Intent, for: Anoma.Resource do
def is_intent(_data) do
true
def from_noun([logic, label, quantity, data, eph, nonce, npk | rseed]) do
%Resource{
logic: logic,
label: Noun.atom_integer_to_binary(label),
quantity: quantity,
data: Noun.atom_integer_to_binary(data),
eph:
case eph do
0 -> true
1 -> false
end,
nonce: Noun.atom_integer_to_binary(nonce),
npk: Noun.atom_integer_to_binary(npk),
rseed: Noun.atom_integer_to_binary(rseed)
}
end
end
21 changes: 21 additions & 0 deletions lib/anoma/sign.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
defmodule Anoma.Sign do
@moduledoc false

@type ed25519_public() :: <<_::256>>
@type ed25519_secret() :: <<_::512>>

@spec new_keypair() :: %{public: ed25519_public(), secret: ed25519_secret()}
def new_keypair do
:enacl.crypto_sign_ed25519_keypair()
end

@spec sign(binary(), ed25519_secret()) :: binary()
def sign(message, secret) do
:enacl.sign(message, secret)
end

@spec verify(binary, ed25519_public()) :: binary()
def verify(signed_message, public) do
:enacl.sign_open(signed_message, public)
end
end
Loading

0 comments on commit c037be9

Please sign in to comment.