Get fundamental discriminant - python

Is there a function in Sage which returns the fundamental discriminant associated to a given discriminant?
See https://en.wikipedia.org/wiki/Fundamental_discriminant
This is the function I wrote, not finding an existing one:
def getFund(D):
if D % 4 == 2 or D % 4 == 3:
raise ValueError("Not a discriminant.")
if D == 0:
raise ValueError("There is no fundamental associated to 0.")
P = sign(D)
for p in factor(D):
if p[1] % 2 == 1:
P *= p[0]
if P % 4 == 2 or P % 4 == 3:
P *= 4
return P

What's the problem with fundamental_discriminant?
sage: fundamental_discriminant(1)
1
sage: fundamental_discriminant(3)
12
sage: fundamental_discriminant?
Signature: fundamental_discriminant(D)
Docstring:
Return the discriminant of the quadratic extension K=Q(sqrt{D}),
i.e. an integer d congruent to either 0 or 1, mod 4, and such that,
at most, the only square dividing it is 4.
INPUT:
* "D" - an integer
OUTPUT:
* an integer, the fundamental discriminant

I don't know if the function is implemented in SageMath.
But if I understand the definition correctly, you can define the function as follows:
def fundamental_discriminant(d):
if d % 4 == 1:
return d.squarefree_part()
if d % 4 == 0:
k = d.valuation(4)
dd = d // 4^k
if dd % 4 == 1:
return dd.squarefree_part()
if dd % 4 == 2:
return 4 * dd.squarefree_part()
if dd % 4 == 3:
return 4 * dd.squarefree_part()
raise ValueError("Not a discriminant.")

Related

How to count horseshoes in python?

I've completely stuck with this task and I really dunno how to make this program work properly, because I think I've already tried many possible options, but it still unfortunately didn't work properly.
The task is: "The blacksmith has to shoe several horses and needs to see if he has the correct number of horseshoes. Write a check(p, k) function that, for a given number of horseshoes p and number of horses k, prints out how many horseshoes are missing, remaining, or whether the number is correct (see sample file for output format)."
The code I've already done is:
def check(p, k):
if p % 2 == 0 and k % 2 == 0 and p % k == 0:
print("Remaining:", k % p)
elif p % k != 0:
print("Missing:", p // k + 1)
else:
print("OK")
check(20, 6)
check(10, 2)
check(12, 3)
check(13, 3)
The output should look like this:
Missing: 4
Remaining: 2
OK
Remaining: 1
You could try this:
def check(shoes, horses):
if shoes > 4*horses:
print("Remaining:", shoes - 4 * horses)
elif shoes == 4*horses:
print("OK")
else:
print("Missing:", 4 * horses - shoes)
Try checking if you have the correct number first:
def check(p, k):
required_shoes = k * 4
if p == required_shoes:
# just right
elif p < required_shoes:
# not enough
else:
# too many
def check(p, k):
if p / k == 4:
print("OK")
elif p / k > 4:
print("Remaining:", p - 4 * k)
else:
print("Missing:", 4 * k - p)
check(20, 6) # Missing: 4
check(10, 2) # Remaining: 2
check(12, 3) # OK
check(13, 3) # Remaining: 1
This works in the given cases

Why do my RSA values for p, q, e = 3 result in unsuccessful decryption?

I'm actually trying to solve cryptopals set 5 challenge 39. I'm trying to implement RSA for some larger primes p and q, e = 3. I've been puzzled over this for hours.
To generate primes, I'm hitting an API to get each prime. I keep generating p until gcd(p - 1, e) == 1, and then repeat for q until gcd(q - 1, e) == 1. I've tested for gcd((p - 1) * (q - 1), e) == 1, too. For example, I end up with p == 16226322033026808497, and q == 14712923008023747557.
I then do the simple RSA math to calculate the other terms, encrypt message 42 (no padding), decrypt that cipher, and compare the resulting plain to the original message. I've generated many, many ps and qs, and it never matches.
Can someone explain why this doesn't work, and help me generate some good parameters, please?
Python:
p = 16226322033026808497
q = 14712923008023747557
e = 3
print(f'1 == gcd(p - 1, e) == {gcd(p - 1, e)}')
print(f'1 == gcd(p - 1, e) == {gcd(q - 1, e)}')
phi = (p - 1) * (q - 1)
print(f'phi == {phi}')
print(f'1 == gcd(phi, e) == {gcd(phi, e)}')
n = p * q
print(f'n == {n}')
d = invmod(e, phi)
print(f'd == {d}')
print(f'1 == (d * e) % phi == {(d * e) % phi}')
m = 42
c = pow(m, e, n);
print(f'c == m**e % n == {c}')
p = pow(c, d, n);
print(f'p == c**d % n == {p}')
Output:
1 == gcd(p - 1, e) == 1
1 == gcd(p - 1, e) == 1
phi == 238736626775322802092761613952260035776
1 == gcd(phi, e) == 1
n == 238736626775322802123700858993310591829
d == 159157751183548534728507742634840023851
1 == (d * e) % phi == 1
c == m**e % n == 74088
p == c**d % n == 145835535613124975159078105657928869819
The API that I used to generate primes was in fact giving composites, which prevents meaningful decryption. Generating with a more reliable source, I find p == 18015945217661527751, q == 11788823512629961979, for example, which are actually prime. And I can now successfully decrypt back to the original message.
I've found that https://asecuritysite.com/encryption/random3 gives some reasonable primes.

Dynamic programming for primitive calculator

I'm dealing with the problem, that is pretty similar to change coins problem.
I need to implement a simple calculator, that can perform the following three operations with the current number x: multiply x by 2, multiply x by 3, or add 1 to x.
Goal is given a positive integer n, find the minimum number of operations needed to obtain the number n starting from the number 1.
I made a greedy approach to that, bur it shows incorrect results
import sys
def optimal_sequence(n):
sequence = []
while n >= 1:
sequence.append(n)
if n % 3 == 0:
n = n // 3
elif n % 2 == 0:
n = n // 2
else:
n = n - 1
return reversed(sequence)
input = sys.stdin.read()
n = int(input)
sequence = list(optimal_sequence(n))
print(len(sequence) - 1)
for x in sequence:
print(x)
For example:
Input: 10
Output:
4
1 2 4 5 10
4 steps. But the correct one is 3 steps:
Output:
3
1 3 9 10
I read about dynamic programming, and hope I could implement it here. But, I can't get how to use it properly in particular case, can someone give me an advice?
Just solve it with a simple recursion and Memoization:
Code:
d = {}
def f(n):
if n == 1:
return 1, -1
if d.get(n) is not None:
return d[n]
ans = (f(n - 1)[0] + 1, n - 1)
if n % 2 == 0:
ret = f(n // 2)
if ans[0] > ret[0]:
ans = (ret[0] + 1, n // 2)
if n % 3 == 0:
ret = f(n // 3)
if ans[0] > ret[0]:
ans = (ret[0] + 1, n // 3)
d[n] = ans
return ans
def print_solution(n):
if f(n)[1] != -1:
print_solution(f(n)[1])
print n,
def solve(n):
print f(n)[0]
print_solution(n)
print ''
solve(10)
Hint: f(x) returns a tuple (a, b), which a denotes the minimum steps to get x from 1, and b denotes the previous number to get the optimum solution. b is only used for print the solution.
Output:
4 # solution for 10
1 3 9 10
7 # solution for 111
1 2 4 12 36 37 111
You may debug my code and to learn how it works. If you are beginner at DP, you could read my another SO post about DP to get a quick start.
Since Python can't recurse a lot (about 10000), I write an iterative version:
# only modified function print_solution(n) and solve(n)
def print_solution(n):
ans = []
while f(n)[1] != -1:
ans.append(n)
n = f(n)[1]
ans.append(1)
ans.reverse()
for x in ans:
print x,
def solve(n):
for i in range(1, n):
f(i)[0]
print_solution(n)
print ''
solve(96234) # 1 3 9 10 11 22 66 198 594 1782 5346 16038 16039 32078 96234

(Miller-Rabin)How do I deal with number with large exponents?

I have Miller-Rabin implemntation
def MillerRabin(n,a):
e = 0
q = n-1
while q % 2 == 0:
e += 1
q = q/2
if a**q % n == 1:
return 1
for i in range(e):
if a ** (q * 2 ** i) % n == n-1:
return 1
return 0
(n, minA, maxA) = map(int, sys.argv[1:4])
print [MillerRabin(n, a) for a in range(minA,maxA)]
There are three inputs: number, min-base, max-base. Function works fine when number is low. But when number is way too big, I get an error (test case is number = 12530759607784496010584573923, min-base = 16, max-base = 32)
exponent must be at most 9223372036854775807
Use the builtin pow function. It can take an optional mod parameter
>>> help(pow)
Help on built-in function pow in module __builtin__:
pow(...)
pow(x, y[, z]) -> number
With two arguments, equivalent to x**y. With three arguments,
equivalent to (x**y) % z, but may be more efficient (e.g. for longs).
def MillerRabin(n, a):
e = 0
q = n-1
while q % 2 == 0:
e += 1
q = q // 2
if pow(a, q, n) == 1:
return 1
for i in range(e):
if pow(a , (q * 2 ** i) , n) == n - 1:
return 1
return 0

Python gcd calulation of rsa

def gcd(e, z):
if z == 0:
return e
else:
return gcd(z, e % z)
e = int(input("Please enter the first number:"))
z = int(input("Please enter the second number:"))
print ("The GCD of ",e," and ",z," is ",gcd(e,z))
d = 1
while d < e:
if d * e == 1 % z:
print (d," * ",e," = 1 (mod ",z,")")
d = d + 1
else:
d = d + 1
I am trying to use this code to find candidates for rsa by brute force it seems like it should work but it doesn't can anyone help me out?
z = (p − 1)(q − 1)
for the calculation of z is used prior to this
with p = 47 and q = 59, e = 17 and d = 157 but after the program runs it finds no matches but it should.
Where you have
if d * e == 1 % z:
you seem to want to check "Is d*e equal (mod z) to 1"
But what you're doing is performing 1 % z (which gives 1) and checking if d * e is equal to 1.
Change it to:
if (d*e) % z == 1:
and it should do the calculation you intend.
some problems from your code:
1) if z = (p-1)(q-1), d*e = 1 (mod z), then z and e are coprime, gcd(e, z) will always equal 1, see
2) if you say d*e = 1 (mod z), the code should be if d * e % z == 1

Categories