:warning: Work in progress :warning:
## WNFS Name Accumulators
This library implements the cryptographic primitives necessary for WNFS to prove that its writes were valid in a way that's verifyable by third parties without read access.
Specifically, it implements 2048-bit RSA accumulators and the PoKE* and PoKCR algorithms from the paper ["Batching Techniques for Accumulators with Applications to IOPs and Stateless Blockchains"](https://eprint.iacr.org/2018/1188.pdf), as well as some WNFS-specific interfaces and serialized representations for them.
## Usage
RSA accumulators require a trusted setup. Whoever has access to the trusted setup can create arbitrary valid proofs, which would in practice let malicious actors who've only been given partial access to a WNFS access to the rest of the file system.
For this reason the trusted setup is run once upon creation of a new WNFS by the root author. The root author is naturally incentivized to throw away the toxic waste from the trusted setup.
```rust
use wnfs_nameaccumulator::{AccumulatorSetup, BatchedProofPart, BatchedProofVerification, Name, NameSegment};
use rand::thread_rng;
// Run the trutsed setup.
let rng = &mut thread_rng();
let setup = &AccumulatorSetup::trusted(rng);
// We want to prove the names for two files at
// /Docs/Note and /Pics/Image respectively
let mut name_note = Name::empty(setup);
let mut name_image = Name::empty(setup);
// Each segment is represented by a random 256-bit prime number
let root_dir_segment = NameSegment::new(rng);
let docs_dir_segment = NameSegment::new(rng);
let pics_dir_segment = NameSegment::new(rng);
let note_file_segment = NameSegment::new(rng);
let image_file_segment = NameSegment::new(rng);
name_note.add_segments([root_dir_segment.clone(), docs_dir_segment, note_file_segment]);
name_image.add_segments([root_dir_segment, pics_dir_segment, image_file_segment]);
// We can collapse these arrays of primes that represent paths into 2048-bit RSA accumulators
// with a proof that they were derived from the same "base" name, in this case the `Name::empty` above.
let (accum_note, proof_note) = name_note.as_proven_accumulator(setup);
let (accum_image, proof_image) = name_image.as_proven_accumulator(setup);
// Knowing the proofs, we can batch at least parts of the proofs together.
// This results in a single 2048-bit batched proof part and ~17-20 bytes of unbatched proof per element.
let mut batched_proof = BatchedProofPart::new();
batched_proof.add(&proof_note);
batched_proof.add(&proof_image);
// Without read access, but given the accumulated base name and the proofs,
// we can verify that the accumulated names are related to the same base name.
let name_base = Name::empty(setup).as_accumulator(setup).clone();
let mut verification = BatchedProofVerification::new(setup);
verification.add(&name_base, &accum_note, &proof_note.part)?;
verification.add(&name_base, &accum_image, &proof_image.part)?;
verification.verify(&batched_proof)?;
```
## The `rug` feature
This enables a different backend for big unsigned integer arithmetic, based on the [rug crate] (which is based on the [GNU multiprecision library], also abbreviated GMP).
It is roughly 2x faster than the `num-bigint-dig` implementation when building for release, but as a bonus is also fast in debug builds (e.g. during tests) due to rug containing a statically linked release build of GMP.
However, it doesn't work in Wasm and it should be noted that GMP is licensed as [LGPLv3].
If you depend on the `wnfs` crate, but want to use the `rug` backend for your application, then simply add a `wnfs-nameaccumulator` as a dependency and enable its `rug` feature. This will make `wnfs` use a version of `wnfs-nameaccumulator` with `rug` enabled:
```toml
wnfs-nameaccumulator = { version = "*", default-features = false, features = ["rug"] }
```
[rug crate]: https://crates.io/crates/rug
[GNU multiprecision library]: https://gmplib.org/
[LGPLv3]: https://www.gnu.org/licenses/lgpl-3.0.en.html