source: git/src-cryptopp/gfpcrypt.cpp

Last change on this file was e230cb0, checked in by David Stainton <dstainton415@…>, at 2016-10-12T13:27:29Z

Add cryptopp from tag CRYPTOPP_5_6_5

  • Property mode set to 100644
File size: 9.8 KB
Line 
1// dsa.cpp - written and placed in the public domain by Wei Dai
2
3#include "pch.h"
4#include "config.h"
5
6// TODO: fix the C4589 warnings
7#if CRYPTOPP_MSC_VERSION
8# pragma warning(disable: 4189 4589)
9#endif
10
11#ifndef CRYPTOPP_IMPORTS
12
13#include "gfpcrypt.h"
14#include "nbtheory.h"
15#include "modarith.h"
16#include "integer.h"
17#include "asn.h"
18#include "oids.h"
19#include "misc.h"
20
21NAMESPACE_BEGIN(CryptoPP)
22
23#if CRYPTOPP_DEBUG && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
24void TestInstantiations_gfpcrypt()
25{
26        GDSA<SHA>::Signer test;
27        GDSA<SHA>::Verifier test1;
28        DSA::Signer test5(NullRNG(), 100);
29        DSA::Signer test2(test5);
30        NR<SHA>::Signer test3;
31        NR<SHA>::Verifier test4;
32        DLIES<>::Encryptor test6;
33        DLIES<>::Decryptor test7;
34}
35#endif
36
37void DL_GroupParameters_DSA::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
38{
39        Integer p, q, g;
40
41        if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g))
42        {
43                q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2);
44                Initialize(p, q, g);
45        }
46        else
47        {
48                int modulusSize = 1024, defaultSubgroupOrderSize;
49                alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize);
50
51                switch (modulusSize)
52                {
53                case 1024:
54                        defaultSubgroupOrderSize = 160;
55                        break;
56                case 2048:
57                        defaultSubgroupOrderSize = 224;
58                        break;
59                case 3072:
60                        defaultSubgroupOrderSize = 256;
61                        break;
62                default:
63                        throw InvalidArgument("DSA: not a valid prime length");
64                }
65
66                DL_GroupParameters_GFP::GenerateRandom(rng, CombinedNameValuePairs(alg, MakeParameters(Name::SubgroupOrderSize(), defaultSubgroupOrderSize, false)));
67        }
68}
69
70bool DL_GroupParameters_DSA::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
71{
72        bool pass = DL_GroupParameters_GFP::ValidateGroup(rng, level);
73        int pSize = GetModulus().BitCount(), qSize = GetSubgroupOrder().BitCount();
74        pass = pass && ((pSize==1024 && qSize==160) || (pSize==2048 && qSize==224) || (pSize==2048 && qSize==256) || (pSize==3072 && qSize==256));
75        return pass;
76}
77
78void DL_SignatureMessageEncodingMethod_DSA::ComputeMessageRepresentative(RandomNumberGenerator &rng,
79        const byte *recoverableMessage, size_t recoverableMessageLength,
80        HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
81        byte *representative, size_t representativeBitLength) const
82{
83        CRYPTOPP_UNUSED(rng), CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(recoverableMessageLength);
84        CRYPTOPP_UNUSED(messageEmpty), CRYPTOPP_UNUSED(hashIdentifier);
85        CRYPTOPP_ASSERT(recoverableMessageLength == 0);
86        CRYPTOPP_ASSERT(hashIdentifier.second == 0);
87
88        const size_t representativeByteLength = BitsToBytes(representativeBitLength);
89        const size_t digestSize = hash.DigestSize();
90        const size_t paddingLength = SaturatingSubtract(representativeByteLength, digestSize);
91
92        memset(representative, 0, paddingLength);
93        hash.TruncatedFinal(representative+paddingLength, STDMIN(representativeByteLength, digestSize));
94
95        if (digestSize*8 > representativeBitLength)
96        {
97                Integer h(representative, representativeByteLength);
98                h >>= representativeByteLength*8 - representativeBitLength;
99                h.Encode(representative, representativeByteLength);
100        }
101}
102
103void DL_SignatureMessageEncodingMethod_NR::ComputeMessageRepresentative(RandomNumberGenerator &rng,
104        const byte *recoverableMessage, size_t recoverableMessageLength,
105        HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
106        byte *representative, size_t representativeBitLength) const
107{
108        CRYPTOPP_UNUSED(rng);CRYPTOPP_UNUSED(recoverableMessage); CRYPTOPP_UNUSED(recoverableMessageLength);
109        CRYPTOPP_UNUSED(hash); CRYPTOPP_UNUSED(hashIdentifier); CRYPTOPP_UNUSED(messageEmpty);
110        CRYPTOPP_UNUSED(representative); CRYPTOPP_UNUSED(representativeBitLength);
111
112        CRYPTOPP_ASSERT(recoverableMessageLength == 0);
113        CRYPTOPP_ASSERT(hashIdentifier.second == 0);
114        const size_t representativeByteLength = BitsToBytes(representativeBitLength);
115        const size_t digestSize = hash.DigestSize();
116        const size_t paddingLength = SaturatingSubtract(representativeByteLength, digestSize);
117
118        memset(representative, 0, paddingLength);
119        hash.TruncatedFinal(representative+paddingLength, STDMIN(representativeByteLength, digestSize));
120
121        if (digestSize*8 >= representativeBitLength)
122        {
123                Integer h(representative, representativeByteLength);
124                h >>= representativeByteLength*8 - representativeBitLength + 1;
125                h.Encode(representative, representativeByteLength);
126        }
127}
128
129bool DL_GroupParameters_IntegerBased::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
130{
131        const Integer &p = GetModulus(), &q = GetSubgroupOrder();
132
133        bool pass = true;
134        pass = pass && p > Integer::One() && p.IsOdd();
135        pass = pass && q > Integer::One() && q.IsOdd();
136
137        if (level >= 1)
138                pass = pass && GetCofactor() > Integer::One() && GetGroupOrder() % q == Integer::Zero();
139        if (level >= 2)
140                pass = pass && VerifyPrime(rng, q, level-2) && VerifyPrime(rng, p, level-2);
141
142        return pass;
143}
144
145bool DL_GroupParameters_IntegerBased::ValidateElement(unsigned int level, const Integer &g, const DL_FixedBasePrecomputation<Integer> *gpc) const
146{
147        const Integer &p = GetModulus(), &q = GetSubgroupOrder();
148
149        bool pass = true;
150        pass = pass && GetFieldType() == 1 ? g.IsPositive() : g.NotNegative();
151        pass = pass && g < p && !IsIdentity(g);
152
153        if (level >= 1)
154        {
155                if (gpc)
156                        pass = pass && gpc->Exponentiate(GetGroupPrecomputation(), Integer::One()) == g;
157        }
158        if (level >= 2)
159        {
160                if (GetFieldType() == 2)
161                        pass = pass && Jacobi(g*g-4, p)==-1;
162
163                // verifying that Lucas((p+1)/2, w, p)==2 is omitted because it's too costly
164                // and at most 1 bit is leaked if it's false
165                bool fullValidate = (GetFieldType() == 2 && level >= 3) || !FastSubgroupCheckAvailable();
166
167                if (fullValidate && pass)
168                {
169                        Integer gp = gpc ? gpc->Exponentiate(GetGroupPrecomputation(), q) : ExponentiateElement(g, q);
170                        pass = pass && IsIdentity(gp);
171                }
172                else if (GetFieldType() == 1)
173                        pass = pass && Jacobi(g, p) == 1;
174        }
175
176        return pass;
177}
178
179void DL_GroupParameters_IntegerBased::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
180{
181        Integer p, q, g;
182
183        if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g))
184        {
185                q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2);
186        }
187        else
188        {
189                int modulusSize, subgroupOrderSize;
190
191                if (!alg.GetIntValue("ModulusSize", modulusSize))
192                        modulusSize = alg.GetIntValueWithDefault("KeySize", 2048);
193
194                if (!alg.GetIntValue("SubgroupOrderSize", subgroupOrderSize))
195                        subgroupOrderSize = GetDefaultSubgroupOrderSize(modulusSize);
196
197                PrimeAndGenerator pg;
198                pg.Generate(GetFieldType() == 1 ? 1 : -1, rng, modulusSize, subgroupOrderSize);
199                p = pg.Prime();
200                q = pg.SubPrime();
201                g = pg.Generator();
202        }
203
204        Initialize(p, q, g);
205}
206
207#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
208void DL_GroupParameters_IntegerBased::EncodeElement(bool reversible, const Element &element, byte *encoded) const
209{
210        CRYPTOPP_UNUSED(reversible);
211        element.Encode(encoded, GetModulus().ByteCount());
212}
213
214unsigned int DL_GroupParameters_IntegerBased::GetEncodedElementSize(bool reversible) const
215{
216        CRYPTOPP_UNUSED(reversible);
217        return GetModulus().ByteCount();
218}
219#endif
220
221Integer DL_GroupParameters_IntegerBased::DecodeElement(const byte *encoded, bool checkForGroupMembership) const
222{
223        CRYPTOPP_UNUSED(checkForGroupMembership);
224        Integer g(encoded, GetModulus().ByteCount());
225        if (!ValidateElement(1, g, NULL))
226                throw DL_BadElement();
227        return g;
228}
229
230void DL_GroupParameters_IntegerBased::BERDecode(BufferedTransformation &bt)
231{
232        BERSequenceDecoder parameters(bt);
233                Integer p(parameters);
234                Integer q(parameters);
235                Integer g;
236                if (parameters.EndReached())
237                {
238                        g = q;
239                        q = ComputeGroupOrder(p) / 2;
240                }
241                else
242                        g.BERDecode(parameters);
243        parameters.MessageEnd();
244
245        SetModulusAndSubgroupGenerator(p, g);
246        SetSubgroupOrder(q);
247}
248
249void DL_GroupParameters_IntegerBased::DEREncode(BufferedTransformation &bt) const
250{
251        DERSequenceEncoder parameters(bt);
252                GetModulus().DEREncode(parameters);
253                m_q.DEREncode(parameters);
254                GetSubgroupGenerator().DEREncode(parameters);
255        parameters.MessageEnd();
256}
257
258bool DL_GroupParameters_IntegerBased::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
259{
260        return GetValueHelper<DL_GroupParameters<Element> >(this, name, valueType, pValue)
261                CRYPTOPP_GET_FUNCTION_ENTRY(Modulus);
262}
263
264void DL_GroupParameters_IntegerBased::AssignFrom(const NameValuePairs &source)
265{
266        AssignFromHelper(this, source)
267                CRYPTOPP_SET_FUNCTION_ENTRY2(Modulus, SubgroupGenerator)
268                CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupOrder)
269                ;
270}
271
272OID DL_GroupParameters_IntegerBased::GetAlgorithmID() const
273{
274        return ASN1::id_dsa();
275}
276
277void DL_GroupParameters_GFP::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
278{
279        ModularArithmetic ma(GetModulus());
280        ma.SimultaneousExponentiate(results, base, exponents, exponentsCount);
281}
282
283DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::MultiplyElements(const Element &a, const Element &b) const
284{
285        return a_times_b_mod_c(a, b, GetModulus());
286}
287
288DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const
289{
290        ModularArithmetic ma(GetModulus());
291        return ma.CascadeExponentiate(element1, exponent1, element2, exponent2);
292}
293
294Integer DL_GroupParameters_IntegerBased::GetMaxExponent() const
295{
296        return STDMIN(GetSubgroupOrder()-1, Integer::Power2(2*DiscreteLogWorkFactor(GetFieldType()*GetModulus().BitCount())));
297}
298
299unsigned int DL_GroupParameters_IntegerBased::GetDefaultSubgroupOrderSize(unsigned int modulusSize) const
300{
301        return 2*DiscreteLogWorkFactor(GetFieldType()*modulusSize);
302}
303
304NAMESPACE_END
305
306#endif
Note: See TracBrowser for help on using the repository browser.