Save negations in var-time group addition #1056

pull peterdettman wants to merge 1 commits into bitcoin-core:master from peterdettman:group_var changing 3 files +105 −81
  1. peterdettman commented at 3:20 pm on December 26, 2021: contributor
    • Updated _gej_add_var, _gej_add_ge_var, _gej_add_zinv_var
    • 2 fewer _fe_negate in each method
    • Updated operation counts and standardize layout
    • Added internal benchmark for _gej_add_zinv_var

    benchmark_internal shows about 2% speedup in each method as a result (64bit).

  2. real-or-random commented at 3:40 pm on December 26, 2021: contributor
    Woho, we’ll soon need a few more Peters to review all those improvements! :)
  3. sipa commented at 3:41 pm on December 26, 2021: contributor
    Can you update the symbolic versions of this code in sage/prove_group_implementations.sage too?
  4. sipa commented at 7:23 pm on December 31, 2021: contributor

    ACK 66a412939351396a6351b062dff820989a63cc56

    I re-derived these formulas by manipulating the sage code until it matches the forms in this PR, and then comparing the result with the C implementations.

  5. sipa cross-referenced this on Dec 31, 2021 from issue Try a non-uniform group law (e.g., for ecmult_gen)? by real-or-random
  6. peterdettman force-pushed on Jan 1, 2022
  7. sipa commented at 6:50 pm on January 7, 2022: contributor
    ACK e6ed3705b602cd8e51612ce6d3728654bc2d1aec. Verified it’s just a rebase of 66a412939351396a6351b062dff820989a63cc56
  8. in src/bench_internal.c:262 in e6ed3705b6 outdated
    244@@ -245,6 +245,15 @@ void bench_group_add_affine_var(void* arg, int iters) {
    245     }
    246 }
    247 
    248+void bench_group_add_zinv_var(void* arg, int iters) {
    249+    int i;
    250+    bench_inv *data = (bench_inv*)arg;
    251+
    252+    for (i = 0; i < iters; i++) {
    253+        secp256k1_gej_add_zinv_var(&data->gej[0], &data->gej[0], &data->ge[1], &data->fe[0]);
    


    real-or-random commented at 10:42 am on February 9, 2022:
    I guess it does not matter but maybe use something like &data->gej[0].y as fe ensure we’re not benchmarking with the same fe over and over?

    peterdettman commented at 9:12 am on February 23, 2022:
    Done.
  9. in sage/prove_group_implementations.sage:113 in e6ed3705b6 outdated
    128     rx = b.X * bzinv2
    129     ry = b.Y * bzinv3
    130     rz = 1
    131     return (constraints(), constraints(zero={b.Infinity : 'b_finite'}, nonzero={a.Infinity : 'a_infinite'}), jacobianpoint(rx, ry, rz))
    132+  if branch == 0:
    133+    return (constraints(), constraints(nonzero={b.Infinity : 'b_infinite'}), a)
    


    real-or-random commented at 10:54 am on February 9, 2022:

    Now that this conditional has been moved, the constraints are off. In the first return, we do not know that b is not infinity (but in the second, we know that a is not infinity, though that shouldn’t be required to prove the formula.) And then the prover finds a bug in the formula because there is no equivalent in the sage code for

    0    if (a->infinity) {
    1        [...]
    2        r->infinity = b->infinity;
    

    Here’s fixed sage code: https://github.com/real-or-random/secp256k1/commits/group_var

    I assume the reason for checking b->infinity first was that this is faster if true, and I guess the likelihood of a or b being infinity is comparable. It’s probably not measurable but was there a performance reason for the reordering, or did you just change it because then it looks cleaner? If the latter, we may just leave it as it was.


    peterdettman commented at 9:17 am on February 23, 2022:

    It was just for consistency across the several methods, but on review ‘b’ is from a lookup table and should never actually be infinity in current usages. So as little as it matters, the check should come after checks that might actually happen (if we can’t just require it to be non-infinity anyway).

    I’ve adopted your fixup for the sage script, thanks.


    real-or-random commented at 9:28 am on February 23, 2022:

    It was just for consistency across the several methods, but on review ‘b’ is from a lookup table and should never actually be infinity in current usages. So as little as it matters, the check should come after checks that might actually happen (if we can’t just require it to be non-infinity anyway).

    We could VERIFY_CHECK it. But the branch can probably be predicted then, so I don’t think it hurts (and it’s certainly safer).

  10. peterdettman force-pushed on Feb 23, 2022
  11. peterdettman force-pushed on Feb 23, 2022
  12. peterdettman commented at 9:23 am on February 23, 2022: contributor
    Rebased with tweak to benchmark and updated sage file from @real-or-random .
  13. real-or-random commented at 9:26 am on February 23, 2022: contributor
    @peterdettman Nice. :) Can you squash this? I think at least the fixup! should be squashed but it’s probably also good to change the sage stuff in the same commit as the C code, then C and sage are always consistent.
  14. peterdettman force-pushed on Feb 23, 2022
  15. peterdettman commented at 12:43 pm on February 23, 2022: contributor
    Squashed everything into a single commit.
  16. real-or-random approved
  17. real-or-random commented at 4:13 pm on February 23, 2022: contributor
    ACK 2d0e1154c1939e8e7ffb05f64faf3f626fcb7000
  18. in sage/prove_group_implementations.sage:112 in 2d0e1154c1 outdated
    123     bzinv3 = bzinv2 * bzinv
    124     rx = b.X * bzinv2
    125     ry = b.Y * bzinv3
    126     rz = 1
    127+    if branch == 0:
    128+      return (constraints(), constraints(nonzero={a.Infinity : 'a_infinite', b.Infinity : 'b_infinite'}), point_at_infinity())
    


    jonasnick commented at 12:30 pm on March 6, 2022:
    Why is this branch inside this block branch == 0 or branch == 1 and not just before? It doesn’t use any of the local variables. Also, why does it exist at all, given that there’s no corresponding branch in the C code?

    real-or-random commented at 1:45 pm on March 6, 2022:

    This branch corresponds to https://github.com/bitcoin-core/secp256k1/blob/2d0e1154c1939e8e7ffb05f64faf3f626fcb7000/src/group_impl.h#L455 in the C code, which is equivalent to

    0if (b->infinity) {
    1    r ->infinity = 1;
    2} else {
    3    r ->infinity = 0;
    4}
    

    So the mapping then is

    • (C) a->infinity && b->infinity -> (sage) branch == 0
    • (C) a->infinity && !b->infinity -> (sage) branch == 1

    When I wrote this I assumed that in sage, we need to write it as an explicit branch because we have no infinity field but instead point_at_infinity() and jacobianpoint(x, y, z) constructors. But now I see that it’s not entirely true. The constructor is actually jacobianpoint(x, y, z, infinity), so there’s a much simpler way that’s closer to the sage code, see the fixup comment at https://github.com/real-or-random/secp256k1/commits/group_var . @peterdettman Can you pick that commit and squash again?


    jonasnick commented at 2:27 pm on March 6, 2022:

    b ->infinity = 1

    You mean r ->infinity = 0? Anyway, I see what you meant to represent with this branch. Your fixup looks good.


    real-or-random commented at 2:32 pm on March 6, 2022:
    yes… edited my comment to fix.
  19. in sage/prove_group_implementations.sage:283 in 2d0e1154c1 outdated
    279@@ -288,7 +280,7 @@ if __name__ == "__main__":
    280   success = True
    281   success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var)
    282   success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var)
    283-  success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var)
    284+  success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 6, formula_secp256k1_gej_add_zinv_var)
    


    real-or-random commented at 1:46 pm on March 6, 2022:
    Anyway, I forgot to make the corresponding change below for the --exhaustive version. But it doesn’t matter as the fixup mentioned above reverts this change here.
  20. sipa commented at 3:08 pm on March 28, 2022: contributor
    Anything left to do here?
  21. peterdettman commented at 3:49 pm on March 28, 2022: contributor
    I may need to followup request from @real-or-random above (unsure if done yet), and rebase.
  22. real-or-random commented at 4:12 pm on March 28, 2022: contributor
    @peterdettman It should boil down to just applying my fixup commit here, so I think it’s a matter of minutes until this ready for final review. https://github.com/real-or-random/secp256k1/commits/group_var
  23. Save negations in var-time group addition
    - Updated _gej_add_var, _gej_add_ge_var, _gej_add_zinv_var
    - 2 fewer _fe_negate in each method
    - Updated operation counts and standardize layout
    - Added internal benchmark for _gej_add_zinv_var
    - Update sage files (fixed by Tim Ruffing)
    2f984ffc45
  24. peterdettman force-pushed on Mar 28, 2022
  25. peterdettman commented at 4:53 pm on March 28, 2022: contributor
    OK, fixup applied, squashed, rebased. Ready from my end.
  26. real-or-random approved
  27. real-or-random commented at 5:00 pm on March 28, 2022: contributor
    ACK 2f984ffc45eba89faa9e79da3d5d5bd50a6c1c3d
  28. jonasnick commented at 9:18 pm on March 28, 2022: contributor
    ACK 2f984ffc45eba89faa9e79da3d5d5bd50a6c1c3d
  29. real-or-random commented at 9:19 am on March 29, 2022: contributor
    @sipa want to reACK this?
  30. real-or-random merged this on Apr 16, 2022
  31. real-or-random closed this on Apr 16, 2022

  32. fanquake referenced this in commit ef62dad39c on May 30, 2022
  33. fanquake referenced this in commit 910bca8285 on May 30, 2022
  34. fanquake referenced this in commit c41bfd1070 on Jun 11, 2022
  35. patricklodder referenced this in commit 21badcf9d2 on Jul 25, 2022
  36. patricklodder referenced this in commit 03002a9013 on Jul 28, 2022
  37. janus referenced this in commit 8a9469f3f4 on Aug 4, 2022
  38. str4d referenced this in commit ca00f27013 on Apr 21, 2023
  39. vmta referenced this in commit e1120c94a1 on Jun 4, 2023
  40. vmta referenced this in commit 8f03457eed on Jul 1, 2023
  41. jonasnick cross-referenced this on Jul 17, 2023 from issue Upstream PRs 1056, 1104, 1105, 1084, 1114, 1115 by jonasnick
  42. jonasnick cross-referenced this on Jul 17, 2023 from issue Upstream PRs 1056, 1104, 1105, 1084, 1114, 1115 by jonasnick
  43. jonasnick cross-referenced this on Jul 17, 2023 from issue Upstream PRs 1056, 1104, 1105, 1084, 1114, 1115, 1116, 1120, 1122, 1121, 1128, 1131, 1144, 1150, 1146 by jonasnick

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin-core/secp256k1. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-12-22 14:15 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me