Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

luc.cpp

00001 // luc.cpp - written and placed in the public domain by Wei Dai
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> &params, 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> &params, 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 // private key operations:
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)  // make sure version is 0
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         // not clear how to do blinding with LUC
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

Generated on Sun Mar 14 20:44:27 2004 for Crypto++ by doxygen 1.3.6-20040222