chiark / gitweb /
shamir.in: Declare subcommands with decorator.
[distorted-keys] / shamir.in
index 019efc95f9de64436732e0f5b4cf2968c382deae..15665ea20d9571142850bf5fe82c68cea5dba93a 100755 (executable)
--- a/shamir.in
+++ b/shamir.in
@@ -546,6 +546,12 @@ class SubcommandOptionParser (OPT.OptionParser, object):
     opts, args = op.parse_args(args[1:])
     sub.func(gopts, opts, args)
 
+def subcommand(name, usage, desc, opts = []):
+  def _(func):
+    OPTPARSE.add_subcommand(name, func, usage, desc, opts)
+    return func
+  return _
+
 OPTPARSE = SubcommandOptionParser(
   usage = '%prog SUBCOMMAND [ARGS ...]',
   version = '%%prog, %s version %s' % (PACKAGE, VERSION),
@@ -562,6 +568,18 @@ def parse_sharing(string):
     raise ValueError, "no `/'"
   return int(string[slash + 1:]), int(string[:slash])
 
+@subcommand('issue', '[-H HASHFN] THRESH/COUNT [SECRET-FILE]',
+  """\
+Issue shares of a secret.  The secret (as a binary lump) is read from
+SECRET-FILE, or standard input if SECRET-FILE is omitted.  COUNT + 1 lines
+are written to standard output: the first line contains the sharing
+parameters, and does not need to be kept especially secret (though it
+contains a hash of the secret, so it compromises the unconditional security
+of the secret sharing scheme); the remaining lines are the shares, one per
+line.  All of the lines are plain text.""",
+  [OPT.make_option('-H', '--hash-function', type = 'string',
+                   action = 'store', dest = 'hashfn', default = 'sha256',
+                   help = 'Hash function for verifying the share.')])
 def cmd_issue(gopts, opts, args):
 
   if len(args) < 1 or len(args) > 2:
@@ -589,24 +607,18 @@ def cmd_issue(gopts, opts, args):
     share = Share(i, ss.issue(i + 1))
     print share.encode()
 
-OPTPARSE.add_subcommand(
-  'issue', cmd_issue,
-  '[-H HASHFN] THRESH/COUNT [SECRET-FILE]',
-  """\
-Issue shares of a secret.  The secret (as a binary lump) is read from
-SECRET-FILE, or standard input if SECRET-FILE is omitted.  COUNT + 1 lines
-are written to standard output: the first line contains the sharing
-parameters, and does not need to be kept especially secret (though it
-contains a hash of the secret, so it compromises the unconditional security
-of the secret sharing scheme); the remaining lines are the shares, one per
-line.  All of the lines are plain text.""",
-  [OPT.make_option('-H', '--hash-function', type = 'string',
-                   action = 'store', dest = 'hashfn', default = 'sha256',
-                   help = 'Hash function for verifying the share.')])
-
 ###--------------------------------------------------------------------------
 ### Recover a secret from shares.
 
+@subcommand('recover', '',
+  """\
+Standard input should contain a number of lines.  The first line should
+contain the secret sharing parameters (the first line output by `issue');
+the remaining lines should contain shares.  The shares may be supplied in
+any order.  The secret is written to the OUTPUT file, or standard output.""",
+  [OPT.make_option('-o', '--output', action = 'store', type = 'string',
+                  dest = 'file', default = '-',
+                  help = 'Write the secret to FILE.')])
 def cmd_recover(gopts, opts, args):
 
   ## Keep track of how well we've done so far.  Report all of the things
@@ -673,18 +685,6 @@ def cmd_recover(gopts, opts, args):
     with open(opts.file, 'wb') as f:
       f.write(secret.secret)
 
-OPTPARSE.add_subcommand(
-  'recover', cmd_recover,
-  '',
-  """\
-Standard input should contain a number of lines.  The first line should
-contain the secret sharing parameters (the first line output by `issue');
-the remaining lines should contain shares.  The shares may be supplied in
-any order.  The secret is written to the OUTPUT file, or standard output.""",
-  [OPT.make_option('-o', '--output', action = 'store', type = 'string',
-                  dest = 'file', default = '-',
-                  help = 'Write the secret to FILE.')])
-
 ###----- That's all, folks --------------------------------------------------
 
 if __name__ == '__main__':