I'm trying to find D by factorizing N.
My N is 265291078722948385089717069136983657793
I've found P & Q using
n = p.q
P - 14716976826788780483
Q -18026193955816294571
Similarly I've found ɸ using
ɸ = (p - 1).(q - 1)
Next step says
Select e; such that, e is relatively prime to ɸ and e < ɸ, gcd (e, ɸ) = 1
Now I am stuck at this step and I'm unable to proceed through. Im not sure if this is the right way to factorize N to find D or not.
P.S - Last step is Select d; such that, d.e mod ɸ = 1 or e = 1 mod ɸ
using this step I'm supposed to find D. But I"m stuck at second last step.
Any help is appreciated. :)
EDIT (ANSWER) :
E =65537 (2^16 + 1), it is the most common form for encryption and is used widely.
The query boils down to
D*E mod ɸ = 1
which implies that D*E = Xɸ + 1, where X=1,2,3,4....
D = (Xɸ + 1)/E
now simply use the above logic to obtain the possible values for D :)
I would suggest to start with e=3, then try e=5, 7, 11 and so on.
The condition to satisfy is
(d * e) % φ(n) = 1
In your example φ(n) = 265291078722948385056973898354378582740
So, in order to find d, I would make a table
For e=3, d = (φ(n)+1) / e
= 265291078722948385056973898354378582741 / 3
= 88430359574316128352324632784792860913
Now find for e=5, 7 and so on
You do not need to guess e, because it is the public exponent, it should be out there in the public along with n in the public key (e, n) pair. Otherwise you have half key, any number co-prime to ɸ(n), gcd(e, ɸ(n)) = 1 is a candidate public exponent.
After you factorized the modulo n, you pretty much done. Just take the public exponent e and find the multiplicative modular inverse of e (mod ɸ(n)), i.e d . e ≡ 1 (mod ɸ(n)). You must get d because e and ɸ(n) must be co-primes to get an inverse.
Related
My problem is limited to unsigned integers of 256 bits.
I have a value x, and I need to descale it by the ratio n / d, where n < d.
The simple solution is of course x * n / d, but the problem is that x * n may overflow.
I am looking for any arithmetic trick which may help in reaching a result as accurate as possible.
Dividing each of n and d by gcd(n, d) before calculating x * n / d does not guarantee success.
Is there any process (iterative or other) which i can use in order to solve this problem?
Note that I am willing to settle on an inaccurate solution, but I'd need to be able to estimate the error.
NOTE: Using integer division instead of normal division
Let us suppose
x = ad + b
n = cd + e
Then find a,b,c,e as follows:
a = x/d
b = x%d
c = n/d
e = n%d
Then,
nx/d = acd + ae + bc + be/d
CALCULATING be/d
1. Represent e in binary form
2. Find b/d, 2b/d, 4b/d, 8b/d, ... 256b/d and their remainders
3. Find be/d = b*binary terms + their remainders
Example:
e = 101 in binary = 4+1
be/d = (b/d + 4b/d) + (b%d + 4b%d)/d
FINDING b/d, 2b/d, ... 256b/d
quotient(2*ib/d) = 2*quotient(ib /d) + (2*remainder(ib /d))/d
remainder(2*ib/d) = (2*remainder(ib/d))%d
Executes in O(number of bits)
I have been working on a Hackerearth Problem. Here is the problem statement:
We have three variables a, b and c. We need to convert a to b and following operations are allowed:
1. Can decrement by 1.
2. Can decrement by 2.
3. Can multiply by c.
Minimum steps required to convert a to b.
Here is the algorithm I came up with:
Increment count to 0.
Loop through till a === b:
1. Perform (x = a * c), (y = a - 1) and (z = a - 2).
2. Among x, y and z, choose the one whose absolute difference with b is the least.
3. Update the value of a to the value chosen among x, y and z.
4. Increment the count by 1.
I can get pass the basic test case but all my advance cases are failing. I guess my logic is correct but due to the complexity it seems to fail.
Can someone suggest a more optimized solution.
Edit 1
Sample Code
function findMinStep(arr) {
let a = parseInt(arr[0]);
let b = parseInt(arr[1]);
let c = parseInt(arr[2]);
let numOfSteps = 0;
while(a !== b) {
let multiply = Math.abs(b - (a * c));
let decrement = Math.abs(b - (a - 1));
let doubleDecrement = Math.abs(b - (a - 2));
let abs = Math.min(multiply, decrement, doubleDecrement);
if(abs === multiply) a = a * c;
else if(abs === decrement) a -= 1;
else a -= 2;
numOfSteps += 1;
}
return numOfSteps.toString()
}
Sample Input: a = 3, b = 10, c = 2
Explanation: Multiply 3 with 2 to get 6, subtract 1 from 6 to get 5, multiply 5 with 2 to get 10.
Reason for tagging both Python and JS: Comfortable with both but I am not looking for code, just an optimized algorithm and analytical thinking.
Edit 2:
function findMinStep(arr) {
let a = parseInt(arr[0]);
let b = parseInt(arr[1]);
let c = parseInt(arr[2]);
let depth = 0;
let queue = [a, 'flag'];
if(a === b ) return 0
if(a > b) {
let output = Math.floor((a - b) / 2);
if((a - b) % 2) return output + 1;
return output
}
while(true) {
let current = queue.shift();
if(current === 'flag') {
depth += 1;
queue.push('flag');
continue;
}
let multiple = current * c;
let decrement = current - 1;
let doubleDecrement = current -2;
if (multiple !== b) queue.push(multiple);
else return depth + 1
if (decrement !== b) queue.push(decrement);
else return depth + 1
if (doubleDecrement !== b) queue.push(doubleDecrement);
else return depth + 1
}
}
Still times out. Any more suggestions?
Link for the question for you reference.
BFS
A greedy approach won't work here.
However it is already on the right track. Consider the graph G, where each node represents a value and each edge represents one of the operations and connects two values that are related by that operation (e.g.: 4 and 3 are connected by "subtract 1"). Using this graph, we can easily perform a BFS-search to find the shortest path:
def a_to_b(a, b, c):
visited = set()
state = {a}
depth = 0
while b not in state:
visited |= state
state = {v - 1 for v in state if v - 1 not in visited} | \
{v - 2 for v in state if v - 2 not in visited} | \
{v * c for v in state if v * c not in visited}
depth += 1
return 1
This query systematically tests all possible combinations of operations until it reaches b by testing stepwise. I.e. generate all values that can be reached with a single operation from a, then test all values that can be reached with two operations, etc., until b is among the generated values.
In depth analysis
(Assuming c >= 0, but can be generalized)
So far for the standard-approach that works with little analysis. This approach has the advantage that it works for any problem of this kind and is easy to implement. However it isn't very efficient and will reach it's limits fairly fast, once the numbers grow. So instead I'll show a way to analyze the problem in depth and gain a (far) more performant solution:
In a first step this answer will analyze the problem:
We need operations -->op such that a -->op b and -->op is a sequence of
subtract 1
subtract 2
multiply by c
First of all, what happens if we first subtract and afterwards multiply?
(a - x) * c = a * c - x * c
Next what happens, if we first multiply and afterwards subtract?
a * c - x'
Positional systems
Well, there's no simplifying transformation for this. But we've got the basic pieces to analyze more complicated chains of operations. Let's see what happens when we chain subtractions and multiplications alternatingly:
(((a - x) * c - x') * c - x'') * c - x'''=
((a * c - x * c - x') * c - x'') * c - x''' =
(a * c^2 - x * c^2 - x' * c - x'') * c - x''' =
a * c^3 - x * c^3 - x' * c^2 - x'' * c - x'''
Looks familiar? We're one step away from defining the difference between a and b in a positional system base c:
a * c^3 - x * c^3 - x' * c^2 - x'' * c - x''' = b
x * c^3 + x' * c^2 + x'' * c + x''' = a * c^3 - b
Unfortunately the above is still not quite what we need. All we can tell is that the LHS of the equation will always be >=0. In general, we first need to derive the proper exponent n (3 in the above example), s.t. it is minimal, nonnegative and a * c^n - b >= 0. Solving this for the individual coefficients (x, x', ...), where all coefficients are non-negative is a fairly trivial task.
We can show two things from the above:
if a < b and a < 0, there is no solution
solving as above and transforming all coefficients into the appropriate operations leads to the optimal solution
Proof of optimality
The second statement above can be proven by induction over n.
n = 0: In this case a - b < c, so there is only one -->op
n + 1: let d = a * c^(n + 1) - b. Let d' = d - m * c^(n + 1), where m is chosen, such that d' is minimal and nonnegative. Per induction-hypothesis d' can be generated optimally via a positional system. Leaving a difference of exactly m * c^n. This difference can not be covered more efficiently via lower-order terms than by m / 2 subtractions.
Algorithm (The TLDR-part)
Consider a * c^n - b as a number base c and try to find it's digits. The final number should have n + 1 digits, where each digit represents a certain number of subtractions. Multiple subtractions are represented by a single digit by addition of the subtracted values. E.g. 5 means -2 -2 -1. Working from the most significant to the least significant digit, the algorithm operates as follows:
perform the subtractions as specified by the digit
if the current digit is was the last, terminate
multiply by c and repeat from 1. with the next digit
E.g.:
a = 3, b = 10, c = 2
choose n = 2
a * c^n - b = 3 * 4 - 10 = 2
2 in binary is 010
steps performed: 3 - 0 = 3, 3 * 2 = 6, 6 - 1 = 5, 5 * 2 = 10
or
a = 2, b = 25, c = 6
choose n = 2
a * c^n - b = 47
47 base 6 is 115
steps performed: 2 - 1 = 1, 1 * 6 = 6, 6 - 1 = 5, 5 * 6 = 30, 30 - 2 - 2 - 1 = 25
in python:
def a_to_b(a, b, c):
# calculate n
n = 0
pow_c = 1
while a * pow_c - b < 0:
n += 1
pow_c *= 1
# calculate coefficients
d = a * pow_c - b
coeff = []
for i in range(0, n + 1):
coeff.append(d // pow_c) # calculate x and append to terms
d %= pow_c # remainder after eliminating ith term
pow_c //= c
# sum up subtractions and multiplications as defined by the coefficients
return n + sum(c // 2 + c % 2 for c in coeff)
def pythagorean(n):
aAndB = []
for a in range(150, n-1):
for b in range(150, n):
for c in range(150,n+1):
if (c * c) == a *a + b*b and a + b + c == 1000:
aAndB.append(a)
return aAndB
print(pythagorean(500))
So I made this function to find pythagorean triplets that meets criteria a+b+c=1000. When I run this, I get [200,375]. Question is why do I receive two numbers in my list aAndB when I specifically asked to append an item for a?
If I try it with aAndB.append(c), the result shows [425, 425]. How do I fix it only to show exactly one element in the list?
Thank you for your help!
That's because there are 2 values, that satisfy your condition:
if (c * c) == a *a + b*b and a + b + c == 1000:
You can debug the code or just add more information in array, like that:
def pythagorean(n):
aAndB = []
for a in range(150, n-1):
for b in range(150, n):
for c in range(150,n+1):
if (c * c) == a * a + b * b and a + b + c == 1000:
aAndB.append({'a': a, 'b': b, 'c': c})
return aAndB
result = pythagorean(500)
for v in result:
print(v)
So if you want just one element - choose which one from 'result' array.
For example, if you want only first:
first_element = None
if len(result) > 0:
first_element = result[0]
print('First element:', first_element)
You can use euclid’s proof of pythagoreas triplets. You can choose any arbitrary numbers greater than zero say m,n. According to euclid the triplet will be a(m∗m−n∗n),b(2∗m∗n),c(m∗m+n∗n). Now apply this formula to find out the triplets , say our one value of triplet is 6 then, other two.
a(m∗m−n∗n),b(2∗m∗n),c(m∗m+n∗n)
It is sure that b(2∗m∗n) is obviously even. So now
(2∗m∗n)=6 =>(m∗n)=3 =>m∗n=3∗1 =>m=3,n=1
You can take any other value rather than 3 and 1 but those two values should hold the product of two numbers is 3 (m∗n=3).
Now , when m equals 3 and n equals 1 then
a(m∗m−n∗n)=(3∗3−1∗1)=8 , c(m∗m−n∗n)=(3∗3+1∗1)=10
6,8,10 is our triplet for value this our visualization of how generating triplets .
If given number is odd like (9) then slightly modified here, because b(2∗m∗n) never be odd. So, here we have to take
a(m∗m−n∗n)=7 , (m+n)∗(m−n)=7∗1 , So,(m+n)=7,(m−n)=1
Now find m and n from here then find other two values.
Do code according this , it will generate distinct triplets and efficiently
I am trying to implement the Johnson-Lindenstrauss lemma. I have search for the pseudocode here but could not get any.
I don't know if I have implemented it correctly or not. I just want you guys who understand the lemma to please check my code for me and advice me as to the correct matlab implementation.
n = 2;
d = 4;
k = 2;
G = rand(n,d);
epsilon = sqrt(log(n)/k);
% Projection in dim k << d
% Defining P (k x d)
P = randn(k,d);
% Projecting down to k-dim
proj = P.*G;
u = proj(:,1);
v = proj(:,2);
% u = P * G(:,5);
% v = P * G(:,36);
norm(G(:,1)-G(:,2))^2 * k * (1-epsilon);
norm(u - v)^2;
norm(G(:,1)-G(:,2))^2 * k * (1+epsilon);
for the first part of that to find the epsilon you need to solve a polynomial equation.
n = 2;
k = 2;
pol1 = [-1/3 1/2 0 4*log2(n)/k];
c = roots(pol1)
1.4654 + 1.4304i
1.4654 - 1.4304i
-1.4308 + 0.0000i
Then you need to remove the complex roots and keep the real one:
epsilon = c(imag(c)==0);
% if there are more than one root with imaginary part equal to 0 then you need to select the smaller one.
now you know that the epsilon should be equal or greater that the result.
For any set of m points in R^N and for k = 20*logm/epsilon^2 and epsilon < 1/2:
1/sqrt(k).*randn(k,N)
obtain Pr[success]>=1-2m^(5*epsilon-3)
An R package is available to perform Random projection using Johnson Lindenstrauss Lemma RandPro
Following is text from Data structure and algorithm analysis by Mark Allen Wessis.
Following x(i+1) should be read as x subscript of i+1, and x(i) should be
read as x subscript i.
x(i + 1) = (a*x(i))mod m.
It is also common to return a random real number in the open interval
(0, 1) (0 and 1 are not possible values); this can be done by
dividing by m. From this, a random number in any closed interval [a,
b] can be computed by normalizing.
The problem with this routine is that the multiplication could
overflow; although this is not an error, it affects the result and
thus the pseudo-randomness. Schrage gave a procedure in which all of
the calculations can be done on a 32-bit machine without overflow. We
compute the quotient and remainder of m/a and define these as q and
r, respectively.
In our case for M=2,147,483,647 A =48,271, q = 127,773, r = 2,836, and r < q.
We have
x(i + 1) = (a*x(i))mod m.---------------------------> Eq 1.
= ax(i) - m (floorof(ax(i)/m)).------------> Eq 2
Also author is mentioning about:
x(i) = q(floor of(x(i)/q)) + (x(i) mod Q).--->Eq 3
My question
what does author mean by random number is computed by normalizing?
How author came with Eq 2 from Eq 1?
How author came with Eq 3?
Normalizing means if you have X ∈ [0,1] and you need to get Y ∈ [a, b] you can compute
Y = a + X * (b - a)
EDIT:
2. Let's suppose
a = 3, x = 5, m = 9
Then we have
where [ax/m] means an integer part.
So we have 15 = [ax/m]*m + 6
We need to get 6. 15 - [ax/m]*m = 6 => ax - [ax/m]*m = 6 => x(i+1) = ax(i) - [ax(i)/m]*m
If you have a random number in the range [0,1], you can get a number in the range [2,5] (for example) by multiplying by 3 and adding 2.