ElGamal签名验证

时间:2014-09-12 09:53:37

标签: c# biginteger elgamal

我尝试实施ElGamal签名,但验证有问题。根据维基百科,如果出现以下情况,则消息m的签名(r,s)是正确的:
verification formula

有一个众所周知的计算ModPow的算法,用于签名步骤: enter image description here

但是我找不到计算第一个公式的方法。如果我试图直接计算功率,这似乎太大了。我在C#中编码并使用BigInteger,它甚至不允许用BigInteger指数计算功率 - 只接受公共整数,这是合理的,我想。是否有任何简化?这应该如何计算? 谢谢

3 个答案:

答案 0 :(得分:0)

我已经在matlab中实现了算法并且工作正常。我已经使用变量精度整数(vpi)来表示大数。

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

我相信C#会有类似的东西。

答案 1 :(得分:0)

您使用与计算g^k (mod p)square-and-multiply完全相同的算法来计算它。您不需要自己实现该算法,ModPow方法是BigInteger类型的一部分。

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

请注意,数学公式右侧的(mod p)不是运算符,它告诉您整个等式应该被视为一致模p。

答案 2 :(得分:0)

是的,您可以使用库gmp,链接选项-lgmp。
尽管,Python中有大量数字,但计算速度太慢,无法使用。
这是一个验证DSA中OpenSSL输出参数的示例。 使用此功能:

  

功能: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);
}

它可以编译为:

在debian系统中安装软件包
 sudo aptitude install libgmp-dev      
编译
   g++ -Wall -g -lgmp   dsa_alg.cpp -o dsa_alg  
运行./dsa_alg
  the modulus :1     
  the result:0