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

CHIA-193: Rust bindings to chiapos #439

Merged
merged 25 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 66 additions & 7 deletions rust-bindings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,33 +34,92 @@ pub fn validate_proof(

#[cfg(test)]
mod tests {
use std::{fs, path::PathBuf};

use super::*;

#[test]
fn test_proofs() {
/*
* Generated by printing the inputs to validate_proof in tests/test_python_bindings.py
* Specifically, the test_k_21 function was adapted to append 100 lines to the file.
* Generated by tools/generate_rust_proof_test.py
*/
let proofs = include_str!("../test_proofs.txt");
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("test_proofs.txt");
let proofs = fs::read_to_string(path).unwrap();

for line in proofs.lines() {
let mut parts = line.split(", ");
let seed = hex::decode(parts.next().unwrap()).unwrap();
let seed = hex::decode(parts.next().unwrap())
.unwrap()
.try_into()
.unwrap();
let k = parts.next().unwrap().parse().unwrap();
let challenge = hex::decode(parts.next().unwrap()).unwrap();
let challenge = hex::decode(parts.next().unwrap())
.unwrap()
.try_into()
.unwrap();
let proof = hex::decode(parts.next().unwrap()).unwrap();
let quality = hex::decode(parts.next().unwrap()).unwrap();

// The test should pass with the initial data.
let mut actual_quality = [0; 32];
assert!(validate_proof(
&seed.try_into().unwrap(),
&seed,
k,
&challenge.try_into().unwrap(),
&challenge,
&proof,
&mut actual_quality
));
assert_eq!(actual_quality.as_slice(), quality);
arvidn marked this conversation as resolved.
Show resolved Hide resolved

// If you change the seed, the test should fail.
let mut actual_quality = [0; 32];
let mut new_seed = seed;
new_seed[0] = new_seed[0].wrapping_add(1);
assert!(!validate_proof(
&new_seed,
k,
&challenge,
&proof,
&mut actual_quality
));
assert_eq!(actual_quality, [0; 32]);

// If you change the K size, the test should fail.
let mut actual_quality = [0; 32];
let new_k = k.wrapping_add(1);
assert!(!validate_proof(
&seed,
new_k,
&challenge,
&proof,
&mut actual_quality
));

// If you change the challenge, the test should fail.
let mut actual_quality = [0; 32];
let mut new_challenge = challenge;
new_challenge[0] = new_challenge[0].wrapping_add(1);
assert!(!validate_proof(
&seed,
k,
&new_challenge,
&proof,
&mut actual_quality
));
assert_eq!(actual_quality, [0; 32]);

// If you change the proof, the test should fail.
let mut actual_quality = [0; 32];
let mut new_proof = proof;
new_proof[0] = new_proof[0].wrapping_add(1);
assert!(!validate_proof(
&seed,
k,
&challenge,
&new_proof,
&mut actual_quality
));
assert_eq!(actual_quality, [0; 32]);
}
}

Expand Down
6 changes: 4 additions & 2 deletions tests/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,16 +598,18 @@ TEST_CASE("K Sizes")

SECTION("Minimum K Size")
{
uint8_t proof_data[0];
uint8_t *proof_data = new uint8_t[0];
arvidn marked this conversation as resolved.
Show resolved Hide resolved
LargeBits result = verifier.ValidateProof(plot_id_1, kMinPlotSize - 1, challenge, proof_data, 0);
REQUIRE(result.GetSize() == 0);
delete[] proof_data;
}

SECTION("Maximum K Size")
{
uint8_t proof_data[200 * 8];
uint8_t *proof_data = new uint8_t[200 * 8];
LargeBits result = verifier.ValidateProof(plot_id_1, 200, challenge, proof_data, 200 * 8);
REQUIRE(result.GetSize() == 0);
delete[] proof_data;
}
}

Expand Down
44 changes: 44 additions & 0 deletions tools/generate_rust_proof_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from chiapos import DiskPlotter, DiskProver, Verifier
from hashlib import sha256
from pathlib import Path
import os

plot_seed = bytes.fromhex(
"05683404333717545b0a6f0c0dde9710e4d3fe2d5cc6cc0a090a0b818bab0f17"
)

pl = DiskPlotter()
pl.create_plot_disk(
".",
".",
".",
"myplot.dat",
21,
bytes([1, 2, 3, 4, 5]),
plot_seed,
300,
32,
8192,
8,
False,
)
pl = None
pr = DiskProver(str(Path("myplot.dat")))

path = "rust-bindings/test_proofs.txt"
os.remove(path)

v = Verifier()
for i in range(100):
if i % 100 == 0:
print(i)
challenge = sha256(i.to_bytes(4, "big")).digest()
for index, quality in enumerate(pr.get_qualities_for_challenge(challenge)):
proof = pr.get_full_proof(challenge, index)
assert len(proof) == 8 * pr.get_size()
haorldbchi marked this conversation as resolved.
Show resolved Hide resolved
with open(path, "a+") as f:
f.write(
f"{plot_seed.hex()}, {pr.get_size()}, {challenge.hex()}, {proof.hex()}, {quality.hex()}\n"
)
computed_quality = v.validate_proof(plot_seed, pr.get_size(), challenge, proof)
assert computed_quality == quality
Loading