aboutsummaryrefslogtreecommitdiff
path: root/epare/formulas.ipynb
blob: e63d29503d4754b624e537a0d790d67ee0441d97 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "672213e3-f426-4113-b5b6-304002474ce3",
   "metadata": {},
   "source": [
    "# Formula analysis"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "09d92ba3-ede4-40c3-a061-a9c328e26fb5",
   "metadata": {},
   "outputs": [],
   "source": [
    "import io\n",
    "import json\n",
    "\n",
    "from pprint import pprint\n",
    "import tabulate\n",
    "from IPython.display import HTML, display\n",
    "\n",
    "from pyecsca.ec.params import load_params_ecgen\n",
    "from pyecsca.ec.coordinates import AffineCoordinateModel\n",
    "from pyecsca.ec.model import ShortWeierstrassModel\n",
    "from pyecsca.ec.point import Point\n",
    "from pyecsca.ec.mod import mod\n",
    "from pyecsca.ec.error import UnsatisfiedAssumptionError\n",
    "from pyecsca.misc.cfg import TemporaryConfig"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "5155a3ab-fd65-4add-ac3d-413de337c849",
   "metadata": {},
   "outputs": [],
   "source": [
    "model = ShortWeierstrassModel()\n",
    "affine_coords = AffineCoordinateModel(model)\n",
    "\n",
    "curve_data = b\"\"\"[{\n",
    "    \"field\": {\n",
    "        \"p\": \"0x57880ae612d14d33afd0c965938ac1ba44824036cea5d4a1699a9f44000fb273\"\n",
    "    },\n",
    "    \"a\": \"0x55d376d1fbcc919da841bb13352d4e419ac85a100fb806014bed884db5916399\",\n",
    "    \"b\": \"0x21e27f7a065039ee59fd6b12c33d96709642aa6ac3738bd4f66fc663c79a19f8\",\n",
    "    \"order\": \"0x57880ae612d14d33afd0c965938ac1b91f16808ee875095bafed41e136ca7bfe\",\n",
    "    \"subgroups\": [\n",
    "        {\n",
    "            \"x\": \"0x407d5c52d9ad6f25bd7ff25f07804b4e4ebd4f5c992eafeb8c92e33f81e73b85\",\n",
    "            \"y\": \"0x4b92eefcfa7c5e295c7e649801b83649156974064a8649f9a94f915754bd2183\",\n",
    "            \"order\": \"0x57880ae612d14d33afd0c965938ac1b91f16808ee875095bafed41e136ca7bfe\",\n",
    "            \"cofactor\": \"0x1\",\n",
    "            \"points\": [\n",
    "                {\n",
    "                    \"x\": \"0x2571326cc99fe050bfe1a6a02ea635c56504e49d122152fd281761748a0501d9\",\n",
    "                    \"y\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n",
    "                    \"order\": \"0x2\"\n",
    "                },\n",
    "                {\n",
    "                    \"x\": \"0x266a5c5927e4f6feec30a9f3e2acb535657f365e1a24c1bb0b0d9158a7668639\",\n",
    "                    \"y\": \"0x49c431e2a2704efb4b193e0fa26c60f815eaf195f712befd53b7bafb72b98488\",\n",
    "                    \"order\": \"0x2bc405730968a699d7e864b2c9c560dc8f8b4047743a84add7f6a0f09b653dff\"\n",
    "                }\n",
    "            ]\n",
    "        }\n",
    "    ]\n",
    "}]\"\"\"\n",
    "curve_json = json.loads(curve_data)[0]\n",
    "p = int(curve_json[\"field\"][\"p\"], 16)\n",
    "order2_aff = Point(affine_coords,\n",
    "                   x=mod(int(curve_json[\"subgroups\"][0][\"points\"][0][\"x\"], 16), p),\n",
    "                   y=mod(int(curve_json[\"subgroups\"][0][\"points\"][0][\"y\"], 16), p))\n",
    "orderbig_aff = Point(affine_coords,\n",
    "                     x=mod(int(curve_json[\"subgroups\"][0][\"points\"][1][\"x\"], 16), p),\n",
    "                     y=mod(int(curve_json[\"subgroups\"][0][\"points\"][1][\"y\"], 16), p))\n",
    "\n",
    "def allzero(pt):\n",
    "    return all(value == 0 for value in pt.coords.values())\n",
    "\n",
    "def affine(pt):\n",
    "    try:\n",
    "        pt.to_affine()\n",
    "    except Exception:\n",
    "        return False\n",
    "    return True\n",
    "\n",
    "def on_curve(curve, pt):\n",
    "    try:\n",
    "        return curve.is_on_curve(pt)\n",
    "    except Exception:\n",
    "        return False\n",
    "\n",
    "def eval_test(expected, out, curve):\n",
    "    return (expected.equals_homog(out) if expected is not None else \"Undefined\", allzero(out), affine(out), on_curve(curve, out), out)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "e045a4cf-97db-4a2f-a191-582987f6473d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Skipping jacobian-3, unsatisfied assumption\n",
      "Skipping jacobian-0, unsatisfied assumption\n",
      "Skipping projective-1, unsatisfied assumption\n",
      "Skipping projective-3, unsatisfied assumption\n",
      "Skipping w12-0, unsatisfied assumption\n",
      "Skipping xyzz-3, unsatisfied assumption\n"
     ]
    }
   ],
   "source": [
    "results_add = {}\n",
    "results_dbl = {}\n",
    "\n",
    "with TemporaryConfig() as cfg:\n",
    "    cfg.ec.unsatisfied_formula_assumption_action = \"ignore\"\n",
    "    for coords_name, coords in model.coordinates.items():\n",
    "        try:\n",
    "            params = load_params_ecgen(io.BytesIO(curve_data), coords_name, infty=False)\n",
    "        except UnsatisfiedAssumptionError:\n",
    "            print(f\"Skipping {coords_name}, unsatisfied assumption\")\n",
    "            continue\n",
    "        results_add[coords_name] = {}\n",
    "        results_dbl[coords_name] = {}\n",
    "        infty = params.curve.neutral\n",
    "        order2 = order2_aff.to_model(coords, params.curve)\n",
    "        orderbig = orderbig_aff.to_model(coords, params.curve)\n",
    "        orderbig_neg = params.curve.affine_negate(orderbig_aff).to_model(coords, params.curve)\n",
    "        orderbig2 = params.curve.affine_double(orderbig_aff).to_model(coords, params.curve)\n",
    "        zeros = Point(coords, **{var: mod(0, p) for var in coords.variables})\n",
    "\n",
    "        adds = set(formula for formula in coords.formulas.values() if formula.shortname == \"add\")\n",
    "        dbls = set(formula for formula in coords.formulas.values() if formula.shortname == \"dbl\")\n",
    "        for add in adds:\n",
    "            res = {}\n",
    "            results_add[coords_name][add.name] = res\n",
    "            # P + P = ?\n",
    "            PpP = add(p, orderbig, orderbig, **params.curve.parameters)[0]\n",
    "            # P + infty = ?\n",
    "            PpInfty = add(p, orderbig, infty, **params.curve.parameters)[0]\n",
    "            InftypP = add(p, infty, orderbig, **params.curve.parameters)[0]\n",
    "            # ord2 + ord2 = ?\n",
    "            O2pO2 = add(p, order2, order2, **params.curve.parameters)[0]\n",
    "            # P + Q = infty\n",
    "            EqInfty1 = add(p, orderbig, orderbig_neg, **params.curve.parameters)[0]\n",
    "            EqInfty2 = add(p, orderbig_neg, orderbig, **params.curve.parameters)[0]\n",
    "            # P + zeros = ?\n",
    "            PpZeros = add(p, orderbig, zeros, **params.curve.parameters)[0]\n",
    "            ZerospP = add(p, zeros, orderbig, **params.curve.parameters)[0]\n",
    "            res[\"PpP\"] = eval_test(orderbig2, PpP, params.curve)\n",
    "            res[\"PpInfty\"] = eval_test(orderbig, PpInfty, params.curve)\n",
    "            res[\"InftypP\"] = eval_test(orderbig, InftypP, params.curve)\n",
    "            res[\"O2pO2\"] = eval_test(infty, O2pO2, params.curve)\n",
    "            res[\"EqInfty1\"] = eval_test(infty, EqInfty1, params.curve)\n",
    "            res[\"EqInfty2\"] = eval_test(infty, EqInfty2, params.curve)\n",
    "            res[\"PpZeros\"] = eval_test(None, PpZeros, params.curve)\n",
    "            res[\"ZerospP\"] = eval_test(None, ZerospP, params.curve)\n",
    "        for dbl in dbls:\n",
    "            res = {}\n",
    "            results_dbl[coords_name][dbl.name] = res\n",
    "            O2twice = dbl(p, order2, **params.curve.parameters)[0]\n",
    "            Inftytwice = dbl(p, infty, **params.curve.parameters)[0]\n",
    "            Zerostwice = dbl(p, zeros, **params.curve.parameters)[0]\n",
    "            res[\"O2twice\"] = eval_test(infty, O2twice, params.curve)\n",
    "            res[\"Inftytwice\"] = eval_test(infty, Inftytwice, params.curve)\n",
    "            res[\"Zerostwice\"] = eval_test(None, Zerostwice, params.curve)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "d0928c16-9688-4d65-a559-5895d1b7c85b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<thead>\n",
       "<tr><th>Formula       </th><th>Test    </th><th>Correct?  </th><th>Zeros?  </th><th>Affine?  </th><th>On curve?  </th></tr>\n",
       "</thead>\n",
       "<tbody>\n",
       "<tr><td>add-2007-bl   </td><td>PpP     </td><td>True      </td><td>False   </td><td>True     </td><td>True       </td></tr>\n",
       "<tr><td>add-2007-bl   </td><td>PpInfty </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2007-bl   </td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2007-bl   </td><td>O2pO2   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-2007-bl   </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-2007-bl   </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-2007-bl   </td><td>PpZeros </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2007-bl   </td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2002-bj   </td><td>PpP     </td><td>True      </td><td>False   </td><td>True     </td><td>True       </td></tr>\n",
       "<tr><td>add-2002-bj   </td><td>PpInfty </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2002-bj   </td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2002-bj   </td><td>O2pO2   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-2002-bj   </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-2002-bj   </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-2002-bj   </td><td>PpZeros </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2002-bj   </td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2015-rcb  </td><td>PpP     </td><td>True      </td><td>False   </td><td>True     </td><td>True       </td></tr>\n",
       "<tr><td>add-2015-rcb  </td><td>PpInfty </td><td>True      </td><td>False   </td><td>True     </td><td>True       </td></tr>\n",
       "<tr><td>add-2015-rcb  </td><td>InftypP </td><td>True      </td><td>False   </td><td>True     </td><td>True       </td></tr>\n",
       "<tr><td>add-2015-rcb  </td><td>O2pO2   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-2015-rcb  </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-2015-rcb  </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-2015-rcb  </td><td>PpZeros </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2015-rcb  </td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-1998-cmo</td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-1998-cmo</td><td>PpInfty </td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-1998-cmo</td><td>InftypP </td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-1998-cmo</td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-1998-cmo</td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>mmadd-1998-cmo</td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>mmadd-1998-cmo</td><td>PpZeros </td><td>Undefined </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-1998-cmo</td><td>ZerospP </td><td>Undefined </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo  </td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo  </td><td>PpInfty </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo  </td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo  </td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo  </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-1998-cmo  </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-1998-cmo  </td><td>PpZeros </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo  </td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-1998-cmo </td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-1998-cmo </td><td>PpInfty </td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>madd-1998-cmo </td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-1998-cmo </td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-1998-cmo </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>madd-1998-cmo </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>madd-1998-cmo </td><td>PpZeros </td><td>Undefined </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>madd-1998-cmo </td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2015-rcb </td><td>PpP     </td><td>True      </td><td>False   </td><td>True     </td><td>True       </td></tr>\n",
       "<tr><td>madd-2015-rcb </td><td>PpInfty </td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>madd-2015-rcb </td><td>InftypP </td><td>True      </td><td>False   </td><td>True     </td><td>True       </td></tr>\n",
       "<tr><td>madd-2015-rcb </td><td>O2pO2   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>madd-2015-rcb </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>madd-2015-rcb </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>madd-2015-rcb </td><td>PpZeros </td><td>Undefined </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>madd-2015-rcb </td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>PpInfty </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>PpZeros </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-2009-bl </td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-2009-bl </td><td>PpInfty </td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-2009-bl </td><td>InftypP </td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-2009-bl </td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-2009-bl </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>mmadd-2009-bl </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>mmadd-2009-bl </td><td>PpZeros </td><td>Undefined </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-2009-bl </td><td>ZerospP </td><td>Undefined </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>add-2009-bl   </td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2009-bl   </td><td>PpInfty </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2009-bl   </td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2009-bl   </td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2009-bl   </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-2009-bl   </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-2009-bl   </td><td>PpZeros </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2009-bl   </td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2009-bl  </td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2009-bl  </td><td>PpInfty </td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>madd-2009-bl  </td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2009-bl  </td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2009-bl  </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>madd-2009-bl  </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>madd-2009-bl  </td><td>PpZeros </td><td>Undefined </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>madd-2009-bl  </td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>PpInfty </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>PpZeros </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2008-s    </td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2008-s    </td><td>PpInfty </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2008-s    </td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2008-s    </td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2008-s    </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-2008-s    </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-2008-s    </td><td>PpZeros </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2008-s    </td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2008-s   </td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2008-s   </td><td>PpInfty </td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>madd-2008-s   </td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2008-s   </td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2008-s   </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>madd-2008-s   </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>madd-2008-s   </td><td>PpZeros </td><td>Undefined </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>madd-2008-s   </td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-2008-s  </td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-2008-s  </td><td>PpInfty </td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-2008-s  </td><td>InftypP </td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-2008-s  </td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-2008-s  </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>mmadd-2008-s  </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>mmadd-2008-s  </td><td>PpZeros </td><td>Undefined </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-2008-s  </td><td>ZerospP </td><td>Undefined </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>madd-2007-bl  </td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2007-bl  </td><td>PpInfty </td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>madd-2007-bl  </td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2007-bl  </td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2007-bl  </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>madd-2007-bl  </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>madd-2007-bl  </td><td>PpZeros </td><td>Undefined </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>madd-2007-bl  </td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo  </td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo  </td><td>PpInfty </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo  </td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo  </td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo  </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-1998-cmo  </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-1998-cmo  </td><td>PpZeros </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo  </td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>zadd-2007-m   </td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>zadd-2007-m   </td><td>PpInfty </td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>zadd-2007-m   </td><td>InftypP </td><td>False     </td><td>False   </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>zadd-2007-m   </td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>zadd-2007-m   </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>zadd-2007-m   </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>zadd-2007-m   </td><td>PpZeros </td><td>Undefined </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>zadd-2007-m   </td><td>ZerospP </td><td>Undefined </td><td>False   </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2001-b    </td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2001-b    </td><td>PpInfty </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2001-b    </td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2001-b    </td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2001-b    </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-2001-b    </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-2001-b    </td><td>PpZeros </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2001-b    </td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>PpInfty </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>PpZeros </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-cmo-2</td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1986-cc   </td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1986-cc   </td><td>PpInfty </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1986-cc   </td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1986-cc   </td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1986-cc   </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-1986-cc   </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-1986-cc   </td><td>PpZeros </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1986-cc   </td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2004-hmv </td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2004-hmv </td><td>PpInfty </td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>madd-2004-hmv </td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2004-hmv </td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2004-hmv </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>madd-2004-hmv </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>madd-2004-hmv </td><td>PpZeros </td><td>Undefined </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>madd-2004-hmv </td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2007-bl   </td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2007-bl   </td><td>PpInfty </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2007-bl   </td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2007-bl   </td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2007-bl   </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-2007-bl   </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-2007-bl   </td><td>PpZeros </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-2007-bl   </td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2008-g   </td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2008-g   </td><td>PpInfty </td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>madd-2008-g   </td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2008-g   </td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd-2008-g   </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>madd-2008-g   </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>madd-2008-g   </td><td>PpZeros </td><td>Undefined </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>madd-2008-g   </td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-2007-bl </td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-2007-bl </td><td>PpInfty </td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-2007-bl </td><td>InftypP </td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-2007-bl </td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-2007-bl </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>mmadd-2007-bl </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>mmadd-2007-bl </td><td>PpZeros </td><td>Undefined </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>mmadd-2007-bl </td><td>ZerospP </td><td>Undefined </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-hnm  </td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-hnm  </td><td>PpInfty </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-hnm  </td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-hnm  </td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-hnm  </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-1998-hnm  </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>add-1998-hnm  </td><td>PpZeros </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>add-1998-hnm  </td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd          </td><td>PpP     </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd          </td><td>PpInfty </td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>madd          </td><td>InftypP </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd          </td><td>O2pO2   </td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>madd          </td><td>EqInfty1</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>madd          </td><td>EqInfty2</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>madd          </td><td>PpZeros </td><td>Undefined </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>madd          </td><td>ZerospP </td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "</tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "table = [[\"Formula\", \"Test\", \"Correct?\", \"Zeros?\", \"Affine?\", \"On curve?\"]]\n",
    "test_filter = None\n",
    "for vals in results_add.values():\n",
    "    for name, formula in vals.items():\n",
    "        for k, v in formula.items():\n",
    "            if test_filter is None or k in test_filter:\n",
    "                table.append((name, k, v[0], v[1], v[2], v[3]))\n",
    "display(HTML(tabulate.tabulate(table, tablefmt=\"html\", headers=\"firstrow\")))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "2d74db05-0606-4e54-87e0-c7fe0cbb5519",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<thead>\n",
       "<tr><th>Formula       </th><th>Test      </th><th>Correct?  </th><th>Zeros?  </th><th>Affine?  </th><th>On curve?  </th></tr>\n",
       "</thead>\n",
       "<tbody>\n",
       "<tr><td>mdbl-2007-bl  </td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>mdbl-2007-bl  </td><td>Inftytwice</td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>mdbl-2007-bl  </td><td>Zerostwice</td><td>Undefined </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2015-rcb  </td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2015-rcb  </td><td>Inftytwice</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2015-rcb  </td><td>Zerostwice</td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>dbl-1998-cmo  </td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-1998-cmo  </td><td>Inftytwice</td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>dbl-1998-cmo  </td><td>Zerostwice</td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>dbl-2007-bl   </td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2007-bl   </td><td>Inftytwice</td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>dbl-2007-bl   </td><td>Zerostwice</td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>dbl-1998-cmo-2</td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-1998-cmo-2</td><td>Inftytwice</td><td>False     </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>dbl-1998-cmo-2</td><td>Zerostwice</td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>dbl-2009-bl   </td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2009-bl   </td><td>Inftytwice</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2009-bl   </td><td>Zerostwice</td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>mdbl-2009-bl  </td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>mdbl-2009-bl  </td><td>Inftytwice</td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>mdbl-2009-bl  </td><td>Zerostwice</td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>dbl-1998-cmo-2</td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-1998-cmo-2</td><td>Inftytwice</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-1998-cmo-2</td><td>Zerostwice</td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>mdbl-2008-s-1 </td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>mdbl-2008-s-1 </td><td>Inftytwice</td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>mdbl-2008-s-1 </td><td>Zerostwice</td><td>Undefined </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2008-s-1  </td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2008-s-1  </td><td>Inftytwice</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2008-s-1  </td><td>Zerostwice</td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>dbl-1998-cmo  </td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-1998-cmo  </td><td>Inftytwice</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-1998-cmo  </td><td>Zerostwice</td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>dbl-1986-cc   </td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-1986-cc   </td><td>Inftytwice</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-1986-cc   </td><td>Zerostwice</td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>dbl-2007-bl   </td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2007-bl   </td><td>Inftytwice</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2007-bl   </td><td>Zerostwice</td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>dbl-1998-cmo-2</td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-1998-cmo-2</td><td>Inftytwice</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-1998-cmo-2</td><td>Zerostwice</td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>dbl-1998-hnm  </td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-1998-hnm  </td><td>Inftytwice</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-1998-hnm  </td><td>Zerostwice</td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>mdbl-2007-bl  </td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>mdbl-2007-bl  </td><td>Inftytwice</td><td>False     </td><td>False   </td><td>True     </td><td>False      </td></tr>\n",
       "<tr><td>mdbl-2007-bl  </td><td>Zerostwice</td><td>Undefined </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2002-bj-3 </td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2002-bj-3 </td><td>Inftytwice</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2002-bj-3 </td><td>Zerostwice</td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>dbl-2002-bj   </td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2002-bj   </td><td>Inftytwice</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2002-bj   </td><td>Zerostwice</td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>dbl-2002-it-2 </td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2002-it-2 </td><td>Inftytwice</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2002-it-2 </td><td>Zerostwice</td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>dbl-2002-it   </td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2002-it   </td><td>Inftytwice</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2002-it   </td><td>Zerostwice</td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "<tr><td>dbl-2002-bj-2 </td><td>O2twice   </td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2002-bj-2 </td><td>Inftytwice</td><td>True      </td><td>False   </td><td>False    </td><td>True       </td></tr>\n",
       "<tr><td>dbl-2002-bj-2 </td><td>Zerostwice</td><td>Undefined </td><td>True    </td><td>False    </td><td>False      </td></tr>\n",
       "</tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "table = [[\"Formula\", \"Test\", \"Correct?\", \"Zeros?\", \"Affine?\", \"On curve?\"]]\n",
    "test_filter = None\n",
    "for vals in results_dbl.values():\n",
    "    for name, formula in vals.items():\n",
    "        for k, v in formula.items():\n",
    "            if test_filter is None or k in test_filter:\n",
    "                table.append((name, k, v[0], v[1], v[2], v[3]))\n",
    "display(HTML(tabulate.tabulate(table, tablefmt=\"html\", headers=\"firstrow\")))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9194ed95-4aeb-4aeb-bf8f-b8e0c1f1f987",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}