I wanted to generate a random real (I guess rational) number.
To do this I wanted to use runif(1, min = m, max = M) and my thoughts were to set m; M (absolute) as large as possible in order to make the interval as large as possible. Which brings me to my question:
M <- .Machine$double.xmax
m <- -M
runif(1, m, M)
## which returns
[1] Inf
Why is it not returning a number? Is the chosen interval simply too large?
PS
> .Machine$double.xmax
[1] 1.797693e+308
As hinted by mt1022 the reason is in runif C source:
double runif(double a, double b)
{
if (!R_FINITE(a) || !R_FINITE(b) || b < a) ML_ERR_return_NAN;
if (a == b)
return a;
else {
double u;
/* This is true of all builtin generators, but protect against
user-supplied ones */
do {u = unif_rand();} while (u <= 0 || u >= 1);
return a + (b - a) * u;
}
}
In the return argument you can see the formula a + (b - a) * u which transoform uniformly [0, 1] generated random value in the user supplied interval [a, b]. In your case it will be -M + (M + M) * u. So M + M in case it 1.79E308 + 1.79E308 generates Inf. I.e. finite + Inf * finite = Inf:
M + (M - m) * runif(1, 0, 1)
# Inf
Is it safe to replace a/(b*c) with a/b/c when using integer-division on positive integers a,b,c, or am I at risk losing information?
I did some random tests and couldn't find an example of a/(b*c) != a/b/c, so I'm pretty sure it's safe but not quite sure how to prove it.
Thank you.
Mathematics
As mathematical expressions, ⌊a/(bc)⌋ and ⌊⌊a/b⌋/c⌋ are equivalent whenever b is nonzero and c is a positive integer (and in particular for positive integers a, b, c). The standard reference for these sorts of things is the delightful book Concrete Mathematics: A Foundation for Computer Science by Graham, Knuth and Patashnik. In it, Chapter 3 is mostly on floors and ceilings, and this is proved on page 71 as a part of a far more general result:
In the 3.10 above, you can define x = a/b (mathematical, i.e. real division), and f(x) = x/c (exact division again), and plug those into the result on the left ⌊f(x)⌋ = ⌊f(⌊x⌋)⌋ (after verifying that the conditions on f hold here) to get ⌊a/(bc)⌋ on the LHS equal to ⌊⌊a/b⌋/c⌋ on the RHS.
If we don't want to rely on a reference in a book, we can prove ⌊a/(bc)⌋ = ⌊⌊a/b⌋/c⌋ directly using their methods. Note that with x = a/b (the real number), what we're trying to prove is that ⌊x/c⌋ = ⌊⌊x⌋/c⌋. So:
if x is an integer, then there is nothing to prove, as x = ⌊x⌋.
Otherwise, ⌊x⌋ < x, so ⌊x⌋/c < x/c which means that ⌊⌊x⌋/c⌋ ≤ ⌊x/c⌋. (We want to show it's equal.) Suppose, for the sake of contradiction, that ⌊⌊x⌋/c⌋ < ⌊x/c⌋ then there must be a number y such that ⌊x⌋ < y ≤ x and y/c = ⌊x/c⌋. (As we increase a number from ⌊x⌋ to x and consider division by c, somewhere we must hit the exact value ⌊x/c⌋.) But this means that y = c*⌊x/c⌋ is an integer between ⌊x⌋ and x, which is a contradiction!
This proves the result.
Programming
#include <stdio.h>
int main() {
unsigned int a = 142857;
unsigned int b = 65537;
unsigned int c = 65537;
printf("a/(b*c) = %d\n", a/(b*c));
printf("a/b/c = %d\n", a/b/c);
}
prints (with 32-bit integers),
a/(b*c) = 1
a/b/c = 0
(I used unsigned integers as overflow behaviour for them is well-defined, so the above output is guaranteed. With signed integers, overflow is undefined behaviour, so the program can in fact print (or do) anything, which only reinforces the point that the results can be different.)
But if you don't have overflow, then the values you get in your program are equal to their mathematical values (that is, a/(b*c) in your code is equal to the mathematical value ⌊a/(bc)⌋, and a/b/c in code is equal to the mathematical value ⌊⌊a/b⌋/c⌋), which we've proved are equal. So it is safe to replace a/(b*c) in code by a/b/c when b*c is small enough not to overflow.
While b*c could overflow (in C) for the original computation, a/b/c can't overflow, so we don't need to worry about overflow for the forward replacement a/(b*c) -> a/b/c. We would need to worry about it the other way around, though.
Let x = a/b/c. Then a/b == x*c + y for some y < c, and a == (x*c + y)*b + z for some z < b.
Thus, a == x*b*c + y*b + z. y*b + z is at most b*c-1, so x*b*c <= a <= (x+1)*b*c, and a/(b*c) == x.
Thus, a/b/c == a/(b*c), and replacing a/(b*c) by a/b/c is safe.
Nested floor division can be reordered as long as you keep track of your divisors and dividends.
#python3.x
x // m // n = x // (m * n)
#python2.x
x / m / n = x / (m * n)
Proof (sucks without LaTeX :( ) in python3.x:
Let k = x // m
then k - 1 < x / m <= k
and (k - 1) / n < x / (m * n) <= k / n
In addition, (x // m) // n = k // n
and because x // m <= x / m and (x // m) // n <= (x / m) // n
k // n <= x // (m * n)
Now, if k // n < x // (m * n)
then k / n < x / (m * n)
and this contradicts the above statement that x / (m * n) <= k / n
so if k // n <= x // (m * n) and k // n !< x // (m * n)
then k // n = x // (m * n)
and (x // m) // n = x // (m * n)
https://en.wikipedia.org/wiki/Floor_and_ceiling_functions#Nested_divisions
link of question
http://codeforces.com/contest/615/problem/D
link of solution is
http://codeforces.com/contest/615/submission/15260890
In below code i am not able to understand why 1 is subtracted from mod
where mod=1000000007
ll d = 1;
ll ans = 1;
for (auto x : cnt) {
ll cnt = x.se;
ll p = x.fi;
ll fp = binPow(p, (cnt + 1) * cnt / 2, MOD);
ans = binPow(ans, (cnt + 1), MOD) * binPow(fp, d, MOD) % MOD;
d = d * (x.se + 1) % (MOD - 1);//why ??
}
Apart from the fact that there is the code does not make much sense as out of context as it is, there is the little theorem of Fermat:
Whenever MOD is a prime number, as 10^9+7 is, one can reduce exponents by multiples of (MOD-1) as for any a not a multiple of MOD
a ^ (MOD-1) == 1 mod MOD.
Which means that
a^b == a ^ (b mod (MOD-1)) mod MOD.
As to the code, which is efficient for its task, consider n=m*p^e where m is composed of primes smaller than p.
Then for each factor f of m there are factors 1*f, p*f, p^2*f,...,p^e*f of n. The product over all factors of n thus is the product over
p^(0+1+2+...+e) * f^(e+1) = p^( e*(e+1)/2 ) * f^(e+1)
over all factors f of m. Putting the numbers of factors as d and the product of factors of m as ans results in the combined formula
ans = ans^( e+1 ) * p^( d*e*(e+1)/2 )
d = d*(e+1)
which can now be recursively applied to the list of prime factors and their multiplicities.
How to calculate complexity of ths recursive algorithm?
int findMax(int a[ ], int l, int r)
{
if (r – l == 1)
return a[ l ];
int m = ( l + r ) / 2;
int u = findMax(a, l, m);
int v = findMax(a, m, r);
if (u > v)
return u;
else
return v;
}
From the Master Theorem:
T(n) = a * T(n/b) + f(n)
Where:
a is number of sub-problems
f(n) is cost of operation outside the recursion; f(n) = O(nc)
n/b size of the sub-problem
The idea behind this function is that you repeat the operation on the first half of items (T(n/2)) and on the second half of items (T(n/2)). You get the results and compare them (O(1)) so you have:
T(n) = 2 * T(n/2) + O(1)
So f(n) = O(1) and in terms of n value we get O(n0) - we need that to calculate c. So a = 2 and b = 2 and c = 0. From the Master Theorem (as correctly pointed out in comments) we end up with case where c < logba as log22 = 0. In this case the complexity of whole recursive call is O(n).
I have a RSA private key with modulus m, public exponent e and private exponent d, but the program I am using needs the modulus's prime factors p and q.
Is it possible to use e and d to get p and q?
Yes -- once you know the modulus N, and public/private exponents d and e, it is not too difficult to obtain p and q such that N=pq.
This paper by Dan Boneh describes an algorithm for doing so. It relies
on the fact that, by definition,
de = 1 mod phi(N).
For any randomly chosen "witness"
in (2,N), there is about a 50% chance of being able to use it to find a nontrivial
square root of 1 mod N (call it x). Then gcd(x-1,N) gives one of the factors.
You can use the open source tool I have developed in 2009 that converts RSA keys between the SFM format (n,e,d) and CRT format (p,q,dp,dq,u), and the other way around. It is on SourceForge : http://rsaconverter.sourceforge.net/
The algorithm I implemented is based on ideas presented by Dan Boneh, as described by the previous answer.
I hope this will be useful.
Mounir IDRASSI - IDRIX
I posted a response on the crypto stack exchange answering the same question here. It uses the same approach as outlined in Boneh's paper, but does a lot more explanation as to how it actually works. I also try to assume a minimal amount of prior knowledge.
Hope this helps!
I put in the effort to dig through Boneh's paper. The "algorithm" for deriving (p, q) from (n, d) is buried at the end of §1.1, coded in maths jargon, and left as an exercise for the reader to render out of his (rather terse) proof that it's efficient to do so.
Let 〈N, e〉 be an RSA public key. Given the private key d, one can efficiently factor the modulus N = pq.
Proof. Compute k = de − 1. By definition of d and e we know that k is a multiple of φ(N). Since φ(N) is even, k = 2tr with r odd and t ≥ 1. We have gk = 1 for every g ∈ ℤN×, and therefore gk/2 is a square root of unity modulo N. By the Chinese Remainder Theorem, 1 has four square roots modulo N = pq. Two of these square roots are ±1. The other two are ±x where x satisfies x = 1 mod p and x = −1 mod q. Using either one of these last two square roots, the factorization of N is revealed by computing gcd(x − 1, N). A straightforward argument shows that if g is chosen at random from ℤN× then with probability at least 1/2 (over the choice of g) one of the elements in the sequence gk/2, gk/4, …, gk/2t mod N is a square root of unity that reveals the factorization of N. All elements in the sequence can be efficiently computed in time O(n3) where n = log2(N).
Obviously, this is pretty close to meaningless for anyone who doesn't know what $Z_N^\ast$ is, and has a pretty nonlinear structure that takes a good deal of time to twist into a linear algorithm.
So here is the worked solution:
from random import randrange
from math import gcd
def ned_to_pqe(secret_key):
"""
https://crypto.stanford.edu/~dabo/papers/RSA-survey.pdf#:~:text=Given%20d%2C,reveals%20the%20factorization%20of%20N%2E
"""
n, e, d = secret_key
k = d * e - 1
t = bit_scan1(k)
trivial_sqrt1 = {1, n - 1}
while True:
g = randrange(2, n - 1)
for j in range(1, t + 1):
x = pow(g, k >> j, n)
if pow(x, 2, n) == 1:
if x in trivial_sqrt1: continue
p = gcd(x - 1, n)
q = n // p
if q > p: p, q = q, p
return p, q, e
def pqe_to_ned(secret_key):
p, q, e = secret_key
n = p * q
l = (p - 1) * (q - 1)
d = pow(e, -1, l)
return n, e, d
def bit_scan1(i):
"""
https://gmpy2.readthedocs.io/en/latest/mpz.html#mpz.bit_scan1
"""
# https://stackoverflow.com/a/63552117/1874170
return (i & -i).bit_length() - 1
def test():
secret_key = (
# https://en.wikipedia.org/wiki/RSA_numbers#RSA-100
# Should take upwards of an hour to factor on a consumer desktop ca. 2022
1522605027922533360535618378132637429718068114961380688657908494580122963258952897654000350692006139,
65537,
1435319569480661473883310243084583371347212233430112391255270984679722445287591616684593449660400673
)
if secret_key != pqe_to_ned(ned_to_pqe(secret_key)):
raise ValueError
if __name__ == '__main__':
test()
print("Self-test OK")
Live demo (JS):
function ned_to_pqe({n, e, d}) {
// https://crypto.stanford.edu/~dabo/papers/RSA-survey.pdf#:~:text=Given%20d%2C,reveals%20the%20factorization%20of%20N%2E
let k = d * e - 1n;
let t = scan1(k);
let trivial_sqrt1 = new Set([1n, n - 1n]);
while (true) {
let g = insecure_randrange(2n, n - 1n);
for ( let j = t ; j > 0 ; --j ) {
let x = bn_powMod(g, k >> j, n);
if (bn_powMod(x, 2n, n) === 1n) {
if (trivial_sqrt1.has(x)) continue;
let p = gcd(x - 1n, n), q = n/p;
if (q > p) [p, q] = [q, p];
return {p, q, e};
}
}
}
}
function pqe_to_ned({p, q, e}) {
let n = p * q;
let l = (p - 1n) * (q - 1n);
let d = bn_modInv(e, l);
return {n, e, d};
}
function bn_powMod(x, e, m) {
// h/t https://umaranis.com/2018/07/12/calculate-modular-exponentiation-powermod-in-javascript-ap-n/
if (m === 1n) return 0n;
let y = 1n;
x = x % m;
while (e > 0n) {
if (e % 2n === 1n) //odd number
y = (y * x) % m;
e = e >> 1n; //divide by 2
x = (x * x) % m;
}
return y;
}
function bn_modInv(x, m) {
// TOY IMPLEMENTATION
// DO NOT USE IN GENERAL-PURPOSE CODE
// h/t https://rosettacode.org/wiki/Modular_inverse#C
let m0 = m, t, q;
let x0 = 0n, y = 1n;
if (m === 1n) return 1n;
while (x > 1n) {
q = x / m;
t = m;
m = x % m;
x = t;
t = x0;
x0 = y - q * x0;
y = t;
}
if (y < 0n) y += m0;
return y;
}
function gcd(a, b) {
// h/t https://stackoverflow.com/a/17445304/1874170
while (b) {
[a, b] = [b, a % b];
}
return a;
}
function scan1(i) {
// https://gmplib.org/manual/Integer-Logic-and-Bit-Fiddling#mpz_scan1
let k = 0n;
if ( i !== 0n ) {
while( (i & 1n) === 0n ) {
i >>= 1n;
k += 1n;
}
}
return k;
}
function insecure_randrange(a, b) {
// h/t https://arxiv.org/abs/1304.1916
let numerator = 0n;
let denominator = 1n;
let n = (b - a);
while (true) {
numerator <<= 1n;
denominator <<= 1n;
numerator |= BigInt(Math.random()>1/2);
if (denominator >= n) {
if (numerator < n)
return a + numerator;
numerator -= n;
denominator -= n;
}
}
}
<form action="javascript:" onsubmit="(({target:form,submitter:{value:action}})=>{eval(action)(form)})(event)">
<p>
<label for="p">p=</label><input name="p" value="37975227936943673922808872755445627854565536638199" /><br />
<label for="q">q=</label><input name="q" value="40094690950920881030683735292761468389214899724061" /><br />
<label for="n">n=</label><input name="n" /><br />
<label for="e">e=</label><input name="e" placeholder="65537" /><br />
<label for="d">d=</label><input name="d" /><br />
</p>
<p>
<button type="submit" value="pqe2nd">Get (n,d) from (p,q,e)</button><br />
<button type="submit" value="delpq">Forget (p,q)</button><br />
<button type="submit" value="ned2pq">Get (p,q) from (n,e,d)</button>
</form>
<script>
function pqe2nd({elements}) {
if (!elements['e'].value) elements['e'].value = elements['e'].placeholder;
let p = BigInt(elements['p'].value||undefined);
let q = BigInt(elements['q'].value||undefined);
let e = BigInt(elements['e'].value||undefined);
let {n, d} = pqe_to_ned({p,q,e});
elements['n'].value = n.toString();
elements['d'].value = d.toString();
}
function ned2pq({elements}) {
if (!elements['e'].value) elements['e'].value = elements['e'].placeholder;
let n = BigInt(elements['n'].value||undefined);
let e = BigInt(elements['e'].value||undefined);
let d = BigInt(elements['d'].value||undefined);
let {p, q} = ned_to_pqe({n,e,d});
elements['p'].value = p.toString();
elements['q'].value = q.toString();
}
function delpq({elements}) {
elements['p'].value = null;
elements['q'].value = null;
}
</script>
To answer the question as-stated in the title: factoring N entails finding N. But you cannot, in the general case, derive N from (e, d). Therefore, you cannot, in the general case, derive the factors of N from (e, d); QED.
finding n from (e, d) is computationally feasible with fair probability, or even certainty, for a small but observable fraction of RSA keys of practical interest
If you want to try to do so anyway, you'll need to be able to factorize e * d - 1 (if I understand the above-linked answer correctly):
from itertools import permutations
def ed_to_pq(e, d):
# NOT ALWAYS POSSIBLE -- the number e*d-1 must be small enough to factorize
# h/t https://crypto.stackexchange.com/a/81620/8287
factors = factorize(e * d - 1)
factors.sort()
# Unimplemented optimization:
# if two factors are larger than (p * q).bit_length()//4
# and the greater of (p, q) is not many times bigger than the lesser,
# then you can safely assume that the large factors belong to (p-1) and (q-1)
# and thereby reduce the number of iterations in the following loops
# Unimplemented optimization:
# permutations are overkill for this partitioning scheme;
# a clever mathematician could come up with something more efficient
# Unimplemented optimization:
# prune permutations based on "sanity" factor of logarithm knapsacking
l = len(factors)
for arrangement in permutations(factors):
for l_pm1 in range(1, l - 1):
for l_qm1 in range(1, l_pm1):
pm1 = prod(arrangement[:l_pm1])
qm1 = prod(arrangement[l_pm1:l_pm1+l_qm1])
try:
if pow(e, -1, pm1 * qm1) == d:
return (pm1 + 1, qm1 + 1)
except Exception:
pass
from functools import reduce
from operator import mul
def prod(l):
return reduce(mul, l)