RustCrypto / crypto-bigint

Cryptography-oriented big integer library with constant-time, stack-allocated (no_std-friendly) implementations of modern formulas
Apache License 2.0
167 stars 45 forks source link

GCD with `Even` modulus #590

Open pinkforest opened 2 months ago

pinkforest commented 2 months ago

NIST.SP.800-56Br2 - Appendix C.2 - Deterministic Prime-Factor Recovery

The second part would require GCD(modulus - 1, public * private exp - 1)

1. Let a = (de – 1) × GCD(n – 1, de – 1).

This leads the modulus to be Even - https://github.com/RustCrypto/RSA/pull/394/files#r1553034591

However Bernstein-Yang (BY) GCD has a tripwire for left side to be Odd:

impl Gcd for BoxedUint {
    type Output = CtOption<Self>;

    fn gcd(&self, rhs: &Self) -> CtOption<Self> {
        let ret = bernstein_yang::boxed::gcd(self, rhs);
        CtOption::new(ret, self.is_odd())
    }
}

BearSSL Trick

Footnote 4. in bigint

Except at some point in RSA key pair generation, where we must invert the public exponent e modulo both p−1 and q−1, which are even. For that operation, BearSSL must employ additional tricks.

Go also seems to use the same "Extended Binary" GCD - by Thomas Pornin -

https://github.com/pornin/bingcd | https://eprint.iacr.org/2020/972.pdf | ncc

Go has report 3.3.2 for Inversion for both Even and Odd with "a standard trick" applied to calculate 𝑥−1 mod 𝑚

𝑢 := 𝑚−1 mod 𝑥 using odd moduli + um - 1 / x

https://cronokirby.com/papers/2021/06/bsc_report.pdf

Other related:

Yaoan Jin & Atsuko Miyaji - CT-GCD work if BY-GCD is not an option for Even modulus ?

Also Hamburg has a paper -https://eprint.iacr.org/2021/1271.pdf re: Jacobi & Bernstein-Yang

"It assumes that the given y is odd, which is often the case in cryptography; if y is not odd, the algorithm first divides out powers of 2 from y and/or x until y is odd"