Files
MP-SPDZ/Math/Subroutines.cpp
2019-06-07 15:26:28 +10:00

115 lines
2.7 KiB
C++

#include "Subroutines.h"
#include "modp.h"
#include "modp.hpp"
void Subs(modp& ans,const vector<int>& poly,const modp& x,const Zp_Data& ZpD)
{
modp one,co;
assignOne(one,ZpD);
assignZero(ans,ZpD);
for (int i=poly.size()-1; i>=0; i--)
{ Mul(ans,ans,x,ZpD);
switch (poly[i])
{ case 0:
break;
case 1:
Add(ans,ans,one,ZpD);
break;
case -1:
Sub(ans,ans,one,ZpD);
break;
case 2:
Add(ans,ans,one,ZpD);
Add(ans,ans,one,ZpD);
break;
case -2:
Sub(ans,ans,one,ZpD);
Sub(ans,ans,one,ZpD);
break;
case 3:
Add(ans,ans,one,ZpD);
Add(ans,ans,one,ZpD);
Add(ans,ans,one,ZpD);
break;
case -3:
Sub(ans,ans,one,ZpD);
Sub(ans,ans,one,ZpD);
Sub(ans,ans,one,ZpD);
break;
default:
throw not_implemented();
}
}
}
/* Find a m'th primitive root moduli the current prime
* This is deterministic so all players have the same root of unity
* poly is Phi_m(X)
*/
modp Find_Primitive_Root_m(int m,const vector<int>& poly,const Zp_Data& ZpD)
{
modp ans,e,one,base;
assignOne(one,ZpD);
assignOne(base,ZpD);
bigint exp;
exp=(ZpD.pr-1)/m;
bool flag=true;
while (flag)
{ Add(base,base,one,ZpD); // Keep incrementing base until we hit the answer
Power(ans,base,exp,ZpD);
// e=Phi(ans)
Subs(e,poly,ans,ZpD);
if (isZero(e,ZpD)) { flag=false; }
}
return ans;
}
/* Find a (2m)'th primitive root moduli the current prime
* This is deterministic so all players have the same root of unity
* poly is Phi_m(X)
*/
modp Find_Primitive_Root_2m(int m,const vector<int>& poly,const Zp_Data& ZpD)
{
// Thin out poly, where poly is Phi_m(X) by 2
vector<int> poly2;
poly2.resize(2*poly.size());
for (unsigned int i=0; i<poly.size(); i++)
{ poly2[2*i]=poly[i];
poly2[2*i+1]=0;
}
modp ans=Find_Primitive_Root_m(2*m,poly2,ZpD);
return ans;
}
/* Find an mth primitive root moduli the current prime
* This is deterministic so all players have the same root of unity
* This assumes m is a power of two and so the cyclotomic polynomial
* is F=X^{m/2}+1
*/
modp Find_Primitive_Root_2power(int m,const Zp_Data& ZpD)
{
modp ans,e,one,base;
assignOne(one,ZpD);
assignOne(base,ZpD);
bigint exp;
exp=(ZpD.pr-1)/m;
bool flag=true;
while (flag)
{ Add(base,base,one,ZpD); // Keep incrementing base until we hit the answer
Power(ans,base,exp,ZpD);
// e=ans^{m/2}+1
Power(e,ans,m/2,ZpD);
Add(e,e,one,ZpD);
if (isZero(e,ZpD)) { flag=false; }
}
return ans;
}