-
Notifications
You must be signed in to change notification settings - Fork 42
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
Signature Subtraction function #67
Conversation
relevant keybase conversation starts here: keybase://chat/grincoin.teams.node_dev#general/8880 |
This is ready for review now. Note that I opted to have a single function that returns whether the caller needs to check the second value to verify. This works well with the rust side, which can just return an tuple containing a result and an optional second possible result only if needed. |
if (!secp256k1_fe_set_b32(&noncesum_fe, sig64)) { | ||
return 0; | ||
} | ||
secp256k1_ge_set_xquad(&noncesum_ge, &noncesum_fe); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know what all these 4 calls do. Could you add comments for each? I wish I could just click on the name and be taken to their definition, but sadly I don't have such an editor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have an editor set up for ansi-C code traversal either, but core secp256k1 functions are all documented in src/field.h
for field elements functions and src/group.h
for group elements.
Line 74 in 8d1f5bb
static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a); |
Line 50 in 8d1f5bb
static int secp256k1_ge_set_xquad(secp256k1_ge *r, const secp256k1_fe *x); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean you should add comments in the style of "/* Parse nonce sum total and negated version (R, -R) */" for every reader's benefit, so it's clear why you need to call that specific function...
if (!secp256k1_fe_set_b32(&noncepartial_fe, partial64)) { | ||
return 0; | ||
} | ||
secp256k1_ge_set_xquad(&noncepartial_ge, &noncepartial_fe); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly for these 2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be in the same file as above
src/modules/aggsig/main_impl.h
Outdated
secp256k1_gej_add_ge(&nonceresult_gej_neg, &noncesum_gej_neg, &noncepartial_ge_neg); | ||
|
||
if (secp256k1_gej_has_quad_y_var(&nonceresult_gej)) { | ||
pos_version_has_quad = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These *_has_quad variables should just be booleans that you assign to, e.g.
pos_version_has_quad = secp256k1_gej_has_quad_y_var(&nonceresult_gej);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tweaked
src/modules/aggsig/main_impl.h
Outdated
return 2; | ||
} | ||
|
||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks unreachacble.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is, removed
src/modules/aggsig/main_impl.h
Outdated
secp256k1_fe_get_b32(result, &final.x); | ||
return 1; | ||
} else { | ||
/* if both, we need to return both possibilities */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh, this is either both or neither.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still don't see this addressed. You should only return 2 when you tested both *_has_quad...
src/modules/aggsig/tests_impl.h
Outdated
} | ||
CHECK(sub_check); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing test for neither, i.e. 0 results.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't happen due to (I think) the manner in which nonces are flipped during the partial sign operation, to demonstrate here's a modded version and the output from tests. Our tests run 20 invocations of this function, and I've run this test hundreds of times now.
if (pos_version_has_quad && !neg_version_has_quad) {
secp256k1_ge_set_gej(&final, &nonceresult_gej);
secp256k1_fe_normalize_var(&final.x);
secp256k1_fe_get_b32(result, &final.x);
printf("POS HAS QUAD, NEG DOES NOT\n");
return 1;
} else if (!pos_version_has_quad && neg_version_has_quad) {
secp256k1_ge_set_gej(&final, &nonceresult_gej_neg);
secp256k1_fe_normalize_var(&final.x);
secp256k1_fe_get_b32(result, &final.x);
printf("NEG HAS QUAD, POS DOES NOT\n");
return 1;
} else if (!pos_version_has_quad && !neg_version_has_quad) {
printf("!!!!!!!!!!!!!THIS DOESN'T HAPPEN!!!!!!!!!!!!!!!\n");
} else {
printf("BOTH HAVE QUAD\n");
/* if both, we need to return both possibilities */
secp256k1_ge_set_gej(&final, &nonceresult_gej);
secp256k1_fe_normalize_var(&final.x);
secp256k1_fe_get_b32(result, &final.x);
secp256k1_ge_set_gej(&final, &nonceresult_gej_neg);
secp256k1_fe_normalize_var(&final.x);
secp256k1_fe_get_b32(result_alt, &final.x);
return 2;
}
And the output:
test count = 64
random seed = 290bdc25ab4fd42b4475f13ee818f9e5
START INVOCATION
BOTH HAVE QUAD
END INVOCATION
START INVOCATION
BOTH HAVE QUAD
END INVOCATION
START INVOCATION
POS HAS QUAD, NEG DOES NOT
END INVOCATION
START INVOCATION
BOTH HAVE QUAD
END INVOCATION
START INVOCATION
POS HAS QUAD, NEG DOES NOT
END INVOCATION
START INVOCATION
BOTH HAVE QUAD
END INVOCATION
START INVOCATION
NEG HAS QUAD, POS DOES NOT
END INVOCATION
START INVOCATION
POS HAS QUAD, NEG DOES NOT
END INVOCATION
START INVOCATION
POS HAS QUAD, NEG DOES NOT
END INVOCATION
START INVOCATION
POS HAS QUAD, NEG DOES NOT
END INVOCATION
START INVOCATION
BOTH HAVE QUAD
END INVOCATION
START INVOCATION
NEG HAS QUAD, POS DOES NOT
END INVOCATION
START INVOCATION
BOTH HAVE QUAD
END INVOCATION
START INVOCATION
NEG HAS QUAD, POS DOES NOT
END INVOCATION
START INVOCATION
BOTH HAVE QUAD
END INVOCATION
START INVOCATION
BOTH HAVE QUAD
END INVOCATION
START INVOCATION
BOTH HAVE QUAD
END INVOCATION
START INVOCATION
BOTH HAVE QUAD
END INVOCATION
START INVOCATION
NEG HAS QUAD, POS DOES NOT
END INVOCATION
START INVOCATION
BOTH HAVE QUAD
END INVOCATION
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can't happen if you use QR partial nonces. But I think if you subtract a random nonce Rb from a random nonce Rb it should be possible for both Ra-Rb and -Ra-Rb to be non-QR?!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh.. okay I think this is where we're not on the same page. I'm assuming that we're only every only going to be subtracting our signatures, which always have QR nonces. You're thinking more general case, signatures that won't be produced by us, is that correct?
Assuming we're only dealing with 32 byte x-values with implicit Y based on convention (in our case where Y is a QR).. this method isn't really 'compatible' with other conventions, but you're suggesting covering those cases anyhow by returning 0 instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought "Returns: 0 on failure" could also be interpreted as saying 0 of the subtraction outcomes are valid QR. So yes, I thought this should apply to arbitrarily constructed signatures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, that's fine. all the existing functions return 0 on failure, but that can mean an argument error (like providing null for an intended out value) or various other things.
I've disambiguated this function at least to provide a 0 on an argument error as before, and return -1 if it's been provided two signatures resulting in no possible QR result. This still won't happen to callers who've only used this lib to generate signatures, but at least the case is covered.
everything else addressed as of last push, I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See inline comments.
…raction with no possible x value with corresponding y QR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok; good to go.
WIP - Due to ambiguity around nonce y-coordinates, the current version returns two separate possible signatures in some cases (both of which much be tried for the purposes of payment proofs.
Debugging output left in for the moment, to run this test only you may want to comment or def out everything in
src/tests.c
other thanrun_aggsig_tests()