123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- /*
- * File: dclxvi-20130329/fpe.c
- * Author: Ruben Niederhagen, Peter Schwabe
- * Public Domain
- */
- #include <math.h>
- #include <assert.h>
- #include "scalar.h"
- #include "fpe.h"
- #include "mul.h"
- extern const scalar_t bn_pminus2;
- extern const double bn_v;
- extern const double bn_v6;
- void fpe_short_coeffred(fpe_t rop)
- {
- mydouble carry11 = round(rop->v[11]/bn_v);
- rop->v[11] = remround(rop->v[11],bn_v);
- rop->v[0] = rop->v[0] - carry11;
- rop->v[3] = rop->v[3] - carry11;
- rop->v[6] = rop->v[6] - 4*carry11;
- rop->v[9] = rop->v[9] - carry11;
- mydouble carry0 = round(rop->v[0]/bn_v6);
- mydouble carry1 = round(rop->v[1]/bn_v);
- mydouble carry2 = round(rop->v[2]/bn_v);
- mydouble carry3 = round(rop->v[3]/bn_v);
- mydouble carry4 = round(rop->v[4]/bn_v);
- mydouble carry5 = round(rop->v[5]/bn_v);
- mydouble carry6 = round(rop->v[6]/bn_v6);
- mydouble carry7 = round(rop->v[7]/bn_v);
- mydouble carry8 = round(rop->v[8]/bn_v);
- mydouble carry9 = round(rop->v[9]/bn_v);
- mydouble carry10 = round(rop->v[10]/bn_v);
- rop->v[0] = remround(rop->v[0],bn_v6);
- rop->v[1] = remround(rop->v[1],bn_v);
- rop->v[2] = remround(rop->v[2],bn_v);
- rop->v[3] = remround(rop->v[3],bn_v);
- rop->v[4] = remround(rop->v[4],bn_v);
- rop->v[5] = remround(rop->v[5],bn_v);
- rop->v[6] = remround(rop->v[6],bn_v6);
- rop->v[7] = remround(rop->v[7],bn_v);
- rop->v[8] = remround(rop->v[8],bn_v);
- rop->v[9] = remround(rop->v[9],bn_v);
- rop->v[10] = remround(rop->v[10],bn_v);
- rop->v[1] += carry0;
- rop->v[2] += carry1;
- rop->v[3] += carry2;
- rop->v[4] += carry3;
- rop->v[5] += carry4;
- rop->v[6] += carry5;
- rop->v[7] += carry6;
- rop->v[8] += carry7;
- rop->v[9] += carry8;
- rop->v[10] += carry9;
- rop->v[11] += carry10;
- }
- // Set fpe_t rop to given value:
- void fpe_set(fpe_t rop, const fpe_t op)
- {
- int i;
- for(i=0;i<12;i++)
- rop->v[i] = op->v[i];
- }
- /* Communicate the fact that the fpe is reduced (and that we don't know anything more about it) */
- void fpe_isreduced(fpe_t rop)
- {
- setmax(rop->v[0],(long)bn_v6/2);
- setmax(rop->v[6],(long)bn_v6/2);
- setmax(rop->v[1],(long)bn_v/2);
- setmax(rop->v[3],(long)bn_v/2);
- setmax(rop->v[4],(long)bn_v/2);
- setmax(rop->v[7],(long)bn_v/2);
- setmax(rop->v[9],(long)bn_v/2);
- setmax(rop->v[10],(long)bn_v/2);
- //XXX: Change additive constant:
- setmax(rop->v[2],(long)bn_v/2+2331);
- setmax(rop->v[5],(long)bn_v/2+2331);
- setmax(rop->v[8],(long)bn_v/2+2331);
- setmax(rop->v[11],(long)bn_v/2+2331);
- }
- // Set fpe_t rop to value given in double array of length 12
- void fpe_set_doublearray(fpe_t rop, const mydouble op[12])
- {
- int i;
- for(i=0;i<12;i++)
- rop->v[i] = op[i];
- }
- // Set rop to one
- void fpe_setone(fpe_t rop)
- {
- int i;
- for(i=1;i<12;i++)
- rop->v[i] = 0.;
- rop->v[0] = 1;
- }
- // Set rop to zero
- void fpe_setzero(fpe_t rop)
- {
- int i;
- for(i=0;i<12;i++)
- rop->v[i] = 0.;
- }
- int fpe_iseq(const fpe_t op1, const fpe_t op2)
- {
- fpe_t t;
- fpe_sub(t, op1, op2);
- return fpe_iszero(t);
- }
- int fpe_isone(const fpe_t op)
- {
- fpe_t t;
- int i;
- for(i=1;i<12;i++)
- t->v[i] = op->v[i];
- t->v[0] = op->v[0] - 1.;
- return fpe_iszero(t);
- }
- int fpe_iszero(const fpe_t op)
- {
- fpe_t t;
- double d;
- int i;
- unsigned long long tr = 0;
- unsigned int differentbits=0;
- for(i=0;i<12;i++)
- t->v[i] = op->v[i];
- coeffred_round_par(t->v);
- //Constant-time comparison
- double zero = 0.;
- unsigned long long *zp = (unsigned long long *)&zero;;
- unsigned long long *tp;
- for(i=0;i<12;i++)
- {
- d = todouble(t->v[i]);
- tp = (unsigned long long *)&d;
- tr |= (*tp ^ *zp);
- }
- for(i=0;i<8;i++)
- differentbits |= i[(unsigned char*)&tr];
- return 1 & ((differentbits - 1) >> 8);
- }
- // Compute the negative of an fpe
- void fpe_neg(fpe_t rop, const fpe_t op)
- {
- int i;
- for(i=0;i<12;i++)
- rop->v[i] = -op->v[i];
- }
- // Double an fpe:
- void fpe_double(fpe_t rop, const fpe_t op)
- {
- int i;
- for(i=0;i<12;i++)
- rop->v[i] = op->v[i]*2;
- }
- // Double an fpe:
- void fpe_triple(fpe_t rop, const fpe_t op)
- {
- int i;
- for(i=0;i<12;i++)
- rop->v[i] = op->v[i]*3;
- }
- // Add two fpe, store result in rop:
- void fpe_add(fpe_t rop, const fpe_t op1, const fpe_t op2)
- {
- int i;
- for(i=0;i<12;i++)
- rop->v[i] = op1->v[i] + op2->v[i];
- }
- // Subtract op2 from op1, store result in rop:
- void fpe_sub(fpe_t rop, const fpe_t op1, const fpe_t op2)
- {
- int i;
- for(i=0;i<12;i++)
- rop->v[i] = op1->v[i] - op2->v[i];
- }
- // Multiply two fpe, store result in rop:
- #ifndef QHASM
- void fpe_mul_c(fpe_t rop, const fpe_t op1, const fpe_t op2)
- {
- mydouble h[24];
- polymul(h,op1->v,op2->v);
- degred(h);
- coeffred_round_par(h);
- int i;
- for (i=0;i<12;i++)
- rop->v[i] = h[i];
- }
- #endif
- // Square an fpe, store result in rop:
- void fpe_square(fpe_t rop, const fpe_t op)
- {
- /* Not used during pairing computation */
- fpe_mul(rop, op, op);
- }
- // Compute inverse of an fpe, store result in rop:
- void fpe_invert(fpe_t rop, const fpe_t op1)
- {
- fpe_set(rop,op1);
- int i;
- for(i = 254; i >= 0; i--)
- {
- fpe_mul(rop,rop,rop);
- if(scalar_getbit(bn_pminus2, i))
- fpe_mul(rop,rop,op1);
- }
- }
- // Print the element to stdout:
- void fpe_print(FILE * outfile, const fpe_t op)
- {
- int i;
- for(i=0;i<11;i++) fprintf(outfile, "%10lf, ", todouble(op->v[i]));
- fprintf(outfile, "%10lf", todouble(op->v[11]));
- }
|