Try   HackMD

Validity Predicates when executed by Taiga will be run in a crafted runtime environment, which will be passed to the VP in the form of public and private inputs. This section outlines a preliminary design for the VP runtime environment.

In the current Taiga design, every partial transaction has exactly two input notes and two output notes. Data of these notes constitutes the primary bulk of the runtime environment. Since these values are all inputs to the cicuit, they must be encoded as an element of field

Fp (base field of Pallas curve, which is the Galois field
GF(0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001)
see here).

Public inputs

Standard Public Inputs

Name Description
spend_note_1_nullifier Spend Note #1 Nullifier
spend_note_2_nullifier Spend Note #2 Nullifier
output_note_1_commitment Output Note #1 Commitment (Hash)
output_note_2_commitment Output Note #2 Commitment (Hash)
owned_note_indicator Equals to one of the nullifiers or one of the commitments, points to the note owned by the currently executing VP (i.e., app_vk of the corresponding note refers to this VP). See this and this for details.

Generally, the note commitment is a point on a curve (see the spec), so it's a 2-element vector

(x,y). Here, the value of output_note_<#>_commitment is just the
x
component of that vector.

Note that owned_note_indicator only can point to one note, however, it is possible that there are more then one note in a ptx that have the current VP as their AppVP. In such case, the VP will be executed (proven) several times, once per every note that belongs to it. A future consideration: can this be optimized/improved?

Note Encryption Public Inputs

If the note owned by the VP is an output note, then we supply a verifiable encryption of this note as public inputs. TODO: do we supply the encryption key as a private input? If the owned note is an input note, these fields are unused but should still be supplied to the VP (with whatever values). TODO: when unused, these can probably be used as additional custom public inputs?

Name Description
own_output_note_app_vk Encryption of the VP verifying key
own_output_note_app_data_static Encryption of the app_data_static commitment?
own_output_note_app_data_dynamic Encryption of the app_data_dynamic commitment?
own_output_note_value Encryption of the note value field
own_output_note_rho Encryption of the note rho field
own_output_note_nk Encryption of the nullifier key commitment
own_output_note_psi Encryption of the note psi field
own_output_note_rcm Encryption of the note commitment randomness

Custom Public Inputs

We also allow VPs to have custom public inputs. Unlike the custom private inputs (see below), the number of custom public inputs is fixed at 10. This is done to ensure function privacy (so that different VPs can't be distinguished by the number of public inputs), but the concrete number can change in the future.

Name Description
public_input_
[1..n]
Public input number #X, from 1 to 10

Standard Private Inputs

Private inputs consist of four sets of note info. In the table below <type> is a stand-in for either spend or output; <#> is a stand-in for note id, either 1 or 2.

Name Description
<type>_note_<#>_app_data_static_commitment Hash (commitment) of app_data_static field
<type>_note_<#>_app_data_static_
[1..n]
Actual static app data. This is represented as
n
field elements, which are interpreted using the logic in the VP
<type>_note_<#>_app_vk Hash (commitment) of the VP verifying key, uniquely identifies the VP
<type>_note_<#>_app_data_dynamic_commitment Hash of app_data_dynamic field
<type>_note_<#>_app_data_dynamic_
[1..n]
Actual dynamic app data. This is represented as
n
field elements, which are interpreted using the logic in the VP
<type>_note_<#>_value Number representing the value of the note
<type>_note_<#>_nullifier_key A key used to derive the nullifier
<type>_note_<#>_rho
ρ
, the nullifier of the parent (ancestor) note, used as input to derive the nullifier of this note
<type>_note_<#>_psi
ψ
, the nullifier randomness. Used together with
ρ
in derivation of the nullifier
<type>_note_<#>_rcm Note commitment randomness, ensures that similar notes have different commitments
<type>_note_<#>_is_merkle_checked 1 if this is a real note, 0 if it's a dummy/ephemeral note

Also, for the output notes we have an additional private input output_note_<#>_nullifier; for input notes we have an additional private parameter input_note_<#>_commitment.

Optional Private Inputs

If the owned note in the partial transaction is an output note, then we supply the VP with a verifiable encryption of that output note. In order to be able to verify the encryption, the VP needs the receiver's public key and the sender's private key, which are used to ferive the note encryption key using DH key exchange. The receiver's public key should be stored in the note's dynamic data (TODO: does it always have to? are there any downsides to this?). The sender's private key (recommended to be an ephemeral key only used once, but that is up to sender) is supplied as a private input.

Name Description
own_output_note_encryption_sender_key Sender's key used for DH key derivation together with the receiver's public key

Custom Private Inputs

In the lifecycle of a partial transaction, in a typical interaction, the validity predicates are proved through the Taiga APIs exposed to the wallet. Typically, to construct and prove the ptx, the user would use their wallet application to interact with the Web3 application, which would then help the wallet to construct the ptx with all the right input and output notes.

Validity predicates may have additional custom private inputs, that are not in the list of standard inputs. These inputs can be anything that the developers decide them to be. It is the job of the Web3 application, which typically would be written by the same developers as the VP, to properly construct the partial transaction with the custom inputs.

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

The names of the custom inputs can be arbitrary but can't clash with the names of standard private and public inputs. Custom inputs still need to be in the form of field elements. If the data that the developers want to pass to VP is no initially in the form of field elements, it should be properly encoded and te VP should know how to decode it back.

TODO: Juvix should support encoding by default (see here)
TODO: Can we somehow meaningfully fool a VP by shadowing one of the standard variables with a custom input?