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 Fq12 math
     17 /*! \file */
     18 
     19 #include "epid/member/tiny/math/fq12.h"
     20 
     21 #include "epid/member/tiny/math/fq.h"
     22 #include "epid/member/tiny/math/fq2.h"
     23 #include "epid/member/tiny/math/fq6.h"
     24 #include "epid/member/tiny/math/mathtypes.h"
     25 #include "epid/member/tiny/math/vli.h"
     26 #include "epid/member/tiny/stdlib/tiny_stdlib.h"
     27 
     28 static void Fq12MulScalar(Fq12Elem* result, Fq12Elem const* left,
     29                           Fq6Elem const* right) {
     30   Fq6Mul(&result->z0, &left->z0, right);
     31   Fq6Mul(&result->z1, &left->z1, right);
     32 }
     33 
     34 static void Fq4Square(Fq2Elem* out0, Fq2Elem* out1, Fq2Elem const* in0,
     35                       Fq2Elem const* in1) {
     36   Fq2Elem tmp;
     37   Fq2Elem* temp = &tmp;
     38   Fq2Square(temp, in1);
     39   Fq2Add(out1, in0, in1);
     40   Fq2Square(out0, in0);
     41   Fq2Square(out1, out1);
     42   Fq2Sub(out1, out1, temp);
     43   Fq2Sub(out1, out1, out0);
     44   Fq2MulXi(temp, temp);
     45   Fq2Add(out0, out0, temp);
     46 }
     47 
     48 static void Fq12CondSet(Fq12Elem* result, Fq12Elem const* true_val,
     49                         Fq12Elem const* false_val, int truth_val) {
     50   Fq6CondSet(&result->z0, &true_val->z0, &false_val->z0, truth_val);
     51   Fq6CondSet(&result->z1, &true_val->z1, &false_val->z1, truth_val);
     52 }
     53 
     54 void Fq12Add(Fq12Elem* result, Fq12Elem const* left, Fq12Elem const* right) {
     55   Fq6Add(&result->z0, &left->z0, &right->z0);
     56   Fq6Add(&result->z1, &left->z1, &right->z1);
     57 }
     58 
     59 void Fq12Sub(Fq12Elem* result, Fq12Elem const* left, Fq12Elem const* right) {
     60   Fq6Sub(&result->z0, &left->z0, &right->z0);
     61   Fq6Sub(&result->z1, &left->z1, &right->z1);
     62 }
     63 
     64 void Fq12Square(Fq12Elem* result, Fq12Elem const* in) {
     65   Fq6Elem tmpa;
     66   Fq6Elem* temp_a = &tmpa;
     67   Fq6Square(temp_a, &in->z1);
     68   Fq6Add(&result->z1, &in->z0, &in->z1);
     69   Fq6Square(&result->z0, &in->z0);
     70   Fq6Square(&result->z1, &result->z1);
     71   Fq6Sub(&result->z1, &result->z1, (&result->z0));
     72   Fq6Sub(&result->z1, &result->z1, temp_a);
     73   Fq6MulV(temp_a, temp_a);
     74   Fq6Add((&result->z0), (&result->z0), temp_a);
     75 }
     76 
     77 void Fq12Mul(Fq12Elem* result, Fq12Elem const* left, Fq12Elem const* right) {
     78   Fq6Elem A;
     79   Fq6Elem B;
     80   Fq6Elem* t0 = &A;
     81   Fq6Elem* t1 = &B;
     82 
     83   Fq6Add(t0, &left->z0, &left->z1);
     84   Fq6Add(t1, &right->z0, &right->z1);
     85   Fq6Mul(t0, t0, t1);
     86   Fq6Mul(&result->z0, &left->z0, &right->z0);
     87   Fq6Sub(t0, t0, &result->z0);
     88   Fq6Mul(t1, &left->z1, &right->z1);
     89   Fq6Sub(&result->z1, t0, t1);
     90   Fq6MulV(t1, t1);
     91   Fq6Add(&result->z0, &result->z0, t1);
     92 }
     93 
     94 void Fq12Inv(Fq12Elem* result, Fq12Elem const* in) {
     95   Fq12Elem tmp3;
     96   Fq12Elem tmp4;
     97   Fq12Elem* const temp3 = &tmp3;
     98   Fq12Elem* const temp4 = &tmp4;
     99   Fq12Conj(temp3, in);
    100   Fq12Mul(temp4, temp3, in);
    101   Fq6Inv(&temp4->z0, &temp4->z0);
    102   Fq12MulScalar(result, temp3, &temp4->z0);
    103 }
    104 
    105 void Fq12Neg(Fq12Elem* result, Fq12Elem const* in) {
    106   Fq6Neg(&result->z0, &in->z0);
    107   Fq6Neg(&result->z1, &in->z1);
    108 }
    109 
    110 void Fq12Set(Fq12Elem* result, uint32_t val) {
    111   Fq12Clear(result);
    112   FqSet(&(*result).z0.y0.x0, val);
    113 }
    114 
    115 void Fq12Exp(Fq12Elem* result, Fq12Elem const* base, VeryLargeInt const* exp) {
    116   int i;
    117   Fq12Elem tmp, tmp2, *const temp = &tmp, *const temp2 = &tmp2;
    118   Fq12Clear(temp);
    119   temp->z0.y0.x0.limbs.word[0]++;
    120   for (i = NUM_ECC_DIGITS * 32 - 1; i >= 0; i--) {
    121     Fq12Square(temp, temp);
    122     Fq12Mul(temp2, temp, base);
    123 
    124     Fq12CondSet(temp, temp2, temp,
    125                 (int)((exp->word[i / 32] >> (i & 31)) & (0x1)));
    126   }
    127   Fq12Cp(result, temp);
    128 }
    129 
    130 void Fq12MultiExp(Fq12Elem* result, Fq12Elem const* base0,
    131                   VeryLargeInt const* exp0, Fq12Elem const* base1,
    132                   VeryLargeInt const* exp1, Fq12Elem const* base2,
    133                   VeryLargeInt const* exp2, Fq12Elem const* base3,
    134                   VeryLargeInt const* exp3) {
    135   Fq12Elem tmp;
    136   Fq12Exp(result, base0, exp0);
    137   Fq12Exp(&tmp, base1, exp1);
    138   Fq12Mul(result, result, &tmp);
    139   Fq12Exp(&tmp, base2, exp2);
    140   Fq12Mul(result, result, &tmp);
    141   Fq12Exp(&tmp, base3, exp3);
    142   Fq12Mul(result, result, &tmp);
    143 }
    144 
    145 int Fq12Eq(Fq12Elem const* left, Fq12Elem const* right) {
    146   return Fq6Eq(&left->z0, &right->z0) && Fq6Eq(&left->z0, &right->z0);
    147 }
    148 
    149 void Fq12Conj(Fq12Elem* result, Fq12Elem const* in) {
    150   Fq6Cp(&result->z0, &in->z0);
    151   Fq6Neg(&result->z1, &in->z1);
    152 }
    153 
    154 void Fq12ExpCyc(Fq12Elem* result, Fq12Elem const* in, VeryLargeInt const* t) {
    155   int i = 0;
    156   Fq12Elem ac;
    157   Fq12Elem* const acc = ∾
    158   Fq12Cp(acc, in);
    159   Fq12Cp(result, in);
    160 
    161   for (i = 61; i >= 0; i--) {
    162     Fq12SqCyc(result, result);
    163 
    164     if (VliTestBit(t, (uint32_t)i)) {
    165       Fq12Mul(result, result, acc);
    166     }
    167   }
    168 }
    169 
    170 void Fq12SqCyc(Fq12Elem* result, Fq12Elem const* in) {
    171   Fq2Elem const* a0 = &(in->z0).y0;
    172   Fq2Elem const* a1 = &(in->z1).y0;
    173   Fq2Elem const* a2 = &(in->z0).y1;
    174   Fq2Elem const* a3 = &(in->z1).y1;
    175   Fq2Elem const* a4 = &(in->z0).y2;
    176   Fq2Elem const* a5 = &(in->z1).y2;
    177   Fq2Elem* e0 = &(result->z0).y0;
    178   Fq2Elem* e1 = &(result->z1).y0;
    179   Fq2Elem* e2 = &(result->z0).y1;
    180   Fq2Elem* e3 = &(result->z1).y1;
    181   Fq2Elem* e4 = &(result->z0).y2;
    182   Fq2Elem* e5 = &(result->z1).y2;
    183   Fq2Elem tmp1;
    184   Fq2Elem tmp2;
    185   Fq2Elem tmp3;
    186   Fq2Elem tmp4;
    187   Fq2Elem* temp1 = &tmp1;
    188   Fq2Elem* temp2 = &tmp2;
    189   Fq2Elem* temp3 = &tmp3;
    190   Fq2Elem* temp4 = &tmp4;
    191 
    192   Fq4Square(temp1, temp2, a0, a3);  // t00,t11 = sq(a0,a3)
    193   Fq2Add(e0, a0, a0);               // e0 = 3*t00 - 2*a0
    194   Fq2Sub(e0, temp1, e0);
    195   Fq2Add(e0, temp1, e0);
    196   Fq2Add(e0, temp1, e0);
    197   Fq2Add(e3, a3, a3);  // e3 = 3*t11 - 2*a3
    198   Fq2Add(e3, temp2, e3);
    199   Fq2Add(e3, temp2, e3);
    200   Fq2Add(e3, temp2, e3);
    201 
    202   Fq4Square(temp1, temp2, a2, a5);  // t02, t10 = sq(a2,a5)
    203   Fq2MulXi(temp2, temp2);
    204   Fq4Square(temp3, temp4, a1, a4);  // t01, t12 = sq(a1,a4)
    205 
    206   Fq2Add(e4, a4, a4);
    207   Fq2Sub(e4, temp1, e4);
    208   Fq2Add(e4, temp1, e4);
    209   Fq2Add(e4, temp1, e4);
    210   Fq2Add(e1, a1, a1);
    211   Fq2Add(e1, temp2, e1);
    212   Fq2Add(e1, temp2, e1);
    213   Fq2Add(e1, temp2, e1);
    214 
    215   Fq2Add(e2, a2, a2);
    216   Fq2Sub(e2, temp3, e2);
    217   Fq2Add(e2, temp3, e2);
    218   Fq2Add(e2, temp3, e2);
    219   Fq2Add(e5, a5, a5);
    220   Fq2Add(e5, temp4, e5);
    221   Fq2Add(e5, temp4, e5);
    222   Fq2Add(e5, temp4, e5);
    223 }
    224 
    225 void Fq12MulSpecial(Fq12Elem* result, Fq12Elem const* left,
    226                     Fq12Elem const* right) {
    227   Fq2Elem T3;
    228   Fq2Elem* t3 = &T3;
    229   Fq2Elem const* b0 = &(right->z0.y0);
    230   Fq2Elem const* b1 = &right->z1.y0;
    231   Fq2Elem const* b3 = &right->z1.y1;
    232   Fq6Elem T0;
    233   Fq6Elem T1;
    234   Fq6Elem T2;
    235   Fq6Elem* t0 = &T0;
    236   Fq6Elem* t1 = &T1;
    237   Fq6Elem* t2 = &T2;
    238   Fq6Elem const* a0 = &left->z0;
    239   Fq6Elem const* a1 = &left->z1;
    240   Fq6Elem* r0 = &result->z0;
    241   Fq6Elem* r1 = &result->z1;
    242 
    243 #if defined(DEBUG)
    244   // validate algorithm precondition
    245   if (!Fq2IsZero(&right->z0.y1) || !Fq2IsZero(&right->z0.y2) ||
    246       !Fq2IsZero(&right->z1.y2)) {
    247     memset(&result, 0xff, sizeof(result));
    248     return;
    249   }
    250 #endif  // defined(DEBUG)
    251 
    252   Fq6Add(t0, a0, a1);
    253   Fq2Add(t3, b0, b1);
    254   Fq6MulScalar(t0, t0, t3);
    255 
    256   Fq6MulScalar(t2, a1, b3);
    257   Fq6MulV(t2, t2);
    258 
    259   Fq6MulScalar(t1, a1, b1);
    260   Fq6Sub(t0, t0, t1);
    261   Fq6Add(t2, t2, t1);
    262   Fq6MulV(t2, t2);
    263 
    264   Fq6MulScalar(t1, a0, b0);
    265   Fq6Add(t2, t2, t1);
    266   Fq6Sub(t0, t0, t1);
    267 
    268   Fq6MulScalar(t1, a0, b3);
    269   Fq6MulV(t1, t1);
    270   Fq6Add(r1, t1, t0);
    271   Fq6Cp(r0, t2);
    272 }
    273 
    274 void Fq12Cp(Fq12Elem* result, Fq12Elem const* in) {
    275   Fq6Cp(&result->z0, &in->z0);
    276   Fq6Cp(&result->z1, &in->z1);
    277 }
    278 
    279 void Fq12Clear(Fq12Elem* result) {
    280   Fq6Clear(&result->z0);
    281   Fq6Clear(&result->z1);
    282 }
    283