# Constraint linearity in the resource machine

**URL:** <https://forum.anoma.net/t/constraint-linearity-in-the-resource-machine/670>\
**Category:** RM\
**Created:** [July 2, 2024, 3:19pm UTC](https://forum.anoma.net/t/constraint-linearity-in-the-resource-machine/670 "2024-07-02T15:19:40Z")\
**Posts on this page:** 1\
**Showing post:** 35

<div class="post-metadata">

**Author:** ![Michael](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.anoma.net/michael/32/434_2.png) [@Michael](https://forum.anoma.net/u/Michael)\
**Post date:** [July 15, 2024, 10:07am UTC](https://forum.anoma.net/t/constraint-linearity-in-the-resource-machine/670/35 "2024-07-15T10:07:23Z")

</div>

> Should be a nullifier, I believe

I just realized that there is still a problem in the context of authorization via signed messages in the extra data (a type alias in the Juvix code hid it for me until now).

If we require the nullifier `nf` instead of the commitment `cm`, we must be able to reproduce it as part of the authorization check (i.e., `isAuthorizedByOwner`) being part of the resource logic (see the implementation code at the end of this post).

However, resource logic functions being currently defined as

```haskell
logic : (self : Resource) (tx : Transaction) -> Bool

```

only receive the resource plaintext `self` and transaction `tx` as inputs, which is not enough to compute the nullifier \texttt{nf} = h\_\texttt{nf}(\texttt{nk}, r). We need the nullifier key `nk` as well, to which the resource logic function does not have access.

I am also aware that we most likely do not want to share the nullifier key, although it can be a randomly generated secret used only once for this specific resource – @vveiln explained it here:

> [@Nullifier Key in the Context of Kudo](https://forum.anoma.net/t/nullifier-key-in-the-context-of-kudo/648/2):
>
> This is not application-specific and defined on the resource machine instantiation level. For example, in Taiga the nullifier key is randomly generated. The user generates a nullifier key, computes the nullifier public key and shares the nullifier public key with the solver so that the solver can create resources for the user. I think you can implement kudos as both shielded or transparent application, “lower security” mostly refers to the way you instantiate the resource machine, not the wa…

If we are ok with sharing it, we could put `nk` (encrypted?) into the `extra` data map, but then the question is under which key to find it. The only way seems to be to use the commitment h\_\texttt{cm}(\texttt{self}) of the `self` resource as the lookup key, which we don’t want to use as it reveals information about the creation date and brings us back to the beginning.

Any ideas how to solve this more simply and elegantly @vveiln @cwgoes @degregat ?  
I am not sure if this changes with an action stack. It could work if an action contains exactly one consumed resource, because then there is only one nullifier to search for.

### Implementation Code

```haskell
tokenLogic
  (self : Resource) (tx : Transaction) : Bool :=
  if
    | isConsumed self tx := isAuthorizedByOwner self tx -- <-- NOTE: `nk` cannot be passed here
    | isCreated self tx := true
    | else := false;

isAuthorizedByOwner
  (self : Resource)
  (tx : Transaction)
  (nk : NullifierKey) -- <-- NOTE: This argument is not available in `tokenLogic.
  : Bool :=
  let
    owner : PublicKey := getOwner self;
    selfNf : Helper.Nullifier := nullifier self nk;
    lookupResult : Maybe (Pair AuthMessage Signature) :=
      lookupExtraData (natToBytes32 selfNf) tx;
  in case lookupResult of
       | nothing := false
       | just (msg, sig) :=
         AuthMessage.consumed msg == selfNf
           && anomaVerifyDetached sig msg owner
           && isSubset
             (AuthMessage.mustBeCreated msg)
             (commitmentSet tx);

type AuthMessage :=
  mkAuthMessage {
    consumed : Nullifier;
    mustBeCreated : Set Commitment
  };

```

---

_[View the full topic](https://forum.anoma.net/t/constraint-linearity-in-the-resource-machine/670)._
