This is a README for a code artifact that accompanies the research paper: NOPE: Strengthening domain authentication with succinct proofs. Along those lines, please note the following Warning.
Warning! NOPE is a research project. This code has not been audited and the zero-knowledge proof system uses a dummy trusted setup. Do not use NOPE in production environments or anywhere else that security is necessary.
See the bottom of this README for licensing details.
There are three core pieces of NOPE, each of which is in a separate directory:
circuits/: circom code for generating proofs of domain ownership, tests, and circuit specific benchmarksserver/: server-side automation for generating proofs and certificates for a given domain, serving them locally, and benchmarking system performanceextension/: a browser extension for NOPE certificate validation and scripts for client benchmarking
The NOPE artifact is these three items, together with a Dockerfile, for portability.
To connect these items to the proof system in NOPE: specifically,
circuits/ contains the underlying proof system specifications, the
prover is server/, the verifier is extension/.
This repository includes instructions for reproducing the results in the paper, figure by figure, and then more general instructions for using each of the components.
The easiest ways to interact with the artifact are to use one of two platforms: (1) a running, NOPE-aware DNS server and (2) a Docker container, for portability. The running DNS server is preferred for artifact evaluation because some of the benchmarks require the ability to update DNS records.
The reviewer account for the DNS server for nope-tools.org
is accessible via ssh at reviewer@34.30.228.2
via the password supplied in the hotcrp artifact submission.
The Docker container is specified in Dockerfile. The following scripts
are relevant:
./build-docker.sh: this builds the docker image./run-docker.sh: this runs the docker image, mounts the current directory, and opens an interactive shell inside the container
These are provided to make deploying NOPE on your own DNS server easier.
The following instructions will reproduce the results in the paper, figure by figure, on either the DNS server or the Docker container.
Note that the description for reproducing each figure is self-contained, and thus the figures can be reproduced in any order.
To reproduce Figure 3, navigate to the extension/bench/ directory and run the following commands:
npm install
taskset -c 1 ./run.sh
python3 tochart.py
Note that this does not reproduce the final "time (native)" column in Figure 3. That column is estimated, and we will explain the estimation process in the next version of the paper.
Additionally, to interpret these results relative to our initial submission, please note the following.
- size (in the artifact) and Bandwidth (in the submission) are the same thing.
- Time and Variance (in the artifact) are the same thing as the submission's "time (JS)" column (the submission reports in the format "time (+/- variance) ms").
- Also, DV (in the artifact) refers to Legacy (in the submission), and NOPE (in the artifact) refers to DOVE (in the submission).
Reproducing Figure 4 is a several step process. Please note that, unlike with the other figures, reproducing some of this one requires access, at one point, to the running DNS server (that is, it cannot be completed solely on Docker). We indicate where below.
We indicate which steps apply to which bars in the figure inline.
First, navigate to the server/ directory and run the following two commands to build the circuits and export (insecure) proving keys.
./build.sh
./export.sh
These commands take several hours to run to completion; however, in the running DNS server, we have pre-executed them to save time in evaluation, so it is safe to skip them if desired (if you are using the Docker container, they will need to be executed). They correspond to a one-time cost for a server owner.
Second, navigate to the server/bench/ directory and run the following two commands.
taskset -c 1 ./bench.sh
python3 parse.py
In the figure, this corresponds to "proof generation" and handles the generation of Certificate Signing Request with NOPE proof embedded.
These commands take 40-50 minutes to run to completion.
Third, navigate to the server/src/ directory and run the following command to begin the ACME protocol with Let's Encrypt.
python3 app.py --time_it -e admin@nope-tools.org -d nope-tools.org
Note that this part involves updating DNS records and is subject to ACME rate limiting, so, for the sake of benchmarking, we require manual input. That is, the script will pause halfway and prompt a manual DNS zone file update, for example:
Please create a DNS TXT record in your zone:
_acme-challenge.nope-tools.org. IN TXT "-3MFg8LCoTFR-gVQuJaUGsLy8agudB7UcL9I6lGcrM8"
The time from ACME start to this prompt is "ACME Initiation" in the figure.
The next piece must happen on the running DNS server, because it
involves updating the DNS configuration of the nope-tools.org domain.
So, if running on Docker, you now need to log in to the provided nope-tools.org DNS
server to modify the zone file.
If you are already on the DNS server, just follow the instructions below.
Run sudo vim /var/cache/bind/nope-tools.org to open the zone file and make the following two edits.
- Increment the serial number.
- Replace the line prefixed by
_acme-challenge.nope-tools.org.with the prompt above, from theapp.pyscript.
After saving the new zone file,
run sudo systemctl reload bind9 on the DNS server
to publish the new records.
Now, if you are running on Docker, you can exit the DNS server and return to the script. If you are on the DNS server, you can just return to the script.
After waiting 10-30 seconds, press Enter on the prompt to continue with the ACME process.
The time from pressing Enter to the end of the script is "ACME Verification" in the figure.
This portion of the benchmark takes 1-2 minutes to run to completion.
The results of this benchmark are stored in the server/src/dat/ directory with files having a .dat suffix.
To summarize the results, run
python3 ../scripts/summarize.py dat
To reproduce the results in Figure 5, navigate to the circuits/bench/ directory and run the following two commands:
./count.sh | tee tmp.log
python3 tochart.py
The tochart.py script uses these results to estimate the effect of NOPE's optimizations on constraint count, prover time, and memory usage (consistent with macrobenchmarks).
These commands take 40-50 minutes to run to completion, with count.sh taking the bulk of the time.
We have also included a ./run.sh script which compiles and runs the full pipeline for the most expensive circuit to demonstrate the full process with dummy data.
Note that the run.sh script requires npm install to be run in the circuits/ directory first.
To replicate the results in Figure 6, navigate to the extension/bench/decomp/ directory and run the following command.
python3 cert.py ../cert/nope.pem ../cert/dv.pem ../cert/r11.pem ../dnssec-chain/data
This Python script handles the slicing and dicing of the raw certificate data and DNSSEC chain data to produce the results in Figure 6.
The arguments above are static paths to test certificates and DNSSEC chain data, but it is easy to replace them with other data if desired.
Exact byte counts will vary slightly from the paper due to inherent variability in certificate issuance and DNSSEC record lengths.
The circuits are a collection of circom files specifying constraints and witness generation code for DNSSEC verification.
To build all circuits, navigate to the circuits/ directory and run make.
All of our circuits are equipped with tests of completeness on sample data.
To the run the tests, first run npm install.
Then run npm test to run all tests or mocha [testname] in the circuits/test/ directory to run a specific test (add option --max-old-space-size=4000 if you see Out Of Memory).
We have provided sample test data from nope-tools.com and nope-tools.me in the circuits/test/sdata/ directory and the tests are configured to use this data by default.
To use custom test data, run python3 fetchmin.py [your url] which fetches sample DNS data for tests from the specified URL and places it in the circuits/test/data/ directory.
Then modify the appropriate test to use the new data.
server.sh is a complete tool for generating a NOPE proof and obtaining a NOPE cert.
Note that this script assumes all the data and binary files are prepared as follows.
- The domain's DNSSEC data must be fetched using sscripts/fetchmin.py (this goes to a data folder by default).
- The corresponding bind Key Signing Key (KSK) should be parsed as follows (based on key type).
- If the KSK is an ECDSA key then
scripts/eccextract.pyshould be run and the output renamed to[domain].-DNSKEY-KSK-dlog.dat - If the KSK is an RSA key then
extract.pyshould be run and the output renamed to[domain].-DNSKEY-KSK-factors.dat
- If the KSK is an ECDSA key then
- The corresponding circuits and keys also need to be compiled and exported. (To make sure of this, run
./build.shthen./export.sh) - For NOPE-managed, run
analyze.pyto get the amount of padding required for the current TXT recordset configuration.
The arguments and one example usage of server.sh are as follows:
./server.sh <domain> <TLD algorithm = 8/13> <SLD algorithm = 8/13> <managed=0/1> <data path> <email>
./server.sh nope-tools.org 8 13 0 data nope-admin@nope-tools.org
./server.sh generates a NOPE proof, encodes it into a Certificate Signing Request, and initiates the ACME protocol with Let's Encrypt using the Request.
server/scripts includes additional helper scripts for server.sh
compress.pycompresses a NOPE proof to a SANhash_pub.pyhashes a TLS public key and encodes it with base64make_input.jscreates prover input for the witness generator
These are used internally by server.sh, but they can be used independently for debugging and testing.
NOTE: Due to browser security policies, this extension only works in Firefox.
To build the extension, navigate to the extension directory and run the following commands:
npm installnpm run build
To load the extension into Firefox, do the following:
- Navigate to
about:debugging#/runtime/this-firefox - Click
Load Temporary Add-on...and select/addon/manifest.json
When visiting a website, for example nope-tools.org, the extension will check if the server is using a NOPE certificate and try extract and verify the proof if found.
If no proof is detected, the NOPE icon will be unchanged. If a NOPE proof is detected and verifies, a green checkmark will appear. However, if a NOPE proof is detected and verification fails, then a red X will appear indicating that the proof is invalid.
This project contains modified code from the following sources with the following licenses
- snarkjs which is licensed under GPL-3.0,
- Bluecrypt ASN.1 Parser which is licensed under MPL-2.0, and
- ffjavascript which is licensed under GPL-3.0
As a result, this project is licensed under a dual-license scheme:
- The Unlicense (see UNLICENSE)
- The GNU General Public License (GPL)
You are free to choose either license when using this code; however, if you wish to use this code under the Unlicense you must do so without the snarkjs, ffjavascript, and ASN.1 parser noted above (otherwise the GPL and/or MPL applies). Informally this means that all circom code is under the Unlicense (and can be freely used) but the NOPE server and client programs are under GPL and/or MPL.
For the unlicense terms (see UNLICENSE).