advice on how to use the gr API

30 views
Skip to first unread message

Giacomo Pope

unread,
Dec 17, 2024, 11:16:22 AM12/17/24
to flint-devel
Hey all,

I want to try and keep this question concise, but if more information is needed please say. My goal is to create some code to work with elliptic curves and friends and I want to try and start off well with reasonable structures for curves and points.

For a curve i would want things like the curve coefficients, but I also want the structure to hold the context for the general ring so I can perform arithmetic and other things.

From the documentation, the two obvious structures would be

typedef struct
{
    gr_ptr a;
    gr_ptr b;
    gr_ctx_t ctx; // to perform arithmetic we will need the gr_ctx
} ec_weierstrass_curve_t;

or

typedef struct
{
    gr_ptr a;
    gr_ptr b;
    gr_ctx_ptr ctx; // to perform arithmetic we will need the gr_ctx
} ec_weierstrass_curve_t;

I can't tell which of these is better, but I cannot make either work.

The issue is how I initialise this curve. Say I write a function:

void ec_weierstrass_curve_init(ec_weierstrass_curve_t *E, gr_ctx_t ctx)
{
    E->ctx = ctx;
    E->a = gr_heap_init(E->ctx);
    E->b = gr_heap_init(E->ctx);
}

Then I can pass a context to this function and store a pointer to it (gr_ctx_ptr) in the structure. The issue with this seems to then be that if I try and do GR_TMP_INIT(x, E->ctx);, this fails and I can't find a reasonable way to deference the pointer.

Instead, if I try and store `gr_ctx_t` itself, then I need something like gr_ctx_copy(E->ctx, ctx), but I can't find such a function.

What I have at the moment is

typedef struct
{
    gr_ptr a;
    gr_ptr b;
    gr_ctx_struct* ctx; // to perform arithmetic we will need the gr_ctx
} ec_weierstrass_curve_t;

which seems to "work" but I'm worried this is a bit of a hack and I'm mainly concerned that I'm just doing something fundamentally wrong.

Also, should I be using `gr_init_heap` here? I tried `gr_init()` instead, but this gave me a bus error.

Fredrik Johansson

unread,
Dec 17, 2024, 11:32:45 AM12/17/24
to flint...@googlegroups.com
Hi Giacomo,

Given gr_ptr x (= (void *) x),

GR_TMP_INIT(x, ctx) allocates space on the stack for x, sets x to point to this space, and initializes the element

x = gr_heap_init(ctx) allocates space on the heap for x, sets x to point to this space, and initializes the element

gr_init(x, ctx) initializes the element at x, assuming that the caller provides a pointer which already points to allocated space

GR_TMP_INIT will not work as you intended because this allocates in the stack frame of ec_weierstrass_curve_init, and this pointer becomes invalid outside ec_weierstrass_curve_init. You could define a *macro* that calls GR_TMP_INIT, but this would have the same restriction as the original macro. gr_init by itself will fail since you have not allocated. In general, gr_heap_init is what you want here.

There is no gr_ctx_copy or gr_ctx_set currently; best would be to put just a pointer to the context object in your structure (and make sure you keep the context object alive externally).

Fredrik

--

---
You received this message because you are subscribed to the Google Groups "flint-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email to flint-devel...@googlegroups.com.
To view this discussion, visit https://groups.google.com/d/msgid/flint-devel/b4b318f6-92f5-4e73-80e1-14283936fd8cn%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages