Last active
August 27, 2018 01:24
-
-
Save val314159/ae5c886a593fc1523d936baf690e8343 to your computer and use it in GitHub Desktop.
pkcrypt2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| *.pyc | |
| *.yky | |
| *~ | |
| .ssh | |
| .gitignore | |
| .gitconfig | |
| .ve | |
| .ve2 | |
| .ve3 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| FROM ubuntu | |
| RUN apt-get -y update && apt-get -y upgrade \ | |
| && apt-get -y update && apt-get -y upgrade \ | |
| && apt-get -y install apt-utils | |
| RUN apt-get -y install wget curl tree git openssh-server screen emacs-nox \ | |
| python-pip python-cryptography python-yaml libgmp-dev | |
| RUN pip install fastecdsa pyaml | |
| RUN echo root:toor | chpasswd | |
| RUN useradd -ms /bin/bash val | |
| RUN usermod -a -G sudo val | |
| RUN echo val:v | chpasswd | |
| WORKDIR /home/val | |
| COPY .ssh/ /home/val/.ssh | |
| COPY Dockerfile / | |
| RUN chown -R val:val /home/val/.ssh | |
| USER val | |
| RUN echo > /home/val/.gitconfig '\ | |
| [user]\n\ | |
| email = [email protected]\n\ | |
| name = @val314159\n\ | |
| ' | |
| RUN echo >/home/val/.bash_aliases '\ | |
| alias pull="git pull"\n\ | |
| alias update="git commit -am update && git push"\n\ | |
| ' | |
| #WORKDIR /root | |
| USER val | |
| WORKDIR /home/val | |
| RUN git clone https://gist.github.com/val314159/ae5c886a593fc1523d936baf690e8343 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| all: clean tst tst2 | |
| tst2: g g2 | |
| @echo "==============0" | |
| @echo " Text: Hello" >dat | |
| @echo "==============1" | |
| @cat dat | ./pkcrypt2.py --ykey g -sign --yenv --full | |
| @echo "==============2" | |
| @./pkcrypt2.py -mine dat --prefix 0000 --suffix SUFFIX | tee raw.out | |
| @echo "==============2" | |
| @./pkcrypt2.py -mine dat --prefix 0000 --suffix SUFFIX -o raw2.out | |
| @echo "==============2" | |
| @cat raw.out | openssl ripemd160 | |
| @echo "==============3" | |
| @./pkcrypt2.py -mine dat --prefix 0000 --ykey g --suffix ' Nonce: ' | tee out | |
| @echo "==============4" | |
| @./pkcrypt2.py -mine dat --prefix 0000 --ykey g --suffix ' Nonce: ' -o out2 | |
| @echo "==============4" | |
| @./pkcrypt2.py -verify --yenv <out | |
| @echo "==============5" | |
| @./pkcrypt2.py -verify --yenv --ykey g <out | |
| @echo "==============6" | |
| @tail +2 out | openssl ripemd160 | |
| @echo "==============7" | |
| @./pkcrypt2.py -verify --yenv --ykey g2 <out | echo THIS SHOULD FAIL | |
| @echo "==============8" | |
| tst: ; python tst.py | |
| clean: ; rm -fr makefile.sig makefile.sig? g *.pyc build dist *~ out? makefile.nonce dat g2 out raw.out | |
| g: | |
| ./pkcrypt2.py -g | tee g | |
| g2: | |
| ./pkcrypt2.py -g | tee g2 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python | |
| """ | |
| Public key encryption utility library, simplified. | |
| Mostly tested with python2.7 | |
| - Examples: | |
| Here are most likely the most common things you want to do | |
| with this library: | |
| pkcrypt2.py -g >g # generate a key | |
| pkcrypt2.py --ykey g -sign --yenv<makefile | tee makefile.sig # sign a document | |
| pkcrypt2.py --ykey g -sign --full --yenv<makefile | tee makefile.sig2 # signature + original file | |
| pkcrypt2.py --ykey g -sign -r --yenv<makefile # same as above but ripemd160 added on start | |
| pkcrypt2.py --ykey g -sign -r --full --yenv<makefile | |
| pkcrypt2.py --ykey g -verify --yenv<makefile.sig2 # verify aforementioned makefile against g | |
| pkcrypt2.py -verify2 --yenv<makefile.sig2 # verify aforementioned makefile | |
| pkcrypt2.py -mine makefile.sig2 --skip >makefile.nonce # this will mine for a RIPEMD160 (except for 1st sig line) | |
| pkcrypt2.py --ykey g -mine2<makefile # this will mine for a RIPEMD160 starting with --prefix | |
| """ | |
| import os, sys, json, time, datetime as dt, traceback as tb, hashlib | |
| from fastecdsa import ecdsa, keys, curve | |
| from fastecdsa.point import Point | |
| from cryptography.fernet import Fernet | |
| from x85 import x85_encode, x85_decode | |
| __version__ = "1.10.4" | |
| def hash_str(s): | |
| h = hashlib.new('ripemd160') | |
| h.update(s) | |
| return h.hexdigest() | |
| def long_encode(n): return x85_encode(bytearray.fromhex('{:064x}'.format(n))) | |
| def long_decode(s): return long(x85_decode(s).encode('hex'), 16) | |
| def _str2vk (x, y): return Point(long_decode(x), long_decode(y), curve.P256) | |
| def _str2sig(r, s): return long_decode(r), long_decode(s) | |
| def str2sk (st): return long_decode(st) | |
| def str2vk (st): return _str2vk(*st.split(',')) | |
| def str2sig (st): return _str2sig(*st.split(',')) | |
| def sk2str (sk): return long_encode(sk) | |
| def vk2str (vk): return long_encode(vk.x) +','+long_encode(vk.y) | |
| def sig2str (rs): return long_encode(rs[0])+','+long_encode(rs[1]) | |
| class RipeMD160HashMixin: | |
| @property | |
| def hash(_): h = hashlib.new('ripemd160'); h.update(_.freeze); return h | |
| @property | |
| def hexdigest(_): return _.hash.hexdigest() | |
| def __hash__(_): return hash(_.hexdigest) | |
| def __eq__(_, other): return _.hexdigest == other.hexdigest | |
| def __lt__(_, other): return _.hexdigest < other.hexdigest | |
| def __gt__(_, other): return _.hexdigest > other.hexdigest | |
| pass # end class RipeMD160Mixin | |
| class SaveLoadFileMixin: | |
| def save_fname(_, filename): | |
| open(filename,'w').write(_.freeze) | |
| return True | |
| def store_fname(_, filename): | |
| if os.path.exists(filename): return False | |
| return _.save_fname(filename) | |
| @classmethod | |
| def load_fname(_, filename): return _.thaw(open(filename).read()) | |
| pass # end class SaveLoadFileMixin | |
| class BaseKey(object): | |
| def __init__(_, vkey='', skey=''): | |
| if not vkey: | |
| vkey, skey = _._gen_pair(skey) | |
| elif isinstance(vkey, Key): | |
| if skey: raise TypeError("cannot supply skey with a Key of vkey") | |
| vkey, skey = vkey.public, vkey.secret | |
| elif ',' not in vkey: | |
| vkey, skey = _._gen_pair(vkey) | |
| pass | |
| _.vk, _.sk = str2vk(vkey), str2sk(skey) if skey else '' | |
| pass | |
| @staticmethod | |
| def _gen_pair(skey): | |
| sk = keys.gen_private_key(curve.P256) if not skey else str2sk(skey) | |
| vk = keys.get_public_key(sk, curve.P256) | |
| vkey, skey = vk2str(vk), sk2str(sk) | |
| return vkey, skey | |
| def sign(_, msg): | |
| if not _.sk: raise RuntimeError("Can't sign with no secret") | |
| return sig2str(ecdsa.sign(msg, _.sk)) | |
| def verify(_, msg, sig, raise_error=True): | |
| if ecdsa.verify(str2sig(sig), msg, _.vk): return True | |
| if not raise_error: return False | |
| raise RuntimeError("Verify Exception") | |
| def __repr__(_): return _.public | |
| def __str__(_): return _.short | |
| @property | |
| def short(_): return long_encode(_.vk.x)[:16] | |
| @property | |
| def secret(_): return long_encode(_.sk) if _.sk else '' | |
| @property | |
| def public(_): return long_encode(_.vk.x)+','+long_encode(_.vk.y) | |
| @property | |
| def keys(_): return [_.public, _.secret] | |
| @property | |
| def freeze(_): return _.public+'/'+_.secret+'\n' | |
| @classmethod | |
| def thaw(_, s): return _(*s.strip().split('/', 1)) | |
| pass # end class BaseKey | |
| class Key(BaseKey, SaveLoadFileMixin, RipeMD160HashMixin): | |
| pass # end class Key | |
| class YamlKey(Key): | |
| @property | |
| def full_msg(_): return _.yaml_public+'\n'+_.yaml_secret+'\n' | |
| @property | |
| def yaml_sig(_): return '- $S: "%s"' % _.sign(_.full_msg) | |
| @property | |
| def yaml_public(_): return ' $V: "%s"' % _.public | |
| @property | |
| def yaml_secret(_): return ' P: "%s"' % _.secret | |
| @property | |
| def freeze(_): return(_.yaml_sig+'\n'+_.full_msg) | |
| @classmethod | |
| def thaw(_, str): | |
| from yaml import load | |
| x = load(str)[0] | |
| return _(x['$V'], x.get('P','')) | |
| pass # end class YamlKey | |
| class BaseEnvelope(object): | |
| def __init__(_, msg, prefix='', suffix=''): | |
| _.msg, _.prefix, _.suffix, _.sig = ( | |
| msg, prefix, suffix, '') | |
| @property | |
| def full_msg(_): return _.prefix + _.msg + _.suffix | |
| @classmethod | |
| def _mk_key(_, secret): | |
| return secret if isinstance(secret, Key) else Key(secret) | |
| def verify(_, secret): | |
| key = _._mk_key(secret) | |
| return key.verify(_.full_msg, _.sig) | |
| def sign(_, secret): | |
| key = _._mk_key(secret) | |
| _.sig = key.sign(_.full_msg) | |
| Envelope.verify(_, key) | |
| return _ | |
| @property | |
| def sig_line(_): return _.sig + '\n' | |
| def __str__(_): return _.sig | |
| def __repr__(_): return _.freeze | |
| @property | |
| def freeze(_): return _.sig_line + _.full_msg | |
| @classmethod | |
| def thaw(_, str): | |
| sig, msg = str.split('\n', 1) | |
| e = _(msg) | |
| e.sig = sig | |
| if e.sig != sig: | |
| raise RuntimeError("Verify Mismatch") | |
| return e | |
| pass # end class BaseEnvelope | |
| class Envelope(BaseEnvelope, SaveLoadFileMixin, RipeMD160HashMixin): | |
| pass # end class Envelope | |
| class YamlEnvelope(Envelope): | |
| def __init__(_, msg, *a, **kw): | |
| if 'suppress_date' in kw: | |
| del kw['suppress_date'] | |
| else: | |
| msg = _.mk_date_line() + msg | |
| pass | |
| super(YamlEnvelope, _).__init__(msg, *a, **kw) | |
| def sign(_, secret): | |
| key = _._mk_key(secret) | |
| _.vkey = key.public | |
| _.prefix = _.verify_line | |
| return super(YamlEnvelope, _).sign(key) | |
| def verify(_, k=None): | |
| return super(YamlEnvelope, _).verify(k or Key(_.vkey)) | |
| @property | |
| def sig_line(_): | |
| return '- $S: "%s"\n' % _.sig | |
| @property | |
| def verify_line(_): | |
| return ' $V: "%s"\n' % _.vkey | |
| @classmethod | |
| def mk_date_line(_): | |
| return ' Date: %sZ\n' % dt.datetime.now().isoformat() | |
| @classmethod | |
| def thaw(_, str): | |
| def qstrip(x): | |
| if x.startswith('"') and x.endswith('"'): return x[1:-1] | |
| return x | |
| sig_line, vfy, msg = str.split('\n', 2) | |
| sig = sig_line.split()[-1] | |
| _ = _(msg, suppress_date=True) | |
| _.vkey = qstrip(vfy.split()[-1]) | |
| _.prefix = _.verify_line | |
| _.sig = qstrip(sig) | |
| _.verify() | |
| return _ | |
| pass # end class YamlEnvelope | |
| def decode(key, encoded_text): | |
| cipher_suite = Fernet(key) | |
| decoded_text = cipher_suite.decrypt(encoded_text) | |
| return key, decoded_text | |
| def encode(key, decoded_text): | |
| cipher_suite = Fernet(key) | |
| encoded_text = cipher_suite.encrypt(decoded_text) | |
| return key, encoded_text | |
| def decode_cli(): | |
| key = sys.stdin.readline() | |
| encoded_text = sys.stdin.read().encode() | |
| _, decoded_text = decode(key, encoded_text) | |
| sys.stdout.write(decoded_text.decode()) | |
| def encode_cli(): | |
| key = Fernet.generate_key() #this is your "password" | |
| cipher_suite = Fernet(key) | |
| decoded_text = sys.stdin.read().encode() | |
| key, encoded_text = encode(key, decoded_text) | |
| print(key.decode()) | |
| print(encoded_text.decode()) | |
| def mine_string(inp, prefix='f00f'): | |
| h0 = hashlib.new('ripemd160'); h0.update(inp) | |
| for n in xrange(0x10000000, 0xffffffff): | |
| nce = '%x\n'%n; h1 = h0.copy(); h1.update(nce); hd = h1.hexdigest() | |
| if hd.startswith(prefix): | |
| open('out2', 'w').write(inp + nce) | |
| open('out1', 'w').write(nce) | |
| return nce + ' ' + hd | |
| if (n%0x100000)==0: | |
| sys.stderr.write('%s %s %s\n' % (nce, hd, prefix)) | |
| def mine_file(filename, prefix='f00f', skip_line=True): | |
| with open(filename) as f: | |
| if skip_line: f.readline() | |
| return mine_string(f, read(), prefix) | |
| def mine_and_sign_str(s, key, prefix, suffix): | |
| ye = YamlEnvelope(s, suffix=suffix) | |
| ye.sign(key) | |
| s2 = ye.full_msg | |
| s3 = mine_string(s2, prefix) | |
| ye.suffix += s3.split(' ')[0] | |
| ye.sign(key) | |
| return ye | |
| def main(): | |
| from argparse import ArgumentParser | |
| parser = ArgumentParser(prog='pkcrypt2.py', description='public key cryptography') | |
| parser.add_argument('--skip', action='store_true', help= 'skip first line') | |
| parser.add_argument('--prefix', dest='prefix', default='000000',help='mining hash prefix') | |
| parser.add_argument('--suffix', dest='suffix', default='',help='mining hash suffix') | |
| parser.add_argument('-mine', dest='mine', help='mine') | |
| parser.add_argument('-mine0', dest='mine0', help='mine0') | |
| parser.add_argument('--okey', dest='okey', help= 'old key') | |
| parser.add_argument('--ykey', dest='ykey', help='yaml key') | |
| parser.add_argument('--oenv', action='store_true', help= 'old envelope') | |
| parser.add_argument('--yenv', action='store_true', help='yaml envelope') | |
| parser.add_argument('--full', action='store_true', help='full output') | |
| parser.add_argument('-sign', action='store_true', help='sign a message') | |
| parser.add_argument('-signd', action='store_true', help='sign a message (no date)') | |
| parser.add_argument('-verify', action='store_true', help='verify a message') | |
| parser.add_argument('-g', action='store_true', help='generate old key') | |
| parser.add_argument('-G', action='store_true', help='generate YAML key') | |
| parser.add_argument('-Y', action='store_true', help='print key in YAML format') | |
| parser.add_argument('-O', action='store_true', help='print key in old format') | |
| parser.add_argument('-o', dest='o', help='output block') | |
| parser.add_argument('--version',action='version', version='%(prog)s '+__version__) | |
| args = parser.parse_args() | |
| def key(): | |
| if args.ykey: return YamlKey.thaw(open(args.ykey).read().strip()) | |
| elif args.okey: return Key.thaw(open(args.okey).read().strip()) | |
| else: return '' | |
| def env_class(): return YamlEnvelope if args.yenv else Envelope | |
| if args.mine0: | |
| f = open(args.mine0) | |
| if args.skip: f.readline() | |
| x = mine_string(f.read(), args.prefix) | |
| nonce = x.split(' ')[0] | |
| sys.stdout.write(nonce) | |
| elif args.mine: | |
| f = open(args.mine) | |
| if args.skip: f.readline() | |
| s = f.read() | |
| k = key() | |
| if k: | |
| ye = mine_and_sign_str(s, k, args.prefix, args.suffix) | |
| if args.o: | |
| with open(args.o, 'w') as f: | |
| f.write(repr(ye)) | |
| else: | |
| sys.stdout.write(repr(ye)) | |
| pass | |
| sys.stderr.write(hash_str(ye.full_msg)) | |
| ye.verify() | |
| else: | |
| x = mine_string(s + args.suffix, args.prefix) | |
| nonce = x.split(' ')[0] | |
| if args.o: | |
| with open(args.o, 'w') as f: | |
| f.write(s) | |
| f.write(nonce) | |
| else: | |
| with sys.stdout as f: | |
| f.write(s) | |
| f.write(nonce) | |
| elif args.g: | |
| sys.stdout.write(YamlKey().freeze) | |
| elif args.G: | |
| sys.stdout.write( Key().freeze+'\n') | |
| elif args.Y: | |
| sys.stdout.write(YamlKey(key().secret).freeze) | |
| elif args.O: | |
| sys.stdout.write( Key(key().secret).freeze+'\n') | |
| elif args.sign: | |
| x = env_class()(sys.stdin.read()).sign(key()) | |
| if args.full: | |
| sys.stdout.write(repr(x)) | |
| else: | |
| sys.stdout.write(x.sig_line) | |
| elif args.signd: | |
| x = YamlEnvelope(sys.stdin.read(),suppress_date=True).sign(key()) | |
| if args.full: | |
| sys.stdout.write(repr(x)) | |
| else: | |
| sys.stdout.write(x.sig_line) | |
| elif args.verify: | |
| print(env_class().thaw(sys.stdin.read()).verify(key())) | |
| else: | |
| print("ARGS", args) | |
| if __name__=='__main__': main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python | |
| try: | |
| from setuptools import setup | |
| except ImportError: | |
| from distutils.core import setup | |
| setup(name='pkcrypt2', | |
| version='1.10.4', | |
| description='public key cryptography', | |
| long_description=open('README.md').read(), | |
| author='Joel Ward', | |
| author_email='[email protected]', | |
| license='MIT', | |
| platforms='any', | |
| url='https://gist.github.com/val314159/ae5c886a593fc1523d936baf690e8343', | |
| py_modules=['pkcrypt2','x85'], | |
| scripts=['pkcrypt2.py','x85.py'], | |
| install_requires=['fastecdsa','pyaml','cryptography'], | |
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import yaml | |
| from pkcrypt2 import * | |
| print() | |
| k0 = Key() | |
| print("-----K0", k0) | |
| print(repr(k0)) | |
| print(k0.public) | |
| print(k0.secret) | |
| print(k0.keys) | |
| print() | |
| k1 = Key(repr(k0)) | |
| print("-----K1", k1) | |
| print(repr(k1)) | |
| print(k1.public) | |
| print(k1.secret) | |
| print(k1.keys) | |
| print() | |
| k2 = Key(repr(k0), k0.secret) | |
| print("-----K2", k2) | |
| print(repr(k2)) | |
| print(k2.public) | |
| print(k2.secret) | |
| print(k2.keys) | |
| print() | |
| msg0 = " Text: hellox" | |
| msg1 = " Text: hello" | |
| msg2 = """\ | |
| Text: hello | |
| Action: purr | |
| Refs: A, B, C | |
| """ | |
| sig = k0.sign(msg1) | |
| result = k0.verify(msg1, sig, False) | |
| if not result: | |
| print("MISMATCH") | |
| result = k0.verify(msg0, sig, False) | |
| if result: | |
| print("MISMATCH") | |
| try: | |
| result = k0.verify(msg0, sig) | |
| print("THIS SHOULD FAIL", result) | |
| except RuntimeError: | |
| pass | |
| k10 = Key(k0) | |
| print(k10) | |
| print(repr(k10)) | |
| print(k10.public) | |
| print(k10.secret) | |
| print(k10.keys) | |
| k11 = Key(k1) | |
| print(k11) | |
| print(repr(k11)) | |
| print(k11.public) | |
| print(k11.secret) | |
| print(k11.keys) | |
| k12 = Key(skey=k0.secret) | |
| k13 = Key(k0.secret) | |
| print(k0.secret) | |
| print(k0.public) | |
| print(k12.public) | |
| print(k12.secret) | |
| print(k13.public) | |
| print(k13.secret) | |
| print(hash(k0.secret)) | |
| print(hash(k12.secret)) | |
| print(hash(k13.secret)) | |
| print(k12 == k13) | |
| k12 = Key(k0.secret) | |
| print(k12) | |
| print(repr(k12)) | |
| print(k12.public) | |
| print(k12.secret) | |
| print(k12.keys) | |
| print("MSG1", msg1) | |
| e1 = Envelope(msg1).sign(k0) | |
| print(e1) | |
| print((e1,)) | |
| print((e1.sig)) | |
| e1.verify(k0) | |
| s = repr(e1) | |
| print("SSS", s) | |
| e2 = Envelope.thaw(s) | |
| print(e2) | |
| print((e2,)) | |
| print((e2.sig)) | |
| print((e2.prefix)) | |
| print((e2.msg,)) | |
| print((e2.suffix)) | |
| e2.verify(k0) | |
| print hash(e1) | |
| print hash(e2) | |
| print(';;;;;;;;') | |
| print("msg1", msg1) | |
| print(';;;;;;;;') | |
| f1 = YamlEnvelope(msg1).sign(k0) | |
| print(f1) | |
| print(';;;;;;;;') | |
| s = repr(f1) | |
| print(s,) | |
| print(';;;;;;;;') | |
| f1.verify(k0) | |
| print("F!", f1.vkey) | |
| f1.verify(Key(f1.vkey)) | |
| f1.verify() | |
| print() | |
| print('*'*40) | |
| #print f1.__dict__ | |
| print('^'*10) | |
| print(s,) | |
| print('^'*10) | |
| print(s) | |
| print('^'*10) | |
| y = YamlEnvelope.thaw(s) | |
| print('^'*10) | |
| print(1,y.sig) | |
| print(1,y.sig_line) | |
| print(1,y.vkey) | |
| print(2,y.prefix) | |
| print(3,y.suffix) | |
| print('^'*10) | |
| print(y) | |
| print('^'*10) | |
| print f1.__dict__ | |
| print y.__dict__ | |
| print("@^--"*20) | |
| print(y) | |
| print(y.freeze) | |
| print(repr(y.freeze)) | |
| import hashlib | |
| h0 = hashlib.new('ripemd160') | |
| h0.update(y.freeze) | |
| print repr(h0.digest()) | |
| print h0.hexdigest() | |
| print h0.hexdigest() | |
| print h0.hexdigest() | |
| print h0.hexdigest() | |
| print repr(h0.digest()) | |
| print(hash(y)) | |
| print(hash(y)) | |
| print(hash(y)) | |
| print(hash(y)) | |
| print(e1) | |
| print("SSS",e1.sig) | |
| print("MMM",e1.msg) | |
| e2 = Envelope(msg1).sign(k0) | |
| print(e2) | |
| print("SSS",e2.sig) | |
| print("MMM",e2.msg) | |
| e1.verify(Key(k0.public)) | |
| e1.verify(Key(k0.secret)) | |
| e1.verify(k0.public) | |
| e1.verify(k0.secret) | |
| e1.verify(k0) | |
| e1.verify(k1) | |
| print("E1 . . . . . . . . . . .") | |
| print("sig", e1.sig_line) | |
| print("str", str(e1)) | |
| print("frz", e1.freeze) | |
| print("rpr", repr(e1)) | |
| print("") | |
| print("~ "*20) | |
| print("") | |
| print(k0) | |
| print(repr(msg0)) | |
| print(repr(msg1)) | |
| y0 = YamlEnvelope(msg0).sign(k0) | |
| y1 = YamlEnvelope(msg1).sign(k0) | |
| print("") | |
| print(y0) | |
| print(y0,) | |
| print("") | |
| print(y1) | |
| print(y1,) | |
| print("") | |
| s0 = repr(y0) | |
| s1 = repr(y1) | |
| yy0 = YamlEnvelope.thaw(s0) | |
| yy1 = YamlEnvelope.thaw(s1) | |
| print("") | |
| print(yy0) | |
| print(yy0,) | |
| print("") | |
| print(yy1) | |
| print(yy1,) | |
| print("") | |
| yy0.verify() | |
| yy1.verify() | |
| y0.verify() | |
| y1.verify() | |
| print(yy0.freeze == y0.freeze) | |
| print(y0.freeze) | |
| print(y0.hash) | |
| print(yy0.hash) | |
| print(y0.hash.hexdigest()) | |
| print(yy0.hash.hexdigest()) | |
| print((y0.hexdigest)) | |
| print((yy0.hexdigest)) | |
| print(hash(yy0)) | |
| print(hash(y0)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python | |
| # | |
| # This is the MIT License | |
| # http://www.opensource.org/licenses/mit-license.php | |
| # | |
| # Copyright (c) 2008 Nick Galbreath | |
| # Copyright (c) 2017 Joel Ward | |
| # | |
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |
| # of this software and associated documentation files (the "Software"), to deal | |
| # in the Software without restriction, including without limitation the rights | |
| # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| # copies of the Software, and to permit persons to whom the Software is | |
| # furnished to do so, subject to the following conditions: | |
| # | |
| # The above copyright notice and this permission notice shall be included in | |
| # all copies or substantial portions of the Software. | |
| # | |
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| # THE SOFTWARE. | |
| # | |
| """ | |
| x85 is a new format suitable for use in filenames, urls, and YAML fields | |
| """ | |
| # Original b85 at https://github.com/client9/stringencoders/blob/master/python/b85.py | |
| # modified to make output better for urls and filesystems - jward | |
| gsIntToChar = [ '!', '#', '$', '(', ')', '*', '+', '-', | |
| '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', | |
| ':', ';', '<', '=', '>', '?', '@', | |
| 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', | |
| 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', | |
| 'U', 'V', 'W', 'X', 'Y', 'Z', '[', ']', '^', '_', | |
| 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', | |
| 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', | |
| 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~' ] | |
| # This was hardcoded, now generated on the fly - jward | |
| gsCharToInt = [ 256 ] * 256 | |
| for n, v in enumerate(gsIntToChar): | |
| gsCharToInt[ord(v)] = n | |
| pass | |
| from struct import unpack, pack | |
| # covert 4 characters into 5 | |
| def x85_encode(s): | |
| parts = [] | |
| numchunks = len(s) // 4 | |
| format = '!' + str(numchunks) + 'I' | |
| for x in unpack(format, s): | |
| # network order (big endian), 32-bit unsigned integer | |
| # note: x86 is little endian | |
| parts.append(gsIntToChar[x // 52200625]) | |
| parts.append(gsIntToChar[(x // 614125) % 85]) | |
| parts.append(gsIntToChar[(x // 7225) % 85]) | |
| parts.append(gsIntToChar[(x // 85) % 85]) | |
| parts.append(gsIntToChar[x % 85]) | |
| return ''.join(parts) | |
| # convert 5 characters to 4 | |
| def x85_decode(s): | |
| parts = [] | |
| for i in xrange(0, len(s), 5): | |
| bsum = 0 | |
| for j in xrange(0,5): | |
| bsum = 85*bsum + gsCharToInt[ord(s[i+j])] | |
| parts.append( pack('!I', bsum) ) | |
| return ''.join(parts) | |
| import unittest | |
| class X85Test(unittest.TestCase): | |
| def testDecode1(self): | |
| s = x85_decode('!!!!#') | |
| self.assertEquals(4, len(s)) | |
| self.assertEquals(0, ord(s[0])) | |
| self.assertEquals(0, ord(s[1])) | |
| self.assertEquals(0, ord(s[2])) | |
| self.assertEquals(1, ord(s[3])) | |
| e = x85_encode(s) | |
| self.assertEquals('!!!!#', e) | |
| def run_timings(): | |
| from time import clock | |
| N = 1000000 | |
| s = '!!!!#' * 10 | |
| t0 = clock() | |
| for i in xrange(N): | |
| x85_decode(s) | |
| t1 = clock() | |
| print("decode v1", t1-t0) | |
| t0 = clock() | |
| for i in xrange(N): | |
| x85_decode2(s) | |
| t1 = clock() | |
| print("decode v2", t1-t0) | |
| s = x85_decode('!!!!#' * 10) | |
| t0 = clock() | |
| for i in xrange(N): | |
| x85_encode(s) | |
| t1 = clock() | |
| print("encode v1", t1-t0) | |
| t0 = clock() | |
| for i in xrange(N): | |
| x85_encode2(s) | |
| t1 = clock() | |
| print("encode v2", t1-t0) | |
| return | |
| def usage(): | |
| print("""\ | |
| x85 - cool encoding/decoding format | |
| -e = encode stdin | |
| -d = decode stdin | |
| -t = run unittests | |
| -r = run timings | |
| """) | |
| def main(): | |
| import sys | |
| if not sys.argv[1:]: | |
| usage() | |
| elif sys.argv[1] == '-d': | |
| msg = sys.stdin.read() | |
| while len(msg) % 4: | |
| msg = msg + '\0' | |
| print(x85_encode(msg)) | |
| elif sys.argv[1] == '-e': | |
| msg = sys.stdin.read() | |
| print(x85_decode(msg.strip())) | |
| elif sys.argv[1] == '-t': | |
| unittest.main() | |
| elif sys.argv[1] == '-r': | |
| run_timings() | |
| else: | |
| return usage() | |
| if __name__ == '__main__': main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment