Split fe_set_b32 into reducing and normalizing variants #1207

pull sipa wants to merge 1 commits into bitcoin-core:master from sipa:202302_split_fe_set32 changing 16 files +68 −39
  1. sipa commented at 10:21 PM on February 5, 2023: contributor

    Follow-up to #1205.

    This splits the secp256k1_fe_set_b32 function into two variants:

    • secp256k1_fe_set_b32_mod, which returns void, reduces modulo the curve order, and only promises weakly normalized output.
    • secp256k1_fe_set_b32_limit, which returns int indicating success/failure, and only promises valid output in case the input is in range (but guarantees it's strongly normalized in this case).

    This removes one of the few cases in the codebase where normalization status depends on runtime values, making it fixed at compile-time instead.

  2. sipa force-pushed on Feb 5, 2023
  3. in src/field_10x26_impl.h:409 in 21c5b28998 outdated
     383 | +        r->magnitude = 1;
     384 | +        r->normalized = 1;
     385 | +        secp256k1_fe_verify(r);
     386 | +    } else {
     387 | +        r->n[4] ^= 1; /* change value, hopefully triggering errors if the value is used. */
     388 | +    }
    


    real-or-random commented at 8:56 AM on February 6, 2023:

    Perhaps we should instead make sure that we call secp256k1_fe_verify on every entry of a function that reads a fe? We do it in some functions but not in all. For instance, t's missing in secp256k1_fe_mul_int.


    sipa commented at 3:49 PM on February 6, 2023:

    Done. I've changed this to set the magnitude to -1 in this invalid path, which should be detected if the output fe is ever fed as input to another function. In an additional commit I've also added more secp256k1_fe_verify checks.

  4. in src/field.h:79 in 21c5b28998 outdated
      74 | @@ -75,10 +75,14 @@ static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b);
      75 |  /** Compare two field elements. Requires both inputs to be normalized */
      76 |  static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b);
      77 |  
      78 | -/** Set a field element equal to 32-byte big endian value.
      79 | - *  Returns 1 if no overflow occurred, and then the output is normalized.
      80 | - *  Returns 0 if overflow occurred, and then the output is only weakly normalized. */
      81 | -static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a);
      82 | +/** Set a field element equal to 32-byte big endian value, reducing modulo the curve
      83 | + *  order if need be. The output is weakly normalized. */
    


    real-or-random commented at 8:57 AM on February 6, 2023:

    nit: s/if need be/if necessary is simpler English


    sipa commented at 3:48 PM on February 6, 2023:

    Fixed.

  5. real-or-random commented at 8:58 AM on February 6, 2023: contributor

    Concept ACK

    Not sure what's wrong with CI. Some tasks show red (exit code 134) though all tests have passed. I restarted those.

  6. real-or-random commented at 9:03 AM on February 6, 2023: contributor

    Not sure what's wrong with CI. Some tasks show red (exit code 134) though all tests have passed. I restarted those.

    Oh, these are the new -DVERIFY tests, so they fail in the benchmark (see bench.log). It's hard to see from the CI output. We should perhabs reconsider that cat to .log thing.

  7. sipa force-pushed on Feb 6, 2023
  8. sipa force-pushed on Feb 6, 2023
  9. sipa force-pushed on May 11, 2023
  10. sipa commented at 1:00 PM on May 11, 2023: contributor

    Rebased on top of (and simplified significantly as a result of) #1066.

  11. sipa force-pushed on May 11, 2023
  12. real-or-random commented at 1:33 PM on May 11, 2023: contributor

    A variant of the commit has been merged as part of #1205, so it should be removed.

  13. real-or-random approved
  14. real-or-random commented at 3:22 PM on May 11, 2023: contributor

    ACK 47bfc0a934c36e9fe1446f583789de6399bdd81d

  15. in src/field.h:204 in 47bfc0a934 outdated
     204 |   *
     205 | - * Note that this function is unusual in that the normalization of the output depends on the
     206 | - * run-time value of a.
     207 | + * On input, r does not need to be initalized. a must be a pointer to an initialized 32-byte array.
     208 | + * On output, r = a if (a < p), it will be normalized with magnitude 1, and 1 is returned.
     209 | + * If a >= 0, 0 is returned, and r will be made invalid (and cannot be used without overwriting).
    


    jonasnick commented at 5:39 PM on May 11, 2023:

    Should be "if a >= p"?


    sipa commented at 5:50 PM on May 11, 2023:

    You're ruining all the fun. This function would be so much simpler to implement otherwise.

    Fixed.

  16. jonasnick commented at 5:46 PM on May 11, 2023: contributor

    Concept ACK

  17. Split fe_set_b32 into reducing and normalizing variants 5b32602295
  18. sipa force-pushed on May 11, 2023
  19. real-or-random approved
  20. real-or-random commented at 5:51 PM on May 11, 2023: contributor

    ACK 5b32602295ff7ad9e1973f96b8ee8344b82f4af0

  21. jonasnick approved
  22. jonasnick commented at 5:51 PM on May 11, 2023: contributor

    ACK 5b32602295ff7ad9e1973f96b8ee8344b82f4af0

  23. sipa merged this on May 11, 2023
  24. sipa closed this on May 11, 2023

  25. sipa referenced this in commit b4eb644b6c on May 12, 2023
  26. hebasto referenced this in commit 49c52ea2b1 on May 13, 2023
  27. vmta referenced this in commit e1120c94a1 on Jun 4, 2023
  28. sipa referenced this in commit 901336eee7 on Jun 21, 2023
  29. vmta referenced this in commit 8f03457eed on Jul 1, 2023
  30. delta1 referenced this in commit 3f32c20932 on Aug 8, 2023
  31. delta1 referenced this in commit 31ac0c1081 on Aug 31, 2023
  32. janus referenced this in commit c4348d88db on Sep 11, 2023
  33. div72 referenced this in commit af627d47c3 on Apr 12, 2025
  34. str4d referenced this in commit 5a6bf5f178 on Jun 4, 2025
  35. Fabcien referenced this in commit b1c5676db5 on Apr 23, 2026
  36. Fabcien referenced this in commit 1bea97c373 on Apr 23, 2026

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: 2026-05-19 06:52 UTC