aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authorng0 <ng0@n0.is>2018-03-05 12:29:45 +0000
committerng0 <ng0@n0.is>2018-03-05 12:29:45 +0000
commit0be7fa64a64245f66fa46bcbb2fe298a931a8b4d (patch)
tree31300a4e6538ca0cb907d97f81ff498f4fa849fe /contrib
parentf18aadc5cbdef52ca02f55f24039f56dbee06321 (diff)
downloadgnunet-0be7fa64a64245f66fa46bcbb2fe298a931a8b4d.tar.gz
gnunet-0be7fa64a64245f66fa46bcbb2fe298a931a8b4d.zip
contrib/gnunet-chk.py: flake8.
Diffstat (limited to 'contrib')
-rwxr-xr-xcontrib/gnunet-chk.py173
1 files changed, 90 insertions, 83 deletions
diff --git a/contrib/gnunet-chk.py b/contrib/gnunet-chk.py
index e51641272..dba694c34 100755
--- a/contrib/gnunet-chk.py
+++ b/contrib/gnunet-chk.py
@@ -16,7 +16,7 @@
16# along with GNUnet; see the file COPYING. If not, write to the 16# along with GNUnet; see the file COPYING. If not, write to the
17# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18# Boston, MA 02110-1301, USA. 18# Boston, MA 02110-1301, USA.
19# 19#
20# File: gnunet-chk.py 20# File: gnunet-chk.py
21# Brief: Computes GNUNET style Content Hash Key for a given file 21# Brief: Computes GNUNET style Content Hash Key for a given file
22# Author: Sree Harsha Totakura 22# Author: Sree Harsha Totakura
@@ -28,6 +28,7 @@ import getopt
28import sys 28import sys
29from Crypto.Cipher import AES 29from Crypto.Cipher import AES
30 30
31
31# Defaults 32# Defaults
32DBLOCK_SIZE = (32 * 1024) # Data block size 33DBLOCK_SIZE = (32 * 1024) # Data block size
33 34
@@ -41,18 +42,18 @@ CHK_HASH_SIZE = 64 # SHA-512 hash = 512 bits = 64 bytes
41 42
42CHK_QUERY_SIZE = CHK_HASH_SIZE # Again a SHA-512 hash 43CHK_QUERY_SIZE = CHK_HASH_SIZE # Again a SHA-512 hash
43 44
44GNUNET_FS_URI_PREFIX = "gnunet://fs/" # FS CHK URI prefix 45GNUNET_FS_URI_PREFIX = "gnunet://fs/" # FS CHK URI prefix
45 46
46GNUNET_FS_URI_CHK_INFIX = "chk/" # FS CHK URI infix 47GNUNET_FS_URI_CHK_INFIX = "chk/" # FS CHK URI infix
47 48
48 49
49def encode_data_to_string (data): 50def encode_data_to_string(data):
50 """Returns an ASCII encoding of the given data block like 51 """Returns an ASCII encoding of the given data block like
51 GNUNET_STRINGS_data_to_string() function. 52 GNUNET_STRINGS_data_to_string() function.
52 53
53 data: A bytearray representing the block of data which has to be encoded 54 data: A bytearray representing the block of data which has to be encoded
54 """ 55 """
55 echart = "0123456789ABCDEFGHIJKLMNOPQRSTUV" 56 echart = "0123456789ABCDEFGHIJKLMNOPQRSTUV"
56 assert (None != data) 57 assert (None != data)
57 assert (bytearray == type(data)) 58 assert (bytearray == type(data))
58 size = len(data) 59 size = len(data)
@@ -64,11 +65,11 @@ def encode_data_to_string (data):
64 out = "" 65 out = ""
65 while (rpos < size) or (vbit > 0): 66 while (rpos < size) or (vbit > 0):
66 if (rpos < size) and (vbit < 5): 67 if (rpos < size) and (vbit < 5):
67 bits = (bits << 8) | data[rpos] # eat 8 more bits 68 bits = (bits << 8) | data[rpos] # eat 8 more bits
68 rpos += 1 69 rpos += 1
69 vbit += 8 70 vbit += 8
70 if (vbit < 5): 71 if (vbit < 5):
71 bits <<= (5 - vbit) # zero-padding 72 bits <<= (5 - vbit) # zero-padding
72 assert (vbit == ((size * 8) % 5)) 73 assert (vbit == ((size * 8) % 5))
73 vbit = 5 74 vbit = 5
74 out += echart[(bits >> (vbit - 5)) & 31] 75 out += echart[(bits >> (vbit - 5)) & 31]
@@ -78,13 +79,13 @@ def encode_data_to_string (data):
78 return out; 79 return out;
79 80
80 81
81def sha512_hash (data): 82def sha512_hash(data):
82 """ Returns the sha512 hash of the given data. 83 """ Returns the sha512 hash of the given data.
83 84
84 data: string to hash 85 data: string to hash
85 """ 86 """
86 hash_obj = sha512() 87 hash_obj = sha512()
87 hash_obj.update (data) 88 hash_obj.update(data)
88 return hash_obj.digest() 89 return hash_obj.digest()
89 90
90 91
@@ -97,42 +98,44 @@ class AESKey:
97 cipher = None # The cipher object 98 cipher = None # The cipher object
98 KEY_SIZE = 32 # AES 256-bit key = 32 bytes 99 KEY_SIZE = 32 # AES 256-bit key = 32 bytes
99 IV_SIZE = AES.block_size # Initialization vector size (= AES block size) 100 IV_SIZE = AES.block_size # Initialization vector size (= AES block size)
100 101
101 def __init__ (self, passphrase): 102 def __init__(self, passphrase):
102 """Creates a new AES key. 103 """Creates a new AES key.
103 104
104 passphrase: string containing the passphrase to get the AES key and 105 passphrase: string containing the passphrase to get the AES key and
105 initialization vector 106 initialization vector
106 """ 107 """
107 passphrase = bytearray (passphrase); 108 passphrase = bytearray(passphrase);
108 self.key = bytearray (self.KEY_SIZE) 109 self.key = bytearray(self.KEY_SIZE)
109 self.iv = bytearray (self.IV_SIZE) 110 self.iv = bytearray(self.IV_SIZE)
110 if (len (passphrase) > self.KEY_SIZE): 111 if (len(passphrase) > self.KEY_SIZE):
111 self.key = passphrase[:self.KEY_SIZE] 112 self.key = passphrase[:self.KEY_SIZE]
112 passphrase = passphrase[self.KEY_SIZE:] 113 passphrase = passphrase[self.KEY_SIZE:]
113 if (len (passphrase) > self.IV_SIZE): 114 if (len(passphrase) > self.IV_SIZE):
114 self.iv = passphrase[:self.IV_SIZE] 115 self.iv = passphrase[:self.IV_SIZE]
115 else: 116 else:
116 self.iv[0:len (passphrase)] = passphrase 117 self.iv[0:len(passphrase)] = passphrase
117 else: 118 else:
118 self.key[0:len (passphrase)] = passphrase 119 self.key[0:len(passphrase)] = passphrase
119 self.key = str (self.key) 120 self.key = str(self.key)
120 self.iv = str (self.iv) 121 self.iv = str(self.iv)
121 assert (len(self.key) == self.KEY_SIZE) 122 assert (len(self.key) == self.KEY_SIZE)
122 assert (len(self.iv) == self.IV_SIZE) 123 assert (len(self.iv) == self.IV_SIZE)
123 124
124def setup_aes_cipher_ (aes_key): 125
126def setup_aes_cipher_(aes_key):
125 """Initializes the AES object with settings similar to those in GNUnet. 127 """Initializes the AES object with settings similar to those in GNUnet.
126 128
127 aes_key: the AESKey object 129 aes_key: the AESKey object
128 Returns the newly initialized AES object 130 Returns the newly initialized AES object
129 """ 131 """
130 return AES.new (aes_key.key, AES.MODE_CFB, aes_key.iv, segment_size=128) 132 return AES.new(aes_key.key, AES.MODE_CFB, aes_key.iv, segment_size=128)
133
131 134
132def aes_pad_ (data): 135def aes_pad_(data):
133 """Adds padding to the data such that the size of the data is a multiple of 136 """Adds padding to the data such that the size of the data is a multiple of
134 16 bytes 137 16 bytes
135 138
136 data: the data string 139 data: the data string
137 Returns a tuple:(pad_len, data). pad_len denotes the number of bytes added 140 Returns a tuple:(pad_len, data). pad_len denotes the number of bytes added
138 as padding; data is the new data string with padded bytes at the end 141 as padding; data is the new data string with padded bytes at the end
@@ -140,32 +143,34 @@ def aes_pad_ (data):
140 pad_len = len(data) % 16 143 pad_len = len(data) % 16
141 if (0 != pad_len): 144 if (0 != pad_len):
142 pad_len = 16 - pad_len 145 pad_len = 16 - pad_len
143 pad_bytes = bytearray (15) 146 pad_bytes = bytearray(15)
144 data += str(pad_bytes[:pad_len]) 147 data += str(pad_bytes[:pad_len])
145 return (pad_len, data) 148 return (pad_len, data)
146 149
147def aes_encrypt (aes_key, data): 150
151def aes_encrypt(aes_key, data):
148 """Encrypts the given data using AES. 152 """Encrypts the given data using AES.
149 153
150 aes_key: the AESKey object to use for AES encryption 154 aes_key: the AESKey object to use for AES encryption
151 data: the data string to encrypt 155 data: the data string to encrypt
152 """ 156 """
153 (pad_len, data) = aes_pad_ (data) 157 (pad_len, data) = aes_pad_(data)
154 cipher = setup_aes_cipher_ (aes_key) 158 cipher = setup_aes_cipher_(aes_key)
155 enc_data = cipher.encrypt (data) 159 enc_data = cipher.encrypt(data)
156 if (0 != pad_len): 160 if (0 != pad_len):
157 enc_data = enc_data[:-pad_len] 161 enc_data = enc_data[:-pad_len]
158 return enc_data 162 return enc_data
159 163
160def aes_decrypt (aes_key, data): 164
165def aes_decrypt(aes_key, data):
161 """Decrypts the given data using AES 166 """Decrypts the given data using AES
162 167
163 aes_key: the AESKey object to use for AES decryption 168 aes_key: the AESKey object to use for AES decryption
164 data: the data string to decrypt 169 data: the data string to decrypt
165 """ 170 """
166 (pad_len, data) = aes_pad_ (data) 171 (pad_len, data) = aes_pad_(data)
167 cipher = setup_aes_cipher_ (aes_key) 172 cipher = setup_aes_cipher_(aes_key)
168 ptext = cipher.decrypt (data) 173 ptext = cipher.decrypt(data)
169 if (0 != pad_len): 174 if (0 != pad_len):
170 ptext = ptext[:-pad_len] 175 ptext = ptext[:-pad_len]
171 return ptext 176 return ptext
@@ -187,9 +192,9 @@ class Chk:
187 self.fsize = size 192 self.fsize = size
188 193
189 def uri(self): 194 def uri(self):
190 sizestr = repr (self.fsize) 195 sizestr = repr(self.fsize)
191 if isinstance (self.fsize, long): 196 if isinstance(self.fsize, long):
192 sizestr = sizestr[:-1] 197 sizestr = sizestr[:-1]
193 return GNUNET_FS_URI_PREFIX + GNUNET_FS_URI_CHK_INFIX + \ 198 return GNUNET_FS_URI_PREFIX + GNUNET_FS_URI_CHK_INFIX + \
194 encode_data_to_string(bytearray(self.key)) + "." + \ 199 encode_data_to_string(bytearray(self.key)) + "." + \
195 encode_data_to_string(bytearray(self.query)) + "." + \ 200 encode_data_to_string(bytearray(self.query)) + "." + \
@@ -198,7 +203,7 @@ class Chk:
198 203
199def compute_depth_(size): 204def compute_depth_(size):
200 """Computes the depth of the hash tree. 205 """Computes the depth of the hash tree.
201 206
202 size: the size of the file whose tree's depth has to be computed 207 size: the size of the file whose tree's depth has to be computed
203 Returns the depth of the tree. Always > 0. 208 Returns the depth of the tree. Always > 0.
204 """ 209 """
@@ -211,6 +216,7 @@ def compute_depth_(size):
211 fl = fl * CHK_PER_INODE 216 fl = fl * CHK_PER_INODE
212 return depth 217 return depth
213 218
219
214def compute_tree_size_(depth): 220def compute_tree_size_(depth):
215 """Calculate how many bytes of payload a block tree of the given depth MAY 221 """Calculate how many bytes of payload a block tree of the given depth MAY
216 correspond to at most (this function ignores the fact that some blocks will 222 correspond to at most (this function ignores the fact that some blocks will
@@ -226,10 +232,11 @@ def compute_tree_size_(depth):
226 rsize *= CHK_PER_INODE 232 rsize *= CHK_PER_INODE
227 return rsize 233 return rsize
228 234
235
229def compute_chk_offset_(depth, end_offset): 236def compute_chk_offset_(depth, end_offset):
230 """Compute the offset of the CHK for the current block in the IBlock 237 """Compute the offset of the CHK for the current block in the IBlock
231 above 238 above
232 239
233 depth: depth of the IBlock in the tree (aka overall number of tree levels 240 depth: depth of the IBlock in the tree (aka overall number of tree levels
234 minus depth); 0 == DBLOCK 241 minus depth); 0 == DBLOCK
235 end_offset: current offset in the overall file, at the *beginning* of the 242 end_offset: current offset in the overall file, at the *beginning* of the
@@ -243,12 +250,13 @@ def compute_chk_offset_(depth, end_offset):
243 ret = end_offset / bds 250 ret = end_offset / bds
244 return ret % CHK_PER_INODE 251 return ret % CHK_PER_INODE
245 252
253
246def compute_iblock_size_(depth, offset): 254def compute_iblock_size_(depth, offset):
247 """Compute the size of the current IBLOCK. The encoder is triggering the 255 """Compute the size of the current IBLOCK. The encoder is triggering the
248 calculation of the size of an IBLOCK at the *end* (hence end_offset) of its 256 calculation of the size of an IBLOCK at the *end* (hence end_offset) of its
249 construction. The IBLOCK maybe a full or a partial IBLOCK, and this 257 construction. The IBLOCK maybe a full or a partial IBLOCK, and this
250 function is to calculate how long it should be. 258 function is to calculate how long it should be.
251 259
252 depth: depth of the IBlock in the tree, 0 would be a DBLOCK, must be > 0 260 depth: depth of the IBlock in the tree, 0 would be a DBLOCK, must be > 0
253 (this function is for IBLOCKs only!) 261 (this function is for IBLOCKs only!)
254 offset: current offset in the payload (!) of the overall file, must be > 0 262 offset: current offset in the payload (!) of the overall file, must be > 0
@@ -257,7 +265,7 @@ def compute_iblock_size_(depth, offset):
257 """ 265 """
258 assert (depth > 0) 266 assert (depth > 0)
259 assert (offset > 0) 267 assert (offset > 0)
260 bds = compute_tree_size_ (depth) 268 bds = compute_tree_size_(depth)
261 mod = offset % bds 269 mod = offset % bds
262 if mod is 0: 270 if mod is 0:
263 ret = CHK_PER_INODE 271 ret = CHK_PER_INODE
@@ -278,46 +286,46 @@ def compute_rootchk(readin, size):
278 """ 286 """
279 depth = compute_depth_(size); 287 depth = compute_depth_(size);
280 current_depth = 0 288 current_depth = 0
281 chks = [None] * (depth * CHK_PER_INODE) # list buffer 289 chks = [None] * (depth * CHK_PER_INODE) # list buffer
282 read_offset = 0 290 read_offset = 0
283 logging.debug("Begining to calculate tree hash with depth: "+ repr(depth)) 291 logging.debug("Begining to calculate tree hash with depth: " + repr(depth))
284 while True: 292 while True:
285 if (depth == current_depth): 293 if (depth == current_depth):
286 off = CHK_PER_INODE * (depth - 1) 294 off = CHK_PER_INODE * (depth - 1)
287 assert (chks[off] is not None) 295 assert (chks[off] is not None)
288 logging.debug("Encoding done, reading CHK `"+ chks[off].query + \ 296 logging.debug("Encoding done, reading CHK `" + chks[off].query + \
289 "' from "+ repr(off) +"\n") 297 "' from " + repr(off) + "\n")
290 uri_chk = chks[off] 298 uri_chk = chks[off]
291 assert (size == read_offset) 299 assert (size == read_offset)
292 uri_chk.setSize (size) 300 uri_chk.setSize(size)
293 return uri_chk 301 return uri_chk
294 if (0 == current_depth): 302 if (0 == current_depth):
295 pt_size = min(DBLOCK_SIZE, size - read_offset); 303 pt_size = min(DBLOCK_SIZE, size - read_offset);
296 try: 304 try:
297 pt_block = readin.read(pt_size) 305 pt_block = readin.read(pt_size)
298 except IOError: 306 except IOError:
299 logging.warning ("Error reading input file stream") 307 logging.warning("Error reading input file stream")
300 return None 308 return None
301 else: 309 else:
302 pt_elements = compute_iblock_size_(current_depth, read_offset) 310 pt_elements = compute_iblock_size_(current_depth, read_offset)
303 pt_block = "" 311 pt_block = ""
304 pt_block = \ 312 pt_block = \
305 reduce ((lambda ba, chk: 313 reduce((lambda ba, chk:
306 ba + (chk.key + chk.query)), 314 ba + (chk.key + chk.query)),
307 chks[(current_depth - 1) * CHK_PER_INODE:][:pt_elements], 315 chks[(current_depth - 1) * CHK_PER_INODE:][:pt_elements],
308 pt_block) 316 pt_block)
309 pt_size = pt_elements * (CHK_HASH_SIZE + CHK_QUERY_SIZE) 317 pt_size = pt_elements * (CHK_HASH_SIZE + CHK_QUERY_SIZE)
310 assert (len(pt_block) == pt_size) 318 assert (len(pt_block) == pt_size)
311 assert (pt_size <= DBLOCK_SIZE) 319 assert (pt_size <= DBLOCK_SIZE)
312 off = compute_chk_offset_ (current_depth, read_offset) 320 off = compute_chk_offset_(current_depth, read_offset)
313 logging.debug ("Encoding data at offset "+ repr(read_offset) + \ 321 logging.debug("Encoding data at offset " + repr(read_offset) + \
314 " and depth "+ repr(current_depth) +" with block " \ 322 " and depth " + repr(current_depth) + " with block " \
315 "size "+ repr(pt_size) +" and target CHK offset "+ \ 323 "size " + repr(pt_size) + " and target CHK offset " + \
316 repr(current_depth * CHK_PER_INODE)) 324 repr(current_depth * CHK_PER_INODE))
317 pt_hash = sha512_hash (pt_block) 325 pt_hash = sha512_hash(pt_block)
318 pt_aes_key = AESKey (pt_hash) 326 pt_aes_key = AESKey(pt_hash)
319 pt_enc = aes_encrypt (pt_aes_key, pt_block) 327 pt_enc = aes_encrypt(pt_aes_key, pt_block)
320 pt_enc_hash = sha512_hash (pt_enc) 328 pt_enc_hash = sha512_hash(pt_enc)
321 chk = Chk(pt_hash, pt_enc_hash) 329 chk = Chk(pt_hash, pt_enc_hash)
322 chks[(current_depth * CHK_PER_INODE) + off] = chk 330 chks[(current_depth * CHK_PER_INODE) + off] = chk
323 if (0 == current_depth): 331 if (0 == current_depth):
@@ -332,44 +340,43 @@ def compute_rootchk(readin, size):
332 current_depth = 0 340 current_depth = 0
333 341
334 342
335def chkuri_from_path (path): 343def chkuri_from_path(path):
336 """Returns the CHK URI of the file at the given path. 344 """Returns the CHK URI of the file at the given path.
337 345
338 path: the path of the file whose CHK has to be calculated 346 path: the path of the file whose CHK has to be calculated
339 """ 347 """
340 size = os.path.getsize (path) 348 size = os.path.getsize(path)
341 readin = open (path, "rb") 349 readin = open(path, "rb")
342 chk = compute_rootchk (readin, size) 350 chk = compute_rootchk(readin, size)
343 readin.close() 351 readin.close()
344 return chk.uri() 352 return chk.uri()
345 353
346def usage (): 354
355def usage():
347 """Prints help about using this script.""" 356 """Prints help about using this script."""
348 print """ 357 print("""
349Usage: gnunet-chk.py [options] file 358Usage: gnunet-chk.py [options] file
350Prints the Content Hash Key of given file in GNUNET-style URI. 359Prints the Content Hash Key of given file in GNUNET-style URI.
351 360
352Options: 361Options:
353 -h, --help : prints this message 362 -h, --help : prints this message
354""" 363""")
355 364
356 365
357if '__main__' == __name__: 366if '__main__' == __name__:
358 try: 367 try:
359 opts, args = getopt.getopt(sys.argv[1:], 368 opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
360 "h",
361 ["help"])
362 except getopt.GetoptError, err: 369 except getopt.GetoptError, err:
363 print err 370 print(err)
364 print "Exception occured" 371 print("Exception occured")
365 usage() 372 usage()
366 sys.exit(2) 373 sys.exit(2)
367 for option, value in opts: 374 for option, value in opts:
368 if option in ("-h", "--help"): 375 if option in("-h", "--help"):
369 usage() 376 usage()
370 sys.exit(0) 377 sys.exit(0)
371 if len(args) != 1: 378 if len(args) != 1:
372 print "Incorrect number of arguments passed" 379 print("Incorrect number of arguments passed")
373 usage() 380 usage()
374 sys.exit(1) 381 sys.exit(1)
375 print chkuri_from_path (args[0]) 382 print chkuri_from_path(args[0])