aboutsummaryrefslogtreecommitdiff
path: root/src/Lecture5/notebook
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Lecture5/notebook/.ipynb_checkpoints/7-SageAlgebra-checkpoint.ipynb1046
-rw-r--r--src/Lecture5/notebook/.ipynb_checkpoints/7-SageAlgebra-modified+solutions-checkpoint.ipynb1099
-rw-r--r--src/Lecture5/notebook/.ipynb_checkpoints/scratchpad-checkpoint.ipynb52
-rw-r--r--src/Lecture5/notebook/7-SageAlgebra.aux56
-rw-r--r--src/Lecture5/notebook/7-SageAlgebra.ipynb1046
-rw-r--r--src/Lecture5/notebook/7-SageAlgebra.log967
-rw-r--r--src/Lecture5/notebook/7-SageAlgebra.out16
-rw-r--r--src/Lecture5/notebook/7-SageAlgebra.pdfbin0 -> 226346 bytes
-rw-r--r--src/Lecture5/notebook/7-SageAlgebra.tex1297
9 files changed, 5579 insertions, 0 deletions
diff --git a/src/Lecture5/notebook/.ipynb_checkpoints/7-SageAlgebra-checkpoint.ipynb b/src/Lecture5/notebook/.ipynb_checkpoints/7-SageAlgebra-checkpoint.ipynb
new file mode 100644
index 0000000..59ea033
--- /dev/null
+++ b/src/Lecture5/notebook/.ipynb_checkpoints/7-SageAlgebra-checkpoint.ipynb
@@ -0,0 +1,1046 @@
1{
2 "cells": [
3 {
4 "cell_type": "markdown",
5 "metadata": {},
6 "source": [
7 "This lecture's notes are in a different format: the presentations for the $\\LaTeX$ part were made with $\\LaTeX$, so this one is made with Sage, or rather with the [Jupyter Notebook](https://jupyter.org/).\n",
8 "\n",
9 "# The Jupyter Notebook\n",
10 "**Reference:** [[1](https://jupyter.org/documentation)]\n",
11 "\n",
12 "The Jupyter Notebook is one of the default interfaces for SageMath, along with the command line interface. You can access it via web browser, but it is running locally on your device (notice the strange url: `http://localhost:8888/notebooks...`).\n",
13 "\n",
14 "You can create a new notebook by clicking on `New > SageMath 9.2`. You can also create a Python 3 notebook to write Python code.\n",
15 "\n",
16 "Jupyter saves and reads files in the `.ipynb` format. If you download the file for this lecture you can open it and follow the examples interactively.\n",
17 "\n",
18 "## Cells\n",
19 "\n",
20 "The notebook contains one or more *interactive cells* that you can run, like this one below:"
21 ]
22 },
23 {
24 "cell_type": "code",
25 "execution_count": 2,
26 "metadata": {},
27 "outputs": [
28 {
29 "data": {
30 "text/plain": [
31 "2/5"
32 ]
33 },
34 "execution_count": 2,
35 "metadata": {},
36 "output_type": "execute_result"
37 }
38 ],
39 "source": [
40 "# Exercise: modify this cell to use the print() command\n",
41 "2+2\n",
42 "2/5"
43 ]
44 },
45 {
46 "cell_type": "markdown",
47 "metadata": {},
48 "source": [
49 "If you are reading this from Jupyter rather than from the pdf file, you can edit the cell above and run it again. You can also add more cells by selecting `Insert` from the menu bar.\n",
50 "\n",
51 "Notice that only the last statement produces an output. You can force anything to be written as output with the `print()` command, which works like in Python. As an exercise, try to modify the cell above to provide more output!"
52 ]
53 },
54 {
55 "cell_type": "markdown",
56 "metadata": {},
57 "source": [
58 "## Markdown\n",
59 "\n",
60 "[Markdown](https://en.wikipedia.org/wiki/Markdown) is a simple markup language - think of LaTeX or html, but much simpler.\n",
61 "You can add text to your notebook with Markdown cells by selecting `Cell > Cell Type > Markdown`.\n",
62 "\n",
63 "You can also include some LaTeX code in Markdown cells, with dollar signs $ or align environments:\n",
64 "\n",
65 "\\begin{align*}\n",
66 "\\frac{(x+y)^2}{x+1} = \\frac{x^2+y^2}{x+1}\n",
67 "\\end{align*}\n",
68 "\n",
69 "When you are done writing a Markdown cell, you can run it to see the well-formatted text. To edit the text again, double-click on the cell. Try doing it now to fix the formula above!"
70 ]
71 },
72 {
73 "cell_type": "markdown",
74 "metadata": {},
75 "source": [
76 "# Symbolic expressions\n",
77 "\n",
78 "**Reference:** [[2](https://doc.sagemath.org/html/en/reference/calculus/sage/symbolic/expression.html)]\n",
79 "\n",
80 "Now, let's get started with Sage. One thing you might want to do is manipulating symbolic expressions, like the following:"
81 ]
82 },
83 {
84 "cell_type": "code",
85 "execution_count": 3,
86 "metadata": {},
87 "outputs": [
88 {
89 "data": {
90 "text/plain": [
91 "[x == -sqrt(6) - 1, x == sqrt(6) - 1]"
92 ]
93 },
94 "execution_count": 3,
95 "metadata": {},
96 "output_type": "execute_result"
97 }
98 ],
99 "source": [
100 "f = x^2 + 2*x - 5 == 0\n",
101 "solve(f,x)"
102 ]
103 },
104 {
105 "cell_type": "markdown",
106 "metadata": {},
107 "source": [
108 "Notice that the single `=` is part of an assignment, as in Python: we are *assigning* to the variable `f` the value `x^2 + 2*x - 5 >= 0`, which in this case is an equation, so it contains the symbol `==`. Keep in mind the difference between the two!\n",
109 "\n",
110 "**Exercise:** change the code above to solve the corresponding inequality $x^2+2x-5\\geq 0$."
111 ]
112 },
113 {
114 "cell_type": "markdown",
115 "metadata": {},
116 "source": [
117 "## Mathematical variables\n",
118 "\n",
119 "Last time we saw what *variables* are in Python, and that they are a little bit different from the *Mathematical variables* that you use in Mathematics. In Sage, both concepts are present, but they are still distinct. For example in the cell above `f` is a variable in the sense of computer science, while `x` is a Mathematical variable.\n",
120 "\n",
121 "If you want to use Mathematical variables other than `x`, you first need to *declare* them with the `var()` command:"
122 ]
123 },
124 {
125 "cell_type": "code",
126 "execution_count": 14,
127 "metadata": {},
128 "outputs": [
129 {
130 "data": {
131 "text/plain": [
132 "[y == -1/2*x - 1/2*sqrt(x^2 + 2*x + 9) - 1/2, y == -1/2*x + 1/2*sqrt(x^2 + 2*x + 9) - 1/2]"
133 ]
134 },
135 "execution_count": 14,
136 "metadata": {},
137 "output_type": "execute_result"
138 }
139 ],
140 "source": [
141 "var('y')\n",
142 "solve(y^2 + (x+1)*y - 2 == 0, y)"
143 ]
144 },
145 {
146 "cell_type": "markdown",
147 "metadata": {},
148 "source": [
149 "Try removing the first line in the cell above and see what error you get!\n",
150 "\n",
151 "Here is another example:"
152 ]
153 },
154 {
155 "cell_type": "code",
156 "execution_count": 16,
157 "metadata": {},
158 "outputs": [
159 {
160 "data": {
161 "text/plain": [
162 "[x == -1/2*a - 1/2*sqrt(a^2 - 4*b), x == -1/2*a + 1/2*sqrt(a^2 - 4*b)]"
163 ]
164 },
165 "execution_count": 16,
166 "metadata": {},
167 "output_type": "execute_result"
168 }
169 ],
170 "source": [
171 "var('a', 'b')\n",
172 "f = x^2+a*x+b\n",
173 "solve(f,x)"
174 ]
175 },
176 {
177 "cell_type": "markdown",
178 "metadata": {},
179 "source": [
180 "Some common constants are [already defined](https://doc.sagemath.org/html/en/reference/calculus/sage/symbolic/expression.html) in Sage:"
181 ]
182 },
183 {
184 "cell_type": "code",
185 "execution_count": 17,
186 "metadata": {},
187 "outputs": [
188 {
189 "data": {
190 "text/plain": [
191 "-1"
192 ]
193 },
194 "execution_count": 17,
195 "metadata": {},
196 "output_type": "execute_result"
197 }
198 ],
199 "source": [
200 "e^(pi*I)"
201 ]
202 },
203 {
204 "cell_type": "markdown",
205 "metadata": {},
206 "source": [
207 "We will study symbolic expressions more in detail next time, in the context of calculus/analysis."
208 ]
209 },
210 {
211 "cell_type": "markdown",
212 "metadata": {},
213 "source": [
214 "# Basic rings and fields\n",
215 "\n",
216 "**References:** [[3](https://doc.sagemath.org/html/en/reference/rings_standard/index.html)]\n",
217 "[[4](https://doc.sagemath.org/html/en/reference/rings_numerical/index.html)]\n",
218 "[[5](https://doc.sagemath.org/html/en/reference/finite_rings/index.html)]\n",
219 "\n",
220 "As you should know, a *field* is a Mathematical structure with two operations, addition and multiplication, which respect certain rules (distributivity, associativity, commutativity...). Some examples of fields are the Rational numbers $\\mathbb Q$, the Real numbers $\\mathbb R$ and the Complex numbers $\\mathbb C$, but there are many more. As you should also know, a *(commutative) ring* is like a field, except not all elements different from $0$ need have a multiplicative inverse. For example the integers $\\mathbb Z = \\{ \\dots, -1, 0, 1, 2, \\dots\\}$ are a ring, but not a field.\n",
221 "\n",
222 "These structures are already implemented in Sage. Some of the most common are listed in the following table:\n",
223 "\n",
224 "|Mathematical object|Math symbol|Sage name|\n",
225 "|------------------:|:---------:|:--------|\n",
226 "|Integers|$\\mathbb Z$|`ZZ`|\n",
227 "|Rational numbers|$\\mathbb Q$|`QQ`|\n",
228 "|Real numbers|$\\mathbb R$|`RR`|\n",
229 "|Complex numbers|$\\mathbb C$|`CC`|\n",
230 "|Integers modulo $n$|$\\mathbb Z/n\\mathbb Z$|`Integers(n)`|\n",
231 "|Finite fields|$\\mathbb F_p$|GF(p)|\n",
232 "|$\\dots$|$\\dots$|$\\dots$|"
233 ]
234 },
235 {
236 "cell_type": "markdown",
237 "metadata": {},
238 "source": [
239 "If you write a number or an expression, Sage will figure out where it \"lives\", choosing the most restrictive interpretation possible. For example `3` will be interpreted to be an integer, even if it is also a rational number, a real number and a complex number."
240 ]
241 },
242 {
243 "cell_type": "markdown",
244 "metadata": {},
245 "source": [
246 "## Parents and coercion\n",
247 "**Reference:** [[6](https://doc.sagemath.org/html/en/tutorial/tour_coercion.html)]\n",
248 "\n",
249 "You can check where an object \"lives\" with the `parent()` command. It works more or less like the Python command `type()`, but it gives a more Mathematically inclined answer. Check the reference link [6] above if you want more details."
250 ]
251 },
252 {
253 "cell_type": "code",
254 "execution_count": 18,
255 "metadata": {},
256 "outputs": [
257 {
258 "data": {
259 "text/plain": [
260 "Rational Field"
261 ]
262 },
263 "execution_count": 18,
264 "metadata": {},
265 "output_type": "execute_result"
266 }
267 ],
268 "source": [
269 "#Edit this cell to find out the type of other objects that we used\n",
270 "parent(3/5)"
271 ]
272 },
273 {
274 "cell_type": "markdown",
275 "metadata": {},
276 "source": [
277 "Sometimes Sage does not give you the best possible interpretation, so you can force something to be interpreted as living in a smaller ring as follows:"
278 ]
279 },
280 {
281 "cell_type": "code",
282 "execution_count": 4,
283 "metadata": {},
284 "outputs": [
285 {
286 "name": "stdout",
287 "output_type": "stream",
288 "text": [
289 "Symbolic Ring\n",
290 "Integer Ring\n"
291 ]
292 }
293 ],
294 "source": [
295 "minus_one = e^(pi*I)\n",
296 "minus_one_coerced = ZZ(e^(pi*I)) # coercion\n",
297 "print(parent(minus_one))\n",
298 "print(parent(minus_one_coerced))"
299 ]
300 },
301 {
302 "cell_type": "markdown",
303 "metadata": {},
304 "source": [
305 "**Remark.** Notice that there is a fundamental difference between the rings `RR` and `CC` and all the others in the table above: the real and complex numbers are *approximated*."
306 ]
307 },
308 {
309 "cell_type": "code",
310 "execution_count": 1,
311 "metadata": {},
312 "outputs": [
313 {
314 "name": "stdout",
315 "output_type": "stream",
316 "text": [
317 "3\n",
318 "3.00000000000000\n"
319 ]
320 }
321 ],
322 "source": [
323 "print(QQ(3))\n",
324 "print(RR(3))"
325 ]
326 },
327 {
328 "cell_type": "markdown",
329 "metadata": {},
330 "source": [
331 "You can also choose the precision of this approximation using the alternative name `RealField`."
332 ]
333 },
334 {
335 "cell_type": "code",
336 "execution_count": 4,
337 "metadata": {},
338 "outputs": [
339 {
340 "name": "stdout",
341 "output_type": "stream",
342 "text": [
343 "Real Field with 53 bits of precision\n",
344 "Real Field with 1000 bits of precision\n"
345 ]
346 }
347 ],
348 "source": [
349 "print(RR)\n",
350 "print(RealField(prec=1000))"
351 ]
352 },
353 {
354 "cell_type": "markdown",
355 "metadata": {},
356 "source": [
357 "# Polynomial rings\n",
358 "\n",
359 "**Reference:** [[7](https://doc.sagemath.org/html/en/reference/polynomial_rings/index.html)]\n",
360 "\n",
361 "If you want to work with polynomials over a certain ring it is better to use this specific construction, rather than the symbolic expressions introduced above."
362 ]
363 },
364 {
365 "cell_type": "code",
366 "execution_count": 5,
367 "metadata": {},
368 "outputs": [
369 {
370 "data": {
371 "text/plain": [
372 "Multivariate Polynomial Ring in x, y, z over Real Field with 53 bits of precision"
373 ]
374 },
375 "execution_count": 5,
376 "metadata": {},
377 "output_type": "execute_result"
378 }
379 ],
380 "source": [
381 "polring.<x,y,z> = RR[] # Alternative: polring.<x,y,z> = PolynomialRing(RR)\n",
382 "polring"
383 ]
384 },
385 {
386 "cell_type": "markdown",
387 "metadata": {},
388 "source": [
389 "You can use as many variables as you like, and you can replace `RR` with any ring. In the example above `polring` is just the name of the variable (in the computer science sense) associated with this polynomial ring.\n",
390 "\n",
391 "## Operations on polynomials\n",
392 "\n",
393 "The usual Mathematical operations are available on polynomial rings, including Euclidean division `//` and remainder `%`. There is also the single-slash division `/`, but the result may not be a polynomial anymore.\n",
394 "\n",
395 "**Exercise:** use the `parent()` command to find out what the quotient of two polynomials is.\n",
396 "\n",
397 "**Question:** what happens if you remove the first line in the cell below? What if we used the variable `y` instead of `x`?"
398 ]
399 },
400 {
401 "cell_type": "code",
402 "execution_count": 6,
403 "metadata": {},
404 "outputs": [
405 {
406 "name": "stdout",
407 "output_type": "stream",
408 "text": [
409 "x + 1\n",
410 "-4\n",
411 "(x^2 + 2*x - 3)/(x + 1)\n"
412 ]
413 }
414 ],
415 "source": [
416 "polring.<x> = QQ[]\n",
417 "p = x^2 + 2*x - 3 # Don't forget * for multiplication!\n",
418 "q = p // (x+1)\n",
419 "r = p % (x+1)\n",
420 "f = p / (x+1)\n",
421 "print(q)\n",
422 "print(r)\n",
423 "print(f)"
424 ]
425 },
426 {
427 "cell_type": "markdown",
428 "metadata": {},
429 "source": [
430 "You can do more complex operations. Try out `roots()` and `factor` in the cell below.\n",
431 "\n",
432 "**Remark.** Notice how the result can change substantially if you change the base ring.\n",
433 "\n",
434 "**Remark.** [Factorizations](https://doc.sagemath.org/html/en/reference/structure/sage/structure/factorization.html) are a particular object in Sage. They are kinda like a list, but not really. You can get a list of pairs (factor, power) with `list(factor(f))`."
435 ]
436 },
437 {
438 "cell_type": "code",
439 "execution_count": 7,
440 "metadata": {},
441 "outputs": [
442 {
443 "name": "stdout",
444 "output_type": "stream",
445 "text": [
446 "(t + 1) * (t^2 - 3) * (t^2 + 1)\n",
447 "[(-1, 1)]\n"
448 ]
449 },
450 {
451 "data": {
452 "text/plain": [
453 "(y + 1) * x"
454 ]
455 },
456 "execution_count": 7,
457 "metadata": {},
458 "output_type": "execute_result"
459 }
460 ],
461 "source": [
462 "polring_onevar.<t> = QQ[]\n",
463 "\n",
464 "f = t^5 + t^4 - 2*t^3 - 2*t^2 - 3*t - 3\n",
465 "print(factor(f))\n",
466 "print(f.roots()) # Result: list of pairs (root,multiplicity)\n",
467 "\n",
468 "polring_manyvar.<x,y,z> = QQ[]\n",
469 "factor(x*y+x)\n",
470 "\n",
471 "# The following line gives an error, because the polynomial\n",
472 "# is understood to possibly have many variables:\n",
473 "#(x^2-1).roots()"
474 ]
475 },
476 {
477 "cell_type": "markdown",
478 "metadata": {},
479 "source": [
480 "# Matrices and vectors\n",
481 "\n",
482 "**References:** [[8](https://doc.sagemath.org/html/en/reference/matrices/index.html)], but in particular the subections [[9](https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/docs.html)] and [[10](https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/matrix2.html)]\n",
483 "\n",
484 "In Sage you can easily manipulate matrices and vectors"
485 ]
486 },
487 {
488 "cell_type": "code",
489 "execution_count": 77,
490 "metadata": {},
491 "outputs": [
492 {
493 "name": "stdout",
494 "output_type": "stream",
495 "text": [
496 "[ 1 2 3]\n",
497 "[ 0 0 1]\n",
498 "[ 4 -3 22/7] \n",
499 "\n",
500 "[1/2 0 0]\n",
501 "[ 7 0 0]\n",
502 "[ 1 1 1] \n",
503 "\n",
504 "(3/2, 21, 6) \n",
505 "\n",
506 "[ -7/2 -10 80/7]\n",
507 "[ 17 -4 15/7]\n",
508 "[ 241/7 -18/7 869/49] \n",
509 "\n",
510 "Rank of A = 3\n",
511 "Rank of B = 2\n"
512 ]
513 }
514 ],
515 "source": [
516 "A = matrix([[1,2,3],[0,0,1],[4,-3,22/7]])\n",
517 "B = matrix([[1/2,0,0],[7,0,0],[1,1,1]])\n",
518 "v = vector([3,4,-1])\n",
519 "\n",
520 "print(A, \"\\n\") # \\n just means \"newline\"\n",
521 "print(B, \"\\n\")\n",
522 "print(B*v, \"\\n\")\n",
523 "print(A^2 + 2*B - A*B, \"\\n\")\n",
524 "\n",
525 "print(\"Rank of A =\", rank(A)) # You can also use A.rank()\n",
526 "print(\"Rank of B =\", rank(B))"
527 ]
528 },
529 {
530 "cell_type": "markdown",
531 "metadata": {},
532 "source": [
533 "**Exercise:** in the cell above, compute the determinant, inverse and characteristic polynomial of the matrix `A`. *Hint: look at the reference [10] above (the functions are listed in alphabetic order).*\n",
534 "\n",
535 "As for polynomials, you can specify where a matrix or a vector lives"
536 ]
537 },
538 {
539 "cell_type": "code",
540 "execution_count": 57,
541 "metadata": {},
542 "outputs": [
543 {
544 "data": {
545 "text/plain": [
546 "Full MatrixSpace of 2 by 2 dense matrices over Complex Field with 53 bits of precision"
547 ]
548 },
549 "execution_count": 57,
550 "metadata": {},
551 "output_type": "execute_result"
552 }
553 ],
554 "source": [
555 "M = matrix(CC, [[0,1],[1,0]])\n",
556 "parent(M)"
557 ]
558 },
559 {
560 "cell_type": "markdown",
561 "metadata": {},
562 "source": [
563 "You can also solve linear systems and compute eigenvalues and eigenvectors of a matrix\n",
564 "\n",
565 "**Warning.** In linear algebra there are distinct concepts of *left* and *right* eigenvalues (and eigenvector). The one you know is probably that of **right** eigen-{value,vector}, that is an element $\\lambda$ of the base field and a non-zero vector $\\mathbf v$ with $A\\mathbf v=\\lambda\\mathbf v$. The other concept corresponds to the equality $\\mathbf v^TA=\\lambda \\mathbf v$."
566 ]
567 },
568 {
569 "cell_type": "code",
570 "execution_count": 60,
571 "metadata": {},
572 "outputs": [
573 {
574 "data": {
575 "text/plain": [
576 "(0.289916349448506, 0.0241596957873755)"
577 ]
578 },
579 "execution_count": 60,
580 "metadata": {},
581 "output_type": "execute_result"
582 }
583 ],
584 "source": [
585 "A = Matrix(RR, [[sqrt(59),32],[-1/4,3]])\n",
586 "v = vector(RR, [3,0])\n",
587 "A.solve_right(v) # Solve Ax=v. Alternative: A \\ v"
588 ]
589 },
590 {
591 "cell_type": "code",
592 "execution_count": 64,
593 "metadata": {},
594 "outputs": [
595 {
596 "data": {
597 "text/plain": [
598 "[\n",
599 "(-0.3722813232690144?, Vector space of degree 2 and dimension 1 over Algebraic Field\n",
600 "User basis matrix:\n",
601 "[ 1 -0.6861406616345072?]),\n",
602 "(5.372281323269015?, Vector space of degree 2 and dimension 1 over Algebraic Field\n",
603 "User basis matrix:\n",
604 "[ 1 2.186140661634508?])\n",
605 "]"
606 ]
607 },
608 "execution_count": 64,
609 "metadata": {},
610 "output_type": "execute_result"
611 }
612 ],
613 "source": [
614 "A = Matrix(QQ, [[1,2],[3,4]])\n",
615 "A.eigenspaces_right() # Also: A.eigenvalues(), A.eigenvectors_right()"
616 ]
617 },
618 {
619 "cell_type": "markdown",
620 "metadata": {},
621 "source": [
622 "We can also extract a specific submatrix by selecting only some rows and columns, with a syntax similar to that of Python's lists. Check out more examples in the reference [9] above, and try them in the cell below."
623 ]
624 },
625 {
626 "cell_type": "code",
627 "execution_count": 94,
628 "metadata": {},
629 "outputs": [
630 {
631 "name": "stdout",
632 "output_type": "stream",
633 "text": [
634 "[-14 2 0 -1 1 -2 -1]\n",
635 "[ 0 -8 0 9 -2 11 1]\n",
636 "[ 0 3 1 -1 1 1 221]\n",
637 "[ -1 2 1 -25 -10 4 0]\n",
638 "[ -3 0 0 2 16 -1 -2]\n",
639 "[ 1 -3 3 -41 1 0 0]\n",
640 "[ -2 1 0 0 -6 2 12] \n",
641 "\n",
642 "[ 0 9 -2]\n",
643 "[ 1 -1 1] \n",
644 "\n",
645 "[-14 2 0 -1 1 -2 -1] \n",
646 "\n",
647 "[-14 2 0 -1 1]\n",
648 "[ 1 -3 3 -41 1]\n",
649 "[ 0 3 1 -1 1]\n"
650 ]
651 }
652 ],
653 "source": [
654 "A = MatrixSpace(ZZ, 7).random_element()\n",
655 "print(A, \"\\n\")\n",
656 "print(A[1:3,2:5], \"\\n\") # Rows from 1 to 3, columns from 2 to 5\n",
657 "print(A[0,0:], \"\\n\") # First row, all columns\n",
658 "print(A[[0,5,2],0:5]) # Rows 0, 5 and 2 (in this order) and columns 0 to 5"
659 ]
660 },
661 {
662 "cell_type": "markdown",
663 "metadata": {},
664 "source": [
665 "**Exercise:** write a sage function that computes the determinant of an $n\\times n$ matrix $A=(a_{ij})$ using Laplace's rule by the first row, that is \n",
666 "\\begin{align*}\n",
667 " \\operatorname{det}A = \\sum_{j=1}^n (-1)^ja_{0j}M_{0j}\n",
668 "\\end{align*}\n",
669 "where $M_{0j}$ is the determinant of the $(n-1)\\times(n-1)$ matrix obtained by removing the $0$-th row and the $j$-th column from $A$."
670 ]
671 },
672 {
673 "cell_type": "code",
674 "execution_count": 91,
675 "metadata": {},
676 "outputs": [],
677 "source": [
678 "def my_det(A):\n",
679 " if not A.is_square():\n",
680 " print(\"Error: matrix is not square\")\n",
681 " \n",
682 " n = A.nrows() # size of the matrix\n",
683 " \n",
684 " # Continue from here!"
685 ]
686 },
687 {
688 "cell_type": "markdown",
689 "metadata": {},
690 "source": [
691 "# Number Theory\n",
692 "\n",
693 "**Reference:** [[11](https://doc.sagemath.org/html/en/reference/rings_standard/sage/rings/integer.html)]\n",
694 "\n",
695 "Sage includes a large library of functions for computing with the integers, see the link above."
696 ]
697 },
698 {
699 "cell_type": "code",
700 "execution_count": 8,
701 "metadata": {},
702 "outputs": [
703 {
704 "name": "stdout",
705 "output_type": "stream",
706 "text": [
707 "3^2 * 3607 * 3803\n",
708 "True\n",
709 "True\n",
710 "619703040\n",
711 "9\n",
712 "13548070123626141\n"
713 ]
714 }
715 ],
716 "source": [
717 "n = 123456789\n",
718 "m = 987654321\n",
719 "p = 3607\n",
720 "\n",
721 "print(factor(n))\n",
722 "print(is_prime(p))\n",
723 "print(p.divides(n))\n",
724 "print(euler_phi(m))\n",
725 "print(gcd(n, m))\n",
726 "print(lcm(n, m))"
727 ]
728 },
729 {
730 "cell_type": "markdown",
731 "metadata": {},
732 "source": [
733 "## Primes\n",
734 "\n",
735 "**Reference:** [[12](https://doc.sagemath.org/html/en/reference/sets/sage/sets/primes.html)]\n",
736 "\n",
737 "The set of prime numbers is called `Primes()`. It is like an infinite list: for example you can get the one-millionth prime number or you can use this list to create other lists. You can also check what the first prime number larger than a given number is."
738 ]
739 },
740 {
741 "cell_type": "code",
742 "execution_count": 9,
743 "metadata": {},
744 "outputs": [
745 {
746 "name": "stdout",
747 "output_type": "stream",
748 "text": [
749 "Set of all prime numbers: 2, 3, 5, 7, ...\n",
750 "31 15485867\n",
751 "47\n",
752 "[79, 83, 89, 97]\n"
753 ]
754 }
755 ],
756 "source": [
757 "PP = Primes()\n",
758 "print(PP)\n",
759 "print(PP[10], PP[10^6])\n",
760 "print(PP.next(44))\n",
761 "\n",
762 "First_Thousand_Primes = PP[0:1000]\n",
763 "print([p for p in First_Thousand_Primes if p < 100 and p > 75])"
764 ]
765 },
766 {
767 "cell_type": "markdown",
768 "metadata": {},
769 "source": [
770 "## The Chinese remainder theorem (CRT)\n",
771 "\n",
772 "We say that two integers $a$ and $b$ are *congruent* modulo another integer $n>0$ if they have the same remainder when divided by $n$. We denote this by $a\\equiv b\\pmod n$, or in Python/Sage syntax `a % n == b % n`.\n",
773 "\n",
774 "The Chinese remainder theorem states that if $a,b\\in\\mathbb Z$ and $n,m\\in \\mathbb Z_{>0}$ are such that $\\gcd(n,m)=1$ then the system of congruences\n",
775 "\n",
776 "\\begin{align*}\n",
777 "\\begin{cases}\n",
778 " x \\equiv a \\pmod n\\\\\n",
779 " x \\equiv b \\pmod m\n",
780 "\\end{cases}\n",
781 "\\end{align*}\n",
782 "\n",
783 "has exactly one solution modulo $mn$. This means that there is one and only one number $x$ with $0\\leq x<mn$ such that $x\\equiv a\\pmod n$ and $x\\equiv b\\pmod m$.\n",
784 "\n",
785 "The procedure to find such a number is not too hard to describe (you might see it in an algebra or number theory course), but it can be a bit long. Luckily, Sage can do this for you:"
786 ]
787 },
788 {
789 "cell_type": "code",
790 "execution_count": 10,
791 "metadata": {},
792 "outputs": [
793 {
794 "name": "stdout",
795 "output_type": "stream",
796 "text": [
797 "74306 2 798\n"
798 ]
799 }
800 ],
801 "source": [
802 "a = 2\n",
803 "b = -1\n",
804 "n = 172\n",
805 "m = 799\n",
806 "\n",
807 "if gcd(n,m) != 1:\n",
808 " print(\"The numbers are not comprime, I can't solve this!\")\n",
809 "else:\n",
810 " x = crt(a, b, n, m)\n",
811 " print(x, x%n, x%m)"
812 ]
813 },
814 {
815 "cell_type": "markdown",
816 "metadata": {},
817 "source": [
818 "**Exercise.** There is a more general version of the Chinese remainder theorem which says that if $a_0, a_1, \\dots, a_k\\in\\mathbb Z$ and $n_0, n_2, \\dots, n_k\\in\\mathbb Z_{>0}$ are such that $\\gcd(n_i, n_j)=1$ for $i\\neq j$, then the system of congruences\n",
819 "\n",
820 "\\begin{align*}\n",
821 "\\begin{cases}\n",
822 " x \\equiv a_0 \\pmod {n_0}\\\\\n",
823 " x \\equiv a_1 \\pmod {n_1}\\\\\n",
824 " \\dots \\\\\n",
825 " x \\equiv a_k \\pmod {n_k}\n",
826 "\\end{cases}\n",
827 "\\end{align*}\n",
828 "\n",
829 "has exactly one solution modulo $\\prod_{i=0}^kn_i$. Use the `crt()` function to find a solution to such a system.\n",
830 "*Hint: start by running the command `help(crt)`."
831 ]
832 },
833 {
834 "cell_type": "code",
835 "execution_count": 127,
836 "metadata": {},
837 "outputs": [],
838 "source": [
839 "#help(crt)"
840 ]
841 },
842 {
843 "cell_type": "markdown",
844 "metadata": {},
845 "source": [
846 "# Cryptography: RSA\n",
847 "\n",
848 "[Cryptography](https://en.wikipedia.org/wiki/Cryptography) is the discipline that studies methods to communicate secrets in such a way that any unauthorized listener would not be able to understand the message.\n",
849 "\n",
850 "A simple cryptographic protocol could be changing every letter of your text following a fixed scheme (or *cypher*), for example by turning every A into a B, every B into a C and so on. However this is not a very secure method, for many reasons. One of them is that at some point the people who want to communicate need to agree on what method to use, and anyone listening to that conversation would be able to decypher every subsequent conversation. A public-key cryptographic protocol solves this problem.\n",
851 "\n",
852 "## Public-key cryptography\n",
853 "\n",
854 "Public-key cryptographic protocols, such as RSA, work like this: there are two keys, a *private* key that is only known to person A (traditionally called Alice in every example), and a *public* key that does not need to be secret.\n",
855 "\n",
856 "The public key is used to *encrypt* the message (that is to \"lock\" it, or \"hyde\" it), but one needs the private key to *decrypt* it. Imagine having two keys for your door, but one can only be used to lock it, while the other only to open it.\n",
857 "\n",
858 "The message exchange works like this: suppose that person B (Bob) wants to send a secret message to Alice. Then Alice secretely generates a private and a public key and sends only the public one to Bob. Now Bob encrypts the message and sends it to Alice, who can use her private key to decrypt it. Even if Eve (short for *eavesdropper*, an unauthorized listener) listens to every message exchanged, she won't be able to decypher the secret: the private key has never left Alice's house!\n",
859 "\n",
860 "Notice that such a protocol is *asymmetric*: if Alice wanted to send a secret to Bob in reply, Bob would need to generate a pair of keys of his own.\n",
861 "\n",
862 "Let's see how we can do this in practice, using number theory!\n",
863 "\n",
864 "## RSA\n",
865 "\n",
866 "As many other cryptography protocols, RSA is based on a Mathematical process that is easy to do in one direction, but very hard to invert. In this case the hard process is integer factorization, that is decomposing an integer number as a product of primes."
867 ]
868 },
869 {
870 "cell_type": "code",
871 "execution_count": 2,
872 "metadata": {},
873 "outputs": [
874 {
875 "name": "stdout",
876 "output_type": "stream",
877 "text": [
878 "True True False\n"
879 ]
880 }
881 ],
882 "source": [
883 "p = 100003100019100043100057100069\n",
884 "q = 100144655312449572059845328443\n",
885 "n = p*q\n",
886 "print(is_prime(p), is_prime(q), is_prime(p*q))\n",
887 "\n",
888 "# Use the command below to see how long it takes\n",
889 "#timeit(\"factor(n)\", number=1, repeat=1)"
890 ]
891 },
892 {
893 "cell_type": "markdown",
894 "metadata": {},
895 "source": [
896 "In order to generate the keys, Alice picks a number $n$ which is the product of two large primes $p$ and $q$ of more or less the same size. Finding such primes is relatively easy compared to factoring the number $n$ she obtained. Then she computes the Euler totient $\\varphi(n)=(p-1)(q-1)$ of $n$, which she can do because she knows that $n=pq$ - it would be impossible otherwise!\n",
897 "\n",
898 "Then Alice can compute two integers $(d,e)$ such that $de\\equiv 1\\pmod{\\varphi(n)}$. She will send the numbers $n$ and $d$ to Bob and keep $e$ secret. In this case the public key is the pair $(n,d)$, while $e$ is the private key.\n",
899 "\n",
900 "Of course, she does all of this using Sage!"
901 ]
902 },
903 {
904 "cell_type": "code",
905 "execution_count": 105,
906 "metadata": {},
907 "outputs": [
908 {
909 "data": {
910 "text/plain": [
911 "(419199544978969, 235530823946467, 80799425863927)"
912 ]
913 },
914 "execution_count": 105,
915 "metadata": {},
916 "output_type": "execute_result"
917 }
918 ],
919 "source": [
920 "def two_large_primes():\n",
921 " p, q = 0, 0\n",
922 " # We make sure that they are different\n",
923 " while p == q:\n",
924 " p = Primes()[randint(10^6, 2*10^6)]\n",
925 " q = Primes()[randint(10^6, 2*10^6)]\n",
926 " return p, q\n",
927 "\n",
928 "def random_unit_mod(N):\n",
929 " R = Integers(N)\n",
930 " d = R(0)\n",
931 " # We make sure that it is invertible\n",
932 " while not d.is_unit():\n",
933 " d = R.random_element()\n",
934 " return d\n",
935 "\n",
936 "def Alice_generate_keys():\n",
937 " p, q = two_large_primes()\n",
938 " n = p*q\n",
939 " phi_n = (p-1)*(q-1) # euler_phi(n) is slow!\n",
940 " \n",
941 " d = random_unit_mod(phi_n)\n",
942 " e = d^-1\n",
943 " return n, d, e\n",
944 "\n",
945 "Alice_generate_keys()"
946 ]
947 },
948 {
949 "cell_type": "markdown",
950 "metadata": {},
951 "source": [
952 "Now, how does Bob encrypt his message? Let's say he wants to send to Alice the number $m$ with $1<m<n$ (In practice he would like to send her some text with emojis, or maybe a voice message; but for computers everything is a number, and there are different ways to translate any sort of information to a number. He just chooses one of the many standard methods that already exist, no cryptography is needed in this step. If the message $m$ is too long, he can split it up in some pieces and repeat the process multiple times.)\n",
953 "\n",
954 "Now he computes $m^d\\pmod n$ and sends it back to Alice."
955 ]
956 },
957 {
958 "cell_type": "code",
959 "execution_count": 3,
960 "metadata": {},
961 "outputs": [
962 {
963 "data": {
964 "text/plain": [
965 "149461597163501"
966 ]
967 },
968 "execution_count": 3,
969 "metadata": {},
970 "output_type": "execute_result"
971 }
972 ],
973 "source": [
974 "def Bob_encrypt(m, n, d):\n",
975 " R = Integers(n)\n",
976 " return R(m)^d # Assume that n is large enough\n",
977 " \n",
978 "message = 42424242\n",
979 "Bob_encrypt(message, 419199544978969, 235530823946467)"
980 ]
981 },
982 {
983 "cell_type": "markdown",
984 "metadata": {},
985 "source": [
986 "Since $de\\equiv 1\\pmod{\\varphi(n)}$, it follows that $(m^d)^e\\equiv m\\pmod n$ (see [Wikipedia: Euler's theorem](https://en.wikipedia.org/wiki/Euler%27s_theorem)). So for Alice it is very easy to get back the original message:"
987 ]
988 },
989 {
990 "cell_type": "code",
991 "execution_count": 108,
992 "metadata": {},
993 "outputs": [
994 {
995 "data": {
996 "text/plain": [
997 "42424242"
998 ]
999 },
1000 "execution_count": 108,
1001 "metadata": {},
1002 "output_type": "execute_result"
1003 }
1004 ],
1005 "source": [
1006 "def Alice_decrypt(m_encrypted, n, e):\n",
1007 " R = Integers(n)\n",
1008 " return R(m_encrypted)^e\n",
1009 "\n",
1010 "Alice_decrypt(149461597163501, 419199544978969, 80799425863927)"
1011 ]
1012 },
1013 {
1014 "cell_type": "markdown",
1015 "metadata": {},
1016 "source": [
1017 "Another assumption on which RSA relies is that even if one knows $M=m^e$ and $e$, extracting the $e$-th root of $M$ modulo $n$ (and thus obtaining $m$) is very hard. Currently the best known way to do this is by factorizing $n$ first, which is considered to be a very hard problem. However, there is no proof that faster algorithms can't be devised.\n",
1018 "\n",
1019 "Moreover, one day we will overcome the current technological difficulties and quantum computers will be available. Quantum computers are not just \"more powerful\" than classical hardware, but they work based on completely different logical foundations and they make the factorization problem much easier to solve: for example [Shor's algorithm](https://en.wikipedia.org/wiki/Shor%27s_algorithm) takes advantage of this different logic and can factorize numbers quickly, if run on a quantum computer.\n",
1020 "\n",
1021 "To this day the largest number factorized with a quantum computer is $21=3\\times 7$. Nonetheless, quantum-safe cryptography protocols (i.e. based on problems that are hard to solve also with quantum computers) have already been developed."
1022 ]
1023 }
1024 ],
1025 "metadata": {
1026 "kernelspec": {
1027 "display_name": "SageMath 9.2",
1028 "language": "sage",
1029 "name": "sagemath"
1030 },
1031 "language_info": {
1032 "codemirror_mode": {
1033 "name": "ipython",
1034 "version": 3
1035 },
1036 "file_extension": ".py",
1037 "mimetype": "text/x-python",
1038 "name": "python",
1039 "nbconvert_exporter": "python",
1040 "pygments_lexer": "ipython3",
1041 "version": "3.8.5"
1042 }
1043 },
1044 "nbformat": 4,
1045 "nbformat_minor": 4
1046}
diff --git a/src/Lecture5/notebook/.ipynb_checkpoints/7-SageAlgebra-modified+solutions-checkpoint.ipynb b/src/Lecture5/notebook/.ipynb_checkpoints/7-SageAlgebra-modified+solutions-checkpoint.ipynb
new file mode 100644
index 0000000..f4e39b2
--- /dev/null
+++ b/src/Lecture5/notebook/.ipynb_checkpoints/7-SageAlgebra-modified+solutions-checkpoint.ipynb
@@ -0,0 +1,1099 @@
1{
2 "cells": [
3 {
4 "cell_type": "markdown",
5 "metadata": {},
6 "source": [
7 "This lecture's notes are in a different format: the presentations for the $\\LaTeX$ part were made with $\\LaTeX$, so this one is made with Sage, or rather with the [Jupyter Notebook](https://jupyter.org/).\n",
8 "\n",
9 "# The Jupyter Notebook\n",
10 "**Reference:** [[1](https://jupyter.org/documentation)]\n",
11 "\n",
12 "The Jupyter Notebook is one of the default interfaces for SageMath, along with the command line interface. You can access it via web browser, but it is running locally on your device (notice the strange url: `http://localhost:8888/notebooks...`).\n",
13 "\n",
14 "You can create a new notebook by clicking on `New > SageMath 9.2`. You can also create a Python 3 notebook to write Python code.\n",
15 "\n",
16 "Jupyter saves and reads files in the `.ipynb` format. If you download the file for this lecture you can open it and follow the examples interactively.\n",
17 "\n",
18 "## Cells\n",
19 "\n",
20 "The notebook contains one or more *interactive cells* that you can run, like this one below:"
21 ]
22 },
23 {
24 "cell_type": "code",
25 "execution_count": null,
26 "metadata": {},
27 "outputs": [],
28 "source": [
29 "# Exercise: modify this cell to use the print() command\n",
30 "\n",
31 "a = 34*102\n",
32 "\n",
33 "print(2+2)\n",
34 "print(\"hello\")\n",
35 "print(a-1)"
36 ]
37 },
38 {
39 "cell_type": "markdown",
40 "metadata": {},
41 "source": [
42 "If you are reading this from Jupyter rather than from the pdf file, you can edit the cell above and run it again. You can also add more cells by selecting `Insert` from the menu bar.\n",
43 "\n",
44 "Notice that only the last statement produces an output. You can force anything to be written as output with the `print()` command, which works like in Python. As an exercise, try to modify the cell above to provide more output!"
45 ]
46 },
47 {
48 "cell_type": "code",
49 "execution_count": null,
50 "metadata": {},
51 "outputs": [],
52 "source": [
53 "print(a)"
54 ]
55 },
56 {
57 "cell_type": "markdown",
58 "metadata": {},
59 "source": [
60 "text *hello*\n",
61 "* this\n",
62 "* is\n",
63 "* a list"
64 ]
65 },
66 {
67 "cell_type": "markdown",
68 "metadata": {},
69 "source": [
70 "## Markdown\n",
71 "\n",
72 "[Markdown](https://en.wikipedia.org/wiki/Markdown) is a simple markup language - think of LaTeX or html, but much simpler.\n",
73 "You can add text to your notebook with Markdown cells by selecting `Cell > Cell Type > Markdown`.\n",
74 "\n",
75 "You can also include some LaTeX code in Markdown cells, with dollar signs $ or align environments:\n",
76 "\n",
77 "\\begin{align*}\n",
78 "\\frac{(x+y)^2}{x+1} = \\frac{x^2+2xy+y^2}{x+1}\n",
79 "\\end{align*}\n",
80 "\n",
81 "When you are done writing a Markdown cell, you can run it to see the well-formatted text. To edit the text again, double-click on the cell. Try doing it now to fix the formula above!"
82 ]
83 },
84 {
85 "cell_type": "markdown",
86 "metadata": {},
87 "source": [
88 "# Symbolic expressions\n",
89 "\n",
90 "**Reference:** [[2](https://doc.sagemath.org/html/en/reference/calculus/sage/symbolic/expression.html)]\n",
91 "\n",
92 "Now, let's get started with Sage. One thing you might want to do is manipulating symbolic expressions, like the following:"
93 ]
94 },
95 {
96 "cell_type": "code",
97 "execution_count": 48,
98 "metadata": {},
99 "outputs": [
100 {
101 "name": "stdout",
102 "output_type": "stream",
103 "text": [
104 "[\n",
105 "x == -1/2*(I*sqrt(3) + 1)*(1/2*I*sqrt(3) - 1/2)^(1/3) + (1/2*I*sqrt(3) - 1/2)^(2/3) - 1,\n",
106 "x == (1/2*I*sqrt(3) - 1/2)^(4/3) - 1/2*(I*sqrt(3) + 1)/(1/2*I*sqrt(3) - 1/2)^(1/3) - 1,\n",
107 "x == (1/2*I*sqrt(3) - 1/2)^(1/3) + 1/(1/2*I*sqrt(3) - 1/2)^(1/3) - 1\n",
108 "]\n"
109 ]
110 }
111 ],
112 "source": [
113 "f = (x^2 + 2*x - 5 >= 0)\n",
114 "solve(f,x)\n",
115 "\n",
116 "g = x^3 + 3*x^2-1\n",
117 "print(solve(g==0, x))\n",
118 "\n",
119 "h = x^2 +3*x -1"
120 ]
121 },
122 {
123 "cell_type": "markdown",
124 "metadata": {},
125 "source": [
126 "Notice that the single `=` is part of an assignment, as in Python: we are *assigning* to the variable `f` the value `x^2 + 2*x - 5 >= 0`, which in this case is an equation, so it contains the symbol `==`. Keep in mind the difference between the two!\n",
127 "\n",
128 "**Exercise:** change the code above to solve the corresponding inequality $x^2+2x-5\\geq 0$."
129 ]
130 },
131 {
132 "cell_type": "markdown",
133 "metadata": {},
134 "source": [
135 "## Mathematical variables\n",
136 "\n",
137 "Last time we saw what *variables* are in Python, and that they are a little bit different from the *Mathematical variables* that you use in Mathematics. In Sage, both concepts are present, but they are still distinct. For example in the cell above `f` is a variable in the sense of computer science, while `x` is a Mathematical variable.\n",
138 "\n",
139 "If you want to use Mathematical variables other than `x`, you first need to *declare* them with the `var()` command:"
140 ]
141 },
142 {
143 "cell_type": "code",
144 "execution_count": null,
145 "metadata": {},
146 "outputs": [],
147 "source": [
148 "var('z')\n",
149 "solve(z^2 + z - 2 == 0, z)"
150 ]
151 },
152 {
153 "cell_type": "markdown",
154 "metadata": {},
155 "source": [
156 "Try removing the first line in the cell above and see what error you get!\n",
157 "\n",
158 "Here is another example:"
159 ]
160 },
161 {
162 "cell_type": "code",
163 "execution_count": null,
164 "metadata": {},
165 "outputs": [],
166 "source": [
167 "var('a', 'b')\n",
168 "f = x^2+a*x+b == 0\n",
169 "solve(f,a)"
170 ]
171 },
172 {
173 "cell_type": "markdown",
174 "metadata": {},
175 "source": [
176 "Some common constants are [already defined](https://doc.sagemath.org/html/en/reference/calculus/sage/symbolic/expression.html) in Sage:"
177 ]
178 },
179 {
180 "cell_type": "code",
181 "execution_count": null,
182 "metadata": {},
183 "outputs": [],
184 "source": [
185 "e^(pi*I)\n",
186 "print(N(pi), N(e))\n",
187 "e = 42\n",
188 "print(e)\n",
189 "reset('e')\n",
190 "print(N(e))"
191 ]
192 },
193 {
194 "cell_type": "markdown",
195 "metadata": {},
196 "source": [
197 "We will study symbolic expressions more in detail next time, in the context of calculus/analysis."
198 ]
199 },
200 {
201 "cell_type": "markdown",
202 "metadata": {},
203 "source": [
204 "# Basic rings and fields\n",
205 "\n",
206 "**References:** [[3](https://doc.sagemath.org/html/en/reference/rings_standard/index.html)]\n",
207 "[[4](https://doc.sagemath.org/html/en/reference/rings_numerical/index.html)]\n",
208 "[[5](https://doc.sagemath.org/html/en/reference/finite_rings/index.html)]\n",
209 "\n",
210 "As you should know, a *field* is a Mathematical structure with two operations, addition and multiplication, which respect certain rules (distributivity, associativity, commutativity...). Some examples of fields are the Rational numbers $\\mathbb Q$, the Real numbers $\\mathbb R$ and the Complex numbers $\\mathbb C$, but there are many more. As you should also know, a *(commutative) ring* is like a field, except not all elements different from $0$ need have a multiplicative inverse. For example the integers $\\mathbb Z = \\{ \\dots, -1, 0, 1, 2, \\dots\\}$ are a ring, but not a field.\n",
211 "\n",
212 "These structures are already implemented in Sage. Some of the most common are listed in the following table:\n",
213 "\n",
214 "|Mathematical object|Math symbol|Sage name|\n",
215 "|------------------:|:---------:|:--------|\n",
216 "|Integers|$\\mathbb Z$|`ZZ`|\n",
217 "|Rational numbers|$\\mathbb Q$|`QQ`|\n",
218 "|Real numbers|$\\mathbb R$|`RR`|\n",
219 "|Complex numbers|$\\mathbb C$|`CC`|\n",
220 "|Integers modulo $n$|$\\mathbb Z/n\\mathbb Z$|`Integers(n)`|\n",
221 "|Finite fields|$\\mathbb F_p$|GF(p)|\n",
222 "|$\\dots$|$\\dots$|$\\dots$|"
223 ]
224 },
225 {
226 "cell_type": "markdown",
227 "metadata": {},
228 "source": [
229 "If you write a number or an expression, Sage will figure out where it \"lives\", choosing the most restrictive interpretation possible. For example `3` will be interpreted to be an integer, even if it is also a rational number, a real number and a complex number."
230 ]
231 },
232 {
233 "cell_type": "markdown",
234 "metadata": {},
235 "source": [
236 "## Parents and coercion\n",
237 "**Reference:** [[6](https://doc.sagemath.org/html/en/tutorial/tour_coercion.html)]\n",
238 "\n",
239 "You can check where an object \"lives\" with the `parent()` command. It works more or less like the Python command `type()`, but it gives a more Mathematically inclined answer. Check the reference link [6] above if you want more details."
240 ]
241 },
242 {
243 "cell_type": "code",
244 "execution_count": null,
245 "metadata": {},
246 "outputs": [],
247 "source": [
248 "#Edit this cell to find out the type of other objects that we used\n",
249 "print(parent(3/5))\n",
250 "print(QQ)\n",
251 "print(type(3/5))"
252 ]
253 },
254 {
255 "cell_type": "markdown",
256 "metadata": {},
257 "source": [
258 "Sometimes Sage does not give you the best possible interpretation, so you can force something to be interpreted as living in a smaller ring as follows:"
259 ]
260 },
261 {
262 "cell_type": "code",
263 "execution_count": null,
264 "metadata": {},
265 "outputs": [],
266 "source": [
267 "minus_one = e^(pi*I)\n",
268 "print(minus_one)\n",
269 "minus_one_coerced = ZZ(e^(pi*I)) # coercion\n",
270 "#print(ZZ(1/2))\n",
271 "print(parent(minus_one))\n",
272 "print(parent(x^2))\n",
273 "print(parent(minus_one_coerced))\n",
274 "print(parent(5.2))\n",
275 "print(parent(QQ(5.2)))"
276 ]
277 },
278 {
279 "cell_type": "markdown",
280 "metadata": {},
281 "source": [
282 "**Remark.** Notice that there is a fundamental difference between the rings `RR` and `CC` and all the others in the table above: the real and complex numbers are *approximated*."
283 ]
284 },
285 {
286 "cell_type": "code",
287 "execution_count": null,
288 "metadata": {},
289 "outputs": [],
290 "source": [
291 "print(QQ(3))\n",
292 "print(RR(3))"
293 ]
294 },
295 {
296 "cell_type": "markdown",
297 "metadata": {},
298 "source": [
299 "You can also choose the precision of this approximation using the alternative name `RealField`."
300 ]
301 },
302 {
303 "cell_type": "code",
304 "execution_count": null,
305 "metadata": {},
306 "outputs": [],
307 "source": [
308 "print(RR)\n",
309 "print(RealField(prec=1000))"
310 ]
311 },
312 {
313 "cell_type": "markdown",
314 "metadata": {},
315 "source": [
316 "# Polynomial rings\n",
317 "\n",
318 "**Reference:** [[7](https://doc.sagemath.org/html/en/reference/polynomial_rings/index.html)]\n",
319 "\n",
320 "If you want to work with polynomials over a certain ring it is better to use this specific construction, rather than the symbolic expressions introduced above."
321 ]
322 },
323 {
324 "cell_type": "code",
325 "execution_count": 55,
326 "metadata": {},
327 "outputs": [
328 {
329 "name": "stdout",
330 "output_type": "stream",
331 "text": [
332 "Univariate Polynomial Ring in x over Rational Field\n",
333 "[]\n",
334 "[(-2, 2)]\n"
335 ]
336 }
337 ],
338 "source": [
339 "polring.<x> = QQ[] # Alternative: polring.<x,y,z> = PolynomialRing(RR)\n",
340 "polring\n",
341 "print(parent(x))\n",
342 "g = x^3 + 3*x^2-1\n",
343 "print(g.roots())\n",
344 "print((x^2+4*x+4).roots())"
345 ]
346 },
347 {
348 "cell_type": "markdown",
349 "metadata": {},
350 "source": [
351 "You can use as many variables as you like, and you can replace `RR` with any ring. In the example above `polring` is just the name of the variable (in the computer science sense) associated with this polynomial ring.\n",
352 "\n",
353 "## Operations on polynomials\n",
354 "\n",
355 "The usual Mathematical operations are available on polynomial rings, including Euclidean division `//` and remainder `%`. There is also the single-slash division `/`, but the result may not be a polynomial anymore.\n",
356 "\n",
357 "**Exercise:** use the `parent()` command to find out what the quotient of two polynomials is.\n",
358 "\n",
359 "**Question:** what happens if you remove the first line in the cell below? What if we used the variable `y` instead of `x`?"
360 ]
361 },
362 {
363 "cell_type": "code",
364 "execution_count": 60,
365 "metadata": {},
366 "outputs": [
367 {
368 "name": "stdout",
369 "output_type": "stream",
370 "text": [
371 "x + 1\n",
372 "-4\n",
373 "(x^2 + 2*x - 3)/(x + 1)\n",
374 "Fraction Field of Univariate Polynomial Ring in x over Rational Field\n"
375 ]
376 },
377 {
378 "data": {
379 "text/plain": [
380 "x^4 + 2*x^3 - 4*x^2 - 2*x + 3"
381 ]
382 },
383 "execution_count": 60,
384 "metadata": {},
385 "output_type": "execute_result"
386 }
387 ],
388 "source": [
389 "polring.<x> = QQ[]\n",
390 "p = x^2 + 2*x - 3 # Don't forget * for multiplication!\n",
391 "q = p // (x+1)\n",
392 "r = p % (x+1)\n",
393 "f = p / (x+1)\n",
394 "print(q)\n",
395 "print(r)\n",
396 "print(f)\n",
397 "print(parent(f))\n",
398 "p*(x^2-1)"
399 ]
400 },
401 {
402 "cell_type": "markdown",
403 "metadata": {},
404 "source": [
405 "You can do more complex operations. Try out `roots()` and `factor` in the cell below.\n",
406 "\n",
407 "**Remark.** Notice how the result can change substantially if you change the base ring.\n",
408 "\n",
409 "**Remark.** [Factorizations](https://doc.sagemath.org/html/en/reference/structure/sage/structure/factorization.html) are a particular object in Sage. They are kinda like a list, but not really. You can get a list of pairs (factor, power) with `list(factor(f))`."
410 ]
411 },
412 {
413 "cell_type": "code",
414 "execution_count": 76,
415 "metadata": {
416 "scrolled": true
417 },
418 "outputs": [
419 {
420 "name": "stdout",
421 "output_type": "stream",
422 "text": [
423 "(t + 1) * (t^2 - 3) * (t^2 + 1)\n",
424 "[(t + 1, 1), (t^2 - 3, 1), (t^2 + 1, 1)]\n",
425 "t^5 + t^4 - 2*t^3 - 2*t^2 - 3*t - 3\n",
426 "t^2 - 1\n",
427 "[(-1, 1)]\n",
428 "Multivariate Polynomial Ring in x, y, z over Rational Field\n"
429 ]
430 },
431 {
432 "data": {
433 "text/plain": [
434 "Multivariate Polynomial Ring in x, y, z over Rational Field"
435 ]
436 },
437 "execution_count": 76,
438 "metadata": {},
439 "output_type": "execute_result"
440 }
441 ],
442 "source": [
443 "polring_onevar.<t> = QQ[]\n",
444 "\n",
445 "f = t^5 + t^4 - 2*t^3 - 2*t^2 - 3*t - 3\n",
446 "fact = factor(f)\n",
447 "print(factor(f))\n",
448 "print(list(fact))\n",
449 "print((t + 1) * (t^2 - 3) * (t^2 + 1))\n",
450 "print((t+1)*(t-1))\n",
451 "print(f.roots()) # Result: list of pairs (root,multiplicity)\n",
452 "\n",
453 "polring_manyvar.<x,y,z> = QQ[]\n",
454 "factor(x*y+x)\n",
455 "\n",
456 "# The following line gives an error, because the polynomial\n",
457 "# is understood to possibly have many variables:\n",
458 "print(parent(x))\n",
459 "(QQ['x'](x^2-1)).roots()\n",
460 "parent(x)"
461 ]
462 },
463 {
464 "cell_type": "markdown",
465 "metadata": {},
466 "source": [
467 "# Matrices and vectors\n",
468 "\n",
469 "**References:** [[8](https://doc.sagemath.org/html/en/reference/matrices/index.html)], but in particular the subections [[9](https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/docs.html)] and [[10](https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/matrix2.html)]\n",
470 "\n",
471 "In Sage you can easily manipulate matrices and vectors"
472 ]
473 },
474 {
475 "cell_type": "code",
476 "execution_count": 94,
477 "metadata": {},
478 "outputs": [
479 {
480 "name": "stdout",
481 "output_type": "stream",
482 "text": [
483 "[ 1 2 3]\n",
484 "[ 0 0 1]\n",
485 "[ 4 -3 22/7] \n",
486 "\n",
487 "[1/2 0 0]\n",
488 "[ 7 0 0]\n",
489 "[ 1 1 1] \n",
490 "\n",
491 "[1 0]\n",
492 "[0 1] \n",
493 "\n",
494 "(3/2, 21, 6) \n",
495 "\n",
496 "[ -7/2 -10 80/7]\n",
497 "[ 17 -4 15/7]\n",
498 "[ 241/7 -18/7 869/49] \n",
499 "\n",
500 "Rank of A = 3\n",
501 "Rank of B = 2\n"
502 ]
503 },
504 {
505 "data": {
506 "text/plain": [
507 "11"
508 ]
509 },
510 "execution_count": 94,
511 "metadata": {},
512 "output_type": "execute_result"
513 }
514 ],
515 "source": [
516 "A = matrix([[1,2,3],[0,0,1],[4,-3,22/7]])\n",
517 "B = matrix([[1/2,0,0],[7,0,0],[1,1,1]])\n",
518 "C = matrix([[1,0],[0,1]])\n",
519 "v = vector([3,4,-1])\n",
520 "\n",
521 "print(A, \"\\n\") # \\n just means \"newline\"\n",
522 "print(B, \"\\n\")\n",
523 "print(C, \"\\n\")\n",
524 "#print(A*C) Error!\n",
525 "print(B*v, \"\\n\")\n",
526 "print(A^2 + 2*B - A*B, \"\\n\")\n",
527 "\n",
528 "print(\"Rank of A =\", rank(A)) # You can also use A.rank()\n",
529 "print(\"Rank of B =\", rank(B))\n",
530 "A.determinant()"
531 ]
532 },
533 {
534 "cell_type": "markdown",
535 "metadata": {},
536 "source": [
537 "**Exercise:** in the cell above, compute the determinant, inverse and characteristic polynomial of the matrix `A`. *Hint: look at the reference [10] above (the functions are listed in alphabetic order).*\n",
538 "\n",
539 "As for polynomials, you can specify where a matrix or a vector lives"
540 ]
541 },
542 {
543 "cell_type": "code",
544 "execution_count": 97,
545 "metadata": {},
546 "outputs": [
547 {
548 "data": {
549 "text/plain": [
550 "Full MatrixSpace of 2 by 2 dense matrices over Complex Field with 53 bits of precision"
551 ]
552 },
553 "execution_count": 97,
554 "metadata": {},
555 "output_type": "execute_result"
556 }
557 ],
558 "source": [
559 "M = matrix(CC, [[0,1/2],[1,0]])\n",
560 "parent(M)"
561 ]
562 },
563 {
564 "cell_type": "markdown",
565 "metadata": {},
566 "source": [
567 "You can also solve linear systems and compute eigenvalues and eigenvectors of a matrix\n",
568 "\n",
569 "**Warning.** In linear algebra there are distinct concepts of *left* and *right* eigenvalues (and eigenvector). The one you know is probably that of **right** eigen-{value,vector}, that is an element $\\lambda$ of the base field and a non-zero vector $\\mathbf v$ with $A\\mathbf v=\\lambda\\mathbf v$. The other concept corresponds to the equality $\\mathbf v^TA=\\lambda \\mathbf v$."
570 ]
571 },
572 {
573 "cell_type": "code",
574 "execution_count": null,
575 "metadata": {},
576 "outputs": [],
577 "source": [
578 "A = Matrix(RR, [[sqrt(59),32],[-1/4,3]])\n",
579 "v = vector(RR, [3,0])\n",
580 "A.solve_right(v) # Solve Ax=v. Alternative: A \\ v"
581 ]
582 },
583 {
584 "cell_type": "code",
585 "execution_count": 103,
586 "metadata": {},
587 "outputs": [
588 {
589 "name": "stderr",
590 "output_type": "stream",
591 "text": [
592 "<ipython-input-103-d1ccc4990851>:2: UserWarning: Using generic algorithm for an inexact ring, which will probably give incorrect results due to numerical precision issues.\n",
593 " A.eigenvalues() # Also: A.eigenvalues(), A.eigenvectors_right()\n"
594 ]
595 },
596 {
597 "data": {
598 "text/plain": [
599 "[5.37228132326901, -0.372281323269014]"
600 ]
601 },
602 "execution_count": 103,
603 "metadata": {},
604 "output_type": "execute_result"
605 }
606 ],
607 "source": [
608 "A = Matrix(RR, [[1,2],[3,4]])\n",
609 "A.eigenvalues() # Also: A.eigenvalues(), A.eigenvectors_right()"
610 ]
611 },
612 {
613 "cell_type": "markdown",
614 "metadata": {},
615 "source": [
616 "We can also extract a specific submatrix by selecting only some rows and columns, with a syntax similar to that of Python's lists. Check out more examples in the reference [9] above, and try them in the cell below."
617 ]
618 },
619 {
620 "cell_type": "code",
621 "execution_count": 105,
622 "metadata": {},
623 "outputs": [
624 {
625 "name": "stdout",
626 "output_type": "stream",
627 "text": [
628 "[ -3 -25 -5 -3 61 0 -1]\n",
629 "[ 23 0 -1 1 0 1 -1]\n",
630 "[286 2 7 0 -21 -1 0]\n",
631 "[ 2 -1 -2 0 -1 4 0]\n",
632 "[ 1 -1 1 0 2 -2 7]\n",
633 "[ 0 15 -1 0 -3 1 -1]\n",
634 "[ -1 1 -2 0 2 1 1] \n",
635 "\n",
636 "[ -1 1 0]\n",
637 "[ 7 0 -21] \n",
638 "\n",
639 "[ -3 -25 -5 -3 61 0 -1] \n",
640 "\n",
641 "[ -3 -25 -5 -3 61]\n",
642 "[ 0 15 -1 0 -3]\n",
643 "[286 2 7 0 -21]\n",
644 "-25\n"
645 ]
646 }
647 ],
648 "source": [
649 "A = MatrixSpace(ZZ, 7).random_element()\n",
650 "print(A, \"\\n\")\n",
651 "print(A[1:3,2:5], \"\\n\") # Rows from 1 to 3, columns from 2 to 5\n",
652 "print(A[0,0:], \"\\n\") # First row, all columns\n",
653 "print(A[[0,5,2],0:5]) # Rows 0, 5 and 2 (in this order) and columns 0 to 5\n",
654 "print(A[0,1])"
655 ]
656 },
657 {
658 "cell_type": "markdown",
659 "metadata": {},
660 "source": [
661 "**Exercise:** write a sage function that computes the determinant of an $n\\times n$ matrix $A=(a_{ij})$ using Laplace's rule by the first row, that is \n",
662 "\\begin{align*}\n",
663 " \\operatorname{det}A = \\sum_{j=1}^n (-1)^ja_{0j}M_{0j}\n",
664 "\\end{align*}\n",
665 "where $M_{0j}$ is the determinant of the $(n-1)\\times(n-1)$ matrix obtained by removing the $0$-th row and the $j$-th column from $A$."
666 ]
667 },
668 {
669 "cell_type": "code",
670 "execution_count": 6,
671 "metadata": {},
672 "outputs": [
673 {
674 "name": "stdout",
675 "output_type": "stream",
676 "text": [
677 "[ -1 -3 -1 11 2 -1 -5]\n",
678 "[ 1 0 0 -6 -1 0 1]\n",
679 "[ 1 0 -1 0 1 -1 0]\n",
680 "[-24 1 -2 -7 4 0 1]\n",
681 "[ -3 0 -1 0 6 -1 0]\n",
682 "[-17 -1 1 0 28 1 0]\n",
683 "[ 1 -4 1 1 -2 -6 -2]\n",
684 "Sage determinant: 13578\n",
685 "my_det: 13578\n"
686 ]
687 }
688 ],
689 "source": [
690 "def my_det(A):\n",
691 " if not A.is_square():\n",
692 " print(\"Error: matrix is not square\")\n",
693 " \n",
694 " n = A.nrows() # size of the matrix\n",
695 " \n",
696 " if n == 1:\n",
697 " return A[0,0]\n",
698 " \n",
699 " my_sum = 0\n",
700 " for j in range(0,n):\n",
701 " rows = range(1,n)\n",
702 " columns = [element for element in range(0,n) if element != j]\n",
703 " submatrix = A[rows,columns]\n",
704 " my_sum += (-1)^j * A[0,j] * my_det(submatrix)\n",
705 " \n",
706 " return my_sum\n",
707 "\n",
708 "A = MatrixSpace(ZZ, 7).random_element()\n",
709 "print(A)\n",
710 "print(\"Sage determinant: \", A.determinant())\n",
711 "print(\"my_det: \", my_det(A))"
712 ]
713 },
714 {
715 "cell_type": "markdown",
716 "metadata": {},
717 "source": [
718 "# Number Theory\n",
719 "\n",
720 "**Reference:** [[11](https://doc.sagemath.org/html/en/reference/rings_standard/sage/rings/integer.html)]\n",
721 "\n",
722 "Sage includes a large library of functions for computing with the integers, see the link above."
723 ]
724 },
725 {
726 "cell_type": "code",
727 "execution_count": 8,
728 "metadata": {},
729 "outputs": [
730 {
731 "name": "stdout",
732 "output_type": "stream",
733 "text": [
734 "3^2 * 3607 * 3803\n",
735 "[(3, 2), (3607, 1), (3803, 1)]\n",
736 "True\n",
737 "True\n",
738 "619703040\n",
739 "9\n",
740 "13548070123626141\n"
741 ]
742 }
743 ],
744 "source": [
745 "n = 123456789\n",
746 "m = 987654321\n",
747 "p = 3607\n",
748 "\n",
749 "print(factor(n))\n",
750 "print(list(factor(n)))\n",
751 "print(is_prime(p))\n",
752 "print(p.divides(n))\n",
753 "print(euler_phi(m))\n",
754 "print(gcd(n, m))\n",
755 "print(lcm(n, m))"
756 ]
757 },
758 {
759 "cell_type": "markdown",
760 "metadata": {},
761 "source": [
762 "## Primes\n",
763 "\n",
764 "**Reference:** [[12](https://doc.sagemath.org/html/en/reference/sets/sage/sets/primes.html)]\n",
765 "\n",
766 "The set of prime numbers is called `Primes()`. It is like an infinite list: for example you can get the one-millionth prime number or you can use this list to create other lists. You can also check what the first prime number larger than a given number is."
767 ]
768 },
769 {
770 "cell_type": "code",
771 "execution_count": null,
772 "metadata": {},
773 "outputs": [
774 {
775 "name": "stdout",
776 "output_type": "stream",
777 "text": [
778 "Set of all prime numbers: 2, 3, 5, 7, ...\n",
779 "31 252097800629\n",
780 "47\n",
781 "[79, 83, 89, 97]\n"
782 ]
783 }
784 ],
785 "source": [
786 "PP = Primes()\n",
787 "print(PP)\n",
788 "print(PP[10], PP[10^10])\n",
789 "print(PP.next(44))\n",
790 "\n",
791 "First_Thousand_Primes = PP[0:1000]\n",
792 "print([p for p in First_Thousand_Primes if p < 100 and p > 75])\n",
793 "#print([p for p in PP if p < 100 and p > 75])"
794 ]
795 },
796 {
797 "cell_type": "markdown",
798 "metadata": {},
799 "source": [
800 "## The Chinese remainder theorem (CRT)\n",
801 "\n",
802 "We say that two integers $a$ and $b$ are *congruent* modulo another integer $n>0$ if they have the same remainder when divided by $n$. We denote this by $a\\equiv b\\pmod n$, or in Python/Sage syntax `a % n == b % n`.\n",
803 "\n",
804 "The Chinese remainder theorem states that if $a,b\\in\\mathbb Z$ and $n,m\\in \\mathbb Z_{>0}$ are such that $\\gcd(n,m)=1$ then the system of congruences\n",
805 "\n",
806 "\\begin{align*}\n",
807 "\\begin{cases}\n",
808 " x \\equiv a \\pmod n\\\\\n",
809 " x \\equiv b \\pmod m\n",
810 "\\end{cases}\n",
811 "\\end{align*}\n",
812 "\n",
813 "\n",
814 "has exactly one solution modulo $mn$. This means that there is one and only one number $x$ with $0\\leq x<mn$ such that $x\\equiv a\\pmod n$ and $x\\equiv b\\pmod m$.\n",
815 "\n",
816 "\n",
817 "For example:\n",
818 "\n",
819 "\\begin{align*}\n",
820 "\\begin{cases}\n",
821 " x \\equiv 1 \\pmod 3\\\\\n",
822 " x \\equiv 2 \\pmod 5\n",
823 "\\end{cases}\n",
824 "\\end{align*}\n",
825 "\n",
826 "Solution: $x=7$ (any other solution is congruent to $7$ modulo $15$; for example $22=15+7$ is also a solution).\n",
827 "\n",
828 "The procedure to find such a number is not too hard to describe (you might see it in an algebra or number theory course), but it can be a bit long. Luckily, Sage can do this for you:"
829 ]
830 },
831 {
832 "cell_type": "code",
833 "execution_count": 1,
834 "metadata": {},
835 "outputs": [
836 {
837 "name": "stdout",
838 "output_type": "stream",
839 "text": [
840 "74306 2 798\n"
841 ]
842 }
843 ],
844 "source": [
845 "a = 2\n",
846 "b = -1\n",
847 "n = 172\n",
848 "m = 799\n",
849 "\n",
850 "if gcd(n,m) != 1:\n",
851 " print(\"The numbers are not comprime, I can't solve this!\")\n",
852 "else:\n",
853 " x = crt(a, b, n, m)\n",
854 " print(x, x%n, x%m)"
855 ]
856 },
857 {
858 "cell_type": "markdown",
859 "metadata": {},
860 "source": [
861 "**Exercise.** There is a more general version of the Chinese remainder theorem which says that if $a_0, a_1, \\dots, a_k\\in\\mathbb Z$ and $n_0, n_2, \\dots, n_k\\in\\mathbb Z_{>0}$ are such that $\\gcd(n_i, n_j)=1$ for $i\\neq j$, then the system of congruences\n",
862 "\n",
863 "\\begin{align*}\n",
864 "\\begin{cases}\n",
865 " x \\equiv a_0 \\pmod {n_0}\\\\\n",
866 " x \\equiv a_1 \\pmod {n_1}\\\\\n",
867 " \\dots \\\\\n",
868 " x \\equiv a_k \\pmod {n_k}\n",
869 "\\end{cases}\n",
870 "\\end{align*}\n",
871 "\n",
872 "has exactly one solution modulo $\\prod_{i=0}^kn_i$. Use the `crt()` function to find a solution to such a system.\n",
873 "*Hint: start by running the command `help(crt)`."
874 ]
875 },
876 {
877 "cell_type": "code",
878 "execution_count": 3,
879 "metadata": {},
880 "outputs": [],
881 "source": [
882 "#help(crt)"
883 ]
884 },
885 {
886 "cell_type": "markdown",
887 "metadata": {},
888 "source": [
889 "# Cryptography: RSA\n",
890 "\n",
891 "[Cryptography](https://en.wikipedia.org/wiki/Cryptography) is the discipline that studies methods to communicate secrets in such a way that any unauthorized listener would not be able to understand the message.\n",
892 "\n",
893 "A simple cryptographic protocol could be changing every letter of your text following a fixed scheme (or *cypher*), for example by turning every A into a B, every B into a C and so on. However this is not a very secure method, for many reasons. One of them is that at some point the people who want to communicate need to agree on what method to use, and anyone listening to that conversation would be able to decypher every subsequent conversation. A public-key cryptographic protocol solves this problem.\n",
894 "\n",
895 "## Public-key cryptography\n",
896 "\n",
897 "Public-key cryptographic protocols, such as RSA, work like this: there are two keys, a *private* key that is only known to person A (traditionally called Alice in every example), and a *public* key that does not need to be secret.\n",
898 "\n",
899 "The public key is used to *encrypt* the message (that is to \"lock\" it, or \"hyde\" it), but one needs the private key to *decrypt* it. Imagine having two keys for your door, but one can only be used to lock it, while the other only to open it.\n",
900 "\n",
901 "The message exchange works like this: suppose that person B (Bob) wants to send a secret message to Alice. Then Alice secretely generates a private and a public key and sends only the public one to Bob. Now Bob encrypts the message and sends it to Alice, who can use her private key to decrypt it. Even if Eve (short for *eavesdropper*, an unauthorized listener) listens to every message exchanged, she won't be able to decypher the secret: the private key has never left Alice's house!\n",
902 "\n",
903 "Notice that such a protocol is *asymmetric*: if Alice wanted to send a secret to Bob in reply, Bob would need to generate a pair of keys of his own.\n",
904 "\n",
905 "Let's see how we can do this in practice, using number theory!\n",
906 "\n",
907 "## RSA\n",
908 "\n",
909 "As many other cryptography protocols, RSA is based on a Mathematical process that is easy to do in one direction, but very hard to invert. In this case the hard process is integer factorization, that is decomposing an integer number as a product of primes."
910 ]
911 },
912 {
913 "cell_type": "code",
914 "execution_count": 5,
915 "metadata": {},
916 "outputs": [
917 {
918 "name": "stdout",
919 "output_type": "stream",
920 "text": [
921 "True True False\n"
922 ]
923 },
924 {
925 "data": {
926 "text/plain": [
927 "1 loop, best of 1: 9.06 s per loop"
928 ]
929 },
930 "execution_count": 5,
931 "metadata": {},
932 "output_type": "execute_result"
933 }
934 ],
935 "source": [
936 "p = 100003100019100043100057100069\n",
937 "q = 100144655312449572059845328443\n",
938 "n = p*q\n",
939 "print(is_prime(p), is_prime(q), is_prime(p*q))\n",
940 "\n",
941 "# Use the command below to see how long it takes\n",
942 "timeit(\"factor(n)\", number=1, repeat=1)"
943 ]
944 },
945 {
946 "cell_type": "markdown",
947 "metadata": {},
948 "source": [
949 "In order to generate the keys, Alice picks a number $n$ which is the product of two large primes $p$ and $q$ of more or less the same size. Finding such primes is relatively easy compared to factoring the number $n$ she obtained. Then she computes the Euler totient $\\varphi(n)=(p-1)(q-1)$ of $n$, which she can do because she knows that $n=pq$ - it would be impossible otherwise!\n",
950 "\n",
951 "Then Alice can compute two integers $(d,e)$ such that $de\\equiv 1\\pmod{\\varphi(n)}$. She will send the numbers $n$ and $d$ to Bob and keep $e$ secret. In this case the public key is the pair $(n,d)$, while $e$ is the private key.\n",
952 "\n",
953 "Of course, she does all of this using Sage!"
954 ]
955 },
956 {
957 "cell_type": "code",
958 "execution_count": 6,
959 "metadata": {},
960 "outputs": [
961 {
962 "data": {
963 "text/plain": [
964 "(338547806707501, 141995674537431, 107165393087271)"
965 ]
966 },
967 "execution_count": 6,
968 "metadata": {},
969 "output_type": "execute_result"
970 }
971 ],
972 "source": [
973 "def two_large_primes():\n",
974 " p, q = 0, 0\n",
975 " # We make sure that they are different\n",
976 " while p == q:\n",
977 " p = Primes()[randint(10^6, 2*10^6)]\n",
978 " q = Primes()[randint(10^6, 2*10^6)]\n",
979 " return p, q\n",
980 "\n",
981 "def random_unit_mod(N):\n",
982 " R = Integers(N)\n",
983 " d = R(0)\n",
984 " # We make sure that it is invertible\n",
985 " while not d.is_unit():\n",
986 " d = R.random_element()\n",
987 " return d\n",
988 "\n",
989 "def Alice_generate_keys():\n",
990 " p, q = two_large_primes()\n",
991 " n = p*q\n",
992 " phi_n = (p-1)*(q-1) # euler_phi(n) is slow!\n",
993 " \n",
994 " d = random_unit_mod(phi_n)\n",
995 " e = d^-1\n",
996 " return n, d, e\n",
997 "\n",
998 "Alice_generate_keys()"
999 ]
1000 },
1001 {
1002 "cell_type": "markdown",
1003 "metadata": {},
1004 "source": [
1005 "Now, how does Bob encrypt his message? Let's say he wants to send to Alice the number $m$ with $1<m<n$ (In practice he would like to send her some text with emojis, or maybe a voice message; but for computers everything is a number, and there are different ways to translate any sort of information to a number. He just chooses one of the many standard methods that already exist, no cryptography is needed in this step. If the message $m$ is too long, he can split it up in some pieces and repeat the process multiple times.)\n",
1006 "\n",
1007 "Now he computes $m^d\\pmod n$ and sends it back to Alice."
1008 ]
1009 },
1010 {
1011 "cell_type": "code",
1012 "execution_count": 7,
1013 "metadata": {},
1014 "outputs": [
1015 {
1016 "data": {
1017 "text/plain": [
1018 "177776139844621"
1019 ]
1020 },
1021 "execution_count": 7,
1022 "metadata": {},
1023 "output_type": "execute_result"
1024 }
1025 ],
1026 "source": [
1027 "def Bob_encrypt(m, n, d):\n",
1028 " R = Integers(n)\n",
1029 " return R(m)^d # Assume that n is large enough\n",
1030 " \n",
1031 "message = 42424242\n",
1032 "Bob_encrypt(message, 338547806707501, 141995674537431)"
1033 ]
1034 },
1035 {
1036 "cell_type": "markdown",
1037 "metadata": {},
1038 "source": [
1039 "Since $de\\equiv 1\\pmod{\\varphi(n)}$, it follows that $(m^d)^e\\equiv m\\pmod n$ (see [Wikipedia: Euler's theorem](https://en.wikipedia.org/wiki/Euler%27s_theorem)). So for Alice it is very easy to get back the original message:"
1040 ]
1041 },
1042 {
1043 "cell_type": "code",
1044 "execution_count": 8,
1045 "metadata": {},
1046 "outputs": [
1047 {
1048 "data": {
1049 "text/plain": [
1050 "42424242"
1051 ]
1052 },
1053 "execution_count": 8,
1054 "metadata": {},
1055 "output_type": "execute_result"
1056 }
1057 ],
1058 "source": [
1059 "def Alice_decrypt(m_encrypted, n, e):\n",
1060 " R = Integers(n)\n",
1061 " return R(m_encrypted)^e\n",
1062 "\n",
1063 "Alice_decrypt(177776139844621, 338547806707501, 107165393087271)"
1064 ]
1065 },
1066 {
1067 "cell_type": "markdown",
1068 "metadata": {},
1069 "source": [
1070 "Another assumption on which RSA relies is that even if one knows $M=m^e$ and $e$, extracting the $e$-th root of $M$ modulo $n$ (and thus obtaining $m$) is very hard. Currently the best known way to do this is by factorizing $n$ first, which is considered to be a very hard problem. However, there is no proof that faster algorithms can't be devised.\n",
1071 "\n",
1072 "Moreover, one day we will overcome the current technological difficulties and quantum computers will be available. Quantum computers are not just \"more powerful\" than classical hardware, but they work based on completely different logical foundations and they make the factorization problem much easier to solve: for example [Shor's algorithm](https://en.wikipedia.org/wiki/Shor%27s_algorithm) takes advantage of this different logic and can factorize numbers quickly, if run on a quantum computer.\n",
1073 "\n",
1074 "To this day the largest number factorized with a quantum computer is $21=3\\times 7$. Nonetheless, quantum-safe cryptography protocols (i.e. based on problems that are hard to solve also with quantum computers) have already been developed."
1075 ]
1076 }
1077 ],
1078 "metadata": {
1079 "kernelspec": {
1080 "display_name": "SageMath 9.2",
1081 "language": "sage",
1082 "name": "sagemath"
1083 },
1084 "language_info": {
1085 "codemirror_mode": {
1086 "name": "ipython",
1087 "version": 3
1088 },
1089 "file_extension": ".py",
1090 "mimetype": "text/x-python",
1091 "name": "python",
1092 "nbconvert_exporter": "python",
1093 "pygments_lexer": "ipython3",
1094 "version": "3.8.5"
1095 }
1096 },
1097 "nbformat": 4,
1098 "nbformat_minor": 4
1099}
diff --git a/src/Lecture5/notebook/.ipynb_checkpoints/scratchpad-checkpoint.ipynb b/src/Lecture5/notebook/.ipynb_checkpoints/scratchpad-checkpoint.ipynb
new file mode 100644
index 0000000..5232819
--- /dev/null
+++ b/src/Lecture5/notebook/.ipynb_checkpoints/scratchpad-checkpoint.ipynb
@@ -0,0 +1,52 @@
1{
2 "cells": [
3 {
4 "cell_type": "code",
5 "execution_count": 1,
6 "metadata": {},
7 "outputs": [
8 {
9 "data": {
10 "text/plain": [
11 "9"
12 ]
13 },
14 "execution_count": 1,
15 "metadata": {},
16 "output_type": "execute_result"
17 }
18 ],
19 "source": [
20 "gcd(36,27)"
21 ]
22 },
23 {
24 "cell_type": "code",
25 "execution_count": null,
26 "metadata": {},
27 "outputs": [],
28 "source": []
29 }
30 ],
31 "metadata": {
32 "kernelspec": {
33 "display_name": "SageMath 9.2",
34 "language": "sage",
35 "name": "sagemath"
36 },
37 "language_info": {
38 "codemirror_mode": {
39 "name": "ipython",
40 "version": 3
41 },
42 "file_extension": ".py",
43 "mimetype": "text/x-python",
44 "name": "python",
45 "nbconvert_exporter": "python",
46 "pygments_lexer": "ipython3",
47 "version": "3.8.5"
48 }
49 },
50 "nbformat": 4,
51 "nbformat_minor": 4
52}
diff --git a/src/Lecture5/notebook/7-SageAlgebra.aux b/src/Lecture5/notebook/7-SageAlgebra.aux
new file mode 100644
index 0000000..a3f33b6
--- /dev/null
+++ b/src/Lecture5/notebook/7-SageAlgebra.aux
@@ -0,0 +1,56 @@
1\relax
2\providecommand\hyper@newdestlabel[2]{}
3\providecommand\HyperFirstAtBeginDocument{\AtBeginDocument}
4\HyperFirstAtBeginDocument{\ifx\hyper@anchor\@undefined
5\global\let\oldcontentsline\contentsline
6\gdef\contentsline#1#2#3#4{\oldcontentsline{#1}{#2}{#3}}
7\global\let\oldnewlabel\newlabel
8\gdef\newlabel#1#2{\newlabelxx{#1}#2}
9\gdef\newlabelxx#1#2#3#4#5#6{\oldnewlabel{#1}{{#2}{#3}}}
10\AtEndDocument{\ifx\hyper@anchor\@undefined
11\let\contentsline\oldcontentsline
12\let\newlabel\oldnewlabel
13\fi}
14\fi}
15\global\let\hyper@last\relax
16\gdef\HyperFirstAtBeginDocument#1{#1}
17\providecommand\HyField@AuxAddToFields[1]{}
18\providecommand\HyField@AuxAddToCoFields[2]{}
19\providecommand \oddpage@label [2]{}
20\@writefile{toc}{\contentsline {section}{\numberline {1}The Jupyter Notebook}{1}{section.1}\protected@file@percent }
21\newlabel{the-jupyter-notebook}{{1}{1}{The Jupyter Notebook}{section.1}{}}
22\@writefile{toc}{\contentsline {subsection}{\numberline {1.1}Cells}{1}{subsection.1.1}\protected@file@percent }
23\newlabel{cells}{{1.1}{1}{Cells}{subsection.1.1}{}}
24\@writefile{toc}{\contentsline {subsection}{\numberline {1.2}Markdown}{1}{subsection.1.2}\protected@file@percent }
25\newlabel{markdown}{{1.2}{1}{Markdown}{subsection.1.2}{}}
26\@writefile{toc}{\contentsline {section}{\numberline {2}Symbolic expressions}{2}{section.2}\protected@file@percent }
27\newlabel{symbolic-expressions}{{2}{2}{Symbolic expressions}{section.2}{}}
28\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Mathematical variables}{2}{subsection.2.1}\protected@file@percent }
29\newlabel{mathematical-variables}{{2.1}{2}{Mathematical variables}{subsection.2.1}{}}
30\gdef \LT@i {\LT@entry
31 {1}{103.45363pt}\LT@entry
32 {1}{76.13344pt}\LT@entry
33 {2}{68.2421pt}}
34\@writefile{toc}{\contentsline {section}{\numberline {3}Basic rings and fields}{3}{section.3}\protected@file@percent }
35\newlabel{basic-rings-and-fields}{{3}{3}{Basic rings and fields}{section.3}{}}
36\@writefile{toc}{\contentsline {subsection}{\numberline {3.1}Parents and coercion}{3}{subsection.3.1}\protected@file@percent }
37\newlabel{parents-and-coercion}{{3.1}{3}{Parents and coercion}{subsection.3.1}{}}
38\@writefile{toc}{\contentsline {section}{\numberline {4}Polynomial rings}{4}{section.4}\protected@file@percent }
39\newlabel{polynomial-rings}{{4}{4}{Polynomial rings}{section.4}{}}
40\@writefile{toc}{\contentsline {subsection}{\numberline {4.1}Operations on polynomials}{4}{subsection.4.1}\protected@file@percent }
41\newlabel{operations-on-polynomials}{{4.1}{4}{Operations on polynomials}{subsection.4.1}{}}
42\@writefile{toc}{\contentsline {section}{\numberline {5}Matrices and vectors}{5}{section.5}\protected@file@percent }
43\newlabel{matrices-and-vectors}{{5}{5}{Matrices and vectors}{section.5}{}}
44\@writefile{toc}{\contentsline {section}{\numberline {6}Number Theory}{8}{section.6}\protected@file@percent }
45\newlabel{number-theory}{{6}{8}{Number Theory}{section.6}{}}
46\@writefile{toc}{\contentsline {subsection}{\numberline {6.1}Primes}{8}{subsection.6.1}\protected@file@percent }
47\newlabel{primes}{{6.1}{8}{Primes}{subsection.6.1}{}}
48\@writefile{toc}{\contentsline {subsection}{\numberline {6.2}The Chinese remainder theorem (CRT)}{9}{subsection.6.2}\protected@file@percent }
49\newlabel{the-chinese-remainder-theorem-crt}{{6.2}{9}{The Chinese remainder theorem (CRT)}{subsection.6.2}{}}
50\@writefile{toc}{\contentsline {section}{\numberline {7}Cryptography: RSA}{10}{section.7}\protected@file@percent }
51\newlabel{cryptography-rsa}{{7}{10}{Cryptography: RSA}{section.7}{}}
52\@writefile{toc}{\contentsline {subsection}{\numberline {7.1}Public-key cryptography}{10}{subsection.7.1}\protected@file@percent }
53\newlabel{public-key-cryptography}{{7.1}{10}{Public-key cryptography}{subsection.7.1}{}}
54\@writefile{toc}{\contentsline {subsection}{\numberline {7.2}RSA}{10}{subsection.7.2}\protected@file@percent }
55\newlabel{rsa}{{7.2}{10}{RSA}{subsection.7.2}{}}
56\gdef \@abspage@last{12}
diff --git a/src/Lecture5/notebook/7-SageAlgebra.ipynb b/src/Lecture5/notebook/7-SageAlgebra.ipynb
new file mode 100644
index 0000000..59ea033
--- /dev/null
+++ b/src/Lecture5/notebook/7-SageAlgebra.ipynb
@@ -0,0 +1,1046 @@
1{
2 "cells": [
3 {
4 "cell_type": "markdown",
5 "metadata": {},
6 "source": [
7 "This lecture's notes are in a different format: the presentations for the $\\LaTeX$ part were made with $\\LaTeX$, so this one is made with Sage, or rather with the [Jupyter Notebook](https://jupyter.org/).\n",
8 "\n",
9 "# The Jupyter Notebook\n",
10 "**Reference:** [[1](https://jupyter.org/documentation)]\n",
11 "\n",
12 "The Jupyter Notebook is one of the default interfaces for SageMath, along with the command line interface. You can access it via web browser, but it is running locally on your device (notice the strange url: `http://localhost:8888/notebooks...`).\n",
13 "\n",
14 "You can create a new notebook by clicking on `New > SageMath 9.2`. You can also create a Python 3 notebook to write Python code.\n",
15 "\n",
16 "Jupyter saves and reads files in the `.ipynb` format. If you download the file for this lecture you can open it and follow the examples interactively.\n",
17 "\n",
18 "## Cells\n",
19 "\n",
20 "The notebook contains one or more *interactive cells* that you can run, like this one below:"
21 ]
22 },
23 {
24 "cell_type": "code",
25 "execution_count": 2,
26 "metadata": {},
27 "outputs": [
28 {
29 "data": {
30 "text/plain": [
31 "2/5"
32 ]
33 },
34 "execution_count": 2,
35 "metadata": {},
36 "output_type": "execute_result"
37 }
38 ],
39 "source": [
40 "# Exercise: modify this cell to use the print() command\n",
41 "2+2\n",
42 "2/5"
43 ]
44 },
45 {
46 "cell_type": "markdown",
47 "metadata": {},
48 "source": [
49 "If you are reading this from Jupyter rather than from the pdf file, you can edit the cell above and run it again. You can also add more cells by selecting `Insert` from the menu bar.\n",
50 "\n",
51 "Notice that only the last statement produces an output. You can force anything to be written as output with the `print()` command, which works like in Python. As an exercise, try to modify the cell above to provide more output!"
52 ]
53 },
54 {
55 "cell_type": "markdown",
56 "metadata": {},
57 "source": [
58 "## Markdown\n",
59 "\n",
60 "[Markdown](https://en.wikipedia.org/wiki/Markdown) is a simple markup language - think of LaTeX or html, but much simpler.\n",
61 "You can add text to your notebook with Markdown cells by selecting `Cell > Cell Type > Markdown`.\n",
62 "\n",
63 "You can also include some LaTeX code in Markdown cells, with dollar signs $ or align environments:\n",
64 "\n",
65 "\\begin{align*}\n",
66 "\\frac{(x+y)^2}{x+1} = \\frac{x^2+y^2}{x+1}\n",
67 "\\end{align*}\n",
68 "\n",
69 "When you are done writing a Markdown cell, you can run it to see the well-formatted text. To edit the text again, double-click on the cell. Try doing it now to fix the formula above!"
70 ]
71 },
72 {
73 "cell_type": "markdown",
74 "metadata": {},
75 "source": [
76 "# Symbolic expressions\n",
77 "\n",
78 "**Reference:** [[2](https://doc.sagemath.org/html/en/reference/calculus/sage/symbolic/expression.html)]\n",
79 "\n",
80 "Now, let's get started with Sage. One thing you might want to do is manipulating symbolic expressions, like the following:"
81 ]
82 },
83 {
84 "cell_type": "code",
85 "execution_count": 3,
86 "metadata": {},
87 "outputs": [
88 {
89 "data": {
90 "text/plain": [
91 "[x == -sqrt(6) - 1, x == sqrt(6) - 1]"
92 ]
93 },
94 "execution_count": 3,
95 "metadata": {},
96 "output_type": "execute_result"
97 }
98 ],
99 "source": [
100 "f = x^2 + 2*x - 5 == 0\n",
101 "solve(f,x)"
102 ]
103 },
104 {
105 "cell_type": "markdown",
106 "metadata": {},
107 "source": [
108 "Notice that the single `=` is part of an assignment, as in Python: we are *assigning* to the variable `f` the value `x^2 + 2*x - 5 >= 0`, which in this case is an equation, so it contains the symbol `==`. Keep in mind the difference between the two!\n",
109 "\n",
110 "**Exercise:** change the code above to solve the corresponding inequality $x^2+2x-5\\geq 0$."
111 ]
112 },
113 {
114 "cell_type": "markdown",
115 "metadata": {},
116 "source": [
117 "## Mathematical variables\n",
118 "\n",
119 "Last time we saw what *variables* are in Python, and that they are a little bit different from the *Mathematical variables* that you use in Mathematics. In Sage, both concepts are present, but they are still distinct. For example in the cell above `f` is a variable in the sense of computer science, while `x` is a Mathematical variable.\n",
120 "\n",
121 "If you want to use Mathematical variables other than `x`, you first need to *declare* them with the `var()` command:"
122 ]
123 },
124 {
125 "cell_type": "code",
126 "execution_count": 14,
127 "metadata": {},
128 "outputs": [
129 {
130 "data": {
131 "text/plain": [
132 "[y == -1/2*x - 1/2*sqrt(x^2 + 2*x + 9) - 1/2, y == -1/2*x + 1/2*sqrt(x^2 + 2*x + 9) - 1/2]"
133 ]
134 },
135 "execution_count": 14,
136 "metadata": {},
137 "output_type": "execute_result"
138 }
139 ],
140 "source": [
141 "var('y')\n",
142 "solve(y^2 + (x+1)*y - 2 == 0, y)"
143 ]
144 },
145 {
146 "cell_type": "markdown",
147 "metadata": {},
148 "source": [
149 "Try removing the first line in the cell above and see what error you get!\n",
150 "\n",
151 "Here is another example:"
152 ]
153 },
154 {
155 "cell_type": "code",
156 "execution_count": 16,
157 "metadata": {},
158 "outputs": [
159 {
160 "data": {
161 "text/plain": [
162 "[x == -1/2*a - 1/2*sqrt(a^2 - 4*b), x == -1/2*a + 1/2*sqrt(a^2 - 4*b)]"
163 ]
164 },
165 "execution_count": 16,
166 "metadata": {},
167 "output_type": "execute_result"
168 }
169 ],
170 "source": [
171 "var('a', 'b')\n",
172 "f = x^2+a*x+b\n",
173 "solve(f,x)"
174 ]
175 },
176 {
177 "cell_type": "markdown",
178 "metadata": {},
179 "source": [
180 "Some common constants are [already defined](https://doc.sagemath.org/html/en/reference/calculus/sage/symbolic/expression.html) in Sage:"
181 ]
182 },
183 {
184 "cell_type": "code",
185 "execution_count": 17,
186 "metadata": {},
187 "outputs": [
188 {
189 "data": {
190 "text/plain": [
191 "-1"
192 ]
193 },
194 "execution_count": 17,
195 "metadata": {},
196 "output_type": "execute_result"
197 }
198 ],
199 "source": [
200 "e^(pi*I)"
201 ]
202 },
203 {
204 "cell_type": "markdown",
205 "metadata": {},
206 "source": [
207 "We will study symbolic expressions more in detail next time, in the context of calculus/analysis."
208 ]
209 },
210 {
211 "cell_type": "markdown",
212 "metadata": {},
213 "source": [
214 "# Basic rings and fields\n",
215 "\n",
216 "**References:** [[3](https://doc.sagemath.org/html/en/reference/rings_standard/index.html)]\n",
217 "[[4](https://doc.sagemath.org/html/en/reference/rings_numerical/index.html)]\n",
218 "[[5](https://doc.sagemath.org/html/en/reference/finite_rings/index.html)]\n",
219 "\n",
220 "As you should know, a *field* is a Mathematical structure with two operations, addition and multiplication, which respect certain rules (distributivity, associativity, commutativity...). Some examples of fields are the Rational numbers $\\mathbb Q$, the Real numbers $\\mathbb R$ and the Complex numbers $\\mathbb C$, but there are many more. As you should also know, a *(commutative) ring* is like a field, except not all elements different from $0$ need have a multiplicative inverse. For example the integers $\\mathbb Z = \\{ \\dots, -1, 0, 1, 2, \\dots\\}$ are a ring, but not a field.\n",
221 "\n",
222 "These structures are already implemented in Sage. Some of the most common are listed in the following table:\n",
223 "\n",
224 "|Mathematical object|Math symbol|Sage name|\n",
225 "|------------------:|:---------:|:--------|\n",
226 "|Integers|$\\mathbb Z$|`ZZ`|\n",
227 "|Rational numbers|$\\mathbb Q$|`QQ`|\n",
228 "|Real numbers|$\\mathbb R$|`RR`|\n",
229 "|Complex numbers|$\\mathbb C$|`CC`|\n",
230 "|Integers modulo $n$|$\\mathbb Z/n\\mathbb Z$|`Integers(n)`|\n",
231 "|Finite fields|$\\mathbb F_p$|GF(p)|\n",
232 "|$\\dots$|$\\dots$|$\\dots$|"
233 ]
234 },
235 {
236 "cell_type": "markdown",
237 "metadata": {},
238 "source": [
239 "If you write a number or an expression, Sage will figure out where it \"lives\", choosing the most restrictive interpretation possible. For example `3` will be interpreted to be an integer, even if it is also a rational number, a real number and a complex number."
240 ]
241 },
242 {
243 "cell_type": "markdown",
244 "metadata": {},
245 "source": [
246 "## Parents and coercion\n",
247 "**Reference:** [[6](https://doc.sagemath.org/html/en/tutorial/tour_coercion.html)]\n",
248 "\n",
249 "You can check where an object \"lives\" with the `parent()` command. It works more or less like the Python command `type()`, but it gives a more Mathematically inclined answer. Check the reference link [6] above if you want more details."
250 ]
251 },
252 {
253 "cell_type": "code",
254 "execution_count": 18,
255 "metadata": {},
256 "outputs": [
257 {
258 "data": {
259 "text/plain": [
260 "Rational Field"
261 ]
262 },
263 "execution_count": 18,
264 "metadata": {},
265 "output_type": "execute_result"
266 }
267 ],
268 "source": [
269 "#Edit this cell to find out the type of other objects that we used\n",
270 "parent(3/5)"
271 ]
272 },
273 {
274 "cell_type": "markdown",
275 "metadata": {},
276 "source": [
277 "Sometimes Sage does not give you the best possible interpretation, so you can force something to be interpreted as living in a smaller ring as follows:"
278 ]
279 },
280 {
281 "cell_type": "code",
282 "execution_count": 4,
283 "metadata": {},
284 "outputs": [
285 {
286 "name": "stdout",
287 "output_type": "stream",
288 "text": [
289 "Symbolic Ring\n",
290 "Integer Ring\n"
291 ]
292 }
293 ],
294 "source": [
295 "minus_one = e^(pi*I)\n",
296 "minus_one_coerced = ZZ(e^(pi*I)) # coercion\n",
297 "print(parent(minus_one))\n",
298 "print(parent(minus_one_coerced))"
299 ]
300 },
301 {
302 "cell_type": "markdown",
303 "metadata": {},
304 "source": [
305 "**Remark.** Notice that there is a fundamental difference between the rings `RR` and `CC` and all the others in the table above: the real and complex numbers are *approximated*."
306 ]
307 },
308 {
309 "cell_type": "code",
310 "execution_count": 1,
311 "metadata": {},
312 "outputs": [
313 {
314 "name": "stdout",
315 "output_type": "stream",
316 "text": [
317 "3\n",
318 "3.00000000000000\n"
319 ]
320 }
321 ],
322 "source": [
323 "print(QQ(3))\n",
324 "print(RR(3))"
325 ]
326 },
327 {
328 "cell_type": "markdown",
329 "metadata": {},
330 "source": [
331 "You can also choose the precision of this approximation using the alternative name `RealField`."
332 ]
333 },
334 {
335 "cell_type": "code",
336 "execution_count": 4,
337 "metadata": {},
338 "outputs": [
339 {
340 "name": "stdout",
341 "output_type": "stream",
342 "text": [
343 "Real Field with 53 bits of precision\n",
344 "Real Field with 1000 bits of precision\n"
345 ]
346 }
347 ],
348 "source": [
349 "print(RR)\n",
350 "print(RealField(prec=1000))"
351 ]
352 },
353 {
354 "cell_type": "markdown",
355 "metadata": {},
356 "source": [
357 "# Polynomial rings\n",
358 "\n",
359 "**Reference:** [[7](https://doc.sagemath.org/html/en/reference/polynomial_rings/index.html)]\n",
360 "\n",
361 "If you want to work with polynomials over a certain ring it is better to use this specific construction, rather than the symbolic expressions introduced above."
362 ]
363 },
364 {
365 "cell_type": "code",
366 "execution_count": 5,
367 "metadata": {},
368 "outputs": [
369 {
370 "data": {
371 "text/plain": [
372 "Multivariate Polynomial Ring in x, y, z over Real Field with 53 bits of precision"
373 ]
374 },
375 "execution_count": 5,
376 "metadata": {},
377 "output_type": "execute_result"
378 }
379 ],
380 "source": [
381 "polring.<x,y,z> = RR[] # Alternative: polring.<x,y,z> = PolynomialRing(RR)\n",
382 "polring"
383 ]
384 },
385 {
386 "cell_type": "markdown",
387 "metadata": {},
388 "source": [
389 "You can use as many variables as you like, and you can replace `RR` with any ring. In the example above `polring` is just the name of the variable (in the computer science sense) associated with this polynomial ring.\n",
390 "\n",
391 "## Operations on polynomials\n",
392 "\n",
393 "The usual Mathematical operations are available on polynomial rings, including Euclidean division `//` and remainder `%`. There is also the single-slash division `/`, but the result may not be a polynomial anymore.\n",
394 "\n",
395 "**Exercise:** use the `parent()` command to find out what the quotient of two polynomials is.\n",
396 "\n",
397 "**Question:** what happens if you remove the first line in the cell below? What if we used the variable `y` instead of `x`?"
398 ]
399 },
400 {
401 "cell_type": "code",
402 "execution_count": 6,
403 "metadata": {},
404 "outputs": [
405 {
406 "name": "stdout",
407 "output_type": "stream",
408 "text": [
409 "x + 1\n",
410 "-4\n",
411 "(x^2 + 2*x - 3)/(x + 1)\n"
412 ]
413 }
414 ],
415 "source": [
416 "polring.<x> = QQ[]\n",
417 "p = x^2 + 2*x - 3 # Don't forget * for multiplication!\n",
418 "q = p // (x+1)\n",
419 "r = p % (x+1)\n",
420 "f = p / (x+1)\n",
421 "print(q)\n",
422 "print(r)\n",
423 "print(f)"
424 ]
425 },
426 {
427 "cell_type": "markdown",
428 "metadata": {},
429 "source": [
430 "You can do more complex operations. Try out `roots()` and `factor` in the cell below.\n",
431 "\n",
432 "**Remark.** Notice how the result can change substantially if you change the base ring.\n",
433 "\n",
434 "**Remark.** [Factorizations](https://doc.sagemath.org/html/en/reference/structure/sage/structure/factorization.html) are a particular object in Sage. They are kinda like a list, but not really. You can get a list of pairs (factor, power) with `list(factor(f))`."
435 ]
436 },
437 {
438 "cell_type": "code",
439 "execution_count": 7,
440 "metadata": {},
441 "outputs": [
442 {
443 "name": "stdout",
444 "output_type": "stream",
445 "text": [
446 "(t + 1) * (t^2 - 3) * (t^2 + 1)\n",
447 "[(-1, 1)]\n"
448 ]
449 },
450 {
451 "data": {
452 "text/plain": [
453 "(y + 1) * x"
454 ]
455 },
456 "execution_count": 7,
457 "metadata": {},
458 "output_type": "execute_result"
459 }
460 ],
461 "source": [
462 "polring_onevar.<t> = QQ[]\n",
463 "\n",
464 "f = t^5 + t^4 - 2*t^3 - 2*t^2 - 3*t - 3\n",
465 "print(factor(f))\n",
466 "print(f.roots()) # Result: list of pairs (root,multiplicity)\n",
467 "\n",
468 "polring_manyvar.<x,y,z> = QQ[]\n",
469 "factor(x*y+x)\n",
470 "\n",
471 "# The following line gives an error, because the polynomial\n",
472 "# is understood to possibly have many variables:\n",
473 "#(x^2-1).roots()"
474 ]
475 },
476 {
477 "cell_type": "markdown",
478 "metadata": {},
479 "source": [
480 "# Matrices and vectors\n",
481 "\n",
482 "**References:** [[8](https://doc.sagemath.org/html/en/reference/matrices/index.html)], but in particular the subections [[9](https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/docs.html)] and [[10](https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/matrix2.html)]\n",
483 "\n",
484 "In Sage you can easily manipulate matrices and vectors"
485 ]
486 },
487 {
488 "cell_type": "code",
489 "execution_count": 77,
490 "metadata": {},
491 "outputs": [
492 {
493 "name": "stdout",
494 "output_type": "stream",
495 "text": [
496 "[ 1 2 3]\n",
497 "[ 0 0 1]\n",
498 "[ 4 -3 22/7] \n",
499 "\n",
500 "[1/2 0 0]\n",
501 "[ 7 0 0]\n",
502 "[ 1 1 1] \n",
503 "\n",
504 "(3/2, 21, 6) \n",
505 "\n",
506 "[ -7/2 -10 80/7]\n",
507 "[ 17 -4 15/7]\n",
508 "[ 241/7 -18/7 869/49] \n",
509 "\n",
510 "Rank of A = 3\n",
511 "Rank of B = 2\n"
512 ]
513 }
514 ],
515 "source": [
516 "A = matrix([[1,2,3],[0,0,1],[4,-3,22/7]])\n",
517 "B = matrix([[1/2,0,0],[7,0,0],[1,1,1]])\n",
518 "v = vector([3,4,-1])\n",
519 "\n",
520 "print(A, \"\\n\") # \\n just means \"newline\"\n",
521 "print(B, \"\\n\")\n",
522 "print(B*v, \"\\n\")\n",
523 "print(A^2 + 2*B - A*B, \"\\n\")\n",
524 "\n",
525 "print(\"Rank of A =\", rank(A)) # You can also use A.rank()\n",
526 "print(\"Rank of B =\", rank(B))"
527 ]
528 },
529 {
530 "cell_type": "markdown",
531 "metadata": {},
532 "source": [
533 "**Exercise:** in the cell above, compute the determinant, inverse and characteristic polynomial of the matrix `A`. *Hint: look at the reference [10] above (the functions are listed in alphabetic order).*\n",
534 "\n",
535 "As for polynomials, you can specify where a matrix or a vector lives"
536 ]
537 },
538 {
539 "cell_type": "code",
540 "execution_count": 57,
541 "metadata": {},
542 "outputs": [
543 {
544 "data": {
545 "text/plain": [
546 "Full MatrixSpace of 2 by 2 dense matrices over Complex Field with 53 bits of precision"
547 ]
548 },
549 "execution_count": 57,
550 "metadata": {},
551 "output_type": "execute_result"
552 }
553 ],
554 "source": [
555 "M = matrix(CC, [[0,1],[1,0]])\n",
556 "parent(M)"
557 ]
558 },
559 {
560 "cell_type": "markdown",
561 "metadata": {},
562 "source": [
563 "You can also solve linear systems and compute eigenvalues and eigenvectors of a matrix\n",
564 "\n",
565 "**Warning.** In linear algebra there are distinct concepts of *left* and *right* eigenvalues (and eigenvector). The one you know is probably that of **right** eigen-{value,vector}, that is an element $\\lambda$ of the base field and a non-zero vector $\\mathbf v$ with $A\\mathbf v=\\lambda\\mathbf v$. The other concept corresponds to the equality $\\mathbf v^TA=\\lambda \\mathbf v$."
566 ]
567 },
568 {
569 "cell_type": "code",
570 "execution_count": 60,
571 "metadata": {},
572 "outputs": [
573 {
574 "data": {
575 "text/plain": [
576 "(0.289916349448506, 0.0241596957873755)"
577 ]
578 },
579 "execution_count": 60,
580 "metadata": {},
581 "output_type": "execute_result"
582 }
583 ],
584 "source": [
585 "A = Matrix(RR, [[sqrt(59),32],[-1/4,3]])\n",
586 "v = vector(RR, [3,0])\n",
587 "A.solve_right(v) # Solve Ax=v. Alternative: A \\ v"
588 ]
589 },
590 {
591 "cell_type": "code",
592 "execution_count": 64,
593 "metadata": {},
594 "outputs": [
595 {
596 "data": {
597 "text/plain": [
598 "[\n",
599 "(-0.3722813232690144?, Vector space of degree 2 and dimension 1 over Algebraic Field\n",
600 "User basis matrix:\n",
601 "[ 1 -0.6861406616345072?]),\n",
602 "(5.372281323269015?, Vector space of degree 2 and dimension 1 over Algebraic Field\n",
603 "User basis matrix:\n",
604 "[ 1 2.186140661634508?])\n",
605 "]"
606 ]
607 },
608 "execution_count": 64,
609 "metadata": {},
610 "output_type": "execute_result"
611 }
612 ],
613 "source": [
614 "A = Matrix(QQ, [[1,2],[3,4]])\n",
615 "A.eigenspaces_right() # Also: A.eigenvalues(), A.eigenvectors_right()"
616 ]
617 },
618 {
619 "cell_type": "markdown",
620 "metadata": {},
621 "source": [
622 "We can also extract a specific submatrix by selecting only some rows and columns, with a syntax similar to that of Python's lists. Check out more examples in the reference [9] above, and try them in the cell below."
623 ]
624 },
625 {
626 "cell_type": "code",
627 "execution_count": 94,
628 "metadata": {},
629 "outputs": [
630 {
631 "name": "stdout",
632 "output_type": "stream",
633 "text": [
634 "[-14 2 0 -1 1 -2 -1]\n",
635 "[ 0 -8 0 9 -2 11 1]\n",
636 "[ 0 3 1 -1 1 1 221]\n",
637 "[ -1 2 1 -25 -10 4 0]\n",
638 "[ -3 0 0 2 16 -1 -2]\n",
639 "[ 1 -3 3 -41 1 0 0]\n",
640 "[ -2 1 0 0 -6 2 12] \n",
641 "\n",
642 "[ 0 9 -2]\n",
643 "[ 1 -1 1] \n",
644 "\n",
645 "[-14 2 0 -1 1 -2 -1] \n",
646 "\n",
647 "[-14 2 0 -1 1]\n",
648 "[ 1 -3 3 -41 1]\n",
649 "[ 0 3 1 -1 1]\n"
650 ]
651 }
652 ],
653 "source": [
654 "A = MatrixSpace(ZZ, 7).random_element()\n",
655 "print(A, \"\\n\")\n",
656 "print(A[1:3,2:5], \"\\n\") # Rows from 1 to 3, columns from 2 to 5\n",
657 "print(A[0,0:], \"\\n\") # First row, all columns\n",
658 "print(A[[0,5,2],0:5]) # Rows 0, 5 and 2 (in this order) and columns 0 to 5"
659 ]
660 },
661 {
662 "cell_type": "markdown",
663 "metadata": {},
664 "source": [
665 "**Exercise:** write a sage function that computes the determinant of an $n\\times n$ matrix $A=(a_{ij})$ using Laplace's rule by the first row, that is \n",
666 "\\begin{align*}\n",
667 " \\operatorname{det}A = \\sum_{j=1}^n (-1)^ja_{0j}M_{0j}\n",
668 "\\end{align*}\n",
669 "where $M_{0j}$ is the determinant of the $(n-1)\\times(n-1)$ matrix obtained by removing the $0$-th row and the $j$-th column from $A$."
670 ]
671 },
672 {
673 "cell_type": "code",
674 "execution_count": 91,
675 "metadata": {},
676 "outputs": [],
677 "source": [
678 "def my_det(A):\n",
679 " if not A.is_square():\n",
680 " print(\"Error: matrix is not square\")\n",
681 " \n",
682 " n = A.nrows() # size of the matrix\n",
683 " \n",
684 " # Continue from here!"
685 ]
686 },
687 {
688 "cell_type": "markdown",
689 "metadata": {},
690 "source": [
691 "# Number Theory\n",
692 "\n",
693 "**Reference:** [[11](https://doc.sagemath.org/html/en/reference/rings_standard/sage/rings/integer.html)]\n",
694 "\n",
695 "Sage includes a large library of functions for computing with the integers, see the link above."
696 ]
697 },
698 {
699 "cell_type": "code",
700 "execution_count": 8,
701 "metadata": {},
702 "outputs": [
703 {
704 "name": "stdout",
705 "output_type": "stream",
706 "text": [
707 "3^2 * 3607 * 3803\n",
708 "True\n",
709 "True\n",
710 "619703040\n",
711 "9\n",
712 "13548070123626141\n"
713 ]
714 }
715 ],
716 "source": [
717 "n = 123456789\n",
718 "m = 987654321\n",
719 "p = 3607\n",
720 "\n",
721 "print(factor(n))\n",
722 "print(is_prime(p))\n",
723 "print(p.divides(n))\n",
724 "print(euler_phi(m))\n",
725 "print(gcd(n, m))\n",
726 "print(lcm(n, m))"
727 ]
728 },
729 {
730 "cell_type": "markdown",
731 "metadata": {},
732 "source": [
733 "## Primes\n",
734 "\n",
735 "**Reference:** [[12](https://doc.sagemath.org/html/en/reference/sets/sage/sets/primes.html)]\n",
736 "\n",
737 "The set of prime numbers is called `Primes()`. It is like an infinite list: for example you can get the one-millionth prime number or you can use this list to create other lists. You can also check what the first prime number larger than a given number is."
738 ]
739 },
740 {
741 "cell_type": "code",
742 "execution_count": 9,
743 "metadata": {},
744 "outputs": [
745 {
746 "name": "stdout",
747 "output_type": "stream",
748 "text": [
749 "Set of all prime numbers: 2, 3, 5, 7, ...\n",
750 "31 15485867\n",
751 "47\n",
752 "[79, 83, 89, 97]\n"
753 ]
754 }
755 ],
756 "source": [
757 "PP = Primes()\n",
758 "print(PP)\n",
759 "print(PP[10], PP[10^6])\n",
760 "print(PP.next(44))\n",
761 "\n",
762 "First_Thousand_Primes = PP[0:1000]\n",
763 "print([p for p in First_Thousand_Primes if p < 100 and p > 75])"
764 ]
765 },
766 {
767 "cell_type": "markdown",
768 "metadata": {},
769 "source": [
770 "## The Chinese remainder theorem (CRT)\n",
771 "\n",
772 "We say that two integers $a$ and $b$ are *congruent* modulo another integer $n>0$ if they have the same remainder when divided by $n$. We denote this by $a\\equiv b\\pmod n$, or in Python/Sage syntax `a % n == b % n`.\n",
773 "\n",
774 "The Chinese remainder theorem states that if $a,b\\in\\mathbb Z$ and $n,m\\in \\mathbb Z_{>0}$ are such that $\\gcd(n,m)=1$ then the system of congruences\n",
775 "\n",
776 "\\begin{align*}\n",
777 "\\begin{cases}\n",
778 " x \\equiv a \\pmod n\\\\\n",
779 " x \\equiv b \\pmod m\n",
780 "\\end{cases}\n",
781 "\\end{align*}\n",
782 "\n",
783 "has exactly one solution modulo $mn$. This means that there is one and only one number $x$ with $0\\leq x<mn$ such that $x\\equiv a\\pmod n$ and $x\\equiv b\\pmod m$.\n",
784 "\n",
785 "The procedure to find such a number is not too hard to describe (you might see it in an algebra or number theory course), but it can be a bit long. Luckily, Sage can do this for you:"
786 ]
787 },
788 {
789 "cell_type": "code",
790 "execution_count": 10,
791 "metadata": {},
792 "outputs": [
793 {
794 "name": "stdout",
795 "output_type": "stream",
796 "text": [
797 "74306 2 798\n"
798 ]
799 }
800 ],
801 "source": [
802 "a = 2\n",
803 "b = -1\n",
804 "n = 172\n",
805 "m = 799\n",
806 "\n",
807 "if gcd(n,m) != 1:\n",
808 " print(\"The numbers are not comprime, I can't solve this!\")\n",
809 "else:\n",
810 " x = crt(a, b, n, m)\n",
811 " print(x, x%n, x%m)"
812 ]
813 },
814 {
815 "cell_type": "markdown",
816 "metadata": {},
817 "source": [
818 "**Exercise.** There is a more general version of the Chinese remainder theorem which says that if $a_0, a_1, \\dots, a_k\\in\\mathbb Z$ and $n_0, n_2, \\dots, n_k\\in\\mathbb Z_{>0}$ are such that $\\gcd(n_i, n_j)=1$ for $i\\neq j$, then the system of congruences\n",
819 "\n",
820 "\\begin{align*}\n",
821 "\\begin{cases}\n",
822 " x \\equiv a_0 \\pmod {n_0}\\\\\n",
823 " x \\equiv a_1 \\pmod {n_1}\\\\\n",
824 " \\dots \\\\\n",
825 " x \\equiv a_k \\pmod {n_k}\n",
826 "\\end{cases}\n",
827 "\\end{align*}\n",
828 "\n",
829 "has exactly one solution modulo $\\prod_{i=0}^kn_i$. Use the `crt()` function to find a solution to such a system.\n",
830 "*Hint: start by running the command `help(crt)`."
831 ]
832 },
833 {
834 "cell_type": "code",
835 "execution_count": 127,
836 "metadata": {},
837 "outputs": [],
838 "source": [
839 "#help(crt)"
840 ]
841 },
842 {
843 "cell_type": "markdown",
844 "metadata": {},
845 "source": [
846 "# Cryptography: RSA\n",
847 "\n",
848 "[Cryptography](https://en.wikipedia.org/wiki/Cryptography) is the discipline that studies methods to communicate secrets in such a way that any unauthorized listener would not be able to understand the message.\n",
849 "\n",
850 "A simple cryptographic protocol could be changing every letter of your text following a fixed scheme (or *cypher*), for example by turning every A into a B, every B into a C and so on. However this is not a very secure method, for many reasons. One of them is that at some point the people who want to communicate need to agree on what method to use, and anyone listening to that conversation would be able to decypher every subsequent conversation. A public-key cryptographic protocol solves this problem.\n",
851 "\n",
852 "## Public-key cryptography\n",
853 "\n",
854 "Public-key cryptographic protocols, such as RSA, work like this: there are two keys, a *private* key that is only known to person A (traditionally called Alice in every example), and a *public* key that does not need to be secret.\n",
855 "\n",
856 "The public key is used to *encrypt* the message (that is to \"lock\" it, or \"hyde\" it), but one needs the private key to *decrypt* it. Imagine having two keys for your door, but one can only be used to lock it, while the other only to open it.\n",
857 "\n",
858 "The message exchange works like this: suppose that person B (Bob) wants to send a secret message to Alice. Then Alice secretely generates a private and a public key and sends only the public one to Bob. Now Bob encrypts the message and sends it to Alice, who can use her private key to decrypt it. Even if Eve (short for *eavesdropper*, an unauthorized listener) listens to every message exchanged, she won't be able to decypher the secret: the private key has never left Alice's house!\n",
859 "\n",
860 "Notice that such a protocol is *asymmetric*: if Alice wanted to send a secret to Bob in reply, Bob would need to generate a pair of keys of his own.\n",
861 "\n",
862 "Let's see how we can do this in practice, using number theory!\n",
863 "\n",
864 "## RSA\n",
865 "\n",
866 "As many other cryptography protocols, RSA is based on a Mathematical process that is easy to do in one direction, but very hard to invert. In this case the hard process is integer factorization, that is decomposing an integer number as a product of primes."
867 ]
868 },
869 {
870 "cell_type": "code",
871 "execution_count": 2,
872 "metadata": {},
873 "outputs": [
874 {
875 "name": "stdout",
876 "output_type": "stream",
877 "text": [
878 "True True False\n"
879 ]
880 }
881 ],
882 "source": [
883 "p = 100003100019100043100057100069\n",
884 "q = 100144655312449572059845328443\n",
885 "n = p*q\n",
886 "print(is_prime(p), is_prime(q), is_prime(p*q))\n",
887 "\n",
888 "# Use the command below to see how long it takes\n",
889 "#timeit(\"factor(n)\", number=1, repeat=1)"
890 ]
891 },
892 {
893 "cell_type": "markdown",
894 "metadata": {},
895 "source": [
896 "In order to generate the keys, Alice picks a number $n$ which is the product of two large primes $p$ and $q$ of more or less the same size. Finding such primes is relatively easy compared to factoring the number $n$ she obtained. Then she computes the Euler totient $\\varphi(n)=(p-1)(q-1)$ of $n$, which she can do because she knows that $n=pq$ - it would be impossible otherwise!\n",
897 "\n",
898 "Then Alice can compute two integers $(d,e)$ such that $de\\equiv 1\\pmod{\\varphi(n)}$. She will send the numbers $n$ and $d$ to Bob and keep $e$ secret. In this case the public key is the pair $(n,d)$, while $e$ is the private key.\n",
899 "\n",
900 "Of course, she does all of this using Sage!"
901 ]
902 },
903 {
904 "cell_type": "code",
905 "execution_count": 105,
906 "metadata": {},
907 "outputs": [
908 {
909 "data": {
910 "text/plain": [
911 "(419199544978969, 235530823946467, 80799425863927)"
912 ]
913 },
914 "execution_count": 105,
915 "metadata": {},
916 "output_type": "execute_result"
917 }
918 ],
919 "source": [
920 "def two_large_primes():\n",
921 " p, q = 0, 0\n",
922 " # We make sure that they are different\n",
923 " while p == q:\n",
924 " p = Primes()[randint(10^6, 2*10^6)]\n",
925 " q = Primes()[randint(10^6, 2*10^6)]\n",
926 " return p, q\n",
927 "\n",
928 "def random_unit_mod(N):\n",
929 " R = Integers(N)\n",
930 " d = R(0)\n",
931 " # We make sure that it is invertible\n",
932 " while not d.is_unit():\n",
933 " d = R.random_element()\n",
934 " return d\n",
935 "\n",
936 "def Alice_generate_keys():\n",
937 " p, q = two_large_primes()\n",
938 " n = p*q\n",
939 " phi_n = (p-1)*(q-1) # euler_phi(n) is slow!\n",
940 " \n",
941 " d = random_unit_mod(phi_n)\n",
942 " e = d^-1\n",
943 " return n, d, e\n",
944 "\n",
945 "Alice_generate_keys()"
946 ]
947 },
948 {
949 "cell_type": "markdown",
950 "metadata": {},
951 "source": [
952 "Now, how does Bob encrypt his message? Let's say he wants to send to Alice the number $m$ with $1<m<n$ (In practice he would like to send her some text with emojis, or maybe a voice message; but for computers everything is a number, and there are different ways to translate any sort of information to a number. He just chooses one of the many standard methods that already exist, no cryptography is needed in this step. If the message $m$ is too long, he can split it up in some pieces and repeat the process multiple times.)\n",
953 "\n",
954 "Now he computes $m^d\\pmod n$ and sends it back to Alice."
955 ]
956 },
957 {
958 "cell_type": "code",
959 "execution_count": 3,
960 "metadata": {},
961 "outputs": [
962 {
963 "data": {
964 "text/plain": [
965 "149461597163501"
966 ]
967 },
968 "execution_count": 3,
969 "metadata": {},
970 "output_type": "execute_result"
971 }
972 ],
973 "source": [
974 "def Bob_encrypt(m, n, d):\n",
975 " R = Integers(n)\n",
976 " return R(m)^d # Assume that n is large enough\n",
977 " \n",
978 "message = 42424242\n",
979 "Bob_encrypt(message, 419199544978969, 235530823946467)"
980 ]
981 },
982 {
983 "cell_type": "markdown",
984 "metadata": {},
985 "source": [
986 "Since $de\\equiv 1\\pmod{\\varphi(n)}$, it follows that $(m^d)^e\\equiv m\\pmod n$ (see [Wikipedia: Euler's theorem](https://en.wikipedia.org/wiki/Euler%27s_theorem)). So for Alice it is very easy to get back the original message:"
987 ]
988 },
989 {
990 "cell_type": "code",
991 "execution_count": 108,
992 "metadata": {},
993 "outputs": [
994 {
995 "data": {
996 "text/plain": [
997 "42424242"
998 ]
999 },
1000 "execution_count": 108,
1001 "metadata": {},
1002 "output_type": "execute_result"
1003 }
1004 ],
1005 "source": [
1006 "def Alice_decrypt(m_encrypted, n, e):\n",
1007 " R = Integers(n)\n",
1008 " return R(m_encrypted)^e\n",
1009 "\n",
1010 "Alice_decrypt(149461597163501, 419199544978969, 80799425863927)"
1011 ]
1012 },
1013 {
1014 "cell_type": "markdown",
1015 "metadata": {},
1016 "source": [
1017 "Another assumption on which RSA relies is that even if one knows $M=m^e$ and $e$, extracting the $e$-th root of $M$ modulo $n$ (and thus obtaining $m$) is very hard. Currently the best known way to do this is by factorizing $n$ first, which is considered to be a very hard problem. However, there is no proof that faster algorithms can't be devised.\n",
1018 "\n",
1019 "Moreover, one day we will overcome the current technological difficulties and quantum computers will be available. Quantum computers are not just \"more powerful\" than classical hardware, but they work based on completely different logical foundations and they make the factorization problem much easier to solve: for example [Shor's algorithm](https://en.wikipedia.org/wiki/Shor%27s_algorithm) takes advantage of this different logic and can factorize numbers quickly, if run on a quantum computer.\n",
1020 "\n",
1021 "To this day the largest number factorized with a quantum computer is $21=3\\times 7$. Nonetheless, quantum-safe cryptography protocols (i.e. based on problems that are hard to solve also with quantum computers) have already been developed."
1022 ]
1023 }
1024 ],
1025 "metadata": {
1026 "kernelspec": {
1027 "display_name": "SageMath 9.2",
1028 "language": "sage",
1029 "name": "sagemath"
1030 },
1031 "language_info": {
1032 "codemirror_mode": {
1033 "name": "ipython",
1034 "version": 3
1035 },
1036 "file_extension": ".py",
1037 "mimetype": "text/x-python",
1038 "name": "python",
1039 "nbconvert_exporter": "python",
1040 "pygments_lexer": "ipython3",
1041 "version": "3.8.5"
1042 }
1043 },
1044 "nbformat": 4,
1045 "nbformat_minor": 4
1046}
diff --git a/src/Lecture5/notebook/7-SageAlgebra.log b/src/Lecture5/notebook/7-SageAlgebra.log
new file mode 100644
index 0000000..615d65f
--- /dev/null
+++ b/src/Lecture5/notebook/7-SageAlgebra.log
@@ -0,0 +1,967 @@
1This is pdfTeX, Version 3.14159265-2.6-1.40.21 (TeX Live 2020/VoidLinux) (preloaded format=pdflatex 2021.4.20) 22 APR 2021 15:19
2entering extended mode
3 \write18 enabled.
4 %&-line parsing enabled.
5**7-SageAlgebra.tex
6(./7-SageAlgebra.tex
7LaTeX2e <2020-10-01> patch level 2
8L3 programming layer <2020-12-03> xparse <2020-03-03>
9(/usr/share/texmf-dist/tex/latex/base/article.cls
10Document Class: article 2020/04/10 v1.4m Standard LaTeX document class
11(/usr/share/texmf-dist/tex/latex/base/size11.clo
12File: size11.clo 2020/04/10 v1.4m Standard LaTeX file (size option)
13)
14\c@part=\count177
15\c@section=\count178
16\c@subsection=\count179
17\c@subsubsection=\count180
18\c@paragraph=\count181
19\c@subparagraph=\count182
20\c@figure=\count183
21\c@table=\count184
22\abovecaptionskip=\skip47
23\belowcaptionskip=\skip48
24\bibindent=\dimen138
25)
26(/usr/share/texmf-dist/tex/latex/tcolorbox/tcolorbox.sty
27Package: tcolorbox 2020/10/09 version 4.42 text color boxes
28
29(/usr/share/texmf-dist/tex/latex/pgf/basiclayer/pgf.sty
30(/usr/share/texmf-dist/tex/latex/pgf/utilities/pgfrcs.sty
31(/usr/share/texmf-dist/tex/generic/pgf/utilities/pgfutil-common.tex
32\pgfutil@everybye=\toks15
33\pgfutil@tempdima=\dimen139
34\pgfutil@tempdimb=\dimen140
35
36(/usr/share/texmf-dist/tex/generic/pgf/utilities/pgfutil-common-lists.tex))
37(/usr/share/texmf-dist/tex/generic/pgf/utilities/pgfutil-latex.def
38\pgfutil@abb=\box47
39)
40(/usr/share/texmf-dist/tex/generic/pgf/utilities/pgfrcs.code.tex
41(/usr/share/texmf-dist/tex/generic/pgf/pgf.revision.tex)
42Package: pgfrcs 2020/12/01 v3.1.7a (3.1.7a)
43))
44Package: pgf 2020/12/01 v3.1.7a (3.1.7a)
45
46(/usr/share/texmf-dist/tex/latex/pgf/basiclayer/pgfcore.sty
47(/usr/share/texmf-dist/tex/latex/graphics/graphicx.sty
48Package: graphicx 2020/09/09 v1.2b Enhanced LaTeX Graphics (DPC,SPQR)
49
50(/usr/share/texmf-dist/tex/latex/graphics/keyval.sty
51Package: keyval 2014/10/28 v1.15 key=value parser (DPC)
52\KV@toks@=\toks16
53)
54(/usr/share/texmf-dist/tex/latex/graphics/graphics.sty
55Package: graphics 2020/08/30 v1.4c Standard LaTeX Graphics (DPC,SPQR)
56
57(/usr/share/texmf-dist/tex/latex/graphics/trig.sty
58Package: trig 2016/01/03 v1.10 sin cos tan (DPC)
59)
60(/usr/share/texmf-dist/tex/latex/graphics-cfg/graphics.cfg
61File: graphics.cfg 2016/06/04 v1.11 sample graphics configuration
62)
63Package graphics Info: Driver file: pdftex.def on input line 105.
64
65(/usr/share/texmf-dist/tex/latex/graphics-def/pdftex.def
66File: pdftex.def 2020/10/05 v1.2a Graphics/color driver for pdftex
67))
68\Gin@req@height=\dimen141
69\Gin@req@width=\dimen142
70)
71(/usr/share/texmf-dist/tex/latex/pgf/systemlayer/pgfsys.sty
72(/usr/share/texmf-dist/tex/generic/pgf/systemlayer/pgfsys.code.tex
73Package: pgfsys 2020/12/01 v3.1.7a (3.1.7a)
74
75(/usr/share/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex
76\pgfkeys@pathtoks=\toks17
77\pgfkeys@temptoks=\toks18
78
79(/usr/share/texmf-dist/tex/generic/pgf/utilities/pgfkeysfiltered.code.tex
80\pgfkeys@tmptoks=\toks19
81))
82\pgf@x=\dimen143
83\pgf@y=\dimen144
84\pgf@xa=\dimen145
85\pgf@ya=\dimen146
86\pgf@xb=\dimen147
87\pgf@yb=\dimen148
88\pgf@xc=\dimen149
89\pgf@yc=\dimen150
90\pgf@xd=\dimen151
91\pgf@yd=\dimen152
92\w@pgf@writea=\write3
93\r@pgf@reada=\read2
94\c@pgf@counta=\count185
95\c@pgf@countb=\count186
96\c@pgf@countc=\count187
97\c@pgf@countd=\count188
98\t@pgf@toka=\toks20
99\t@pgf@tokb=\toks21
100\t@pgf@tokc=\toks22
101\pgf@sys@id@count=\count189
102
103(/usr/share/texmf-dist/tex/generic/pgf/systemlayer/pgf.cfg
104File: pgf.cfg 2020/12/01 v3.1.7a (3.1.7a)
105)
106Driver file for pgf: pgfsys-pdftex.def
107
108(/usr/share/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-pdftex.def
109File: pgfsys-pdftex.def 2020/12/01 v3.1.7a (3.1.7a)
110
111(/usr/share/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf.def
112File: pgfsys-common-pdf.def 2020/12/01 v3.1.7a (3.1.7a)
113)))
114(/usr/share/texmf-dist/tex/generic/pgf/systemlayer/pgfsyssoftpath.code.tex
115File: pgfsyssoftpath.code.tex 2020/12/01 v3.1.7a (3.1.7a)
116\pgfsyssoftpath@smallbuffer@items=\count190
117\pgfsyssoftpath@bigbuffer@items=\count191
118)
119(/usr/share/texmf-dist/tex/generic/pgf/systemlayer/pgfsysprotocol.code.tex
120File: pgfsysprotocol.code.tex 2020/12/01 v3.1.7a (3.1.7a)
121))
122(/usr/share/texmf-dist/tex/latex/xcolor/xcolor.sty
123Package: xcolor 2016/05/11 v2.12 LaTeX color extensions (UK)
124
125(/usr/share/texmf-dist/tex/latex/graphics-cfg/color.cfg
126File: color.cfg 2016/01/02 v1.6 sample color configuration
127)
128Package xcolor Info: Driver file: pdftex.def on input line 225.
129Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1348.
130Package xcolor Info: Model `hsb' substituted by `rgb' on input line 1352.
131Package xcolor Info: Model `RGB' extended on input line 1364.
132Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1366.
133Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1367.
134Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1368.
135Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1369.
136Package xcolor Info: Model `Gray' substituted by `gray' on input line 1370.
137Package xcolor Info: Model `wave' substituted by `hsb' on input line 1371.
138)
139(/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcore.code.tex
140Package: pgfcore 2020/12/01 v3.1.7a (3.1.7a)
141
142(/usr/share/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex
143(/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathcalc.code.tex
144(/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathutil.code.tex)
145(/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex
146\pgfmath@dimen=\dimen153
147\pgfmath@count=\count192
148\pgfmath@box=\box48
149\pgfmath@toks=\toks23
150\pgfmath@stack@operand=\toks24
151\pgfmath@stack@operation=\toks25
152)
153(/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.code.tex
154(/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.basic.code.tex)
155(/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.trigonometric.code
156.tex)
157(/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.random.code.tex)
158(/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.comparison.code.te
159x) (/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.base.code.tex)
160(/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.round.code.tex)
161(/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.misc.code.tex)
162(/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.integerarithmetics
163.code.tex))) (/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfloat.code.tex
164\c@pgfmathroundto@lastzeros=\count193
165)) (/usr/share/texmf-dist/tex/generic/pgf/math/pgfint.code.tex)
166(/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepoints.code.tex
167File: pgfcorepoints.code.tex 2020/12/01 v3.1.7a (3.1.7a)
168\pgf@picminx=\dimen154
169\pgf@picmaxx=\dimen155
170\pgf@picminy=\dimen156
171\pgf@picmaxy=\dimen157
172\pgf@pathminx=\dimen158
173\pgf@pathmaxx=\dimen159
174\pgf@pathminy=\dimen160
175\pgf@pathmaxy=\dimen161
176\pgf@xx=\dimen162
177\pgf@xy=\dimen163
178\pgf@yx=\dimen164
179\pgf@yy=\dimen165
180\pgf@zx=\dimen166
181\pgf@zy=\dimen167
182)
183(/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex
184File: pgfcorepathconstruct.code.tex 2020/12/01 v3.1.7a (3.1.7a)
185\pgf@path@lastx=\dimen168
186\pgf@path@lasty=\dimen169
187) (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathusage.code.tex
188File: pgfcorepathusage.code.tex 2020/12/01 v3.1.7a (3.1.7a)
189\pgf@shorten@end@additional=\dimen170
190\pgf@shorten@start@additional=\dimen171
191)
192(/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorescopes.code.tex
193File: pgfcorescopes.code.tex 2020/12/01 v3.1.7a (3.1.7a)
194\pgfpic=\box49
195\pgf@hbox=\box50
196\pgf@layerbox@main=\box51
197\pgf@picture@serial@count=\count194
198)
199(/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex
200File: pgfcoregraphicstate.code.tex 2020/12/01 v3.1.7a (3.1.7a)
201\pgflinewidth=\dimen172
202)
203(/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransformations.code.t
204ex
205File: pgfcoretransformations.code.tex 2020/12/01 v3.1.7a (3.1.7a)
206\pgf@pt@x=\dimen173
207\pgf@pt@y=\dimen174
208\pgf@pt@temp=\dimen175
209) (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorequick.code.tex
210File: pgfcorequick.code.tex 2020/12/01 v3.1.7a (3.1.7a)
211)
212(/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreobjects.code.tex
213File: pgfcoreobjects.code.tex 2020/12/01 v3.1.7a (3.1.7a)
214)
215(/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathprocessing.code.te
216x
217File: pgfcorepathprocessing.code.tex 2020/12/01 v3.1.7a (3.1.7a)
218) (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex
219File: pgfcorearrows.code.tex 2020/12/01 v3.1.7a (3.1.7a)
220\pgfarrowsep=\dimen176
221)
222(/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreshade.code.tex
223File: pgfcoreshade.code.tex 2020/12/01 v3.1.7a (3.1.7a)
224\pgf@max=\dimen177
225\pgf@sys@shading@range@num=\count195
226\pgf@shadingcount=\count196
227)
228(/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreimage.code.tex
229File: pgfcoreimage.code.tex 2020/12/01 v3.1.7a (3.1.7a)
230
231(/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreexternal.code.tex
232File: pgfcoreexternal.code.tex 2020/12/01 v3.1.7a (3.1.7a)
233\pgfexternal@startupbox=\box52
234))
235(/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorelayers.code.tex
236File: pgfcorelayers.code.tex 2020/12/01 v3.1.7a (3.1.7a)
237)
238(/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransparency.code.tex
239File: pgfcoretransparency.code.tex 2020/12/01 v3.1.7a (3.1.7a)
240) (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepatterns.code.tex
241File: pgfcorepatterns.code.tex 2020/12/01 v3.1.7a (3.1.7a)
242)
243(/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorerdf.code.tex
244File: pgfcorerdf.code.tex 2020/12/01 v3.1.7a (3.1.7a)
245)))
246(/usr/share/texmf-dist/tex/generic/pgf/modules/pgfmoduleshapes.code.tex
247File: pgfmoduleshapes.code.tex 2020/12/01 v3.1.7a (3.1.7a)
248\pgfnodeparttextbox=\box53
249)
250(/usr/share/texmf-dist/tex/generic/pgf/modules/pgfmoduleplot.code.tex
251File: pgfmoduleplot.code.tex 2020/12/01 v3.1.7a (3.1.7a)
252)
253(/usr/share/texmf-dist/tex/latex/pgf/compatibility/pgfcomp-version-0-65.sty
254Package: pgfcomp-version-0-65 2020/12/01 v3.1.7a (3.1.7a)
255\pgf@nodesepstart=\dimen178
256\pgf@nodesepend=\dimen179
257)
258(/usr/share/texmf-dist/tex/latex/pgf/compatibility/pgfcomp-version-1-18.sty
259Package: pgfcomp-version-1-18 2020/12/01 v3.1.7a (3.1.7a)
260))
261(/usr/share/texmf-dist/tex/latex/tools/verbatim.sty
262Package: verbatim 2020-07-07 v1.5u LaTeX2e package for verbatim enhancements
263\every@verbatim=\toks26
264\verbatim@line=\toks27
265\verbatim@in@stream=\read3
266)
267(/usr/share/texmf-dist/tex/latex/environ/environ.sty
268Package: environ 2014/05/04 v0.3 A new way to define environments
269
270(/usr/share/texmf-dist/tex/latex/trimspaces/trimspaces.sty
271Package: trimspaces 2009/09/17 v1.1 Trim spaces around a token list
272)
273\@envbody=\toks28
274)
275(/usr/share/texmf-dist/tex/latex/etoolbox/etoolbox.sty
276Package: etoolbox 2020/10/05 v2.5k e-TeX tools for LaTeX (JAW)
277\etb@tempcnta=\count197
278)
279\tcb@titlebox=\box54
280\tcb@upperbox=\box55
281\tcb@lowerbox=\box56
282\tcb@phantombox=\box57
283\c@tcbbreakpart=\count198
284\c@tcblayer=\count199
285\c@tcolorbox@number=\count266
286\tcb@temp=\box58
287\tcb@temp=\box59
288\tcb@temp=\box60
289\tcb@temp=\box61
290\tcb@out=\write4
291\tcb@record@out=\write5
292
293(/usr/share/texmf-dist/tex/latex/tcolorbox/tcbbreakable.code.tex
294Library (tcolorbox): 'tcbbreakable.code.tex' version '4.42'
295(/usr/share/texmf-dist/tex/generic/oberdiek/pdfcol.sty
296Package: pdfcol 2019/12/29 v1.6 Handle new color stacks for pdfTeX (HO)
297
298(/usr/share/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty
299Package: ltxcmds 2020-05-10 v1.25 LaTeX kernel commands for general use (HO)
300)
301(/usr/share/texmf-dist/tex/generic/infwarerr/infwarerr.sty
302Package: infwarerr 2019/12/03 v1.5 Providing info/warning/error messages (HO)
303)
304(/usr/share/texmf-dist/tex/generic/iftex/iftex.sty
305Package: iftex 2020/03/06 v1.0d TeX engine tests
306))
307Package pdfcol Info: New color stack `tcb@breakable' = 1 on input line 23.
308\tcb@testbox=\box62
309\tcb@totalupperbox=\box63
310\tcb@totallowerbox=\box64
311))
312(/usr/share/texmf-dist/tex/latex/parskip/parskip.sty
313Package: parskip 2020-06-15 v2.0f non-zero parskip adjustments
314
315(/usr/share/texmf-dist/tex/latex/kvoptions/kvoptions.sty
316Package: kvoptions 2020-10-07 v3.14 Key value format for package options (HO)
317
318(/usr/share/texmf-dist/tex/generic/kvsetkeys/kvsetkeys.sty
319Package: kvsetkeys 2019/12/15 v1.18 Key value parser (HO)
320)))
321(/usr/share/texmf-dist/tex/latex/base/fontenc.sty
322Package: fontenc 2020/08/10 v2.0s Standard LaTeX package
323)
324(/usr/share/texmf-dist/tex/latex/psnfss/mathpazo.sty
325Package: mathpazo 2020/03/25 PSNFSS-v9.3 Palatino w/ Pazo Math (D.Puga, WaS)
326\symupright=\mathgroup4
327)
328(/usr/share/texmf-dist/tex/latex/caption/caption.sty
329Package: caption 2020/10/26 v3.5g Customizing captions (AR)
330
331(/usr/share/texmf-dist/tex/latex/caption/caption3.sty
332Package: caption3 2020/10/21 v2.2e caption3 kernel (AR)
333\captionmargin=\dimen180
334\captionmargin@=\dimen181
335\captionwidth=\dimen182
336\caption@tempdima=\dimen183
337\caption@indent=\dimen184
338\caption@parindent=\dimen185
339\caption@hangindent=\dimen186
340Package caption Info: Standard document class detected.
341)
342\c@caption@flags=\count267
343\c@continuedfloat=\count268
344)
345(/usr/share/texmf-dist/tex/latex/adjustbox/adjustbox.sty
346Package: adjustbox 2020/08/19 v1.3 Adjusting TeX boxes (trim, clip, ...)
347
348(/usr/share/texmf-dist/tex/latex/xkeyval/xkeyval.sty
349Package: xkeyval 2020/11/20 v2.8 package option processing (HA)
350
351(/usr/share/texmf-dist/tex/generic/xkeyval/xkeyval.tex
352(/usr/share/texmf-dist/tex/generic/xkeyval/xkvutils.tex
353\XKV@toks=\toks29
354\XKV@tempa@toks=\toks30
355)
356\XKV@depth=\count269
357File: xkeyval.tex 2014/12/03 v2.7a key=value parser (HA)
358))
359(/usr/share/texmf-dist/tex/latex/adjustbox/adjcalc.sty
360Package: adjcalc 2012/05/16 v1.1 Provides advanced setlength with multiple back
361-ends (calc, etex, pgfmath)
362)
363(/usr/share/texmf-dist/tex/latex/adjustbox/trimclip.sty
364Package: trimclip 2020/08/19 v1.2 Trim and clip general TeX material
365
366(/usr/share/texmf-dist/tex/latex/collectbox/collectbox.sty
367Package: collectbox 2012/05/17 v0.4b Collect macro arguments as boxes
368\collectedbox=\box65
369)
370\tc@llx=\dimen187
371\tc@lly=\dimen188
372\tc@urx=\dimen189
373\tc@ury=\dimen190
374Package trimclip Info: Using driver 'tc-pdftex.def'.
375
376(/usr/share/texmf-dist/tex/latex/adjustbox/tc-pdftex.def
377File: tc-pdftex.def 2019/01/04 v2.2 Clipping driver for pdftex
378))
379\adjbox@Width=\dimen191
380\adjbox@Height=\dimen192
381\adjbox@Depth=\dimen193
382\adjbox@Totalheight=\dimen194
383\adjbox@pwidth=\dimen195
384\adjbox@pheight=\dimen196
385\adjbox@pdepth=\dimen197
386\adjbox@ptotalheight=\dimen198
387
388(/usr/share/texmf-dist/tex/latex/ifoddpage/ifoddpage.sty
389Package: ifoddpage 2016/04/23 v1.1 Conditionals for odd/even page detection
390\c@checkoddpage=\count270
391)
392(/usr/share/texmf-dist/tex/latex/varwidth/varwidth.sty
393Package: varwidth 2009/03/30 ver 0.92; Variable-width minipages
394\@vwid@box=\box66
395\sift@deathcycles=\count271
396\@vwid@loff=\dimen199
397\@vwid@roff=\dimen256
398))
399(/usr/share/texmf-dist/tex/latex/float/float.sty
400Package: float 2001/11/08 v1.3d Float enhancements (AL)
401\c@float@type=\count272
402\float@exts=\toks31
403\float@box=\box67
404\@float@everytoks=\toks32
405\@floatcapt=\box68
406)
407(/usr/share/texmf-dist/tex/latex/tools/enumerate.sty
408Package: enumerate 2015/07/23 v3.00 enumerate extensions (DPC)
409\@enLab=\toks33
410)
411(/usr/share/texmf-dist/tex/latex/geometry/geometry.sty
412Package: geometry 2020/01/02 v5.9 Page Geometry
413
414(/usr/share/texmf-dist/tex/generic/iftex/ifvtex.sty
415Package: ifvtex 2019/10/25 v1.7 ifvtex legacy package. Use iftex instead.
416)
417\Gm@cnth=\count273
418\Gm@cntv=\count274
419\c@Gm@tempcnt=\count275
420\Gm@bindingoffset=\dimen257
421\Gm@wd@mp=\dimen258
422\Gm@odd@mp=\dimen259
423\Gm@even@mp=\dimen260
424\Gm@layoutwidth=\dimen261
425\Gm@layoutheight=\dimen262
426\Gm@layouthoffset=\dimen263
427\Gm@layoutvoffset=\dimen264
428\Gm@dimlist=\toks34
429)
430(/usr/share/texmf-dist/tex/latex/amsmath/amsmath.sty
431Package: amsmath 2020/09/23 v2.17i AMS math features
432\@mathmargin=\skip49
433
434For additional information on amsmath, use the `?' option.
435(/usr/share/texmf-dist/tex/latex/amsmath/amstext.sty
436Package: amstext 2000/06/29 v2.01 AMS text
437
438(/usr/share/texmf-dist/tex/latex/amsmath/amsgen.sty
439File: amsgen.sty 1999/11/30 v2.0 generic functions
440\@emptytoks=\toks35
441\ex@=\dimen265
442))
443(/usr/share/texmf-dist/tex/latex/amsmath/amsbsy.sty
444Package: amsbsy 1999/11/29 v1.2d Bold Symbols
445\pmbraise@=\dimen266
446)
447(/usr/share/texmf-dist/tex/latex/amsmath/amsopn.sty
448Package: amsopn 2016/03/08 v2.02 operator names
449)
450\inf@bad=\count276
451LaTeX Info: Redefining \frac on input line 234.
452\uproot@=\count277
453\leftroot@=\count278
454LaTeX Info: Redefining \overline on input line 399.
455\classnum@=\count279
456\DOTSCASE@=\count280
457LaTeX Info: Redefining \ldots on input line 496.
458LaTeX Info: Redefining \dots on input line 499.
459LaTeX Info: Redefining \cdots on input line 620.
460\Mathstrutbox@=\box69
461\strutbox@=\box70
462\big@size=\dimen267
463LaTeX Font Info: Redeclaring font encoding OML on input line 743.
464LaTeX Font Info: Redeclaring font encoding OMS on input line 744.
465\macc@depth=\count281
466\c@MaxMatrixCols=\count282
467\dotsspace@=\muskip16
468\c@parentequation=\count283
469\dspbrk@lvl=\count284
470\tag@help=\toks36
471\row@=\count285
472\column@=\count286
473\maxfields@=\count287
474\andhelp@=\toks37
475\eqnshift@=\dimen268
476\alignsep@=\dimen269
477\tagshift@=\dimen270
478\tagwidth@=\dimen271
479\totwidth@=\dimen272
480\lineht@=\dimen273
481\@envbody=\toks38
482\multlinegap=\skip50
483\multlinetaggap=\skip51
484\mathdisplay@stack=\toks39
485LaTeX Info: Redefining \[ on input line 2923.
486LaTeX Info: Redefining \] on input line 2924.
487)
488(/usr/share/texmf-dist/tex/latex/amsfonts/amssymb.sty
489Package: amssymb 2013/01/14 v3.01 AMS font symbols
490
491(/usr/share/texmf-dist/tex/latex/amsfonts/amsfonts.sty
492Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support
493\symAMSa=\mathgroup5
494\symAMSb=\mathgroup6
495LaTeX Font Info: Redeclaring math symbol \hbar on input line 98.
496LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold'
497(Font) U/euf/m/n --> U/euf/b/n on input line 106.
498))
499(/usr/share/texmf-dist/tex/latex/base/textcomp.sty
500Package: textcomp 2020/02/02 v2.0n Standard LaTeX package
501)
502(/usr/share/texmf-dist/tex/latex/upquote/upquote.sty
503Package: upquote 2012/04/19 v1.3 upright-quote and grave-accent glyphs in verba
504tim
505)
506(/usr/share/texmf-dist/tex/latex/eurosym/eurosym.sty
507Package: eurosym 1998/08/06 v1.1 European currency symbol ``Euro''
508\@eurobox=\box71
509)
510(/usr/share/texmf-dist/tex/latex/ucs/ucs.sty
511Package: ucs 2013/05/11 v2.2 UCS: Unicode input support
512
513(/usr/share/texmf-dist/tex/latex/ucs/data/uni-global.def
514File: uni-global.def 2013/05/13 UCS: Unicode global data
515)
516\uc@secondtry=\count288
517\uc@combtoks=\toks40
518\uc@combtoksb=\toks41
519\uc@temptokena=\toks42
520)
521(/usr/share/texmf-dist/tex/latex/fancyvrb/fancyvrb.sty
522Package: fancyvrb 2020/05/03 v3.6 verbatim text (tvz,hv)
523\FV@CodeLineNo=\count289
524\FV@InFile=\read4
525\FV@TabBox=\box72
526\c@FancyVerbLine=\count290
527\FV@StepNumber=\count291
528\FV@OutFile=\write6
529)
530(/usr/share/texmf-dist/tex/latex/grffile/grffile.sty
531Package: grffile 2019/11/11 v2.1 Extended file name support for graphics (legac
532y)
533Package grffile Info: This package is an empty stub for compatibility on input
534line 40.
535)
536(/usr/share/texmf-dist/tex/latex/hyperref/hyperref.sty
537Package: hyperref 2020-05-15 v7.00e Hypertext links for LaTeX
538
539(/usr/share/texmf-dist/tex/generic/pdftexcmds/pdftexcmds.sty
540Package: pdftexcmds 2020-06-27 v0.33 Utility functions of pdfTeX for LuaTeX (HO
541)
542Package pdftexcmds Info: \pdf@primitive is available.
543Package pdftexcmds Info: \pdf@ifprimitive is available.
544Package pdftexcmds Info: \pdfdraftmode found.
545)
546(/usr/share/texmf-dist/tex/generic/kvdefinekeys/kvdefinekeys.sty
547Package: kvdefinekeys 2019-12-19 v1.6 Define keys (HO)
548)
549(/usr/share/texmf-dist/tex/generic/pdfescape/pdfescape.sty
550Package: pdfescape 2019/12/09 v1.15 Implements pdfTeX's escape features (HO)
551)
552(/usr/share/texmf-dist/tex/latex/hycolor/hycolor.sty
553Package: hycolor 2020-01-27 v1.10 Color options for hyperref/bookmark (HO)
554)
555(/usr/share/texmf-dist/tex/latex/letltxmacro/letltxmacro.sty
556Package: letltxmacro 2019/12/03 v1.6 Let assignment for LaTeX macros (HO)
557)
558(/usr/share/texmf-dist/tex/latex/auxhook/auxhook.sty
559Package: auxhook 2019-12-17 v1.6 Hooks for auxiliary files (HO)
560)
561\@linkdim=\dimen274
562\Hy@linkcounter=\count292
563\Hy@pagecounter=\count293
564
565(/usr/share/texmf-dist/tex/latex/hyperref/pd1enc.def
566File: pd1enc.def 2020-05-15 v7.00e Hyperref: PDFDocEncoding definition (HO)
567Now handling font encoding PD1 ...
568... no UTF-8 mapping file for font encoding PD1
569)
570(/usr/share/texmf-dist/tex/generic/intcalc/intcalc.sty
571Package: intcalc 2019/12/15 v1.3 Expandable calculations with integers (HO)
572)
573(/usr/share/texmf-dist/tex/generic/etexcmds/etexcmds.sty
574Package: etexcmds 2019/12/15 v1.7 Avoid name clashes with e-TeX commands (HO)
575)
576\Hy@SavedSpaceFactor=\count294
577Package hyperref Info: Hyper figures OFF on input line 4464.
578Package hyperref Info: Link nesting OFF on input line 4469.
579Package hyperref Info: Hyper index ON on input line 4472.
580Package hyperref Info: Plain pages OFF on input line 4479.
581Package hyperref Info: Backreferencing OFF on input line 4484.
582Package hyperref Info: Implicit mode ON; LaTeX internals redefined.
583Package hyperref Info: Bookmarks ON on input line 4717.
584\c@Hy@tempcnt=\count295
585
586(/usr/share/texmf-dist/tex/latex/url/url.sty
587\Urlmuskip=\muskip17
588Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc.
589)
590LaTeX Info: Redefining \url on input line 5076.
591\XeTeXLinkMargin=\dimen275
592
593(/usr/share/texmf-dist/tex/generic/bitset/bitset.sty
594Package: bitset 2019/12/09 v1.3 Handle bit-vector datatype (HO)
595
596(/usr/share/texmf-dist/tex/generic/bigintcalc/bigintcalc.sty
597Package: bigintcalc 2019/12/15 v1.5 Expandable calculations on big integers (HO
598)
599))
600\Fld@menulength=\count296
601\Field@Width=\dimen276
602\Fld@charsize=\dimen277
603Package hyperref Info: Hyper figures OFF on input line 6347.
604Package hyperref Info: Link nesting OFF on input line 6352.
605Package hyperref Info: Hyper index ON on input line 6355.
606Package hyperref Info: backreferencing OFF on input line 6362.
607Package hyperref Info: Link coloring OFF on input line 6367.
608Package hyperref Info: Link coloring with OCG OFF on input line 6372.
609Package hyperref Info: PDF/A mode OFF on input line 6377.
610LaTeX Info: Redefining \ref on input line 6417.
611LaTeX Info: Redefining \pageref on input line 6421.
612
613(/usr/share/texmf-dist/tex/latex/base/atbegshi-ltx.sty
614Package: atbegshi-ltx 2020/08/17 v1.0a Emulation of the original atbegshi packa
615ge
616with kernel methods
617)
618\Hy@abspage=\count297
619\c@Item=\count298
620\c@Hfootnote=\count299
621)
622Package hyperref Info: Driver (autodetected): hpdftex.
623
624(/usr/share/texmf-dist/tex/latex/hyperref/hpdftex.def
625File: hpdftex.def 2020-05-15 v7.00e Hyperref driver for pdfTeX
626
627(/usr/share/texmf-dist/tex/latex/base/atveryend-ltx.sty
628Package: atveryend-ltx 2020/08/19 v1.0a Emulation of the original atvery packag
629e
630with kernel methods
631)
632\Fld@listcount=\count300
633\c@bookmark@seq@number=\count301
634
635(/usr/share/texmf-dist/tex/latex/rerunfilecheck/rerunfilecheck.sty
636Package: rerunfilecheck 2019/12/05 v1.9 Rerun checks for auxiliary files (HO)
637
638(/usr/share/texmf-dist/tex/generic/uniquecounter/uniquecounter.sty
639Package: uniquecounter 2019/12/15 v1.4 Provide unlimited unique counter (HO)
640)
641Package uniquecounter Info: New unique counter `rerunfilecheck' on input line 2
64286.
643)
644\Hy@SectionHShift=\skip52
645)
646(/usr/share/texmf-dist/tex/latex/titling/titling.sty
647Package: titling 2009/09/04 v2.1d maketitle typesetting
648\thanksmarkwidth=\skip53
649\thanksmargin=\skip54
650\droptitle=\skip55
651)
652(/usr/share/texmf-dist/tex/latex/tools/longtable.sty
653Package: longtable 2020/01/07 v4.13 Multi-page Table package (DPC)
654\LTleft=\skip56
655\LTright=\skip57
656\LTpre=\skip58
657\LTpost=\skip59
658\LTchunksize=\count302
659\LTcapwidth=\dimen278
660\LT@head=\box73
661\LT@firsthead=\box74
662\LT@foot=\box75
663\LT@lastfoot=\box76
664\LT@cols=\count303
665\LT@rows=\count304
666\c@LT@tables=\count305
667\c@LT@chunks=\count306
668\LT@p@ftn=\toks43
669)
670(/usr/share/texmf-dist/tex/latex/booktabs/booktabs.sty
671Package: booktabs 2020/01/12 v1.61803398 Publication quality tables
672\heavyrulewidth=\dimen279
673\lightrulewidth=\dimen280
674\cmidrulewidth=\dimen281
675\belowrulesep=\dimen282
676\belowbottomsep=\dimen283
677\aboverulesep=\dimen284
678\abovetopsep=\dimen285
679\cmidrulesep=\dimen286
680\cmidrulekern=\dimen287
681\defaultaddspace=\dimen288
682\@cmidla=\count307
683\@cmidlb=\count308
684\@aboverulesep=\dimen289
685\@belowrulesep=\dimen290
686\@thisruleclass=\count309
687\@lastruleclass=\count310
688\@thisrulewidth=\dimen291
689)
690(/usr/share/texmf-dist/tex/latex/enumitem/enumitem.sty
691Package: enumitem 2019/06/20 v3.9 Customized lists
692\labelindent=\skip60
693\enit@outerparindent=\dimen292
694\enit@toks=\toks44
695\enit@inbox=\box77
696\enit@count@id=\count311
697\enitdp@description=\count312
698)
699(/usr/share/texmf-dist/tex/generic/ulem/ulem.sty
700\UL@box=\box78
701\UL@hyphenbox=\box79
702\UL@skip=\skip61
703\UL@hook=\toks45
704\UL@height=\dimen293
705\UL@pe=\count313
706\UL@pixel=\dimen294
707\ULC@box=\box80
708Package: ulem 2019/11/18
709\ULdepth=\dimen295
710)
711(/usr/share/texmf-dist/tex/latex/jknapltx/mathrsfs.sty
712Package: mathrsfs 1996/01/01 Math RSFS package v1.0 (jk)
713\symrsfs=\mathgroup7
714)
715\Wrappedcontinuationbox=\box81
716\Wrappedvisiblespacebox=\box82
717Package hyperref Info: Option `breaklinks' set `true' on input line 361.
718Package hyperref Info: Option `colorlinks' set `true' on input line 361.
719LaTeX Font Info: Trying to load font information for T1+ppl on input line 36
7208.
721
722(/usr/share/texmf-dist/tex/latex/psnfss/t1ppl.fd
723File: t1ppl.fd 2001/06/04 font definitions for T1/ppl.
724)
725(/usr/share/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def
726File: l3backend-pdftex.def 2020-09-24 L3 backend support: PDF output (pdfTeX)
727\l__kernel_color_stack_int=\count314
728\l__pdf_internal_box=\box83
729)
730No file 7-SageAlgebra.aux.
731\openout1 = `7-SageAlgebra.aux'.
732
733LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 368.
734LaTeX Font Info: ... okay on input line 368.
735LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 368.
736LaTeX Font Info: ... okay on input line 368.
737LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 368.
738LaTeX Font Info: ... okay on input line 368.
739LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 368.
740LaTeX Font Info: ... okay on input line 368.
741LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 368.
742LaTeX Font Info: ... okay on input line 368.
743LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 368.
744LaTeX Font Info: ... okay on input line 368.
745LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 368.
746LaTeX Font Info: ... okay on input line 368.
747LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 368.
748LaTeX Font Info: ... okay on input line 368.
749(/usr/share/texmf-dist/tex/context/base/mkii/supp-pdf.mkii
750[Loading MPS to PDF converter (version 2006.09.02).]
751\scratchcounter=\count315
752\scratchdimen=\dimen296
753\scratchbox=\box84
754\nofMPsegments=\count316
755\nofMParguments=\count317
756\everyMPshowfont=\toks46
757\MPscratchCnt=\count318
758\MPscratchDim=\dimen297
759\MPnumerator=\count319
760\makeMPintoPDFobject=\count320
761\everyMPtoPDFconversion=\toks47
762) (/usr/share/texmf-dist/tex/latex/epstopdf-pkg/epstopdf-base.sty
763Package: epstopdf-base 2020-01-24 v2.11 Base part for package epstopdf
764Package epstopdf-base Info: Redefining graphics rule for `.eps' on input line 4
76585.
766
767(/usr/share/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg
768File: epstopdf-sys.cfg 2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Liv
769e
770))
771Package caption Info: Begin \AtBeginDocument code.
772Package caption Info: float package is loaded.
773Package caption Info: hyperref package is loaded.
774Package caption Info: longtable package is loaded.
775
776(/usr/share/texmf-dist/tex/latex/caption/ltcaption.sty
777Package: ltcaption 2020/05/30 v1.4b longtable captions (AR)
778)
779Package caption Info: End \AtBeginDocument code.
780
781*geometry* driver: auto-detecting
782*geometry* detected driver: pdftex
783*geometry* verbose mode - [ preamble ] result:
784* driver: pdftex
785* paper: <default>
786* layout: <same size as paper>
787* layoutoffset:(h,v)=(0.0pt,0.0pt)
788* modes:
789* h-part:(L,W,R)=(72.26999pt, 469.75502pt, 72.26999pt)
790* v-part:(T,H,B)=(72.26999pt, 650.43001pt, 72.26999pt)
791* \paperwidth=614.295pt
792* \paperheight=794.96999pt
793* \textwidth=469.75502pt
794* \textheight=650.43001pt
795* \oddsidemargin=0.0pt
796* \evensidemargin=0.0pt
797* \topmargin=-37.0pt
798* \headheight=12.0pt
799* \headsep=25.0pt
800* \topskip=11.0pt
801* \footskip=30.0pt
802* \marginparwidth=59.0pt
803* \marginparsep=10.0pt
804* \columnsep=10.0pt
805* \skip\footins=10.0pt plus 4.0pt minus 2.0pt
806* \hoffset=0.0pt
807* \voffset=0.0pt
808* \mag=1000
809* \@twocolumnfalse
810* \@twosidefalse
811* \@mparswitchfalse
812* \@reversemarginfalse
813* (1in=72.27pt=25.4mm, 1cm=28.453pt)
814
815(/usr/share/texmf-dist/tex/latex/ucs/ucsencs.def
816File: ucsencs.def 2011/01/21 Fixes to fontencodings LGR, T3
817)
818Package hyperref Info: Link coloring ON on input line 368.
819
820(/usr/share/texmf-dist/tex/latex/hyperref/nameref.sty
821Package: nameref 2019/09/16 v2.46 Cross-referencing by name of section
822
823(/usr/share/texmf-dist/tex/latex/refcount/refcount.sty
824Package: refcount 2019/12/15 v3.6 Data extraction from label references (HO)
825)
826(/usr/share/texmf-dist/tex/generic/gettitlestring/gettitlestring.sty
827Package: gettitlestring 2019/12/15 v1.6 Cleanup title references (HO)
828)
829\c@section@level=\count321
830)
831LaTeX Info: Redefining \ref on input line 368.
832LaTeX Info: Redefining \pageref on input line 368.
833LaTeX Info: Redefining \nameref on input line 368.
834\@outlinefile=\write7
835\openout7 = `7-SageAlgebra.out'.
836
837LaTeX Font Info: Trying to load font information for OT1+ppl on input line 3
83870.
839
840(/usr/share/texmf-dist/tex/latex/psnfss/ot1ppl.fd
841File: ot1ppl.fd 2001/06/04 font definitions for OT1/ppl.
842)
843LaTeX Font Info: Trying to load font information for OML+zplm on input line
844370.
845
846(/usr/share/texmf-dist/tex/latex/psnfss/omlzplm.fd
847File: omlzplm.fd 2002/09/08 Fontinst v1.914 font definitions for OML/zplm.
848)
849LaTeX Font Info: Trying to load font information for OMS+zplm on input line
850370.
851
852(/usr/share/texmf-dist/tex/latex/psnfss/omszplm.fd
853File: omszplm.fd 2002/09/08 Fontinst v1.914 font definitions for OMS/zplm.
854)
855LaTeX Font Info: Trying to load font information for OMX+zplm on input line
856370.
857
858(/usr/share/texmf-dist/tex/latex/psnfss/omxzplm.fd
859File: omxzplm.fd 2002/09/08 Fontinst v1.914 font definitions for OMX/zplm.
860)
861LaTeX Font Info: Trying to load font information for OT1+zplm on input line
862370.
863
864(/usr/share/texmf-dist/tex/latex/psnfss/ot1zplm.fd
865File: ot1zplm.fd 2002/09/08 Fontinst v1.914 font definitions for OT1/zplm.
866)
867LaTeX Font Info: Font shape `U/msa/m/n' will be
868(Font) scaled to size 12.50409pt on input line 370.
869LaTeX Font Info: Font shape `U/msa/m/n' will be
870(Font) scaled to size 9.37807pt on input line 370.
871LaTeX Font Info: Font shape `U/msa/m/n' will be
872(Font) scaled to size 7.29405pt on input line 370.
873LaTeX Font Info: Font shape `U/msb/m/n' will be
874(Font) scaled to size 12.50409pt on input line 370.
875LaTeX Font Info: Font shape `U/msb/m/n' will be
876(Font) scaled to size 9.37807pt on input line 370.
877LaTeX Font Info: Font shape `U/msb/m/n' will be
878(Font) scaled to size 7.29405pt on input line 370.
879LaTeX Font Info: Trying to load font information for U+rsfs on input line 37
8800.
881
882(/usr/share/texmf-dist/tex/latex/jknapltx/ursfs.fd
883File: ursfs.fd 1998/03/24 rsfs font definition file (jk)
884)
885LaTeX Font Info: Trying to load font information for T1+cmtt on input line 3
88670.
887
888(/usr/share/texmf-dist/tex/latex/base/t1cmtt.fd
889File: t1cmtt.fd 2019/12/16 v2.5j Standard LaTeX font definitions
890)
891LaTeX Font Info: Font shape `U/msa/m/n' will be
892(Font) scaled to size 11.40997pt on input line 376.
893LaTeX Font Info: Font shape `U/msa/m/n' will be
894(Font) scaled to size 8.33606pt on input line 376.
895LaTeX Font Info: Font shape `U/msa/m/n' will be
896(Font) scaled to size 6.25204pt on input line 376.
897LaTeX Font Info: Font shape `U/msb/m/n' will be
898(Font) scaled to size 11.40997pt on input line 376.
899LaTeX Font Info: Font shape `U/msb/m/n' will be
900(Font) scaled to size 8.33606pt on input line 376.
901LaTeX Font Info: Font shape `U/msb/m/n' will be
902(Font) scaled to size 6.25204pt on input line 376.
903 [1
904
905{/usr/share/texmf-var/fonts/map/pdftex/updmap/pdftex.map}]
906LaTeX Font Info: Trying to load font information for TS1+cmtt on input line
907496.
908 (/usr/share/texmf-dist/tex/latex/base/ts1cmtt.fd
909File: ts1cmtt.fd 2019/12/16 v2.5j Standard LaTeX font definitions
910) [2]
911LaTeX Font Info: Trying to load font information for U+fplmbb on input line
912562.
913 (/usr/share/texmf-dist/tex/latex/psnfss/ufplmbb.fd
914File: ufplmbb.fd 2003/10/30 Fontinst v1.914 font definitions for U/fplmbb.
915)
916
917Package longtable Warning: Column widths have changed
918(longtable) in table 1 on input line 587.
919
920[3] [4]
921LaTeX Font Info: Font shape `T1/cmtt/bx/n' in size <10.95> not available
922(Font) Font shape `T1/cmtt/m/n' tried instead on input line 798.
923 [5] [6] [7] [8] [9] [10] [11] [12]
924
925Package longtable Warning: Table widths have changed. Rerun LaTeX.
926
927(./7-SageAlgebra.aux)
928
929Package rerunfilecheck Warning: File `7-SageAlgebra.out' has changed.
930(rerunfilecheck) Rerun to get outlines right
931(rerunfilecheck) or use package `bookmark'.
932
933Package rerunfilecheck Info: Checksums for `7-SageAlgebra.out':
934(rerunfilecheck) Before: <no file>
935(rerunfilecheck) After: 961D93ACE9582C324C6D1EA7B5DE7C92;970.
936
937LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right.
938
939 )
940Here is how much of TeX's memory you used:
941 21321 strings out of 479383
942 388521 string characters out of 5875798
943 751012 words of memory out of 5000000
944 37920 multiletter control sequences out of 15000+600000
945 445530 words of font info for 135 fonts, out of 8000000 for 9000
946 1141 hyphenation exceptions out of 8191
947 107i,14n,111p,506b,616s stack positions out of 5000i,500n,10000p,200000b,80000s
948{/usr/share/texmf-dist/fonts/enc/dvips/cm-super/cm-super-ts1.enc}{/usr/share/
949texmf-dist/fonts/enc/dvips/cm-super/cm-super-t1.enc}{/usr/share/texmf-dist/font
950s/enc/dvips/base/8r.enc}</usr/share/texmf-dist/fonts/type1/public/amsfonts/cm/c
951mex10.pfb></usr/share/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi10.pfb></us
952r/share/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb></usr/share/texmf-d
953ist/fonts/type1/public/amsfonts/cm/cmsy10.pfb></usr/share/texmf-dist/fonts/type
9541/public/mathpazo/fplmbb.pfb></usr/share/texmf-dist/fonts/type1/public/mathpazo
955/fplmr.pfb></usr/share/texmf-dist/fonts/type1/public/mathpazo/fplmri.pfb></usr/
956share/texmf-dist/fonts/type1/public/cm-super/sfit1095.pfb></usr/share/texmf-dis
957t/fonts/type1/public/cm-super/sftt1095.pfb></usr/share/texmf-dist/fonts/type1/p
958ublic/cm-super/sftt1200.pfb></usr/share/texmf-dist/fonts/type1/urw/palatino/upl
959b8a.pfb></usr/share/texmf-dist/fonts/type1/urw/palatino/uplr8a.pfb></usr/share/
960texmf-dist/fonts/type1/urw/palatino/uplri8a.pfb>
961Output written on 7-SageAlgebra.pdf (12 pages, 226346 bytes).
962PDF statistics:
963 184 PDF objects out of 1000 (max. 8388607)
964 155 compressed objects within 2 object streams
965 46 named destinations out of 1000 (max. 500000)
966 13 words of extra memory for PDF output out of 10000 (max. 10000000)
967
diff --git a/src/Lecture5/notebook/7-SageAlgebra.out b/src/Lecture5/notebook/7-SageAlgebra.out
new file mode 100644
index 0000000..a3ec270
--- /dev/null
+++ b/src/Lecture5/notebook/7-SageAlgebra.out
@@ -0,0 +1,16 @@
1\BOOKMARK [1][-]{section.1}{The Jupyter Notebook}{}% 1
2\BOOKMARK [2][-]{subsection.1.1}{Cells}{section.1}% 2
3\BOOKMARK [2][-]{subsection.1.2}{Markdown}{section.1}% 3
4\BOOKMARK [1][-]{section.2}{Symbolic expressions}{}% 4
5\BOOKMARK [2][-]{subsection.2.1}{Mathematical variables}{section.2}% 5
6\BOOKMARK [1][-]{section.3}{Basic rings and fields}{}% 6
7\BOOKMARK [2][-]{subsection.3.1}{Parents and coercion}{section.3}% 7
8\BOOKMARK [1][-]{section.4}{Polynomial rings}{}% 8
9\BOOKMARK [2][-]{subsection.4.1}{Operations on polynomials}{section.4}% 9
10\BOOKMARK [1][-]{section.5}{Matrices and vectors}{}% 10
11\BOOKMARK [1][-]{section.6}{Number Theory}{}% 11
12\BOOKMARK [2][-]{subsection.6.1}{Primes}{section.6}% 12
13\BOOKMARK [2][-]{subsection.6.2}{The Chinese remainder theorem \(CRT\)}{section.6}% 13
14\BOOKMARK [1][-]{section.7}{Cryptography: RSA}{}% 14
15\BOOKMARK [2][-]{subsection.7.1}{Public-key cryptography}{section.7}% 15
16\BOOKMARK [2][-]{subsection.7.2}{RSA}{section.7}% 16
diff --git a/src/Lecture5/notebook/7-SageAlgebra.pdf b/src/Lecture5/notebook/7-SageAlgebra.pdf
new file mode 100644
index 0000000..3b9d17c
--- /dev/null
+++ b/src/Lecture5/notebook/7-SageAlgebra.pdf
Binary files differ
diff --git a/src/Lecture5/notebook/7-SageAlgebra.tex b/src/Lecture5/notebook/7-SageAlgebra.tex
new file mode 100644
index 0000000..a9c6c72
--- /dev/null
+++ b/src/Lecture5/notebook/7-SageAlgebra.tex
@@ -0,0 +1,1297 @@
1\documentclass[11pt]{article}
2
3 \usepackage[breakable]{tcolorbox}
4 \usepackage{parskip} % Stop auto-indenting (to mimic markdown behaviour)
5
6 \usepackage{iftex}
7 \ifPDFTeX
8 \usepackage[T1]{fontenc}
9 \usepackage{mathpazo}
10 \else
11 \usepackage{fontspec}
12 \fi
13
14 % Basic figure setup, for now with no caption control since it's done
15 % automatically by Pandoc (which extracts ![](path) syntax from Markdown).
16 \usepackage{graphicx}
17 % Maintain compatibility with old templates. Remove in nbconvert 6.0
18 \let\Oldincludegraphics\includegraphics
19 % Ensure that by default, figures have no caption (until we provide a
20 % proper Figure object with a Caption API and a way to capture that
21 % in the conversion process - todo).
22 \usepackage{caption}
23 \DeclareCaptionFormat{nocaption}{}
24 \captionsetup{format=nocaption,aboveskip=0pt,belowskip=0pt}
25
26 \usepackage[Export]{adjustbox} % Used to constrain images to a maximum size
27 \adjustboxset{max size={0.9\linewidth}{0.9\paperheight}}
28 \usepackage{float}
29 \floatplacement{figure}{H} % forces figures to be placed at the correct location
30 \usepackage{xcolor} % Allow colors to be defined
31 \usepackage{enumerate} % Needed for markdown enumerations to work
32 \usepackage{geometry} % Used to adjust the document margins
33 \usepackage{amsmath} % Equations
34 \usepackage{amssymb} % Equations
35 \usepackage{textcomp} % defines textquotesingle
36 % Hack from http://tex.stackexchange.com/a/47451/13684:
37 \AtBeginDocument{%
38 \def\PYZsq{\textquotesingle}% Upright quotes in Pygmentized code
39 }
40 \usepackage{upquote} % Upright quotes for verbatim code
41 \usepackage{eurosym} % defines \euro
42 \usepackage[mathletters]{ucs} % Extended unicode (utf-8) support
43 \usepackage{fancyvrb} % verbatim replacement that allows latex
44 \usepackage{grffile} % extends the file name processing of package graphics
45 % to support a larger range
46 \makeatletter % fix for grffile with XeLaTeX
47 \def\Gread@@xetex#1{%
48 \IfFileExists{"\Gin@base".bb}%
49 {\Gread@eps{\Gin@base.bb}}%
50 {\Gread@@xetex@aux#1}%
51 }
52 \makeatother
53
54 % The hyperref package gives us a pdf with properly built
55 % internal navigation ('pdf bookmarks' for the table of contents,
56 % internal cross-reference links, web links for URLs, etc.)
57 \usepackage{hyperref}
58 % The default LaTeX title has an obnoxious amount of whitespace. By default,
59 % titling removes some of it. It also provides customization options.
60 \usepackage{titling}
61 \usepackage{longtable} % longtable support required by pandoc >1.10
62 \usepackage{booktabs} % table support for pandoc > 1.12.2
63 \usepackage[inline]{enumitem} % IRkernel/repr support (it uses the enumerate* environment)
64 \usepackage[normalem]{ulem} % ulem is needed to support strikethroughs (\sout)
65 % normalem makes italics be italics, not underlines
66 \usepackage{mathrsfs}
67
68
69
70 % Colors for the hyperref package
71 \definecolor{urlcolor}{rgb}{0,.145,.698}
72 \definecolor{linkcolor}{rgb}{.71,0.21,0.01}
73 \definecolor{citecolor}{rgb}{.12,.54,.11}
74
75 % ANSI colors
76 \definecolor{ansi-black}{HTML}{3E424D}
77 \definecolor{ansi-black-intense}{HTML}{282C36}
78 \definecolor{ansi-red}{HTML}{E75C58}
79 \definecolor{ansi-red-intense}{HTML}{B22B31}
80 \definecolor{ansi-green}{HTML}{00A250}
81 \definecolor{ansi-green-intense}{HTML}{007427}
82 \definecolor{ansi-yellow}{HTML}{DDB62B}
83 \definecolor{ansi-yellow-intense}{HTML}{B27D12}
84 \definecolor{ansi-blue}{HTML}{208FFB}
85 \definecolor{ansi-blue-intense}{HTML}{0065CA}
86 \definecolor{ansi-magenta}{HTML}{D160C4}
87 \definecolor{ansi-magenta-intense}{HTML}{A03196}
88 \definecolor{ansi-cyan}{HTML}{60C6C8}
89 \definecolor{ansi-cyan-intense}{HTML}{258F8F}
90 \definecolor{ansi-white}{HTML}{C5C1B4}
91 \definecolor{ansi-white-intense}{HTML}{A1A6B2}
92 \definecolor{ansi-default-inverse-fg}{HTML}{FFFFFF}
93 \definecolor{ansi-default-inverse-bg}{HTML}{000000}
94
95 % commands and environments needed by pandoc snippets
96 % extracted from the output of `pandoc -s`
97 \providecommand{\tightlist}{%
98 \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
99 \DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}}
100 % Add ',fontsize=\small' for more characters per line
101 \newenvironment{Shaded}{}{}
102 \newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}}
103 \newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{{#1}}}
104 \newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}
105 \newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}
106 \newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}
107 \newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
108 \newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
109 \newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{{#1}}}}
110 \newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{{#1}}}
111 \newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}}
112 \newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{{#1}}}
113 \newcommand{\RegionMarkerTok}[1]{{#1}}
114 \newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}}
115 \newcommand{\NormalTok}[1]{{#1}}
116
117 % Additional commands for more recent versions of Pandoc
118 \newcommand{\ConstantTok}[1]{\textcolor[rgb]{0.53,0.00,0.00}{{#1}}}
119 \newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
120 \newcommand{\VerbatimStringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
121 \newcommand{\SpecialStringTok}[1]{\textcolor[rgb]{0.73,0.40,0.53}{{#1}}}
122 \newcommand{\ImportTok}[1]{{#1}}
123 \newcommand{\DocumentationTok}[1]{\textcolor[rgb]{0.73,0.13,0.13}{\textit{{#1}}}}
124 \newcommand{\AnnotationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}}
125 \newcommand{\CommentVarTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}}
126 \newcommand{\VariableTok}[1]{\textcolor[rgb]{0.10,0.09,0.49}{{#1}}}
127 \newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}}
128 \newcommand{\OperatorTok}[1]{\textcolor[rgb]{0.40,0.40,0.40}{{#1}}}
129 \newcommand{\BuiltInTok}[1]{{#1}}
130 \newcommand{\ExtensionTok}[1]{{#1}}
131 \newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.74,0.48,0.00}{{#1}}}
132 \newcommand{\AttributeTok}[1]{\textcolor[rgb]{0.49,0.56,0.16}{{#1}}}
133 \newcommand{\InformationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}}
134 \newcommand{\WarningTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}}
135
136
137 % Define a nice break command that doesn't care if a line doesn't already
138 % exist.
139 \def\br{\hspace*{\fill} \\* }
140 % Math Jax compatibility definitions
141 \def\gt{>}
142 \def\lt{<}
143 \let\Oldtex\TeX
144 \let\Oldlatex\LaTeX
145 \renewcommand{\TeX}{\textrm{\Oldtex}}
146 \renewcommand{\LaTeX}{\textrm{\Oldlatex}}
147 % Document parameters
148 % Document title
149 \title{Algebra and Cryptography with SageMath}
150 \date{2021-04-23}
151 \author{Sebastiano Tronto - \texttt{sebastiano.tronto@uni.lu}}
152
153
154
155
156
157% Pygments definitions
158\makeatletter
159\def\PY@reset{\let\PY@it=\relax \let\PY@bf=\relax%
160 \let\PY@ul=\relax \let\PY@tc=\relax%
161 \let\PY@bc=\relax \let\PY@ff=\relax}
162\def\PY@tok#1{\csname PY@tok@#1\endcsname}
163\def\PY@toks#1+{\ifx\relax#1\empty\else%
164 \PY@tok{#1}\expandafter\PY@toks\fi}
165\def\PY@do#1{\PY@bc{\PY@tc{\PY@ul{%
166 \PY@it{\PY@bf{\PY@ff{#1}}}}}}}
167\def\PY#1#2{\PY@reset\PY@toks#1+\relax+\PY@do{#2}}
168
169\expandafter\def\csname PY@tok@w\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.73,0.73}{##1}}}
170\expandafter\def\csname PY@tok@c\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
171\expandafter\def\csname PY@tok@cp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.74,0.48,0.00}{##1}}}
172\expandafter\def\csname PY@tok@k\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
173\expandafter\def\csname PY@tok@kp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
174\expandafter\def\csname PY@tok@kt\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.69,0.00,0.25}{##1}}}
175\expandafter\def\csname PY@tok@o\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
176\expandafter\def\csname PY@tok@ow\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.67,0.13,1.00}{##1}}}
177\expandafter\def\csname PY@tok@nb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
178\expandafter\def\csname PY@tok@nf\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
179\expandafter\def\csname PY@tok@nc\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
180\expandafter\def\csname PY@tok@nn\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
181\expandafter\def\csname PY@tok@ne\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.82,0.25,0.23}{##1}}}
182\expandafter\def\csname PY@tok@nv\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
183\expandafter\def\csname PY@tok@no\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.53,0.00,0.00}{##1}}}
184\expandafter\def\csname PY@tok@nl\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.00}{##1}}}
185\expandafter\def\csname PY@tok@ni\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.60,0.60,0.60}{##1}}}
186\expandafter\def\csname PY@tok@na\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.49,0.56,0.16}{##1}}}
187\expandafter\def\csname PY@tok@nt\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
188\expandafter\def\csname PY@tok@nd\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.67,0.13,1.00}{##1}}}
189\expandafter\def\csname PY@tok@s\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
190\expandafter\def\csname PY@tok@sd\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
191\expandafter\def\csname PY@tok@si\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.53}{##1}}}
192\expandafter\def\csname PY@tok@se\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.13}{##1}}}
193\expandafter\def\csname PY@tok@sr\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.53}{##1}}}
194\expandafter\def\csname PY@tok@ss\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
195\expandafter\def\csname PY@tok@sx\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
196\expandafter\def\csname PY@tok@m\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
197\expandafter\def\csname PY@tok@gh\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
198\expandafter\def\csname PY@tok@gu\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}}
199\expandafter\def\csname PY@tok@gd\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.63,0.00,0.00}{##1}}}
200\expandafter\def\csname PY@tok@gi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}}
201\expandafter\def\csname PY@tok@gr\endcsname{\def\PY@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}}
202\expandafter\def\csname PY@tok@ge\endcsname{\let\PY@it=\textit}
203\expandafter\def\csname PY@tok@gs\endcsname{\let\PY@bf=\textbf}
204\expandafter\def\csname PY@tok@gp\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
205\expandafter\def\csname PY@tok@go\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}}
206\expandafter\def\csname PY@tok@gt\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.27,0.87}{##1}}}
207\expandafter\def\csname PY@tok@err\endcsname{\def\PY@bc##1{\setlength{\fboxsep}{0pt}\fcolorbox[rgb]{1.00,0.00,0.00}{1,1,1}{\strut ##1}}}
208\expandafter\def\csname PY@tok@kc\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
209\expandafter\def\csname PY@tok@kd\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
210\expandafter\def\csname PY@tok@kn\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
211\expandafter\def\csname PY@tok@kr\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
212\expandafter\def\csname PY@tok@bp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
213\expandafter\def\csname PY@tok@fm\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
214\expandafter\def\csname PY@tok@vc\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
215\expandafter\def\csname PY@tok@vg\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
216\expandafter\def\csname PY@tok@vi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
217\expandafter\def\csname PY@tok@vm\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
218\expandafter\def\csname PY@tok@sa\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
219\expandafter\def\csname PY@tok@sb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
220\expandafter\def\csname PY@tok@sc\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
221\expandafter\def\csname PY@tok@dl\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
222\expandafter\def\csname PY@tok@s2\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
223\expandafter\def\csname PY@tok@sh\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
224\expandafter\def\csname PY@tok@s1\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
225\expandafter\def\csname PY@tok@mb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
226\expandafter\def\csname PY@tok@mf\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
227\expandafter\def\csname PY@tok@mh\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
228\expandafter\def\csname PY@tok@mi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
229\expandafter\def\csname PY@tok@il\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
230\expandafter\def\csname PY@tok@mo\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
231\expandafter\def\csname PY@tok@ch\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
232\expandafter\def\csname PY@tok@cm\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
233\expandafter\def\csname PY@tok@cpf\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
234\expandafter\def\csname PY@tok@c1\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
235\expandafter\def\csname PY@tok@cs\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
236
237\def\PYZbs{\char`\\}
238\def\PYZus{\char`\_}
239\def\PYZob{\char`\{}
240\def\PYZcb{\char`\}}
241\def\PYZca{\char`\^}
242\def\PYZam{\char`\&}
243\def\PYZlt{\char`\<}
244\def\PYZgt{\char`\>}
245\def\PYZsh{\char`\#}
246\def\PYZpc{\char`\%}
247\def\PYZdl{\char`\$}
248\def\PYZhy{\char`\-}
249\def\PYZsq{\char`\'}
250\def\PYZdq{\char`\"}
251\def\PYZti{\char`\~}
252% for compatibility with earlier versions
253\def\PYZat{@}
254\def\PYZlb{[}
255\def\PYZrb{]}
256\makeatother
257
258
259 % For linebreaks inside Verbatim environment from package fancyvrb.
260 \makeatletter
261 \newbox\Wrappedcontinuationbox
262 \newbox\Wrappedvisiblespacebox
263 \newcommand*\Wrappedvisiblespace {\textcolor{red}{\textvisiblespace}}
264 \newcommand*\Wrappedcontinuationsymbol {\textcolor{red}{\llap{\tiny$\m@th\hookrightarrow$}}}
265 \newcommand*\Wrappedcontinuationindent {3ex }
266 \newcommand*\Wrappedafterbreak {\kern\Wrappedcontinuationindent\copy\Wrappedcontinuationbox}
267 % Take advantage of the already applied Pygments mark-up to insert
268 % potential linebreaks for TeX processing.
269 % {, <, #, %, $, ' and ": go to next line.
270 % _, }, ^, &, >, - and ~: stay at end of broken line.
271 % Use of \textquotesingle for straight quote.
272 \newcommand*\Wrappedbreaksatspecials {%
273 \def\PYGZus{\discretionary{\char`\_}{\Wrappedafterbreak}{\char`\_}}%
274 \def\PYGZob{\discretionary{}{\Wrappedafterbreak\char`\{}{\char`\{}}%
275 \def\PYGZcb{\discretionary{\char`\}}{\Wrappedafterbreak}{\char`\}}}%
276 \def\PYGZca{\discretionary{\char`\^}{\Wrappedafterbreak}{\char`\^}}%
277 \def\PYGZam{\discretionary{\char`\&}{\Wrappedafterbreak}{\char`\&}}%
278 \def\PYGZlt{\discretionary{}{\Wrappedafterbreak\char`\<}{\char`\<}}%
279 \def\PYGZgt{\discretionary{\char`\>}{\Wrappedafterbreak}{\char`\>}}%
280 \def\PYGZsh{\discretionary{}{\Wrappedafterbreak\char`\#}{\char`\#}}%
281 \def\PYGZpc{\discretionary{}{\Wrappedafterbreak\char`\%}{\char`\%}}%
282 \def\PYGZdl{\discretionary{}{\Wrappedafterbreak\char`\$}{\char`\$}}%
283 \def\PYGZhy{\discretionary{\char`\-}{\Wrappedafterbreak}{\char`\-}}%
284 \def\PYGZsq{\discretionary{}{\Wrappedafterbreak\textquotesingle}{\textquotesingle}}%
285 \def\PYGZdq{\discretionary{}{\Wrappedafterbreak\char`\"}{\char`\"}}%
286 \def\PYGZti{\discretionary{\char`\~}{\Wrappedafterbreak}{\char`\~}}%
287 }
288 % Some characters . , ; ? ! / are not pygmentized.
289 % This macro makes them "active" and they will insert potential linebreaks
290 \newcommand*\Wrappedbreaksatpunct {%
291 \lccode`\~`\.\lowercase{\def~}{\discretionary{\hbox{\char`\.}}{\Wrappedafterbreak}{\hbox{\char`\.}}}%
292 \lccode`\~`\,\lowercase{\def~}{\discretionary{\hbox{\char`\,}}{\Wrappedafterbreak}{\hbox{\char`\,}}}%
293 \lccode`\~`\;\lowercase{\def~}{\discretionary{\hbox{\char`\;}}{\Wrappedafterbreak}{\hbox{\char`\;}}}%
294 \lccode`\~`\:\lowercase{\def~}{\discretionary{\hbox{\char`\:}}{\Wrappedafterbreak}{\hbox{\char`\:}}}%
295 \lccode`\~`\?\lowercase{\def~}{\discretionary{\hbox{\char`\?}}{\Wrappedafterbreak}{\hbox{\char`\?}}}%
296 \lccode`\~`\!\lowercase{\def~}{\discretionary{\hbox{\char`\!}}{\Wrappedafterbreak}{\hbox{\char`\!}}}%
297 \lccode`\~`\/\lowercase{\def~}{\discretionary{\hbox{\char`\/}}{\Wrappedafterbreak}{\hbox{\char`\/}}}%
298 \catcode`\.\active
299 \catcode`\,\active
300 \catcode`\;\active
301 \catcode`\:\active
302 \catcode`\?\active
303 \catcode`\!\active
304 \catcode`\/\active
305 \lccode`\~`\~
306 }
307 \makeatother
308
309 \let\OriginalVerbatim=\Verbatim
310 \makeatletter
311 \renewcommand{\Verbatim}[1][1]{%
312 %\parskip\z@skip
313 \sbox\Wrappedcontinuationbox {\Wrappedcontinuationsymbol}%
314 \sbox\Wrappedvisiblespacebox {\FV@SetupFont\Wrappedvisiblespace}%
315 \def\FancyVerbFormatLine ##1{\hsize\linewidth
316 \vtop{\raggedright\hyphenpenalty\z@\exhyphenpenalty\z@
317 \doublehyphendemerits\z@\finalhyphendemerits\z@
318 \strut ##1\strut}%
319 }%
320 % If the linebreak is at a space, the latter will be displayed as visible
321 % space at end of first line, and a continuation symbol starts next line.
322 % Stretch/shrink are however usually zero for typewriter font.
323 \def\FV@Space {%
324 \nobreak\hskip\z@ plus\fontdimen3\font minus\fontdimen4\font
325 \discretionary{\copy\Wrappedvisiblespacebox}{\Wrappedafterbreak}
326 {\kern\fontdimen2\font}%
327 }%
328
329 % Allow breaks at special characters using \PYG... macros.
330 \Wrappedbreaksatspecials
331 % Breaks at punctuation characters . , ; ? ! and / need catcode=\active
332 \OriginalVerbatim[#1,codes*=\Wrappedbreaksatpunct]%
333 }
334 \makeatother
335
336 % Exact colors from NB
337 \definecolor{incolor}{HTML}{303F9F}
338 \definecolor{outcolor}{HTML}{D84315}
339 \definecolor{cellborder}{HTML}{CFCFCF}
340 \definecolor{cellbackground}{HTML}{F7F7F7}
341
342 % prompt
343 \makeatletter
344 \newcommand{\boxspacing}{\kern\kvtcb@left@rule\kern\kvtcb@boxsep}
345 \makeatother
346 \newcommand{\prompt}[4]{
347 \ttfamily\llap{{\color{#2}[#3]:\hspace{3pt}#4}}\vspace{-\baselineskip}
348 }
349
350
351
352 % Prevent overflowing lines due to hard-to-break entities
353 \sloppy
354 % Setup hyperref package
355 \hypersetup{
356 breaklinks=true, % so long urls are correctly broken across lines
357 colorlinks=true,
358 urlcolor=urlcolor,
359 linkcolor=linkcolor,
360 citecolor=citecolor,
361 }
362 % Slightly bigger margins than the latex defaults
363
364 \geometry{verbose,tmargin=1in,bmargin=1in,lmargin=1in,rmargin=1in}
365
366
367
368\begin{document}
369
370 \maketitle
371
372
373
374
375 This lecture's notes are in a different format: the presentations for
376the \(\LaTeX\) part were made with \(\LaTeX\), so this one is made with
377Sage, or rather with the \href{https://jupyter.org/}{Jupyter Notebook}.
378
379\hypertarget{the-jupyter-notebook}{%
380\section{The Jupyter Notebook}\label{the-jupyter-notebook}}
381
382\textbf{Reference:} {[}\href{https://jupyter.org/documentation}{1}{]}
383
384The Jupyter Notebook is one of the default interfaces for SageMath,
385along with the command line interface. You can access it via web
386browser, but it is running locally on your device (notice the strange
387url: \texttt{http://localhost:8888/notebooks...}).
388
389You can create a new notebook by clicking on
390\texttt{New\ \textgreater{}\ SageMath\ 9.2}. You can also create a
391Python 3 notebook to write Python code.
392
393Jupyter saves and reads files in the \texttt{.ipynb} format. If you
394download the file for this lecture you can open it and follow the
395examples interactively.
396
397\hypertarget{cells}{%
398\subsection{Cells}\label{cells}}
399
400The notebook contains one or more \emph{interactive cells} that you can
401run, like this one below:
402
403 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
404\prompt{In}{incolor}{2}{\boxspacing}
405\begin{Verbatim}[commandchars=\\\{\}]
406\PY{c+c1}{\PYZsh{} Exercise: modify this cell to use the print() command}
407\PY{l+m+mi}{2}\PY{o}{+}\PY{l+m+mi}{2}
408\PY{l+m+mi}{2}\PY{o}{/}\PY{l+m+mi}{5}
409\end{Verbatim}
410\end{tcolorbox}
411
412 \begin{tcolorbox}[breakable, size=fbox, boxrule=.5pt, pad at break*=1mm, opacityfill=0]
413\prompt{Out}{outcolor}{2}{\boxspacing}
414\begin{Verbatim}[commandchars=\\\{\}]
4152/5
416\end{Verbatim}
417\end{tcolorbox}
418
419 If you are reading this from Jupyter rather than from the pdf file, you
420can edit the cell above and run it again. You can also add more cells by
421selecting \texttt{Insert} from the menu bar.
422
423Notice that only the last statement produces an output. You can force
424anything to be written as output with the \texttt{print()} command,
425which works like in Python. As an exercise, try to modify the cell above
426to provide more output!
427
428 \hypertarget{markdown}{%
429\subsection{Markdown}\label{markdown}}
430
431\href{https://en.wikipedia.org/wiki/Markdown}{Markdown} is a simple
432markup language - think of LaTeX or html, but much simpler. You can add
433text to your notebook with Markdown cells by selecting
434\texttt{Cell\ \textgreater{}\ Cell\ Type\ \textgreater{}\ Markdown}.
435
436You can also include some LaTeX code in Markdown cells, with dollar
437signs \$ or align environments:
438
439\begin{align*}
440\frac{(x+y)^2}{x+1} = \frac{x^2+y^2}{x+1}
441\end{align*}
442
443When you are done writing a Markdown cell, you can run it to see the
444well-formatted text. To edit the text again, double-click on the cell.
445Try doing it now to fix the formula above!
446
447 \hypertarget{symbolic-expressions}{%
448\section{Symbolic expressions}\label{symbolic-expressions}}
449
450\textbf{Reference:}
451{[}\href{https://doc.sagemath.org/html/en/reference/calculus/sage/symbolic/expression.html}{2}{]}
452
453Now, let's get started with Sage. One thing you might want to do is
454manipulating symbolic expressions, like the following:
455
456 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
457\prompt{In}{incolor}{3}{\boxspacing}
458\begin{Verbatim}[commandchars=\\\{\}]
459\PY{n}{f} \PY{o}{=} \PY{n}{x}\PY{o}{\PYZca{}}\PY{l+m+mi}{2} \PY{o}{+} \PY{l+m+mi}{2}\PY{o}{*}\PY{n}{x} \PY{o}{\PYZhy{}} \PY{l+m+mi}{5} \PY{o}{==} \PY{l+m+mi}{0}
460\PY{n}{solve}\PY{p}{(}\PY{n}{f}\PY{p}{,}\PY{n}{x}\PY{p}{)}
461\end{Verbatim}
462\end{tcolorbox}
463
464 \begin{tcolorbox}[breakable, size=fbox, boxrule=.5pt, pad at break*=1mm, opacityfill=0]
465\prompt{Out}{outcolor}{3}{\boxspacing}
466\begin{Verbatim}[commandchars=\\\{\}]
467[x == -sqrt(6) - 1, x == sqrt(6) - 1]
468\end{Verbatim}
469\end{tcolorbox}
470
471 Notice that the single \texttt{=} is part of an assignment, as in
472Python: we are \emph{assigning} to the variable \texttt{f} the value
473\texttt{x\^{}2\ +\ 2*x\ -\ 5\ \textgreater{}=\ 0}, which in this case is
474an equation, so it contains the symbol \texttt{==}. Keep in mind the
475difference between the two!
476
477\textbf{Exercise:} change the code above to solve the corresponding
478inequality \(x^2+2x-5\geq 0\).
479
480 \hypertarget{mathematical-variables}{%
481\subsection{Mathematical variables}\label{mathematical-variables}}
482
483Last time we saw what \emph{variables} are in Python, and that they are
484a little bit different from the \emph{Mathematical variables} that you
485use in Mathematics. In Sage, both concepts are present, but they are
486still distinct. For example in the cell above \texttt{f} is a variable
487in the sense of computer science, while \texttt{x} is a Mathematical
488variable.
489
490If you want to use Mathematical variables other than \texttt{x}, you
491first need to \emph{declare} them with the \texttt{var()} command:
492
493 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
494\prompt{In}{incolor}{14}{\boxspacing}
495\begin{Verbatim}[commandchars=\\\{\}]
496\PY{n}{var}\PY{p}{(}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{y}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)}
497\PY{n}{solve}\PY{p}{(}\PY{n}{y}\PY{o}{\PYZca{}}\PY{l+m+mi}{2} \PY{o}{+} \PY{p}{(}\PY{n}{x}\PY{o}{+}\PY{l+m+mi}{1}\PY{p}{)}\PY{o}{*}\PY{n}{y} \PY{o}{\PYZhy{}} \PY{l+m+mi}{2} \PY{o}{==} \PY{l+m+mi}{0}\PY{p}{,} \PY{n}{y}\PY{p}{)}
498\end{Verbatim}
499\end{tcolorbox}
500
501 \begin{tcolorbox}[breakable, size=fbox, boxrule=.5pt, pad at break*=1mm, opacityfill=0]
502\prompt{Out}{outcolor}{14}{\boxspacing}
503\begin{Verbatim}[commandchars=\\\{\}]
504[y == -1/2*x - 1/2*sqrt(x\^{}2 + 2*x + 9) - 1/2, y == -1/2*x + 1/2*sqrt(x\^{}2 + 2*x +
5059) - 1/2]
506\end{Verbatim}
507\end{tcolorbox}
508
509 Try removing the first line in the cell above and see what error you
510get!
511
512Here is another example:
513
514 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
515\prompt{In}{incolor}{16}{\boxspacing}
516\begin{Verbatim}[commandchars=\\\{\}]
517\PY{n}{var}\PY{p}{(}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{a}\PY{l+s+s1}{\PYZsq{}}\PY{p}{,} \PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{b}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)}
518\PY{n}{f} \PY{o}{=} \PY{n}{x}\PY{o}{\PYZca{}}\PY{l+m+mi}{2}\PY{o}{+}\PY{n}{a}\PY{o}{*}\PY{n}{x}\PY{o}{+}\PY{n}{b}
519\PY{n}{solve}\PY{p}{(}\PY{n}{f}\PY{p}{,}\PY{n}{x}\PY{p}{)}
520\end{Verbatim}
521\end{tcolorbox}
522
523 \begin{tcolorbox}[breakable, size=fbox, boxrule=.5pt, pad at break*=1mm, opacityfill=0]
524\prompt{Out}{outcolor}{16}{\boxspacing}
525\begin{Verbatim}[commandchars=\\\{\}]
526[x == -1/2*a - 1/2*sqrt(a\^{}2 - 4*b), x == -1/2*a + 1/2*sqrt(a\^{}2 - 4*b)]
527\end{Verbatim}
528\end{tcolorbox}
529
530 Some common constants are
531\href{https://doc.sagemath.org/html/en/reference/calculus/sage/symbolic/expression.html}{already
532defined} in Sage:
533
534 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
535\prompt{In}{incolor}{17}{\boxspacing}
536\begin{Verbatim}[commandchars=\\\{\}]
537\PY{n}{e}\PY{o}{\PYZca{}}\PY{p}{(}\PY{n}{pi}\PY{o}{*}\PY{n}{I}\PY{p}{)}
538\end{Verbatim}
539\end{tcolorbox}
540
541 \begin{tcolorbox}[breakable, size=fbox, boxrule=.5pt, pad at break*=1mm, opacityfill=0]
542\prompt{Out}{outcolor}{17}{\boxspacing}
543\begin{Verbatim}[commandchars=\\\{\}]
544-1
545\end{Verbatim}
546\end{tcolorbox}
547
548 We will study symbolic expressions more in detail next time, in the
549context of calculus/analysis.
550
551 \hypertarget{basic-rings-and-fields}{%
552\section{Basic rings and fields}\label{basic-rings-and-fields}}
553
554\textbf{References:}
555{[}\href{https://doc.sagemath.org/html/en/reference/rings_standard/index.html}{3}{]}
556{[}\href{https://doc.sagemath.org/html/en/reference/rings_numerical/index.html}{4}{]}
557{[}\href{https://doc.sagemath.org/html/en/reference/finite_rings/index.html}{5}{]}
558
559As you should know, a \emph{field} is a Mathematical structure with two
560operations, addition and multiplication, which respect certain rules
561(distributivity, associativity, commutativity\ldots). Some examples of
562fields are the Rational numbers \(\mathbb Q\), the Real numbers
563\(\mathbb R\) and the Complex numbers \(\mathbb C\), but there are many
564more. As you should also know, a \emph{(commutative) ring} is like a
565field, except not all elements different from \(0\) need have a
566multiplicative inverse. For example the integers
567\(\mathbb Z = \{ \dots, -1, 0, 1, 2, \dots\}\) are a ring, but not a
568field.
569
570These structures are already implemented in Sage. Some of the most
571common are listed in the following table:
572
573\begin{longtable}[]{@{}rcl@{}}
574\toprule
575Mathematical object & Math symbol & Sage name \\
576\midrule
577\endhead
578Integers & \(\mathbb Z\) & \texttt{ZZ} \\
579Rational numbers & \(\mathbb Q\) & \texttt{QQ} \\
580Real numbers & \(\mathbb R\) & \texttt{RR} \\
581Complex numbers & \(\mathbb C\) & \texttt{CC} \\
582Integers modulo \(n\) & \(\mathbb Z/n\mathbb Z\) &
583\texttt{Integers(n)} \\
584Finite fields & \(\mathbb F_p\) & GF(p) \\
585\(\dots\) & \(\dots\) & \(\dots\) \\
586\bottomrule
587\end{longtable}
588
589 If you write a number or an expression, Sage will figure out where it
590``lives'', choosing the most restrictive interpretation possible. For
591example \texttt{3} will be interpreted to be an integer, even if it is
592also a rational number, a real number and a complex number.
593
594 \hypertarget{parents-and-coercion}{%
595\subsection{Parents and coercion}\label{parents-and-coercion}}
596
597\textbf{Reference:}
598{[}\href{https://doc.sagemath.org/html/en/tutorial/tour_coercion.html}{6}{]}
599
600You can check where an object ``lives'' with the \texttt{parent()}
601command. It works more or less like the Python command \texttt{type()},
602but it gives a more Mathematically inclined answer. Check the reference
603link {[}6{]} above if you want more details.
604
605 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
606\prompt{In}{incolor}{18}{\boxspacing}
607\begin{Verbatim}[commandchars=\\\{\}]
608\PY{c+c1}{\PYZsh{}Edit this cell to find out the type of other objects that we used}
609\PY{n}{parent}\PY{p}{(}\PY{l+m+mi}{3}\PY{o}{/}\PY{l+m+mi}{5}\PY{p}{)}
610\end{Verbatim}
611\end{tcolorbox}
612
613 \begin{tcolorbox}[breakable, size=fbox, boxrule=.5pt, pad at break*=1mm, opacityfill=0]
614\prompt{Out}{outcolor}{18}{\boxspacing}
615\begin{Verbatim}[commandchars=\\\{\}]
616Rational Field
617\end{Verbatim}
618\end{tcolorbox}
619
620 Sometimes Sage does not give you the best possible interpretation, so
621you can force something to be interpreted as living in a smaller ring as
622follows:
623
624 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
625\prompt{In}{incolor}{4}{\boxspacing}
626\begin{Verbatim}[commandchars=\\\{\}]
627\PY{n}{minus\PYZus{}one} \PY{o}{=} \PY{n}{e}\PY{o}{\PYZca{}}\PY{p}{(}\PY{n}{pi}\PY{o}{*}\PY{n}{I}\PY{p}{)}
628\PY{n}{minus\PYZus{}one\PYZus{}coerced} \PY{o}{=} \PY{n}{ZZ}\PY{p}{(}\PY{n}{e}\PY{o}{\PYZca{}}\PY{p}{(}\PY{n}{pi}\PY{o}{*}\PY{n}{I}\PY{p}{)}\PY{p}{)} \PY{c+c1}{\PYZsh{} coercion}
629\PY{n+nb}{print}\PY{p}{(}\PY{n}{parent}\PY{p}{(}\PY{n}{minus\PYZus{}one}\PY{p}{)}\PY{p}{)}
630\PY{n+nb}{print}\PY{p}{(}\PY{n}{parent}\PY{p}{(}\PY{n}{minus\PYZus{}one\PYZus{}coerced}\PY{p}{)}\PY{p}{)}
631\end{Verbatim}
632\end{tcolorbox}
633
634 \begin{Verbatim}[commandchars=\\\{\}]
635Symbolic Ring
636Integer Ring
637 \end{Verbatim}
638
639 \textbf{Remark.} Notice that there is a fundamental difference between
640the rings \texttt{RR} and \texttt{CC} and all the others in the table
641above: the real and complex numbers are \emph{approximated}.
642
643 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
644\prompt{In}{incolor}{1}{\boxspacing}
645\begin{Verbatim}[commandchars=\\\{\}]
646\PY{n+nb}{print}\PY{p}{(}\PY{n}{QQ}\PY{p}{(}\PY{l+m+mi}{3}\PY{p}{)}\PY{p}{)}
647\PY{n+nb}{print}\PY{p}{(}\PY{n}{RR}\PY{p}{(}\PY{l+m+mi}{3}\PY{p}{)}\PY{p}{)}
648\end{Verbatim}
649\end{tcolorbox}
650
651 \begin{Verbatim}[commandchars=\\\{\}]
6523
6533.00000000000000
654 \end{Verbatim}
655
656 You can also choose the precision of this approximation using the
657alternative name \texttt{RealField}.
658
659 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
660\prompt{In}{incolor}{4}{\boxspacing}
661\begin{Verbatim}[commandchars=\\\{\}]
662\PY{n+nb}{print}\PY{p}{(}\PY{n}{RR}\PY{p}{)}
663\PY{n+nb}{print}\PY{p}{(}\PY{n}{RealField}\PY{p}{(}\PY{n}{prec}\PY{o}{=}\PY{l+m+mi}{1000}\PY{p}{)}\PY{p}{)}
664\end{Verbatim}
665\end{tcolorbox}
666
667 \begin{Verbatim}[commandchars=\\\{\}]
668Real Field with 53 bits of precision
669Real Field with 1000 bits of precision
670 \end{Verbatim}
671
672 \hypertarget{polynomial-rings}{%
673\section{Polynomial rings}\label{polynomial-rings}}
674
675\textbf{Reference:}
676{[}\href{https://doc.sagemath.org/html/en/reference/polynomial_rings/index.html}{7}{]}
677
678If you want to work with polynomials over a certain ring it is better to
679use this specific construction, rather than the symbolic expressions
680introduced above.
681
682 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
683\prompt{In}{incolor}{5}{\boxspacing}
684\begin{Verbatim}[commandchars=\\\{\}]
685\PY{n}{polring}\PY{o}{.}\PY{o}{\PYZlt{}}\PY{n}{x}\PY{p}{,}\PY{n}{y}\PY{p}{,}\PY{n}{z}\PY{o}{\PYZgt{}} \PY{o}{=} \PY{n}{RR}\PY{p}{[}\PY{p}{]} \PY{c+c1}{\PYZsh{} Alternative: polring.\PYZlt{}x,y,z\PYZgt{} = PolynomialRing(RR)}
686\PY{n}{polring}
687\end{Verbatim}
688\end{tcolorbox}
689
690 \begin{tcolorbox}[breakable, size=fbox, boxrule=.5pt, pad at break*=1mm, opacityfill=0]
691\prompt{Out}{outcolor}{5}{\boxspacing}
692\begin{Verbatim}[commandchars=\\\{\}]
693Multivariate Polynomial Ring in x, y, z over Real Field with 53 bits of
694precision
695\end{Verbatim}
696\end{tcolorbox}
697
698 You can use as many variables as you like, and you can replace
699\texttt{RR} with any ring. In the example above \texttt{polring} is just
700the name of the variable (in the computer science sense) associated with
701this polynomial ring.
702
703\hypertarget{operations-on-polynomials}{%
704\subsection{Operations on polynomials}\label{operations-on-polynomials}}
705
706The usual Mathematical operations are available on polynomial rings,
707including Euclidean division \texttt{//} and remainder \texttt{\%}.
708There is also the single-slash division \texttt{/}, but the result may
709not be a polynomial anymore.
710
711\textbf{Exercise:} use the \texttt{parent()} command to find out what
712the quotient of two polynomials is.
713
714\textbf{Question:} what happens if you remove the first line in the cell
715below? What if we used the variable \texttt{y} instead of \texttt{x}?
716
717 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
718\prompt{In}{incolor}{6}{\boxspacing}
719\begin{Verbatim}[commandchars=\\\{\}]
720\PY{n}{polring}\PY{o}{.}\PY{o}{\PYZlt{}}\PY{n}{x}\PY{o}{\PYZgt{}} \PY{o}{=} \PY{n}{QQ}\PY{p}{[}\PY{p}{]}
721\PY{n}{p} \PY{o}{=} \PY{n}{x}\PY{o}{\PYZca{}}\PY{l+m+mi}{2} \PY{o}{+} \PY{l+m+mi}{2}\PY{o}{*}\PY{n}{x} \PY{o}{\PYZhy{}} \PY{l+m+mi}{3} \PY{c+c1}{\PYZsh{} Don\PYZsq{}t forget * for multiplication!}
722\PY{n}{q} \PY{o}{=} \PY{n}{p} \PY{o}{/}\PY{o}{/} \PY{p}{(}\PY{n}{x}\PY{o}{+}\PY{l+m+mi}{1}\PY{p}{)}
723\PY{n}{r} \PY{o}{=} \PY{n}{p} \PY{o}{\PYZpc{}} \PY{p}{(}\PY{n}{x}\PY{o}{+}\PY{l+m+mi}{1}\PY{p}{)}
724\PY{n}{f} \PY{o}{=} \PY{n}{p} \PY{o}{/} \PY{p}{(}\PY{n}{x}\PY{o}{+}\PY{l+m+mi}{1}\PY{p}{)}
725\PY{n+nb}{print}\PY{p}{(}\PY{n}{q}\PY{p}{)}
726\PY{n+nb}{print}\PY{p}{(}\PY{n}{r}\PY{p}{)}
727\PY{n+nb}{print}\PY{p}{(}\PY{n}{f}\PY{p}{)}
728\end{Verbatim}
729\end{tcolorbox}
730
731 \begin{Verbatim}[commandchars=\\\{\}]
732x + 1
733-4
734(x\^{}2 + 2*x - 3)/(x + 1)
735 \end{Verbatim}
736
737 You can do more complex operations. Try out \texttt{roots()} and
738\texttt{factor} in the cell below.
739
740\textbf{Remark.} Notice how the result can change substantially if you
741change the base ring.
742
743\textbf{Remark.}
744\href{https://doc.sagemath.org/html/en/reference/structure/sage/structure/factorization.html}{Factorizations}
745are a particular object in Sage. They are kinda like a list, but not
746really. You can get a list of pairs (factor, power) with
747\texttt{list(factor(f))}.
748
749 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
750\prompt{In}{incolor}{7}{\boxspacing}
751\begin{Verbatim}[commandchars=\\\{\}]
752\PY{n}{polring\PYZus{}onevar}\PY{o}{.}\PY{o}{\PYZlt{}}\PY{n}{t}\PY{o}{\PYZgt{}} \PY{o}{=} \PY{n}{QQ}\PY{p}{[}\PY{p}{]}
753
754\PY{n}{f} \PY{o}{=} \PY{n}{t}\PY{o}{\PYZca{}}\PY{l+m+mi}{5} \PY{o}{+} \PY{n}{t}\PY{o}{\PYZca{}}\PY{l+m+mi}{4} \PY{o}{\PYZhy{}} \PY{l+m+mi}{2}\PY{o}{*}\PY{n}{t}\PY{o}{\PYZca{}}\PY{l+m+mi}{3} \PY{o}{\PYZhy{}} \PY{l+m+mi}{2}\PY{o}{*}\PY{n}{t}\PY{o}{\PYZca{}}\PY{l+m+mi}{2} \PY{o}{\PYZhy{}} \PY{l+m+mi}{3}\PY{o}{*}\PY{n}{t} \PY{o}{\PYZhy{}} \PY{l+m+mi}{3}
755\PY{n+nb}{print}\PY{p}{(}\PY{n}{factor}\PY{p}{(}\PY{n}{f}\PY{p}{)}\PY{p}{)}
756\PY{n+nb}{print}\PY{p}{(}\PY{n}{f}\PY{o}{.}\PY{n}{roots}\PY{p}{(}\PY{p}{)}\PY{p}{)} \PY{c+c1}{\PYZsh{} Result: list of pairs (root,multiplicity)}
757
758\PY{n}{polring\PYZus{}manyvar}\PY{o}{.}\PY{o}{\PYZlt{}}\PY{n}{x}\PY{p}{,}\PY{n}{y}\PY{p}{,}\PY{n}{z}\PY{o}{\PYZgt{}} \PY{o}{=} \PY{n}{QQ}\PY{p}{[}\PY{p}{]}
759\PY{n}{factor}\PY{p}{(}\PY{n}{x}\PY{o}{*}\PY{n}{y}\PY{o}{+}\PY{n}{x}\PY{p}{)}
760
761\PY{c+c1}{\PYZsh{} The following line gives an error, because the polynomial}
762\PY{c+c1}{\PYZsh{} is understood to possibly have many variables:}
763\PY{c+c1}{\PYZsh{}(x\PYZca{}2\PYZhy{}1).roots()}
764\end{Verbatim}
765\end{tcolorbox}
766
767 \begin{Verbatim}[commandchars=\\\{\}]
768(t + 1) * (t\^{}2 - 3) * (t\^{}2 + 1)
769[(-1, 1)]
770 \end{Verbatim}
771
772 \begin{tcolorbox}[breakable, size=fbox, boxrule=.5pt, pad at break*=1mm, opacityfill=0]
773\prompt{Out}{outcolor}{7}{\boxspacing}
774\begin{Verbatim}[commandchars=\\\{\}]
775(y + 1) * x
776\end{Verbatim}
777\end{tcolorbox}
778
779 \hypertarget{matrices-and-vectors}{%
780\section{Matrices and vectors}\label{matrices-and-vectors}}
781
782\textbf{References:}
783{[}\href{https://doc.sagemath.org/html/en/reference/matrices/index.html}{8}{]},
784but in particular the subections
785{[}\href{https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/docs.html}{9}{]}
786and
787{[}\href{https://doc.sagemath.org/html/en/reference/matrices/sage/matrix/matrix2.html}{10}{]}
788
789In Sage you can easily manipulate matrices and vectors
790
791 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
792\prompt{In}{incolor}{77}{\boxspacing}
793\begin{Verbatim}[commandchars=\\\{\}]
794\PY{n}{A} \PY{o}{=} \PY{n}{matrix}\PY{p}{(}\PY{p}{[}\PY{p}{[}\PY{l+m+mi}{1}\PY{p}{,}\PY{l+m+mi}{2}\PY{p}{,}\PY{l+m+mi}{3}\PY{p}{]}\PY{p}{,}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{,}\PY{l+m+mi}{1}\PY{p}{]}\PY{p}{,}\PY{p}{[}\PY{l+m+mi}{4}\PY{p}{,}\PY{o}{\PYZhy{}}\PY{l+m+mi}{3}\PY{p}{,}\PY{l+m+mi}{22}\PY{o}{/}\PY{l+m+mi}{7}\PY{p}{]}\PY{p}{]}\PY{p}{)}
795\PY{n}{B} \PY{o}{=} \PY{n}{matrix}\PY{p}{(}\PY{p}{[}\PY{p}{[}\PY{l+m+mi}{1}\PY{o}{/}\PY{l+m+mi}{2}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{]}\PY{p}{,}\PY{p}{[}\PY{l+m+mi}{7}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{]}\PY{p}{,}\PY{p}{[}\PY{l+m+mi}{1}\PY{p}{,}\PY{l+m+mi}{1}\PY{p}{,}\PY{l+m+mi}{1}\PY{p}{]}\PY{p}{]}\PY{p}{)}
796\PY{n}{v} \PY{o}{=} \PY{n}{vector}\PY{p}{(}\PY{p}{[}\PY{l+m+mi}{3}\PY{p}{,}\PY{l+m+mi}{4}\PY{p}{,}\PY{o}{\PYZhy{}}\PY{l+m+mi}{1}\PY{p}{]}\PY{p}{)}
797
798\PY{n+nb}{print}\PY{p}{(}\PY{n}{A}\PY{p}{,} \PY{l+s+s2}{\PYZdq{}}\PY{l+s+se}{\PYZbs{}n}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)} \PY{c+c1}{\PYZsh{} \PYZbs{}n just means \PYZdq{}newline\PYZdq{}}
799\PY{n+nb}{print}\PY{p}{(}\PY{n}{B}\PY{p}{,} \PY{l+s+s2}{\PYZdq{}}\PY{l+s+se}{\PYZbs{}n}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)}
800\PY{n+nb}{print}\PY{p}{(}\PY{n}{B}\PY{o}{*}\PY{n}{v}\PY{p}{,} \PY{l+s+s2}{\PYZdq{}}\PY{l+s+se}{\PYZbs{}n}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)}
801\PY{n+nb}{print}\PY{p}{(}\PY{n}{A}\PY{o}{\PYZca{}}\PY{l+m+mi}{2} \PY{o}{+} \PY{l+m+mi}{2}\PY{o}{*}\PY{n}{B} \PY{o}{\PYZhy{}} \PY{n}{A}\PY{o}{*}\PY{n}{B}\PY{p}{,} \PY{l+s+s2}{\PYZdq{}}\PY{l+s+se}{\PYZbs{}n}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)}
802
803\PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Rank of A =}\PY{l+s+s2}{\PYZdq{}}\PY{p}{,} \PY{n}{rank}\PY{p}{(}\PY{n}{A}\PY{p}{)}\PY{p}{)} \PY{c+c1}{\PYZsh{} You can also use A.rank()}
804\PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Rank of B =}\PY{l+s+s2}{\PYZdq{}}\PY{p}{,} \PY{n}{rank}\PY{p}{(}\PY{n}{B}\PY{p}{)}\PY{p}{)}
805\end{Verbatim}
806\end{tcolorbox}
807
808 \begin{Verbatim}[commandchars=\\\{\}]
809[ 1 2 3]
810[ 0 0 1]
811[ 4 -3 22/7]
812
813[1/2 0 0]
814[ 7 0 0]
815[ 1 1 1]
816
817(3/2, 21, 6)
818
819[ -7/2 -10 80/7]
820[ 17 -4 15/7]
821[ 241/7 -18/7 869/49]
822
823Rank of A = 3
824Rank of B = 2
825 \end{Verbatim}
826
827 \textbf{Exercise:} in the cell above, compute the determinant, inverse
828and characteristic polynomial of the matrix \texttt{A}. \emph{Hint: look
829at the reference {[}10{]} above (the functions are listed in alphabetic
830order).}
831
832As for polynomials, you can specify where a matrix or a vector lives
833
834 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
835\prompt{In}{incolor}{57}{\boxspacing}
836\begin{Verbatim}[commandchars=\\\{\}]
837\PY{n}{M} \PY{o}{=} \PY{n}{matrix}\PY{p}{(}\PY{n}{CC}\PY{p}{,} \PY{p}{[}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{,}\PY{l+m+mi}{1}\PY{p}{]}\PY{p}{,}\PY{p}{[}\PY{l+m+mi}{1}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{]}\PY{p}{]}\PY{p}{)}
838\PY{n}{parent}\PY{p}{(}\PY{n}{M}\PY{p}{)}
839\end{Verbatim}
840\end{tcolorbox}
841
842 \begin{tcolorbox}[breakable, size=fbox, boxrule=.5pt, pad at break*=1mm, opacityfill=0]
843\prompt{Out}{outcolor}{57}{\boxspacing}
844\begin{Verbatim}[commandchars=\\\{\}]
845Full MatrixSpace of 2 by 2 dense matrices over Complex Field with 53 bits of
846precision
847\end{Verbatim}
848\end{tcolorbox}
849
850 You can also solve linear systems and compute eigenvalues and
851eigenvectors of a matrix
852
853\textbf{Warning.} In linear algebra there are distinct concepts of
854\emph{left} and \emph{right} eigenvalues (and eigenvector). The one you
855know is probably that of \textbf{right} eigen-\{value,vector\}, that is
856an element \(\lambda\) of the base field and a non-zero vector
857\(\mathbf v\) with \(A\mathbf v=\lambda\mathbf v\). The other concept
858corresponds to the equality \(\mathbf v^TA=\lambda \mathbf v\).
859
860 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
861\prompt{In}{incolor}{60}{\boxspacing}
862\begin{Verbatim}[commandchars=\\\{\}]
863\PY{n}{A} \PY{o}{=} \PY{n}{Matrix}\PY{p}{(}\PY{n}{RR}\PY{p}{,} \PY{p}{[}\PY{p}{[}\PY{n}{sqrt}\PY{p}{(}\PY{l+m+mi}{59}\PY{p}{)}\PY{p}{,}\PY{l+m+mi}{32}\PY{p}{]}\PY{p}{,}\PY{p}{[}\PY{o}{\PYZhy{}}\PY{l+m+mi}{1}\PY{o}{/}\PY{l+m+mi}{4}\PY{p}{,}\PY{l+m+mi}{3}\PY{p}{]}\PY{p}{]}\PY{p}{)}
864\PY{n}{v} \PY{o}{=} \PY{n}{vector}\PY{p}{(}\PY{n}{RR}\PY{p}{,} \PY{p}{[}\PY{l+m+mi}{3}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{]}\PY{p}{)}
865\PY{n}{A}\PY{o}{.}\PY{n}{solve\PYZus{}right}\PY{p}{(}\PY{n}{v}\PY{p}{)} \PY{c+c1}{\PYZsh{} Solve Ax=v. Alternative: A \PYZbs{} v}
866\end{Verbatim}
867\end{tcolorbox}
868
869 \begin{tcolorbox}[breakable, size=fbox, boxrule=.5pt, pad at break*=1mm, opacityfill=0]
870\prompt{Out}{outcolor}{60}{\boxspacing}
871\begin{Verbatim}[commandchars=\\\{\}]
872(0.289916349448506, 0.0241596957873755)
873\end{Verbatim}
874\end{tcolorbox}
875
876 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
877\prompt{In}{incolor}{64}{\boxspacing}
878\begin{Verbatim}[commandchars=\\\{\}]
879\PY{n}{A} \PY{o}{=} \PY{n}{Matrix}\PY{p}{(}\PY{n}{QQ}\PY{p}{,} \PY{p}{[}\PY{p}{[}\PY{l+m+mi}{1}\PY{p}{,}\PY{l+m+mi}{2}\PY{p}{]}\PY{p}{,}\PY{p}{[}\PY{l+m+mi}{3}\PY{p}{,}\PY{l+m+mi}{4}\PY{p}{]}\PY{p}{]}\PY{p}{)}
880\PY{n}{A}\PY{o}{.}\PY{n}{eigenspaces\PYZus{}right}\PY{p}{(}\PY{p}{)} \PY{c+c1}{\PYZsh{} Also: A.eigenvalues(), A.eigenvectors\PYZus{}right()}
881\end{Verbatim}
882\end{tcolorbox}
883
884 \begin{tcolorbox}[breakable, size=fbox, boxrule=.5pt, pad at break*=1mm, opacityfill=0]
885\prompt{Out}{outcolor}{64}{\boxspacing}
886\begin{Verbatim}[commandchars=\\\{\}]
887[
888(-0.3722813232690144?, Vector space of degree 2 and dimension 1 over Algebraic
889Field
890User basis matrix:
891[ 1 -0.6861406616345072?]),
892(5.372281323269015?, Vector space of degree 2 and dimension 1 over Algebraic
893Field
894User basis matrix:
895[ 1 2.186140661634508?])
896]
897\end{Verbatim}
898\end{tcolorbox}
899
900 We can also extract a specific submatrix by selecting only some rows and
901columns, with a syntax similar to that of Python's lists. Check out more
902examples in the reference {[}9{]} above, and try them in the cell below.
903
904 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
905\prompt{In}{incolor}{94}{\boxspacing}
906\begin{Verbatim}[commandchars=\\\{\}]
907\PY{n}{A} \PY{o}{=} \PY{n}{MatrixSpace}\PY{p}{(}\PY{n}{ZZ}\PY{p}{,} \PY{l+m+mi}{7}\PY{p}{)}\PY{o}{.}\PY{n}{random\PYZus{}element}\PY{p}{(}\PY{p}{)}
908\PY{n+nb}{print}\PY{p}{(}\PY{n}{A}\PY{p}{,} \PY{l+s+s2}{\PYZdq{}}\PY{l+s+se}{\PYZbs{}n}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)}
909\PY{n+nb}{print}\PY{p}{(}\PY{n}{A}\PY{p}{[}\PY{l+m+mi}{1}\PY{p}{:}\PY{l+m+mi}{3}\PY{p}{,}\PY{l+m+mi}{2}\PY{p}{:}\PY{l+m+mi}{5}\PY{p}{]}\PY{p}{,} \PY{l+s+s2}{\PYZdq{}}\PY{l+s+se}{\PYZbs{}n}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)} \PY{c+c1}{\PYZsh{} Rows from 1 to 3, columns from 2 to 5}
910\PY{n+nb}{print}\PY{p}{(}\PY{n}{A}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{:}\PY{p}{]}\PY{p}{,} \PY{l+s+s2}{\PYZdq{}}\PY{l+s+se}{\PYZbs{}n}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)} \PY{c+c1}{\PYZsh{} First row, all columns}
911\PY{n+nb}{print}\PY{p}{(}\PY{n}{A}\PY{p}{[}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{,}\PY{l+m+mi}{5}\PY{p}{,}\PY{l+m+mi}{2}\PY{p}{]}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{:}\PY{l+m+mi}{5}\PY{p}{]}\PY{p}{)} \PY{c+c1}{\PYZsh{} Rows 0, 5 and 2 (in this order) and columns 0 to 5}
912\end{Verbatim}
913\end{tcolorbox}
914
915 \begin{Verbatim}[commandchars=\\\{\}]
916[-14 2 0 -1 1 -2 -1]
917[ 0 -8 0 9 -2 11 1]
918[ 0 3 1 -1 1 1 221]
919[ -1 2 1 -25 -10 4 0]
920[ -3 0 0 2 16 -1 -2]
921[ 1 -3 3 -41 1 0 0]
922[ -2 1 0 0 -6 2 12]
923
924[ 0 9 -2]
925[ 1 -1 1]
926
927[-14 2 0 -1 1 -2 -1]
928
929[-14 2 0 -1 1]
930[ 1 -3 3 -41 1]
931[ 0 3 1 -1 1]
932 \end{Verbatim}
933
934 \textbf{Exercise:} write a sage function that computes the determinant
935of an \(n\times n\) matrix \(A=(a_{ij})\) using Laplace's rule by the
936first row, that is \begin{align*}
937 \operatorname{det}A = \sum_{j=1}^n (-1)^ja_{0j}M_{0j}
938\end{align*} where \(M_{0j}\) is the determinant of the
939\((n-1)\times(n-1)\) matrix obtained by removing the \(0\)-th row and
940the \(j\)-th column from \(A\).
941
942 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
943\prompt{In}{incolor}{91}{\boxspacing}
944\begin{Verbatim}[commandchars=\\\{\}]
945\PY{k}{def} \PY{n+nf}{my\PYZus{}det}\PY{p}{(}\PY{n}{A}\PY{p}{)}\PY{p}{:}
946 \PY{k}{if} \PY{o+ow}{not} \PY{n}{A}\PY{o}{.}\PY{n}{is\PYZus{}square}\PY{p}{(}\PY{p}{)}\PY{p}{:}
947 \PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Error: matrix is not square}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)}
948
949 \PY{n}{n} \PY{o}{=} \PY{n}{A}\PY{o}{.}\PY{n}{nrows}\PY{p}{(}\PY{p}{)} \PY{c+c1}{\PYZsh{} size of the matrix}
950
951 \PY{c+c1}{\PYZsh{} Continue from here!}
952\end{Verbatim}
953\end{tcolorbox}
954
955 \hypertarget{number-theory}{%
956\section{Number Theory}\label{number-theory}}
957
958\textbf{Reference:}
959{[}\href{https://doc.sagemath.org/html/en/reference/rings_standard/sage/rings/integer.html}{11}{]}
960
961Sage includes a large library of functions for computing with the
962integers, see the link above.
963
964 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
965\prompt{In}{incolor}{8}{\boxspacing}
966\begin{Verbatim}[commandchars=\\\{\}]
967\PY{n}{n} \PY{o}{=} \PY{l+m+mi}{123456789}
968\PY{n}{m} \PY{o}{=} \PY{l+m+mi}{987654321}
969\PY{n}{p} \PY{o}{=} \PY{l+m+mi}{3607}
970
971\PY{n+nb}{print}\PY{p}{(}\PY{n}{factor}\PY{p}{(}\PY{n}{n}\PY{p}{)}\PY{p}{)}
972\PY{n+nb}{print}\PY{p}{(}\PY{n}{is\PYZus{}prime}\PY{p}{(}\PY{n}{p}\PY{p}{)}\PY{p}{)}
973\PY{n+nb}{print}\PY{p}{(}\PY{n}{p}\PY{o}{.}\PY{n}{divides}\PY{p}{(}\PY{n}{n}\PY{p}{)}\PY{p}{)}
974\PY{n+nb}{print}\PY{p}{(}\PY{n}{euler\PYZus{}phi}\PY{p}{(}\PY{n}{m}\PY{p}{)}\PY{p}{)}
975\PY{n+nb}{print}\PY{p}{(}\PY{n}{gcd}\PY{p}{(}\PY{n}{n}\PY{p}{,} \PY{n}{m}\PY{p}{)}\PY{p}{)}
976\PY{n+nb}{print}\PY{p}{(}\PY{n}{lcm}\PY{p}{(}\PY{n}{n}\PY{p}{,} \PY{n}{m}\PY{p}{)}\PY{p}{)}
977\end{Verbatim}
978\end{tcolorbox}
979
980 \begin{Verbatim}[commandchars=\\\{\}]
9813\^{}2 * 3607 * 3803
982True
983True
984619703040
9859
98613548070123626141
987 \end{Verbatim}
988
989 \hypertarget{primes}{%
990\subsection{Primes}\label{primes}}
991
992\textbf{Reference:}
993{[}\href{https://doc.sagemath.org/html/en/reference/sets/sage/sets/primes.html}{12}{]}
994
995The set of prime numbers is called \texttt{Primes()}. It is like an
996infinite list: for example you can get the one-millionth prime number or
997you can use this list to create other lists. You can also check what the
998first prime number larger than a given number is.
999
1000 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
1001\prompt{In}{incolor}{9}{\boxspacing}
1002\begin{Verbatim}[commandchars=\\\{\}]
1003\PY{n}{PP} \PY{o}{=} \PY{n}{Primes}\PY{p}{(}\PY{p}{)}
1004\PY{n+nb}{print}\PY{p}{(}\PY{n}{PP}\PY{p}{)}
1005\PY{n+nb}{print}\PY{p}{(}\PY{n}{PP}\PY{p}{[}\PY{l+m+mi}{10}\PY{p}{]}\PY{p}{,} \PY{n}{PP}\PY{p}{[}\PY{l+m+mi}{10}\PY{o}{\PYZca{}}\PY{l+m+mi}{6}\PY{p}{]}\PY{p}{)}
1006\PY{n+nb}{print}\PY{p}{(}\PY{n}{PP}\PY{o}{.}\PY{n}{next}\PY{p}{(}\PY{l+m+mi}{44}\PY{p}{)}\PY{p}{)}
1007
1008\PY{n}{First\PYZus{}Thousand\PYZus{}Primes} \PY{o}{=} \PY{n}{PP}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{:}\PY{l+m+mi}{1000}\PY{p}{]}
1009\PY{n+nb}{print}\PY{p}{(}\PY{p}{[}\PY{n}{p} \PY{k}{for} \PY{n}{p} \PY{o+ow}{in} \PY{n}{First\PYZus{}Thousand\PYZus{}Primes} \PY{k}{if} \PY{n}{p} \PY{o}{\PYZlt{}} \PY{l+m+mi}{100} \PY{o+ow}{and} \PY{n}{p} \PY{o}{\PYZgt{}} \PY{l+m+mi}{75}\PY{p}{]}\PY{p}{)}
1010\end{Verbatim}
1011\end{tcolorbox}
1012
1013 \begin{Verbatim}[commandchars=\\\{\}]
1014Set of all prime numbers: 2, 3, 5, 7, {\ldots}
101531 15485867
101647
1017[79, 83, 89, 97]
1018 \end{Verbatim}
1019
1020 \hypertarget{the-chinese-remainder-theorem-crt}{%
1021\subsection{The Chinese remainder theorem
1022(CRT)}\label{the-chinese-remainder-theorem-crt}}
1023
1024We say that two integers \(a\) and \(b\) are \emph{congruent} modulo
1025another integer \(n>0\) if they have the same remainder when divided by
1026\(n\). We denote this by \(a\equiv b\pmod n\), or in Python/Sage syntax
1027\texttt{a\ \%\ n\ ==\ b\ \%\ n}.
1028
1029The Chinese remainder theorem states that if \(a,b\in\mathbb Z\) and
1030\(n,m\in \mathbb Z_{>0}\) are such that \(\gcd(n,m)=1\) then the system
1031of congruences
1032
1033\begin{align*}
1034\begin{cases}
1035 x \equiv a \pmod n\\
1036 x \equiv b \pmod m
1037\end{cases}
1038\end{align*}
1039
1040has exactly one solution modulo \(mn\). This means that there is one and
1041only one number \(x\) with \(0\leq x<mn\) such that \(x\equiv a\pmod n\)
1042and \(x\equiv b\pmod m\).
1043
1044The procedure to find such a number is not too hard to describe (you
1045might see it in an algebra or number theory course), but it can be a bit
1046long. Luckily, Sage can do this for you:
1047
1048 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
1049\prompt{In}{incolor}{10}{\boxspacing}
1050\begin{Verbatim}[commandchars=\\\{\}]
1051\PY{n}{a} \PY{o}{=} \PY{l+m+mi}{2}
1052\PY{n}{b} \PY{o}{=} \PY{o}{\PYZhy{}}\PY{l+m+mi}{1}
1053\PY{n}{n} \PY{o}{=} \PY{l+m+mi}{172}
1054\PY{n}{m} \PY{o}{=} \PY{l+m+mi}{799}
1055
1056\PY{k}{if} \PY{n}{gcd}\PY{p}{(}\PY{n}{n}\PY{p}{,}\PY{n}{m}\PY{p}{)} \PY{o}{!=} \PY{l+m+mi}{1}\PY{p}{:}
1057 \PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{The numbers are not comprime, I can}\PY{l+s+s2}{\PYZsq{}}\PY{l+s+s2}{t solve this!}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)}
1058\PY{k}{else}\PY{p}{:}
1059 \PY{n}{x} \PY{o}{=} \PY{n}{crt}\PY{p}{(}\PY{n}{a}\PY{p}{,} \PY{n}{b}\PY{p}{,} \PY{n}{n}\PY{p}{,} \PY{n}{m}\PY{p}{)}
1060 \PY{n+nb}{print}\PY{p}{(}\PY{n}{x}\PY{p}{,} \PY{n}{x}\PY{o}{\PYZpc{}}\PY{k}{n}, x\PYZpc{}m)
1061\end{Verbatim}
1062\end{tcolorbox}
1063
1064 \begin{Verbatim}[commandchars=\\\{\}]
106574306 2 798
1066 \end{Verbatim}
1067
1068 \textbf{Exercise.} There is a more general version of the Chinese
1069remainder theorem which says that if
1070\(a_0, a_1, \dots, a_k\in\mathbb Z\) and
1071\(n_0, n_2, \dots, n_k\in\mathbb Z_{>0}\) are such that
1072\(\gcd(n_i, n_j)=1\) for \(i\neq j\), then the system of congruences
1073
1074\begin{align*}
1075\begin{cases}
1076 x \equiv a_0 \pmod {n_0}\\
1077 x \equiv a_1 \pmod {n_1}\\
1078 \dots \\
1079 x \equiv a_k \pmod {n_k}
1080\end{cases}
1081\end{align*}
1082
1083has exactly one solution modulo \(\prod_{i=0}^kn_i\). Use the
1084\texttt{crt()} function to find a solution to such a system. *Hint:
1085start by running the command \texttt{help(crt)}.
1086
1087 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
1088\prompt{In}{incolor}{127}{\boxspacing}
1089\begin{Verbatim}[commandchars=\\\{\}]
1090\PY{c+c1}{\PYZsh{}help(crt)}
1091\end{Verbatim}
1092\end{tcolorbox}
1093
1094 \hypertarget{cryptography-rsa}{%
1095\section{Cryptography: RSA}\label{cryptography-rsa}}
1096
1097\href{https://en.wikipedia.org/wiki/Cryptography}{Cryptography} is the
1098discipline that studies methods to communicate secrets in such a way
1099that any unauthorized listener would not be able to understand the
1100message.
1101
1102A simple cryptographic protocol could be changing every letter of your
1103text following a fixed scheme (or \emph{cypher}), for example by turning
1104every A into a B, every B into a C and so on. However this is not a very
1105secure method, for many reasons. One of them is that at some point the
1106people who want to communicate need to agree on what method to use, and
1107anyone listening to that conversation would be able to decypher every
1108subsequent conversation. A public-key cryptographic protocol solves this
1109problem.
1110
1111\hypertarget{public-key-cryptography}{%
1112\subsection{Public-key cryptography}\label{public-key-cryptography}}
1113
1114Public-key cryptographic protocols, such as RSA, work like this: there
1115are two keys, a \emph{private} key that is only known to person A
1116(traditionally called Alice in every example), and a \emph{public} key
1117that does not need to be secret.
1118
1119The public key is used to \emph{encrypt} the message (that is to
1120``lock'' it, or ``hyde'' it), but one needs the private key to
1121\emph{decrypt} it. Imagine having two keys for your door, but one can
1122only be used to lock it, while the other only to open it.
1123
1124The message exchange works like this: suppose that person B (Bob) wants
1125to send a secret message to Alice. Then Alice secretely generates a
1126private and a public key and sends only the public one to Bob. Now Bob
1127encrypts the message and sends it to Alice, who can use her private key
1128to decrypt it. Even if Eve (short for \emph{eavesdropper}, an
1129unauthorized listener) listens to every message exchanged, she won't be
1130able to decypher the secret: the private key has never left Alice's
1131house!
1132
1133Notice that such a protocol is \emph{asymmetric}: if Alice wanted to
1134send a secret to Bob in reply, Bob would need to generate a pair of keys
1135of his own.
1136
1137Let's see how we can do this in practice, using number theory!
1138
1139\hypertarget{rsa}{%
1140\subsection{RSA}\label{rsa}}
1141
1142As many other cryptography protocols, RSA is based on a Mathematical
1143process that is easy to do in one direction, but very hard to invert. In
1144this case the hard process is integer factorization, that is decomposing
1145an integer number as a product of primes.
1146
1147 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
1148\prompt{In}{incolor}{2}{\boxspacing}
1149\begin{Verbatim}[commandchars=\\\{\}]
1150\PY{n}{p} \PY{o}{=} \PY{l+m+mi}{100003100019100043100057100069}
1151\PY{n}{q} \PY{o}{=} \PY{l+m+mi}{100144655312449572059845328443}
1152\PY{n}{n} \PY{o}{=} \PY{n}{p}\PY{o}{*}\PY{n}{q}
1153\PY{n+nb}{print}\PY{p}{(}\PY{n}{is\PYZus{}prime}\PY{p}{(}\PY{n}{p}\PY{p}{)}\PY{p}{,} \PY{n}{is\PYZus{}prime}\PY{p}{(}\PY{n}{q}\PY{p}{)}\PY{p}{,} \PY{n}{is\PYZus{}prime}\PY{p}{(}\PY{n}{p}\PY{o}{*}\PY{n}{q}\PY{p}{)}\PY{p}{)}
1154
1155\PY{c+c1}{\PYZsh{} Use the command below to see how long it takes}
1156\PY{c+c1}{\PYZsh{}timeit(\PYZdq{}factor(n)\PYZdq{}, number=1, repeat=1)}
1157\end{Verbatim}
1158\end{tcolorbox}
1159
1160 \begin{Verbatim}[commandchars=\\\{\}]
1161True True False
1162 \end{Verbatim}
1163
1164 In order to generate the keys, Alice picks a number \(n\) which is the
1165product of two large primes \(p\) and \(q\) of more or less the same
1166size. Finding such primes is relatively easy compared to factoring the
1167number \(n\) she obtained. Then she computes the Euler totient
1168\(\varphi(n)=(p-1)(q-1)\) of \(n\), which she can do because she knows
1169that \(n=pq\) - it would be impossible otherwise!
1170
1171Then Alice can compute two integers \((d,e)\) such that
1172\(de\equiv 1\pmod{\varphi(n)}\). She will send the numbers \(n\) and
1173\(d\) to Bob and keep \(e\) secret. In this case the public key is the
1174pair \((n,d)\), while \(e\) is the private key.
1175
1176Of course, she does all of this using Sage!
1177
1178 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
1179\prompt{In}{incolor}{105}{\boxspacing}
1180\begin{Verbatim}[commandchars=\\\{\}]
1181\PY{k}{def} \PY{n+nf}{two\PYZus{}large\PYZus{}primes}\PY{p}{(}\PY{p}{)}\PY{p}{:}
1182 \PY{n}{p}\PY{p}{,} \PY{n}{q} \PY{o}{=} \PY{l+m+mi}{0}\PY{p}{,} \PY{l+m+mi}{0}
1183 \PY{c+c1}{\PYZsh{} We make sure that they are different}
1184 \PY{k}{while} \PY{n}{p} \PY{o}{==} \PY{n}{q}\PY{p}{:}
1185 \PY{n}{p} \PY{o}{=} \PY{n}{Primes}\PY{p}{(}\PY{p}{)}\PY{p}{[}\PY{n}{randint}\PY{p}{(}\PY{l+m+mi}{10}\PY{o}{\PYZca{}}\PY{l+m+mi}{6}\PY{p}{,} \PY{l+m+mi}{2}\PY{o}{*}\PY{l+m+mi}{10}\PY{o}{\PYZca{}}\PY{l+m+mi}{6}\PY{p}{)}\PY{p}{]}
1186 \PY{n}{q} \PY{o}{=} \PY{n}{Primes}\PY{p}{(}\PY{p}{)}\PY{p}{[}\PY{n}{randint}\PY{p}{(}\PY{l+m+mi}{10}\PY{o}{\PYZca{}}\PY{l+m+mi}{6}\PY{p}{,} \PY{l+m+mi}{2}\PY{o}{*}\PY{l+m+mi}{10}\PY{o}{\PYZca{}}\PY{l+m+mi}{6}\PY{p}{)}\PY{p}{]}
1187 \PY{k}{return} \PY{n}{p}\PY{p}{,} \PY{n}{q}
1188
1189\PY{k}{def} \PY{n+nf}{random\PYZus{}unit\PYZus{}mod}\PY{p}{(}\PY{n}{N}\PY{p}{)}\PY{p}{:}
1190 \PY{n}{R} \PY{o}{=} \PY{n}{Integers}\PY{p}{(}\PY{n}{N}\PY{p}{)}
1191 \PY{n}{d} \PY{o}{=} \PY{n}{R}\PY{p}{(}\PY{l+m+mi}{0}\PY{p}{)}
1192 \PY{c+c1}{\PYZsh{} We make sure that it is invertible}
1193 \PY{k}{while} \PY{o+ow}{not} \PY{n}{d}\PY{o}{.}\PY{n}{is\PYZus{}unit}\PY{p}{(}\PY{p}{)}\PY{p}{:}
1194 \PY{n}{d} \PY{o}{=} \PY{n}{R}\PY{o}{.}\PY{n}{random\PYZus{}element}\PY{p}{(}\PY{p}{)}
1195 \PY{k}{return} \PY{n}{d}
1196
1197\PY{k}{def} \PY{n+nf}{Alice\PYZus{}generate\PYZus{}keys}\PY{p}{(}\PY{p}{)}\PY{p}{:}
1198 \PY{n}{p}\PY{p}{,} \PY{n}{q} \PY{o}{=} \PY{n}{two\PYZus{}large\PYZus{}primes}\PY{p}{(}\PY{p}{)}
1199 \PY{n}{n} \PY{o}{=} \PY{n}{p}\PY{o}{*}\PY{n}{q}
1200 \PY{n}{phi\PYZus{}n} \PY{o}{=} \PY{p}{(}\PY{n}{p}\PY{o}{\PYZhy{}}\PY{l+m+mi}{1}\PY{p}{)}\PY{o}{*}\PY{p}{(}\PY{n}{q}\PY{o}{\PYZhy{}}\PY{l+m+mi}{1}\PY{p}{)} \PY{c+c1}{\PYZsh{} euler\PYZus{}phi(n) is slow!}
1201
1202 \PY{n}{d} \PY{o}{=} \PY{n}{random\PYZus{}unit\PYZus{}mod}\PY{p}{(}\PY{n}{phi\PYZus{}n}\PY{p}{)}
1203 \PY{n}{e} \PY{o}{=} \PY{n}{d}\PY{o}{\PYZca{}}\PY{o}{\PYZhy{}}\PY{l+m+mi}{1}
1204 \PY{k}{return} \PY{n}{n}\PY{p}{,} \PY{n}{d}\PY{p}{,} \PY{n}{e}
1205
1206\PY{n}{Alice\PYZus{}generate\PYZus{}keys}\PY{p}{(}\PY{p}{)}
1207\end{Verbatim}
1208\end{tcolorbox}
1209
1210 \begin{tcolorbox}[breakable, size=fbox, boxrule=.5pt, pad at break*=1mm, opacityfill=0]
1211\prompt{Out}{outcolor}{105}{\boxspacing}
1212\begin{Verbatim}[commandchars=\\\{\}]
1213(419199544978969, 235530823946467, 80799425863927)
1214\end{Verbatim}
1215\end{tcolorbox}
1216
1217 Now, how does Bob encrypt his message? Let's say he wants to send to
1218Alice the number \(m\) with \(1<m<n\) (In practice he would like to send
1219her some text with emojis, or maybe a voice message; but for computers
1220everything is a number, and there are different ways to translate any
1221sort of information to a number. He just chooses one of the many
1222standard methods that already exist, no cryptography is needed in this
1223step. If the message \(m\) is too long, he can split it up in some
1224pieces and repeat the process multiple times.)
1225
1226Now he computes \(m^d\pmod n\) and sends it back to Alice.
1227
1228 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
1229\prompt{In}{incolor}{3}{\boxspacing}
1230\begin{Verbatim}[commandchars=\\\{\}]
1231\PY{k}{def} \PY{n+nf}{Bob\PYZus{}encrypt}\PY{p}{(}\PY{n}{m}\PY{p}{,} \PY{n}{n}\PY{p}{,} \PY{n}{d}\PY{p}{)}\PY{p}{:}
1232 \PY{n}{R} \PY{o}{=} \PY{n}{Integers}\PY{p}{(}\PY{n}{n}\PY{p}{)}
1233 \PY{k}{return} \PY{n}{R}\PY{p}{(}\PY{n}{m}\PY{p}{)}\PY{o}{\PYZca{}}\PY{n}{d} \PY{c+c1}{\PYZsh{} Assume that n is large enough}
1234
1235\PY{n}{message} \PY{o}{=} \PY{l+m+mi}{42424242}
1236\PY{n}{Bob\PYZus{}encrypt}\PY{p}{(}\PY{n}{message}\PY{p}{,} \PY{l+m+mi}{419199544978969}\PY{p}{,} \PY{l+m+mi}{235530823946467}\PY{p}{)}
1237\end{Verbatim}
1238\end{tcolorbox}
1239
1240 \begin{tcolorbox}[breakable, size=fbox, boxrule=.5pt, pad at break*=1mm, opacityfill=0]
1241\prompt{Out}{outcolor}{3}{\boxspacing}
1242\begin{Verbatim}[commandchars=\\\{\}]
1243149461597163501
1244\end{Verbatim}
1245\end{tcolorbox}
1246
1247 Since \(de\equiv 1\pmod{\varphi(n)}\), it follows that
1248\((m^d)^e\equiv m\pmod n\) (see
1249\href{https://en.wikipedia.org/wiki/Euler\%27s_theorem}{Wikipedia:
1250Euler's theorem}). So for Alice it is very easy to get back the original
1251message:
1252
1253 \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
1254\prompt{In}{incolor}{108}{\boxspacing}
1255\begin{Verbatim}[commandchars=\\\{\}]
1256\PY{k}{def} \PY{n+nf}{Alice\PYZus{}decrypt}\PY{p}{(}\PY{n}{m\PYZus{}encrypted}\PY{p}{,} \PY{n}{n}\PY{p}{,} \PY{n}{e}\PY{p}{)}\PY{p}{:}
1257 \PY{n}{R} \PY{o}{=} \PY{n}{Integers}\PY{p}{(}\PY{n}{n}\PY{p}{)}
1258 \PY{k}{return} \PY{n}{R}\PY{p}{(}\PY{n}{m\PYZus{}encrypted}\PY{p}{)}\PY{o}{\PYZca{}}\PY{n}{e}
1259
1260\PY{n}{Alice\PYZus{}decrypt}\PY{p}{(}\PY{l+m+mi}{149461597163501}\PY{p}{,} \PY{l+m+mi}{419199544978969}\PY{p}{,} \PY{l+m+mi}{80799425863927}\PY{p}{)}
1261\end{Verbatim}
1262\end{tcolorbox}
1263
1264 \begin{tcolorbox}[breakable, size=fbox, boxrule=.5pt, pad at break*=1mm, opacityfill=0]
1265\prompt{Out}{outcolor}{108}{\boxspacing}
1266\begin{Verbatim}[commandchars=\\\{\}]
126742424242
1268\end{Verbatim}
1269\end{tcolorbox}
1270
1271 Another assumption on which RSA relies is that even if one knows
1272\(M=m^e\) and \(e\), extracting the \(e\)-th root of \(M\) modulo \(n\)
1273(and thus obtaining \(m\)) is very hard. Currently the best known way to
1274do this is by factorizing \(n\) first, which is considered to be a very
1275hard problem. However, there is no proof that faster algorithms can't be
1276devised.
1277
1278Moreover, one day we will overcome the current technological
1279difficulties and quantum computers will be available. Quantum computers
1280are not just ``more powerful'' than classical hardware, but they work
1281based on completely different logical foundations and they make the
1282factorization problem much easier to solve: for example
1283\href{https://en.wikipedia.org/wiki/Shor\%27s_algorithm}{Shor's
1284algorithm} takes advantage of this different logic and can factorize
1285numbers quickly, if run on a quantum computer.
1286
1287To this day the largest number factorized with a quantum computer is
1288\(21=3\times 7\). Nonetheless, quantum-safe cryptography protocols
1289(i.e.~based on problems that are hard to solve also with quantum
1290computers) have already been developed.
1291
1292
1293 % Add a bibliography block to the postdoc
1294
1295
1296
1297\end{document}

Generated with cgit - Back to sebastiano.tronto.net