I am looking for a reduced way of this code. I had to do the division separately because of the multiplicative inverse condition.
"""This code calculates the multiplication Elliptic curves over Zp"""
#Initial values for testing
yq = 3
yp = 3
xq = 8
xp = 8
a = 1
p = 11
#Calculate the Euclid greatest common divisor
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return g, x - (b // a) * y, y
#Calculate the multiplicate inverse
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('Mod inverse does not exist')
else:
return x % m
#veces = Number of times for the multiplication
veces = 7
print(f"The next results are the multiplication of {veces}*({xp},{yp})")
z = 1
while z <= (veces - 1):
if xp == xq and yp == yq:
numerador = (3 * pow(xp, 2) + a) % p
denominador = ((2 * yp) % p)
inver = modinv(denominador, p)
landa = (inver * numerador) % p
else:
numerador = (yq - yp) % p
denominador = (xq - xp) % p
inver = modinv(denominador, p)
landa = (inver * numerador) % p
xr = (pow(landa, 2) - xp - xq) % p
yr = (landa * (xp - xr) - yp) % p
z += 1
xp, yp = xr, yr
print(f"The result is ({xp},{yp})")
#Any way to simplify this code? I had to do the division separately but I think we can a reducted code for the division.
Related
I have the following code:
#!/usr/bin/env lua5.3
-- Code adapted from https://github.com/EmmanuelOga/columns/blob/master/utils/color.lua#L51
local function hslToRgb(h, s, l, a)
local r, g, b
h = (h / 255)
s = (s / 100)
l = (l / 100)
if s == 0 then
r, g, b = l, l, l -- achromatic
else
local function hue2rgb(p, q, t)
if t < 0 then t = t + 1 end
if t > 1 then t = t - 1 end
if t < 1/6 then return p + (q - p) * 6 * t end
if t < 1/2 then return q end
if t < 2/3 then return p + (q - p) * (2/3 - t) * 6 end
return p
end
local q
if l < 0.5 then q = l * (1 + s) else q = l + s - l * s end
local p = 2 * l - q
r = hue2rgb(p, q, h + 1/3)
g = hue2rgb(p, q, h)
b = hue2rgb(p, q, h - 1/3)
end
if not a then a = 1 end
return r * 255, g * 255, b * 255, a * 255
end
local h,s,l,a
h,s,l,a = hslToRgb(220, 16.4, 21.6)
print(h,s,l,a)
-- expected output: 46 52 64 255
-- actual output: 64.11312 46.04688 60.92496 255
But, as stated at the end, the color values it outputs are completely wrong. The decimals are not an issue (as in, it's not an issue that it outputs them; their values are still wrong).
A hue value it's calculated in degrees, so the max isn't 255, but 360:
function hslToRgb(h, s, l)
h = h / 360
s = s / 100
l = l / 100
local r, g, b;
if s == 0 then
r, g, b = l, l, l; -- achromatic
else
local function hue2rgb(p, q, t)
if t < 0 then t = t + 1 end
if t > 1 then t = t - 1 end
if t < 1 / 6 then return p + (q - p) * 6 * t end
if t < 1 / 2 then return q end
if t < 2 / 3 then return p + (q - p) * (2 / 3 - t) * 6 end
return p;
end
local q = l < 0.5 and l * (1 + s) or l + s - l * s;
local p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
end
if not a then a = 1 end
return r * 255, g * 255, b * 255, a * 255
end
You can see this code working here.
I have been working on a more elegant solution to the HSV to RGB problem for a little bit now and this is what I've come up with.
local ceil = math.ceil
local abs = math.abs
local function clamp(v, min, max)
if v < min then return min end
if v > max then return max end
return v
end
local function HSV(h, s, v)
local vert = ceil(h / 120)
local r = abs(((h / 60) - 2 * vert))
local r, g, b = clamp(r, 1 - s, 1), clamp(2 - r, 1 - s, 1), (1 - s * v)
if vert == 1 then return r, g, b end
if vert == 2 then return b, r, g end
if vert == 3 then return g, b, r end
end
-- HSV to RGB
min = math.min
max = math.max
abs = math.abs
local function HSV2RGB (h, s, v)
local k1 = v*(1-s)
local k2 = v - k1
local r = min (max (3*abs (((h )/180)%2-1)-1, 0), 1)
local g = min (max (3*abs (((h -120)/180)%2-1)-1, 0), 1)
local b = min (max (3*abs (((h +120)/180)%2-1)-1, 0), 1)
return k1 + k2 * r, k1 + k2 * g, k1 + k2 * b
end
I've got a math equation that I want to visually record the substitution of.
The equation is y = h * f(t + h, h + f(t, h)), where f(x, y) = x + y - 1
I want to substitute f into y, such that I get:
y = h * f(t + h, h + (t + h - 1))
y = h * (t + h + h + (t + h - 1) - 1)
I've had issues with replace not allowing me to do multi-parameter substitution
I don't have much code, since I'm not sure how to implement it
from sympy import *
f = Function('f')(x, y)
eqn = h * f(t + h, h + f(t, h))
Thanks
sympy.Function is used for declaring undefined functions but in your case the function is known.
The following code seems to work fine over here
from sympy import *
x,y,t,h = symbols('x y t h')
def f(x,y):
return x + y - 1
y = h * f(t+h,h+f(t,h))
y = expand(y)
display(y)
The role of the expand function was to work out the outer multiplication by h in the definition of y.
You can run it in a Jupyter notebook or as an alternative use the print or display function, I get the following result:
Extending average's answer -- Their solution works perfectly if the function is known.
To make it work for a function that's input from the user, you need to do this:
function = input()
def f(x, y, evaluate = False):
eqn = sympify(function)
if evaluate:
eqn = eqn.subs([("x", x), ("y", y)])
return eqn
y = h + f(h, t, True)
This way, if the user inputs "x ** y" for f, y will expand to h + h ** t
So I have to perform the following calculation in python using the following values:
g^response mod p == (commitment)*(public_key_k)^c mod p
response = 1798504909811498641585788989097480059610472466605727419221908325725492625454059229439555828626804680183806468816373215601063565006206068675156743699829546676540107235594790722537029068950539064303645556838303768140715990225949480617994868684304692684872657878847353607016743753387060553449827051212521100889882315213754701194584603400975539123612457745335627513231512419845120373289319998525762252114847939075623683635101459254064343707561020578062272583241711744
g = 633902738424928856783669360417409461352724866437176267937054971987929518113968311572018846775440350331394872441420725806863767569147521628581387346133794141162759618915434384470928048515684966754389921404728037087585951549298706749491681316440418023335644037157549668734734747234193236480208211700649047792505290394509276323498712019417085994608675098219625068478389802372911974790447602798848267203035795626948013815751746314708193865142515067213438779931341448784231764283922931059803394647357407601820746377200693540251395985610151207325893305136968984729108604308872514815118245429658506703427331797397729626291989388778680839647127066755635696870257359738766274560298982571341199340105150191282665463341766016615086716556537263439886148093374656225718217401337340651580107886515914073965138178083420939392671278560530056147682312589783964279302141118430614587577025403023718516789910534505871873011436491653121601912717709648600938567837813521742472036386528727473354399846339619270536399678071529700504925046483796750809603796528358402843506478188359404393987635666119244256746743854126114174948922250715011664059118382465474343042744744366613138372697678748514832068141362891787033831013749278870696574778057534613154041019988
p = 1044388881413152506691752710716624382579964249047383780384233483283953907971557456848826811934997558340890106714439262837987573438185793607263236087851365277945956976543709998340361590134383718314428070011855946226376318839397712745672334684344586617496807908705803704071284048740118609114467977783598029006686938976881787785946905630190260940599579453432823469303026696443059025015972399867714215541693835559885291486318237914434496734087811872639496475100189041349008417061675093668333850551032972088269550769983616369411933015213796825837188091833656751221318492846368125550225998300412344784862595674492194617023806505913245610825731835380087608622102834270197698202313169017678006675195485079921636419370285375124784014907159135459982790513399611551794271106831134090584272884279791554849782954323534517065223269061394905987693002122963395687782878948440616007412945674919823050571642377154816321380631045902916136926708342856440730447899971901781465763473223850267253059899795996090799469201774624817718449867455659250178329070473119433165550807568221846571746373296884912819520317457002440926616910874148385078411929804522981857338977648103126085895011648256092372242446818525911665961045150145231572613786749168750228798758833
commitment= 2020675137930448463428712210699816377193388795956936955368481577678186252928308173553464572252495743781550875659773513809435786840535637124578067477896971665575935166527060316619051471051210246502668698327245923852291583447595092128659406887368657131869401939279706099725440871802711550213026404990472910817206252771895691223697718745541630125166110241325111941992598904064238282617139280375363809225737959729994345492410515939174560166672596708090703781989210954
public_key_k= 1003984929417870213515336739925548790770111120760264823891351725159288043410871239949310577373062378763331943177698297734039338641147796251418513873689452683273850688383067446727776769706425799938906550445532369849808734611985822181736172724148838646620601396815561586226959391463589873364266684088955346195425684063242763135652048735053741050269224316588887929259000548116678926935189145525181639366543164685162598318329861171236716093650271474650457781832849534
I have the following function that can perform 2^a mod p where a and p are large:
def fast_powmod(n, m):
pow2 = 2
result = 1
while n > 0:
if n % 2 == 1:
result = (result * pow2) % m
pow2 = (pow2 * pow2) % m
n >>= 1
return result
How do I do the same thing where it's a^b mod p with a and b both being very large?
Why does GHCi give incorrect answer below?
GHCi
λ> ((-20.24373193905347)^12)^2 - ((-20.24373193905347)^24)
4.503599627370496e15
Python3
>>> ((-20.24373193905347)**12)**2 - ((-20.24373193905347)**24)
0.0
UPDATE
I would implement Haskell's (^) function as follows.
powerXY :: Double -> Int -> Double
powerXY x 0 = 1
powerXY x y
| y < 0 = powerXY (1/x) (-y)
| otherwise =
let z = powerXY x (y `div` 2)
in if odd y then z*z*x else z*z
main = do
let x = -20.24373193905347
print $ powerXY (powerXY x 12) 2 - powerXY x 24 -- 0
print $ ((x^12)^2) - (x ^ 24) -- 4.503599627370496e15
Although my version doesn't appear any more correct than the one provided below by #WillemVanOnsem, it strangely gives the correct answer for this particular case at least.
Python is similar.
def pw(x, y):
if y < 0:
return pw(1/x, -y)
if y == 0:
return 1
z = pw(x, y//2)
if y % 2 == 1:
return z*z*x
else:
return z*z
# prints 0.0
print(pw(pw(-20.24373193905347, 12), 2) - pw(-20.24373193905347, 24))
Short answer: there is a difference between (^) :: (Num a, Integral b) => a -> b -> a and (**) :: Floating a => a -> a -> a.
The (^) function works only on integral exponents. It will normally make use of an iterative algorithm that will each time check if the power is divisible by two, and divide the power by two (and if non-divisible multiply the result with x). This thus means that for 12, it will perform a total of six multiplications. If a multiplication has a certain rounding-off error, that error can "explode". As we can see in the source code, the (^) function is implemented as:
(^) :: (Num a, Integral b) => a -> b -> a
x0 ^ y0 | y0 < 0 = errorWithoutStackTrace "Negative exponent"
| y0 == 0 = 1
| otherwise = f x0 y0
where -- f : x0 ^ y0 = x ^ y
f x y | even y = f (x * x) (y `quot` 2)
| y == 1 = x
| otherwise = g (x * x) (y `quot` 2) x -- See Note [Half of y - 1]
-- g : x0 ^ y0 = (x ^ y) * z
g x y z | even y = g (x * x) (y `quot` 2) z
| y == 1 = x * z
| otherwise = g (x * x) (y `quot` 2) (x * z) -- See Note [Half of y - 1]
The (**) function is, at least for Floats and Doubles implemented to work on the floating point unit. Indeed, if we take a look at the implementation of (**), we see:
instance Floating Float where
-- …
(**) x y = powerFloat x y
-- …
This thus redirect to the powerFloat# :: Float# -> Float# -> Float# function, which will, normally be linked to the corresponding FPU operation(s) by the compiler.
If we use (**) instead, we obtain zero as well for a 64-bit floating point unit:
Prelude> (a**12)**2 - a**24
0.0
We can for example implement the iterative algorithm in Python:
def pw(x0, y0):
if y0 < 0:
raise Error()
if y0 == 0:
return 1
return f(x0, y0)
def f(x, y):
if (y % 2 == 0):
return f(x*x, y//2)
if y == 1:
return x
return g(x*x, y // 2, x)
def g(x, y, z):
if (y % 2 == 0):
return g(x*x, y//2, z)
if y == 1:
return x*z
return g(x*x, y//2, x*z)
If we then perform the same operation, I get locally:
>>> pw(pw(-20.24373193905347, 12), 2) - pw(-20.24373193905347, 24)
4503599627370496.0
Which is the same value as what we get for (^) in GHCi.
The "main" code works to calculate every single binomial coefficient, unless (n = k + 1). It is mind boggling - it says there is a division by zero error but I cannot see why. the error occurs in the main function ( d = n2 / c ). Any idea why?
def getInteger( prompt ):
while True:
try:
num = int( input(prompt))
except ValueError:
print( "That is not an integer -- please try again")
continue
return num
def factorial(f):
f = f
q = (f - 1)
fac = (f * q)
while (q) > 1:
q -= 1
fac = (fac * q)
return (fac)
def main():
n = getInteger("enter a factor:")
k = getInteger("enter a factor:")
while n >= k :
n2 = factorial(n)
k2 = factorial(k)
a = n - k
b = factorial(a)
c = b * k2
d = n2 / c
print("n2 = {} k2 = {} a = {} b = {} c = {} d = {}" .format(n2, k2, a, b, c, d) )
return
else:
print("n must be larger than k")
if __name__ == '__main__':
main()
main()
Note that I need to implement the calculations myself so I cannot use libraries.
Your factorial function is not correct for the inputs 0,1. It returns 0 for both of them, while it should return 1 for both of them.