fpe.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /*
  2. * File: dclxvi-20130329/fpe.c
  3. * Author: Ruben Niederhagen, Peter Schwabe
  4. * Public Domain
  5. */
  6. #include <math.h>
  7. #include <assert.h>
  8. #ifdef NEW_PARAMETERS
  9. #include "scalar_512.h"
  10. #else
  11. #include "scalar.h"
  12. #endif
  13. #include "mul.h"
  14. extern "C" {
  15. #include "fpe.h"
  16. }
  17. #include "zout.hpp"
  18. // sans mul.h la cible « ../obj/fpe_666.o » a échouée erreur: ‘coeffred_round_par’ was not declared in this scope
  19. // sans extern "C" la cible « bgn » a échouée référence indéfinie vers « fpe_iszero »
  20. // sans "fpe.h" la cible « ../obj/fpe_666.o » a échouée erreur: variable or field ‘fpe_short_coeffred’ declared void
  21. extern const scalar_t bn_pminus2;
  22. extern const double bn_v;
  23. extern const double bn_v6;
  24. void fpe_short_coeffred(fpe_t rop)
  25. {
  26. mydouble carry11 = round(rop->v[11]/bn_v);
  27. rop->v[11] = remround(rop->v[11],bn_v);
  28. rop->v[0] = rop->v[0] - carry11;
  29. rop->v[3] = rop->v[3] - carry11;
  30. rop->v[6] = rop->v[6] - 4*carry11;
  31. rop->v[9] = rop->v[9] - carry11;
  32. mydouble carry0 = round(rop->v[0]/bn_v6);
  33. mydouble carry1 = round(rop->v[1]/bn_v);
  34. mydouble carry2 = round(rop->v[2]/bn_v);
  35. mydouble carry3 = round(rop->v[3]/bn_v);
  36. mydouble carry4 = round(rop->v[4]/bn_v);
  37. mydouble carry5 = round(rop->v[5]/bn_v);
  38. mydouble carry6 = round(rop->v[6]/bn_v6);
  39. mydouble carry7 = round(rop->v[7]/bn_v);
  40. mydouble carry8 = round(rop->v[8]/bn_v);
  41. mydouble carry9 = round(rop->v[9]/bn_v);
  42. mydouble carry10 = round(rop->v[10]/bn_v);
  43. rop->v[0] = remround(rop->v[0],bn_v6);
  44. rop->v[1] = remround(rop->v[1],bn_v);
  45. rop->v[2] = remround(rop->v[2],bn_v);
  46. rop->v[3] = remround(rop->v[3],bn_v);
  47. rop->v[4] = remround(rop->v[4],bn_v);
  48. rop->v[5] = remround(rop->v[5],bn_v);
  49. rop->v[6] = remround(rop->v[6],bn_v6);
  50. rop->v[7] = remround(rop->v[7],bn_v);
  51. rop->v[8] = remround(rop->v[8],bn_v);
  52. rop->v[9] = remround(rop->v[9],bn_v);
  53. rop->v[10] = remround(rop->v[10],bn_v);
  54. rop->v[1] += carry0;
  55. rop->v[2] += carry1;
  56. rop->v[3] += carry2;
  57. rop->v[4] += carry3;
  58. rop->v[5] += carry4;
  59. rop->v[6] += carry5;
  60. rop->v[7] += carry6;
  61. rop->v[8] += carry7;
  62. rop->v[9] += carry8;
  63. rop->v[10] += carry9;
  64. rop->v[11] += carry10;
  65. }
  66. // Set fpe_t rop to given value:
  67. void fpe_set(fpe_t rop, const fpe_t op)
  68. {
  69. int i;
  70. for(i=0;i<12;i++)
  71. rop->v[i] = op->v[i];
  72. }
  73. /* Communicate the fact that the fpe is reduced (and that we don't know anything more about it) */
  74. void fpe_isreduced(fpe_t rop)
  75. {
  76. setmax(rop->v[0],(long)bn_v6/2);
  77. setmax(rop->v[6],(long)bn_v6/2);
  78. setmax(rop->v[1],(long)bn_v/2);
  79. setmax(rop->v[3],(long)bn_v/2);
  80. setmax(rop->v[4],(long)bn_v/2);
  81. setmax(rop->v[7],(long)bn_v/2);
  82. setmax(rop->v[9],(long)bn_v/2);
  83. setmax(rop->v[10],(long)bn_v/2);
  84. //XXX: Change additive constant:
  85. setmax(rop->v[2],(long)bn_v/2+2331);
  86. setmax(rop->v[5],(long)bn_v/2+2331);
  87. setmax(rop->v[8],(long)bn_v/2+2331);
  88. setmax(rop->v[11],(long)bn_v/2+2331);
  89. }
  90. // Set fpe_t rop to value given in double array of length 12
  91. void fpe_set_doublearray(fpe_t rop, const mydouble op[12])
  92. {
  93. int i;
  94. for(i=0;i<12;i++)
  95. rop->v[i] = op[i];
  96. }
  97. // Set rop to one
  98. void fpe_setone(fpe_t rop)
  99. {
  100. int i;
  101. for(i=1;i<12;i++)
  102. rop->v[i] = 0.;
  103. rop->v[0] = 1;
  104. }
  105. // Set rop to zero
  106. void fpe_setzero(fpe_t rop)
  107. {
  108. int i;
  109. for(i=0;i<12;i++)
  110. rop->v[i] = 0.;
  111. }
  112. int fpe_iseq(const fpe_t op1, const fpe_t op2)
  113. {
  114. fpe_t t;
  115. fpe_sub(t, op1, op2);
  116. return fpe_iszero(t);
  117. }
  118. int fpe_isone(const fpe_t op)
  119. {
  120. fpe_t t;
  121. int i;
  122. for(i=1;i<12;i++)
  123. t->v[i] = op->v[i];
  124. t->v[0] = op->v[0] - 1.;
  125. return fpe_iszero(t);
  126. }
  127. int fpe_iszero(const fpe_t op)
  128. {
  129. fpe_t t;
  130. double d;
  131. int i;
  132. unsigned long long tr = 0;
  133. unsigned int differentbits=0;
  134. for(i=0;i<12;i++)
  135. t->v[i] = op->v[i];
  136. coeffred_round_par(t->v);
  137. //Constant-time comparison
  138. double zero = 0.;
  139. unsigned long long *zp = (unsigned long long *)&zero;;
  140. unsigned long long *tp;
  141. for(i=0;i<12;i++)
  142. {
  143. d = todouble(t->v[i]);
  144. tp = (unsigned long long *)&d;
  145. tr |= (*tp ^ *zp);
  146. }
  147. for(i=0;i<8;i++)
  148. differentbits |= i[(unsigned char*)&tr];
  149. return 1 & ((differentbits - 1) >> 8);
  150. }
  151. // Compute the negative of an fpe
  152. void fpe_neg(fpe_t rop, const fpe_t op)
  153. {
  154. int i;
  155. for(i=0;i<12;i++)
  156. rop->v[i] = -op->v[i];
  157. }
  158. // Double an fpe:
  159. void fpe_double(fpe_t rop, const fpe_t op)
  160. {
  161. //printf("\n\n\nop="); fpe_print(stdout,op);
  162. int i;
  163. for(i=0;i<12;i++)
  164. rop->v[i] = op->v[i]*2;
  165. //printf("%f\n",rop->v[i]);
  166. }
  167. // Double an fpe:
  168. void fpe_triple(fpe_t rop, const fpe_t op)
  169. {
  170. int i;
  171. for(i=0;i<12;i++)
  172. rop->v[i] = op->v[i]*3;
  173. }
  174. // Add two fpe, store result in rop:
  175. void fpe_add(fpe_t rop, const fpe_t op1, const fpe_t op2)
  176. {
  177. int i;
  178. for(i=0;i<12;i++)
  179. rop->v[i] = op1->v[i] + op2->v[i];
  180. }
  181. // Subtract op2 from op1, store result in rop:
  182. void fpe_sub(fpe_t rop, const fpe_t op1, const fpe_t op2)
  183. {
  184. int i;
  185. for(i=0;i<12;i++)
  186. rop->v[i] = op1->v[i] - op2->v[i];
  187. }
  188. // Multiply two fpe, store result in rop:
  189. #ifndef QHASM
  190. void fpe_mul_c(fpe_t rop, const fpe_t op1, const fpe_t op2)
  191. {
  192. //debug(50);
  193. mydouble h[24];
  194. //abc;
  195. polymul(h,op1->v,op2->v);
  196. //xyz;
  197. degred(h);
  198. coeffred_round_par(h);
  199. int i;
  200. for (i=0;i<12;i++)
  201. rop->v[i] = h[i];
  202. }
  203. #endif
  204. // Square an fpe, store result in rop:
  205. void fpe_square(fpe_t rop, const fpe_t op)
  206. {
  207. /* Not used during pairing computation */
  208. fpe_mul(rop, op, op);
  209. }
  210. // Compute inverse of an fpe, store result in rop:
  211. void fpe_invert(fpe_t rop, const fpe_t op1)
  212. {
  213. fpe_set(rop,op1);
  214. int i;
  215. for(i = 254; i >= 0; i--)
  216. {
  217. fpe_mul(rop,rop,rop);
  218. if(scalar_getbit(bn_pminus2, i))
  219. fpe_mul(rop,rop,op1);
  220. }
  221. }
  222. // Print the element to stdout:
  223. void fpe_print(FILE * outfile, const fpe_t op)
  224. {
  225. int i;
  226. //for(i=0;i<11;i++) fprintf(outfile, "%10lf, ", todouble(op->v[i]));
  227. //fprintf(outfile, "%10lf", todouble(op->v[11]));
  228. for(i=0;i<11;i++) fprintf(outfile, "%.0lf, ", todouble(op->v[i]));
  229. fprintf(outfile, "%.0lf", todouble(op->v[11]));
  230. }