Skip to content

Instantly share code, notes, and snippets.

@Carreau
Created April 3, 2013 17:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Carreau/5303427 to your computer and use it in GitHub Desktop.
Save Carreau/5303427 to your computer and use it in GitHub Desktop.
%% This file was auto-generated by IPython.
%% Conversion from the original notebook file:
%% recitation4.ipynb
%%
\documentclass[11pt,english]{article}
%% This is the automatic preamble used by IPython. Note that it does *not*
%% include a documentclass declaration. The documentclass is added at runtime
%% to the overall document.
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{graphicx}
\usepackage{ucs}
\usepackage[utf8x]{inputenc}
% needed for markdown enumerations to work
\usepackage{enumerate}
% Slightly bigger margins than the latex defaults
\usepackage{geometry}
\geometry{verbose,tmargin=3cm,bmargin=3cm,lmargin=2.5cm,rmargin=2.5cm}
% Define a few colors for use in code, links and cell shading
\usepackage{color}
\definecolor{orange}{cmyk}{0,0.4,0.8,0.2}
\definecolor{darkorange}{rgb}{.71,0.21,0.01}
\definecolor{darkgreen}{rgb}{.12,.54,.11}
\definecolor{myteal}{rgb}{.26, .44, .56}
\definecolor{gray}{gray}{0.45}
\definecolor{lightgray}{gray}{.95}
\definecolor{mediumgray}{gray}{.8}
\definecolor{inputbackground}{rgb}{.95, .95, .85}
\definecolor{outputbackground}{rgb}{.95, .95, .95}
\definecolor{traceback}{rgb}{1, .95, .95}
% Framed environments for code cells (inputs, outputs, errors, ...). The
% various uses of \unskip (or not) at the end were fine-tuned by hand, so don't
% randomly change them unless you're sure of the effect it will have.
\usepackage{framed}
% remove extraneous vertical space in boxes
\setlength\fboxsep{0pt}
% codecell is the whole input+output set of blocks that a Code cell can
% generate.
% TODO: unfortunately, it seems that using a framed codecell environment breaks
% the ability of the frames inside of it to be broken across pages. This
% causes at least the problem of having lots of empty space at the bottom of
% pages as new frames are moved to the next page, and if a single frame is too
% long to fit on a page, it will completely stop latex from compiling the
% document. So unless we figure out a solution to this, we'll have to instead
% leave the codecell env. as empty. I'm keeping the original codecell
% definition here (a thin vertical bar) for reference, in case we find a
% solution to the page break issue.
%% \newenvironment{codecell}{%
%% \def\FrameCommand{\color{mediumgray} \vrule width 1pt \hspace{5pt}}%
%% \MakeFramed{\vspace{-0.5em}}}
%% {\unskip\endMakeFramed}
% For now, make this a no-op...
\newenvironment{codecell}{}
\newenvironment{codeinput}{%
\def\FrameCommand{\colorbox{inputbackground}}%
\MakeFramed{\advance\hsize-\width \FrameRestore}}
{\unskip\endMakeFramed}
\newenvironment{codeoutput}{%
\def\FrameCommand{\colorbox{outputbackground}}%
\vspace{-1.4em}
\MakeFramed{\advance\hsize-\width \FrameRestore}}
{\unskip\medskip\endMakeFramed}
\newenvironment{traceback}{%
\def\FrameCommand{\colorbox{traceback}}%
\MakeFramed{\advance\hsize-\width \FrameRestore}}
{\endMakeFramed}
% Use and configure listings package for nicely formatted code
\usepackage{listingsutf8}
\lstset{
language=python,
inputencoding=utf8x,
extendedchars=\true,
aboveskip=\smallskipamount,
belowskip=\smallskipamount,
xleftmargin=2mm,
breaklines=true,
basicstyle=\small \ttfamily,
showstringspaces=false,
keywordstyle=\color{blue}\bfseries,
commentstyle=\color{myteal},
stringstyle=\color{darkgreen},
identifierstyle=\color{darkorange},
columns=fullflexible, % tighter character kerning, like verb
}
% The hyperref package gives us a pdf with properly built
% internal navigation ('pdf bookmarks' for the table of contents,
% internal cross-reference links, web links for URLs, etc.)
\usepackage{hyperref}
\hypersetup{
breaklinks=true, % so long urls are correctly broken across lines
colorlinks=true,
urlcolor=blue,
linkcolor=darkorange,
citecolor=darkgreen,
}
% hardcode size of all verbatim environments to be a bit smaller
\makeatletter
\g@addto@macro\@verbatim\small\topsep=0.5em\partopsep=0pt
\makeatother
% Prevent overflowing lines due to urls and other hard-to-break entities.
\sloppy
\begin{document}
\section{CS1001.py}
\subsection{Extended Introduction to Computer Science with Python,
Tel-Aviv University, Spring 2013}
\section{Recitation 4 - 4-8.4.2013}
\subsection{Last update: 3.4.2013}
\section{Reminder - \texttt{Big O} notation}
Let $f(x)$ and $g(x)$ be two function. Then \[
f(x) = O(g(x)) \; as \; x \to \infty
\] If and only if there exist $M \ge 0 \;$ and $x_{0}\in \mathbb{R}$
such that \[
|f(x)| \le M|g(x)| \; \forall x>x_{0}
\]
\section{Time complexity hierarchy}
The most common time complexities we encounter are (\emph{c
\textgreater{} 1} is a real constant, *n \textgreater{}1 * is the size
of the input):
\begin{itemize}
\item
Constant - $O(1)$
\item
Logarithmic - $O(log(n))$
\item
Root/fractional - $O(n^{1/c})$
\item
Linear - $O(n)$
\item
Loglinear - $O(n log(n))$
\item
Polynomial - $O(n^{c})$
\item
Exponential - $O(c^{n})$
\item
Factorial - $O(n!)$
\end{itemize}
See also this list on
\href{http://en.wikipedia.org/wiki/Time\_complexity\#Table\_of\_common\_time\_complexities}{Wikipedia}.
\subsection{Size of the input}
\begin{itemize}
\item
For a numerical input (factorization, prime numbers) the size of the
input is the number of bits of the numerical input
\item
For a list/vector input, the size is the number of elements
\item
For a matrix?
\end{itemize}
\subsection{Examples}
\subsubsection{Constant, Linear, Loglinear, Polynomial}
\begin{codecell}
\begin{codeinput}
\begin{lstlisting}
from math import log
domain = range(1,100)
const = [10 for x in domain]
lin = [x for x in domain]
loglin = [x * log(x) for x in domain]
poly = [x ** 2 for x in domain]
# these lines are the plotting directives
fig = figure(figsize=(16,6))
ax = subplot(1,3,1)
ax.plot(domain,const)
ax.plot(domain,lin)
ax.legend(["const","lin"],loc=2);
ax = subplot(1,3,2)
ax.plot(domain,lin)
ax.plot(domain,loglin)
ax.legend(["lin","loglin"],loc=2);
ax = subplot(1,3,3)
ax.plot(domain,loglin)
ax.plot(domain,poly)
ax.legend(["loglin","poly"],loc=2);
\end{lstlisting}
\end{codeinput}
\begin{codeoutput}
\begin{center}
\includegraphics[width=0.7\textwidth]{recitation4_files/recitation4_fig_00.png}
\par
\end{center}
\end{codeoutput}
\end{codecell}
\subsection{Exercises}
\subsubsection{Transitivity}
If \$ f(n)=O(g(n)); \$ and \$ g(n) = O(h(n)); \$ then \$ f = O(h(n)); \$
?
\subsubsection{Symmetry}
If $f=O(g)\;$ then $g=O(f)$? Or $g \ne O(f)$?
\subsubsection{Series Loops}
Let $f_1 = O(g_1)\;$ and $f_2=O(g_2)$.
Show that $f_1 + f_2 = O(g_1 + g_2)$.
This relates to two consecutive loops:
\begin{verbatim}
for i in range(len(list1)):
print i
for i in range(len(list2)):
print i
\end{verbatim}
\subsubsection{Parallel Loops}
Show that $f_1 \cdot f_2 = O(g_1 \cdot g_2)$.
This relates to independent nested loops:
\begin{verbatim}
for i in range(len(list1)):
print i
for j in range(len(list2)):
print j
\end{verbatim}
\subsubsection{Maximum}
Show that $_1 + f_2 + ... + f_k = O(f_max)$. That is, in a finite
constant sum of functions, the dominate function defines the growth
rate.
A private case is that of a polynomial.
\subsubsection{Dependent nested loops}
For exmaple,
\begin{verbatim}
for i in range(len(list1)):
for j in range(i):
print i, j
\end{verbatim}
Prove:
\begin{itemize}
\item
$\sum_{i=1}^{n}{i} = O(n^2)$ - the arithmetic series
\item
$\sum_{i=1}^{n}{2^i} = O(2^n)$ - the geometric series
\end{itemize}
\section{Primality testing}
\subsubsection{\href{http://en.wikipedia.org/wiki/Fermat's\_little\_theorem}{Fermat's
little theorem}}
If $p$ is a prime $a$ is a natural number such that $1\le a < p\;$, then
$a^{p-1} = 1 \; (mod \; p)$.
\subsubsection{Probabilistic test with Fermat's little theorem}
We can use this to create a primality test for \emph{p}.
\begin{codecell}
\begin{codeinput}
\begin{lstlisting}
from random import randrange
def is_prime(p):
"""probabilistic test for p's compositeness"""
for i in range(100):
a = randrange(1, p-1) # a is a random integer in [1..p-1]
if pow(a, p-1, p) != 1: # this takes O(n^3) = O((log2 p)^3)
#print(p, "is composite")
return False
#print(p, "is prime")
return True # we get here if no compositeness witness was found
\end{lstlisting}
\end{codeinput}
\end{codecell}
\begin{codecell}
\begin{codeinput}
\begin{lstlisting}
is_prime(11)
\end{lstlisting}
\end{codeinput}
\begin{codeoutput}
\begin{verbatim}
True
\end{verbatim}
\end{codeoutput}
\end{codecell}
\begin{codecell}
\begin{codeinput}
\begin{lstlisting}
is_prime(190125101)
\end{lstlisting}
\end{codeinput}
\begin{codeoutput}
\begin{verbatim}
True
\end{verbatim}
\end{codeoutput}
\end{codecell}
\subsubsection{Notes}
\begin{itemize}
\item
\texttt{pow(a,b,c)} is equivalent to $a^b \; mod \; c$, only it is
more efficient by use of \emph{iterated squaring}.
\item
The \emph{False Positive} rate - the probablity the function returns
\texttt{True} when it should return \texttt{False} - is less than
$0.25^{100}$ (Miller-Rabin).
\end{itemize}
\subsubsection{Testing the prime number theorem}
\paragraph{The theorem}
Define by $\pi(x)$ the number of prime numbersless than or equal to $x$.
Then the
\href{http://en.wikipedia.org/wiki/Prime\_number\_theorem}{prime number
theorem} states that
\[
\pi(x) \thicksim \frac{x}{log(x)}
\]
for large $x$.
Since $n$ the number of bits in $x$ is $O(log(x))\;$ this translates to
\[
\pi(x) = O(1/n)
\]
And we can say that \textgreater{} A number with \emph{n} bits is prime
with a probability of $O(1/n)$.
We'd like to check this, but for large \emph{n} there are too many
($2^{n-1}$) numbers to check. So we will use \emph{sampling}.
\begin{codecell}
\begin{codeinput}
\begin{lstlisting}
def prob_prime(n):
"""evaluate the probability of an n-bit long integer to be prime"""
count = 0
sample_size = 10 ** 5
for i in range(sample_size):
p = random.randint(2 ** (n-1), 2 ** n-1)
count += is_prime(p)
return count/sample_size
\end{lstlisting}
\end{codeinput}
\end{codecell}
\begin{codecell}
\begin{codeinput}
\begin{lstlisting}
prob_prime(20)
\end{lstlisting}
\end{codeinput}
\begin{codeoutput}
\begin{verbatim}
0.07521
\end{verbatim}
\end{codeoutput}
\end{codecell}
\begin{codecell}
\begin{codeinput}
\begin{lstlisting}
1/20
\end{lstlisting}
\end{codeinput}
\begin{codeoutput}
\begin{verbatim}
0.05
\end{verbatim}
\end{codeoutput}
\end{codecell}
\section{Diffie-Hellman}
A Khan Academy video that illustrates the Diffie-Hellman key exchange:
See the paper
\href{http://www.cs.tau.ac.il/~bchor/diffie-hellman.pdf}{New directions
in cryptography}.
This is the protocol:
\begin{codecell}
\begin{codeinput}
\begin{lstlisting}
def DH_exchange(p):
""" generates a shared DH key """
g = randrange(1,p-1)
a = randrange(1,p-1) # Alice's secret
b = randrange(1,p-1) # Bob's secret
x = pow(g,a,p)
y = pow(g,b,p)
key_A = pow(y,a,p)
key_B = pow(x,b,p)
return g, a, b, x, y, key_A, key_B
\end{lstlisting}
\end{codeinput}
\end{codecell}
\begin{codecell}
\begin{codeinput}
\begin{lstlisting}
DH_exchange(190125101)
\end{lstlisting}
\end{codeinput}
\begin{codeoutput}
\begin{verbatim}
(130721310, 61963609, 1775050, 132736567, 143446917, 74182194, 74182194)
\end{verbatim}
\end{codeoutput}
\end{codecell}
\begin{codecell}
\begin{codeinput}
\begin{lstlisting}
DH_exchange(833648000993161193752610727299)
\end{lstlisting}
\end{codeinput}
\begin{codeoutput}
\begin{verbatim}
(225405422835827732918401478004,
153883981994400043514132897779,
556710940458985113442266962618,
620358857758647613746179753310,
479744267228387852844588852918,
610421506532174772126394293202,
610421506532174772126394293202)
\end{verbatim}
\end{codeoutput}
\end{codecell}
Now let's try and break it:
\begin{codecell}
\begin{codeinput}
\begin{lstlisting}
def crack_DH(p, g, x):
"""find secret "a" that satisfies g**a%p == x
Not feasible for large p"""
for a in range(1,p-1):
if a % 100000 == 0:
print("Iteration",a) # progress bar
if pow(g,a,p) == x:
return a
return None
\end{lstlisting}
\end{codeinput}
\end{codecell}
We need a function that finds primes:
\begin{codecell}
\begin{codeinput}
\begin{lstlisting}
def find_prime(n):
""" find random n-bit long prime (no leading zeros: 2**(n-1)<= N < 2**n )"""
while True: #here we're optimistic, but actually we have a good reason to be:
# after O(1/n) iterations we expect to find a prime and halt
candidate = randrange(2**(n - 1), 2**n)
if is_prime(candidate):
return candidate
\end{lstlisting}
\end{codeinput}
\end{codecell}
\begin{codecell}
\begin{codeinput}
\begin{lstlisting}
find_prime(10)
\end{lstlisting}
\end{codeinput}
\begin{codeoutput}
\begin{verbatim}
809
\end{verbatim}
\end{codeoutput}
\end{codecell}
\begin{codecell}
\begin{codeinput}
\begin{lstlisting}
find_prime(100)
\end{lstlisting}
\end{codeinput}
\begin{codeoutput}
\begin{verbatim}
867229771910197365894912239707
\end{verbatim}
\end{codeoutput}
\end{codecell}
Running with a 10-bit prime:
\begin{codecell}
\begin{codeinput}
\begin{lstlisting}
p = find_prime(10)
print(p,log(p,2))
g,a,b,x,y,key_A,key_B = DH_exchange(p)
print('g',g,'a',a,'b',b,'x',x,'y',y,'key_A',key_A,'key_B',key_B)
print('a',crack_DH(p,g,x))
\end{lstlisting}
\end{codeinput}
\begin{codeoutput}
\begin{verbatim}
571 9.157346935362844
g 323 a 376 b 467 x 271 y 353 key_A 350 key_B 350
a 15
\end{verbatim}
\end{codeoutput}
\end{codecell}
Running with a 16-bit prime:
\begin{codecell}
\begin{codeinput}
\begin{lstlisting}
p = find_prime(16)
print(p,log(p,2))
g,a,b,x,y,key_A,key_B = DH_exchange(p)
print('g',g,'a',a,'b',b,'x',x,'y',y,'key_A',key_A,'key_B',key_B)
print('a',crack_DH(p,g,x))
\end{lstlisting}
\end{codeinput}
\begin{codeoutput}
\begin{verbatim}
43913 15.422360477832592
g 38791 a 18986 b 43896 x 19571 y 18163 key_A 32540 key_B 32540
a
\end{verbatim}
\begin{verbatim}
18986
\end{verbatim}
\end{codeoutput}
\end{codecell}
\begin{codecell}
\begin{codeinput}
\begin{lstlisting}
p = find_prime(24)
print(p,log(p,2))
g,a,b,x,y,key_A,key_B = DH_exchange(p)
print('g',g,'a',a,'b',b,'x',x,'y',y,'key_A',key_A,'key_B',key_B)
print('a',crack_DH(p,g,x))
\end{lstlisting}
\end{codeinput}
\begin{codeoutput}
\begin{verbatim}
14410853 23.78065239753461
g 336845 a 5626365 b 10932040 x 2437765 y 286640 key_A 7725816 key_B 7725816
Iteration
\end{verbatim}
\begin{verbatim}
100000
Iteration
\end{verbatim}
\begin{verbatim}
200000
Iteration
\end{verbatim}
\begin{verbatim}
300000
Iteration
\end{verbatim}
\begin{verbatim}
400000
Iteration
\end{verbatim}
\begin{verbatim}
500000
Iteration
\end{verbatim}
\begin{verbatim}
600000
Iteration
\end{verbatim}
\begin{verbatim}
700000
Iteration
\end{verbatim}
\begin{verbatim}
800000
Iteration
\end{verbatim}
\begin{verbatim}
900000
Iteration
\end{verbatim}
\begin{verbatim}
1000000
Iteration
\end{verbatim}
\begin{verbatim}
1100000
Iteration
\end{verbatim}
\begin{verbatim}
1200000
Iteration
\end{verbatim}
\begin{verbatim}
1300000
Iteration
\end{verbatim}
\begin{verbatim}
1400000
Iteration
\end{verbatim}
\begin{verbatim}
1500000
Iteration
\end{verbatim}
\begin{verbatim}
1600000
Iteration
\end{verbatim}
\begin{verbatim}
1700000
Iteration
\end{verbatim}
\begin{verbatim}
1800000
Iteration
\end{verbatim}
\begin{verbatim}
1900000
Iteration
\end{verbatim}
\begin{verbatim}
2000000
Iteration
\end{verbatim}
\begin{verbatim}
2100000
Iteration
\end{verbatim}
\begin{verbatim}
2200000
Iteration
\end{verbatim}
\begin{verbatim}
2300000
Iteration
\end{verbatim}
\begin{verbatim}
2400000
Iteration
\end{verbatim}
\begin{verbatim}
2500000
Iteration
\end{verbatim}
\begin{verbatim}
2600000
Iteration
\end{verbatim}
\begin{verbatim}
2700000
Iteration
\end{verbatim}
\begin{verbatim}
2800000
Iteration
\end{verbatim}
\begin{verbatim}
2900000
Iteration
\end{verbatim}
\begin{verbatim}
3000000
Iteration
\end{verbatim}
\begin{verbatim}
3100000
Iteration
\end{verbatim}
\begin{verbatim}
3200000
Iteration
\end{verbatim}
\begin{verbatim}
3300000
Iteration
\end{verbatim}
\begin{verbatim}
3400000
Iteration
\end{verbatim}
\begin{verbatim}
3500000
Iteration
\end{verbatim}
\begin{verbatim}
3600000
Iteration
\end{verbatim}
\begin{verbatim}
3700000
Iteration
\end{verbatim}
\begin{verbatim}
3800000
Iteration
\end{verbatim}
\begin{verbatim}
3900000
Iteration
\end{verbatim}
\begin{verbatim}
4000000
Iteration
\end{verbatim}
\begin{verbatim}
4100000
Iteration
\end{verbatim}
\begin{verbatim}
4200000
Iteration
\end{verbatim}
\begin{verbatim}
4300000
Iteration
\end{verbatim}
\begin{verbatim}
4400000
Iteration
\end{verbatim}
\begin{verbatim}
4500000
Iteration
\end{verbatim}
\begin{verbatim}
4600000
Iteration
\end{verbatim}
\begin{verbatim}
4700000
Iteration
\end{verbatim}
\begin{verbatim}
4800000
Iteration
\end{verbatim}
\begin{verbatim}
4900000
Iteration
\end{verbatim}
\begin{verbatim}
5000000
Iteration
\end{verbatim}
\begin{verbatim}
5100000
Iteration
\end{verbatim}
\begin{verbatim}
5200000
Iteration
\end{verbatim}
\begin{verbatim}
5300000
Iteration
\end{verbatim}
\begin{verbatim}
5400000
Iteration
\end{verbatim}
\begin{verbatim}
5500000
Iteration
\end{verbatim}
\begin{verbatim}
5600000
a
\end{verbatim}
\begin{verbatim}
5626365
\end{verbatim}
\end{codeoutput}
\end{codecell}
\subsection{Fin}
This notebook is part of the
\href{http://tau-cs1001-py.wikidot.com/}{Extended introduction to
computer science} course at Tel-Aviv University.
The notebook was written using Python 3.2 and IPython 0.13.1.
The code is available at
\url{https://raw.github.com/yoavram/CS1001.py/master/recitation4.ipynb}.
The notebook can be viewed online at
\url{http://nbviewer.ipython.org/urls/raw.github.com/yoavram/CS1001.py/master/recitation4.ipynb}.
This work is licensed under a
\href{http://creativecommons.org/licenses/by-sa/3.0/}{Creative Commons
Attribution-ShareAlike 3.0 Unported License}.
\end{document}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment