1

I try to implement ElGamal signature, but have a trouble with verification. According to wikipedia, signature (r,s) of message m is correct if:
verification formula

There is a well-known algorithm for calculating ModPow, which is used on signing step: enter image description here

But I can't find a way to calculate the first formula. It seems that this would be too huge number if I try to calculate power directly. I code in C# and use BigInteger, which even doesn't allow to calculate the power with the BigInteger exponent - only common integers are accepted, which is reasonable, I suppose.
Is there any simplification? How this is supposed to be calculated? Thank you

Celestis
  • 525
  • 1
  • 4
  • 11

3 Answers3

0

I have implemented the algorithm in matlab and its working fine. I have used variable precision integer (vpi) for large numbers.

zvyr = vpi(mod(((y^r)*(r^s)),p))

I believe something similar would be available for C#.

Magnilex
  • 11,584
  • 9
  • 62
  • 84
Ajay
  • 1
  • I removed your question from this answer. If you have an own question, you should post it as a question instead. – Magnilex Mar 18 '15 at 16:39
0

You calculate it using exactly the same algorithm as you use to compute g^k (mod p), square-and-multiply. You don't need to implement that algorithm yourself, the ModPow method is part of the BigInteger type.

bool success = BigInteger.ModPow(g, h, p) ==
               (BigInteger.ModPow(y, r, p) + BigInteger.ModPow(r, s, p)) % p;

Note that (mod p) to the right of a mathematical formula isn't an operator, it tells you that the whole equation should be treated as congruency modulo p.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
0

Yes ,you can use the library gmp, linking option -lgmp.
Although, There is big number in Python, the calculation speed is too slow to use.
This is an example to verify the parameters of the output of OpenSSL in DSA。 Use this function:

Function: void mpz_powm (mpz_t rop, const mpz_t base, const mpz_t exp, const mpz_t mod)

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include "gmp.h"
int main()
{
    mpz_t P;    // a big prime
    mpz_t Q;    // order
    mpz_t G;    // generator 
    mpz_t pub;  // public key
    mpz_t priv; // private key
    mpz_t tmp; //  tmp variable

    //  Initialize a NULL-terminated list of mpz_t variables, and set their values to 0.
    mpz_inits (P ,Q, G, pub, priv,  tmp, NULL);

    mpz_set_str (P, "0x00e79d25ca547dc8931850eaaa6784e365eecf69374243d902c12df7d4896a9e5b8717c4c7b24e30d1b468061838f5bc76df050ef6b7c58105ee2cf23ecb67e7d89830a0976f606e194d0b85e6566cca6275b7b184416337fc7ac37bebe9c9f76e982b9a82ee0a904900a0a7f76f4760e76120ecd2732a1dfe9a1dfa568757690670460688205a7e0d744feacdc27416a27afe5233dd58945801af83c7fd7199dcbed00819750c81cd3f2b5d68c29cd43e035eed70bfd85f55259df953f4f69d719ebe5c06b3443d249b110e602d81366ea88407ed81d3cf6f6fcea1bb7f9af563d2ca436d5c2d794f06407d1f111cb25a86f7568368e085ebe31f7eb8b9bedb89", 0); //  the prime P 
    mpz_set_str (Q, "0x00c39250922561c4b56a9c1bfb0d523bbfe8395182c5464b38a1d9959aa121871b", 0); // the order 
    mpz_set_str (G, "0x6cde6920c61fa80e51212de15be6b2aca93174e3fd5d479d08affb57222370c9047b099ea9e9d53b694915967709580b77a5cfd70629e1308c9db7a9e8c2f41f3c7c792c9ffe9dd6695bbc549d2a008005c18e75096c9d455de4d75011dfaa4d18df4ee955de3da692b2a49084285794d9e53df199b0dd5514bee1e387e897d971b6e56f9dcb49bf8a5a4470bf0216816b4ce1ab498957cb5dcc4ef64146a1a424b2d829fe29215e998590213053735618df90485353cee4702194c4de66bd77c3d9cf0fa45ef4b64b5c41186735b46805d2eaf91542507a28805db5838ac3d17ed3227764f5b80d19d8f752f58f01eec5ba12a4c8375a5a47b11f0dc36c2679", 0);  // generator
    mpz_set_str (priv, "0x404dcd0061be1e3d4e5dac6322600d442c1f55fd15b5ecc3d6ad52b527cf44b8", 0); // private key 
    mpz_set_str (pub, "0x71fd06b1b4c4ea7b392b6f33486063db6fe318559046bf750e4b236d59b883ca9174b3e8c9fc788aa2b926d2eaddd36fa7610e6d91822818a69526057d65c4fe1f7e7620ac54164c21ea2c27783eeb58880a3758b7b8f570383c964f37756f5b331d2afda9bc104e99d1a7fb2d29abf9017fac13cf87b4a6d18838c16aa52e130a3ca1b8b88ce830f982200c5dba7369934af4aee15a83963874b0c04d1fd57cf7525b46e4add4f57c892fefa698be330c22282145ada2589a1a2d2816c470164341a8482de9ad72ed1d636a7836b91218932c565c2b5a5ab03ca5704ca5da13904e0bbd6288d99a9827b751de19bb7c165ce3d910f94f43d6166def03aa895b", 0); // public key 

    // verify (G^Q)%P==1
    //Negative exp is supported if an inverse base^-1 mod mod exists (see mpz_invert in Number Theoretic Functions). If an inverse doesn’t exist then a divide by zero is raised.
    mpz_powm(tmp, G, Q, P);
    printf("the modulus :");
    mpz_out_str(stdout, 10, tmp);
    printf("\n");

    // verify the private == public key 
    mpz_powm(tmp, G, priv, P);
    int result = mpz_cmp(tmp, pub);
    printf("the result:%d\n", result);
}

It can be compiled as:

Install the package in debian system
 sudo aptitude install libgmp-dev      
compile
   g++ -Wall -g -lgmp   dsa_alg.cpp -o dsa_alg  
run ./dsa_alg
  the modulus :1     
  the result:0   
孙海城
  • 1
  • 1