-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Make fe magnitude implied statically #1001
Comments
To be clear, all the instances of magnitude are currently statically implied because all those "variables" that are dynamic are currently only ever passed integer literal values. |
@roconnor-blockstream Surely not, e.g. what about _fe_cmov? |
I wasn't aware of that one. (I'm less familiar with the non-verification related code.) Make sense to patch that case by always setting the magnitude to the max of the two values? |
Yes, which was already done, then patched out, so this time with more comments I think! |
@peterdettman Can you elaborate a little bit more on the reasoning behind this suggestion? I fully agree it's conceptually nicer. But as long as we don't have automated checks that prove that the magnitude is always low enough, does it really matter? |
The whole point of the magnitude field is to have a check that the tested code paths would not overflow even if different values were used. It is a poor man's abstract interpretation. But when we, say, set the magnitude of the output of cmov, based on the flag value, and the value of that flag value is dependent on the specific initial value we are testing, then our "abstract interpretation" ends up being limited to only those value that would produce the same flag value at that call site. I respect that our poor man's abstract interpretation is imperfect. There are places were we explicitly branch on data (especially in the (For illustration: the opposite course of action would be to make the magnitude based more and more on concrete values, but there is no point in doing that. We already have a prefect measure of the a concrete magnitude: using the actual value itself!). |
I thought of the magnitude verification AS the automated checks. It's inherently worst-case, basically a static bounds check. That plus code coverage of all branches (and careful analysis of the very few loops) means there's no overflows in the field arithmetic. Without that property you need to be sure you have test cases that exercise every code path at the maximum possible magnitude, which is just a harder-to-prove/understand version of the same thing. |
Bingo. |
Oh sure, I missed this part! (My thinking was: "it's only dynamic analysis anyway". But if the values are statically determined, then that's indeed all we need...) |
It sure would be nice to have a way of restricting a function argument to be a literal. Both to allow the obvious implementation for _mul_int, but also to restrict _fe_negate to specifying a literal for its 'm' (magnitude) argument. |
I'm moderately sure there is some horrible way to enforce this with macros. The specific solution I came across uses compound literals, but I suspect there are C89 ways too. But I'm not sure that we really want to go down the horrible-macro route. Edit: Maybe just casting through a one dimensional array somehow I'm not sure.
|
@roconnor-blockstream What about just appending |
appending |
Oh indeed. What about this?
edit: that doesn't give an error in GCC. It just gives a warning, and you need Here's a better one:
(suggested by @roconnor-blockstream again) Another way of doing it is to define a
That only works up to the bitwidth of https://port70.net/~nsz/c/c89/c89-draft.html#45 is pretty useful here. There's also in https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005fconstant_005fp in gcc. |
An entirely different way to do this is the approach in #833. |
Does that allow something generic like requiring that for any function parameter named literal_* (just for example), at all call sites the argument must be an actual literal (after pre-processor stage, say)? (Maybe the restriction is really to compile-time constant or something else more complicated, but we could just look at literals for the moment.) |
I haven't tried but I'm pretty sure that this is possible. Coupling it to the parameter name is a pretty nice idea! |
So I think #1066 makes it very clear in what ways norm/mag are not compile-time known, as it puts all propagation logic for these fields together. I find:
|
7fc642f Simplify secp256k1_fe_{impl_,}verify (Pieter Wuille) 4e176ad Abstract out verify logic for fe_is_square_var (Pieter Wuille) 4371f98 Abstract out verify logic for fe_add_int (Pieter Wuille) 89e324c Abstract out verify logic for fe_half (Pieter Wuille) 283cd80 Abstract out verify logic for fe_get_bounds (Pieter Wuille) d5aa2f0 Abstract out verify logic for fe_inv{,_var} (Pieter Wuille) 3167646 Abstract out verify logic for fe_from_storage (Pieter Wuille) 76d31e5 Abstract out verify logic for fe_to_storage (Pieter Wuille) 1e6894b Abstract out verify logic for fe_cmov (Pieter Wuille) be82bd8 Improve comments/checks for fe_sqrt (Pieter Wuille) 6ab3508 Abstract out verify logic for fe_sqr (Pieter Wuille) 4c25f6e Abstract out verify logic for fe_mul (Pieter Wuille) e179e65 Abstract out verify logic for fe_add (Pieter Wuille) 7e7ad7f Abstract out verify logic for fe_mul_int (Pieter Wuille) 65d82a3 Abstract out verify logic for fe_negate (Pieter Wuille) 1446708 Abstract out verify logic for fe_get_b32 (Pieter Wuille) f7a7666 Abstract out verify logic for fe_set_b32 (Pieter Wuille) ce4d209 Abstract out verify logic for fe_cmp_var (Pieter Wuille) 7d7d43c Improve comments/check for fe_equal{,_var} (Pieter Wuille) c5e788d Abstract out verify logic for fe_is_odd (Pieter Wuille) d3f3fe8 Abstract out verify logic for fe_is_zero (Pieter Wuille) c701d9a Abstract out verify logic for fe_clear (Pieter Wuille) 19a2bfe Abstract out verify logic for fe_set_int (Pieter Wuille) 864f9db Abstract out verify logic for fe_normalizes_to_zero{,_var} (Pieter Wuille) 6c31371 Abstract out verify logic for fe_normalize_var (Pieter Wuille) e28b51f Abstract out verify logic for fe_normalize_weak (Pieter Wuille) b6b6f9c Abstract out verify logic for fe_normalize (Pieter Wuille) 7fa5195 Bugfix: correct SECP256K1_FE_CONST mag/norm fields (Pieter Wuille) b29566c Merge magnitude/normalized fields, move/improve comments (Pieter Wuille) Pull request description: Right now, all the logic for propagating/computing the magnitude/normalized fields in `secp256k1_fe` (when `VERIFY` is defined) and the code for checking it, is duplicated across the two field implementations. I believe that is undesirable, as these properties should purely be a function of the performed fe_ functions, and not of the choice of field implementation. This becomes even uglier with #967, which would copy all that, and even needs an additional dimension that would then need to be added to the two other fields. It's also related to #1001, which I think will become easier if it doesn't need to be done/reasoned about separately for every field. This PR moves all logic around these fields (collectively called field verification) to implementations in field_impl.h, which dispatch to renamed functions in field_*_impl.h for the actual implementation. Fixes #1060. ACKs for top commit: jonasnick: ACK 7fc642f real-or-random: ACK 7fc642f Tree-SHA512: 0f94e13fedc47e47859261a182c4077308f8910495691f7e4d7877d9298385172c70e98b4a1e270b6bde4d0062b932607106306bdb35a519cdeab9695a5c71e4
31b4bbe Make fe_cmov take max of magnitudes (Pieter Wuille) Pull request description: This addresses part of #1001. The magnitude and normalization of the output of `secp256k1_fe_cmov` should not depend on the runtime value of `flag`. ACKs for top commit: real-or-random: utACK 31b4bbe stratospher: ACK 31b4bbe. Tree-SHA512: 08bef9f63797cb8a1f3ea63c716c09aaa267dfee285b74ef5fbb47d614569d2787ec73d21bce080214872dfe70246f73cea42ad3c24e6baccecabe3312f71433
…re constant be8ff3a field: Static-assert that int args affecting magnitude are constant (Tim Ruffing) Pull request description: See #1001. Try to revert the lines in `tests.c` to see the error message in action. ACKs for top commit: sipa: ACK be8ff3a. Verified by introducing some non-constant expressions and seeing compilation fail. theStack: ACK be8ff3a Tree-SHA512: 8befec6ee64959cdc7f3e29b4b622410794cfaf69e9df8df17600390a93bc787dba5cf86239de6eb2e99c038b9aca5461e4b3c82f0e0c4cf066ad7c689941b19
One instance we have overlooked is |
See the discussion starting here: #943 (comment)
The text was updated successfully, but these errors were encountered: