main.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #!/usr/bin/python3
  2. import argparse
  3. from os.path import join, exists, isfile, basename
  4. from os import makedirs, listdir
  5. from core import shamir_decode, shamir_encode
  6. def main():
  7. parser = argparse.ArgumentParser("Shamir's Secret Sharing")
  8. parser.set_defaults(mode='None')
  9. subparsers = parser.add_subparsers()
  10. split = subparsers.add_parser("split")
  11. split.add_argument("file", help="File to split into multiple files")
  12. split.add_argument("-n", type=int, required=True,
  13. help="Number of parts to split the file.")
  14. split.add_argument("-k", type=int, required=True,
  15. help="Expected number of parts needed to recover the original file.")
  16. split.add_argument("-o", "--output", default='output',
  17. help="Output directory of all the files.")
  18. split.set_defaults(mode='split')
  19. recover = subparsers.add_parser("recover")
  20. recover.add_argument("directory")
  21. recover.add_argument("-p", "--prefix", default="",
  22. help="Read parts from files in directory with this prefix.")
  23. recover.add_argument("-o", "--output", default='',
  24. help="Output file to save the recovered file.")
  25. recover.set_defaults(mode='recover')
  26. args = parser.parse_args()
  27. if args.mode == 'split':
  28. name = basename(args.file)
  29. for part_id in range(args.n):
  30. name_file = f'{name}.{part_id+1}.shamir'
  31. path = join(args.output, name_file)
  32. if exists(path):
  33. print(f"File: {path} already exists, use another directory.")
  34. exit(1)
  35. makedirs(args.output, exist_ok=True)
  36. with open(args.file, 'rb') as f:
  37. data = f.read()
  38. parts = shamir_encode(data, args.k, args.n)
  39. for part_id, part in enumerate(parts):
  40. name_file = f'{name}.{part_id+1}.shamir'
  41. path = join(args.output, name_file)
  42. with open(path, 'wb') as f:
  43. f.write(part)
  44. elif args.mode == 'recover':
  45. parts = []
  46. expected_name = False
  47. for name in listdir(args.directory):
  48. if name.endswith('.shamir') and name.startswith(args.prefix):
  49. file_name = join(args.directory, name)
  50. if isfile(file_name) and name.endswith('shamir'):
  51. expected_name = '.'.join(name.split('.')[:-2])
  52. with open(file_name, 'rb') as f:
  53. parts.append(f.read())
  54. if len(parts) == 0:
  55. print("No parts found")
  56. exit(2)
  57. if args.output != '':
  58. makedirs(args.output, exist_ok=True)
  59. output = join(args.output, expected_name)
  60. if exists(output):
  61. print(f"File: {output} already exists, use another file.")
  62. secret = shamir_decode(parts)
  63. with open(output, 'wb') as f:
  64. f.write(secret)
  65. else:
  66. parser.print_help()
  67. if __name__ == '__main__':
  68. main()