1
0
mirror of https://github.com/MariaDB/server.git synced 2025-11-27 05:41:41 +03:00
Files
mariadb/extra/yassl/taocrypt/src/dsa.cpp
2016-10-13 11:18:30 +02:00

275 lines
5.0 KiB
C++

/*
Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#include "runtime.hpp"
#include "dsa.hpp"
#include "sha.hpp"
#include "asn.hpp"
#include "modarith.hpp"
namespace TaoCrypt {
void DSA_PublicKey::Swap(DSA_PublicKey& other)
{
p_.Swap(other.p_);
q_.Swap(other.q_);
g_.Swap(other.g_);
y_.Swap(other.y_);
}
DSA_PublicKey::DSA_PublicKey(const DSA_PublicKey& other)
: p_(other.p_), q_(other.q_), g_(other.g_), y_(other.y_)
{}
DSA_PublicKey& DSA_PublicKey::operator=(const DSA_PublicKey& that)
{
DSA_PublicKey tmp(that);
Swap(tmp);
return *this;
}
DSA_PublicKey::DSA_PublicKey(Source& source)
{
Initialize(source);
}
void DSA_PublicKey::Initialize(Source& source)
{
DSA_Public_Decoder decoder(source);
decoder.Decode(*this);
}
void DSA_PublicKey::Initialize(const Integer& p, const Integer& q,
const Integer& g, const Integer& y)
{
p_ = p;
q_ = q;
g_ = g;
y_ = y;
}
const Integer& DSA_PublicKey::GetModulus() const
{
return p_;
}
const Integer& DSA_PublicKey::GetSubGroupOrder() const
{
return q_;
}
const Integer& DSA_PublicKey::GetSubGroupGenerator() const
{
return g_;
}
const Integer& DSA_PublicKey::GetPublicPart() const
{
return y_;
}
void DSA_PublicKey::SetModulus(const Integer& p)
{
p_ = p;
}
void DSA_PublicKey::SetSubGroupOrder(const Integer& q)
{
q_ = q;
}
void DSA_PublicKey::SetSubGroupGenerator(const Integer& g)
{
g_ = g;
}
void DSA_PublicKey::SetPublicPart(const Integer& y)
{
y_ = y;
}
word32 DSA_PublicKey::SignatureLength() const
{
return GetSubGroupOrder().ByteCount() * 2; // r and s
}
DSA_PrivateKey::DSA_PrivateKey(Source& source)
{
Initialize(source);
}
void DSA_PrivateKey::Initialize(Source& source)
{
DSA_Private_Decoder decoder(source);
decoder.Decode(*this);
}
void DSA_PrivateKey::Initialize(const Integer& p, const Integer& q,
const Integer& g, const Integer& y,
const Integer& x)
{
DSA_PublicKey::Initialize(p, q, g, y);
x_ = x;
}
const Integer& DSA_PrivateKey::GetPrivatePart() const
{
return x_;
}
void DSA_PrivateKey::SetPrivatePart(const Integer& x)
{
x_ = x;
}
DSA_Signer::DSA_Signer(const DSA_PrivateKey& key)
: key_(key)
{}
word32 DSA_Signer::Sign(const byte* sha_digest, byte* sig,
RandomNumberGenerator& rng)
{
const Integer& p = key_.GetModulus();
const Integer& q = key_.GetSubGroupOrder();
const Integer& g = key_.GetSubGroupGenerator();
const Integer& x = key_.GetPrivatePart();
byte* tmpPtr = sig; // initial signature output
Integer k(rng, 1, q - 1);
r_ = a_exp_b_mod_c(g, k, p);
r_ %= q;
Integer H(sha_digest, SHA::DIGEST_SIZE); // sha Hash(m)
Integer kInv = k.InverseMod(q);
s_ = (kInv * (H + x*r_)) % q;
if (!(!!r_ && !!s_))
return (word32) -1;
int rSz = r_.ByteCount();
int tmpSz = rSz;
while (tmpSz++ < SHA::DIGEST_SIZE) {
*sig++ = 0;
}
r_.Encode(sig, rSz);
sig = tmpPtr + SHA::DIGEST_SIZE; // advance sig output to s
int sSz = s_.ByteCount();
tmpSz = sSz;
while (tmpSz++ < SHA::DIGEST_SIZE) {
*sig++ = 0;
}
s_.Encode(sig, sSz);
return 40;
}
DSA_Verifier::DSA_Verifier(const DSA_PublicKey& key)
: key_(key)
{}
bool DSA_Verifier::Verify(const byte* sha_digest, const byte* sig)
{
const Integer& p = key_.GetModulus();
const Integer& q = key_.GetSubGroupOrder();
const Integer& g = key_.GetSubGroupGenerator();
const Integer& y = key_.GetPublicPart();
int sz = q.ByteCount();
r_.Decode(sig, sz);
s_.Decode(sig + sz, sz);
if (r_ >= q || r_ < 1 || s_ >= q || s_ < 1)
return false;
Integer H(sha_digest, SHA::DIGEST_SIZE); // sha Hash(m)
Integer w = s_.InverseMod(q);
Integer u1 = (H * w) % q;
Integer u2 = (r_ * w) % q;
// verify r == ((g^u1 * y^u2) mod p) mod q
ModularArithmetic ma(p);
Integer v = ma.CascadeExponentiate(g, u1, y, u2);
v %= q;
return r_ == v;
}
const Integer& DSA_Signer::GetR() const
{
return r_;
}
const Integer& DSA_Signer::GetS() const
{
return s_;
}
const Integer& DSA_Verifier::GetR() const
{
return r_;
}
const Integer& DSA_Verifier::GetS() const
{
return s_;
}
} // namespace