<?xml version="1.0" encoding="UTF-8"?>
<leo_file>
<leo_header file_format="2" tnodes="0" max_tnode_index="153" clone_windows="0"/>
<globals body_outline_ratio="0.384146341463">
	<global_window_position top="57" left="324" height="624" width="892"/>
	<global_log_window_position top="0" left="0" height="0" width="0"/>
</globals>
<preferences>
</preferences>
<find_panel_settings>
	<find_string></find_string>
	<change_string></change_string>
</find_panel_settings>
<vnodes>
<v t="davidmcnab.121303201707" a="E"><vh>pySSL</vh>
<v t="davidmcnab.121303201707.1" a="E" tnodeList="davidmcnab.121303201707.1,davidmcnab.121303201707.2,davidmcnab.121303201707.3,davidmcnab.121303201707.4,davidmcnab.121303201707.5,davidmcnab.121303201707.6,davidmcnab.121303201707.7,davidmcnab.121303201707.8,davidmcnab.121303201707.9,davidmcnab.121303201707.10,davidmcnab.121303201707.11,davidmcnab.121303201707.12,davidmcnab.121303201707.13,aum.20040819015743,davidmcnab.121303201707.14,davidmcnab.121303201707.15,aum.20040819131129,davidmcnab.121303201707.16,davidmcnab.121303201707.17,davidmcnab.121303201707.18,davidmcnab.121303201707.19,davidmcnab.121303201707.20,davidmcnab.121303201707.21,davidmcnab.121303201707.22,davidmcnab.121303201707.23,davidmcnab.121303201707.24,davidmcnab.121303201707.25,davidmcnab.121303201707.26,davidmcnab.121303201707.27,davidmcnab.121303201707.28,davidmcnab.121303201707.29,davidmcnab.121303201707.30,davidmcnab.121303201707.31,davidmcnab.121303201707.32,davidmcnab.121303201707.33,davidmcnab.121303201707.34,davidmcnab.121303201707.35,davidmcnab.121303201707.36,davidmcnab.121303201707.37,davidmcnab.121303201707.38,davidmcnab.121303201707.39,davidmcnab.121303201707.40,davidmcnab.121303201707.41,davidmcnab.121303201707.42,davidmcnab.121303201707.43,davidmcnab.121303201707.44,davidmcnab.121303201707.45,davidmcnab.121303201707.46,davidmcnab.121303201707.47,davidmcnab.121303201707.48,davidmcnab.121303201707.49,davidmcnab.121303201707.50,davidmcnab.121303201707.51,davidmcnab.121303201707.52,aum.20040819015001,aum.20040819015042,aum.20040819015125,aum.20040819015157,aum.20040819124740,aum.20040819131621,aum.20040819140140,aum.20040819140214,aum.20040819135812,aum.20040819135941,aum.20040819132953,aum.20040819134128,aum.20040819132953.1,aum.20040819134151,davidmcnab.121303201707.53,davidmcnab.121303201707.54,davidmcnab.121303201707.55,davidmcnab.121303201707.56,davidmcnab.121303201707.57,davidmcnab.121303201707.58,davidmcnab.121303201707.59,davidmcnab.121303201707.60,davidmcnab.121303201707.61,davidmcnab.121303201707.62,davidmcnab.121303201707.63,davidmcnab.121303201707.64,davidmcnab.121303201707.65,davidmcnab.121303201707.66,davidmcnab.121303201707.67,davidmcnab.121303201707.68,davidmcnab.121303201707.69,davidmcnab.121303201707.70,davidmcnab.121303201707.71,davidmcnab.121303201707.72,davidmcnab.121303201707.73,davidmcnab.121303201707.74,davidmcnab.121303201707.75,davidmcnab.121303201707.76,davidmcnab.121303201707.77,davidmcnab.121303201707.78,davidmcnab.121303201707.79,davidmcnab.121303201707.80,davidmcnab.121303201707.81,davidmcnab.121303201707.82,davidmcnab.121303201707.83,davidmcnab.121303201707.84,davidmcnab.121303201707.85,davidmcnab.121303201707.86,davidmcnab.121303201707.87,davidmcnab.121303201707.88,davidmcnab.121303201707.89,davidmcnab.121303201707.90,davidmcnab.121303201707.91,davidmcnab.121303201707.92,davidmcnab.121303201707.93,davidmcnab.121303201707.94,davidmcnab.121303201707.95,davidmcnab.121303201707.96,davidmcnab.121303201707.97,davidmcnab.121303201707.98,davidmcnab.121303201707.99,davidmcnab.121303201707.100,davidmcnab.121303201707.101,davidmcnab.121303201707.102,davidmcnab.121303201707.103,davidmcnab.121303201707.104,davidmcnab.121303201707.105,davidmcnab.121303201707.106,davidmcnab.121303201707.107,davidmcnab.121303201707.108,davidmcnab.121303201707.109,davidmcnab.121303201707.110,davidmcnab.121303201707.111,davidmcnab.121303201707.112,davidmcnab.121303201707.113,davidmcnab.121303201707.114,davidmcnab.121303201707.115,davidmcnab.121303201707.116,davidmcnab.121303201707.117,davidmcnab.121303201707.118,davidmcnab.121303201707.119,davidmcnab.121303201707.120,davidmcnab.121303201707.121,davidmcnab.121303201707.122,davidmcnab.121303201707.123,davidmcnab.121303201707.124,davidmcnab.121303201707.125,davidmcnab.121303201707.126,davidmcnab.121303201707.127,davidmcnab.121303201707.128,davidmcnab.121303201707.129,davidmcnab.121303201707.130,davidmcnab.010604143156,davidmcnab.121303201707.131,davidmcnab.121303201707.132,davidmcnab.121303201707.133,davidmcnab.121303201707.134,davidmcnab.121303201707.135,davidmcnab.121303201707.136,davidmcnab.121303201707.137,davidmcnab.121303201707.138,davidmcnab.121303201707.139,davidmcnab.121303201707.140,davidmcnab.121303201707.141,davidmcnab.121303201707.142"><vh>@file SSLCrypto.pyx</vh>
<v t="davidmcnab.121303201707.2"><vh>imports</vh></v>
<v t="davidmcnab.121303201707.3"><vh>Exceptions</vh></v>
<v t="davidmcnab.121303201707.4" a="E"><vh>cdef externs</vh>
<v t="davidmcnab.121303201707.5"><vh>Python.h</vh></v>
<v t="davidmcnab.121303201707.6"><vh>string.h</vh></v>
<v t="davidmcnab.121303201707.7"><vh>stdio.h</vh></v>
<v t="davidmcnab.121303201707.8"><vh>stdlib.h</vh></v>
<v t="davidmcnab.121303201707.9"><vh>openssl/crypto.h</vh></v>
<v t="davidmcnab.121303201707.10"><vh>openssl/bn.h</vh></v>
<v t="davidmcnab.121303201707.11"><vh>openssl/dh.h</vh></v>
<v t="davidmcnab.121303201707.12"><vh>openssl/blowfish.h</vh></v>
<v t="davidmcnab.121303201707.13"><vh>openssl/rsa.h</vh></v>
<v t="aum.20040819015743"><vh>openssl/dsa.h</vh></v>
<v t="davidmcnab.121303201707.14"><vh>openssl/rand.h</vh></v>
<v t="davidmcnab.121303201707.15"><vh>openssl/objects.h</vh></v>
<v t="aum.20040819131129"><vh>pyrex_fixup.h</vh></v>
</v>
<v t="davidmcnab.121303201707.16" a="E"><vh>globals</vh>
<v t="davidmcnab.121303201707.17"><vh>hardPrimes</vh></v>
</v>
<v t="davidmcnab.121303201707.18"><vh>class dh</vh>
<v t="davidmcnab.121303201707.19"><vh>&lt;&lt; class dh declarations &gt;&gt;</vh></v>
<v t="davidmcnab.121303201707.20"><vh>C vars</vh></v>
<v t="davidmcnab.121303201707.21"><vh>__new__</vh></v>
<v t="davidmcnab.121303201707.22"><vh>__dealloc__</vh></v>
<v t="davidmcnab.121303201707.23"><vh>genParms</vh></v>
<v t="davidmcnab.121303201707.24"><vh>importParms</vh></v>
<v t="davidmcnab.121303201707.25"><vh>exportParms</vh></v>
<v t="davidmcnab.121303201707.26"><vh>genPubKey</vh></v>
<v t="davidmcnab.121303201707.27"><vh>privKey</vh></v>
<v t="davidmcnab.121303201707.28"><vh>genSessKey</vh></v>
</v>
<v t="davidmcnab.121303201707.29" a="E"><vh>class blowfish</vh>
<v t="davidmcnab.121303201707.30"><vh>C vars</vh></v>
<v t="davidmcnab.121303201707.31"><vh>__new__</vh></v>
<v t="davidmcnab.121303201707.32"><vh>__dealloc__</vh></v>
<v t="davidmcnab.121303201707.33"><vh>setKey</vh></v>
<v t="davidmcnab.121303201707.34"><vh>setIV</vh></v>
<v t="davidmcnab.121303201707.35"><vh>encrypt</vh></v>
<v t="davidmcnab.121303201707.36"><vh>decrypt</vh></v>
</v>
<v t="davidmcnab.121303201707.37" a="E"><vh>class rsa</vh>
<v t="davidmcnab.121303201707.38"><vh>C attributes</vh></v>
<v t="davidmcnab.121303201707.39"><vh>__new__</vh></v>
<v t="davidmcnab.121303201707.40"><vh>__dealloc__</vh></v>
<v t="davidmcnab.121303201707.41"><vh>generateKey</vh></v>
<v t="davidmcnab.121303201707.42"><vh>pubKey</vh></v>
<v t="davidmcnab.121303201707.43"><vh>privKey</vh></v>
<v t="davidmcnab.121303201707.44"><vh>rawprimes()</vh></v>
<v t="davidmcnab.121303201707.45"><vh>importPubKey</vh></v>
<v t="davidmcnab.121303201707.46"><vh>importPrivKey</vh></v>
<v t="davidmcnab.121303201707.47"><vh>hasPrivateKey</vh></v>
<v t="davidmcnab.121303201707.48"><vh>encrypt</vh></v>
<v t="davidmcnab.121303201707.49"><vh>decrypt</vh></v>
<v t="davidmcnab.121303201707.50"><vh>maxSize</vh></v>
<v t="davidmcnab.121303201707.51"><vh>sign</vh></v>
<v t="davidmcnab.121303201707.52"><vh>verify</vh></v>
</v>
<v t="aum.20040819015001" a="E"><vh>class dsa</vh>
<v t="aum.20040819015042"><vh>C attributes</vh></v>
<v t="aum.20040819015125"><vh>__new__</vh></v>
<v t="aum.20040819015157"><vh>__dealloc__</vh></v>
<v t="aum.20040819124740"><vh>generateParameters</vh></v>
<v t="aum.20040819131621"><vh>generateKey</vh></v>
<v t="aum.20040819140140"><vh>pubKey</vh></v>
<v t="aum.20040819140214"><vh>privKey</vh></v>
<v t="aum.20040819135812"><vh>importPubKey</vh></v>
<v t="aum.20040819135941"><vh>importPrivKey</vh></v>
<v t="aum.20040819132953"><vh>sign</vh></v>
<v t="aum.20040819134128"><vh>signSha</vh></v>
<v t="aum.20040819132953.1"><vh>verify</vh></v>
<v t="aum.20040819134151"><vh>verifySha</vh></v>
</v>
<v t="davidmcnab.121303201707.53"><vh>class ElGamal</vh>
<v t="davidmcnab.121303201707.54"><vh>attribs</vh></v>
<v t="davidmcnab.121303201707.55"><vh>__init__</vh></v>
<v t="davidmcnab.121303201707.56"><vh>generateKey</vh></v>
<v t="davidmcnab.121303201707.57"><vh>genk</vh></v>
<v t="davidmcnab.121303201707.58"><vh>construct</vh></v>
<v t="davidmcnab.121303201707.59"><vh>__getstate__</vh></v>
<v t="davidmcnab.121303201707.60"><vh>__setstate__</vh></v>
<v t="davidmcnab.121303201707.61"><vh>encrypt</vh></v>
<v t="davidmcnab.121303201707.62"><vh>decrypt</vh></v>
<v t="davidmcnab.121303201707.63"><vh>sign</vh></v>
<v t="davidmcnab.121303201707.64"><vh>verify</vh></v>
<v t="davidmcnab.121303201707.65"><vh>importPubKey</vh></v>
<v t="davidmcnab.121303201707.66"><vh>importPrivKey</vh></v>
<v t="davidmcnab.121303201707.67"><vh>hasPrivateKey</vh></v>
<v t="davidmcnab.121303201707.68"><vh>pubKey</vh></v>
<v t="davidmcnab.121303201707.69"><vh>privkey</vh></v>
<v t="davidmcnab.121303201707.70"><vh>maxSize</vh></v>
<v t="davidmcnab.121303201707.71"><vh>__eq__</vh></v>
</v>
<v t="davidmcnab.121303201707.72"><vh>class key</vh>
<v t="davidmcnab.121303201707.73"><vh>&lt;&lt; class key declarations &gt;&gt;</vh></v>
<v t="davidmcnab.121303201707.74"><vh>__init__</vh></v>
<v t="davidmcnab.121303201707.75"><vh>makeNewKeys()</vh></v>
<v t="davidmcnab.121303201707.76"><vh>importKey()</vh></v>
<v t="davidmcnab.121303201707.77"><vh>exportKey()</vh></v>
<v t="davidmcnab.121303201707.78"><vh>exportKeyPrivate()</vh></v>
<v t="davidmcnab.121303201707.79"><vh>hasPrivateKey()</vh></v>
<v t="davidmcnab.121303201707.80"><vh>encString()</vh></v>
<v t="davidmcnab.121303201707.81"><vh>encStringToAscii()</vh></v>
<v t="davidmcnab.121303201707.82"><vh>decString()</vh></v>
<v t="davidmcnab.121303201707.83"><vh>decStringFromAscii()</vh></v>
<v t="davidmcnab.121303201707.84" a="E"><vh>Sign and Verify Methods</vh>
<v t="davidmcnab.121303201707.85"><vh>signString()</vh></v>
<v t="davidmcnab.121303201707.86"><vh>verifyString()</vh></v>
</v>
<v t="davidmcnab.121303201707.87"><vh>Raw Session Cipher Methods</vh>
<v t="davidmcnab.121303201707.88"><vh>getSessKey()</vh></v>
<v t="davidmcnab.121303201707.89"><vh>getSessIV()</vh></v>
<v t="davidmcnab.121303201707.90"><vh>setSessKey()</vh></v>
<v t="davidmcnab.121303201707.91"><vh>genSessKey()</vh></v>
<v t="davidmcnab.121303201707.92"><vh>encStringSess()</vh></v>
<v t="davidmcnab.121303201707.93"><vh>decStringSess()</vh></v>
</v>
<v t="davidmcnab.121303201707.94"><vh>test()</vh></v>
<v t="davidmcnab.121303201707.95"><vh>testAscii()</vh></v>
<v t="davidmcnab.121303201707.96"><vh>Stream Methods</vh>
<v t="davidmcnab.121303201707.97"><vh>encStart()</vh></v>
<v t="davidmcnab.121303201707.98"><vh>encNext()</vh></v>
<v t="davidmcnab.121303201707.99"><vh>encEnd()</vh></v>
<v t="davidmcnab.121303201707.100"><vh>decStart()</vh></v>
<v t="davidmcnab.121303201707.101"><vh>decNext()</vh></v>
<v t="davidmcnab.121303201707.102"><vh>decEnd()</vh></v>
</v>
<v t="davidmcnab.121303201707.103"><vh>Low Level</vh>
<v t="davidmcnab.121303201707.104"><vh>_wrap()</vh></v>
<v t="davidmcnab.121303201707.105"><vh>_unwrap()</vh></v>
<v t="davidmcnab.121303201707.106"><vh>_calcPubBlkSize()</vh></v>
<v t="davidmcnab.121303201707.107"><vh>_encRawPub()</vh></v>
<v t="davidmcnab.121303201707.108"><vh>_decRawPub()</vh></v>
<v t="davidmcnab.121303201707.109"><vh>_initBlkCipher()</vh></v>
<v t="davidmcnab.121303201707.110"><vh>_calcSesBlkSize()</vh></v>
<v t="davidmcnab.121303201707.111"><vh>_testPubKey()</vh></v>
<v t="davidmcnab.121303201707.112"><vh>_rawPubKey()</vh></v>
<v t="davidmcnab.121303201707.113"><vh>_rawPrivKey()</vh></v>
<v t="davidmcnab.121303201707.114"><vh>_random</vh></v>
<v t="davidmcnab.121303201707.115"><vh>_genNewSessKey()</vh></v>
<v t="davidmcnab.121303201707.116"><vh>_setNewSessKey()</vh></v>
</v>
</v>
<v t="davidmcnab.121303201707.117" a="E"><vh>Misc Functions</vh>
<v t="davidmcnab.121303201707.118" a="E"><vh>ElGamal globals</vh>
<v t="davidmcnab.121303201707.119"><vh>rndfunc</vh></v>
<v t="davidmcnab.121303201707.120"><vh>size</vh></v>
<v t="davidmcnab.121303201707.121"><vh>GCD</vh></v>
<v t="davidmcnab.121303201707.122"><vh>inverse</vh></v>
<v t="davidmcnab.121303201707.123"><vh>long_to_bytes</vh></v>
<v t="davidmcnab.121303201707.124"><vh>bytes_to_long</vh></v>
</v>
<v t="davidmcnab.121303201707.125"><vh>genprime</vh></v>
<v t="davidmcnab.121303201707.126"><vh>callback()</vh></v>
<v t="davidmcnab.121303201707.127"><vh>genrandom</vh></v>
<v t="davidmcnab.121303201707.128"><vh>bn2pyLong()</vh></v>
<v t="davidmcnab.121303201707.129"><vh>pyLong2bn()</vh></v>
<v t="davidmcnab.121303201707.130"><vh>randomseed</vh></v>
<v t="davidmcnab.010604143156"><vh>_exctest</vh></v>
<v t="davidmcnab.121303201707.131"><vh>_die()</vh></v>
</v>
<v t="davidmcnab.121303201707.132"><vh>Bencoder functions</vh>
<v t="davidmcnab.121303201707.133"><vh>imports</vh></v>
<v t="davidmcnab.121303201707.134"><vh>global data</vh></v>
<v t="davidmcnab.121303201707.135"><vh>decode_int</vh></v>
<v t="davidmcnab.121303201707.136"><vh>decode_string</vh></v>
<v t="davidmcnab.121303201707.137"><vh>decode_list</vh></v>
<v t="davidmcnab.121303201707.138"><vh>decode_dict</vh></v>
<v t="davidmcnab.121303201707.139"><vh>bdecode_rec</vh></v>
<v t="davidmcnab.121303201707.140"><vh>bdecode</vh></v>
<v t="davidmcnab.121303201707.141"><vh>bencode_rec</vh></v>
<v t="davidmcnab.121303201707.142"><vh>bencode</vh></v>
</v>
</v>
<v t="davidmcnab.121303201707.143"><vh>@file bencode.py</vh>
<v t="davidmcnab.121303201707.132" a="E"><vh>Bencoder functions</vh>
<v t="davidmcnab.121303201707.133"><vh>imports</vh></v>
<v t="davidmcnab.121303201707.134"><vh>global data</vh></v>
<v t="davidmcnab.121303201707.135"><vh>decode_int</vh></v>
<v t="davidmcnab.121303201707.136"><vh>decode_string</vh></v>
<v t="davidmcnab.121303201707.137"><vh>decode_list</vh></v>
<v t="davidmcnab.121303201707.138"><vh>decode_dict</vh></v>
<v t="davidmcnab.121303201707.139"><vh>bdecode_rec</vh></v>
<v t="davidmcnab.121303201707.140"><vh>bdecode</vh></v>
<v t="davidmcnab.121303201707.141"><vh>bencode_rec</vh></v>
<v t="davidmcnab.121303201707.142"><vh>bencode</vh></v>
</v>
</v>
<v t="davidmcnab.121303201707.144" a="E" tnodeList="davidmcnab.121303201707.144,davidmcnab.121303201707.145,davidmcnab.121303201707.146,davidmcnab.121303201707.17,davidmcnab.121303201707.147,davidmcnab.121303201707.53,davidmcnab.121303201707.54,davidmcnab.121303201707.55,davidmcnab.121303201707.56,davidmcnab.121303201707.57,davidmcnab.121303201707.58,davidmcnab.121303201707.59,davidmcnab.121303201707.60,davidmcnab.121303201707.61,davidmcnab.121303201707.62,davidmcnab.121303201707.63,davidmcnab.121303201707.64,davidmcnab.121303201707.65,davidmcnab.121303201707.66,davidmcnab.121303201707.67,davidmcnab.121303201707.68,davidmcnab.121303201707.69,davidmcnab.121303201707.70,davidmcnab.121303201707.71,davidmcnab.121303201707.118,davidmcnab.121303201707.119,davidmcnab.121303201707.120,davidmcnab.121303201707.121,davidmcnab.121303201707.122,davidmcnab.121303201707.123,davidmcnab.121303201707.124,davidmcnab.121303201707.132,davidmcnab.121303201707.133,davidmcnab.121303201707.134,davidmcnab.121303201707.135,davidmcnab.121303201707.136,davidmcnab.121303201707.137,davidmcnab.121303201707.138,davidmcnab.121303201707.139,davidmcnab.121303201707.140,davidmcnab.121303201707.141,davidmcnab.121303201707.142"><vh>@file ElGamal.py</vh>
<v t="davidmcnab.121303201707.145"><vh>imports</vh></v>
<v t="davidmcnab.121303201707.146" a="E"><vh>globals</vh>
<v t="davidmcnab.121303201707.17"><vh>hardPrimes</vh></v>
</v>
<v t="davidmcnab.121303201707.147" a="E"><vh>class error</vh></v>
<v t="davidmcnab.121303201707.53" a="E"><vh>class ElGamal</vh>
<v t="davidmcnab.121303201707.54"><vh>attribs</vh></v>
<v t="davidmcnab.121303201707.55"><vh>__init__</vh></v>
<v t="davidmcnab.121303201707.56"><vh>generateKey</vh></v>
<v t="davidmcnab.121303201707.57"><vh>genk</vh></v>
<v t="davidmcnab.121303201707.58"><vh>construct</vh></v>
<v t="davidmcnab.121303201707.59"><vh>__getstate__</vh></v>
<v t="davidmcnab.121303201707.60"><vh>__setstate__</vh></v>
<v t="davidmcnab.121303201707.61"><vh>encrypt</vh></v>
<v t="davidmcnab.121303201707.62"><vh>decrypt</vh></v>
<v t="davidmcnab.121303201707.63"><vh>sign</vh></v>
<v t="davidmcnab.121303201707.64"><vh>verify</vh></v>
<v t="davidmcnab.121303201707.65"><vh>importPubKey</vh></v>
<v t="davidmcnab.121303201707.66"><vh>importPrivKey</vh></v>
<v t="davidmcnab.121303201707.67"><vh>hasPrivateKey</vh></v>
<v t="davidmcnab.121303201707.68"><vh>pubKey</vh></v>
<v t="davidmcnab.121303201707.69"><vh>privkey</vh></v>
<v t="davidmcnab.121303201707.70"><vh>maxSize</vh></v>
<v t="davidmcnab.121303201707.71"><vh>__eq__</vh></v>
</v>
<v t="davidmcnab.121303201707.118" a="E"><vh>ElGamal globals</vh>
<v t="davidmcnab.121303201707.119"><vh>rndfunc</vh></v>
<v t="davidmcnab.121303201707.120"><vh>size</vh></v>
<v t="davidmcnab.121303201707.121"><vh>GCD</vh></v>
<v t="davidmcnab.121303201707.122"><vh>inverse</vh></v>
<v t="davidmcnab.121303201707.123"><vh>long_to_bytes</vh></v>
<v t="davidmcnab.121303201707.124" a="TV"><vh>bytes_to_long</vh></v>
</v>
<v t="davidmcnab.121303201707.132"><vh>Bencoder functions</vh>
<v t="davidmcnab.121303201707.133"><vh>imports</vh></v>
<v t="davidmcnab.121303201707.134"><vh>global data</vh></v>
<v t="davidmcnab.121303201707.135"><vh>decode_int</vh></v>
<v t="davidmcnab.121303201707.136"><vh>decode_string</vh></v>
<v t="davidmcnab.121303201707.137"><vh>decode_list</vh></v>
<v t="davidmcnab.121303201707.138"><vh>decode_dict</vh></v>
<v t="davidmcnab.121303201707.139"><vh>bdecode_rec</vh></v>
<v t="davidmcnab.121303201707.140"><vh>bdecode</vh></v>
<v t="davidmcnab.121303201707.141"><vh>bencode_rec</vh></v>
<v t="davidmcnab.121303201707.142"><vh>bencode</vh></v>
</v>
</v>
<v t="davidmcnab.121303201707.148" tnodeList="davidmcnab.121303201707.148"><vh>@file elgtest.py</vh></v>
<v t="aum.20040819140719" a="E" tnodeList="aum.20040819140719,aum.20040819141226,aum.20040819141226.1,aum.20040819141226.2"><vh>@file dsatest.py</vh>
<v t="aum.20040819141226"><vh>imports</vh></v>
<v t="aum.20040819141226.1"><vh>test</vh></v>
<v t="aum.20040819141226.2"><vh>mainline</vh></v>
</v>
</v>
</vnodes>
<tnodes>
<t tx="aum.20040819015001">cdef class dsa:
    """
    For DSA signature ciphers
    """
    @others
</t>
<t tx="aum.20040819015042">cdef DSA *dsaObj
cdef BN_CTX *bnCtx
</t>
<t tx="aum.20040819015125">def __new__(self):
    cdef DSA *dsaC
    dsaC = DSA_new()
    self.dsaObj = dsaC
    self.bnCtx = BN_CTX_new()
    BN_CTX_init(self.bnCtx)

</t>
<t tx="aum.20040819015157">def __dealloc__(self):
    #print "dealloc'ing dsa object"
    BN_CTX_free(self.bnCtx)
    DSA_free(self.dsaObj)

</t>
<t tx="aum.20040819015743">cdef extern from "openssl/dsa.h":

    #
    # Structs
    #
    ctypedef struct DSA:
        int pad
        long version
        int write_params

        BIGNUM *p
        BIGNUM *q
        BIGNUM *g

        BIGNUM *pub_key   # y public key
        BIGNUM *priv_key  # x private key

        BIGNUM *kinv 	    # Signing pre-calc
        BIGNUM *r         # Signing pre-calc

        int    flags
        # Normally used to cache montgomery values
        char   *method_mont_p
        int    references
        CRYPTO_EX_DATA ex_data
        void   *meth      # shouldn't use
        # functional reference if 'meth' is ENGINE-provided
        void   *engine

    cdef DSA *DSA_new()
    cdef void	DSA_free(DSA *r)
    cdef int	DSA_size(DSA *)
    cdef int	DSA_generate_key(DSA *a)
    cdef DSA *	DSA_generate_parameters(
        int bits,
		unsigned char *seed,
        int seed_len,
		int *counter_ret,
        unsigned long *h_ret,
        void (*callback)(int, int, void *),
        void *cb_arg)

    cdef int	DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)

    cdef int	DSA_sign(
        int type,
        unsigned char *dgst,
        int dlen,
        unsigned char *sig,
        unsigned int *siglen,
        DSA *dsa)
    cdef int	DSA_verify(
        int type,
        unsigned char *dgst,
        int dgst_len,
        unsigned char *sigbuf,
        int siglen,
        DSA *dsa)

    # ---------- prolly won't use these -------------------
    # "up" the DSA object's reference count
    cdef int	DSA_up_ref(DSA *r)
    # next 4 return -1 on error
    cdef int DSA_get_ex_new_index(
        long argl,
        void *argp,
        void *new_func,
        void *dup_func,
        void *free_func)
    cdef int DSA_set_ex_data(DSA *d, int idx, void *arg)
    cdef void *DSA_get_ex_data(DSA *d, int idx)
    cdef DSA *DSA_new_method(void *engine)
    cdef DSA *	d2i_DSAPublicKey(DSA **a, unsigned char **pp, long length)
    cdef DSA *	d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length)
    cdef DSA * 	d2i_DSAparams(DSA **a, unsigned char **pp, long length)

</t>
<t tx="aum.20040819124740">def generateParameters(self, seed=None, **kw):
    """
    Generate a set of DSA parameters, as with
    DSA_generate_parameters()
    
    Arguments:
        - seed - a string to use for seeding the PRNG, optional
        - func - a callback func which is periodically invoked to
          report generation progress, optional
    """
    cdef DSA *dobj
    cdef char *c_seed
    cdef int c_seed_len
    
    myCallback = kw.get('callback', None)

    if seed:
        PyString_AsStringAndSize(seed, &amp;c_seed, &amp;c_seed_len)
    else:
        c_seed = &lt;char *&gt;0
        c_seed_len = 0
    
    dobj = DSA_generate_parameters(
        1024, 
        &lt;unsigned char *&gt;c_seed, c_seed_len,
        &lt;int *&gt;0, &lt;unsigned long *&gt;0,
        callback, &lt;void *&gt;myCallback)

    if self.dsaObj != &lt;DSA *&gt;0:
        DSA_free(self.dsaObj)
    
    self.dsaObj = dobj

</t>
<t tx="aum.20040819131129">cdef extern from "pyrex_fixup.h":
    pass

</t>
<t tx="aum.20040819131621">def generateKey(self):
    """
    Given that generateParameters has already been called,
    generates the private/public keys
    """
    return DSA_generate_key(self.dsaObj)

</t>
<t tx="aum.20040819132953">def sign(self, raw):
    """
    Returns a signature of string 'raw'
    """
    cdef char *dgst
    cdef int dgstLen
    cdef char *sigret
    cdef unsigned int siglen
    cdef int res
    cdef int sigsize
    
    # get digest
    PyString_AsStringAndSize(raw, &amp;dgst, &amp;dgstLen)
    
    sigsize = DSA_size(self.dsaObj)
    
    # make space for returned sig
    sigret = &lt;char *&gt;malloc(sigsize + 1)
    
    # get sig
    res = DSA_sign(
        0,
        &lt;unsigned char *&gt;dgst, dgstLen,
        &lt;unsigned char *&gt;sigret, &amp;siglen,
        self.dsaObj)
    
    # convert back to sig
    sig = PyString_FromStringAndSize(sigret, siglen)

    # done with sigret buf
    free(sigret)
    
    # done
    return sig


</t>
<t tx="aum.20040819132953.1">def verify(self, raw, sig):
    """
    Attempts to validate signature 'sig' against string 'raw',
    returning True if sig is valid, or False if not
    """
    cdef char *dgst
    cdef int dgstLen

    cdef char *sigbuf
    cdef int siglen

    cdef int res
    cdef int sigsize
    
    # get digest
    PyString_AsStringAndSize(raw, &amp;dgst, &amp;dgstLen)
    
    # convert sig to C
    PyString_AsStringAndSize(sig, &amp;sigbuf, &amp;siglen)

    res = DSA_verify(
        0,
        &lt;unsigned char *&gt;dgst, dgstLen,
        &lt;unsigned char *&gt;sigbuf, siglen,
        self.dsaObj)
    
    if res == 1:
        return True
    else:
        #print "res=%s" % res
        return False

</t>
<t tx="aum.20040819134128">def signSha(self, raw):
    """
    Convenience method which sha1-hashes the string,
    then signs it
    """
    # hash the raw string
    h = sha.sha(raw).digest()
    
    return self.sign(h)
</t>
<t tx="aum.20040819134151">def verifySha(self, raw, sig):
    """
    Convenience method which sha1-hashes the string,
    then verifies it
    """
    # hash the raw string
    h = sha.sha(raw).digest()
    
    return self.verify(h, sig)

</t>
<t tx="aum.20040819135812">def importPubKey(self, params):
    """
    Imports public key parameters
    
    params is a tuple (p, q, g, y)
    """
    p, q, g, y = params[:4]
    
    self.dsaObj.p = pyLong2bn(p)
    self.dsaObj.q = pyLong2bn(q)
    self.dsaObj.g = pyLong2bn(g)
    self.dsaObj.pub_key = pyLong2bn(y)

</t>
<t tx="aum.20040819135941">def importPrivKey(self, params):
    """
    Imports public key parameters
    
    params is a tuple (p, q, g, y, x)
    """
    p, q, g, y, x = params
    
    self.dsaObj.p = pyLong2bn(p)
    self.dsaObj.q = pyLong2bn(q)
    self.dsaObj.g = pyLong2bn(g)
    self.dsaObj.pub_key = pyLong2bn(y)
    self.dsaObj.priv_key = pyLong2bn(x)

</t>
<t tx="aum.20040819140140">def pubKey(self):
    """
    Returns the public key for this object.&lt;br&gt;&lt;br&gt;

    Arguments:
      - None

    Returns:
      - Public key, as a tuple (p, q, g, y) (refer: Applied Cryptography)
    """

    return (bn2pyLong(self.dsaObj.p),
            bn2pyLong(self.dsaObj.q),
            bn2pyLong(self.dsaObj.g),
            bn2pyLong(self.dsaObj.pub_key),
            )

</t>
<t tx="aum.20040819140214">def privKey(self):
    """
    Returns the private key for this object.&lt;br&gt;&lt;br&gt;

    Arguments:
      - None

    Returns:
      - Private key, as a tuple (p, q, g, y, x) (refer: Applied Cryptography)
    """
    return (bn2pyLong(self.dsaObj.p),
            bn2pyLong(self.dsaObj.q),
            bn2pyLong(self.dsaObj.g),
            bn2pyLong(self.dsaObj.pub_key),
            bn2pyLong(self.dsaObj.priv_key),
            )

</t>
<t tx="aum.20040819140719">@first #! /usr/bin/env python
"""
A test routine for DSA sign/verify
"""
@others
</t>
<t tx="aum.20040819141226">from SSLCrypto import dsa

</t>
<t tx="aum.20040819141226.1">def test():

    d1 = dsa()
    
    d1.generateParameters()
    d1.generateKey()
    
    org = "Hello, this is a string we want to sign and verify"
    org1 = org + "x" # for attempting to defraud
    
    s = d1.signSha(org)
    
    if d1.verifySha(org, s):
        print "Signature verified ok"
        print "pass\n"
    else:
        print "Signature verify failed"
        return False
    
    if not d1.verifySha(org1, s):
        print "Signature failed on tampered string - good"
        print "pass\n"
    else:
        print "Signature verify passed on tampered string - bad"
        return False
    
    print "Creating whole new sig obj"
    d2 = dsa()
    pubkey = d1.pubKey()
    d2.importPubKey(pubkey)
    
    if d2.verifySha(org, s):
        print "Signature verified ok with pub-only obj"
        print "pass\n"
    else:
        print "Signature verify failed"
        return False
    
    if not d2.verifySha(org1, s):
        print "Signature failed on tampered string with pub-only obj - good"
        print "pass\n"
    else:
        print "Signature verify passed on tampered string with pub-only obj - bad"
        return False

    return True

</t>
<t tx="aum.20040819141226.2">if __name__ == '__main__':
    test()

</t>
<t tx="davidmcnab.010604143156">def _exctest():
    """
    Tests exception handling in pyrex"
    """
    print "about to raise exception"
    raise Exception("this is an exception")
</t>
<t tx="davidmcnab.121303201707"></t>
<t tx="davidmcnab.121303201707.1">@language python

"""
SSLCrypto - partial Python wrapper for SSL crypto

Contains an abstract class called &lt;b&gt;key&lt;/b&gt;, which provides
an effortlessly simple API for most common crypto operations.&lt;br&gt;

An almost totally-compatible replacement for ezPyCrypto

Also, features an implementation of ElGamal
"""
@others
</t>
<t tx="davidmcnab.121303201707.2">#import sys, types

#
# Crypto imports
#

#from pdb import set_trace as trace
#import pickle
import base64
import zlib
import md5
import sha
import types
import traceback
import struct
import random
import math
</t>
<t tx="davidmcnab.121303201707.3"># Define some exceptions for the various problems that can happen

class CryptoKeyError(Exception):
    "Attempt to import invalid key"

class CryptoCannotDecrypt(Exception):
    "Cannot decrypt - private key not present"

class CryptoNoPrivateKey(Exception):
    "Key object has no private key"

class CryptoInvalidCiphertext(Exception):
    "Ciphertext was not produced with SSLCrypto"

class CryptoInvalidSignature(Exception):
    "Signature text was not produced with SSLCrypto"

class CryptoInvalidElGamalK(Exception):
    "Invalid k parameter for ElGamal operation"
</t>
<t tx="davidmcnab.121303201707.4"># Extern declarations

@others

</t>
<t tx="davidmcnab.121303201707.5">cdef extern from "Python.h":
    object PyString_FromStringAndSize(char *, int)
    int PyString_AsStringAndSize(object obj, char **, int *)

</t>
<t tx="davidmcnab.121303201707.6">cdef extern from "string.h":

    cdef void *memset(void *s, int c, int n)
    cdef void *memcpy(void *dest, void *src, int n)
</t>
<t tx="davidmcnab.121303201707.7">cdef extern from "stdio.h":
    int printf(char *format,...)

</t>
<t tx="davidmcnab.121303201707.8">cdef extern from "stdlib.h":
    void *malloc(int size)
    void free(void *ptr)

</t>
<t tx="davidmcnab.121303201707.9">cdef extern from "openssl/crypto.h":
    void CRYPTO_free(void *)

    ctypedef struct CRYPTO_EX_DATA:
        void *sk
        int dummy

</t>
<t tx="davidmcnab.121303201707.10">cdef extern from "openssl/bn.h":
    ctypedef struct BIGNUM:
        unsigned long *d
        int top
        int dmax
        int neg
        int flags

    ctypedef unsigned long BN_ULONG

    ctypedef struct BN_MONT_CTX:
        int ri      # number of bits in R
        BIGNUM RR   # used to convert to montgomery form
        BIGNUM N    # The modulus
        BIGNUM Ni   # R*(1/R mod N) - N*Ni = 1
                    # (Ni is only stored for bignum algorithm)
        BN_ULONG n0 # least significant word of Ni
        int flags

    ctypedef struct BN_BLINDING:
        int init
        BIGNUM *A
        BIGNUM *Ai
        BIGNUM *mod

    ctypedef struct BN_CTX:
        int dummy

    cdef BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,
                                   BIGNUM *add, BIGNUM *rem,
                                   void (*callback)(int,int,void *),void *cb_arg)
    cdef BIGNUM *BN_rand(BIGNUM *rnd, int bits, int top, int bottom)



    cdef int BN_dec2bn(BIGNUM **a, char *str)
    cdef char *BN_bn2dec(BIGNUM *a)
    BIGNUM *BN_new()
    cdef void BN_free(BIGNUM *a)


    cdef BN_CTX *BN_CTX_new()
    cdef void BN_CTX_init(BN_CTX *c)
    cdef void BN_CTX_free(BN_CTX *c)

</t>
<t tx="davidmcnab.121303201707.11">cdef extern from "openssl/dh.h":

    ctypedef struct DH:
        int pad
        int version
        BIGNUM *p
        BIGNUM *g
        long length
        BIGNUM *pub_key
        BIGNUM *priv_key
        int flags
        char *method_mont_p
        # Place holders if we want to do X9.42 DH
        BIGNUM *q
        BIGNUM *j
        unsigned char *seed
        int seedlen
        BIGNUM *counter

        int references
        CRYPTO_EX_DATA ex_data
        void *meth
        void *engine
    
    cdef DH *DH_new()
    cdef void DH_free(DH *dh)
    cdef int DH_up_ref(DH *dh)
    cdef int DH_size(DH *dh)
    cdef int DH_get_ex_new_index(long argl, void *argp, void *new_func,
                                 void *dup_func, void *free_func)
    cdef int DH_set_ex_data(DH *d, int idx, void *arg)
    cdef void *DH_get_ex_data(DH *d, int idx)
    cdef DH *DH_generate_parameters(int prime_len,int generator,
                               void (*callback)(int,int,void *),void *cb_arg)
    cdef int DH_check(DH *dh,int *codes)
    cdef int DH_generate_key(DH *dh)
    cdef int DH_compute_key(unsigned char *key, BIGNUM *pub_key,DH *dh)
</t>
<t tx="davidmcnab.121303201707.12">
cdef extern from "openssl/blowfish.h":

    ctypedef enum BF_CONSTANTS:
        BF_ENCRYPT
        BF_DECRYPT
        BF_ROUNDS

    ctypedef long int BF_LONG

    ctypedef struct BF_KEY:
        BF_LONG P[BF_ROUNDS+2] # BF_ROUNDS + 2
        BF_LONG S[4*256]
 
    cdef void BF_set_key(BF_KEY *key, int len, char *data)

    cdef void BF_cfb64_encrypt(char *inbuf, char *outbuf, long length, BF_KEY *schedule,
                               char *ivec, int *num, int enc)

</t>
<t tx="davidmcnab.121303201707.13">cdef extern from "openssl/rsa.h":

    #
    # Constants
    #
    ctypedef enum RSA_PAD_MODES:
        RSA_PKCS1_OAEP_PADDING
        RSA_PKCS1_PADDING

    #
    # Structs
    #
    ctypedef struct RSA:
        int pad
        long version
        void *meth
        # functional reference if 'meth' is ENGINE-provided
        void *engine
        BIGNUM *n
        BIGNUM *e
        BIGNUM *d
        BIGNUM *p
        BIGNUM *q
        BIGNUM *dmp1
        BIGNUM *dmq1
        BIGNUM *iqmp

        # be careful using this if the RSA structure is shared
        CRYPTO_EX_DATA ex_data
        int references
        int flags

        # Used to cache montgomery values
        BN_MONT_CTX *_method_mod_n
        BN_MONT_CTX *_method_mod_p
        BN_MONT_CTX *_method_mod_q

        # all BIGNUM values are actually in the
        # following data, if it is not NULL
        char *bignum_data
        BN_BLINDING *blinding

    #
    # Function 'prototypes'
    #
    cdef RSA *RSA_new()
    cdef RSA *RSA_new_method(void *engine)
    cdef int RSA_size(RSA *)
    cdef RSA *RSA_generate_key(int bits, unsigned long e,
                               void (*callback)(int,int,void *),void *cb_arg)
    cdef int RSA_check_key(RSA *key)

    cdef int RSA_public_encrypt(int flen, unsigned char *pfrom,
                                unsigned char *pto, RSA *rsaobj, int padding)
    cdef int RSA_private_encrypt(int flen, unsigned char *pfrom,
                                 unsigned char *pto, RSA *rsaobj, int padding)
    cdef int RSA_public_decrypt(int flen, unsigned char *pfrom, 
                                unsigned char *pto, RSA *rsaobj, int padding)
    cdef int RSA_private_decrypt(int flen, unsigned char *pfrom, 
                                 unsigned char *pto, RSA *rsaobj, int padding)
    cdef void RSA_free (RSA *r)

    cdef int RSA_blinding_on(RSA *rsa, void *bnctx)
    cdef void RSA_blinding_off(RSA *rsa)

    cdef int RSA_sign(int type, unsigned char *m, unsigned int m_len,
                      unsigned char *sigret, unsigned int *siglen, RSA *rsa)

    cdef int RSA_verify(int type, unsigned char *m, unsigned int m_len,
                        unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
</t>
<t tx="davidmcnab.121303201707.14">cdef extern from "openssl/rand.h":

    cdef void RAND_seed(char *buf, int num)
    cdef int RAND_bytes(char *buf, int num)
</t>
<t tx="davidmcnab.121303201707.15">cdef extern from "openssl/objects.h":

    #
    # Constants
    #
    ctypedef enum RSA_HASH_ALGOS:
        NID_md5
</t>
<t tx="davidmcnab.121303201707.16">cdef BIGNUM *BN_NULL
BN_NULL = &lt;BIGNUM *&gt;0

_True = 1
_False = 0

version = "0.2.3"

@others
</t>
<t tx="davidmcnab.121303201707.17">hardPrimes = {
    4096: long("FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
               "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
               "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
               "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
               "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
               "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
               "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
               "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
               "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
               "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
               "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
               "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
               "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
               "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
               "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
               "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
               "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
               "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
               "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
               "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
               "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199"
               "FFFFFFFF" "FFFFFFFF",
               16),

    1024: long("FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234"	"C4C6628B" "80DC1CD1"
               "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
               "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
               "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" 
               "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
               "FFFFFFFF" "FFFFFFFF",
               16),
    
    1536: long("FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
               "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
               "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
               "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
               "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
               "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
               "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
               "670C354E" "4ABC9804" "F1746C08" "CA237327" "FFFFFFFF" "FFFFFFFF",
               16),

    2048: long("FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
               "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
               "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
               "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
               "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
               "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
               "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
               "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
               "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
               "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
               "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF",
               16),
    3072: long("FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
               "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
               "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
               "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
               "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
               "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
               "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
               "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
               "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
               "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
               "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
               "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
               "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
               "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
               "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
               "43DB5BFC" "E0FD108E" "4B82D120" "A93AD2CA" "FFFFFFFF" "FFFFFFFF",
               16),

    4096: long("FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
               "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
               "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
               "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
               "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
               "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
               "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
               "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
               "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
               "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
               "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
               "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
               "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
               "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
               "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
               "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
               "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
               "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
               "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
               "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
               "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199"
               "FFFFFFFF" "FFFFFFFF",
               16),

    6144: long("FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
               "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
               "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
               "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
               "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
               "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
               "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
               "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
               "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
               "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
               "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
               "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
               "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
               "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
               "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
               "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
               "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
               "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
               "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
               "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
               "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
               "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD"
               "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831"
               "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B"
               "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF"
               "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6"
               "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3"
               "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
               "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328"
               "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C"
               "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE"
               "12BF2D5B" "0B7474D6" "E694F91E" "6DCC4024" "FFFFFFFF" "FFFFFFFF",
               16),
    8192: long("FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
               "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
               "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
               "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
               "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
               "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
               "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
               "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
               "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
               "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
               "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
               "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
               "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
               "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
               "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
               "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
               "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
               "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
               "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
               "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9" + \
               "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
               "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD"
               "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831"
               "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B"
               "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF"
               "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6"
               "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3"
               "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
               "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328"
               "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C"
               "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE"
               "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4"
               "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300"
               "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568"
               "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9"
               "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B"
               "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A"
               "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36"
               "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1"
               "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92"
               "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47"
               "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71"
               "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF",
               16),
    }
</t>
<t tx="davidmcnab.121303201707.18">cdef class dh:
    """
    class for Diffie-Hellman secure session key exchange&lt;br&gt;
    &lt;br&gt;
    Constructor arguments:&lt;ul&gt;
    &lt;li&gt;None&lt;/li&gt;&lt;/ul&gt;
    """
    &lt;&lt; class dh declarations &gt;&gt;
    @others
</t>
<t tx="davidmcnab.121303201707.19"></t>
<t tx="davidmcnab.121303201707.20"># hold the C-level DH structure
cdef DH *myDH

</t>
<t tx="davidmcnab.121303201707.21">def __new__(self):
    self.myDH = NULL
    pass
</t>
<t tx="davidmcnab.121303201707.22">def __dealloc__(self):
    "Destructor"
    if self.myDH != NULL:
        DH_free(self.myDH)
    pass
</t>
<t tx="davidmcnab.121303201707.23">def genParms(self, prime_len=1024, generator=5, myCallback=None):
    """
    &lt;b&gt;generateParms&lt;/b&gt;&lt;br&gt;
    &lt;br&gt;
    Generate random modulus for DH key generation&lt;br&gt;
    &lt;br&gt;
    Arguments:&lt;ul&gt;
     &lt;li&gt;&lt;b&gt;prime_len&lt;/b&gt; - length of modulus (n) in bits, default 1024&lt;/li&gt;
     &lt;li&gt;&lt;b&gt;generator&lt;/b&gt; - g, as in pub = g^x mod n. Default 5&lt;/li&gt;
     &lt;li&gt;&lt;b&gt;myCallback&lt;/b&gt; - a python func for status callbacks. Must accept 2 args,
       'type' and 'num'. 'type' is a number from 0 to 3. Default is no callback&lt;/li&gt;
    &lt;/ul&gt;
    Returns:&lt;ul&gt;
     &lt;li&gt;None&lt;/li&gt;&lt;/ul&gt;
    """
    if self.myDH != NULL:
        DH_free(self.myDH)
    self.myDH = DH_generate_parameters(prime_len,
                                       generator,
                                       callback, &lt;void *&gt;myCallback)
    callback(-1, 0, &lt;void *&gt;myCallback)
    return (bn2pyLong(self.myDH.g), bn2pyLong(self.myDH.p))
</t>
<t tx="davidmcnab.121303201707.24">def importParms(self, generator, modulus=None):
    """
    &lt;b&gt;importParms&lt;/b&gt;&lt;br&gt;
    &lt;br&gt;
    Imports DH key generation parameters into this DH object.&lt;br&gt;
    &lt;br&gt;
    Arguments - choice of:&lt;ul&gt;
     &lt;li&gt;&lt;b&gt;tuple&lt;/b&gt; - (generator, modulus)&lt;br&gt;
         &lt;b&gt;OR:&lt;/b&gt;&lt;br&gt;&lt;li&gt;
     &lt;li&gt;&lt;b&gt;generator&lt;/b&gt;&lt;/li&gt;
     &lt;li&gt;&lt;b&gt;modulus&lt;/b&gt; (as separate arguments)&lt;/ul&gt;

    Returns:&lt;ul&gt;
     &lt;li&gt;None&lt;/li&gt;&lt;/ul&gt;
    """

    self.myDH = DH_new()

    if type(generator) is type(()):
        modulus = generator[1]
        generator = generator[0]
    self.myDH.g = pyLong2bn(generator)
    self.myDH.p = pyLong2bn(modulus)
</t>
<t tx="davidmcnab.121303201707.25">def exportParms(self):
    """
    &lt;b&gt;exportParms&lt;/b&gt;&lt;br&gt;
    &lt;br&gt;
    Returns the DH key generation parameters required for a peer to generate pub keys&lt;br&gt;
    &lt;br&gt;
    Arguments:&lt;ul&gt;
     &lt;li&gt;&lt;b&gt;None&lt;/b&gt;&lt;/li&gt;
    &lt;/ul&gt;
    Returns:&lt;ul&gt;
     &lt;li&gt;&lt;b&gt;tuple&lt;/b&gt; - (generator, modulus)&lt;/ul&gt;
    """
    return (bn2pyLong(self.myDH.g),
            bn2pyLong(self.myDH.p))
</t>
<t tx="davidmcnab.121303201707.26">def genPubKey(self):
    """
    &lt;b&gt;genPubKey&lt;/b&gt;&lt;br&gt;
    &lt;br&gt;
    Generates a public key from generated (or imported) parameters&lt;br&gt;
    &lt;br&gt;
    Arguments:&lt;ul&gt;
     &lt;li&gt;None&lt;/li&gt;
     &lt;/ul&gt;
    Returns:&lt;ul&gt;
     &lt;li&gt;&lt;b&gt;public key&lt;/b&gt;, as a long int
     &lt;/ul&gt;
    """
    if self.myDH == NULL:
        raise Exception("Can't generate public key: DH object has no generation parameters")

    DH_generate_key(self.myDH)
    return bn2pyLong(self.myDH.pub_key)
</t>
<t tx="davidmcnab.121303201707.27">def privKey(self):
    """
    &lt;b&gt;privKey&lt;/b&gt;&lt;br&gt;
    &lt;br&gt;
    Returns the private key as a long int
    """
    if self.myDH == NULL:
        raise Exception("DH object has no public or private keys")
    return bn2pyLong(self.myDH.priv_key)
</t>
<t tx="davidmcnab.121303201707.28">def genSessKey(self, peerKey):
    """
    &lt;br&gt;genSessKey&lt;/b&gt;&lt;br&gt;&lt;br&gt;

    Calculates and returns the session key.&lt;br&gt;&lt;br&gt;

    Arguments:&lt;ul&gt;
      &lt;li&gt;&lt;b&gt;peerKey&lt;/b&gt; - peer's public key, as returned from &lt;b&gt;genPubKey&lt;/b&gt;&lt;/li&gt;
      &lt;/ul&gt;
    Returns:&lt;ul&gt;
      &lt;li&gt;None&lt;/li&gt;
      &lt;/ul&gt;
    """
    if self.myDH == NULL:
        raise Exception("Can't generate public key: DH object has no generation parameters")
    if self.myDH.pub_key == NULL:
        raise Exception("Can't generate session key: DH object has no public key")

    cdef keySize
    cdef BIGNUM *peerKeyBN
    cdef char *key

    peerKeyBN = pyLong2bn(peerKey)
    keySize = DH_size(self.myDH)
    key = &lt;char *&gt;malloc(keySize)

    DH_compute_key(&lt;unsigned char *&gt;key, peerKeyBN, self.myDH)

    BN_free(peerKeyBN)
    s = PyString_FromStringAndSize(key, keySize)
    free(key)

    return s
</t>
<t tx="davidmcnab.121303201707.29">cdef class blowfish:
    """
    class for Blowfish stream encryption&lt;br&gt;
    &lt;br&gt;
    Constructor Arguments:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;key&lt;/b&gt; - string containing encryption key, &lt;i&gt;default None&lt;/i&gt;&lt;/li&gt;
    &lt;li&gt;&lt;b&gt;iv&lt;/b&gt; - 8-byte string for initial value (for chaining), default None&lt;/li&gt;
    &lt;/ul&gt;
    """
    @others
</t>
<t tx="davidmcnab.121303201707.30">cdef BF_KEY keyStruct
cdef char iv[8]
cdef int counter
cdef char *key
cdef int keylen
</t>
<t tx="davidmcnab.121303201707.31">def __new__(self, key=None, iv=None):

    # set key and IV
    self.setKey(key)
    self.setIV(iv)

    # initialise C attributes
    self.counter = 0
</t>
<t tx="davidmcnab.121303201707.32">def __dealloc__(self):
    pass

</t>
<t tx="davidmcnab.121303201707.33">def setKey(self, key, iv=None):
    """
    &lt;b&gt;setKey&lt;/b&gt;&lt;br&gt;&lt;br&gt;

    Sets the session key for the Blowfish cipher object.&lt;br&gt;&lt;br&gt;

    Arguments:&lt;ul&gt;
      &lt;li&gt;&lt;b&gt;key&lt;/b&gt; - blowfish encryption key, as a string. For acceptable
          security, this should be at least 16 characters&lt;/li&gt;
      &lt;li&gt;&lt;b&gt;iv&lt;/b&gt; - cipher &lt;b&gt;initial value&lt;/b&gt;, as used in the chaining feedback.&lt;br&gt;
          Not essential, default nothing&lt;/li&gt;
      &lt;/ul&gt;
    """
    cdef char *keyBuf
    # Validate key
    if key == None:
        self.key = &lt;char *&gt;0

    self.keylen = len(key)
    if self.keylen == 0:
        raise Exception("Key length is zero")
    else:
        self.key = &lt;char *&gt;malloc(self.keylen)
        keyBuf = key
        memcpy(self.key, keyBuf, self.keylen)

    # reset IV - it won't work now
    self.setIV(iv)</t>
<t tx="davidmcnab.121303201707.34">def setIV(self, iv=None):
    """
    &lt;b&gt;setIV&lt;/b&gt; - sets the cipher chaining &lt;b&gt;initial value&lt;/b&gt;&lt;br&gt;&lt;br&gt;

    Arguments:&lt;ul&gt;
      &lt;li&gt;&lt;b&gt;iv&lt;/b&gt; - 8-byte initial value, as a python string&lt;/li&gt;
      &lt;/ul&gt;
    Returns:&lt;ul&gt;
      &lt;li&gt;None&lt;/li&gt;
      &lt;/ul&gt;
    """
    cdef char *ivBuf
    # Validate IV
    if iv == None:
        memset(self.iv, 0, 8)
    elif len(iv) != 8:
        raise Exception(
            "Blowfish IV length=%d, should be 8" % len(iv))
    else:
        ivBuf = iv
        memcpy(self.iv, ivBuf, 8)

    self.counter = 0
    BF_set_key(&amp;(self.keyStruct), self.keylen, self.key)
</t>
<t tx="davidmcnab.121303201707.35">def encrypt(self, inbuf):
    """
    &lt;b&gt;encrypt&lt;/b&gt; - encrypt a block of data&lt;br&gt;&lt;br&gt;

    Arguments:&lt;ul&gt;
      &lt;li&gt;&lt;b&gt;inbuf&lt;/b&gt; - plaintext to be encrypted, as a string&lt;/li&gt;
      &lt;/ul&gt;

    Returns:&lt;ul&gt;
      &lt;li&gt;Encrypted ciphertext, as a string&lt;/li&gt;
      &lt;/ul&gt;
    """
    cdef char *inbufC
    cdef char *outbufC
    cdef int blklen

    inbufC = inbuf
    blklen = len(inbuf)
    #printf("blk len=%d\n", blklen)
    outbufC = &lt;char *&gt;malloc(blklen)
    #printf("out=%lx\n", outbufC)

    BF_cfb64_encrypt(inbufC,
                     outbufC, blklen, &amp;self.keyStruct,
                     self.iv, &amp;self.counter, BF_ENCRYPT)
    outbuf = PyString_FromStringAndSize(outbufC, blklen)
    free(outbufC)
    return outbuf
</t>
<t tx="davidmcnab.121303201707.36">def decrypt(self, inbuf):
    """
    &lt;b&gt;decrypt&lt;/b&gt; - decrypt a block of data&lt;br&gt;&lt;br&gt;

    Arguments:&lt;ul&gt;
      &lt;li&gt;&lt;b&gt;inbuf&lt;/b&gt; - ciphertext to be decrypted, as a string&lt;/li&gt;
      &lt;/ul&gt;

    Returns:&lt;ul&gt;
      &lt;li&gt;Decrypted plaintext, as a string&lt;/li&gt;
      &lt;/ul&gt;
    """
    cdef char *inbufC
    cdef char *outbufC
    cdef int blklen

    inbufC = inbuf
    blklen = len(inbuf)
    outbufC = &lt;char *&gt;malloc(blklen)
        
    BF_cfb64_encrypt(inbufC,
                     outbufC, blklen, &amp;self.keyStruct,
                     self.iv, &amp;self.counter, BF_DECRYPT)
    outbuf = PyString_FromStringAndSize(outbufC, blklen)
    free(outbufC)
    return outbuf
</t>
<t tx="davidmcnab.121303201707.37">cdef class rsa:
    """
    class for RSA public-key encryption&lt;br&gt;&lt;br&gt;

    Constructor Arguments:&lt;ul&gt;
    &lt;li&gt;None&lt;/li&gt;
    &lt;/ul&gt;
    """
    @others
</t>
<t tx="davidmcnab.121303201707.38">cdef RSA *rsaObj
cdef BN_CTX *bnCtx
</t>
<t tx="davidmcnab.121303201707.39">def __new__(self):
    cdef RSA *rsaC
    rsaC = RSA_new()
    self.rsaObj = rsaC
    self.bnCtx = BN_CTX_new()
    BN_CTX_init(self.bnCtx)
</t>
<t tx="davidmcnab.121303201707.40">def __dealloc__(self):
    #print "dealloc'ing rsa object"
    BN_CTX_free(self.bnCtx)
    RSA_free(self.rsaObj)
</t>
<t tx="davidmcnab.121303201707.41">def generateKey(self, nbits=1024, **kw):
    """
    Generate a fresh RSA keypair&lt;br&gt;&lt;br&gt;

    Arguments:
     - bits&lt;/b&gt; - length of required key in bits, &gt;=1024 recommended, default 1024

    Keywords:
     - e - exponent for key generation, default 5
     - myCallback - a Python callback function which accepts
       2 arguments - level and num. Default None
    """

    e = kw.get('e', 5)
    myCallback = kw.get('myCallback', None)

    # ditch any old key info
    if self.rsaObj != NULL:
        RSA_free(self.rsaObj)

    # cook up a new key
    self.rsaObj = RSA_generate_key(nbits, e, callback, &lt;void *&gt;myCallback)

    # and turn on blinding
    RSA_blinding_on(self.rsaObj, self.bnCtx)

    callback(-1, 0, &lt;void *&gt;myCallback)
</t>
<t tx="davidmcnab.121303201707.42">def pubKey(self):
    """
    Returns the public key for this object.&lt;br&gt;&lt;br&gt;

    Arguments:
      - None

    Returns:
      - Public key, as a tuple (e, n) (refer: Applied Cryptography)
    """

    return (bn2pyLong(self.rsaObj.e),
            bn2pyLong(self.rsaObj.n),
            )
</t>
<t tx="davidmcnab.121303201707.43">def privKey(self):
    """
    Returns the public key for this object.&lt;br&gt;&lt;br&gt;

    Arguments:&lt;ul&gt;
    &lt;li&gt;None&lt;/li&gt;
    &lt;/ul&gt;

    Returns:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;Public and Private key&lt;/b&gt;, as a tuple (e, n, d) (refer: Applied Cryptography)&lt;/li&gt;
    &lt;/ul&gt;
    """

    return (bn2pyLong(self.rsaObj.e),
            bn2pyLong(self.rsaObj.n),
            bn2pyLong(self.rsaObj.d),
            )
</t>
<t tx="davidmcnab.121303201707.44">def rawprimes(self):
    """
    Returns the p and q for this RSA key.&lt;br&gt;&lt;br&gt;

    Arguments:&lt;ul&gt;
    &lt;li&gt;None&lt;/li&gt;
    &lt;/ul&gt;

    Returns:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;p and q as a tuple (refer: Applied Cryptography)&lt;/li&gt;
    &lt;/ul&gt;
    """

    return (bn2pyLong(self.rsaObj.p),
            bn2pyLong(self.rsaObj.q),
            )
</t>
<t tx="davidmcnab.121303201707.45">def importPubKey(self, parms):
    """
    Import someone else's public key

    Arguments:
      - (e, n), a tuple (as returned by pubKey()),
    """

    if type(parms) not in [type(()), type([])]:
        raise Exception("Invalid public key parameters")
    e = parms[0]
    n = parms[1]

    #print "e = %s" % e
    #print "n = %s" % n

    self.rsaObj.e = pyLong2bn(e)
    self.rsaObj.n = pyLong2bn(n)
    self.rsaObj.d = &lt;BIGNUM *&gt;0

    # and turn on blinding
    RSA_blinding_on(self.rsaObj, self.bnCtx)

</t>
<t tx="davidmcnab.121303201707.46">def importPrivKey(self, parms):
    """
    importPubKey - import private key parameters

    Arguments:
     - (e, n, d), as a tuple (as returned by privKey())
    """

    if type(parms) not in [type(()), type([])]:
        raise Exception("Invalid private key parameters")
    e = parms[0]
    n = parms[1]
    d = parms[2]

    #print "e = %s" % e
    #print "n = %s" % n
    #print "d = %s" % d

    self.rsaObj.e = pyLong2bn(e)
    self.rsaObj.n = pyLong2bn(n)
    self.rsaObj.d = pyLong2bn(d)

    # and turn on blinding
    RSA_blinding_on(self.rsaObj, self.bnCtx)
</t>
<t tx="davidmcnab.121303201707.47">def hasPrivateKey(self):
    """
    Returns &lt;b&gt;True&lt;/b&gt; if private key is present in this key object (and therefore the
    key object is capable of decryption), or &lt;b&gt;False&lt;/b&gt; if not.
    """
    if self.rsaObj.d == &lt;BIGNUM *&gt;0:
        return _False
    else:
        return _True
</t>
<t tx="davidmcnab.121303201707.48">def encrypt(self, pPlain):
    """
    Encrypts a block of data.&lt;br&gt;&lt;br&gt;

    Arguments:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;plain&lt;/b&gt; - plaintext to be encrypted, as a string&lt;/li&gt;
    &lt;/ul&gt;

    Returns:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;ciphertext&lt;/b&gt; - encrypted data, as a string&lt;/b&gt;&lt;/li&gt;
    &lt;/ul&gt;

    &lt;b&gt;Note:&lt;/b&gt; This method has a strict limit as to the size of the block which can
    be encrypted. To determine the limit, call the &lt;b&gt;maxSize&lt;/b&gt; method.
    """
    cdef char *cPlain
    cdef int cPlainLen
    cdef char *cCipher
    cdef int cCipherLen
    cdef int cRsaSize

    cRsaSize = RSA_size(self.rsaObj)

    cPlain = pPlain
    cPlainLen = len(pPlain)

    # spit if plaintext is too long
    #if cPlainLen &gt; cRsaSize - 11:
    if cPlainLen &gt; self.maxSize():
        raise Exception("Plaintext exceeds maximum %d bytes" % self.maxSize())

    cCipher = &lt;char *&gt;malloc(cRsaSize)

    cCipherLen = RSA_public_encrypt(cPlainLen,
                                    &lt;unsigned char *&gt;cPlain,
                                    &lt;unsigned char *&gt;cCipher,
                                    self.rsaObj,
                                    RSA_PKCS1_PADDING)
    pCipher = PyString_FromStringAndSize(cCipher, cCipherLen)

    free(&lt;char *&gt;cCipher)
    return pCipher
</t>
<t tx="davidmcnab.121303201707.49">def decrypt(self, pCipher):
    """
    decrypt a previously encrypted block&lt;br&gt;&lt;br&gt;

    Arguments:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;cipher&lt;/b&gt; - ciphertext to be decrypted, as a string&lt;/li&gt;
    &lt;/ul&gt;
    
    Returns:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;plaintext&lt;/b&gt; - decrypted asa python string&lt;/li&gt;
    &lt;/ul&gt;
    """
    cdef char *cPlain
    cdef int cPlainLen
    cdef char *cCipher
    cdef int cCipherLen

    cCipher = pCipher
    cCipherLen = len(pCipher)

    cPlain = &lt;char *&gt;malloc(RSA_size(self.rsaObj))

    if self.rsaObj.d == &lt;BIGNUM *&gt;0:
        raise CryptoCannotDecrypt("Private key not present")

    cPlainLen = RSA_private_decrypt(cCipherLen,
                                    &lt;unsigned char *&gt;cCipher,
                                    &lt;unsigned char *&gt;cPlain,
                                    self.rsaObj,
                                    RSA_PKCS1_PADDING)
    pPlain = PyString_FromStringAndSize(cPlain, cPlainLen)

    free(&lt;char *&gt;cPlain)
    return pPlain
</t>
<t tx="davidmcnab.121303201707.50">def maxSize(self):
    """
    Returns the maximum allowable size of plaintext strings which can
    be encrypted
    """

    return RSA_size(self.rsaObj) - 11
</t>
<t tx="davidmcnab.121303201707.51">def sign(self, digest):
    """
    Signs an MD5 message digest&lt;br&gt;&lt;br&gt;

    Arguments:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;digest&lt;/b&gt; - MD5 digest of data, as a string&lt;/li&gt;
    &lt;/ul&gt;

    Returns:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;signature&lt;/b&gt;, as a MIME-friendly, base64-encoded string&lt;/li&gt;
    &lt;/ul&gt;
    """
    cdef char *cSigBuf
    cdef int cSigLen
    cdef char *cDigestBuf
    cdef int  cDigestLen

    cSigBuf = &lt;char *&gt;malloc(RSA_size(self.rsaObj))
    cDigestBuf = digest
    cDigestLen = len(digest)

    RSA_sign(NID_md5,
             &lt;unsigned char *&gt;cDigestBuf, &lt;unsigned int&gt;cDigestLen,
             &lt;unsigned char *&gt;cSigBuf, &lt;unsigned int *&gt;&amp;cSigLen,
             self.rsaObj)

    pSig = PyString_FromStringAndSize(cSigBuf, cSigLen)
    free(cSigBuf)
    return pSig
</t>
<t tx="davidmcnab.121303201707.52">def verify(self, digest, sig):
    """
    Verify a digest against a signature&lt;li&gt;&lt;li&gt;

    Arguments:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;digest&lt;/b&gt; - digest against which signature is to be checked.&lt;/b&gt;&lt;/li&gt;
    &lt;li&gt;&lt;b&gt;signature&lt;/b&gt; - signature as returned from the &lt;b&gt;sign()&lt;/b&gt; method&lt;/li&gt;
    &lt;/ul&gt;

    Returns:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;True&lt;/b&gt; if signature is valid, or &lt;b&gt;False&lt;/b&gt; if not.&lt;/li&gt;
    &lt;/ul&gt;

    Note:&lt;ul&gt;
    &lt;li&gt;To pass as valid, the key object must contain the same public key as was used
        in creating the original signature&lt;/li&gt;
    &lt;/ul&gt;
    """
    cdef char *cSigBuf
    cdef int cSigLen
    cdef char *cDigestBuf
    cdef int  cDigestLen
    cdef int result

    cSigBuf = sig
    cSigLen = len(sig)
    cDigestBuf = digest
    cDigestLen = len(digest)

    result = RSA_verify(NID_md5,
                      &lt;unsigned char *&gt;cDigestBuf, &lt;unsigned int&gt;cDigestLen,
                      &lt;unsigned char *&gt;cSigBuf, &lt;unsigned int&gt;cSigLen,
                      self.rsaObj)
    return result
</t>
<t tx="davidmcnab.121303201707.53">class ElGamal:
    @others
</t>
<t tx="davidmcnab.121303201707.54">keydata=['p', 'g', 'y', 'x']

</t>
<t tx="davidmcnab.121303201707.55">def __init__(self, bits=None, progressfunc=None, **kw):
    if bits:
        self.keysize = bits
        self.generateKey(bits, progressfunc, **kw)
    pass
</t>
<t tx="davidmcnab.121303201707.56"># Generate an ElGamal key with N bits
def generateKey(self, bits, progress_func=None, **kw):
    """generate(bits:int, progress_func:callable, **kw)

    Generate an ElGamal key of length 'bits', using 'randfunc' to get
    random data and 'progress_func', if present, to display
    the progress of the key generation.
    
    Keywords:
        - privbytes - if given, causes the private key (.x), when represented
          as a binary string, to be exactly this many bytes long
    """
    privNumBytes = kw.get('privbytes', None)

    self.keysize = bits

    # Generate prime p
    if 0:
        if progress_func:
            progress_func('p\n')
        #obj.p=bignum(getPrime(bits, randfunc))
        self.p = genprime(bits)
    else:
        if hardPrimes.has_key(bits):
            self.p = hardPrimes[bits]
        else:
            self.p = genprime(bits)

    # Generate random number g
    if progress_func:
        progress_func('g\n')

    size = bits - 1 - (ord(rndfunc(1)) &amp; 63) # g will be from 1--64 bits smaller than p

    if size&lt;1:
        size=bits-1
    while (1):
        # self.g = genprime(size, None, 0)
        self.g = genprime(bits/2, progress_func, 0)
        #print "----"
        #print self.g
        #print self.p
        if self.g &lt; self.p:
            break
        size=(size+1) % bits
        if size==0:
            size=4
    # Generate random number x
    if progress_func:
        progress_func('x\n')

    #while (1):
    #    size=bits-1-ord(rndfunc(1)) # x will be from 1 to 256 bits smaller than p
    #    if size&gt;2:
    #        break
    
    #while (1):
    #    #self.x = SSLCrypto.genprime(size)
    #    self.x = genprime(size/2, progress_func, 0)
    #    if self.x &lt; self.p:
    #        break
    #    size = (size+1) % bits
    #    if size==0:
    #        size=4
    if privNumBytes != None:
        bits = privNumBytes * 8 + 16 # a wee bit hackish
    while 1:
        self.x = genrandom(bits-16)
        if progress_func:
            progress_func('y\n')
        if privNumBytes == None or len(long_to_bytes(self.x)) == privNumBytes:
            break
    self.y = pow(self.g, self.x, self.p)
</t>
<t tx="davidmcnab.121303201707.57">def genk(self):
    """
    Generate a 'K' value for signing/encrypting
    """
    while 1:
        K = genrandom(self.keysize - 1 - genrandom(5,1))
        if GCD(K, self.p - 1) == 1:

            #print "sign: p = %s" % self.p
            #print "sign: k = %s" % K

            return K

</t>
<t tx="davidmcnab.121303201707.58">def construct(tuple):
    """construct(tuple:(long,long,long,long)|(long,long,long,long,long)))
             : ElGamalobj
    Construct an ElGamal key from a 3- or 4-tuple of numbers.
    """

    obj=ElGamalobj()
    if len(tuple) not in [3,4]:
        raise error, 'argument for construct() wrong length'
    for i in range(len(tuple)):
        field = obj.keydata[i]
        setattr(obj, field, tuple[i])
    return obj
</t>
<t tx="davidmcnab.121303201707.59">def __getstate__(self):
    """To keep key objects platform-independent, the key data is
    converted to standard Python long integers before being
    written out.  It will then be reconverted as necessary on
    restoration."""
    d=self.__dict__
    for key in self.keydata:
        if d.has_key(key): d[key]=long(d[key])
    return d
</t>
<t tx="davidmcnab.121303201707.60">def __setstate__(self, d):
    """On unpickling a key object, the key data is converted to the big
number representation being used, whether that is Python long
integers, MPZ objects, or whatever."""
    for key in self.keydata:
        if d.has_key(key): self.__dict__[key]=bignum(d[key])
</t>
<t tx="davidmcnab.121303201707.61">def encrypt(self, plaintext, K=None):
    """encrypt(plaintext:string|long, K:string|long) : tuple
    Encrypt the string or integer plaintext.  K is a random
    parameter required by some algorithms.
    """
    wasString=0

    if K is None:
        K = genprime(256)

    if isinstance(plaintext, types.StringType):
        plaintext = bytes_to_long(plaintext)
        wasString=1

    if isinstance(K, types.StringType):
        K = bytes_to_long(K)

    a = pow(self.g, K, self.p)
    b = (plaintext * pow(self.y, K, self.p)) % self.p
    ciphertext = (a, b)

    if wasString:
        ctext1 = tuple(map(long_to_bytes, ciphertext))
    else:
        ctext1 = ciphertext

    return bencode(ctext1)
</t>
<t tx="davidmcnab.121303201707.62">def decrypt(self, ciphertext):
    """decrypt(ciphertext:tuple|string|long): string
    Decrypt 'ciphertext' using this key.
    """
    try:
        ciphertext = bdecode(ciphertext)
    except:
        raise CryptoInvalidCiphertext

    wasString = 0

    if type(ciphertext) not in [type(()), type([])]:
        ciphertext = (ciphertext,)

    if isinstance(ciphertext[0], types.StringType):
        ciphertext = tuple(map(bytes_to_long, ciphertext))
        wasString = 1

    if (not hasattr(self, 'x')):
        raise error, 'Private key not available in this object'

    ax = pow(ciphertext[0], self.x, self.p)
    plaintext = (ciphertext[1] * inverse(ax, self.p)) % self.p

    if wasString:
        return long_to_bytes(plaintext)
    else:
        return plaintext
</t>
<t tx="davidmcnab.121303201707.63">def sign(self, M, K=None):
    """sign(M : string|long, K:string|long) : tuple
    Return a tuple containing the signature for the message M.
    K is a random parameter required by some algorithms.
    """
    if (not self.hasPrivateKey()):
        raise error, 'Private key not available in this object'
    if isinstance(M, types.StringType): M=bytes_to_long(M)

    #if isinstance(K, types.StringType): K=bytes_to_long(K)
    if K is None:
        K = self.genk()

    #print "sign: p = %s" % self.p
    #print "sign: k = %s" % K
    
    p1 = self.p - 1
    if (GCD(K, p1) != 1):
        raise CryptoInvalidElGamalK("Bad K value: GCD(K, p-1) != 1")
    a = pow(self.g, K, self.p)
    t = (M - self.x * a) % p1
    while t &lt; 0:
        t=t+p1
    b = (t * inverse(K, p1)) % p1

    return bencode((a, b))


</t>
<t tx="davidmcnab.121303201707.64">def verify(self, M, sig):
    """verify(M:string|long, signature:tuple) : bool
    Verify that the signature is valid for the message M;
    returns true if the signature checks out.
    """
    try:
        sig = bdecode(sig)
    except:
        raise CryptoInvalidSignature

    if isinstance(M, types.StringType):
        M = bytes_to_long(M)

    v1 = pow(self.y, sig[0], self.p)
    v1 = (v1 * pow(sig[0], sig[1], self.p)) % self.p
    v2 = pow(self.g, M, self.p)
    if v1 == v2:
        return 1
    return 0
</t>
<t tx="davidmcnab.121303201707.65">def importPubKey(self, parms):
    """
    Import someone else's public key

    Arguments:
     - (p, g, y), a tuple (as returned by pubKey())
    """

    if (type(parms) not in [type(()), type([])]) or (len(parms) != 3):
        raise Exception("Invalid public key parameters")
    self.p = parms[0]
    self.g = parms[1]
    self.y = parms[2]

    self.keysize = size(self.p)

    #print "p = %s" % self.p
    #print "g = %s" % self.g
    #print "y = %s" % self.y

</t>
<t tx="davidmcnab.121303201707.66">def importPrivKey(self, parms):
    """
    importPubKey - import private key parameters

    Arguments:
     - (p, g, y, x), as a tuple (as returned by privKey())
    """

    if (type(parms) not in [type(()), type([])]) or (len(parms) != 4):
        raise Exception("Invalid private key parameters")
    self.p = parms[0]
    self.g = parms[1]
    self.y = parms[2]
    self.x = parms[3]

    self.keysize = size(self.p)

    #print "p = %s" % self.p
    #print "g = %s" % self.g
    #print "y = %s" % self.y
    #print "x = %s" % self.x


</t>
<t tx="davidmcnab.121303201707.67">def hasPrivateKey(self):
    """
    Returns &lt;b&gt;True&lt;/b&gt; if private key is present in this key object (and therefore the
    key object is capable of decryption), or &lt;b&gt;False&lt;/b&gt; if not.
    """
    if hasattr(self, 'x'):
        return _True
    else:
        return _False
</t>
<t tx="davidmcnab.121303201707.68">def pubKey(self):
    """Return tuple containing only the public information."""
    return (self.p, self.g, self.y)
</t>
<t tx="davidmcnab.121303201707.69">def privKey(self):
    """Return tuple containing the public and private information."""
    return (self.p, self.g, self.y, self.x)
</t>
<t tx="davidmcnab.121303201707.70">def maxSize(self):
    """
    Returns the maximum allowable size of plaintext strings which can
    be encrypted
    """

    #print "WARNING: ElGamal.maxSize() not implemented"
    return 128
</t>
<t tx="davidmcnab.121303201707.71">def __eq__ (self, other):
    """__eq__(other): 0, 1
    Compare us to other for equality.
    """
    return self.__getstate__() == other.__getstate__()
</t>
<t tx="davidmcnab.121303201707.72">class key:
    """
    key - simple crypto API object.&lt;br&gt;&lt;br&gt;
    
    This may well be the only crypto class for Python that you'll ever need.
    Think of this class, and the ezPyCrypto module, as 'cryptography for
    the rest of us'.&lt;br&gt;&lt;br&gt;
    
    Designed to strike the optimal balance between ease of use, features
    and performance.&lt;br&gt;&lt;br&gt;
    
    Basic High-level methods:
    &lt;ul&gt;
     &lt;li&gt;encString - encrypt a string&lt;/li&gt;
     &lt;li&gt;decString - decrypt a string&lt;/li&gt;
     &lt;li&gt;encStringToAscii - encrypt a string to a printable, mailable format&lt;/li&gt;
     &lt;li&gt;decStringFromAscii - decrypt an ascii-format encrypted string&lt;br&gt;&lt;br&gt;&lt;/li&gt;

     &lt;li&gt;signString - produce ascii-format signature of a string&lt;/li&gt;
     &lt;li&gt;verifyString - verify a string against a signature&lt;br&gt;&lt;br&gt;&lt;/li&gt;

     &lt;li&gt;importKey - import public key (and possibly private key too)&lt;/li&gt;
     &lt;li&gt;exportKey - export public key only, as printable mailable string&lt;/li&gt;
     &lt;li&gt;exportKeyPrivate - same, but export private key as well&lt;/li&gt;
     &lt;li&gt;makeNewKeys - generate a new, random private/public key pair&lt;/li&gt;
    &lt;/ul&gt;

    Middle-level (stream-oriented) methods:
    &lt;ul&gt;
     &lt;li&gt;encStart - start a stream encryption session&lt;/li&gt;
     &lt;li&gt;encNext - encrypt another piece of data&lt;/li&gt;
     &lt;li&gt;encEnd} - finalise stream encryption session&lt;/li&gt;
     &lt;li&gt;decStart} - start a stream decryption session&lt;/li&gt;
     &lt;li&gt;decNext} - decrypt the next piece of available data&lt;/li&gt;
     &lt;li&gt;decEnd} - finalise stream decryption session&lt;/li&gt;
     &lt;/ul&gt;

    Low-level methods:&lt;ul&gt;
    &lt;li&gt;refer to the source code&lt;/li&gt;
    &lt;/ul&gt;
    """

#Principle of operation:
#     - Data is encrypted with choice of symmetric block-mode session cipher
#       (or default Blowfish if user doesn't care)
#     - CFB block chaining is used for added security - each next block's
#       key is affected by the previous block
#     - The session key and initial value (IV) are encrypted against an RSA
#       or ElGamal public key (user's choice, default RSA)
#     - Each block in the stream is prepended with a 'length' byte, indicating
#       how many bytes in the decrypted block are significant - needed when
#       total data len mod block size is non-zero
#     - Format of encrypted data is:
#         - public key len - 2 bytes, little-endian - size of public key in bytes
#        - public key - public key of recipient
#        - block cipher len - unencrypted length byte - size of block cipher in bytes
#        - block cipher - encrypted against public key, index into array
#          of session algorithms
#        - block key len - unencrypted length byte - size of block key in bytes
#        - block key - encrypted against public key
#        - block IV len - unencrypted length of block cipher IV - IV length in bytes
#        - block cipher IV - encrypted against public key, prefixed 1-byte length
#        - block1 len - 1 byte - number of significant chars in block1 *
#        - block1 data - always 8 bytes, encrypted against session key
#        - ...
#        - blockn len
#        - blockn data
#        - If last data block is of the same size as the session cipher blocksize,
#          a final byte 0x00 is sent.

    &lt;&lt; class key declarations &gt;&gt;
    @others

</t>
<t tx="davidmcnab.121303201707.73"># Various lookup tables for encryption algorithms

_algosPub = {'RSA' : rsa,
             'ElGamal' : ElGamal}

_algosPub1 = {rsa : 'RSA',
              ElGamal : 'ElGamal'}

_algosSes = { "Blowfish":blowfish,
              }
_algosSes1 = {'Blowfish':0}

_algosSes2 = [blowfish]

_algosSes3 = {blowfish:'Blowfish'}

# Generate IV for passphrase encryption
_passIV = "w@8.~Z4("

# Buffer for yet-to-be-encrypted stream data
_encBuf = ''
</t>
<t tx="davidmcnab.121303201707.74">def __init__(self, something=1024, algoPub=None, algoSess=None, **kw):
    """Constructor. Creates a key object&lt;br&gt;&lt;br&gt;

    This constructor, when creating the key object, does one of
    two things:
     - Creates a completely new keypair, OR
     - Imports an existing keypair

    Arguments:
     - If new keys are desired:
       - key size in bits (int), default 1024 - advise 2048 or more
       - algoPub - only 'RSA' (default) or 'ElGamal' presently supported
       - algoSess - only 'Blowfish' (default) presently supported

     - If importing an existing key or keypair:
        - keyobj (string) - result of a prior exportKey() call
    
    Keywords:
     - passphrase - default '':
        - If creating new keypair, this passphrase is used to encrypt privkey when
          exporting.
        - If importing a new keypair, the passphrase is used to authenticate and
          grant/deny access to private key
    """
    #print "raise exc"
    #raise Exception("test of pyrex exceptions in windows")

    #print "key constructor called"
    if type(something) in [types.IntType, types.LongType]:
    #if type(something) == type(0):
        # which public key algorithm did they choose?
        if algoPub == None:
            algoPub = 'RSA'
        algoP = self._algosPub.get(algoPub, None)
        if algoP == None:
            # Whoops - don't know that one
            raise Exception("AlgoPub must be one of: " + ",".join(self._algosPub.keys()))
        self.algoPub = algoP
        self.algoPname = algoPub
        self.callback = kw.get('myCallback', None)

        # which session key algorithm?
        if algoSess == None:
            algoSess = 'Blowfish'
        algoS = self._algosSes.get(algoSess, None)
        if algoS == None:
            # Whoops - don't know that session algorithm
            raise Exception(
	      "AlgoSess must be one of %s" % self._aldosSes.keys()) 
        self.algoSes = algoS
        self.algoSname = algoSess

        # organise random data pool

        # now create the keypair
        self.makeNewKeys(something, **kw)

    elif type(something) is type(""):
        if algoPub != None:
            raise Exception("Don't specify algoPub if importing a key")
        if self.importKey(something, passphrase=kw.get('passphrase', '')) == _False:
            #print "key.__init__: bad key"
            raise CryptoKeyError(
                "Attempted to import invalid key, or passphrase is bad")
    else:
        raise Exception("Must pass keysize or importable keys")


</t>
<t tx="davidmcnab.121303201707.75">def makeNewKeys(self, keysize=512, **kw):
    """
    Creates a new keypair in cipher object, and a new session key

    Arguments:
      - keysize (default 512), advise at least 1536

    Returns:
      - None

    Keywords:
      - passphrase - used to secure exported private key - default '' (no passphrase)
      - e - e value, in case of RSA
    &lt;/ul&gt;

    Keypair gets stored within the key object. Refer exportKey()
    exportKeyPrivate() and importKey()
    
    Generally no need to call this yourself, since the constructor
    calls this in cases where you aren't instantiating with an
    importable key.
    """

    passphrase = kw.get('passphrase', '')
    if passphrase == None:
        passphrase = ''
    self.passphrase = passphrase

    # set up a public key object
    self.k = self.algoPub()
    self.k.generateKey(keysize, **kw)

    #self.k = self.algoPub.generate(keysize, self.randfunc)
    self._calcPubBlkSize()

    # Generate random session key
    self._genNewSessKey()

    # Create a new block cipher object
    self._initBlkCipher()
</t>
<t tx="davidmcnab.121303201707.76">def importKey(self, keystring, **kwds):
    """
    Imports a public key or private/public key pair.&lt;br&gt;&lt;br&gt;

    (as previously exported from this object
    with the &lt;b&gt;exportKey&lt;/b&gt; or &lt;b&gt;exportKeyPrivate&lt;/b&gt; methods.&lt;br&gt;&lt;br&gt;

    Arguments:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;keystring&lt;/b&gt; - a string previously imported with
    &lt;b&gt;exportKey&lt;/b&gt; or &lt;b&gt;exportKeyPrivate&lt;/b&gt;&lt;/li&gt;
    &lt;/ul&gt;
    
    Keywords:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;passphrase&lt;/b&gt; - string (default '', meaning 'try to import without passphrase')
    &lt;/li&gt;&lt;/ul&gt;
    
    Returns:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;True&lt;/b&gt; if import successful, &lt;b&gt;False&lt;/b&gt; if failed&lt;li&gt;
    &lt;/ul&gt;

    You don't have to call this if you instantiate your key object
    in 'import' mode - ie, by calling it with a previously exported key.&lt;br&gt;&lt;br&gt;

    Note - you shouldn't give a 'passphrase' when importing a public key.
    """

    passphrase = kwds.get('passphrase', '')
    if passphrase == None:
        passphrase = ''

    screwed = 0

    try:
        keypickle = self._unwrap("Key", keystring)

        #print "bailingf early"
        #raise Exception

        #keytuple = pickle.loads(keypickle)
        keytuple = bdecode(keypickle)

        ispriv, haspass, keyobj = keytuple

        if haspass:
            ppCipher = blowfish(passphrase, self._passIV)
            keyobj = ppCipher.decrypt(keyobj)

        #self.algoPname, keyparms = pickle.loads(keyobj)
        #print "key.importKey: before bdecode"
        
        # if bad passphrase was given, we'll have non-ascii chars
        # need to do this because bdecode crashes the interp if it sees
        # bad chars
        #print "testing keyobj before bdecode..."
        #print "keyobj = %s" % repr(keyobj)
        for c in keyobj:
            oc = ord(c)
            if oc &gt; 127:
                # print "badd char in keyobj - passphrase must be wrong"
                screwed = 1
                break

        if not screwed:
            #print "keyobj seems ok"
            pass

            # should be safe to attempt decode now
            self.algoPname, keyparms = bdecode(keyobj)
    
            #print "key.importKey: after bdecode"
    
            self.algoPub = self._algosPub[self.algoPname]
    
            # Create empty public key object
            self.k = self.algoPub()
            if ispriv:
                self.k.importPrivKey(keyparms)
            else:
                self.k.importPubKey(keyparms)
    
            #raise Exception("Tried to import Invalid Key")
            self._calcPubBlkSize()
            self.passphrase = passphrase
    
            # create new session key
            algoSess = 'Blowfish'
            algoS = self._algosSes.get(algoSess, None)
            if algoS == None:
                # Whoops - don't know that session algorithm
                raise Exception(
              "AlgoSess must be one of %s" % self._aldosSes.keys()) 
            self.algoSes = algoS
            self.algoSname = algoSess
            
    except:
        #traceback.print_exc()
        #print "importKey: exception"
        screwed = 1

    if screwed:
        #print "returning false"
        return _False
    else:
        #print "returning true"
        return _True

</t>
<t tx="davidmcnab.121303201707.77">def exportKey(self):
    """
    Exports the public key as a printable string.&lt;br&gt;&lt;br&gt;

    Exported keys can be imported elsewhere into MyCipher instances
    with the &lt;b&gt;importKey&lt;/b&gt; method.&lt;br&gt;&lt;br&gt;
    
    Note that this object contains only the public key. If you want to
    export the private key as well, call &lt;b&gt;exportKeyPrivate&lt;/b&gt; instaead.&lt;br&gt;&lt;br&gt;

    Note also that the exported string is Base64-encoded, and safe for sending
    in email.&lt;br&gt;&lt;br&gt;

    Arguments:&lt;ul&gt;
    &lt;li&gt;None&lt;/li&gt;
    &lt;/ul&gt;
    Returns:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;base64-encoded string&lt;/b&gt; containing an importable key&lt;/li&gt;
    &lt;/ul&gt;
    """
    rawpub = self._rawPubKey()
    # tuple format: (isprivate haspassphrase keyparameters)
    expTuple = (_False, _False, rawpub)

    #expPickle = pickle.dumps(expTuple, _True)
    expPickle = bencode(expTuple)

    return self._wrap("Key", expPickle)
</t>
<t tx="davidmcnab.121303201707.78">def exportKeyPrivate(self, **kwds):
    """
    Exports public/private key pair as a printable string.&lt;br&gt;&lt;br&gt;

    This string is a binary string consisting of a pickled key object,
    that can be imported elsewhere into &lt;b&gt;key&lt;/b&gt; instances
    with the &lt;b&gt;importKey&lt;/b&gt; method.&lt;br&gt;&lt;br&gt;
    
    Note that this object contains the public AND PRIVATE keys.
    Don't EVER email any keys you export with this function (unless you
    know what you're doing, and you encrypt the exported keys against
    another key). When in doubt, use L{exportKey} instead.&lt;br&gt;&lt;br&gt;

    Keep your private keys safe at all times. You have been warned.&lt;br&gt;&lt;br&gt;

    Note also that the exported string is Base64-encoded, and safe for sending
    in email.&lt;br&gt;&lt;br&gt;

    Arguments:&lt;ul&gt;
    &lt;li&gt;None&lt;/li&gt;
    &lt;/ul&gt;
    
    Keywords:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;passphrase&lt;/b&gt; - default (None) to using existing passphrase.
    Set to '' to export without passphrase (if this is really what you want to do!)&lt;/li&gt;
    &lt;/ul&gt;
    Returns:&lt;ul&gt;
    &lt;li&gt;A base64-encoded string containing an importable key, or None if there is no
    private key available.&lt;/li&gt;
    &lt;/ul&gt;
    """

    passphrase = kwds.get('passphrase', None)
    if passphrase == None:
        passphrase = self.passphrase

    rawpriv = self._rawPrivKey()
    if not rawpriv:
        return None

    # tuple format: (isprivate haspassphrase keyparameters)
    # if using passphrase, 'keypickle' is encrypted against blowfish

    # prepare the key tuple, depending on whether we're using passphrases
    if passphrase != '':
        # encrypt this against passphrase
        ppCipher = blowfish(passphrase, self._passIV)
        encpriv = ppCipher.encrypt(rawpriv)
        keytuple = (_True, _True, encpriv)
    else:
        keytuple = (_True, _False, rawpriv)

    # prepare final pickle, base64 encode, wrap

    #keypickle = pickle.dumps(keytuple, _True)
    keypickle = bencode(keytuple)

    return self._wrap("Key", keypickle)
</t>
<t tx="davidmcnab.121303201707.79">def hasPrivateKey(self):
    """
    Returns 1 if this key object has a private key, 0 if not
    """
    return self.k.hasPrivateKey()
</t>
<t tx="davidmcnab.121303201707.80">def encString(self, raw):
    """
    Encrypt a string of data&lt;br&gt;&lt;br&gt;

    High-level func. encrypts an entire string of data, returning the encrypted
    string as binary.&lt;br&gt;&lt;Br&gt;

    Arguments:&lt;ul&gt;
    &lt;li&gt;raw string to encrypt&lt;/li&gt;
    &lt;/ul&gt;
    Returns:&lt;ul&gt;
    &lt;li&gt;encrypted string as binary&lt;/li&gt;
    &lt;/ul&gt;

    Note - the encrypted string can be stored in files, but I'd suggest
    not emailing them - use L{encStringToAscii} instead. The sole advantage
    of this method is that it produces more compact data, and works a bit faster.
    """

    # All the work gets done by the stream level
    #print "encString: ok1"
    self.encStart()
    #print "encString: ok2"
    enc = self.encNext(raw)
    return enc
</t>
<t tx="davidmcnab.121303201707.81">def encStringToAscii(self, raw):
    """
    Encrypts a string of data to printable ASCII format&lt;br&gt;&lt;br&gt;

    Use this method instead of L{encString}, unless size and speed are
    major issues.&lt;br&gt;&lt;br&gt;

    This method returns encrypted data in bracketed  base64 format,
    safe for sending in email.&lt;br&gt;&lt;br&gt;

    Arguments:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;raw&lt;/b&gt; - string to encrypt&lt;/li&gt;
    &lt;/ul&gt;
    Returns:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;enc&lt;/b&gt; - encrypted string, text-wrapped and Base-64 encoded, safe for
    mailing.&lt;/li&gt;
    &lt;/ul&gt;

    There's an overhead with base64-encoding. It costs size, bandwidth and
    speed. Unless you need ascii-safety, use encString() instead.
    """
    enc = self.encString(raw)
    return self._wrap("Message", enc)
</t>
<t tx="davidmcnab.121303201707.82">def decString(self, enc):
    """
    Decrypts a previously encrypted string.&lt;br&gt;&lt;Br&gt;

    Arguments:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;enc&lt;/b&gt; - string, previously encrypted in binary mode with encString&lt;/li&gt;
    &lt;/ul&gt;
    
    Returns:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;dec&lt;/b&gt; - raw decrypted string&lt;/li&gt;
    &lt;/ul&gt;
    """

    #chunklen = 1024
    #
    #size = len(enc)
    #bits = []
    #pos = 0

    self.decStart()

    # carve up into small chunks so we don't get any order n^2 on large strings
    #while pos &lt; size:
    #    bits.append(self.decNext(enc[pos:pos+chunklen]))
    #    pos = pos + chunklen
    #
    dec = self.decNext(enc)
    self.decEnd()

    #dec = "".join(bits)
    return dec

</t>
<t tx="davidmcnab.121303201707.83">def decStringFromAscii(self, enc):
    """
    Decrypts a previously encrypted string in ASCII (base64)
    format, as created by encryptAscii()&lt;br&gt;&lt;br&gt;

    Arguments:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;enc&lt;/b&gt;ascii-encrypted string, as previously encrypted with
    encStringToAscii()&lt;/li&gt;
    &lt;/ul&gt;
    
    Returns:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;dec&lt;/b&gt; - decrypted string&lt;/li&gt;
    &lt;/ul&gt;

    May generate an exception if the public key of the encrypted string
    doesn't match the public/private keypair in this key object.&lt;br&gt;&lt;br&gt;

    To work around this problem, either instantiate a key object with
    the saved keypair, or use the &lt;b&gt;importKey()&lt;/b&gt; function.&lt;br&gt;&lt;br&gt;

    Exception will also occur if this object is not holding a private key
    (which can happen if you import a key which was previously exported
    via exportKey(). If you get this problem, use exportKeyPrivate() instead
    to export your keypair.
    """
    #trace()
    wrapped = self._unwrap("Message", enc)
    return self.decString(wrapped)
</t>
<t tx="davidmcnab.121303201707.84"></t>
<t tx="davidmcnab.121303201707.85">def signString(self, raw, wrap=_True):
    """
    Sign a string using private key&lt;br&gt;&lt;br&gt;

    Arguments:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;raw&lt;/b&gt; - string to be signed&lt;/li&gt;
    &lt;li&gt;&lt;b&gt;wrap&lt;/b&gt; - wrap in email-friendly ASCII, default True
    &lt;/ul&gt;
    
    Returns:&lt;ul&gt;
    &lt;li&gt;wrapped, base-64 encoded string of signature&lt;/li&gt;
    &lt;/ul&gt;

    Note - private key must already be present in the key object.
    Call &lt;b&gt;importKey()&lt;/b&gt; for the right private key first if needed.
    """

    # hash the key with MD5
    m = md5.new()
    m.update(raw)
    d = m.digest()
    #print "sign: digest"
    #print repr(d)

    # sign the hash with our current public key cipher
    s = self.k.sign(d)

    # now wrap into a tuple with the public key cipher
    tup = (self.algoPname, s)

    # and pickle it

    #p = pickle.dumps(tup, _True)
    p = bencode(tup)

    # lastly, wrap it into our base64
    if wrap:
        p = self._wrap("Signature", p)

    return p

</t>
<t tx="davidmcnab.121303201707.86">def verifyString(self, raw, signature, wrap=_True):
    """
    Verifies a string against a signature.&lt;br&gt;&lt;br&gt;

    Object must first have the correct public key loaded. (see
    &lt;b&gt;importKey&lt;/b&gt;. An exception will occur if this is not the case.&lt;br&gt;&lt;br&gt;

    Arguments:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;raw&lt;/b&gt; - string to be verified&lt;/li&gt;
    &lt;li&gt;&lt;b&gt;signature&lt;/b&gt; - as produced when key is signed with &lt;b&gt;signString&lt;/b&gt;&lt;/li&gt;
    &lt;li&gt;&lt;b&gt;wrap&lt;/b&gt; - take signature as email-friendly wrapped (default True)&lt;/b&gt;&lt;/li&gt;
    &lt;/ul&gt;
    
    Returns:&lt;ul&gt;
    &lt;li&gt;True if signature is authentic, or False if not&lt;/li&gt;
    &lt;/ul&gt;
    """

    # unrwap the signature to a pickled tuple
    if wrap:
        signature = self._unwrap("Signature", signature)

    # unpickle

    #algoname, rawsig = pickle.loads(signature)
    algoname, rawsig = bdecode(signature)

    # ensure we've got the right algorithm
    if algoname != self.algoPname:
        return _False # wrong algorithm - automatic fail

    # hash the string
    m = md5.new()
    m.update(raw)
    d = m.digest()
    #print "verify: digest"
    #print repr(d)

    # now verify the hash against sig
    if self.k.verify(d, rawsig):
        return _True # signature valid, or very clever forgery
    else:
        return _False # sorry
</t>
<t tx="davidmcnab.121303201707.87"></t>
<t tx="davidmcnab.121303201707.88">def getSessKey(self):
    """
    Returns the current cipher's session key
    """
    return self.sessKey
</t>
<t tx="davidmcnab.121303201707.89">def getSessIV(self):
    """
    Returns the starting IV for current session cipher
    """
    return self.sessIV
</t>
<t tx="davidmcnab.121303201707.90">def setSessKey(self, sessKey, IV):
    """
    Resets block cipher to use given session key and IV
    """
    self._setNewSessKey(sessKey, IV)
    self._initBlkCipher()
</t>
<t tx="davidmcnab.121303201707.91">def genSessKey(self):
    """
    Resets block cipher to use random session key and IV
    """
    self._genNewSessKey()
    self._initBlkCipher()
</t>
<t tx="davidmcnab.121303201707.92">def encStringSess(self, plain):
    """
    Encrypts a string against the session cipher,
    with none of the high=level packaging
    """
    return self.blkCipher.encrypt(plain)
</t>
<t tx="davidmcnab.121303201707.93">def decStringSess(self, ciphertext):
    """
    Decrypts a string against the session cipher,
    with none of the high=level packaging
    """
    return self.blkCipher.decrypt(ciphertext)
</t>
<t tx="davidmcnab.121303201707.94">def test(self, raw):
    """
    Encrypts, then decrypts a string. What you get back should
    be the same as what you put in.

    This is totally useless - it just gives a way to test if this API
    is doing what it should.
    """
    enc = self.encString(raw)
    dec = self.decString(enc)
    return dec
</t>
<t tx="davidmcnab.121303201707.95">def testAscii(self, raw):
    """
    Encrypts, then decrypts a string. What you get back should
    be the same as what you put in.

    This is totally useless - it just gives a way to test if this API
    is doing what it should.
    """
    enc = self.encStringToAscii(raw)
    dec = self.decStringFromAscii(enc)
    return dec
</t>
<t tx="davidmcnab.121303201707.96"># ---------------------------------------------
#
# These methods provide stream-level encryption
#
# ---------------------------------------------

</t>
<t tx="davidmcnab.121303201707.97">def encStart(self):
    """
    Starts a stream encryption session&lt;br&gt;
    Sets up internal buffers for accepting ad-hoc data.&lt;br&gt;&lt;br&gt;

    No arguments needed, nothing returned.
    """

    # Create a header block of segments, each segment is
    # encrypted against recipient's public key, to enable
    # recipient to decrypt the rest of the stream.

    # format of header block is:
    #  - recipient public key
    #  - stream algorithm identifiers
    #  - stream session key
    #  - stream cipher initial value

    # stick in pubkey
    pubkey = self._rawPubKey()

    #print "encStart: ok1"
    pubkeyLen = len(pubkey)
    len0 = pubkeyLen % 256
    len1 = pubkeyLen / 256

    #print "pub key len = %d" % pubkeyLen

    self._encHdrs = chr(len0) + chr(len1) + pubkey

    # Create algorithms identifiers blk. Structure is:
    #  1byte  - index into session ciphers table
    #  1byte - session key len in bytes
    #  1byte  - session IV len in bytes

    # add algorithms index
    algInfo = chr(self._algosSes2.index(self.algoSes))

    #print "encStart: ok2"

    # Create new session key
    self._genNewSessKey()

    # add session key length
    sessKeyLen = len(self.sessKey)
    algInfo = algInfo + chr(sessKeyLen)

    # add session IV length
    sessIVLen = len(self.sessIV)
    algInfo = algInfo + chr(sessIVLen)

    # Prefix with 2 length bytes for consistency
    # hardwire because we know the length, which won't change anytime soon
    # don't encrypt this - because the range of values is small,
    # encrypting it could weaken the public key encryption
    algInfo = chr(3) + chr(0) + algInfo
    
    # Add to encrypted headers
    self._encHdrs = self._encHdrs + algInfo

    # ensure we can encrypt session key in one hit
    if len(self.sessKey) &gt; self.pubBlkSize:
        raise Exception(
           "encStart: you need a bigger public key length")

    #print "encStart: ok3"

    # encrypt and add session key
    sKeyEnc = self._encRawPub(self.sessKey)

    #print "encStart: ok4"

    if sKeyEnc == None:
        raise Exception(
            "encStart: encryption of session key failed")

    # Add to encrypted headers
    self._encHdrs = self._encHdrs + sKeyEnc

    # encrypt and add session cipher initial value
    sCipherInit = self._encRawPub(self.sessIV)
    if sCipherInit == None:
        raise Exception(
            "encStart: encryption of session IV failed")


    # Add to encrypted headers
    self._encHdrs = self._encHdrs + sCipherInit

    # Create a new block cipher object
    self._initBlkCipher()

    # ready to go!
    self._encBuf = ''
</t>
<t tx="davidmcnab.121303201707.98">def encNext(self, raw=''):
    """
    Encrypt the next piece of data in a stream.&lt;br&gt;&lt;Br&gt;

    Arguments:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;raw&lt;/b&gt; - raw piece of data to encrypt&lt;/li&gt;
    &lt;/ul&gt;
    
    Returns - one of:&lt;ul&gt;
    &lt;li&gt;'' - not enough data to encrypt yet - stored for later, OR&lt;/li&gt;
    &lt;li&gt;&lt;b&gt;encdata&lt;/b&gt; - string of encrypted data&lt;/li&gt;
    &lt;/ul&gt;
    """

    if raw == '':
        return ''

    # grab any headers
    enc = self._encHdrs
    self._encHdrs = ''

    enc = enc + self.blkCipher.encrypt(raw)
    return enc

</t>
<t tx="davidmcnab.121303201707.99">def encEnd(self):
    """
    Called to terminate a stream session.
    Encrypts any remaining data in buffer.&lt;br&gt;
    &lt;br&gt;
    Kinda obsolete now that we're using stream ciphers with full
    stream chaining mode.&lt;br&gt;
    &lt;br&gt;
    Arguments:&lt;ul&gt;
     &lt;li&gt;None&lt;/li&gt;&lt;/ul&gt;
    Returns:&lt;ul&gt;&lt;li&gt;None&lt;/li&gt;&lt;/ul&gt;
    """

    return ''
</t>
<t tx="davidmcnab.121303201707.100">def decStart(self):
    """
    Start a stream decryption session.&lt;br&gt;&lt;br&gt;

    Call this method first, then feed in pieces of stream data into decNext until
    there's no more data to decrypt&lt;br&gt;&lt;br&gt;

    No arguments, nothing returned
    """

    # Start with fresh buffer and initial state
    self._decBuf = ''
    self._decState = 'p'
    self._decEmpty = _False

    # states - 'p'-&gt;awaiting public key
    #          'c'-&gt;awaiting cipher index
    #          'k'-&gt;awaiting session key
    #          'i'-&gt;awaiting cipher initial data
    #          'd'-&gt;awaiting data block
</t>
<t tx="davidmcnab.121303201707.101">def decNext(self, chunk):
    """
    Decrypt the next piece of incoming stream data.&lt;br&gt;&lt;Br&gt;

    Arguments:&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;chunk&lt;/b&gt; - some more of the encrypted stream&lt;/li&gt;
    &lt;/ul&gt;
    
    Returns (depending on state)&lt;ul&gt;
    &lt;li&gt;'' - no more decrypted data available just yet, OR&lt;/li&gt;
    &lt;li&gt;&lt;b&gt;data&lt;/b&gt; - the next available piece of decrypted data, OR&lt;/li&gt;
    &lt;li&gt;&lt;b&gt;None&lt;/b&gt; - session is complete - no more data available&lt;/li&gt;
    &lt;/ul&gt;
    """

    if self._decEmpty:
        return None

    # add chunk to our buffer
    self._decBuf = self._decBuf + chunk

    # bail out if nothing to do
    chunklen = len(self._decBuf)

    #print "decNext: state=%s, chunklen=%d" % (self._decState, chunklen)
    if chunklen &lt; 2 and self._decState != 'd':
        return ''

    # start with empty decryption buffer
    decData = ''

    # loop around processing as much data as we can
    #print "decNext: started"
    while 1:
        #print "decNext loop: state=%s" % self._decState

        if self._decState == 'd':
            # Expecting raw session stream data
            if self._decBuf == '':
                return ''
            else:
                decData = self.blkCipher.decrypt(self._decBuf)
                self._decBuf = ''
                return decData

        if self._decState == 'p':
            # Expecting public key portion
            size = ord(self._decBuf[0]) + 256 * ord(self._decBuf[1])
            if chunklen &lt; size + 2:
                # don't have full pubkey yet
                return ''
            else:
                pubkey = self._decBuf[2:size+2]
                if not self._testPubKey(pubkey):
                    raise Exception("Can't decrypt - public key mismatch")

                self._decBuf = self._decBuf[size+2:]
                self._decState = 'c'
                #print "Got good public key, size %d" % size
                continue

        if len(self._decBuf) &lt; 2:
            return decData

        sizeReqd = ord(self._decBuf[0]) + 256 * ord(self._decBuf[1]) + 2
        size = len(self._decBuf)

        #print "sizeReqd = %d" % sizeReqd
    
        # bail if we have insufficient data
        if size &lt; sizeReqd:
            return decData

        # extract block
        blk = self._decBuf[0:sizeReqd]
        self._decBuf = self._decBuf[sizeReqd:]

        # state-dependent processing
        if self._decState == 'c':
            # awaiting cipher info - this is plaintext

            #print "Want cipher info block"

            # session cipher index
            c = ord(blk[2])
            self.algoSes = self._algosSes2[c]

            # session key len
            self._tmpSessKeyLen = ord(blk[3])

            # session IV len
            self._tmpSessIVLen = ord(blk[4])

            self._decState = 'k'
            continue

        elif self._decState == 'k':
            # awaiting session key - encrypted
            #print "decrypting session key"
            blk = self._decRawPub(blk)
            self.sessKey = blk[0:self._tmpSessKeyLen]
            self._decState = 'i'
            continue

        elif self._decState == 'i':
            # awaiting cipher start value
            #print "decrypting IV"
            blk = self._decRawPub(blk)
            self.sessIV = blk[0:self._tmpSessIVLen]

            # Create cipher object, now we have what we need
            #self.blkCipher = self.algoSes.new(self.sessKey,
            #                                  getattr(self.algoSes, "MODE_CFB"),
            #                                  self.sessIV)
            self.blkCipher = self.algoSes(self.sessKey, self.sessIV)
            self._calcSesBlkSize()
            self._decState = 'd'
            continue

        else:
            raise Exception(
                "decNext: strange state '%s'" % self._decState[0])
</t>
<t tx="davidmcnab.121303201707.102">def decEnd(self):
    """
    Ends a stream decryption session.
    """
    # nothing really to do here - decNext() has taken care of it
    # just reset internal state
    self._decBuf = ''
    self._decState = 'c'
</t>
<t tx="davidmcnab.121303201707.103"></t>
<t tx="davidmcnab.121303201707.104">def _wrap(self, type, msg):
    """
    Encodes message as base64 and wraps with &lt;StartPyCryptoname&gt;/&lt;EndPycryptoname&gt;
    Args:
     - type - string to use in header/footer - eg 'Key', 'Message'
     - msg - binary string to wrap
    """
    return "&lt;StartPycrypto%s&gt;\n%s&lt;EndPycrypto%s&gt;\n" \
             % (type, base64.encodestring(msg), type)
</t>
<t tx="davidmcnab.121303201707.105">def _unwrap(self, type, msg):
    """
    Unwraps a previously _wrap()'ed message.
    """
    try:
        #trace()
        k1 = msg.split("&lt;StartPycrypto%s&gt;" % type, 1)
        k2 = k1[1].split("&lt;EndPycrypto%s&gt;" % type)
        k = k2[0]
        #print "raw = "
        #print k
        bin = base64.decodestring(k)
        return bin
    except:
        raise Exception("Tried to import Invalid %s" % type)
        self._calcBlkSize()
</t>
<t tx="davidmcnab.121303201707.106">def _calcPubBlkSize(self):
    """
    Determine size of public key
    """
    #self.pubBlkSize = (self.k.size() - 7) / 8
    self.pubBlkSize = self.k.maxSize()
</t>
<t tx="davidmcnab.121303201707.107">def _encRawPub(self, raw):
    """
    Encrypt a small raw string using the public key
    algorithm. Input must not exceed the allowable
    block size.&lt;br&gt;
    &lt;br&gt;
    Arguments:&lt;ul&gt;
     &lt;li&gt;raw - small raw bit of string to encrypt&lt;/li&gt;&lt;/ul&gt;
    Returns:&lt;ul&gt;
     &lt;li&gt;binary representation of encrypted chunk, or
         None if verify failed&lt;/li&gt;&lt;/ul&gt;

    &lt;b&gt;Note&lt;/b&gt; - returned block is prefixed by 2 length bytes, LSB first
    """

    if len(raw) &gt; self.pubBlkSize:
        raise Exception(
            "_encraw: max len %d, passed %d bytes" % (self.pubBlkSize, len(raw)))

    #print "_encRawPub: ok1"
    enc = self.k.encrypt(raw)
    #print "_encRawPub: ok2"

    if self.k.hasPrivateKey():
        dec = self.k.decrypt(enc)
        #print "_encRawPub: ok3"
        if dec != raw:
            raise Exception(
                "_encRawPub: decrypt verify fail")

    enclen = len(enc)
    #print "_encRawPub: hdr bytes are %02x %02x" % (enclen%256, enclen/256)

    enc = chr(enclen % 256) + chr(enclen / 256) + enc
    return enc
</t>
<t tx="davidmcnab.121303201707.108">def _decRawPub(self, enc):
    """
    Decrypt a public-key encrypted block, and return the decrypted string&lt;br&gt;
    &lt;br&gt;
    Arguments:&lt;ul&gt;
     &lt;li&gt;&lt;b&gt;enc&lt;/b&gt; - the encrypted string, in the format as
         created by _encRawPub()&lt;/li&gt;&lt;/ul&gt;
    Returns:&lt;ul&gt;
     &lt;li&gt;decrypted block&lt;/li&gt;&lt;/ul&gt;

    &lt;b&gt;Note&lt;/b&gt;&lt;ul&gt;&lt;li&gt;The ciphertext should be prefixed by 2
                       length bytes, LSB first, as created by
                       &lt;b&gt;_encRawPub&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;
    """

    enclen = len(enc)
    if enclen &lt; 2:
        raise Exception("_decRawPub: ciphertext block too small")
    enclen0 = ord(enc[0]) + 256 * ord(enc[1])
    #print "_decRawPub: hdr bytes are %02x %02x" % (ord(enc[0]), ord(enc[1]))
    if enclen != enclen0 + 2:
        print "_decRawPub: expected %d bytes, got %d bytes" % (
            enclen0+2, enclen)
        raise Exception("_decRawPub: ciphertext block length mismatch")
    
    dec = self.k.decrypt(enc[2:])
    return dec
</t>
<t tx="davidmcnab.121303201707.109">def _initBlkCipher(self):
    """
    Create a new block cipher object, set up with a new session key
    and IV
    """

    self.blkCipher = self.algoSes(self.sessKey, self.sessIV)
    self._calcSesBlkSize()
</t>
<t tx="davidmcnab.121303201707.110">def _calcSesBlkSize(self):
    """
    Determine size of session blocks
    """
    #self.sesBlkSize = (self.blkCipher.block_size)
    self.sesBlkSize = 8 # TODO - ditch this
</t>
<t tx="davidmcnab.121303201707.111">def _testPubKey(self, k):
    """
    Checks if binary-encoded key matches this object's pubkey
    """

    if k == self._rawPubKey():
        return _True
    else:
        return _False
</t>
<t tx="davidmcnab.121303201707.112">def _rawPubKey(self):
    """
    Returns a binary-encoded string of public key
    """
    #return pickle.dumps((self.algoPname, self.k.pubKey()), _True)
    return bencode((self.algoPname, self.k.pubKey()))

</t>
<t tx="davidmcnab.121303201707.113">def _rawPrivKey(self):
    """
    Returns a binary-encoded string of private key, or None if there is no private key
    """
    #return pickle.dumps((self.algoPname, self.k.privKey()), _True)
    if not self.k.hasPrivateKey():
        raise CryptoNoPrivateKey
    return bencode((self.algoPname, self.k.privKey()))
</t>
<t tx="davidmcnab.121303201707.114">def _random(self, bytes):
    """
    Generate an n-byte random number and return it as a string
    """
    cdef char *buf
    buf = &lt;char *&gt;malloc(bytes)
    cdef int RAND_bytes(buf, bytes)

    # convert to python string
    pBuf = PyString_FromStringAndSize(buf, bytes)
    
    # ditch temp buf
    free(buf)
    
    return pBuf
</t>
<t tx="davidmcnab.121303201707.115">def _genNewSessKey(self):
    """
    Generate a new random session key
    """
    self.sessKey = self._random(32)
    self.sessIV = self._random(8)
</t>
<t tx="davidmcnab.121303201707.116">def _setNewSessKey(self, sessKey, IV):
    """
    Sets the session key to specific values
    """
    self.sessKey = sessKey
    self.sessIV = IV
</t>
<t tx="davidmcnab.121303201707.117"></t>
<t tx="davidmcnab.121303201707.118"></t>
<t tx="davidmcnab.121303201707.119">def rndfunc(nbytes):
    bytes = []
    i = 0
    while i &lt; nbytes:
        bytes.append(chr(random.randint(0, 255)))
        i = i + 1
    return "".join(bytes)
</t>
<t tx="davidmcnab.121303201707.120">#
#   number.py : Number-theoretic functions
#
#  Part of the Python Cryptography Toolkit
#
# Distribute and use freely; there are no restrictions on further
# dissemination and usage except those imposed by the laws of your
# country of residence.  This software is provided "as is" without
# warranty of fitness for use or suitability for any purpose, express
# or implied. Use at your own risk or not at all.
#

__revision__ = "$Id: number.py,v 1.13 2003/04/04 18:21:07 akuchling Exp $"

#bignum = long

#try:
#    from Crypto.PublicKey import _fastmath
#except ImportError:
#    _fastmath = None

#_fastmath = None


def size (N):
    """size(N:long) : int
    Returns the size of the number N in bits.
    """
    bits = 0
    power = long(1)
    while N &gt;= power:
        bits = bits + 1
        power = power &lt;&lt; 1
    return bits
</t>
<t tx="davidmcnab.121303201707.121">def GCD(a, b):
    """GCD(a:long, b:long): long
    Return the GCD of a and b.
    """
    a = abs(a)
    b = abs(b)

    if a &lt; b:
        a, b = b, a

    while b &gt; 0:
        r = a % b
        a = b
        b = r
    return a
</t>
<t tx="davidmcnab.121303201707.122">def inverse(u, v):
    """inverse(u:long, u:long):long
    Return the inverse of u mod v.
    """
    u3 = long(u)
    v3 = long(v)

    u1 = long(1)
    v1 = long(0)

    while v3 &gt; 0:
        q = u3 / v3
        u1, v1 = v1, u1 - v1 * q
        u3, v3 = v3, u3 - v3 * q
    while u1 &lt; 0:
        u1 = u1 + v
    return u1
</t>
<t tx="davidmcnab.121303201707.123">def long_to_bytes(n):
    """
    convert a number back to a string
    string is big-endian byte order
    """
    chars = []
    while n &gt; 0:
        rest, chn = divmod(n, 256)
        chars.append(chr(chn))
        n = rest
    chars.reverse()
    return "".join(chars)

</t>
<t tx="davidmcnab.121303201707.124">def bytes_to_long(s):
    """bytes_to_long(string) : long
    Convert a byte string to a long integer.
    string is big-endian byte order

    This is (essentially) the inverse of long_to_bytes().
    """
    n = 0
    for ch in s:
        n = n * 256 + ord(ch)
    return n

</t>
<t tx="davidmcnab.121303201707.125">def genprime(bits=256, myCallback=None, safe=1):
    """
    Generate a secure (Sophie-Germain) prime number&lt;br&gt;
    &lt;br&gt;
    Arguments:&lt;ul&gt;
      &lt;li&gt;bits - number of bits length, default 256&lt;/li&gt;
      &lt;li&gt;callback - a function which accepts 2 arguents - level, num - for giving
          user some feedback of progress&lt;/li&gt;
    &lt;/ul&gt;
    """
    cdef BIGNUM *rand
    #cdef char *randStr

    # change the third parameter to 1 for a strong prime
    rand = BN_generate_prime(NULL,
                             bits,
                             safe,
                             NULL,
                             NULL,
                             callback, &lt;void *&gt;myCallback)

    # convert to a python long
    randLong = bn2pyLong(rand)
    BN_free(rand)
    callback(-1, 0, &lt;void *&gt;myCallback)
    return randLong

</t>
<t tx="davidmcnab.121303201707.126">cdef public void callback(int type, int num, void *arg):
    if arg != &lt;void *&gt;0 and (&lt;object&gt;arg) != None:
        (&lt;object&gt;arg)(type, num)
</t>
<t tx="davidmcnab.121303201707.127">def genrandom(bits=256, top=0, bottom=0):
    """
    Generates an n-bit quality random number
    """
    cdef BIGNUM *rand
    #cdef char *randStr

    # change the third parameter to 1 for a strong prime

    rand = BN_new()

    #print "got new rand obje"

    BN_rand(rand,
            bits,
            top,
            bottom)

    #print "Generated rand"

    # convert to a python long
    randLong = bn2pyLong(rand)

    #print "converted to long"

    BN_free(rand)

    #print "freed rand"

    return randLong

</t>
<t tx="davidmcnab.121303201707.128">cdef public bn2pyLong(BIGNUM *bnum):
    cdef char *numStr
    numStr = BN_bn2dec(bnum)
    numLong = long(numStr)
    CRYPTO_free(numStr)
    return numLong

</t>
<t tx="davidmcnab.121303201707.129">cdef public BIGNUM *pyLong2bn(object n):

    cdef BIGNUM *bnum
    cdef int result
    cdef char *cstr
    
    bnum = BN_new()

    s = repr(n)
    cstr = s
    result = BN_dec2bn(&amp;bnum, cstr)
    if result == 0:
        print "pyLong2bn: conversion failed!!"
        print n
        raise Exception("Conversion failed - Invalid number")
    else:
        return bnum
</t>
<t tx="davidmcnab.121303201707.130">def randomseed(entropy):
    """
    &lt;b&gt;randomseed&lt;/b&gt; - feed entropy to the random number generator&lt;br&gt;
    &lt;br&gt;
    Allows client code to pass entropy to OpenSSL's pseudo-random
    number generation.&lt;br&gt;
    &lt;br&gt;
    You &lt;b&gt;must&lt;/b&gt; call this function before doing anything with this module.
    If you don't, you'll be totally susceptible to random number analysis
    attacks, and your security could be dead in the water. &lt;i&gt;You have been warned!&lt;/i&gt;&lt;br&gt;
    &lt;br&gt;
    Arguments:&lt;ul&gt;
     &lt;li&gt;&lt;b&gt;entropy&lt;/b&gt; - a plain string of data to be fed in as entropy.
     You can pass anything you like here - sampled mouse movements,
     keystrokes etc.&lt;/li&gt;
    &lt;/ul&gt;
    Returns:&lt;ul&gt;
     &lt;li&gt;None&lt;/li&gt;
     &lt;/ul&gt;
    """

    cdef int cBufLen
    cdef char *cBuf

    cBuf = entropy
    cBufLen = len(entropy)

    RAND_seed(cBuf, cBufLen)
</t>
<t tx="davidmcnab.121303201707.131">cdef extern void _c_die()

def _die():
    _c_die()
</t>
<t tx="davidmcnab.121303201707.132"></t>
<t tx="davidmcnab.121303201707.133"># Written by Petru Paler
# see LICENSE.txt for license information

from types import IntType, LongType, StringType, ListType, TupleType, DictType
import re
from cStringIO import StringIO
</t>
<t tx="davidmcnab.121303201707.134">int_filter = re.compile('(0|-?[1-9][0-9]*)e')
string_filter = re.compile('(0|[1-9][0-9]*):')
</t>
<t tx="davidmcnab.121303201707.135">def decode_int(x, f):
    m = int_filter.match(x, f)
    if m is None:
        raise ValueError
    return (long(m.group(1)), m.end())
</t>
<t tx="davidmcnab.121303201707.136">def decode_string(x, f):
    m = string_filter.match(x, f)
    if m is None:
        raise ValueError
    l = int(m.group(1))
    s = m.end()
    return (x[s:s+l], s + l)
</t>
<t tx="davidmcnab.121303201707.137">def decode_list(x, f):
    r = []
    while x[f] != 'e':
        v, f = bdecode_rec(x, f)
        r.append(v)
    return (r, f + 1)
</t>
<t tx="davidmcnab.121303201707.138">def decode_dict(x, f):
    r = {}
    lastkey = None
    while x[f] != 'e':
        k, f = decode_string(x, f)
        if lastkey is not None and lastkey &gt;= k:
            raise ValueError
        lastkey = k
        v, f = bdecode_rec(x, f)
        r[k] = v
    return (r, f + 1)
</t>
<t tx="davidmcnab.121303201707.139">def bdecode_rec(x, f):
    t = x[f]
    if t == 'i':
        return decode_int(x, f + 1)
    elif t == 'l':
        return decode_list(x, f + 1)
    elif t == 'd':
        return decode_dict(x, f + 1)
    else:
        return decode_string(x, f)
</t>
<t tx="davidmcnab.121303201707.140">def bdecode(x):
    try:
        r, l = bdecode_rec(x, 0)
    except IndexError:
        raise ValueError
    if l != len(x):
        raise ValueError
    return r
</t>
<t tx="davidmcnab.121303201707.141">def bencode_rec(x, b):
    t = type(x)
    if t in (IntType, LongType):
        b.write('i%de' % x)
    elif t is StringType:
        b.write('%d:%s' % (len(x), x))
    elif t in (ListType, TupleType):
        b.write('l')
        for e in x:
            bencode_rec(e, b)
        b.write('e')
    elif t is DictType:
        b.write('d')
        keylist = x.keys()
        keylist.sort()
        for k in keylist:
            assert type(k) is StringType
            bencode_rec(k, b)
            bencode_rec(x[k], b)
        b.write('e')
    else:
        assert 0
</t>
<t tx="davidmcnab.121303201707.142">def bencode(x):
    b = StringIO()
    bencode_rec(x, b)
    return b.getvalue()
</t>
<t tx="davidmcnab.121303201707.143">@language python
@others
</t>
<t tx="davidmcnab.121303201707.144">@language python
@others

</t>
<t tx="davidmcnab.121303201707.145">import sys
import struct
import random
import types

from pdb import set_trace

import SSLCrypto

</t>
<t tx="davidmcnab.121303201707.146">

@others
</t>
<t tx="davidmcnab.121303201707.147">class error(Exception):
    pass

</t>
<t tx="davidmcnab.121303201707.148">import time
import sys

import Crypto
from Crypto.Util import randpool
from Crypto.PublicKey import ElGamal as ElGamalOrg

import SSLCrypto

import ElGamal

randfunc = randpool.RandomPool().get_bytes

keysize = 2048

then = time.time()
k1 = ElGamalOrg.generate(keysize, randfunc, sys.stdout.write)
now = time.time()
k1time = now - then
then = now

k2 = ElGamal.ElGamal(keysize, sys.stdout.write)
now = time.time()
k2time = now - then

print "generation times: %s %s" % (k1time, k2time)

pt = "This is a piece of plaintext"


ct1 = k1.encrypt(pt, 12345678)
ct2 = k2.encrypt(pt, 12345678)

print "ct1=%s" % repr(ct1)
print "ct2=%s" % repr(ct2)

dt1 = k1.decrypt(ct1)
dt2 = k2.decrypt(ct2)

print "dt1=%s" % dt1
print "dt2=%s" % dt2

</t>
</tnodes>
</leo_file>
