import dsa import rsa p = 0x800000000000000089e1855218a0e7dac38136ffafa72eda7859f2171e25e65eac698c1702578b07dc2a1076da241c76c62d374d8389ea5aeffd3226a0530cc565f3bf6b50929139ebeac04f48c3c84afb796d61e5a4f9a8fda812ab59494232c7d2b4deb50aa18ee9e132bfa85ac4374d7f9091abc3d015efc871a584471bb1 q = 0xf4f47f05794b256174bba6e9b396a7707e563c5b if __name__ == '__main__': # er, g = 0 means all signature r values will be 0 -- signature generation won't halt # because that case is detected and retried with another k value # # for signature validation, the signature is rejected early because r < 1 group = dsa.group(p, q, p + 1) pub, priv = dsa.gen_pair(group) z = 1 y = pub[1] r = pow(y, z, group.p) % group.q zinv = rsa.invmod(z, group.q) s = (r * zinv) % group.q magic_sig = (r, s) dsa.verify_sha1(pub, magic_sig, 'hello world') dsa.verify_sha1(pub, magic_sig, 'goodbye world') print 'ok'
dsa_sig = decode_dsa_sig_packet(sig) # recover input to dsa. weirdshit trailer is documented in rfc4880 h = sha256() h.update(msg) h.update(dsa_sig.hashed_hdr) h.update('\x04\xff' + struct.pack('>I', len(dsa_sig.hashed_hdr))) signed_hash = h.hexdigest() assert signed_hash.startswith(dsa_sig.hash_hint.encode('hex')) # we need the group and public key. these are copy and pasted # from gpg --list-keys --with-key-data group = dsa.group( 0xEFAA7C6712B7051C74B47CB4521833A339B8963AC81C7393D8AF569BCAF42B2403BBF098265394F055604C05F6CA8D355590F4F1FD40BA9A6E6FE4858279C005DD7FD236A5918F73884B8B4F852806C4B759FABBF367721397B6864D7B8820D15296594802A62F673E5BCC5B8A974DB6BFD530F383D3EA63178CDB5CE547532288387344BA0E0288178F81211D099B0A9BF072240F6A0CE4E7029CCA034B7887C3AF8C67C21F767262396ED63A6D61311661AACBC4455325236D58E286131C985DA6D83ADC03FA36921250F678EC1453199933ADC2E1187BA30C0AA13C9D7F1076C42F2F33EFD58E6778CCB81CF09B9D56184F2E5E8B54C0F0BE25C34EE092B7, 0xF4EADB01CE599BE4472A92DD673660733D7A3690C1628D74C4A8AA8739B9577B, 0x8B77977DFCB54A8215E1F899A726F9256340C65AD6481E0075AF770CCBC1143581F7D8F0ADE56FC7AE4F1909B0DEEA88B4F87510A91FB4A88E60EC8E5F6ECDC36274A3D4A34A4AEECC71F6BC5DE3F087E6DCD18BB1BDA5FE8B75C1BBF96BEFC4256C48A10B18DD3C47C80F47455FF1D5BBB8F37D6DCEBD47804062895D2B498E65C23C53D0541868DF2D2E781E8A5F5E34C0E72F78BBCEAB6BCFD5B4B11320C81424FDFA929BB999719BFAFE68F50C4AE93F5BBA5AF68A6D843EACEFABBDB43D4639C40851D2A367B0FFD7C0A47A196DEE67A86EED010483AC2CF0AF30BE799BF19ABF61078DAD7CE254C3565F998392B657F141826C30B666BDB1291DBD51FA ) pubkey = 0x8E4602D95606287968CD3BDC48D6815304E53818EEB18B2F8D5A1B463747648A1F91DF4EDF7F559F4ABCEEDBD79DAF5CE028322B09B1E7F10C1C8BABC0986F4C94AB3E9FFCE240BA3A13E9B1D46F3D5F3D2ED1DD50803C1CCEFDE9E27A02A27322045F5E2AF6BC05A8544CA01DC3260385EBDC7345FA00D95E73793ED7FC5F86E4C3A8CAB13056A1B276A82E82FC3A3B7D5BE37511CE08F3D67FA8084DCB10C4F81E6E99147C317045E6447FF525721AAF247B2EC262FFD52BEB1B2FAA90430A5F1F48F07D2F02EAA6D0C746E708814D3DDD24DDE045E4864CA909C969B81CC6C5E3002C1E8E8F706FEC9ECF021F922D11BF0592AAED2C1561DDA2344ACA154 sig = (dsa_sig.dsa_r, dsa_sig.dsa_s) pub = (group, pubkey) h = long(signed_hash, 16) dsa.verify(pub, sig, h) # search for k in chunks of this many values perjob = 0xffff def search_k_from(start):
import dsa, rsa from hashlib import sha1 p = 0x800000000000000089e1855218a0e7dac38136ffafa72eda7859f2171e25e65eac698c1702578b07dc2a1076da241c76c62d374d8389ea5aeffd3226a0530cc565f3bf6b50929139ebeac04f48c3c84afb796d61e5a4f9a8fda812ab59494232c7d2b4deb50aa18ee9e132bfa85ac4374d7f9091abc3d015efc871a584471bb1 q = 0xf4f47f05794b256174bba6e9b396a7707e563c5b g = 0x5958c9d3898b224b12672c0b98e06c60df923cb8bc999d119458fef538b8fa4046c8db53039db620c094c9fa077ef389b5322a559946a71903f990f1f7e0e025e2d7f7cf494aff1a0470f5b64c36b625a097f1651fe775323556fe00b3608c887892878480e99041be601a62166ca6894bdd41a7054ec89f756ba9fc95302291 group = dsa.group(p, q, g) y = 0x2d026f4bf30195ede3a088da85e398ef869611d0f68f0713d51c9c1a3a26c95105d915e2d8cdf26d056b86b8a7b85519b1c23cc3ecdc6062650462e3063bd179c2a6581519f674a61f1d89a1fff27171ebc1b93d4dc57bceb7ae2430f98a6a4d83d8279ee65d71c1203d2c96d65ebbf7cce9d32971c3de5084cce04a2e147821 hash_x = 'ca8f6f7c66fa362d40760d135b763eb8527d3d52' sigs = [ dict(msg='Listen for me, you better listen for me now. ', s=1267396447369736888040262262183731677867615804316, r=1105520928110492191417703162650245113664610474875, m='a4db3de27e2db3e5ef085ced2bced91b82e0df19'), dict(msg='Listen for me, you better listen for me now. ', s=29097472083055673620219739525237952924429516683, r=51241962016175933742870323080382366896234169532, m='a4db3de27e2db3e5ef085ced2bced91b82e0df19'), dict(msg='When me rockin\' the microphone me rock on steady, ', s=277954141006005142760672187124679727147013405915, r=228998983350752111397582948403934722619745721541, m='21194f72fe39a80c9c20689b8cf6ce9b0e7e52d4'), dict(msg='Yes a Daddy me Snow me are de article dan. ', s=1013310051748123261520038320957902085950122277350, r=1099349585689717635654222811555852075108857446485, m='1d7aaaa05d2dee2f7dabdc6fa70b6ddab9c051c5'), dict(msg='But in a in an\' a out de dance em ', s=203941148183364719753516612269608665183595279549,
import dsa p = 0x800000000000000089e1855218a0e7dac38136ffafa72eda7859f2171e25e65eac698c1702578b07dc2a1076da241c76c62d374d8389ea5aeffd3226a0530cc565f3bf6b50929139ebeac04f48c3c84afb796d61e5a4f9a8fda812ab59494232c7d2b4deb50aa18ee9e132bfa85ac4374d7f9091abc3d015efc871a584471bb1 q = 0xf4f47f05794b256174bba6e9b396a7707e563c5b g = 0x5958c9d3898b224b12672c0b98e06c60df923cb8bc999d119458fef538b8fa4046c8db53039db620c094c9fa077ef389b5322a559946a71903f990f1f7e0e025e2d7f7cf494aff1a0470f5b64c36b625a097f1651fe775323556fe00b3608c887892878480e99041be601a62166ca6894bdd41a7054ec89f756ba9fc95302291 y = 0x84ad4719d044495496a3201c8ff484feb45b962e7302e56a392aee4abab3e4bdebf2955b4736012f21a08084056b19bcd7fee56048e004e44984e2f411788efdc837a0d2e5abb7b555039fd243ac01f0fb2ed1dec568280ce678e931868d23eb095fde9d3779191b8c0299d6e07bbb283e6633451e535c45513b2d33c99ea17 hash_x = '0954edd5e0afe5542a4adf012611a91912a3ec16' group = dsa.group(p, q, g) if __name__ == '__main__': # smoke test pub, priv = dsa.gen_pair(group) msg = 'fart' sig = dsa.sign_sha1(priv, msg) dsa.verify_sha1(pub, sig, msg) msg = "For those that envy a MC it can be hazardous to your health\nSo be friendly, a matter of life and death, just like a etch-a-sketch\n" pub = (group, y) sig = (548099063082341131477253921760299949438196259240, 857042759984254168557880549501802188789837994940) dsa.verify_sha1(pub, sig, msg) # brute force value for k for k in range(0, 2**16): x = dsa.recover_x_given_sig_k(group, k, sig, msg) # check using known hash (could also use pubkey = g^x mod p) if dsa.sha1('%x' % x).hexdigest() == hash_x: print 'k: 0x%x, x: 0x%x' % (k, x) break
assert hashfn == 'SHA256' dsa_sig = decode_dsa_sig_packet(sig) # recover input to dsa. weirdshit trailer is documented in rfc4880 h = sha256() h.update(msg) h.update(dsa_sig.hashed_hdr) h.update('\x04\xff' + struct.pack('>I', len(dsa_sig.hashed_hdr))) signed_hash = h.hexdigest() assert signed_hash.startswith(dsa_sig.hash_hint.encode('hex')) # we need the group and public key. these are copy and pasted # from gpg --list-keys --with-key-data group = dsa.group(0xEFAA7C6712B7051C74B47CB4521833A339B8963AC81C7393D8AF569BCAF42B2403BBF098265394F055604C05F6CA8D355590F4F1FD40BA9A6E6FE4858279C005DD7FD236A5918F73884B8B4F852806C4B759FABBF367721397B6864D7B8820D15296594802A62F673E5BCC5B8A974DB6BFD530F383D3EA63178CDB5CE547532288387344BA0E0288178F81211D099B0A9BF072240F6A0CE4E7029CCA034B7887C3AF8C67C21F767262396ED63A6D61311661AACBC4455325236D58E286131C985DA6D83ADC03FA36921250F678EC1453199933ADC2E1187BA30C0AA13C9D7F1076C42F2F33EFD58E6778CCB81CF09B9D56184F2E5E8B54C0F0BE25C34EE092B7, 0xF4EADB01CE599BE4472A92DD673660733D7A3690C1628D74C4A8AA8739B9577B, 0x8B77977DFCB54A8215E1F899A726F9256340C65AD6481E0075AF770CCBC1143581F7D8F0ADE56FC7AE4F1909B0DEEA88B4F87510A91FB4A88E60EC8E5F6ECDC36274A3D4A34A4AEECC71F6BC5DE3F087E6DCD18BB1BDA5FE8B75C1BBF96BEFC4256C48A10B18DD3C47C80F47455FF1D5BBB8F37D6DCEBD47804062895D2B498E65C23C53D0541868DF2D2E781E8A5F5E34C0E72F78BBCEAB6BCFD5B4B11320C81424FDFA929BB999719BFAFE68F50C4AE93F5BBA5AF68A6D843EACEFABBDB43D4639C40851D2A367B0FFD7C0A47A196DEE67A86EED010483AC2CF0AF30BE799BF19ABF61078DAD7CE254C3565F998392B657F141826C30B666BDB1291DBD51FA) pubkey = 0x8E4602D95606287968CD3BDC48D6815304E53818EEB18B2F8D5A1B463747648A1F91DF4EDF7F559F4ABCEEDBD79DAF5CE028322B09B1E7F10C1C8BABC0986F4C94AB3E9FFCE240BA3A13E9B1D46F3D5F3D2ED1DD50803C1CCEFDE9E27A02A27322045F5E2AF6BC05A8544CA01DC3260385EBDC7345FA00D95E73793ED7FC5F86E4C3A8CAB13056A1B276A82E82FC3A3B7D5BE37511CE08F3D67FA8084DCB10C4F81E6E99147C317045E6447FF525721AAF247B2EC262FFD52BEB1B2FAA90430A5F1F48F07D2F02EAA6D0C746E708814D3DDD24DDE045E4864CA909C969B81CC6C5E3002C1E8E8F706FEC9ECF021F922D11BF0592AAED2C1561DDA2344ACA154 sig = (dsa_sig.dsa_r, dsa_sig.dsa_s) pub = (group, pubkey) h = long(signed_hash, 16) dsa.verify(pub, sig, h) # search for k in chunks of this many values perjob = 0xffff def search_k_from(start): search_k(group, start, start + perjob, sig, h)