Java 中的模幂

发布于 2024-09-30 05:28:44 字数 507 浏览 8 评论 0原文

我需要一种计算方法:

(g^u * y^v) mod p

用Java。

我发现了这个计算 (g^u) mod p 的算法:

int modulo(int a,int b,int c) {
    long x=1
    long y=a;
    while(b > 0){
        if(b%2 == 1){
            x=(x*y)%c;
        }
        y = (y*y)%c; // squaring the base
        b /= 2;
    }
    return (int) x%c;
}

它效果很好,但我似乎找不到一种方法来做到这一点,

(g^u * y^v) mod p

因为我的数学技能很差。

放在上下文中,它是“简化”DSA 的 java 实现 - 验证部分需要解决这个问题。

I need a way to calculate:

(g^u * y^v) mod p

in Java.

I've found this algorithm for calculating (g^u) mod p:

int modulo(int a,int b,int c) {
    long x=1
    long y=a;
    while(b > 0){
        if(b%2 == 1){
            x=(x*y)%c;
        }
        y = (y*y)%c; // squaring the base
        b /= 2;
    }
    return (int) x%c;
}

and it works great, but I can't seem to find a way to do this for

(g^u * y^v) mod p

as my math skills are lackluster.

To put it in context, it's for a java implementation of a "reduced" DSA - the verifying part requires this to be solved.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

嘿咻 2024-10-07 05:28:44

假设这两个因子不会溢出,我相信您可以这样简化表达式:

(x * y) mod p = ( (x mod p)*(y mod p) ) mod p(x * y) mod p = ( (x mod p)*(y mod p) ) mod p.我相信你可以从那里弄清楚。

Assuming that the two factors will not overflow, I believe you can simplify an expression like that in this way:

(x * y) mod p = ( (x mod p)*(y mod p) ) mod p. I'm sure you can figure it out from there.

年少掌心 2024-10-07 05:28:44

该代码片段实现了众所周知的“快速求幂”算法,也称为平方求幂

它还使用 (a * b) mod p = ((a mod p) * (b mod p)) mod p 的事实。 (加法和乘法都是在取素数模的情况下保留的结构——它是同态)。这样,算法中的每个点都会减少到小于 p 的数字。

虽然您可以尝试在循环中以交错方式计算这些值,但这样做并没有真正的好处。只需分别计算它们,将它们相乘,最后一次取模即可。

请注意,如果 p^2 大于可表示的最大 int,您将发生溢出,这将导致您得到错误的答案。对于 Java,切换到大整数可能是谨慎的做法,或者至少对 p 的大小进行运行时检查并抛出异常。

最后,如果这是出于加密目的,您可能应该使用库来执行此操作,而不是自己实现。很容易做一些看似有效的轻微错误,但提供的安全性极低甚至没有。

That fragment of code implements the well known "fast exponentiation" algorithm, also known as Exponentiation by squaring.

It also uses the fact that (a * b) mod p = ((a mod p) * (b mod p)) mod p. (Both addition and multiplications are preserved structures under taking a prime modulus -- it is a homomorphism). This way at every point in the algorithm it reduces to numbers smaller than p.

While you could try to calculate these in an interleaved fashion in a loop, there's no real benefit to doing so. Just calculate them separately, multiply them together, and take the mod one last time.

Be warned that you will get overflow if p^2 is greater than the largest representable int, and that this will cause you to have the wrong answer. For Java, switching to big integer might be prudent, or at least doing a runtime check on the size of p and throwing an exception.

Finally, if this is for cryptographic purposes, you should probably be using a library to do this, rather than implementing it yourself. It's very easy to do something slightly wrong that appears to work, but provides minimal to no security.

可遇━不可求 2024-10-07 05:28:44

尝试

(Math.pow(q, u) * Math.pow(y, v)) % p

Try

(Math.pow(q, u) * Math.pow(y, v)) % p

他不在意 2024-10-07 05:28:44

下面是一些示例代码,它输入原始问题中的变量并遵循 Christian Mann 的答案。
BigInteger 解决了溢出问题。
返回语句是一个 BigInteger。

    public static BigInteger ModularExponent(BigInteger G, BigInteger U, BigInteger Y, BigInteger V, BigInteger P) {
      
      return ((G.modPow(U,P)).multiply(Y.modPow(V,P))).mod(P);
    }

Here's some sample code that inputs the variables in the original question and follows on from Christian Mann's answer.
BigInteger gets around the overflow issues.
The return statement is a BigInteger.

    public static BigInteger ModularExponent(BigInteger G, BigInteger U, BigInteger Y, BigInteger V, BigInteger P) {
      
      return ((G.modPow(U,P)).multiply(Y.modPow(V,P))).mod(P);
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文