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

Verify perf #4

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open

Verify perf #4

wants to merge 9 commits into from

Conversation

NDobrev
Copy link
Contributor

@NDobrev NDobrev commented Feb 7, 2025

No description provided.

Copy link
Collaborator

@smanilov smanilov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preliminary review; interrupted by other tasks.

src/main.rs Outdated Show resolved Hide resolved
src/main.rs Outdated
}

fn read_text_file(filename: &str) -> Result<String, Box<dyn Error>> {
fn read_text_file(filename: &str) -> Result<String, Box<dyn Error>> {
let mut file = File::open(filename).map_err(|e| format!("Error opening file: {}", e))?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error currently looks like this:

# ./target/release/dvt_prover_host --input-file examples/dvt_bad_share.json --type share --json-schema-file foo
Error opening file: No such file or directory (os error 2)

In my opinion, this is a shortcoming of std::io: the name of the file is not printed. I would add it in the error message manually:

let mut file = File::open(filename).map_err(|e| format!("Error opening file {filename}: {e}"))?;

Also, note that you can interpolate variables directly. (But not expressions; format!("{x}"); works, but format!("{call_me()}"); does not.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reworked

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see this change in the current code. Did you forget to add it?

src/main.rs Outdated
@@ -80,7 +130,7 @@ fn main() {
}

if args.json_schema.is_some() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section can be rewritten using "if let" statements:

    if let Some(json_schema) = args.json_schema {
        if let Err(err) = validate_json(json_schema.as_str(), args.input_file.as_str()) {
            eprintln!("{err}");
            std::process::exit(1);
        }
    }

before, it was

    if args.json_schema.is_some() {
        let ok = validate_json(args.json_schema.unwrap().as_str(), args.input_file.as_str());
        if ok.is_err() {
            eprintln!("{}", ok.unwrap_err());
            std::process::exit(1);
        }
    }

Generally, using unwrap() is a code smell in Rust.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, use panic!() for controlled-crashing, like mentioned later:

    if let Some(json_schema) = args.json_schema {
        if let Err(err) = validate_json(json_schema.as_str(), args.input_file.as_str()) {
            panic!("{err}");
        }
    }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good. Changed

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note also

    if let Err(err) = validate_json(json_schema.as_str(), args.input_file.as_str()) {

instead of

     let ok = validate_json(path_to_schema.as_str(), args.input_file.as_str());
     if ok.is_err() {

Commenting again, in case you didn't just ignore the suggestion, but missed it.

src/main.rs Show resolved Hide resolved
src/main.rs Show resolved Hide resolved
src/main.rs Show resolved Hide resolved
src/main.rs Outdated Show resolved Hide resolved
src/main.rs Outdated Show resolved Hide resolved
src/main.rs Outdated Show resolved Hide resolved
crates/bls_utils/src/input.rs Outdated Show resolved Hide resolved
Copy link
Collaborator

@smanilov smanilov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finished review of the share_exchange_prove guest program.

Let me know if you would like me to review more of this code (the other guest programs).

let found = data.verification_hashes.iter().find(|h| {
h == &&data.initial_commitment.hash
});
let found = data
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use any() instead of find() for a micro-optimization in terms of using the best idiom:

    let found = data
        .verification_hashes
        .iter()
        .any(|h| h == &data.initial_commitment.hash);

    if !found {

@@ -63,6 +65,14 @@ pub fn get_index_in_commitments(
)))
}

pub fn to_g1_affine(pubkey: &dvt_abi::BLSPubkey) -> G1Affine {
G1Affine::from_compressed(&pubkey).into_option().unwrap()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned before, an unwrap() in the code is a code smell.

In this case, you could replace it with an expect(), which is the same, but gives context why the unwrap failed:

    G1Affine::from_compressed(&pubkey)
        .into_option()
        .expect("G1 point is not torsion free.")

I inferred this from reading the source of from_compressed(), but perhaps the message could be better.

Some(g2_sig) => g2_sig,
None => {
return Err(Box::new(VerificationErrors::UnslashableError(
String::from(format!(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can drop the String::from() here (and later).

let g1_pubkey = to_g1_affine(&commitment.pubkey);

let g2_sig = match G2Affine::from_compressed(&commitment.signature).into_option() {
Some(g2_sig) => g2_sig,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to suggest the same, as I was looking at the previous version of this code locally. Great minds!

let domain = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
let pk_projective = G1Projective::from(pubkey);
let sig_projective = G2Projective::from(signature);
<G2Projective as HashToCurve<ExpandMsgXmd<Sha256>>>::hash_to_curve(msg, domain)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. I thought maybe you could drop G2Projective as, but it turns out that you cannot. Using dyn also does not help. So much for knowing Rust.

return Err(Box::new(VerificationErrors::SlashableError(String::from(
format!(
"Invalid field seeds_exchange_commitment.shared_secret.secret: {} \n",
e
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this e can go in the format string


let unwraped = dest_id.unwrap() + 1;
let test_id = bls_id_from_u32(unwraped);
// F(0) is aways reserved for the aggregated key so we need to start from 1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: typo


let mut cfst: Vec<G1Affine> = Vec::new();
for pubkey in &initial_commitment.verification_vector.pubkeys {
cfst.push(G1Affine::from_compressed(pubkey).into_option().unwrap());
cfst.push(to_g1_affine(pubkey));
}

let le_bytes = seed_exchange.shared_secret.dst_id.clone();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is about the following String::from on line 164, but I cannot leave a comment there, since it's not part of this PR.

For converting &str to String, there are multiple ways, none of which is idiomatic. But you might want to consider using to_owned(), as "it conveys the most intent": https://users.rust-lang.org/t/what-is-the-idiomatic-way-to-convert-str-to-string/12160/7

Comment on lines 44 to 54
if count == 0 {
return G1Projective::identity();
} else if count == 1 {
return G1Projective::from(cfs[0]);
} else {
let mut y = cfs[count - 1];
for i in 2..(count + 1) {
y = y * x + cfs[count - i];
}
return y;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two more ways to write this, depending on your taste:

    return if count == 0 {
        G1Affine::identity()
    } else if count == 1 {
        cfs[0]
    } else {
        let mut y = cfst[count - 1];
        for i in 2..(count + 1) {
            y = y * x + cfs[count - i];
        }
        G1Affine::from(y)
    };

or even

    if count == 0 {
        G1Affine::identity()
    } else if count == 1 {
        cfs[0]
    } else {
        let mut y = cfst[count - 1];
        for i in 2..(count + 1) {
            y = y * x + cfs[count - i];
        }
        G1Affine::from(y)
    }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i am not sure, if it's more readable but changed it anyway

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