How to use Crypto++ with DSA?

77 views
Skip to first unread message

Александр Мартынов

unread,
Nov 19, 2009, 11:49:45 AM11/19/09
to cryptop...@googlegroups.com
Hello!

 I need to check DSA digital signature on some data. I have next parameters:
  Signature Part R
  Signature Part S
  Big P
  Big Q
  Big G
  Big Y (public key of signer)

  I can't understand how to use Crypto++. I wrote such function:

bool checkDsaSignature( const ::std::string &message
                      , const ::std::string &signaturePartR
                      , const ::std::string &signaturePartS
                      , const ::std::string &saBigP // BigP
                      , const ::std::string &saBigQ // BigQ
                      , const ::std::string &saBigG // BigG
                      , const ::std::string &saPublicKey // BigY
                      )
   {
    try{
        using namespace CryptoPP;

        DSA::PublicKey publicKey;
        publicKey.Initialize( Integer( (const byte*)saBigP.data(), saBigP.size(), Integer::UNSIGNED)
                            , Integer( (const byte*)saBigQ.data(), saBigQ.size(), Integer::UNSIGNED)
                            , Integer( (const byte*)saBigG.data(), saBigG.size(), Integer::UNSIGNED)
                            , Integer( (const byte*)saPublicKey.data(), saPublicKey.size(), Integer::UNSIGNED)
                            );
        DSA::Verifier verifier( publicKey );
        SignatureVerificationFilter svf( verifier, 0, SignatureVerificationFilter::SIGNATURE_AT_BEGIN | SignatureVerificationFilter::PUT_RESULT );
    
        StringSource( signaturePartR+signaturePartS+message, true, new Redirector( svf ) );
    
        return svf.GetLastResult();
       }
    catch(...)
       {
        return false;
       }
   }

 but I think it's wrong, it' fails on any combinations of input. Possible, I don't undestand something in DSS/DSA usage, and|or in Crypto++ usage.

 DSA parameters are readed from file such this:
// Big p
C16C BAD3 4D47 5EC5 3966 95D6 94BC 8BC4 7E59 8E23 B5A9 D7C5 CEC8 2D65 B682 7D44 E953 7848 4730 C0BF F1F4 CB56 F47C 6E51 054B E892 00F3 0D43 DC4F EF96 24D4 665B.
// Big q
B7B8 10B5 8C09 34F6 4287 8F36 0B96 D7CC 26B5 3E4D.
// Big g
4C53 C726 BDBF BBA6 549D 7E73 1939 C6C9 3A86 9A27 C5DB 17BA 3CAC 589D 7B3E 003F A735 F290 CFD0 7A3E F10F 3515 5F1A 2EF7 0335 AF7B 6A52 11A1 1035 18FB A44E 9718.
// Big y
063A C955 F639 B2F9 202E 070C 4A10 E82F 877A BC7F D928 D5F4 55C2 A3BF E928 92C5 9EB5 5DB0 ED6A 9555 ED8F 1C6E F218 DB62 FFFD F74E 5755 A989 44C7 6B50 9C41 B022.

All of them converted into string that contains binary (not ascii hex) representation - bigP looks in debugger as string like "C1 6C BA D3 4D 47 5E C5...", R and S has the same format and representation. My docs tells me that message must be SHA-1 digest of data, I try to use both variants - put SHA-1 digest and put data as is (I guess that makeing SHA-1 hash is a part of DSA algoritm and Crypto++ will make it for me), but both versions not works.

 Can anybody take hints for me how it can be solved?

Jeffrey Walton

unread,
Nov 19, 2009, 6:25:11 PM11/19/09
to Александр Мартынов, cryptop...@googlegroups.com
Hi Александр,

> publicKey.Initialize(...)
What is the result of publicKey.Validate(3)?

> signaturePartR+signaturePartS+message...
SIGNATURE_AT_BEGIN is correct for the code below. What is
(signaturePartR+signaturePartS).length()? It must be exactly 40 bytes.

Jeff

2009/11/19 Александр Мартынов <marty...@gmail.com>:

Александр Мартынов

unread,
Nov 20, 2009, 4:41:28 AM11/20/09
to nolo...@gmail.com, cryptop...@googlegroups.com


20 ноября 2009 г. 2:25 пользователь Jeffrey Walton <nolo...@gmail.com> написал:

Hi Александр,

> publicKey.Initialize(...)
What is the result of publicKey.Validate(3)?
Hm. I can't understand how to call Validate.
call exact as your wrote Validate(3) takes compiler errors,
next code throws an exception and tells that NullRNG not allowed;
        #ifdef OS_RNG_AVAILABLE
            //AutoSeededX917RNG<AES> rng;
        #else
            // this is used to allow this function to compile on platforms that don't have auto-seeded RNGs
            //RandomNumberGenerator &rng(NullRNG());
        #endif
        if (!publicKey.Validate(rng,3)) return false;

and next code falls into infinite loop
        std::string tmpStr =
            "\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a"
            "\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4"
            "\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52"
            "\x62\x51";
        ByteQueue bq;
        bq.Put((const byte *)tmpStr.data(), tmpStr.size());
        FixedRNG rng(bq);
> signaturePartR+signaturePartS+message...
SIGNATURE_AT_BEGIN  is correct for the code below. What is
(signaturePartR+signaturePartS).length()? It must be exactly 40 bytes.
 
Yes, it is exact 40 bytes

Александр Мартынов

unread,
Nov 20, 2009, 5:32:45 AM11/20/09
to nolo...@gmail.com, cryptop...@googlegroups.com
20 ноября 2009 г. 2:25 пользователь Jeffrey Walton <nolo...@gmail.com> написал:
Hi Александр,


> publicKey.Initialize(...)
What is the result of publicKey.Validate(3)?

Next code works:
DefaultAutoSeededRNG rng;
publicKey.ThrowIfInvalid(rng,3);
 
and I catch an exception with message "CryptoMaterial: this object contains invalid values".
What can be wrong?
Parameters lengths are: BigP - 64 bytes, BigQ - 20 bytes, BigG - 64 bytes and public key - 64 bytes

Александр Мартынов

unread,
Nov 20, 2009, 5:56:54 AM11/20/09
to nolo...@gmail.com, cryptop...@googlegroups.com
Update:
I was define DSA_1024_BIT_MODULUS_ONLY=0 for all project in compiler
options and publicKey validation passed, but validation does not work.

2009/11/20, Александр Мартынов <marty...@gmail.com>:

Александр Мартынов

unread,
Nov 20, 2009, 6:09:02 AM11/20/09
to nolo...@gmail.com, cryptop...@googlegroups.com
Solution found - I pass all message as is, not a SHA-1 digest, and
verification passed.
Problem solved, thanks!

2009/11/20, Александр Мартынов <marty...@gmail.com>:
Reply all
Reply to author
Forward
0 new messages