00001
00002
00003
#include "pch.h"
00004
#include "luc.h"
00005
#include "asn.h"
00006
#include "nbtheory.h"
00007
#include "sha.h"
00008
#include "algparam.h"
00009
00010
#include "oaep.cpp"
00011
00012 NAMESPACE_BEGIN(CryptoPP)
00013
00014 void LUC_TestInstantiations()
00015 {
00016
LUC_HMP<SHA>::Signer t1;
00017
LUCFunction t2;
00018
InvertibleLUCFunction t3;
00019 }
00020
00021
void DL_Algorithm_LUC_HMP::Sign(
const DL_GroupParameters<Integer> ¶ms,
const Integer &x,
const Integer &k,
const Integer &e,
Integer &r,
Integer &s)
const
00022
{
00023
const Integer &q = params.
GetSubgroupOrder();
00024 r = params.
ExponentiateBase(k);
00025 s = (k + x*(r+e)) % q;
00026 }
00027
00028
bool DL_Algorithm_LUC_HMP::Verify(
const DL_GroupParameters<Integer> ¶ms,
const DL_PublicKey<Integer> &publicKey,
const Integer &e,
const Integer &r,
const Integer &s)
const
00029
{
00030
Integer p = params.
GetGroupOrder()-1;
00031
const Integer &q = params.
GetSubgroupOrder();
00032
00033
Integer Vsg = params.
ExponentiateBase(s);
00034
Integer Vry = publicKey.
ExponentiatePublicElement((r+e)%q);
00035
return (Vsg*Vsg + Vry*Vry + r*r) % p == (Vsg * Vry * r + 4) % p;
00036 }
00037
00038
Integer DL_BasePrecomputation_LUC::Exponentiate(
const DL_GroupPrecomputation<Element> &group,
const Integer &exponent)
const
00039
{
00040
return Lucas(exponent, m_g, static_cast<const DL_GroupPrecomputation_LUC &>(group).GetModulus());
00041 }
00042
00043
void DL_GroupParameters_LUC::SimultaneousExponentiate(Element *results,
const Element &base,
const Integer *exponents,
unsigned int exponentsCount)
const
00044
{
00045
for (
unsigned int i=0; i<exponentsCount; i++)
00046 results[i] = Lucas(exponents[i], base, GetModulus());
00047 }
00048
00049
void LUCFunction::BERDecode(
BufferedTransformation &bt)
00050 {
00051
BERSequenceDecoder seq(bt);
00052 m_n.
BERDecode(seq);
00053 m_e.
BERDecode(seq);
00054 seq.
MessageEnd();
00055 }
00056
00057
void LUCFunction::DEREncode(
BufferedTransformation &bt)
const
00058
{
00059
DERSequenceEncoder seq(bt);
00060 m_n.
DEREncode(seq);
00061 m_e.
DEREncode(seq);
00062 seq.
MessageEnd();
00063 }
00064
00065
Integer LUCFunction::ApplyFunction(
const Integer &x)
const
00066
{
00067 DoQuickSanityCheck();
00068
return Lucas(m_e, x, m_n);
00069 }
00070
00071 bool LUCFunction::Validate(
RandomNumberGenerator &rng,
unsigned int level)
const
00072
{
00073
bool pass =
true;
00074 pass = pass && m_n >
Integer::One() && m_n.
IsOdd();
00075 pass = pass && m_e >
Integer::One() && m_e.
IsOdd() && m_e < m_n;
00076
return pass;
00077 }
00078
00079 bool LUCFunction::GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const
00080
{
00081
return GetValueHelper(
this, name, valueType, pValue).Assignable()
00082 CRYPTOPP_GET_FUNCTION_ENTRY(Modulus)
00083 CRYPTOPP_GET_FUNCTION_ENTRY(PublicExponent)
00084 ;
00085 }
00086
00087 void LUCFunction::AssignFrom(
const NameValuePairs &source)
00088 {
00089 AssignFromHelper(
this, source)
00090 CRYPTOPP_SET_FUNCTION_ENTRY(Modulus)
00091 CRYPTOPP_SET_FUNCTION_ENTRY(PublicExponent)
00092 ;
00093 }
00094
00095
00096
00097
00098
class LUCPrimeSelector :
public PrimeSelector
00099 {
00100
public:
00101 LUCPrimeSelector(
const Integer &e) : m_e(e) {}
00102
bool IsAcceptable(
const Integer &candidate)
const
00103
{
00104
return RelativelyPrime(m_e, candidate+1) && RelativelyPrime(m_e, candidate-1);
00105 }
00106
Integer m_e;
00107 };
00108
00109 void InvertibleLUCFunction::GenerateRandom(
RandomNumberGenerator &rng,
const NameValuePairs &alg)
00110 {
00111
int modulusSize = 2048;
00112 alg.
GetIntValue(
"ModulusSize", modulusSize) || alg.
GetIntValue(
"KeySize", modulusSize);
00113
00114
if (modulusSize < 16)
00115
throw InvalidArgument(
"InvertibleLUCFunction: specified modulus size is too small");
00116
00117 m_e = alg.
GetValueWithDefault(
"PublicExponent",
Integer(17));
00118
00119
if (m_e < 5 || m_e.
IsEven())
00120
throw InvalidArgument(
"InvertibleLUCFunction: invalid public exponent");
00121
00122 LUCPrimeSelector selector(m_e);
00123
const NameValuePairs &primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize)
00124 (
"PointerToPrimeSelector", selector.GetSelectorPointer());
00125 m_p.
GenerateRandom(rng, primeParam);
00126 m_q.
GenerateRandom(rng, primeParam);
00127
00128 m_n = m_p * m_q;
00129 m_u = m_q.
InverseMod(m_p);
00130 }
00131
00132
void InvertibleLUCFunction::Initialize(
RandomNumberGenerator &rng,
unsigned int keybits,
const Integer &e)
00133 {
00134 GenerateRandom(rng, MakeParameters(
"ModulusSize", (
int)keybits)(
"PublicExponent", e));
00135 }
00136
00137
void InvertibleLUCFunction::BERDecode(
BufferedTransformation &bt)
00138 {
00139
BERSequenceDecoder seq(bt);
00140
00141
Integer version(seq);
00142
if (!!version)
00143 BERDecodeError();
00144
00145 m_n.
BERDecode(seq);
00146 m_e.
BERDecode(seq);
00147 m_p.
BERDecode(seq);
00148 m_q.
BERDecode(seq);
00149 m_u.
BERDecode(seq);
00150 seq.
MessageEnd();
00151 }
00152
00153
void InvertibleLUCFunction::DEREncode(
BufferedTransformation &bt)
const
00154
{
00155
DERSequenceEncoder seq(bt);
00156
00157
const byte version[] = {INTEGER, 1, 0};
00158 seq.Put(version,
sizeof(version));
00159 m_n.
DEREncode(seq);
00160 m_e.
DEREncode(seq);
00161 m_p.
DEREncode(seq);
00162 m_q.
DEREncode(seq);
00163 m_u.
DEREncode(seq);
00164 seq.
MessageEnd();
00165 }
00166
00167
Integer InvertibleLUCFunction::CalculateInverse(
RandomNumberGenerator &rng,
const Integer &x)
const
00168
{
00169
00170 DoQuickSanityCheck();
00171
return InverseLucas(m_e, x, m_q, m_p, m_u);
00172 }
00173
00174 bool InvertibleLUCFunction::Validate(
RandomNumberGenerator &rng,
unsigned int level)
const
00175
{
00176
bool pass = LUCFunction::Validate(rng, level);
00177 pass = pass && m_p >
Integer::One() && m_p.
IsOdd() && m_p < m_n;
00178 pass = pass && m_q >
Integer::One() && m_q.
IsOdd() && m_q < m_n;
00179 pass = pass && m_u.
IsPositive() && m_u < m_p;
00180
if (level >= 1)
00181 {
00182 pass = pass && m_p * m_q == m_n;
00183 pass = pass && RelativelyPrime(m_e, m_p+1);
00184 pass = pass && RelativelyPrime(m_e, m_p-1);
00185 pass = pass && RelativelyPrime(m_e, m_q+1);
00186 pass = pass && RelativelyPrime(m_e, m_q-1);
00187 pass = pass && m_u * m_q % m_p == 1;
00188 }
00189
if (level >= 2)
00190 pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2);
00191
return pass;
00192 }
00193
00194 bool InvertibleLUCFunction::GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const
00195
{
00196
return GetValueHelper<LUCFunction>(
this, name, valueType, pValue).Assignable()
00197 CRYPTOPP_GET_FUNCTION_ENTRY(Prime1)
00198 CRYPTOPP_GET_FUNCTION_ENTRY(Prime2)
00199 CRYPTOPP_GET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1)
00200 ;
00201 }
00202
00203 void InvertibleLUCFunction::AssignFrom(
const NameValuePairs &source)
00204 {
00205 AssignFromHelper<LUCFunction>(
this, source)
00206 CRYPTOPP_SET_FUNCTION_ENTRY(Prime1)
00207 CRYPTOPP_SET_FUNCTION_ENTRY(Prime2)
00208 CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1)
00209 ;
00210 }
00211
00212 NAMESPACE_END