Alternative cmov implementation #457

pull peterdettman wants to merge 1 commits into bitcoin-core:master from peterdettman:alt_cmov changing 2 files +34 −39
  1. peterdettman commented at 2:47 pm on May 17, 2017: contributor

    See the paper “Attacking embedded ECC implementations through cmov side channels” for a description of the problem. @sipa and I discussed this briefly in NYC, and we thought maybe this alternative construction might improve the situation. Peter Schwabe also independently mentioned the same construction, and that they hoped to get around to a second paper looking at suggested countermeasures.

    Edit: Link to paper: https://eprint.iacr.org/2016/923

  2. Alternative cmov implementation 42b6b426ce
  3. gmaxwell commented at 11:36 pm on May 18, 2017: contributor
    Interesting. I suppose better is better… though I think we’re kinda shooting in the dark. We really need to have a good power analysis test setup to really know if we’re successful against those kinds of sidechannels. @tdaede was working on one before.
  4. peterdettman commented at 2:45 am on May 19, 2017: contributor
    My thoughts exactly.
  5. sipa commented at 7:43 am on July 31, 2017: contributor
    I-guess-it-won’t-hurt-ACK 42b6b426ce6366bbe18c3631713e8b90216e6ac9
  6. real-or-random requested review from real-or-random on Dec 2, 2019
  7. real-or-random commented at 5:51 pm on December 2, 2019: contributor

    The code changes look perfectly fine to me and pass tests, ACK on these.

    gcc introduces some branches here with -O3. I had a glimpse at it and it could be that all of these are not dependent on secrets (wild guesses: checking whether r and a overlap? checking whether len is 0?). We need to have a closer look. I’m not really good in reading assembly, maybe someone wants to give it a try: https://godbolt.org/z/XqeEK5

  8. real-or-random commented at 2:52 pm on December 4, 2019: contributor

    Okay, I played around with this a little bit.

    First, the branches are not an issue. These really only implement the loop, even though they looked different to me at first glance.

    But GCC manages to factor out the computation of the entire mask half ^ rest and move it before the loop. This happens already with -O1 and even on AVR GCC (which is interesting because the attack in the paper targeted AVR as an example). My understanding is that the 0x55...55 constants (= 0101…01 as bits) here are a crucial part of the countermeasure because they ensure all XOR operations are performed with masks of the same Hamming weight (0101…01 or 1010…10 depending on the secret input bit).

    So while this PR does not hurt, it does not really help if you use GCC, which is simply too clever for us. So I’m not sure if there’s a simple way that works across platform. What we could do for x86_64 specifically will be an implementation based on the CMOV instruction but even here we don’t know what that means for power analysis. At least it’s “guaranteed” to be constant-time and fast.

  9. real-or-random commented at 1:58 pm on March 26, 2020: contributor

    So while this PR does not hurt, it does not really help if you use GCC, which is simply too clever for us. So I’m not sure if there’s a simple way that works across platform.

    #728 reminded me of this PR, and this variant should work:

     0static void secp256k1_fe_cmov_limbs(uint32_t *r, const uint32_t *a, int len, int flag) {
     1    int i;
     2    uint32_t diff, r_i;
     3    volatile const uint32_t half = 0x55555555UL;
     4    volatile const uint32_t rest = half << flag;
     5    for (i=0; i<len; i++) {
     6        diff = r[i] ^ a[i];
     7        r[i] ^= (diff & half);
     8        r[i] ^= (diff & rest);
     9    }
    10}
    

    Not sure why I didn’t think of volatile when I looked at this previously.

  10. real-or-random cross-referenced this on Jul 28, 2020 from issue secp256k1_scalar_cmov not constant-time on ICC by real-or-random
  11. real-or-random cross-referenced this on Dec 28, 2021 from issue Signed-digit multi-comb for ecmult_gen (by peterdettman) by sipa
  12. real-or-random referenced this in commit 4a496a36fb on Apr 1, 2023
  13. real-or-random cross-referenced this on Apr 1, 2023 from issue ct: Use volatile "trick" in all fe/scalar cmov implementations by real-or-random
  14. real-or-random referenced this in commit 2d51a454fc on Apr 6, 2023
  15. real-or-random assigned real-or-random on May 8, 2023
  16. real-or-random commented at 2:12 pm on May 8, 2023: contributor

    After discussing with @sipa and @jonasnick, we believe it’s worth to do this even if we’re not entirely sure how much it helps. (And we anyway have volatile everywhere in CMOV after #1257).

     0static void secp256k1_fe_cmov_limbs(uint32_t *r, const uint32_t *a, int len, int flag) {
     1    int i;
     2    uint32_t diff, r_i;
     3    volatile const uint32_t half = 0x55555555UL;
     4    volatile const uint32_t rest = half << flag;
     5    for (i=0; i<len; i++) {
     6        diff = r[i] ^ a[i];
     7        r[i] ^= (diff & half);
     8        r[i] ^= (diff & rest);
     9    }
    10}
    

    I’ll open a follow-up PR with that volatile variant above.

  17. real-or-random added the label assurance on May 8, 2023
  18. real-or-random added the label side-channel on May 8, 2023
  19. dderjoel referenced this in commit e9da2fe043 on May 23, 2023

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 09:15 UTC

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