pod2/book/src/simpleexample.md
tideofwords d3bc892906
Aard custom (#49)
* Merge changes to docs

* Fix typo

* Correct SUMMARY so it compiles; update .gitignore

* Clean up statements.md

Make syntax and notation consistent with Rust source code.

* Fix statements for Merkle trees and compound types

* First draft of custom statements and small updates to signedpod.md

* Update book/src/merkletree.md

Co-authored-by: Ahmad Afuni <root@ahmadafuni.com>

* merklestatements correct typo

Co-authored-by: Ahmad Afuni <root@ahmadafuni.com>

* add todo for gadget ids

Co-authored-by: Ahmad Afuni <root@ahmadafuni.com>

* Separate out custom statements version 1

* More details on custom statements version 1

* new file custom2

* Partial draft of version 2

* First draft of version 2 spec, it's kind of a mess

* Another version of the custom predicates spec

* Update book/src/custom2.md

Co-authored-by: Eduard S. <eduardsanou@posteo.net>

* Simple example of deduction rule applied in circuit

* Implement Edu's comments on custom predicates

* Backend predicates must be defined in groups

* Add more examples

* Two diff statements using same constant

* Remove deprecated example

---------

Co-authored-by: Ahmad Afuni <root@ahmadafuni.com>
Co-authored-by: Eduard S. <eduardsanou@posteo.net>
2025-02-24 09:05:30 -08:00

3.6 KiB

Simple example

Circuit structure, two-column proof

A "proof" is a table that looks like

STATEMENT REASON
STATEMENT1 REASON1
STATEMENT2 REASON2
...

In other words:

A "proof" is an ordered list of 100 proof-rows.

Each "row" is a pair (statement, reason).

The statement is the statement.

The reason is everything the circuit needs to verify that the statement is true.

Example:

STATEMENT1 = Equals(oldpod, "name", otherpod, "field")

STATEMENT2 = Equals(otherpod, "field", newpod, "result")

STATEMENT3 = Equals(oldpod, "name", newpod, "result")

The reasons in human-readable simplified format:

REASON1 -- "came from previous pod"

REASON2 -- "came from previous pod"

REASON3 -- "use transitive property on STATEMENT1 and STATEMENT2"

What does the reason look like in circuit?

It won't be so simple. I'll just explain what REASON3 has to look like.

First, the operation (deduction rule).

A simple example of a deduction rule

Here is the transitive property of equality, in human-readable form.

if
Equals(a, b) and Equals(b, c)
then
Equals(a, c)

First, we need to decompose all the anchored keys as (key, origin) pairs. This is the frontend description of the deduction rule.

IF
Equals(a_or, a_key, b_or, b_key)
AND
Equals(b_or, b_key, c_or, c_key)
THEN
Equals(a_or, a_key, c_or, c_key)

In-circuit, all these identifiers are replaced with wildcards, which come in numerical order (because they will be used as array indices). So the backend representation is:

IF
Equals( *1, *2, *3, *4 ) and Equals ( *3, *4, *5, *6 )
THEN
Equals( *1, *2, *5, *6 )

What does REASON3 need to look like in-circuit?

  • Repeat deduction rule
IF
Equals( *1, *2, *3, *4 ) and Equals ( *3, *4, *5, *6 )
THEN
Equals( *1, *2, *5, *6 )
  • Say what the wildcards are
*1 -- oldpod
*2 -- "name"
*3 -- otherpod
...
  • Substitute the wildcards into the deduction rule
IF
Equals( oldpod, "name", ... ) ...
Equals( otherpod, "value")
THEN
Equals( oldpod, "name", newpod, ... )
...
  • Say where to find the previous statements (indices in the list), and check that they are above this one.
Statement1
Statement2
  • Check that the input statements match. Check that the output statement matches.

Decomposing anchored keys

Sometimes a deduction rule requires different anchored keys to come from the same POD. Here's an example from Ethdos.

The wildcard system handles this very naturally, since origin ID and key are two separate wildcards.

eth_friend(src_or, src_key, dst_or, dst_key) = and<
    // there is an attestation pod that's a SIGNATURE POD
    ValueOf(attestation_pod, "type", SIGNATURE)     
    
    // the attestation pod is signed by (src_or, src_key)
    Equal((attestation_pod, "signer"), (src_or, src_key))  

    // that same attestation pod has an "attestation"
    Equal((attestation_pod, "attestation"), (dst_or, dst_key))
>

In terms of anchored keys, it would be a little more complicated. five anchored keys show up in this deduction rule:

AK1 = src
AK2 = dst
AK3 = (attestation_pod, "type")
AK4 = (attestation_pod, "signer")
AK5 = (attestation_pod, "attestation")

and we need to force AK3, AK4, AK5 to come from the same origin.

WILDCARD matching takes care of it.

eth_friend(*1, *2, *3, *4) = and<
    // there is an attestation pod that's a SIGNATURE POD
    ValueOf(*5, "type", SIGNATURE)     
    
    // the attestation pod is signed by (src_or, src_key)
    Equal((*5, "signer"), (*1, *2))  

    // that same attestation pod has an "attestation"
    Equal((*5, "attestation"), (*3, *4))
>