├── requirements.txt ├── example ├── generate.sh ├── horcrux_2.svg ├── horcrux_6.svg ├── horcrux_3.svg ├── horcrux_4.svg ├── horcrux_5.svg ├── horcrux_7.svg ├── horcrux_1.svg └── horcrux_full.svg ├── README.md └── horqrux.py /requirements.txt: -------------------------------------------------------------------------------- 1 | beautifulsoup4 2 | more-itertools 3 | qrcode 4 | -------------------------------------------------------------------------------- /example/generate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ../horqrux.py "hello hackernews" 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # horQRux 2 | 3 | ### Disclaimer 4 | 5 | This is only a proof of concept, don't use it to protect serious data. 6 | 7 | ### Proof of concept 8 | 9 | By splitting a QR code into 7 fragments, we may physically split and distribute a secret into the real world. For example by printing the QR fragments onto transparent paper and handing them out to multiple people. 10 | 11 | ![full](example/horcrux_full.svg) = ![1](example/horcrux_1.svg) + ![2](example/horcrux_2.svg) + ![3](example/horcrux_3.svg) + ![4](example/horcrux_4.svg) + ![5](example/horcrux_5.svg) + ![6](example/horcrux_6.svg) + ![7](example/horcrux_7.svg) 12 | -------------------------------------------------------------------------------- /horqrux.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | 3 | import random 4 | import sys 5 | from copy import copy 6 | 7 | import qrcode 8 | import qrcode.image.svg 9 | from bs4 import BeautifulSoup 10 | from more_itertools import chunked_even 11 | 12 | factory = qrcode.image.svg.SvgFragmentImage 13 | qrcode = qrcode.make(sys.argv[1], image_factory=factory) 14 | svg_string = qrcode.to_string(encoding='unicode') 15 | with open("horcrux_full.svg", 'w') as f: 16 | f.write(svg_string) 17 | svg = BeautifulSoup(svg_string, 'xml') 18 | svg_object = svg.find('svg:svg') 19 | 20 | rects = svg.find_all('svg:rect') 21 | random.shuffle(rects) 22 | horcruxes = chunked_even(rects, len(rects)//6) 23 | 24 | svg_object.clear() 25 | 26 | # write horcruxes to svg files 27 | for idx, horcrux in enumerate(horcruxes): 28 | horcrux_svg = copy(svg_object) 29 | for rect in horcrux: 30 | horcrux_svg.append(rect) 31 | with open(f"horcrux_{idx + 1}.svg", 'w') as f: 32 | f.write(str(horcrux_svg)) 33 | -------------------------------------------------------------------------------- /example/horcrux_2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/horcrux_6.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/horcrux_3.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/horcrux_4.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/horcrux_5.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/horcrux_7.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/horcrux_1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/horcrux_full.svg: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------