Commit graph

178 commits

Author SHA1 Message Date
Daniel Gulotta
b02d0ec462
allow downstream crates to instantiate *CircuitDataSerializer (#405) 2025-09-03 10:13:54 -07:00
Ahmad Afuni
1479400555
feat(backend): use custom gate for Schnorr signature verification (#397)
* schnorr signature prover optimization. TODO: implemented eval_unfiltered_circuit, serialize

* Use new gate(s) in MainPod circuit

* Formatting

* Clean-up

* Code review

* Code review

* Code review

* Formatting

* Remove unnecessary elements

---------

Co-authored-by: Linus Tang <linust@mit.edu>
2025-09-04 00:47:59 +10:00
ca97d9edc4
update docs with no-pod-id (#403)
* update docs with no-pod-id

* Update book/src/anchoredkeys.md

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

* Update book/src/custompred.md

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

* Update book/src/statements.md

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

* Update book/src/statements.md

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

---------

Co-authored-by: Ahmad Afuni <root@ahmadafuni.com>
2025-09-02 13:34:19 +02:00
511efa8d44
rename some old id to sts_hash (#402) 2025-08-28 10:48:43 +10:00
0e2f7b756e
No Pod IDs (#394)
- middleware:
  - Add `Statement::Intro`
  - Add `SignedBy` native predicate and operation.  The signature is auxiliary data to the operation
  - Rename `PodSigner` to `Signer` with a new API (just for signing `RawValue`)
  - Removed `NewEntry` operation.  Use `ContainsFromEntries` instead
  - Remove `KEY_SIGNER` and `KEY_TYPE` which are no longer used
  - Merge `RecursivePod` and `Pod` traits
  - Change the `Pod::deserialize_data` method to use `Self` instead of `Box<dyn Pod>` 
  - Extend `Pod` trait with these methods:
    - `is_main`: when the pod is Main, in a (recursive) verification its vk will be checked to exist in the vd_set but not if it's intro pod
    - `is_mock`: skip some verifications in the recursive mock MainPod verification
    - `verifier_data_hash`
    - `pod_id` renamed to `statements_hash`
  - AnchoredKeys are now a pair of dictionary root and key
  - Entry statements are now defined as Contains with literal arguments
    - Operations that take Entries now use Contains statements with literal arguments
- frontend:
  - Rename `SignedPod` to `SignedDict` (which now contains the dict, public key and signature, and can still `verify(self)`ed)
  - The `SignedDict` keeps the method `get_statement` for convenience but now it returns a `Contains` statement that proves the existence of the key in the dict
  - The `MainPodBuilder` automatically inserts a `Contains` statement when an operation is added that uses an entry as argument that was not yet "opened".
  - Removed the `literal` methods from the `MainPodBuilder` that were loading literals to anchored keys: that was no longer needed after we introduced literal arguments
- backend
  - Only verify inclusion of the verifying key into the vd_set if the pod is MainPod.  A pod is not MainPod if the first statement is Intro.
  - Reject intro pods that have non-intro statements
  - Empty pod now returns an intro statement
  - Don't insert a type statement automatically in MainPod and MockMainPod.  We get rid of the type entry.
  - Implement `SignedBy` operation, which uses the muxed table to store signature verifications
- Rename `PodId` to `statements_hash` or `sts_hash` for short.  Now this is only used as a hash of the statements for the circuits public inputs.
- Refactor normalization of `self` statements:
  - Before: replace values that contain `SELF` by the given pod_id
  - After: place the verifying key hash into the Intro predicates
2025-08-27 13:19:40 +02:00
Daniel Gulotta
122f9c3cac
pad_circuit: use config to determine zk and check for underflow (#395) 2025-08-25 08:12:04 -07:00
Daniel Gulotta
f76197c602
Fix handling of Lt, LtEq (#393)
Changed the middleware to only allow comparison of integers and to
use the implementation of Ord for i64.  This matches the backend
behavior.

Also fixed a separate bug where LtEqFromEntries was producing a
NotEquals statement.
2025-08-18 07:54:20 -07:00
Ahmad Afuni
1508dd6126
feat: add container update ops (#390)
* Add container update ops

* Update src/middleware/operation.rs

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

* Update src/backends/plonky2/mainpod/mod.rs

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

* Code review

---------

Co-authored-by: Eduard S. <eduardsanou@posteo.net>
2025-08-13 06:34:45 +10:00
656cae77e0
Add versioning features (#387)
- Add a function to calculate the hash of the `CommonCircuitData`.  The hash uniquely identify the `CommonCircuitData` used for a circuit/proof.  Serializing the struct is not enough because the polynomial identities of the custom gates are not serialized (only their parameters are); so I made a function to extract "fingerprints" of the custom gates by evaluating them over a predefined list of uniform values, and then doing a random linear combination over the results.
- Store the full verifier only circuit data of a proof in the MainPod so that we can verify pods from old circuits in new circuits and code
- Store the hash of the `CommonCircuitData` in the MainPod so that we can reject verifying old pods that use a different `CommonCircuitData` than the current one.  This has two goals
  - If the `CommonCircuitData` changes it's very likely that the verification will fail, but it will be hard to debug.  Doing this early check helps identify the origin of the verification failure as early as possible
  - There's a chance that the verification could succeed when the `CommonCircuitData` changes, and that could be dangerous because the verification will be doing different checks than the ones intended for the original proof, so we may be skipping some constraints that could lead to exploiting the system.  For this reason, whenever the common circuit data hash changes, all previous verifying keys should be discarded (that is, not included in the VDSet)
    - The fingerprint only has ~64 bits and the "random evaluation point" is fixed.  The assumption is that the pod developers are not malicious and are not changing the gates such that different gates give the same fingerprint.  With this assumption, I find it reasonable to assume that with high probability if a gate changes, its fingerprint changes as well.
- Add a github action that updates a wiki page with a table that contains: date, commit, params hash (with a link to the actual params), verifier data only circuit data hash and common circuit data hash.  This will make it easy to track when the common circuit data changes as well as track the verifier data corresponding to various versions (identified by commit)
  - The edited page is this one https://github.com/0xPARC/pod2/wiki/MainPod-circuit-info
  
Resolve https://github.com/0xPARC/pod2/issues/386

Summary of breaking changes:
- The `RecursivePod` trait has a new method `common_hash` that needs to return the result of `hash_common_data` on the `CommonCircuitData` that the circuit uses.
2025-08-08 09:33:44 -07:00
Ahmad Afuni
594c4d2e63
feat(backend): add updates and deletions to Merkle tree state transition proofs (#383)
* Add updates and deletions to Merkle tree state transition proofs

* Code review
2025-08-06 12:19:21 +10:00
bcaef6c47a
Add table multiplexer (and use it for container, custom pred & PublicKeyOf ops) (#376)
- Extend the `Flattenable` trait to include a `size` method that returns the number of `Target`s the type requires.  This is used in the table to figure out the max length of an array that must fit all entry types.
- Move the circuit methods to precalculate hash states and do hashes started from a precomputed state to a new module
- Introduce `MuxTableTarget` which allows easy multiplexing of tables where each sub-table may have entries of different lengths.  The table access is done via hashing + unhashing automatically (via use of a generator)
- Use the `MuxTableTarget` to access merkle tree claims and custom predicate verification, which where previously in different tables and accessed with independent random accesses each
- Move the public key derivation for the PublicKeyOf operation check to the same multiplexed table.  Now we can choose how many of those operations a circuit supports.

Resolve https://github.com/0xPARC/pod2/issues/357
Resolve https://github.com/0xPARC/pod2/issues/361
2025-08-05 19:09:41 -07:00
Daniel Gulotta
0305a4de19
add missing constructors to frontend::Operation (#379) 2025-08-04 14:42:13 -07:00
Daniel Gulotta
fe8c4eceb3
remove op! macro (#378) 2025-08-01 09:52:06 -07:00
Daniel Gulotta
7f120f026d
fix frontend::Operation::new_entry + doc improvements (#370) 2025-07-30 16:55:15 -07:00
4fa285d9fb
support longer arrays in vec_ref (#367)
Support arrays up to 256 elements (hardcoded maximum just to avoid abuse) by combining multiple random_accesses.
The index is now split into low and high parts. It's a bit more inconvenient than using a single Target but this allows avoiding bit decomposition.
2025-07-30 16:07:25 -07:00
Rob Knight
bde35369d3
Return an error instead of panicking when too many statements (#372)
* Return an error instead of panicking when too many statements

* Improve clarity of variable names and error message
2025-07-30 12:21:39 -07:00
Rob Knight
ae39ff307d
Remove unnecessary 'params' argument to MainPodBuilder::prove (#373) 2025-07-30 11:39:10 -07:00
Rob Knight
f10a5adb41
Check a single POD against a POD Request (#359) 2025-07-30 02:46:14 +01:00
Rob Knight
c7b39f21f0
Support SELF keyword in Podlang parser (#368)
* Support SELF keyword in Podlang parser

* Add pretty-printing for SELF
2025-07-29 17:35:48 -07:00
0606a4098b
fix: missing gate and generator for serialization (#369)
Add the missing gates and generator in the serializer that were added
with the PublicKeyOf operation.

Add a test for CircuitData serialization+deserialization to avoid these
kind of bugs in the future.
2025-07-29 16:45:51 -07:00
Rob Knight
59c6151dbc
Secret keys in Podlang (#365) 2025-07-29 15:50:10 -07:00
Daniel Gulotta
ce8cabc337
remove some unsafe code (#366)
This commit modifies the cache code to use Box::leak, eliminating the need for std::mem::transmute.
2025-07-29 13:23:08 -07:00
Rob Knight
d6c4d9e943
Try actions-rust-lang/setup-rust-toolchain for possibly faster test b… (#364)
* Try actions-rust-lang/setup-rust-toolchain for possibly faster test builds

* Use toolchain from toml file

* Use the same action for the build job
2025-07-29 10:21:13 -07:00
brian6l
5b04b2a360
New Native Operation PublicKeyOf (#355)
* wrote some initial code

* added way to input private key into circuit

* TypedValue::SecretKey hashed as 10 32-bit limbs

* Check PublicKeyOf in Frontend and Middleware

* Diff review

* PR review

* Finish utest

* Fix bounds check

* added giving secret key witness to circuit

* Test & doc improvements

* added private key comparison to circuit and added test cases

* cargo fmt

* Add frontend tests for PublicKeyOf

* Add public_key_of and hash_of to op! macro

* Add ownership check to ticket example

* Group order checking in tests

* More negative test cases at circuit level

* Cleanups after self review

* clippy fixes

* Fixes after merge.  Temporarily remove plonky2 commit hash

* Add a nullifier to the ticket test example

* Test PublicKeyOf with a real prover (not mock)

* plonky-u32 dependency

* feat: optimize operation checks

Skip the circuits that verify operation checks other than None, Copy or
NewEntry for the public statements.  This works because public
statements are created by copying private statements, so we never use
the other operation checks in those slots.

---------

Co-authored-by: Andrew Twyman <artwyman@gmail.com>
Co-authored-by: Eduard S. <eduardsanou@posteo.net>
2025-07-28 15:53:01 -07:00
Rob Knight
9f8335756c
Add Podlang pretty-printing (#353)
* Add Podlang pretty-printing

* Review feedback changes

* Formatting

* Use Display impl for printing StatementTmplArg
2025-07-25 08:43:43 -07:00
8429cd224d
Feat/disk cache (#354)
- Bump rust version to `nightly-2025-07-02` because some of the nightly features we were using have been stabilized.
- Introduce feature `disk_cache` which enables caching to disk.  Each time an artifact is retrieved from the cache it will be read and deserialized.  On a cache miss the artifact will be created, serialized and stored to disk.
- Introduce feature `mem_cache` which enables caching to memory.  All cached artifacts are kept in memory after they are created.  The mem cache implementation avoids cloning of artifacts by extending their lifetime to `'static`.  This is `unsafe` code, but I argue that this usage is safe.
- Add a `build.rs`
  - When the feature `disk_cache` is enabled, the `build.rs` will inject env variables to the process with the git commit information, which is used to index the cached artifacts
- Replace all previous cached artifacts from `LazyStatic` methods that call the cache API
- Derive `Serialize, Deserialize` for all `*Target` types so that they can be serialized for caching to disk
- Add finer level of caching: now we cache the `CircuitData` and `VerifierData` independently.  The reason for this is that `CircuitData` is a very big artifact which is not needed for verification.  So by only accessing `VerifierData` in verification we don't pay a big overhead for reading from disk and deserializing
- Add missing artifacts to the cache: like the `CircuitData` for the `MainPod` indexed by `Params`
- Add helper types to serialize and deserialize `CircuitData`, `CommonData` and `VerifierData` with the set of gates and generators used in the recursive MainPod circuit
- Tweak the ids of our custom gates so that they remain unique when their generic parameters change
- Bugfix: several tests were using the standard `vd_set` but were using MainPod circuits with non-default parameters.  This was working before because there was a bug: the MainPod circuit was reporting that the used verifier data was the standard one instead of picking the one corresponding to it's own Params.

Summary of breaking changes:
- One and only one of the features `mem_cache` or `disk_cache` need to be enabled.  By default it's `mem_cache`
  - To enable the `disk_cache` you need to disable the default features like this: `--no-default-features --features=backend_plonky2,zk,disk_cache`
- Removed `DEFAULT_PARAMS`, instead use `Params::default()`
- Removed `STANDARD_REC_MAIN_POD_CIRCUIT_DATA`, instead use `cache_get_standard_rec_main_pod_common_circuit_data`
- The library is now using `nightly-2025-07-02`.  Some rust language features are unstable in previous versions.
2025-07-24 12:15:31 +02:00
arnaucube
745d654048
MerkleTree insertion proofs (#344)
* implement merkletree insert & insert-proof-verification

* add merkletree circuit to verify insertion proof

wip

* fix merkletree's GraphViz generation for cases with empty siblings

* implement tree insert-verif circuit siblings checks

Note: I've implemented also an alternative version which instead of
inputting a witness value 'divergence_level' it inputs a bitmask. Both
approaches (divergence_level and divergence_bitmask) take the same
amount of constraints (336 constraints for a tree of 32 levels, and for
an hybrid approach it takes 331 constraints but the code gets a bit less
readable). So I've kept with the current implementation (using
divergence_level) which is more easy to follow.

* [tree] modify the strategy for the insert-proof (out-circuit)

* re-implement insert-proof verification circuit

* add pending checks and polish

* add tests for disabled(&enabled) cases that should fail

* update typos.toml config

* Add test with tampering

* add check 5.3, to prevent tampering (at insertion proof circuit)

* move old_leaf_hash computation outside the loop, simplify check 5.3 booleans

* apply @ed255 review suggestions

---------

Co-authored-by: Ahmad <root@ahmadafuni.com>
2025-07-24 12:02:44 +02:00
Daniel Gulotta
89dfc4e214
always replace SELF when copying statements (#345) 2025-07-22 14:56:37 -07:00
Rob Knight
5cdf53576b
Make serialized POD ids available (#350) 2025-07-22 14:43:37 -07:00
Ahmad Afuni
757f8c0734
Add hash_of to op macro (#348) 2025-07-22 16:10:49 +10:00
Ahmad Afuni
1c9b735da6
chore(middleware): add container op checks and tests (#347)
* Add container op checks

* Formatting & comments

* Formatting
2025-07-19 10:25:42 +10:00
Daniel Gulotta
673a461246
clippy check for tests (#346) 2025-07-17 19:30:14 -07:00
143a8c9d4e
First iteration of circuits naming convention
In this commit I remove all `*Gadget` types and instead implement the naming convention defined here https://github.com/0xPARC/pod2/issues/181#issuecomment-3051954321

The biggest changes can be summarized by:
- a) Removal of `*Gadget` types and their `eval_*` methods in favour of `verb_object_circuit` functions.
- b) The above functions don't create targets that need to be witness-assigned later.  Instead they receive those as arguments.  This clearly shows what's the circuit input and output.

I'm specially happy about the changes from b), I think they make the flow of data in the circuit more clear.

Missing things that I did not address in this PR
- The RecursiveCircuit still uses some old naming conventions like `build`.
- We have some `*Target` types that have methods that define constraints.  I think we can keep those as they are convenient and I don't see them as strongly breaking the new convention: I see them as the object-oriented way to apply the convention.  In those cases the `object` can be omitted from the method when it's implied by the type name, and the `_circuit` suffix doesn't appear because it's implied by the fact that the type is a `*Target`.  Examples are: `SignatureTarget::verify -> BoolTarget`, `StatementTarget::has_native_type -> BoolTarget` or `OperationTypeTarget::as_custom -> (BoolTarget, HashOutTarget, Target)`.
2025-07-15 17:49:29 +02:00
63a716ebd7
Remove unnecessary mut in PodSigner trait (#340)
The PodSigner trait was taking `&mut self` in the `sign` method, but the
signer doesn't need mutation in the Shcnorr implementation.  Remove the
`mut`.

Previously the PodProver trait was also taking `&mut self` in the
`prove` method, and we had many tests creating a `mut Prover/mut
MockProver`.  Remove all those `mut`.

Breaking change: `PodSigner` trait method `sign` replaces `&mut self` by
`&self`
2025-07-15 17:37:26 +02:00
b5e0d97cb6
remove MockSignedPod (#339)
- breaking change: Removal of MockSignedPod.  Use SignedPod instead.
- breaking change: Redefinition of numerical id for values of PodType.
2025-07-15 11:19:19 +02:00
arnaucube
06b84e8dca
change Hash (and RawValue) hex-string representation to show the least-significant field element as big-endian hex string (#338)
* change Hash (and RawValue) hex-string representation to show the least-significant field element as big-endian hex string

The motivation is that since some commits ago, the hex representation
was changed from little-endian to big-endian, and when cropping the long
strings of hex (hex representation of byte-arrays), the small values
(224 bits or less) were being represented by `0x00000000...`, which is
indistinguishable from the `0` value.
This commit updates this cropped representation to print the last
characters of the string (the less signifcant bytes of the big-endian
representation), so that for example for the integer `5` the
representation would be `0x...00000005`.
2025-07-14 15:27:58 +02:00
Ahmad Afuni
e8468d7fa8
chore(middleware): additional error reporting for custom predicates (#330)
* Additional error reporting for custom predicates

* Code review

* Typo
2025-07-14 23:27:33 +10:00
aeedf55bad
fix: consistently serialize signer (#334)
- serialize the signer in base58 both as Value and as the signer embedded
in the SignedPod json data field.
- Implement serialization/deserialization for Signature
2025-07-10 11:48:47 +02:00
Rob Knight
0750dbeaff
Detect invalid wildcards in the language processor (#321) 2025-07-08 15:31:15 -07:00
Ahmad Afuni
2c41a6c554
chore: minor error handling improvements (#325)
* Minor error handling improvements

* Fix error
2025-07-05 20:06:44 +10:00
Daniel Gulotta
901ba6442c
clone SecretKey, remove Infallible error type, set_contains arity (#329) 2025-07-02 17:55:02 -07:00
Rob Knight
24cafde231
Assorted tweaks to support external playground crate (#322)
* Assorted tweaks to support external playground crate

* Fix schemas

* Fixed schema again

* Add ToHex for RawValue

* Add FromHex to RawValue
2025-07-02 09:27:54 -07:00
Daniel Gulotta
335100d1d7
add auto implementation of Pod::equals (#327) 2025-07-01 11:09:35 -07:00
arnaucube
e0d2fce060
fix #315, and add cargo check in GitHub CI with zk feature disabled (#316) 2025-07-01 12:02:12 +02:00
Rob Knight
b123185ee9
Support public key literals and tidy up handling of Raw vs PodId (#319)
* Support public key literals and tidy up handling of Raw vs PodId
2025-07-01 01:34:35 -07:00
Rob Knight
6aa4acac4a
Restore typed data to serialized PODs (#318) 2025-06-27 22:53:31 -07:00
3306f360f7
make Pod trait thread-safe (#317) 2025-06-27 15:48:52 +01:00
arnaucube
b6041508e5
resolve #273: remove global constant MAX_DEPTH, instead use the respective value from Params (#314)
* resolve #273: remove global constant MAX_DEPTH, instead use the respective value from Params

* simplify partialeq at mockmainpod
2025-06-26 13:54:28 +02:00
Ahmad Afuni
115c3c1152
fix: use raw values for container keys and values (#312)
* Get rid of additional key/value hashing in container types

* Add test
2025-06-25 22:41:52 +10:00
arnaucube
e1775d8578
add eq & partial_eq for RecursivePod, Pod traits and VDSet struct (for usage from introduction-pods) (#309)
* add eq & partial_eq for VDSet (for usage from introduction-pods)

* add eq & partial_eq impls for Pod & RecursivePod traits
2025-06-24 17:41:46 +02:00