00001
00002
00003 #include "pch.h"
00004 #include "rw.h"
00005 #include "nbtheory.h"
00006 #include "asn.h"
00007
00008 #ifndef CRYPTOPP_IMPORTS
00009
00010 NAMESPACE_BEGIN(CryptoPP)
00011
00012 void RWFunction::BERDecode(BufferedTransformation &bt)
00013 {
00014 BERSequenceDecoder seq(bt);
00015 m_n.BERDecode(seq);
00016 seq.MessageEnd();
00017 }
00018
00019 void RWFunction::DEREncode(BufferedTransformation &bt) const
00020 {
00021 DERSequenceEncoder seq(bt);
00022 m_n.DEREncode(seq);
00023 seq.MessageEnd();
00024 }
00025
00026 Integer RWFunction::ApplyFunction(const Integer &in) const
00027 {
00028 DoQuickSanityCheck();
00029
00030 Integer out = in.Squared()%m_n;
00031 const word r = 12;
00032
00033
00034 const word r2 = r/2;
00035 const word r3a = (16 + 5 - r) % 16;
00036 const word r3b = (16 + 13 - r) % 16;
00037 const word r4 = (8 + 5 - r/2) % 8;
00038 switch (out % 16)
00039 {
00040 case r:
00041 break;
00042 case r2:
00043 case r2+8:
00044 out <<= 1;
00045 break;
00046 case r3a:
00047 case r3b:
00048 out.Negate();
00049 out += m_n;
00050 break;
00051 case r4:
00052 case r4+8:
00053 out.Negate();
00054 out += m_n;
00055 out <<= 1;
00056 break;
00057 default:
00058 out = Integer::Zero();
00059 }
00060 return out;
00061 }
00062
00063 bool RWFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const
00064 {
00065 bool pass = true;
00066 pass = pass && m_n > Integer::One() && m_n%8 == 5;
00067 return pass;
00068 }
00069
00070 bool RWFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00071 {
00072 return GetValueHelper(this, name, valueType, pValue).Assignable()
00073 CRYPTOPP_GET_FUNCTION_ENTRY(Modulus)
00074 ;
00075 }
00076
00077 void RWFunction::AssignFrom(const NameValuePairs &source)
00078 {
00079 AssignFromHelper(this, source)
00080 CRYPTOPP_SET_FUNCTION_ENTRY(Modulus)
00081 ;
00082 }
00083
00084
00085
00086
00087
00088 void InvertibleRWFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
00089 {
00090 int modulusSize = 2048;
00091 alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize);
00092
00093 if (modulusSize < 16)
00094 throw InvalidArgument("InvertibleRWFunction: specified modulus length is too small");
00095
00096 const NameValuePairs &primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize);
00097 m_p.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("EquivalentTo", 3)("Mod", 8)));
00098 m_q.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("EquivalentTo", 7)("Mod", 8)));
00099
00100 m_n = m_p * m_q;
00101 m_u = m_q.InverseMod(m_p);
00102 }
00103
00104 void InvertibleRWFunction::BERDecode(BufferedTransformation &bt)
00105 {
00106 BERSequenceDecoder seq(bt);
00107 m_n.BERDecode(seq);
00108 m_p.BERDecode(seq);
00109 m_q.BERDecode(seq);
00110 m_u.BERDecode(seq);
00111 seq.MessageEnd();
00112 }
00113
00114 void InvertibleRWFunction::DEREncode(BufferedTransformation &bt) const
00115 {
00116 DERSequenceEncoder seq(bt);
00117 m_n.DEREncode(seq);
00118 m_p.DEREncode(seq);
00119 m_q.DEREncode(seq);
00120 m_u.DEREncode(seq);
00121 seq.MessageEnd();
00122 }
00123
00124 Integer InvertibleRWFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &in) const
00125 {
00126
00127
00128 DoQuickSanityCheck();
00129
00130 Integer cp=in%m_p, cq=in%m_q;
00131
00132 if (Jacobi(cp, m_p) * Jacobi(cq, m_q) != 1)
00133 {
00134 cp = cp%2 ? (cp+m_p) >> 1 : cp >> 1;
00135 cq = cq%2 ? (cq+m_q) >> 1 : cq >> 1;
00136 }
00137
00138 cp = ModularSquareRoot(cp, m_p);
00139 cq = ModularSquareRoot(cq, m_q);
00140
00141 Integer out = CRT(cq, m_q, cp, m_p, m_u);
00142
00143 return STDMIN(out, m_n-out);
00144 }
00145
00146 bool InvertibleRWFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const
00147 {
00148 bool pass = RWFunction::Validate(rng, level);
00149 pass = pass && m_p > Integer::One() && m_p%8 == 3 && m_p < m_n;
00150 pass = pass && m_q > Integer::One() && m_q%8 == 7 && m_q < m_n;
00151 pass = pass && m_u.IsPositive() && m_u < m_p;
00152 if (level >= 1)
00153 {
00154 pass = pass && m_p * m_q == m_n;
00155 pass = pass && m_u * m_q % m_p == 1;
00156 }
00157 if (level >= 2)
00158 pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2);
00159 return pass;
00160 }
00161
00162 bool InvertibleRWFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00163 {
00164 return GetValueHelper<RWFunction>(this, name, valueType, pValue).Assignable()
00165 CRYPTOPP_GET_FUNCTION_ENTRY(Prime1)
00166 CRYPTOPP_GET_FUNCTION_ENTRY(Prime2)
00167 CRYPTOPP_GET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1)
00168 ;
00169 }
00170
00171 void InvertibleRWFunction::AssignFrom(const NameValuePairs &source)
00172 {
00173 AssignFromHelper<RWFunction>(this, source)
00174 CRYPTOPP_SET_FUNCTION_ENTRY(Prime1)
00175 CRYPTOPP_SET_FUNCTION_ENTRY(Prime2)
00176 CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1)
00177 ;
00178 }
00179
00180 NAMESPACE_END
00181
00182 #endif