Skip to content

Commit fb10a4a

Browse files
author
sushmit
committed
SR: adding files
1 parent 54f956b commit fb10a4a

File tree

5 files changed

+340
-2
lines changed

5 files changed

+340
-2
lines changed

cracking_rand.py

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
# Copyright 2013 David Eisenstat
2+
"""
3+
Computes the tempering matrix from the MT19937 pseudorandom number generator.
4+
5+
>>> from cracking_rand import *
6+
>>> import random
7+
>>> prng = random.Random()
8+
>>> n = 624
9+
>>> data = [prng.getrandbits(32) for k in range(n)]
10+
>>> seed = prng.getstate()[1][:n]
11+
>>> T = tempering_mat()
12+
>>> data == [int_from_vec(T * vec_from_int(x)) for x in seed]
13+
True
14+
"""
15+
16+
17+
from mat import Mat
18+
from vec import Vec
19+
20+
#This module should use GF2.one but doesn't yet
21+
22+
one = 1
23+
24+
25+
def format_bit(b):
26+
"""
27+
Converts a bit to a string.
28+
29+
>>> format_bit(0)
30+
'0'
31+
>>> format_bit(one)
32+
'1'
33+
"""
34+
return '0' if b == 0 else '1'
35+
36+
37+
def print_vec(v):
38+
"""
39+
Prints a bit vector compactly.
40+
41+
>>> print_vec(Vec({0, 1, 2, 3, 4, 5, 6, 7}, {1: one, 3: one, 5: one}))
42+
01010100
43+
>>> print_vec(Vec({0, 1, 2, 3}, {0: one, 2: one, 3: one}))
44+
1011
45+
"""
46+
print(''.join(format_bit(v[k]) for k in sorted(v.D)))
47+
48+
49+
def print_mat(m):
50+
"""
51+
Prints a bit matrix compactly.
52+
53+
>>> print_mat(Mat(({0, 1, 2}, {0, 1, 2}), {(0, 1): one, (1, 2): one}))
54+
010
55+
001
56+
000
57+
"""
58+
D0, D1 = map(sorted, m.D)
59+
for i in D0:
60+
print(''.join(format_bit(m[(i, j)]) for j in D1))
61+
62+
63+
def vec_from_int(m, n=32):
64+
"""
65+
Returns the n-bit vector specified by the integer m.
66+
67+
>>> print_vec(vec_from_int(0b00101010, 8))
68+
01010100
69+
>>> print_vec(vec_from_int(0b1101, 4))
70+
1011
71+
"""
72+
return Vec(set(range(n)), {k: one for k in range(n) if (2 ** k) & m})
73+
74+
75+
def int_from_vec(v):
76+
"""
77+
Returns the integer specified by the bit vector v.
78+
79+
>>> int_from_vec(vec_from_int(42, 8))
80+
42
81+
>>> int_from_vec(vec_from_int(13, 4))
82+
13
83+
"""
84+
# TODO(david): use GF2
85+
return sum(2 ** k for k in v.D if v[k] & 1)
86+
87+
88+
def left_shift(k, n=32):
89+
"""
90+
Returns the n*n matrix corresponding to the operation
91+
92+
lambda v: vec_from_int(int_from_vec(v) << k, n)
93+
94+
>>> print_mat(left_shift(2, 6))
95+
000000
96+
000000
97+
100000
98+
010000
99+
001000
100+
000100
101+
>>> int_from_vec(left_shift(2) * vec_from_int(42)) == 42 << 2
102+
True
103+
"""
104+
D = set(range(n))
105+
return Mat((D, D), {(j + k, j): one for j in range(n - k)})
106+
107+
108+
def right_shift(k, n=32):
109+
"""
110+
Returns the n*n matrix corresponding to the operation
111+
112+
lambda v: vec_from_int(int_from_vec(v) >> k, n)
113+
114+
>>> print_mat(right_shift(1, 4))
115+
0100
116+
0010
117+
0001
118+
0000
119+
>>> int_from_vec(right_shift(1) * vec_from_int(13)) == 13 >> 1
120+
True
121+
"""
122+
D = set(range(n))
123+
return Mat((D, D), {(i, i + k): one for i in range(n - k)})
124+
125+
126+
def diag(v):
127+
"""
128+
Returns the diagonal matrix specified by the vector v.
129+
130+
>>> print_mat(diag(vec_from_int(13, 4)))
131+
1000
132+
0000
133+
0010
134+
0001
135+
"""
136+
return Mat((v.D, v.D), {(k, k): v[k] for k in v.D})
137+
138+
139+
def bitwise_and(m, n=32):
140+
"""
141+
Returns the matrix for masking an n-bit vector by the integer m.
142+
143+
>>> print_mat(bitwise_and(13, 4))
144+
1000
145+
0000
146+
0010
147+
0001
148+
"""
149+
return diag(vec_from_int(m, n))
150+
151+
152+
def identity_mat(n=32):
153+
"""
154+
Returns the n*n identity matrix.
155+
156+
>>> print_mat(identity_mat(4))
157+
1000
158+
0100
159+
0010
160+
0001
161+
"""
162+
D = set(range(n))
163+
return Mat((D, D), {(k, k): one for k in range(n)})
164+
165+
166+
def tempering_mat():
167+
"""
168+
Returns the matrix corresponding to the MT19937 tempering transform.
169+
170+
>>> print_mat(tempering_mat())
171+
10010000000100100010001000000100
172+
01000000000010000001000100000010
173+
00100000000001000000100000000001
174+
00010000000000100000010001000000
175+
10001001000100010010001000000000
176+
00000100100000001001000100000000
177+
00100010010001000100100010001000
178+
10010001001100100010010001000000
179+
00000000100100000001001000100010
180+
00100100010011001000100100010001
181+
00010000001000100000010000001000
182+
00000001000100100010001001000100
183+
00000100000010011000000100100010
184+
00000000000001001000000010010001
185+
00000001000000100010000001000000
186+
00000000000000010000000000100000
187+
00000000000000001000000000010000
188+
00100000000001000100000000001000
189+
00010000000100100010001000000100
190+
00000000000010000001000100000010
191+
00000000000000000000100000000001
192+
00000000000000100000010001000000
193+
10000001000100000010001000000000
194+
00000000100000000001000100000000
195+
00100000010001000100100010001000
196+
00010000001000100000010001000000
197+
00000000000100000001001000100010
198+
00000100000010001000100100010001
199+
00000000000000000000010000001000
200+
00000001000000100010000001000100
201+
00000000000000010000000000100010
202+
00000000000000001000000010010001
203+
"""
204+
m = identity_mat()
205+
m += right_shift(11) * m
206+
m += bitwise_and(0x9d2c5680) * left_shift(7) * m
207+
m += bitwise_and(0xefc60000) * left_shift(15) * m
208+
m += right_shift(18) * m
209+
return m
210+
211+
212+
if __name__ == '__main__':
213+
from doctest import testmod
214+
testmod()

echelon.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Copyright 2013 Philip N. Klein
2+
from vec import Vec
3+
from mat import Mat
4+
import GF2
5+
6+
def row_reduce(rowlist):
7+
"""Given a list of vectors, transform the vectors.
8+
Mutates the argument.
9+
Returns a list of the nonzero reduced vectors in echelon form.
10+
"""
11+
col_label_list = sorted(rowlist[0].D, key=repr)
12+
rows_left = set(range(len(rowlist)))
13+
new_rowlist = []
14+
for c in col_label_list:
15+
#among rows left, list of row-labels whose rows have a nonzero in position c
16+
rows_with_nonzero = [r for r in rows_left if rowlist[r][c] != 0]
17+
if rows_with_nonzero != []:
18+
pivot = rows_with_nonzero[0]
19+
rows_left.remove(pivot)
20+
new_rowlist.append(rowlist[pivot])
21+
for r in rows_with_nonzero[1:]:
22+
rowlist[r] -= (rowlist[r][c]/rowlist[pivot][c])*rowlist[pivot]
23+
return new_rowlist
24+
25+
def transformation_rows(rowlist_input, col_label_list = None):
26+
"""Given a matrix A represented by a list of rows
27+
optionally given the unit field element (1 by default),
28+
and optionally given a list of the domain elements of the rows,
29+
return a matrix M represented by a list of rows such that
30+
M A is in echelon form
31+
"""
32+
one = GF2.one # replace this with 1 if working over R or C
33+
rowlist = list(rowlist_input)
34+
if col_label_list == None: col_label_list = sorted(rowlist[0].D, key=repr)
35+
m = len(rowlist)
36+
row_labels = set(range(m))
37+
M_rowlist = [Vec(row_labels, {i:one}) for i in range(m)]
38+
new_M_rowlist = []
39+
rows_left = set(range(m))
40+
for c in col_label_list:
41+
rows_with_nonzero = [r for r in rows_left if rowlist[r][c] != 0]
42+
if rows_with_nonzero != []:
43+
pivot = rows_with_nonzero[0]
44+
rows_left.remove(pivot)
45+
new_M_rowlist.append(M_rowlist[pivot])
46+
for r in rows_with_nonzero[1:]:
47+
multiplier = rowlist[r][c]/rowlist[pivot][c]
48+
rowlist[r] -= multiplier*rowlist[pivot]
49+
M_rowlist[r] -= multiplier*M_rowlist[pivot]
50+
for r in rows_left: new_M_rowlist.append(M_rowlist[r])
51+
return new_M_rowlist
52+
53+
def transformation(A, col_label_list = None):
54+
"""Given a matrix A, and optionally the unit field element (1 by default),
55+
compute matrix M such that M is invertible and
56+
U = M*A is in echelon form.
57+
"""
58+
row_labels, col_labels = A.D
59+
m = len(row_labels)
60+
row_label_list = sorted(row_labels, key=repr)
61+
rowlist = [Vec(col_labels, {c:A[r,c] for c in col_labels}) for r in row_label_list]
62+
M_rows = transformation_rows(rowlist, col_label_list)
63+
M = Mat((set(range(m)), row_labels), {})
64+
for r in range(m):
65+
for (i,value) in M_rows[r].f.items():
66+
M[r,row_label_list[i]] = value
67+
return M

factoring_support.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from math import sqrt
2+
from functools import reduce
3+
import operator
4+
5+
def gcd(x,y): return x if y == 0 else gcd(y, x % y)
6+
7+
def dumb_factor(x, primeset):
8+
""" If x can be factored over the primeset, return the
9+
set of pairs (p_i, a_i) such that x is the product
10+
of p_i to the power of a_i.
11+
If not, return []
12+
"""
13+
factors = []
14+
for p in primeset:
15+
exponent = 0
16+
while x % p == 0:
17+
exponent = exponent + 1
18+
x = x//p
19+
if exponent > 0:
20+
factors.append((p,exponent))
21+
return factors if x == 1 else []
22+
23+
def primes(limit):
24+
primeset = set()
25+
a = [True] * limit # Initialize the primality list
26+
a[0] = a[1] = False
27+
for (i, isprime) in enumerate(a):
28+
if isprime:
29+
primeset.add(i)
30+
for n in range(i*i, limit, i): # Mark factors non-prime
31+
a[n] = False
32+
return primeset
33+
34+
def intsqrt(x):
35+
L = 1
36+
H = x
37+
if H<L: L, H = H, L
38+
while H - L > 1:
39+
m = int((L+H)//2)
40+
d = x//m
41+
if d > m: L = m
42+
else: H = m
43+
return L if L*L == x else H
44+
45+
def prod(factors):
46+
"return product of numbers in given list"
47+
return reduce(operator.mul, factors, 1)

gaussian_examples.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from mat import Mat
2+
from GF2 import one
3+
4+
Ad = (set([1,2,3,4]), set(['A','B','C','D']))
5+
Af = {k:one for k in {(2,'A'),(2,'C'),(2,'D'),(1,'C'),(1,'D'),(3,'A'),(3,'D'),(4,'A'),(4,'B'),(4,'C'),(4,'D')}}
6+
A = Mat(Ad,Af)
7+
8+
Bd = (set([1,2,3,4]), set(['A','B','C','D']))
9+
Bf = {k:one for k in {(1,'A'),(1,'B'),(2,'A'),(2,'C'),(3,'B'),(3,'C'),(3,'D'),(4,'A')}}
10+
B=Mat(Bd, Bf)

new_notebook.ipynb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"cells": [
33
{
44
"cell_type": "code",
5-
"execution_count": 5,
5+
"execution_count": 1,
66
"metadata": {
77
"collapsed": false
88
},
@@ -16,7 +16,7 @@
1616
" Vec({0, 1, 2, 3, 4},{0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 3.0})]"
1717
]
1818
},
19-
"execution_count": 5,
19+
"execution_count": 1,
2020
"metadata": {},
2121
"output_type": "execute_result"
2222
}

0 commit comments

Comments
 (0)