unused
This commit is contained in:
@@ -1,32 +0,0 @@
|
|||||||
// hex.cpp - written and placed in the public domain by Wei Dai
|
|
||||||
|
|
||||||
#include "pch.h"
|
|
||||||
#include "hex.h"
|
|
||||||
|
|
||||||
NAMESPACE_BEGIN(CryptoPP)
|
|
||||||
|
|
||||||
static const byte s_vecUpper[] = "0123456789ABCDEF";
|
|
||||||
static const byte s_vecLower[] = "0123456789abcdef";
|
|
||||||
|
|
||||||
void HexEncoder::IsolatedInitialize(const NameValuePairs ¶meters)
|
|
||||||
{
|
|
||||||
bool uppercase = parameters.GetValueWithDefault("Uppercase", true);
|
|
||||||
m_filter->Initialize(CombinedNameValuePairs(
|
|
||||||
parameters,
|
|
||||||
MakeParameters("EncodingLookupArray", uppercase ? &s_vecUpper[0] : &s_vecLower[0])("Log2Base", 4)));
|
|
||||||
}
|
|
||||||
|
|
||||||
const int *HexDecoder::GetDecodingLookupArray()
|
|
||||||
{
|
|
||||||
static bool s_initialized = false;
|
|
||||||
static int s_array[256];
|
|
||||||
|
|
||||||
if (!s_initialized)
|
|
||||||
{
|
|
||||||
InitializeDecodingLookupArray(s_array, s_vecUpper, 16, true);
|
|
||||||
s_initialized = true;
|
|
||||||
}
|
|
||||||
return s_array;
|
|
||||||
}
|
|
||||||
|
|
||||||
NAMESPACE_END
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
#ifndef CRYPTOPP_HEX_H
|
|
||||||
#define CRYPTOPP_HEX_H
|
|
||||||
|
|
||||||
#include "basecode.h"
|
|
||||||
|
|
||||||
NAMESPACE_BEGIN(CryptoPP)
|
|
||||||
|
|
||||||
//! Converts given data to base 16
|
|
||||||
class HexEncoder : public SimpleProxyFilter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
HexEncoder(BufferedTransformation *attachment = NULL, bool uppercase = true, int outputGroupSize = 0, const std::string &separator = ":", const std::string &terminator = "")
|
|
||||||
: SimpleProxyFilter(new BaseN_Encoder(new Grouper), attachment)
|
|
||||||
{
|
|
||||||
IsolatedInitialize(MakeParameters("Uppercase", uppercase)("GroupSize", outputGroupSize)("Separator", ConstByteArrayParameter(separator)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void IsolatedInitialize(const NameValuePairs ¶meters);
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Decode base 16 data back to bytes
|
|
||||||
class HexDecoder : public BaseN_Decoder
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
HexDecoder(BufferedTransformation *attachment = NULL)
|
|
||||||
: BaseN_Decoder(GetDecodingLookupArray(), 4, attachment) {}
|
|
||||||
|
|
||||||
void IsolatedInitialize(const NameValuePairs ¶meters) {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static const int *GetDecodingLookupArray();
|
|
||||||
};
|
|
||||||
|
|
||||||
NAMESPACE_END
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,579 +0,0 @@
|
|||||||
// polynomi.cpp - written and placed in the public domain by Wei Dai
|
|
||||||
|
|
||||||
// Part of the code for polynomial evaluation and interpolation
|
|
||||||
// originally came from Hal Finney's public domain secsplit.c.
|
|
||||||
|
|
||||||
#include "pch.h"
|
|
||||||
#include "polynomi.h"
|
|
||||||
#include "secblock.h"
|
|
||||||
|
|
||||||
#include <strstream>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
NAMESPACE_BEGIN(CryptoPP)
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void PolynomialOver<T>::Randomize(RandomNumberGenerator &rng, const RandomizationParameter ¶meter, const Ring &ring)
|
|
||||||
{
|
|
||||||
m_coefficients.resize(parameter.m_coefficientCount);
|
|
||||||
for (unsigned int i=0; i<m_coefficients.size(); ++i)
|
|
||||||
m_coefficients[i] = ring.RandomElement(rng, parameter.m_coefficientParameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void PolynomialOver<T>::FromStr(const char *str, const Ring &ring)
|
|
||||||
{
|
|
||||||
std::istrstream in((char *)str);
|
|
||||||
bool positive = true;
|
|
||||||
CoefficientType coef;
|
|
||||||
unsigned int power;
|
|
||||||
|
|
||||||
while (in)
|
|
||||||
{
|
|
||||||
std::ws(in);
|
|
||||||
if (in.peek() == 'x')
|
|
||||||
coef = ring.MultiplicativeIdentity();
|
|
||||||
else
|
|
||||||
in >> coef;
|
|
||||||
|
|
||||||
std::ws(in);
|
|
||||||
if (in.peek() == 'x')
|
|
||||||
{
|
|
||||||
in.get();
|
|
||||||
std::ws(in);
|
|
||||||
if (in.peek() == '^')
|
|
||||||
{
|
|
||||||
in.get();
|
|
||||||
in >> power;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
power = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
power = 0;
|
|
||||||
|
|
||||||
if (!positive)
|
|
||||||
coef = ring.Inverse(coef);
|
|
||||||
|
|
||||||
SetCoefficient(power, coef, ring);
|
|
||||||
|
|
||||||
std::ws(in);
|
|
||||||
switch (in.get())
|
|
||||||
{
|
|
||||||
case '+':
|
|
||||||
positive = true;
|
|
||||||
break;
|
|
||||||
case '-':
|
|
||||||
positive = false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return; // something's wrong with the input string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
unsigned int PolynomialOver<T>::CoefficientCount(const Ring &ring) const
|
|
||||||
{
|
|
||||||
unsigned count = m_coefficients.size();
|
|
||||||
while (count && ring.Equal(m_coefficients[count-1], ring.Identity()))
|
|
||||||
count--;
|
|
||||||
const_cast<std::vector<CoefficientType> &>(m_coefficients).resize(count);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
typename PolynomialOver<T>::CoefficientType PolynomialOver<T>::GetCoefficient(unsigned int i, const Ring &ring) const
|
|
||||||
{
|
|
||||||
return (i < m_coefficients.size()) ? m_coefficients[i] : ring.Identity();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
PolynomialOver<T>& PolynomialOver<T>::operator=(const PolynomialOver<T>& t)
|
|
||||||
{
|
|
||||||
if (this != &t)
|
|
||||||
{
|
|
||||||
m_coefficients.resize(t.m_coefficients.size());
|
|
||||||
for (unsigned int i=0; i<m_coefficients.size(); i++)
|
|
||||||
m_coefficients[i] = t.m_coefficients[i];
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
PolynomialOver<T>& PolynomialOver<T>::Accumulate(const PolynomialOver<T>& t, const Ring &ring)
|
|
||||||
{
|
|
||||||
unsigned int count = t.CoefficientCount(ring);
|
|
||||||
|
|
||||||
if (count > CoefficientCount(ring))
|
|
||||||
m_coefficients.resize(count, ring.Identity());
|
|
||||||
|
|
||||||
for (unsigned int i=0; i<count; i++)
|
|
||||||
ring.Accumulate(m_coefficients[i], t.GetCoefficient(i, ring));
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
PolynomialOver<T>& PolynomialOver<T>::Reduce(const PolynomialOver<T>& t, const Ring &ring)
|
|
||||||
{
|
|
||||||
unsigned int count = t.CoefficientCount(ring);
|
|
||||||
|
|
||||||
if (count > CoefficientCount(ring))
|
|
||||||
m_coefficients.resize(count, ring.Identity());
|
|
||||||
|
|
||||||
for (unsigned int i=0; i<count; i++)
|
|
||||||
ring.Reduce(m_coefficients[i], t.GetCoefficient(i, ring));
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
typename PolynomialOver<T>::CoefficientType PolynomialOver<T>::EvaluateAt(const CoefficientType &x, const Ring &ring) const
|
|
||||||
{
|
|
||||||
int degree = Degree(ring);
|
|
||||||
|
|
||||||
if (degree < 0)
|
|
||||||
return ring.Identity();
|
|
||||||
|
|
||||||
CoefficientType result = m_coefficients[degree];
|
|
||||||
for (int j=degree-1; j>=0; j--)
|
|
||||||
{
|
|
||||||
result = ring.Multiply(result, x);
|
|
||||||
ring.Accumulate(result, m_coefficients[j]);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
PolynomialOver<T>& PolynomialOver<T>::ShiftLeft(unsigned int n, const Ring &ring)
|
|
||||||
{
|
|
||||||
unsigned int i = CoefficientCount(ring) + n;
|
|
||||||
m_coefficients.resize(i, ring.Identity());
|
|
||||||
while (i > n)
|
|
||||||
{
|
|
||||||
i--;
|
|
||||||
m_coefficients[i] = m_coefficients[i-n];
|
|
||||||
}
|
|
||||||
while (i)
|
|
||||||
{
|
|
||||||
i--;
|
|
||||||
m_coefficients[i] = ring.Identity();
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
PolynomialOver<T>& PolynomialOver<T>::ShiftRight(unsigned int n, const Ring &ring)
|
|
||||||
{
|
|
||||||
unsigned int count = CoefficientCount(ring);
|
|
||||||
if (count > n)
|
|
||||||
{
|
|
||||||
for (unsigned int i=0; i<count-n; i++)
|
|
||||||
m_coefficients[i] = m_coefficients[i+n];
|
|
||||||
m_coefficients.resize(count-n, ring.Identity());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_coefficients.resize(0, ring.Identity());
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void PolynomialOver<T>::SetCoefficient(unsigned int i, const CoefficientType &value, const Ring &ring)
|
|
||||||
{
|
|
||||||
if (i >= m_coefficients.size())
|
|
||||||
m_coefficients.resize(i+1, ring.Identity());
|
|
||||||
m_coefficients[i] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void PolynomialOver<T>::Negate(const Ring &ring)
|
|
||||||
{
|
|
||||||
unsigned int count = CoefficientCount(ring);
|
|
||||||
for (unsigned int i=0; i<count; i++)
|
|
||||||
m_coefficients[i] = ring.Inverse(m_coefficients[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void PolynomialOver<T>::swap(PolynomialOver<T> &t)
|
|
||||||
{
|
|
||||||
m_coefficients.swap(t.m_coefficients);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
bool PolynomialOver<T>::Equals(const PolynomialOver<T>& t, const Ring &ring) const
|
|
||||||
{
|
|
||||||
unsigned int count = CoefficientCount(ring);
|
|
||||||
|
|
||||||
if (count != t.CoefficientCount(ring))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (unsigned int i=0; i<count; i++)
|
|
||||||
if (!ring.Equal(m_coefficients[i], t.m_coefficients[i]))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
PolynomialOver<T> PolynomialOver<T>::Plus(const PolynomialOver<T>& t, const Ring &ring) const
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
unsigned int count = CoefficientCount(ring);
|
|
||||||
unsigned int tCount = t.CoefficientCount(ring);
|
|
||||||
|
|
||||||
if (count > tCount)
|
|
||||||
{
|
|
||||||
PolynomialOver<T> result(ring, count);
|
|
||||||
|
|
||||||
for (i=0; i<tCount; i++)
|
|
||||||
result.m_coefficients[i] = ring.Add(m_coefficients[i], t.m_coefficients[i]);
|
|
||||||
for (; i<count; i++)
|
|
||||||
result.m_coefficients[i] = m_coefficients[i];
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PolynomialOver<T> result(ring, tCount);
|
|
||||||
|
|
||||||
for (i=0; i<count; i++)
|
|
||||||
result.m_coefficients[i] = ring.Add(m_coefficients[i], t.m_coefficients[i]);
|
|
||||||
for (; i<tCount; i++)
|
|
||||||
result.m_coefficients[i] = t.m_coefficients[i];
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
PolynomialOver<T> PolynomialOver<T>::Minus(const PolynomialOver<T>& t, const Ring &ring) const
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
unsigned int count = CoefficientCount(ring);
|
|
||||||
unsigned int tCount = t.CoefficientCount(ring);
|
|
||||||
|
|
||||||
if (count > tCount)
|
|
||||||
{
|
|
||||||
PolynomialOver<T> result(ring, count);
|
|
||||||
|
|
||||||
for (i=0; i<tCount; i++)
|
|
||||||
result.m_coefficients[i] = ring.Subtract(m_coefficients[i], t.m_coefficients[i]);
|
|
||||||
for (; i<count; i++)
|
|
||||||
result.m_coefficients[i] = m_coefficients[i];
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PolynomialOver<T> result(ring, tCount);
|
|
||||||
|
|
||||||
for (i=0; i<count; i++)
|
|
||||||
result.m_coefficients[i] = ring.Subtract(m_coefficients[i], t.m_coefficients[i]);
|
|
||||||
for (; i<tCount; i++)
|
|
||||||
result.m_coefficients[i] = ring.Inverse(t.m_coefficients[i]);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
PolynomialOver<T> PolynomialOver<T>::Inverse(const Ring &ring) const
|
|
||||||
{
|
|
||||||
unsigned int count = CoefficientCount(ring);
|
|
||||||
PolynomialOver<T> result(ring, count);
|
|
||||||
|
|
||||||
for (unsigned int i=0; i<count; i++)
|
|
||||||
result.m_coefficients[i] = ring.Inverse(m_coefficients[i]);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
PolynomialOver<T> PolynomialOver<T>::Times(const PolynomialOver<T>& t, const Ring &ring) const
|
|
||||||
{
|
|
||||||
if (IsZero(ring) || t.IsZero(ring))
|
|
||||||
return PolynomialOver<T>();
|
|
||||||
|
|
||||||
unsigned int count1 = CoefficientCount(ring), count2 = t.CoefficientCount(ring);
|
|
||||||
PolynomialOver<T> result(ring, count1 + count2 - 1);
|
|
||||||
|
|
||||||
for (unsigned int i=0; i<count1; i++)
|
|
||||||
for (unsigned int j=0; j<count2; j++)
|
|
||||||
ring.Accumulate(result.m_coefficients[i+j], ring.Multiply(m_coefficients[i], t.m_coefficients[j]));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
PolynomialOver<T> PolynomialOver<T>::DividedBy(const PolynomialOver<T>& t, const Ring &ring) const
|
|
||||||
{
|
|
||||||
PolynomialOver<T> remainder, quotient;
|
|
||||||
Divide(remainder, quotient, *this, t, ring);
|
|
||||||
return quotient;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
PolynomialOver<T> PolynomialOver<T>::Modulo(const PolynomialOver<T>& t, const Ring &ring) const
|
|
||||||
{
|
|
||||||
PolynomialOver<T> remainder, quotient;
|
|
||||||
Divide(remainder, quotient, *this, t, ring);
|
|
||||||
return remainder;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
PolynomialOver<T> PolynomialOver<T>::MultiplicativeInverse(const Ring &ring) const
|
|
||||||
{
|
|
||||||
return Degree(ring)==0 ? ring.MultiplicativeInverse(m_coefficients[0]) : ring.Identity();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
bool PolynomialOver<T>::IsUnit(const Ring &ring) const
|
|
||||||
{
|
|
||||||
return Degree(ring)==0 && ring.IsUnit(m_coefficients[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
std::istream& PolynomialOver<T>::Input(std::istream &in, const Ring &ring)
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
unsigned int length = 0;
|
|
||||||
SecBlock<char> str(length + 16);
|
|
||||||
bool paren = false;
|
|
||||||
|
|
||||||
std::ws(in);
|
|
||||||
|
|
||||||
if (in.peek() == '(')
|
|
||||||
{
|
|
||||||
paren = true;
|
|
||||||
in.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
in.read(&c, 1);
|
|
||||||
str[length++] = c;
|
|
||||||
if (length >= str.size())
|
|
||||||
str.Grow(length + 16);
|
|
||||||
}
|
|
||||||
// if we started with a left paren, then read until we find a right paren,
|
|
||||||
// otherwise read until the end of the line
|
|
||||||
while (in && ((paren && c != ')') || (!paren && c != '\n')));
|
|
||||||
|
|
||||||
str[length-1] = '\0';
|
|
||||||
*this = PolynomialOver<T>(str, ring);
|
|
||||||
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
std::ostream& PolynomialOver<T>::Output(std::ostream &out, const Ring &ring) const
|
|
||||||
{
|
|
||||||
unsigned int i = CoefficientCount(ring);
|
|
||||||
if (i)
|
|
||||||
{
|
|
||||||
bool firstTerm = true;
|
|
||||||
|
|
||||||
while (i--)
|
|
||||||
{
|
|
||||||
if (m_coefficients[i] != ring.Identity())
|
|
||||||
{
|
|
||||||
if (firstTerm)
|
|
||||||
{
|
|
||||||
firstTerm = false;
|
|
||||||
if (!i || !ring.Equal(m_coefficients[i], ring.MultiplicativeIdentity()))
|
|
||||||
out << m_coefficients[i];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CoefficientType inverse = ring.Inverse(m_coefficients[i]);
|
|
||||||
std::ostrstream pstr, nstr;
|
|
||||||
|
|
||||||
pstr << m_coefficients[i];
|
|
||||||
nstr << inverse;
|
|
||||||
|
|
||||||
if (pstr.pcount() <= nstr.pcount())
|
|
||||||
{
|
|
||||||
out << " + ";
|
|
||||||
if (!i || !ring.Equal(m_coefficients[i], ring.MultiplicativeIdentity()))
|
|
||||||
out << m_coefficients[i];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
out << " - ";
|
|
||||||
if (!i || !ring.Equal(inverse, ring.MultiplicativeIdentity()))
|
|
||||||
out << inverse;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (i)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
out << "x";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
out << "x^" << i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
out << ring.Identity();
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void PolynomialOver<T>::Divide(PolynomialOver<T> &r, PolynomialOver<T> &q, const PolynomialOver<T> &a, const PolynomialOver<T> &d, const Ring &ring)
|
|
||||||
{
|
|
||||||
unsigned int i = a.CoefficientCount(ring);
|
|
||||||
const int dDegree = d.Degree(ring);
|
|
||||||
|
|
||||||
if (dDegree < 0)
|
|
||||||
throw DivideByZero();
|
|
||||||
|
|
||||||
r = a;
|
|
||||||
q.m_coefficients.resize(STDMAX(0, int(i - dDegree)));
|
|
||||||
|
|
||||||
while (i > (unsigned int)dDegree)
|
|
||||||
{
|
|
||||||
--i;
|
|
||||||
q.m_coefficients[i-dDegree] = ring.Divide(r.m_coefficients[i], d.m_coefficients[dDegree]);
|
|
||||||
for (int j=0; j<=dDegree; j++)
|
|
||||||
ring.Reduce(r.m_coefficients[i-dDegree+j], ring.Multiply(q.m_coefficients[i-dDegree], d.m_coefficients[j]));
|
|
||||||
}
|
|
||||||
|
|
||||||
r.CoefficientCount(ring); // resize r.m_coefficients
|
|
||||||
}
|
|
||||||
|
|
||||||
// ********************************************************
|
|
||||||
|
|
||||||
// helper function for Interpolate() and InterpolateAt()
|
|
||||||
template <class T>
|
|
||||||
void RingOfPolynomialsOver<T>::CalculateAlpha(std::vector<CoefficientType> &alpha, const CoefficientType x[], const CoefficientType y[], unsigned int n) const
|
|
||||||
{
|
|
||||||
for (unsigned int j=0; j<n; ++j)
|
|
||||||
alpha[j] = y[j];
|
|
||||||
|
|
||||||
for (unsigned int k=1; k<n; ++k)
|
|
||||||
{
|
|
||||||
for (unsigned int j=n-1; j>=k; --j)
|
|
||||||
{
|
|
||||||
m_ring.Reduce(alpha[j], alpha[j-1]);
|
|
||||||
|
|
||||||
CoefficientType d = m_ring.Subtract(x[j], x[j-k]);
|
|
||||||
if (!m_ring.IsUnit(d))
|
|
||||||
throw InterpolationFailed();
|
|
||||||
alpha[j] = m_ring.Divide(alpha[j], d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
typename RingOfPolynomialsOver<T>::Element RingOfPolynomialsOver<T>::Interpolate(const CoefficientType x[], const CoefficientType y[], unsigned int n) const
|
|
||||||
{
|
|
||||||
assert(n > 0);
|
|
||||||
|
|
||||||
std::vector<CoefficientType> alpha(n);
|
|
||||||
CalculateAlpha(alpha, x, y, n);
|
|
||||||
|
|
||||||
std::vector<CoefficientType> coefficients((size_t)n, m_ring.Identity());
|
|
||||||
coefficients[0] = alpha[n-1];
|
|
||||||
|
|
||||||
for (int j=n-2; j>=0; --j)
|
|
||||||
{
|
|
||||||
for (unsigned int i=n-j-1; i>0; i--)
|
|
||||||
coefficients[i] = m_ring.Subtract(coefficients[i-1], m_ring.Multiply(coefficients[i], x[j]));
|
|
||||||
|
|
||||||
coefficients[0] = m_ring.Subtract(alpha[j], m_ring.Multiply(coefficients[0], x[j]));
|
|
||||||
}
|
|
||||||
|
|
||||||
return PolynomialOver<T>(coefficients.begin(), coefficients.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
typename RingOfPolynomialsOver<T>::CoefficientType RingOfPolynomialsOver<T>::InterpolateAt(const CoefficientType &position, const CoefficientType x[], const CoefficientType y[], unsigned int n) const
|
|
||||||
{
|
|
||||||
assert(n > 0);
|
|
||||||
|
|
||||||
std::vector<CoefficientType> alpha(n);
|
|
||||||
CalculateAlpha(alpha, x, y, n);
|
|
||||||
|
|
||||||
CoefficientType result = alpha[n-1];
|
|
||||||
for (int j=n-2; j>=0; --j)
|
|
||||||
{
|
|
||||||
result = m_ring.Multiply(result, m_ring.Subtract(position, x[j]));
|
|
||||||
m_ring.Accumulate(result, alpha[j]);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Ring, class Element>
|
|
||||||
void PrepareBulkPolynomialInterpolation(const Ring &ring, Element *w, const Element x[], unsigned int n)
|
|
||||||
{
|
|
||||||
for (unsigned int i=0; i<n; i++)
|
|
||||||
{
|
|
||||||
Element t = ring.MultiplicativeIdentity();
|
|
||||||
for (unsigned int j=0; j<n; j++)
|
|
||||||
if (i != j)
|
|
||||||
t = ring.Multiply(t, ring.Subtract(x[i], x[j]));
|
|
||||||
w[i] = ring.MultiplicativeInverse(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Ring, class Element>
|
|
||||||
void PrepareBulkPolynomialInterpolationAt(const Ring &ring, Element *v, const Element &position, const Element x[], const Element w[], unsigned int n)
|
|
||||||
{
|
|
||||||
assert(n > 0);
|
|
||||||
|
|
||||||
std::vector<Element> a(2*n-1);
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i=0; i<n; i++)
|
|
||||||
a[n-1+i] = ring.Subtract(position, x[i]);
|
|
||||||
|
|
||||||
for (i=n-1; i>1; i--)
|
|
||||||
a[i-1] = ring.Multiply(a[2*i], a[2*i-1]);
|
|
||||||
|
|
||||||
a[0] = ring.MultiplicativeIdentity();
|
|
||||||
|
|
||||||
for (i=0; i<n-1; i++)
|
|
||||||
{
|
|
||||||
std::swap(a[2*i+1], a[2*i+2]);
|
|
||||||
a[2*i+1] = ring.Multiply(a[i], a[2*i+1]);
|
|
||||||
a[2*i+2] = ring.Multiply(a[i], a[2*i+2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i<n; i++)
|
|
||||||
v[i] = ring.Multiply(a[n-1+i], w[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Ring, class Element>
|
|
||||||
Element BulkPolynomialInterpolateAt(const Ring &ring, const Element y[], const Element v[], unsigned int n)
|
|
||||||
{
|
|
||||||
Element result = ring.Identity();
|
|
||||||
for (unsigned int i=0; i<n; i++)
|
|
||||||
ring.Accumulate(result, ring.Multiply(y[i], v[i]));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ********************************************************
|
|
||||||
|
|
||||||
template <class T, int instance>
|
|
||||||
const PolynomialOverFixedRing<T, instance> &PolynomialOverFixedRing<T, instance>::Zero()
|
|
||||||
{
|
|
||||||
static const PolynomialOverFixedRing<T, instance> zero;
|
|
||||||
return zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, int instance>
|
|
||||||
const PolynomialOverFixedRing<T, instance> &PolynomialOverFixedRing<T, instance>::One()
|
|
||||||
{
|
|
||||||
static const PolynomialOverFixedRing<T, instance> one = fixedRing.MultiplicativeIdentity();
|
|
||||||
return one;
|
|
||||||
}
|
|
||||||
|
|
||||||
NAMESPACE_END
|
|
||||||
@@ -1,451 +0,0 @@
|
|||||||
#ifndef CRYPTOPP_POLYNOMI_H
|
|
||||||
#define CRYPTOPP_POLYNOMI_H
|
|
||||||
|
|
||||||
/*! \file */
|
|
||||||
|
|
||||||
#include "cryptlib.h"
|
|
||||||
#include "misc.h"
|
|
||||||
#include "algebra.h"
|
|
||||||
|
|
||||||
#include <iosfwd>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
NAMESPACE_BEGIN(CryptoPP)
|
|
||||||
|
|
||||||
//! represents single-variable polynomials over arbitrary rings
|
|
||||||
/*! \nosubgrouping */
|
|
||||||
template <class T> class PolynomialOver
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
//! \name ENUMS, EXCEPTIONS, and TYPEDEFS
|
|
||||||
//@{
|
|
||||||
//! division by zero exception
|
|
||||||
class DivideByZero : public Exception
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DivideByZero() : Exception(OTHER_ERROR, "PolynomialOver<T>: division by zero") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! specify the distribution for randomization functions
|
|
||||||
class RandomizationParameter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RandomizationParameter(unsigned int coefficientCount, const typename T::RandomizationParameter &coefficientParameter )
|
|
||||||
: m_coefficientCount(coefficientCount), m_coefficientParameter(coefficientParameter) {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned int m_coefficientCount;
|
|
||||||
typename T::RandomizationParameter m_coefficientParameter;
|
|
||||||
friend class PolynomialOver<T>;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef T Ring;
|
|
||||||
typedef typename T::Element CoefficientType;
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//! \name CREATORS
|
|
||||||
//@{
|
|
||||||
//! creates the zero polynomial
|
|
||||||
PolynomialOver() {}
|
|
||||||
|
|
||||||
//!
|
|
||||||
PolynomialOver(const Ring &ring, unsigned int count)
|
|
||||||
: m_coefficients((size_t)count, ring.Identity()) {}
|
|
||||||
|
|
||||||
//! copy constructor
|
|
||||||
PolynomialOver(const PolynomialOver<Ring> &t)
|
|
||||||
: m_coefficients(t.m_coefficients.size()) {*this = t;}
|
|
||||||
|
|
||||||
//! construct constant polynomial
|
|
||||||
PolynomialOver(const CoefficientType &element)
|
|
||||||
: m_coefficients(1, element) {}
|
|
||||||
|
|
||||||
//! construct polynomial with specified coefficients, starting from coefficient of x^0
|
|
||||||
template <typename Iterator> PolynomialOver(Iterator begin, Iterator end)
|
|
||||||
: m_coefficients(begin, end) {}
|
|
||||||
|
|
||||||
//! convert from string
|
|
||||||
PolynomialOver(const char *str, const Ring &ring) {FromStr(str, ring);}
|
|
||||||
|
|
||||||
//! convert from big-endian byte array
|
|
||||||
PolynomialOver(const byte *encodedPolynomialOver, unsigned int byteCount);
|
|
||||||
|
|
||||||
//! convert from Basic Encoding Rules encoded byte array
|
|
||||||
explicit PolynomialOver(const byte *BEREncodedPolynomialOver);
|
|
||||||
|
|
||||||
//! convert from BER encoded byte array stored in a BufferedTransformation object
|
|
||||||
explicit PolynomialOver(BufferedTransformation &bt);
|
|
||||||
|
|
||||||
//! create a random PolynomialOver<T>
|
|
||||||
PolynomialOver(RandomNumberGenerator &rng, const RandomizationParameter ¶meter, const Ring &ring)
|
|
||||||
{Randomize(rng, parameter, ring);}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//! \name ACCESSORS
|
|
||||||
//@{
|
|
||||||
//! the zero polynomial will return a degree of -1
|
|
||||||
int Degree(const Ring &ring) const {return int(CoefficientCount(ring))-1;}
|
|
||||||
//!
|
|
||||||
unsigned int CoefficientCount(const Ring &ring) const;
|
|
||||||
//! return coefficient for x^i
|
|
||||||
CoefficientType GetCoefficient(unsigned int i, const Ring &ring) const;
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//! \name MANIPULATORS
|
|
||||||
//@{
|
|
||||||
//!
|
|
||||||
PolynomialOver<Ring>& operator=(const PolynomialOver<Ring>& t);
|
|
||||||
|
|
||||||
//!
|
|
||||||
void Randomize(RandomNumberGenerator &rng, const RandomizationParameter ¶meter, const Ring &ring);
|
|
||||||
|
|
||||||
//! set the coefficient for x^i to value
|
|
||||||
void SetCoefficient(unsigned int i, const CoefficientType &value, const Ring &ring);
|
|
||||||
|
|
||||||
//!
|
|
||||||
void Negate(const Ring &ring);
|
|
||||||
|
|
||||||
//!
|
|
||||||
void swap(PolynomialOver<Ring> &t);
|
|
||||||
//@}
|
|
||||||
|
|
||||||
|
|
||||||
//! \name BASIC ARITHMETIC ON POLYNOMIALS
|
|
||||||
//@{
|
|
||||||
bool Equals(const PolynomialOver<Ring> &t, const Ring &ring) const;
|
|
||||||
bool IsZero(const Ring &ring) const {return CoefficientCount(ring)==0;}
|
|
||||||
|
|
||||||
PolynomialOver<Ring> Plus(const PolynomialOver<Ring>& t, const Ring &ring) const;
|
|
||||||
PolynomialOver<Ring> Minus(const PolynomialOver<Ring>& t, const Ring &ring) const;
|
|
||||||
PolynomialOver<Ring> Inverse(const Ring &ring) const;
|
|
||||||
|
|
||||||
PolynomialOver<Ring> Times(const PolynomialOver<Ring>& t, const Ring &ring) const;
|
|
||||||
PolynomialOver<Ring> DividedBy(const PolynomialOver<Ring>& t, const Ring &ring) const;
|
|
||||||
PolynomialOver<Ring> Modulo(const PolynomialOver<Ring>& t, const Ring &ring) const;
|
|
||||||
PolynomialOver<Ring> MultiplicativeInverse(const Ring &ring) const;
|
|
||||||
bool IsUnit(const Ring &ring) const;
|
|
||||||
|
|
||||||
PolynomialOver<Ring>& Accumulate(const PolynomialOver<Ring>& t, const Ring &ring);
|
|
||||||
PolynomialOver<Ring>& Reduce(const PolynomialOver<Ring>& t, const Ring &ring);
|
|
||||||
|
|
||||||
//!
|
|
||||||
PolynomialOver<Ring> Doubled(const Ring &ring) const {return Plus(*this, ring);}
|
|
||||||
//!
|
|
||||||
PolynomialOver<Ring> Squared(const Ring &ring) const {return Times(*this, ring);}
|
|
||||||
|
|
||||||
CoefficientType EvaluateAt(const CoefficientType &x, const Ring &ring) const;
|
|
||||||
|
|
||||||
PolynomialOver<Ring>& ShiftLeft(unsigned int n, const Ring &ring);
|
|
||||||
PolynomialOver<Ring>& ShiftRight(unsigned int n, const Ring &ring);
|
|
||||||
|
|
||||||
//! calculate r and q such that (a == d*q + r) && (0 <= degree of r < degree of d)
|
|
||||||
static void Divide(PolynomialOver<Ring> &r, PolynomialOver<Ring> &q, const PolynomialOver<Ring> &a, const PolynomialOver<Ring> &d, const Ring &ring);
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//! \name INPUT/OUTPUT
|
|
||||||
//@{
|
|
||||||
std::istream& Input(std::istream &in, const Ring &ring);
|
|
||||||
std::ostream& Output(std::ostream &out, const Ring &ring) const;
|
|
||||||
//@}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void FromStr(const char *str, const Ring &ring);
|
|
||||||
|
|
||||||
std::vector<CoefficientType> m_coefficients;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Polynomials over a fixed ring
|
|
||||||
/*! Having a fixed ring allows overloaded operators */
|
|
||||||
template <class T, int instance> class PolynomialOverFixedRing : private PolynomialOver<T>
|
|
||||||
{
|
|
||||||
typedef PolynomialOver<T> B;
|
|
||||||
typedef PolynomialOverFixedRing<T, instance> ThisType;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef T Ring;
|
|
||||||
typedef typename T::Element CoefficientType;
|
|
||||||
typedef typename B::DivideByZero DivideByZero;
|
|
||||||
typedef typename B::RandomizationParameter RandomizationParameter;
|
|
||||||
|
|
||||||
//! \name CREATORS
|
|
||||||
//@{
|
|
||||||
//! creates the zero polynomial
|
|
||||||
PolynomialOverFixedRing(unsigned int count = 0) : B(fixedRing, count) {}
|
|
||||||
|
|
||||||
//! copy constructor
|
|
||||||
PolynomialOverFixedRing(const ThisType &t) : B(t) {}
|
|
||||||
|
|
||||||
explicit PolynomialOverFixedRing(const B &t) : B(t) {}
|
|
||||||
|
|
||||||
//! construct constant polynomial
|
|
||||||
PolynomialOverFixedRing(const CoefficientType &element) : B(element) {}
|
|
||||||
|
|
||||||
//! construct polynomial with specified coefficients, starting from coefficient of x^0
|
|
||||||
template <typename Iterator> PolynomialOverFixedRing(Iterator first, Iterator last)
|
|
||||||
: B(first, last) {}
|
|
||||||
|
|
||||||
//! convert from string
|
|
||||||
explicit PolynomialOverFixedRing(const char *str) : B(str, fixedRing) {}
|
|
||||||
|
|
||||||
//! convert from big-endian byte array
|
|
||||||
PolynomialOverFixedRing(const byte *encodedPoly, unsigned int byteCount) : B(encodedPoly, byteCount) {}
|
|
||||||
|
|
||||||
//! convert from Basic Encoding Rules encoded byte array
|
|
||||||
explicit PolynomialOverFixedRing(const byte *BEREncodedPoly) : B(BEREncodedPoly) {}
|
|
||||||
|
|
||||||
//! convert from BER encoded byte array stored in a BufferedTransformation object
|
|
||||||
explicit PolynomialOverFixedRing(BufferedTransformation &bt) : B(bt) {}
|
|
||||||
|
|
||||||
//! create a random PolynomialOverFixedRing
|
|
||||||
PolynomialOverFixedRing(RandomNumberGenerator &rng, const RandomizationParameter ¶meter) : B(rng, parameter, fixedRing) {}
|
|
||||||
|
|
||||||
static const ThisType &Zero();
|
|
||||||
static const ThisType &One();
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//! \name ACCESSORS
|
|
||||||
//@{
|
|
||||||
//! the zero polynomial will return a degree of -1
|
|
||||||
int Degree() const {return B::Degree(fixedRing);}
|
|
||||||
//! degree + 1
|
|
||||||
unsigned int CoefficientCount() const {return B::CoefficientCount(fixedRing);}
|
|
||||||
//! return coefficient for x^i
|
|
||||||
CoefficientType GetCoefficient(unsigned int i) const {return B::GetCoefficient(i, fixedRing);}
|
|
||||||
//! return coefficient for x^i
|
|
||||||
CoefficientType operator[](unsigned int i) const {return B::GetCoefficient(i, fixedRing);}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//! \name MANIPULATORS
|
|
||||||
//@{
|
|
||||||
//!
|
|
||||||
ThisType& operator=(const ThisType& t) {B::operator=(t); return *this;}
|
|
||||||
//!
|
|
||||||
ThisType& operator+=(const ThisType& t) {Accumulate(t, fixedRing); return *this;}
|
|
||||||
//!
|
|
||||||
ThisType& operator-=(const ThisType& t) {Reduce(t, fixedRing); return *this;}
|
|
||||||
//!
|
|
||||||
ThisType& operator*=(const ThisType& t) {return *this = *this*t;}
|
|
||||||
//!
|
|
||||||
ThisType& operator/=(const ThisType& t) {return *this = *this/t;}
|
|
||||||
//!
|
|
||||||
ThisType& operator%=(const ThisType& t) {return *this = *this%t;}
|
|
||||||
|
|
||||||
//!
|
|
||||||
ThisType& operator<<=(unsigned int n) {ShiftLeft(n, fixedRing); return *this;}
|
|
||||||
//!
|
|
||||||
ThisType& operator>>=(unsigned int n) {ShiftRight(n, fixedRing); return *this;}
|
|
||||||
|
|
||||||
//! set the coefficient for x^i to value
|
|
||||||
void SetCoefficient(unsigned int i, const CoefficientType &value) {B::SetCoefficient(i, value, fixedRing);}
|
|
||||||
|
|
||||||
//!
|
|
||||||
void Randomize(RandomNumberGenerator &rng, const RandomizationParameter ¶meter) {B::Randomize(rng, parameter, fixedRing);}
|
|
||||||
|
|
||||||
//!
|
|
||||||
void Negate() {B::Negate(fixedRing);}
|
|
||||||
|
|
||||||
void swap(ThisType &t) {B::swap(t);}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//! \name UNARY OPERATORS
|
|
||||||
//@{
|
|
||||||
//!
|
|
||||||
bool operator!() const {return CoefficientCount()==0;}
|
|
||||||
//!
|
|
||||||
ThisType operator+() const {return *this;}
|
|
||||||
//!
|
|
||||||
ThisType operator-() const {return ThisType(Inverse(fixedRing));}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//! \name BINARY OPERATORS
|
|
||||||
//@{
|
|
||||||
//!
|
|
||||||
friend ThisType operator>>(ThisType a, unsigned int n) {return ThisType(a>>=n);}
|
|
||||||
//!
|
|
||||||
friend ThisType operator<<(ThisType a, unsigned int n) {return ThisType(a<<=n);}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//! \name OTHER ARITHMETIC FUNCTIONS
|
|
||||||
//@{
|
|
||||||
//!
|
|
||||||
ThisType MultiplicativeInverse() const {return ThisType(B::MultiplicativeInverse(fixedRing));}
|
|
||||||
//!
|
|
||||||
bool IsUnit() const {return B::IsUnit(fixedRing);}
|
|
||||||
|
|
||||||
//!
|
|
||||||
ThisType Doubled() const {return ThisType(B::Doubled(fixedRing));}
|
|
||||||
//!
|
|
||||||
ThisType Squared() const {return ThisType(B::Squared(fixedRing));}
|
|
||||||
|
|
||||||
CoefficientType EvaluateAt(const CoefficientType &x) const {return B::EvaluateAt(x, fixedRing);}
|
|
||||||
|
|
||||||
//! calculate r and q such that (a == d*q + r) && (0 <= r < abs(d))
|
|
||||||
static void Divide(ThisType &r, ThisType &q, const ThisType &a, const ThisType &d)
|
|
||||||
{B::Divide(r, q, a, d, fixedRing);}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//! \name INPUT/OUTPUT
|
|
||||||
//@{
|
|
||||||
//!
|
|
||||||
friend std::istream& operator>>(std::istream& in, ThisType &a)
|
|
||||||
{return a.Input(in, fixedRing);}
|
|
||||||
//!
|
|
||||||
friend std::ostream& operator<<(std::ostream& out, const ThisType &a)
|
|
||||||
{return a.Output(out, fixedRing);}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static const Ring fixedRing;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Ring of polynomials over another ring
|
|
||||||
template <class T> class RingOfPolynomialsOver : public AbstractEuclideanDomain<PolynomialOver<T> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef T CoefficientRing;
|
|
||||||
typedef PolynomialOver<T> Element;
|
|
||||||
typedef typename Element::CoefficientType CoefficientType;
|
|
||||||
typedef typename Element::RandomizationParameter RandomizationParameter;
|
|
||||||
|
|
||||||
RingOfPolynomialsOver(const CoefficientRing &ring) : m_ring(ring) {}
|
|
||||||
|
|
||||||
Element RandomElement(RandomNumberGenerator &rng, const RandomizationParameter ¶meter)
|
|
||||||
{return Element(rng, parameter, m_ring);}
|
|
||||||
|
|
||||||
bool Equal(const Element &a, const Element &b) const
|
|
||||||
{return a.Equals(b, m_ring);}
|
|
||||||
|
|
||||||
const Element& Identity() const
|
|
||||||
{return result = m_ring.Identity();}
|
|
||||||
|
|
||||||
const Element& Add(const Element &a, const Element &b) const
|
|
||||||
{return result = a.Plus(b, m_ring);}
|
|
||||||
|
|
||||||
Element& Accumulate(Element &a, const Element &b) const
|
|
||||||
{a.Accumulate(b, m_ring); return a;}
|
|
||||||
|
|
||||||
const Element& Inverse(const Element &a) const
|
|
||||||
{return result = a.Inverse(m_ring);}
|
|
||||||
|
|
||||||
const Element& Subtract(const Element &a, const Element &b) const
|
|
||||||
{return result = a.Minus(b, m_ring);}
|
|
||||||
|
|
||||||
Element& Reduce(Element &a, const Element &b) const
|
|
||||||
{return a.Reduce(b, m_ring);}
|
|
||||||
|
|
||||||
const Element& Double(const Element &a) const
|
|
||||||
{return result = a.Doubled(m_ring);}
|
|
||||||
|
|
||||||
const Element& MultiplicativeIdentity() const
|
|
||||||
{return result = m_ring.MultiplicativeIdentity();}
|
|
||||||
|
|
||||||
const Element& Multiply(const Element &a, const Element &b) const
|
|
||||||
{return result = a.Times(b, m_ring);}
|
|
||||||
|
|
||||||
const Element& Square(const Element &a) const
|
|
||||||
{return result = a.Squared(m_ring);}
|
|
||||||
|
|
||||||
bool IsUnit(const Element &a) const
|
|
||||||
{return a.IsUnit(m_ring);}
|
|
||||||
|
|
||||||
const Element& MultiplicativeInverse(const Element &a) const
|
|
||||||
{return result = a.MultiplicativeInverse(m_ring);}
|
|
||||||
|
|
||||||
const Element& Divide(const Element &a, const Element &b) const
|
|
||||||
{return result = a.DividedBy(b, m_ring);}
|
|
||||||
|
|
||||||
const Element& Mod(const Element &a, const Element &b) const
|
|
||||||
{return result = a.Modulo(b, m_ring);}
|
|
||||||
|
|
||||||
void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const
|
|
||||||
{Element::Divide(r, q, a, d, m_ring);}
|
|
||||||
|
|
||||||
class InterpolationFailed : public Exception
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
InterpolationFailed() : Exception(OTHER_ERROR, "RingOfPolynomialsOver<T>: interpolation failed") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
Element Interpolate(const CoefficientType x[], const CoefficientType y[], unsigned int n) const;
|
|
||||||
|
|
||||||
// a faster version of Interpolate(x, y, n).EvaluateAt(position)
|
|
||||||
CoefficientType InterpolateAt(const CoefficientType &position, const CoefficientType x[], const CoefficientType y[], unsigned int n) const;
|
|
||||||
/*
|
|
||||||
void PrepareBulkInterpolation(CoefficientType *w, const CoefficientType x[], unsigned int n) const;
|
|
||||||
void PrepareBulkInterpolationAt(CoefficientType *v, const CoefficientType &position, const CoefficientType x[], const CoefficientType w[], unsigned int n) const;
|
|
||||||
CoefficientType BulkInterpolateAt(const CoefficientType y[], const CoefficientType v[], unsigned int n) const;
|
|
||||||
*/
|
|
||||||
protected:
|
|
||||||
void CalculateAlpha(std::vector<CoefficientType> &alpha, const CoefficientType x[], const CoefficientType y[], unsigned int n) const;
|
|
||||||
|
|
||||||
CoefficientRing m_ring;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Ring, class Element>
|
|
||||||
void PrepareBulkPolynomialInterpolation(const Ring &ring, Element *w, const Element x[], unsigned int n);
|
|
||||||
template <class Ring, class Element>
|
|
||||||
void PrepareBulkPolynomialInterpolationAt(const Ring &ring, Element *v, const Element &position, const Element x[], const Element w[], unsigned int n);
|
|
||||||
template <class Ring, class Element>
|
|
||||||
Element BulkPolynomialInterpolateAt(const Ring &ring, const Element y[], const Element v[], unsigned int n);
|
|
||||||
|
|
||||||
//!
|
|
||||||
template <class T, int instance>
|
|
||||||
inline bool operator==(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
|
|
||||||
{return a.Equals(b, fixedRing);}
|
|
||||||
//!
|
|
||||||
template <class T, int instance>
|
|
||||||
inline bool operator!=(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
|
|
||||||
{return !(a==b);}
|
|
||||||
|
|
||||||
//!
|
|
||||||
template <class T, int instance>
|
|
||||||
inline bool operator> (const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
|
|
||||||
{return a.Degree() > b.Degree();}
|
|
||||||
//!
|
|
||||||
template <class T, int instance>
|
|
||||||
inline bool operator>=(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
|
|
||||||
{return a.Degree() >= b.Degree();}
|
|
||||||
//!
|
|
||||||
template <class T, int instance>
|
|
||||||
inline bool operator< (const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
|
|
||||||
{return a.Degree() < b.Degree();}
|
|
||||||
//!
|
|
||||||
template <class T, int instance>
|
|
||||||
inline bool operator<=(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
|
|
||||||
{return a.Degree() <= b.Degree();}
|
|
||||||
|
|
||||||
//!
|
|
||||||
template <class T, int instance>
|
|
||||||
inline CryptoPP::PolynomialOverFixedRing<T, instance> operator+(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
|
|
||||||
{return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Plus(b, fixedRing));}
|
|
||||||
//!
|
|
||||||
template <class T, int instance>
|
|
||||||
inline CryptoPP::PolynomialOverFixedRing<T, instance> operator-(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
|
|
||||||
{return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Minus(b, fixedRing));}
|
|
||||||
//!
|
|
||||||
template <class T, int instance>
|
|
||||||
inline CryptoPP::PolynomialOverFixedRing<T, instance> operator*(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
|
|
||||||
{return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Times(b, fixedRing));}
|
|
||||||
//!
|
|
||||||
template <class T, int instance>
|
|
||||||
inline CryptoPP::PolynomialOverFixedRing<T, instance> operator/(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
|
|
||||||
{return CryptoPP::PolynomialOverFixedRing<T, instance>(a.DividedBy(b, fixedRing));}
|
|
||||||
//!
|
|
||||||
template <class T, int instance>
|
|
||||||
inline CryptoPP::PolynomialOverFixedRing<T, instance> operator%(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
|
|
||||||
{return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Modulo(b, fixedRing));}
|
|
||||||
|
|
||||||
NAMESPACE_END
|
|
||||||
|
|
||||||
NAMESPACE_BEGIN(std)
|
|
||||||
template<class T> inline void swap(CryptoPP::PolynomialOver<T> &a, CryptoPP::PolynomialOver<T> &b)
|
|
||||||
{
|
|
||||||
a.swap(b);
|
|
||||||
}
|
|
||||||
template<class T, int i> inline void swap(CryptoPP::PolynomialOverFixedRing<T,i> &a, CryptoPP::PolynomialOverFixedRing<T,i> &b)
|
|
||||||
{
|
|
||||||
a.swap(b);
|
|
||||||
}
|
|
||||||
NAMESPACE_END
|
|
||||||
|
|
||||||
#endif
|
|
||||||
Reference in New Issue
Block a user