SageMath: defining class of functions on Elliptic Curves

$\begingroup$

In SageMath,

I would like to manipulate rational functions on elliptic curves (defined on finite fields). For example, for $P = (x,y)$ on some curve $E$

$$f = x+y-12$$$$g = \frac{x+y-3}{(x-3)^2} $$ etc.

Is there a natural class ?

I am looking to make a toy example with pairings, so I need to define stuff like $$P \rightarrow f_P$$ where $$f_P:Q \rightarrow f_P(Q)$$ is a function

I can't see how to do that, and I'm able to make computations if I define

def f (P,Q): ....

but I can only compute the values taken by the function $f_P$, I cannot "see" the function $f_P$. Basically I'm trying as an exercise to re-write the following Magma code to SageMath:

EDIT: my question hasn't attracted much interest so i'm going to give a more concrete example:

# this is the beginning of the code related to the example in Costello
q=47
F = GF(q)
R.<x> = F[] ; R
F4.<u>= F.extension(x^4-4*x^2+5)
a = 21 ; b= 15
E = EllipticCurve(F4,[a,b])
r=17
k=4
(q^4-1) % r # r=17 is a divisor of q^4 - 1 = 47^4 - 1
P = E([45,23])
P.order()
h = E.cardinality() / r^2
O = E(0)
Q = E([5*u^3 + 37*u + 13,7*u^3 + 45*u^2 + 10*u + 7])
def fADD_(P,Q,x,y): lamb_da=(Q[1]-P[1])/(Q[0]-P[0]) c =P[1]-lamb_da*P[0] l =(y-(lamb_da*x+c)) v =(x-(lamb_da^2-P[0]-P[1])) return (l/v)

fADD_(P,Q,x,y) will return an error while i would have liked it to return a rational function in x,y

--------------------------------------------------------------------------- KeyError Traceback (most recent call last) /Applications/ in sage.structure.coerce.CoercionModel.bin_op (build/cythonized/sage/structure/coerce.c:9946)() 1195 try: -> 1196 action = self._action_maps.get(xp, yp, op) 1197 except KeyError:

/Applications/ in sage.structure.coerce_dict.TripleDict.get (build/cythonized/sage/structure/coerce_dict.c:7917)() 1327
if not valid(cursor.key_id1): -> 1328 raise KeyError((k1, k2, k3)) 1329 value = cursor.value

KeyError: (Finite Field in u of size 47^4, Symbolic Ring, )

During handling of the above exception, another exception occurred:

TypeError Traceback (most recent call last) in () ----> 1 fADD_(P,Q,x,y)

in fADD_(P, Q, x, y) 2 lamb_da=(Q[Integer(1)]-P[Integer(1)])/(Q[Integer(0)]-P[Integer(0)]) 3 c =P[Integer(1)]-lamb_daP[Integer(0)] ----> 4 l =(y-(lamb_dax+c)) 5 v =(x-(lamb_da**Integer(2)-P[Integer(0)]-P[Integer(1)])) 6 return (l/v)

/Applications/ in sage.structure.element.Element.mul(build/cythonized/sage/structure/element.c:12034)() 1515
return (left).mul(right) 1516 if BOTH_ARE_ELEMENT(cl): -> 1517 return coercion_model.bin_op(left, right, mul) 1518 1519 cdef long value

/Applications/ in sage.structure.coerce.CoercionModel.bin_op (build/cythonized/sage/structure/coerce.c:9996)() 1196
action = self._action_maps.get(xp, yp, op) 1197 except KeyError: -> 1198 action = self.get_action(xp, yp, op, x, y) 1199 if action is not None: 1200 if (action)._is_left:

/Applications/ in sage.structure.coerce.CoercionModel.get_action (build/cythonized/sage/structure/coerce.c:16783)() 1725
except KeyError: 1726 pass -> 1727 action = self.discover_action(R, S, op, r, s) 1728 action = self.verify_action(action, R, S, op) 1729
self._action_maps.set(R, S, op, action)

/Applications/ in sage.structure.coerce.CoercionModel.discover_action (build/cythonized/sage/structure/coerce.c:18201)() 1856 """ 1857 if isinstance(R, Parent): -> 1858 action = (R).get_action(S, op, True, r, s) 1859 if action is not None: 1860 return action

/Applications/ in sage.structure.parent.Parent.get_action (build/cythonized/sage/structure/parent.c:19901)() 2475
action = self.get_action(S, op, self_on_left) 2476 if action is None: -> 2477 action = self.discover_action(S, op, self_on_left, self_el, S_el) 2478 2479 if action is not None:

/Applications/ in sage.structure.parent.Parent.discover_action (build/cythonized/sage/structure/parent.c:20878)() 2554

detect actions defined by rmul, lmul, act_on, and acted_upon methods 2555 from .coerce_actions import

detect_element_action -> 2556 action = detect_element_action(self, S, self_on_left, self_el, S_el) 2557 if action is not None: 2558 return action

/Applications/ in sage.structure.coerce_actions.detect_element_action (build/cythonized/sage/structure/coerce_actions.c:5026)() 215 if isinstance(x, ModuleElement) and isinstance(y, Element): 216 try: --> 217 return (RightModuleAction if X_on_left else LeftModuleAction)(Y, X, y, x) 218 except CoercionException as msg: 219 _record_exception()

/Applications/ in sage.structure.coerce_actions.ModuleAction.init(build/cythonized/sage/structure/coerce_actions.c:6778)() 361 if not isinstance(g, Element) or not isinstance(a, ModuleElement): 362 raise CoercionException("not an Element acting on a ModuleElement") --> 363 res = self.act(g, a) 364 if parent(res) is not the_set: 365 # In particular we will raise an error if res is None

/Applications/ in sage.categories.action.Action.act (build/cythonized/sage/categories/action.c:4115)() 213 5*x 214 """ --> 215 return self._act_convert(g, x) 216 217 def invert(self):

/Applications/ in sage.categories.action.Action._act_convert (build/cythonized/sage/categories/action.c:3759)() 169 if parent(x) is not U: 170 x = U(x) --> 171 return self.act(g, x) 172 173 cpdef act(self, g, x):

/Applications/ in sage.structure.coerce_actions.RightModuleAction.act(build/cythonized/sage/structure/coerce_actions.c:8600)() 629 g = <Element?>self.connecting.call(g) 630 if self.extended_base is not None: --> 631 a = <ModuleElement?>self.extended_base(a) 632 return (a).lmul(g) # a * g 633

/Applications/ in sage.structure.parent.Parent.call(build/cythonized/sage/structure/parent.c:9218)() 898 if mor is not None: 899 if no_extra_args: --> 900 return mor.call(x) 901 else: 902 return mor._call_with_args(x, args, kwds)

/Applications/ in sage.structure.coerce_maps.DefaultConvertMap_unique.call(build/cythonized/sage/structure/coerce_maps.c:4556)() 159 print(type(C), C) 160 print(type(C._element_constructor), C._element_constructor) --> 161 raise 162 163 cpdef Element _call_with_args(self, x, args=(), kwds={}):

/Applications/ in sage.structure.coerce_maps.DefaultConvertMap_unique.call(build/cythonized/sage/structure/coerce_maps.c:4448)() 154 cdef Parent C = self._codomain 155 try: --> 156 return C._element_constructor(x) 157 except Exception: 158 if print_warnings:

/Applications/ in sage.symbolic.ring.SymbolicRing.element_constructor(build/cythonized/sage/symbolic/ring.cpp:6648)() 377 elif isinstance(x, (RingElement, Matrix)): 378 if x.parent().characteristic(): --> 379 raise TypeError('positive characteristic not allowed in symbolic computations') 380 exp = x 381 elif isinstance(x, Factorization):

TypeError: positive characteristic not allowed in symbolic computations

$\endgroup$ 5

1 Answer

$\begingroup$

It was hard (for me) to find the starting point of the question. You are working i a concrete situation and the task is clear, but i had to guess which is the point of the question. (We want to "translate" some magma code to sage? Or we want to correct the sage code snippet only? Or the question is the reason for the long traceback information?)

This answer is "making the sage code work". (If something else is the subject of the question, please edit.) Note first that the given code is not complete, well y is not defined. This may be also the reason for the error. (If it is a variable, or it is not "married" structurally with x, then i would expect such errors.)


The following piece of code worked for me:

p = 47
F = GF(p)
R.<x> = PolynomialRing(F)
F4.<u> = GF(p^4, modulus=x^4 - 4*x^2 + 5)
a, b = 21, 15
E = EllipticCurve(F4, [a,b])
print(f"Working with the elliptic curve E:\n{E}")
r = 17
k = 4
print("Is r = {} dividing p^4 - 1 = {}? {}" .format(r, p^4 - 1, r.divides(p^4 - 1)))
P = E.point([45, 23])
print(f"The order of the point {P.xy()} is {P.order()}")
h = E.cardinality() / r^2
O = E(0)
Q = E.point([5*u^3 + 37*u + 13, 7*u^3 + 45*u^2 + 10*u + 7])
R.<x,y> = PolynomialRing(F)
# or F4 instead of F, to avoid structural coerce
def myadd(P, Q, x, y): m = (Q[1] - P[1]) / (Q[0] - P[0]) c = P[1] - m*P[0] return (y - (m*x+c)) / (x - (m^2 - P[0] - P[1]))
myadd(P, Q, x, y)

(Please try to give a readable shape to the code, i also break pep8 rules, but spaces make reading (and error searching) easier.)


The above gave me:

Working with the elliptic curve E:
Elliptic Curve defined by y^2 = x^3 + 21*x + 15 over Finite Field in u of size 47^4
Is r = 17 dividing p^4 - 1 = 4879680? True
The order of the point (45, 23) is 17
((5*u^3 + 22*u^2 + 2*u - 4)*x + y + (10*u^3 - 3*u^2 + 4*u + 16))
/
(x + (12*u^3 - 4*u^2 - 12*u + 17))

(... manually rearrange to better fit the stackexchange format.)

And indeed, the result of myadd(P, Q, x, y) is a rational function in x and y, defined over F4.

(I will try to see what happens in the other code, but i do not have magma on this own linux machine.)

$\endgroup$

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like