You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

91 lines
2.2 KiB

  1. /* Copyright (c) 2016 Cryptography Research, Inc.
  2. * Released under the MIT License. See LICENSE.txt for license information.
  3. */
  4. #include "f_field.h"
  5. void gf_mul (gf_s *__restrict__ cs, const gf as, const gf bs) {
  6. const uint32_t *a = as->limb, *b = bs->limb, maske = ((1<<26)-1), masko = ((1<<25)-1);
  7. uint32_t bh[9];
  8. int i,j;
  9. for (i=0; i<9; i++) bh[i] = b[i+1] * 19;
  10. uint32_t *c = cs->limb;
  11. uint64_t accum = 0;
  12. for (i=0; i<10; /*i+=2*/) {
  13. /* Even case. */
  14. for (j=0; j<i; /*j+=2*/) {
  15. accum += widemul(b[i-j], a[j]); j++;
  16. accum += widemul(b[i-j], 2*a[j]); j++;
  17. }
  18. accum += widemul(b[0], a[j]); j++;
  19. accum += widemul(bh[8], 2*a[j]); j++;
  20. for (; j<10; /* j+=2*/) {
  21. accum += widemul(bh[i-j+9], a[j]); j++;
  22. accum += widemul(bh[i-j+9], 2*a[j]); j++;
  23. }
  24. c[i] = accum & maske;
  25. accum >>= 26;
  26. i++;
  27. /* Odd case is easier: all place values are exact. */
  28. for (j=0; j<=i; j++) {
  29. accum += widemul(b[i-j], a[j]);
  30. }
  31. for (; j<10; j++) {
  32. accum += widemul(bh[i-j+9], a[j]);
  33. }
  34. c[i] = accum & masko;
  35. accum >>= 25;
  36. i++;
  37. }
  38. accum *= 19;
  39. accum += c[0];
  40. c[0] = accum & maske;
  41. accum >>= 26;
  42. assert(accum < masko);
  43. c[1] += (uint32_t)accum;
  44. }
  45. void gf_mulw_unsigned (gf_s *__restrict__ cs, const gf as, uint32_t b) {
  46. const uint32_t *a = as->limb, maske = ((1<<26)-1), masko = ((1<<25)-1);
  47. uint32_t *c = cs->limb;
  48. uint64_t accum = widemul(b, a[0]);
  49. c[0] = accum & maske;
  50. accum >>= 26;
  51. accum += widemul(b, a[1]);
  52. c[1] = accum & masko;
  53. accum >>= 25;
  54. for (int i=2; i<10; /*i+=2*/) {
  55. accum += widemul(b, a[i]);
  56. c[i] = accum & maske;
  57. accum >>= 26;
  58. i++;
  59. accum += widemul(b, a[i]);
  60. c[i] = accum & masko;
  61. accum >>= 25;
  62. i++;
  63. }
  64. accum *= 19;
  65. accum += c[0];
  66. c[0] = accum & maske;
  67. accum >>= 26;
  68. assert(accum < masko);
  69. c[1] += (uint32_t)accum;
  70. }
  71. void gf_sqr (gf_s *__restrict__ cs, const gf as) {
  72. gf_mul(cs,as,as); /* Performs better with dedicated square */
  73. }