1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
|
// luc.cpp - written and placed in the public domain by Wei Dai
#include "pch.h"
#include "luc.h"
#include "asn.h"
#include "nbtheory.h"
#include "sha.h"
#include "algparam.h"
NAMESPACE_BEGIN(CryptoPP)
void LUC_TestInstantiations()
{
LUC_HMP<SHA>::Signer t1;
LUCFunction t2;
InvertibleLUCFunction t3;
}
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
{
const Integer &q = params.GetSubgroupOrder();
r = params.ExponentiateBase(k);
s = (k + x*(r+e)) % q;
}
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
{
Integer p = params.GetGroupOrder()-1;
const Integer &q = params.GetSubgroupOrder();
Integer Vsg = params.ExponentiateBase(s);
Integer Vry = publicKey.ExponentiatePublicElement((r+e)%q);
return (Vsg*Vsg + Vry*Vry + r*r) % p == (Vsg * Vry * r + 4) % p;
}
Integer DL_BasePrecomputation_LUC::Exponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent) const
{
return Lucas(exponent, m_g, static_cast<const DL_GroupPrecomputation_LUC &>(group).GetModulus());
}
void DL_GroupParameters_LUC::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
{
for (unsigned int i=0; i<exponentsCount; i++)
results[i] = Lucas(exponents[i], base, GetModulus());
}
void LUCFunction::BERDecode(BufferedTransformation &bt)
{
BERSequenceDecoder seq(bt);
m_n.BERDecode(seq);
m_e.BERDecode(seq);
seq.MessageEnd();
}
void LUCFunction::DEREncode(BufferedTransformation &bt) const
{
DERSequenceEncoder seq(bt);
m_n.DEREncode(seq);
m_e.DEREncode(seq);
seq.MessageEnd();
}
Integer LUCFunction::ApplyFunction(const Integer &x) const
{
DoQuickSanityCheck();
return Lucas(m_e, x, m_n);
}
bool LUCFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const
{
bool pass = true;
pass = pass && m_n > Integer::One() && m_n.IsOdd();
pass = pass && m_e > Integer::One() && m_e.IsOdd() && m_e < m_n;
return pass;
}
bool LUCFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
{
return GetValueHelper(this, name, valueType, pValue).Assignable()
CRYPTOPP_GET_FUNCTION_ENTRY(Modulus)
CRYPTOPP_GET_FUNCTION_ENTRY(PublicExponent)
;
}
void LUCFunction::AssignFrom(const NameValuePairs &source)
{
AssignFromHelper(this, source)
CRYPTOPP_SET_FUNCTION_ENTRY(Modulus)
CRYPTOPP_SET_FUNCTION_ENTRY(PublicExponent)
;
}
// *****************************************************************************
// private key operations:
class LUCPrimeSelector : public PrimeSelector
{
public:
LUCPrimeSelector(const Integer &e) : m_e(e) {}
bool IsAcceptable(const Integer &candidate) const
{
return RelativelyPrime(m_e, candidate+1) && RelativelyPrime(m_e, candidate-1);
}
Integer m_e;
};
void InvertibleLUCFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
{
int modulusSize = 2048;
alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize);
if (modulusSize < 16)
throw InvalidArgument("InvertibleLUCFunction: specified modulus size is too small");
m_e = alg.GetValueWithDefault("PublicExponent", Integer(17));
if (m_e < 5 || m_e.IsEven())
throw InvalidArgument("InvertibleLUCFunction: invalid public exponent");
LUCPrimeSelector selector(m_e);
const NameValuePairs &primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize)
("PointerToPrimeSelector", selector.GetSelectorPointer());
m_p.GenerateRandom(rng, primeParam);
m_q.GenerateRandom(rng, primeParam);
m_n = m_p * m_q;
m_u = m_q.InverseMod(m_p);
}
void InvertibleLUCFunction::Initialize(RandomNumberGenerator &rng, unsigned int keybits, const Integer &e)
{
GenerateRandom(rng, MakeParameters("ModulusSize", (int)keybits)("PublicExponent", e));
}
void InvertibleLUCFunction::BERDecode(BufferedTransformation &bt)
{
BERSequenceDecoder seq(bt);
Integer version(seq);
if (!!version) // make sure version is 0
BERDecodeError();
m_n.BERDecode(seq);
m_e.BERDecode(seq);
m_p.BERDecode(seq);
m_q.BERDecode(seq);
m_u.BERDecode(seq);
seq.MessageEnd();
}
void InvertibleLUCFunction::DEREncode(BufferedTransformation &bt) const
{
DERSequenceEncoder seq(bt);
const byte version[] = {INTEGER, 1, 0};
seq.Put(version, sizeof(version));
m_n.DEREncode(seq);
m_e.DEREncode(seq);
m_p.DEREncode(seq);
m_q.DEREncode(seq);
m_u.DEREncode(seq);
seq.MessageEnd();
}
Integer InvertibleLUCFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const
{
// not clear how to do blinding with LUC
DoQuickSanityCheck();
return InverseLucas(m_e, x, m_q, m_p, m_u);
}
bool InvertibleLUCFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const
{
bool pass = LUCFunction::Validate(rng, level);
pass = pass && m_p > Integer::One() && m_p.IsOdd() && m_p < m_n;
pass = pass && m_q > Integer::One() && m_q.IsOdd() && m_q < m_n;
pass = pass && m_u.IsPositive() && m_u < m_p;
if (level >= 1)
{
pass = pass && m_p * m_q == m_n;
pass = pass && RelativelyPrime(m_e, m_p+1);
pass = pass && RelativelyPrime(m_e, m_p-1);
pass = pass && RelativelyPrime(m_e, m_q+1);
pass = pass && RelativelyPrime(m_e, m_q-1);
pass = pass && m_u * m_q % m_p == 1;
}
if (level >= 2)
pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2);
return pass;
}
bool InvertibleLUCFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
{
return GetValueHelper<LUCFunction>(this, name, valueType, pValue).Assignable()
CRYPTOPP_GET_FUNCTION_ENTRY(Prime1)
CRYPTOPP_GET_FUNCTION_ENTRY(Prime2)
CRYPTOPP_GET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1)
;
}
void InvertibleLUCFunction::AssignFrom(const NameValuePairs &source)
{
AssignFromHelper<LUCFunction>(this, source)
CRYPTOPP_SET_FUNCTION_ENTRY(Prime1)
CRYPTOPP_SET_FUNCTION_ENTRY(Prime2)
CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1)
;
}
NAMESPACE_END
|