Home | History | Annotate | Download | only in src
      1 /*############################################################################
      2 # Copyright 2017 Intel Corporation
      3 #
      4 # Licensed under the Apache License, Version 2.0 (the "License");
      5 # you may not use this file except in compliance with the License.
      6 # You may obtain a copy of the License at
      7 #
      8 #     http://www.apache.org/licenses/LICENSE-2.0
      9 #
     10 # Unless required by applicable law or agreed to in writing, software
     11 # distributed under the License is distributed on an "AS IS" BASIS,
     12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 # See the License for the specific language governing permissions and
     14 # limitations under the License.
     15 ############################################################################*/
     16 /// Implementation of Tate pairing
     17 /*! \file */
     18 
     19 #include "epid/member/tiny/math/pairing.h"
     20 #include "epid/member/tiny/math/efq2.h"
     21 #include "epid/member/tiny/math/fq.h"
     22 #include "epid/member/tiny/math/fq12.h"
     23 #include "epid/member/tiny/math/fq2.h"
     24 #include "epid/member/tiny/math/mathtypes.h"
     25 #include "epid/member/tiny/math/vli.h"
     26 
     27 static const VeryLargeInt epid_e = {{0xf2788803, 0x7886dcf9, 0x2dc401c0,
     28                                      0xd77a10ff, 0x27bd9b6f, 0x367ba865,
     29                                      0xaaaa2822, 0x2aaaaaaa}};
     30 static const VeryLargeInt epid_t = {{0x30B0A801, 0x6882F5C0, 0, 0, 0, 0, 0, 0}};
     31 static const Fq2Elem epid_xi = {
     32     {{{0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
     33        0x00000000, 0x00000000}}},
     34     {{{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
     35        0x00000000, 0x00000000}}}};
     36 static const int neg = 1;
     37 
     38 void PairingInit(PairingState* state) {
     39   int i;
     40   Fq2Exp(&state->g[0][0], &epid_xi, &epid_e);
     41   for (i = 1; i < 5; i++) {
     42     Fq2Mul(&state->g[0][i], &state->g[0][i - 1], &state->g[0][0]);
     43   }
     44   for (i = 0; i < 5; i++) {
     45     FqSquare(&state->g[1][i].x0, &state->g[0][i].x0);
     46     FqSquare(&state->g[1][i].x1, &state->g[0][i].x1);
     47     FqAdd(&state->g[1][i].x0, &state->g[1][i].x0, &state->g[1][i].x1);
     48     FqClear(&state->g[1][i].x1);
     49     Fq2Mul(&state->g[2][i], &state->g[0][i], &state->g[1][i]);
     50   }
     51 }
     52 
     53 static void piOp(EccPointFq2* Qout, EccPointFq2 const* Qin, int e,
     54                  PairingState const* scratch) {
     55   if (e == 1) {
     56     Fq2Conj(&Qout->x, &Qin->x);
     57     Fq2Conj(&Qout->y, &Qin->y);
     58   } else {
     59     Fq2Cp(&Qout->x, &Qin->x);
     60     Fq2Cp(&Qout->y, &Qin->y);
     61   }
     62   Fq2Mul(&Qout->x, &Qout->x, &scratch->g[e - 1][1]);
     63   Fq2Mul(&Qout->y, &Qout->y, &scratch->g[e - 1][2]);
     64 }
     65 
     66 /*
     67  * Computes the Frobenius endomorphism Pout = Pin^(p^e)
     68  */
     69 static void frob_op(Fq12Elem* Pout, Fq12Elem const* Pin, int e,
     70                     PairingState const* state) {
     71   if (e == 1 || e == 3) {
     72     Fq2Conj(&Pout->z0.y0, &Pin->z0.y0);
     73     Fq2Conj(&Pout->z1.y0, &Pin->z1.y0);
     74     Fq2Conj(&Pout->z0.y1, &Pin->z0.y1);
     75     Fq2Conj(&Pout->z1.y1, &Pin->z1.y1);
     76     Fq2Conj(&Pout->z0.y2, &Pin->z0.y2);
     77     Fq2Conj(&Pout->z1.y2, &Pin->z1.y2);
     78   } else {
     79     Fq2Cp(&Pout->z0.y0, &Pin->z0.y0);
     80     Fq2Cp(&Pout->z1.y0, &Pin->z1.y0);
     81     Fq2Cp(&Pout->z0.y1, &Pin->z0.y1);
     82     Fq2Cp(&Pout->z1.y1, &Pin->z1.y1);
     83     Fq2Cp(&Pout->z0.y2, &Pin->z0.y2);
     84     Fq2Cp(&Pout->z1.y2, &Pin->z1.y2);
     85   }
     86   Fq2Mul(&Pout->z1.y0, &Pout->z1.y0, &state->g[e - 1][0]);
     87   Fq2Mul(&Pout->z0.y1, &Pout->z0.y1, &state->g[e - 1][1]);
     88   Fq2Mul(&Pout->z1.y1, &Pout->z1.y1, &state->g[e - 1][2]);
     89   Fq2Mul(&Pout->z0.y2, &Pout->z0.y2, &state->g[e - 1][3]);
     90   Fq2Mul(&Pout->z1.y2, &Pout->z1.y2, &state->g[e - 1][4]);
     91 }
     92 
     93 static void finalExp(Fq12Elem* f, PairingState const* state) {
     94   Fq12Elem t3;
     95   Fq12Elem t2;
     96   Fq12Elem t1;
     97   Fq12Elem t0;
     98 
     99   Fq12Conj(&t1, f);
    100   Fq12Inv(&t2, f);
    101   Fq12Mul(f, &t1, &t2);
    102   frob_op(&t2, f, 2, state);
    103   Fq12Mul(f, f, &t2);
    104   Fq12ExpCyc(&t1, f, &epid_t);
    105   if (neg) {
    106     Fq12Conj(&t1, &t1);
    107   }
    108   Fq12ExpCyc(&t3, &t1, &epid_t);
    109   if (neg) {
    110     Fq12Conj(&t3, &t3);
    111   }
    112   Fq12ExpCyc(&t0, &t3, &epid_t);
    113   if (neg) {
    114     Fq12Conj(&t0, &t0);
    115   }
    116   frob_op(&t2, &t0, 1, state);
    117   Fq12Mul(&t2, &t2, &t0);
    118   Fq12Conj(&t2, &t2);
    119   Fq12SqCyc(&t0, &t2);
    120   frob_op(&t2, &t3, 1, state);
    121   Fq12Mul(&t2, &t2, &t1);
    122   Fq12Conj(&t2, &t2);
    123   Fq12Mul(&t0, &t0, &t2);
    124   Fq12Conj(&t2, &t3);
    125   Fq12Mul(&t0, &t0, &t2);
    126   frob_op(&t1, &t1, 1, state);
    127   Fq12Conj(&t1, &t1);
    128   Fq12Mul(&t1, &t1, &t2);
    129   Fq12Mul(&t1, &t1, &t0);
    130   frob_op(&t2, &t3, 2, state);
    131   Fq12Mul(&t0, &t0, &t2);
    132   Fq12SqCyc(&t1, &t1);
    133   Fq12Mul(&t1, &t1, &t0);
    134   Fq12SqCyc(&t1, &t1);
    135   Fq12Conj(&t2, f);
    136   Fq12Mul(&t0, &t1, &t2);
    137   frob_op(&t2, f, 1, state);
    138   Fq12Mul(&t1, &t1, &t2);
    139   frob_op(&t2, f, 2, state);
    140   Fq12Mul(&t1, &t1, &t2);
    141   frob_op(&t2, f, 3, state);
    142   Fq12Mul(&t1, &t1, &t2);
    143   Fq12SqCyc(&t0, &t0);
    144   Fq12Mul(f, &t1, &t0);
    145 }
    146 
    147 static void pair_tangent(Fq12Elem* f, Fq2Elem* X, Fq2Elem* Y, Fq2Elem* Z,
    148                          Fq2Elem* Z2, EccPointFq const* P) {
    149   Fq2Mul(&f->z0.y0, X, X);
    150   Fq2Add(&f->z0.y2, &f->z0.y0, &f->z0.y0);
    151   Fq2Add(&f->z0.y2, &f->z0.y2, &f->z0.y0);
    152   Fq2Add(&f->z1.y1, X, &f->z0.y2);
    153   Fq2Mul(&f->z1.y1, &f->z1.y1, &f->z1.y1);
    154   Fq2Sub(&f->z1.y1, &f->z1.y1, &f->z0.y0);
    155   Fq2Mul(&f->z0.y1, Y, Y);
    156   Fq2Add(&f->z1.y0, &f->z0.y1, X);
    157   Fq2Mul(&f->z1.y0, &f->z1.y0, &f->z1.y0);
    158   Fq2Sub(&f->z1.y0, &f->z1.y0, &f->z0.y0);
    159   Fq2Mul(&f->z0.y0, &f->z0.y1, &f->z0.y1);
    160   Fq2Sub(&f->z1.y0, &f->z1.y0, &f->z0.y0);
    161   Fq2Add(&f->z1.y0, &f->z1.y0, &f->z1.y0);
    162   Fq2Mul(&f->z1.y2, &f->z0.y2, &f->z0.y2);
    163   Fq2Add(Z, Y, Z);
    164   Fq2Mul(Z, Z, Z);
    165   Fq2Sub(Z, Z, &f->z0.y1);
    166   Fq2Sub(Z, Z, Z2);
    167   Fq2Add(&f->z0.y1, &f->z0.y1, &f->z0.y1);
    168   Fq2Add(&f->z0.y1, &f->z0.y1, &f->z0.y1);
    169   Fq2Sub(&f->z1.y1, &f->z1.y1, &f->z1.y2);
    170   Fq2Sub(&f->z1.y1, &f->z1.y1, &f->z0.y1);
    171   Fq2Sub(X, &f->z1.y2, &f->z1.y0);
    172   Fq2Sub(X, X, &f->z1.y0);
    173   Fq2Add(&f->z0.y0, &f->z0.y0, &f->z0.y0);
    174   Fq2Add(&f->z0.y0, &f->z0.y0, &f->z0.y0);
    175   Fq2Add(&f->z0.y0, &f->z0.y0, &f->z0.y0);
    176   Fq2Sub(Y, &f->z1.y0, X);
    177   Fq2Mul(Y, Y, &f->z0.y2);
    178   Fq2Sub(Y, Y, &f->z0.y0);
    179   Fq2Mul(&f->z1.y0, &f->z0.y2, Z2);
    180   Fq2Neg(&f->z1.y0, &f->z1.y0);
    181   Fq2Add(&f->z1.y0, &f->z1.y0, &f->z1.y0);
    182   Fq2MulScalar(&f->z1.y0, &f->z1.y0, &P->x);
    183   Fq2Mul(&f->z0.y0, Z, Z2);
    184   Fq2Add(&f->z0.y0, &f->z0.y0, &f->z0.y0);
    185   Fq2MulScalar(&f->z0.y0, &f->z0.y0, &P->y);
    186   Fq2Mul(Z2, Z, Z);
    187   Fq2Clear(&f->z0.y1);
    188   Fq2Clear(&f->z0.y2);
    189   Fq2Clear(&f->z1.y2);
    190   Fq2Square(Z2, Z);
    191 }
    192 
    193 static void pair_line(Fq12Elem* f, Fq2Elem* X, Fq2Elem* Y, Fq2Elem* Z,
    194                       Fq2Elem* Z2, EccPointFq const* P, EccPointFq2 const* Q) {
    195   Fq2Mul(&f->z0.y1, &Q->x, Z2);
    196   Fq2Add(&f->z1.y0, &Q->y, Z);
    197   Fq2Mul(&f->z1.y0, &f->z1.y0, &f->z1.y0);
    198   Fq2Square(&f->z0.y0, &Q->y);
    199   Fq2Sub(&f->z1.y0, &f->z1.y0, &f->z0.y0);
    200   Fq2Sub(&f->z1.y0, &f->z1.y0, Z2);
    201   Fq2Mul(&f->z1.y0, &f->z1.y0, Z2);
    202   Fq2Sub(&f->z0.y1, &f->z0.y1, X);
    203   Fq2Mul(&f->z0.y2, &f->z0.y1, &f->z0.y1);
    204   Fq2Add(Z, Z, &f->z0.y1);
    205   Fq2Square(Z, Z);
    206   Fq2Sub(Z, Z, Z2);
    207   Fq2Sub(Z, Z, &f->z0.y2);
    208   Fq2Mul(Z2, Z, Z);
    209   Fq2Add(&f->z1.y2, &Q->y, Z);
    210   Fq2Mul(&f->z1.y2, &f->z1.y2, &f->z1.y2);
    211   Fq2Sub(&f->z1.y2, &f->z1.y2, &f->z0.y0);
    212   Fq2Sub(&f->z1.y2, &f->z1.y2, Z2);
    213   Fq2Sub(&f->z1.y0, &f->z1.y0, Y);
    214   Fq2Sub(&f->z1.y0, &f->z1.y0, Y);
    215   Fq2Mul(&f->z1.y1, &f->z1.y0, &Q->x);
    216   Fq2Add(&f->z1.y1, &f->z1.y1, &f->z1.y1);
    217   Fq2Sub(&f->z1.y1, &f->z1.y1, &f->z1.y2);
    218   Fq2Add(&f->z0.y2, &f->z0.y2, &f->z0.y2);
    219   Fq2Add(&f->z0.y2, &f->z0.y2, &f->z0.y2);
    220   Fq2Mul(&f->z0.y1, &f->z0.y2, &f->z0.y1);
    221   Fq2Mul(&f->z0.y2, X, &f->z0.y2);
    222   Fq2Mul(X, &f->z1.y0, &f->z1.y0);
    223   Fq2Sub(X, X, &f->z0.y1);
    224   Fq2Sub(X, X, &f->z0.y2);
    225   Fq2Sub(X, X, &f->z0.y2);
    226   Fq2Sub(&f->z0.y2, &f->z0.y2, X);
    227   Fq2Mul(&f->z0.y2, &f->z0.y2, &f->z1.y0);
    228   Fq2Mul(&f->z0.y1, Y, &f->z0.y1);
    229   Fq2Add(&f->z0.y1, &f->z0.y1, &f->z0.y1);
    230   Fq2Sub(Y, &f->z0.y2, &f->z0.y1);
    231   Fq2MulScalar(&f->z0.y0, Z, &P->y);
    232   Fq2Add(&f->z0.y0, &f->z0.y0, &f->z0.y0);
    233   Fq2Neg(&f->z1.y0, &f->z1.y0);
    234   Fq2MulScalar(&f->z1.y0, &f->z1.y0, &P->x);
    235   Fq2Add(&f->z1.y0, &f->z1.y0, &f->z1.y0);
    236   Fq2Clear(&f->z0.y1);
    237   Fq2Clear(&f->z0.y2);
    238   Fq2Clear(&f->z1.y2);
    239 }
    240 
    241 void PairingCompute(Fq12Elem* d, EccPointFq const* P, EccPointFq2 const* Q,
    242                     PairingState const* state) {
    243   Fq2Elem X;
    244   Fq2Elem Y;
    245   Fq2Elem Z;
    246   Fq2Elem Z2;
    247   EccPointFq2 Qp;
    248   Fq12Elem f;
    249   VeryLargeInt s;
    250   const VeryLargeInt two = {{2}};
    251   uint32_t i;
    252 
    253   VliAdd(&s, &epid_t, &epid_t);  // s = 2*t
    254   VliAdd(&s, &s, &epid_t);       // s = 3*t
    255   VliAdd(&s, &s, &s);            // s = 6*t
    256   if (neg) {
    257     VliSub(&s, &s, &two);
    258   } else {
    259     VliAdd(&s, &s, &two);
    260   }
    261   Fq2Cp(&X, &Q->x);
    262   Fq2Cp(&Y, &Q->y);
    263   Fq2Set(&Z, 1);
    264   Fq2Set(&Z2, 1);
    265   Fq12Set(d, 1);
    266 
    267   Fq12Clear(&f);
    268   // s has 66 bits, 0 through 65, so starting point is bit 64
    269   i = 65;
    270   while (i > 0) {
    271     i -= 1;
    272     pair_tangent(&f, &X, &Y, &Z, &Z2, P);
    273     Fq12Square(d, d);
    274     Fq12MulSpecial(d, d, &f);
    275     if (VliTestBit(&s, i)) {
    276       pair_line(&f, &X, &Y, &Z, &Z2, P, Q);
    277       Fq12MulSpecial(d, d, &f);
    278     }
    279   }
    280   if (neg) {
    281     Fq2Neg(&Y, &Y);
    282     Fq12Conj(d, d);
    283   }
    284   piOp(&Qp, Q, 1, state);
    285   pair_line(&f, &X, &Y, &Z, &Z2, P, &Qp);
    286   Fq12MulSpecial(d, d, &f);
    287   piOp(&Qp, Q, 2, state);
    288   Fq2Neg(&Qp.y, &Qp.y);
    289   pair_line(&f, &X, &Y, &Z, &Z2, P, &Qp);
    290   Fq12MulSpecial(d, d, &f);
    291   finalExp(d, state);
    292   // s doesn't have secret information; no need to clear it.
    293   Fq12Clear(&f);
    294   Fq2Clear(&X);
    295   Fq2Clear(&Y);
    296   Fq2Clear(&Z);
    297   Fq2Clear(&Z2);
    298   Fq2Clear(&Qp.x);
    299   Fq2Clear(&Qp.y);
    300 }
    301