main.py 2.9 KB

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