Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Introduce a proof-of-concept field Writer for writing to "native field" as well as "foreign field" transcripts #340

Closed
wants to merge 4 commits into from

Conversation

huitseeker
Copy link
Member

@huitseeker huitseeker commented Feb 22, 2024

The problem

We wanted a proof-of-concept of a set of traits that allow, for each concrete type:

  • modelizing how to absorb it to a transcript able to ingest field elements of the native field,
  • also modelizing how to absorb it to a transcript able to ingest field elements not in the native field, through a limbing conversion,
  • not having to re-explain the conversion between sorts of field elements for every struct: we ideally want to explain field ingestion once and be done with it.

We're working with the following restrictions:

  • the Rust type system does not allow trait specialization, or any form of ambiguous trait dispatch.

What's in this PR?

A PoC suite of traits explaining how structs can have a "serialization" to their "native" notion of field element, the transcripts can have a "native" notion of field element they accept, and how we can have a generic struct apply a systematic conversion between those two notions in order to define a general way to absorb the structs into the transcripts.

When the "native" fields on each end (struct and transcript) match, the conversion resolves to something trivial. That conversion is then made accessible to any struct that has defined its "native serialization" by way of an extension trait.

In Detail

  • Created src/transcript.rs with concepts and traits for field operations.
  • Defined a new Limbable trait for encoding translation between fields.
  • Implemented FieldWriter and FieldWritable traits for respectively writing and producing field elements.
  • Presented FieldWritableExt extension trait to accommodate different target field types.
  • Added FieldEncodingWriter structure, a translating field writer.
  • Integrated smallvec library with const_generics feature to implement it efficiently.
  • Added tests for the src/transcript.rs module and its functionalities.

@huitseeker huitseeker force-pushed the field_writer branch 4 times, most recently from 0e57337 to 38d39de Compare February 22, 2024 04:10
@adr1anh
Copy link
Contributor

adr1anh commented Feb 23, 2024

Amazing work! Can't wait to use this throughout.

How easily can we adapt this to write to a u8 buffer, so that we could use the same API for the pp-SNARK's keccack transcript?

@huitseeker
Copy link
Member Author

huitseeker commented Feb 23, 2024

@adr1anh does the last commit de9f873 answer your question precisely?

@adr1anh
Copy link
Contributor

adr1anh commented Feb 25, 2024

Thanks @huitseeker ! It's nice how easy you made it to serialize to a bytes buffer by reusing the io::write trait.

I’m realizing though that this may lead to a slightly less optimal verifier, if the latter is not restricted to only field elements (e.g. in Solidity).

With our current stack, the Solidity verifier has to run two interactive protocols to verify an NIVC proof.

  • The folding verifier which uses the field-only Poseidon transcript, to correspond with the implementation in the circuit.
  • The CompressedSNARK, where we would want to either create a proof using Poseidon to facilitate verification inside a circuit, or a proof using Keccack (or another pre-compile enabled hash function).

For the latter, we'll want to modify the "serialization" strategy to match the verification environment.

  • Both Scalar and Base fields are "equivalent" in the sense that there is no difference in computation we perform on them. Both should be serialized using as_repr instead of limbing
  • Commitments on the primary curve will not be pre-hashed and can be absorbed as-is. Moreover, we might want to write the "compressed" version instead.

What I was thinking originally is that we could get away with having a different implementation of write depending on whether the Writer writes Field or u8 elements.

I hope this extra context helps, but I’m also fine with focusing on the Poseidon use-case for now if this is becoming too complex!

- Created `src/transcript.rs` with concepts and traits for field operations.
- Defined a new `Limbable` trait for encoding translation between fields.
- Implemented `FieldWriter` and `FieldWritable` traits for respectively writing and producing field elements.
- Presented `FieldWritableExt` extension trait to accommodate different target field types.
- Added `FieldEncodingWriter` structure, a translating field writer.
- Integrated `smallvec` library with `const_generics` feature to implement it efficiently.
- Added tests for the `src/transcript.rs` module and its functionalities.
- Introduced a new `FieldEquippedWriter` struct in `transcript.rs` for efficient handling of "native" fields for digests.
- Implemented the ability to perform conversions from a writer, write field elements, and flush the writer using the new `FieldEquippedWriter` struct.
- Renamed the function `it_works` with `test_limbing_works` to improve test naming conventions.
- Implemented a new test, `test_keccak_works`, that verifies the Keccak256 hash of field elements implementation via `FieldEquippedWriter`.
@adr1anh adr1anh mentioned this pull request Feb 26, 2024
@huitseeker
Copy link
Member Author

@adr1anh is 3f516aa working for you?

@huitseeker
Copy link
Member Author

This seems less useful to @adr1anh this days. Closing for clarity, @adr1anh feel free to re-open.

@huitseeker huitseeker closed this Mar 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants