Population of nonce, rseed, and npk during Transaction Function Execution Time

As mentioned to @paulcadman this morning, I am trying to figure out how the nonce , rseed , and npk value of a resource can/should be populated in transaction function.
In particular, I would need transaction functions to be able to create a new resource r and then use its commitment cm in the tx.extra data mapping.
For this to work, the r plaintext must be complete already to produce the correct cm = h_{cm}(r) .

My question is:
How are the above mentioned fields populated during transaction function execution time?

My guess is:
The npk value can probably be provided as an input argument to the transaction function.
The nonce probably shouldn’t be an input because a user can pick one being already taken.
The rseed probably shouldn’t be an input because it could allow attackers to game/exploit applications.

Has anyone already thought about this and the communication between the Anoma node and an application transaction function potentially being required here?

@mariari @cwgoes @vveiln @degregat

2 Likes

Good questions

In transparent cases, you can find the plaintext of all resources in ProofRecord, including the npk, nonce, rseed, etc. @ray checks uniqueness of commitments and nullifiers when storing them. Even if someone uses malicious nonces, it won’t cause any issues. rseed may not have much significance in transparent transactions. It’s mainly for shielded resources. Btw, the correctness of cm should not depend on the cm user provided. The Anoma node (validator) needs to recalculate or verify the correctness of cm. The correctness of nulliffier would be verified by a signature, which is designed by @ray and will be documented at some point.

In shielded cases, the plaintext of resources won’t be exposed in a transaction. The zk proof goes into the ProofRecord of the transaction. The plaintext, along with extra data, is used to generate the zk proof. Users are not allowed to choose the nonce. In compliance proof, the nonce of the output resource must be the cm of the input resource to ensure uniqueness of cm and nf. We have constraints in compliance circuits.

Hope it’s helpful

@Michael @mariari

2 Likes

Who chooses the nonce in the transparent case?
I think we need a more precise definition in what sense it is a nonce (i.e., a number used once).

It sounds to me like the application/user can choose it, and that the Anoma node just makes sure that the resource commitment is unique.

If this is the case, can there be situations, where applications try to create resources (with lazily chosen nonces) resulting in conflicting commitments and therefore transactions that can not be settled and must be repeated? That wouldn’t be a good UX.

Should there be a utility that derives nonces from the private key of the calling identity?

The nonce is usually generated randomly by the API we provided. However, if a malicious app or user manages to hack into the client code, they might be able to specify a bad nonce. But in the end, any transaction with a bad nonce will still be rejected by validators.

1 Like

Ah, so there is a utility for generating it already here, but it is not available in Juvix as a builtin yet @paulcadman.

If we want to use this function in Juvix then we must make a request (to the Anoma Node team) for it to be exposed via the Anoma / Hoon stdlib.

1 Like

transparent resource logics may make use of randomness, but that’s not related to rseed which isn’t used in the transparent case, it just comes from the execution vm

1 Like

Just a quick note: we should not assume the existence of secure randomness at replicated execution time (e.g. in the execution engine, when evaluating transaction functions). In general, secure randomness is difficult to achieve in a replicated execution context since replicated execution must also be deterministic. We may be able to achieve it in some cases using threshold cryptographic schemes, but this should not be a requirement in order to run the resource machine.

I suspect that secure randomness is only required for certain guarantees in the shielded resource case, but we should double-check this (cc @xuyang).

1 Like

The existence of secure randomness is never assumed, and the protocol doesn’t rely on it either. All the computation on the validator side is deterministic. Are there any security concerns?

In theory, you only need a different nonce when everything else in the resource is exactly the same. When creating a resource, the user has to specify a nonce anyway, which happens on client side. The user can use anoma’s default API, which I assume uses a system random-generator API. Alternatively, the user can also specify the nonce as all zeros if they want. Additionally, we have mechanisms in place on the validator to prevent duplicate cms and nfs.

2 Likes

Thanks for all the answers. It now got clear to me.

Maybe my confusion came from the naming. A nonce being commonly defined as

  • A value that is used only once.
  • A time-varying value that has at most a negligible chance of repeating, for example, a random value that is generated anew for each use, a timestamp, a sequence number, or some combination of these.
  • A random or non-repeating value that is included in data exchanged by a protocol, usually for the purpose of guaranteeing the transmittal of live data rather than replayed data, thus detecting and protecting against replay attacks.
  • […]

Source: nonce - Glossary | CSRC

created the expectation for me that there is a mechanism populating this field so that it really has an “at most a negligible chance of repeating”.
However, there is no mechanism protecting the nonce from always being chosen with 0, e.g., by an application developer, and we check instead that the resulting commitment is unique.

This works, obviously, and there is no security concern. I just want to point out that this created a wrong expectation.

Maybe nonce is, in fact, an additional entropy source (besides rseed) making sure that the resulting commitment cm is a true nonce. Should nonce be renamed to entropy?
(It is worth noting that rseed is not necessarily an entropy source for the commitment derivation, as devs might want to have identical resources with the same rseed. Thus, to make these resources unique, we still need the nonce.)

The simple solution for now @paulcadman, could be that we have a random number generator on the Juvix side populating the field by default, when a resource constructor is called.

It is another thing that comes from the shielded case. In the shielded case (taiga) nonce is set to be a nullifier of the resource from the same compliance statement (which contains one created and one consumed resource), and because nullifiers are unique the nonce field is also unique.

It might be confusing to have it called nonce, and I’m not very happy it being generated randomly, but I think renaming it to entropy makes even less sense to be honest. Devs might want to have identical resources with the same rseed, but what stops them from wanting the resources to have the same entropy fields? Whatever the answer to that question is, it can be re-applied to the rseed field, making having two entropy sources redundant

The fact that we are generating this field randomly for the transparent instantiation doesn’t imply it is always random for every rm, it is an implementation choice

Right. However, the name nonce implies that it “has at most a negligible chance of repeating” and the fact that this is actually an implementation or even developer/user choice is confusing.

when Alice creates “10 space bucks”, and then identically but distinctly creates “10 space bucks” again, the second “10 space bucks” cannot be committed to the resource set unless it differs in some field.

sometimes, Alice wants to do this; maybe she has 20 identical space bucks and wants to split them this way

choosing a 128-bit (or whatever) random number to fill in this field in the ordinary-course code paths is a simple way to make sure this caveat never bothers a user during the next however many zillions of years. nothing else is done with the field and it’s not used as entropy, used to seed anything, &c.

i’m not planning to change it because i’m a user and i don’t want to be bothered in the next however many zillions of years either. juvix code can do whatever it likes (and has to, the particular code in question isn’t a thing i provide to user code, it’s a thing i provide to my own elixir repl), but it probably wants to do things like generate “10 space bucks” twice distinctly at some point.

what i can do which may help juvix code is pass transaction candidates a bunch of OS randomness at execution, which is just some number without security properties either express or implied. this is just to be convenient; it has about as many security implications as wall clock time (which i would like to pass in theory but probably can’t ever), i.e. none. the main reason this isn’t done now is because it’s actually difficult! it would be very easy to put in the code naively for single-node but would break the instant we attempt consensus and every node starts outputting different resources; it would have to be something like “deterministic prng based on last block hash” or something

shielded resources can happily do their own thing to be distinct, or so Xuyang tells me (and i believe him)

Yeah I agree, but if we look at it like that it applies to every name that comes from the shielded context (is a nullifier key really a key in the transparent context? what is a transparent secret key, anyway? how meaningful it is to have a secret key that you have revealed?).

In the end from the spec perspective we cannot do much more than to say what the field is there for. The nonce field is there to ensure uniqueness, it is stated in the spec afaik. The fact that the implementation doesn’t follow your definition of having negligible chance of repeating is, in my opinion, a flaw, and we need to make it very explicit what consequences it might inflict on the system in the docs, the same with every implementation choice

To summarise, I don’t think the problem, if there is a problem, is on the spec level, and therefore I don’t think that is where it should be fixed

1 Like

That being said, randomness does have not too bad uniqueness properties, and given that it only matters in the context of identical resources and that the resources are verified for the uniqueness (same nonce + same everything else → same commitment), I think we are fine. In the end, given that all other fields are the same, nonce has to be the one guaranteeing uniqueness, in both transparent and shielded cases, whatever way it is computed

1 Like