"""
+import base64
import binascii
import bisect
import ctypes
PDTCRYPT_DEFAULT_VER = 1
PDTCRYPT_DEFAULT_PVER = 1
+# scrypt hashing output control
+PDTCRYPT_SCRYPT_INTRANATOR = 0
+PDTCRYPT_SCRYPT_PARAMETERS = 1
+
+PDTCRYPT_SCRYPT_FORMAT = \
+ { "i2n" : PDTCRYPT_SCRYPT_INTRANATOR
+ , "params" : PDTCRYPT_SCRYPT_PARAMETERS }
+
class PDTDecryptionError (Exception):
"""Decryption failed."""
return 0
-def mode_scrypt (pw, ins=None, nacl=None):
+def mode_scrypt (pw, ins=None, nacl=None, fmt=PDTCRYPT_SCRYPT_INTRANATOR):
hsh = None
+ paramversion = PDTCRYPT_DEFAULT_PVER
if ins is not None:
hsh, nacl, version, paramversion = scrypt_hashsource (pw, ins)
defs = ENCRYPTION_PARAMETERS.get(paramversion, None)
else:
nacl = binascii.unhexlify (nacl)
- defs = ENCRYPTION_PARAMETERS.get(PDTCRYPT_DEFAULT_PVER, None)
+ defs = ENCRYPTION_PARAMETERS.get(paramversion, None)
version = PDTCRYPT_DEFAULT_VER
kdfname, params = defs ["kdf"]
hsh, _void = kdf (pw, nacl)
import json
- out = json.dumps ({ "salt" : binascii.hexlify (nacl).decode ()
- , "hash" : binascii.hexlify (hsh).decode ()
- , "version" : version
- , "scrypt_params" : { "N" : params ["N"]
- , "r" : params ["r"]
- , "p" : params ["p"]
- , "dkLen" : params ["dkLen"] } })
+
+ if fmt == PDTCRYPT_SCRYPT_INTRANATOR:
+ out = json.dumps ({ "salt" : base64.b64encode (nacl).decode ()
+ , "key" : base64.b64encode (hsh) .decode ()
+ , "paramversion" : paramversion })
+ elif fmt == PDTCRYPT_SCRYPT_PARAMETERS:
+ out = json.dumps ({ "salt" : binascii.hexlify (nacl).decode ()
+ , "key" : binascii.hexlify (hsh) .decode ()
+ , "version" : version
+ , "scrypt_params" : { "N" : params ["N"]
+ , "r" : params ["r"]
+ , "p" : params ["p"]
+ , "dkLen" : params ["dkLen"] } })
+ else:
+ raise RuntimeError ("bad scrypt output scheme %r" % fmt)
+
print (out)
+
def usage (err=False):
out = print
if err is True:
out (" %s [ { -n | --nacl } { SALT } ]" % indent)
out (" %s [ { -o | --out } { - | DESTINATION } ]" % indent)
out (" %s [ -D | --no-decrypt ] [ -S | --split ]" % indent)
+ out (" %s [ -f | --format ]" % indent)
out ("")
out ("\twhere")
out ("\t\tSUBCOMMAND main mode: { process | scrypt }")
out ("\t\t-S split into files at object boundaries; this")
out ("\t\t requires DESTINATION to refer to directory")
out ("\t\t-D PDT header and ciphertext passthrough")
+ out ("\t\t-f format of SCRYPT hash output (“default” or “parameters”)")
out ("")
out ("\tinstead of filenames, “-” may used to specify stdin / stdout")
out ("")
def parse_argv (argv):
global SELF
- mode = PDTCRYPT_DECRYPT
- secret = None
- insspec = None
- outsspec = None
- nacl = None
+ mode = PDTCRYPT_DECRYPT
+ secret = None
+ insspec = None
+ outsspec = None
+ nacl = None
+ scrypt_format = None
argvi = iter (argv)
SELF = os.path.basename (next (argvi))
if arg in [ "-n", "--nacl", "--salt" ]:
nacl = checked_arg ()
if PDTCRYPT_VERBOSE is True: noise ("PDT: salt key with %s" % nacl)
+ elif arg in [ "-f", "--format" ]:
+ arg = checked_arg ()
+ try:
+ scrypt_format = PDTCRYPT_SCRYPT_FORMAT [arg]
+ except KeyError:
+ bail ("ERROR: invalid scrypt output format %s" % arg)
+ if PDTCRYPT_VERBOSE is True:
+ noise ("PDT: scrypt output format “%s”" % scrypt_format)
else:
bail ("ERROR: unexpected positional argument “%s”" % arg)
ins = deptdcrypt_mk_stream (PDTCRYPT_SOURCE, insspec or "-")
if subcommand == PDTCRYPT_SUB_SCRYPT:
- return True, partial (mode_scrypt, secret [1].encode (), ins, nacl)
+ return True, partial (mode_scrypt, secret [1].encode (), ins, nacl,
+ fmt=scrypt_format)
if mode & PDTCRYPT_SPLIT: # destination must be directory
if outsspec is None or outsspec == "-":