[Cryptography] What should I put in notifications to NSA?

Henry Baker hbaker1 at pipeline.com
Thu Dec 17 17:23:31 EST 2015

At 02:01 PM 12/17/2015, John Levine wrote:
>>Henry Baker asked:
>>What is "encryption"?  What is "encryption technology" ?
>These are laws, not software.  Encryption technology is something that
>a non-insane person would use to encrypt stuff.  Openssl is encryption
>technology, rsync is not.
>Judges are notably impatient with people playing hyper-literal word
>games, so I would advise not going there.

Glad to hear it.  Here's some non-encryption software:


#define maskn(n) ((1<<n)-1)
#define inhex(ch) ((table[ch]&0xff)!=0xff)
#define hex2bin(hi,lo) ((table[(int) (hi)]<<4) | table[(int) (lo)])

#define hexlo(ch) (hextable[(ch)&0xf])
#define hexhi(ch) (hextable[((ch)>>4)&0xf])

/* This code is in the Public Domain.  2015-DEC-17. */
/* This code is for operation on Windows after compilation by MinGW. */
/* http://www.mingw.org/ */
/* Implement set operations on very long binary strings. */
/* Map a binary operation on two files to produce a result file. */
/* Result file length is the length of the shortest file. */
/* xmap stdin with command line file to produce stdout;
   format is *hex* only for stdin, stdout. */
/* The filename given as an argument is a *binary* file. */
/* stdin & stdout files are in *hex* due to Windows brain damage;
   Windows stdin & stdout are not transparent to ^J and ^Z.  */
/* Example:
   b2x <file1> | xmap -a -i123 -n456 <file2> | x2b <file3>
   This will select the subsequence of <file2>,
   starting with 123rd byte and progressing for 456 bytes.
   <file3> gets <file1> AND <file2>
   <file1>, <file2>, <file3> are all binary files. */
/* -a means <file3> gets <file1> AND <file2>     (set intersection)
   -o means <file3> gets <file1> OR <file2>      (set union)
   -x means <file3> gets <file1> XOR <file2>     (set exclusive union)
   -m means <file3> gets <file1> AND NOT <file2> (set difference) */

/* Seek to proper place before processing bytes from binary stream. */
/* The complexity here is to enable seeking in *raw* files like
   "\\\\.\\PhysicalDisk2" and "\\\\.\\F:" */

__int64 _fseeki64( FILE *stream, __int64 offset, int whence )
   long long offsethi = offset & (-512); /* Blocksize = 512 bytes. */
   int offsetlo = offset & 511;
   fflush(stream); /* I don't know why this is required, but it is. */
   int f = _fileno(stream);
   long long retval = _lseeki64( f , offsethi, whence );
   if (retval<0)
       fprintf(stderr,"fseek: failed offsethi=%I64d offsetlo=%d retval=%I64d\n",offsethi,offsetlo,retval);
       return 1;}
   /* We've done the long seek.  Now get to the correct byte. */
   int j,ch;
   for (j=0, ch=fgetc(stream);
        (j<offsetlo) && (ch>=0);
        j++, ch=fgetc(stream));
   if (ch>=0) ungetc(ch,stream);
   /* It seems that retval == offset unless there is an error. */
   return ((ch>=0) && (retval>=0)) ? 0 : 1;

int main(int argc, char *argv[])
  int opt; /* for handling command line options */
  int operation='x'; /* the actual binary operation */
  long long i; /* Used to count # bytes processed. */
  const int linemask=maskn(5); /* linelength of 64. */
  long long initial=0;
  long long length=-1;
  int ch1,ch2,ch3; /* The bytes from file1, file2, file3. */
  char hex1[4]="FF";
  char table[256]; /* Character table */
  const char hextable[16]="0123456789ABCDEF";
  FILE *fp;    /* file1=stdin, file2=fp. */

  /* Initialize character table. */

  for (i=0;i<256;i++) table[i]=255;
  for (i='0';i<='9';i++) table[i]=i-'0';
  for (i='a';i<='f';i++) table[i]=i-'a'+10;
  for (i='A';i<='F';i++) table[i]=i-'A'+10;

  while ((opt=getopt(argc,argv,"ahi:mn:ox"))!=-1)
    switch (opt)
      case 'a': operation='a'; break; /* AND */
      case 'o': operation='o'; break; /* OR */
      case 'm': operation='m'; break; /* SET MINUS = AND NOT */
      case 'x': operation='x'; break; /* XOR */
      case 'i': sscanf(optarg,"%I64d",&initial); break;
      case 'n': sscanf(optarg,"%I64d",&length); break;
      case 'h':
      case '?':
        fprintf(stderr,"\nUsage:\nxmap {-a -m -o -x} -i<position> -n<length> file\n");
        return 1;

  if ((argc-1) != optind) {fprintf(stderr,"xmap: wrong # of args: %d\n",argc-1); return 1;}

  if ((fp=fopen(argv[optind],"rb"))==NULL)
    {fprintf(stderr,"xmap: bad file arg: %s\n",argv[optind]); return 1;}

  if (_fseeki64(fp,initial,SEEK_SET))
    {fprintf(stderr,"b2x: error fseek to position %I64d\n",initial); return 1;}

  /* Skip over non-hex characters. */

  for (ch1=fgetc(stdin); !feof(stdin) && !inhex(ch1); ch1=fgetc(stdin));

  /* map stdin operation fp; shortest file wins. */

  for (hex1[0]=fgetc(stdin),ch2=fgetc(fp),i=0;
       (!feof(stdin)) && (!feof(fp)) && ((i<length) || (length<0));
    { if (feof(stdin)) break; hex1[1]=fgetc(stdin);
      if ((i&linemask)==0) fprintf(stdout,"\n");
      switch (operation)
        case 'a': ch3=ch1&ch2; break;
        case 'm': ch3=ch1&(~ch2); break;
        case 'o': ch3=ch1|ch2; break;
        case 'x': ch3=ch1^ch2; break;
        default: fprintf(stderr,"xmap: bad binop: %c\n",operation); return 1;
      fputc(hexhi(ch3),stdout); fputc(hexlo(ch3),stdout); i++;
      for (ch1=fgetc(stdin); !feof(stdin) && !inhex(ch1); ch1=fgetc(stdin));
      if (feof(stdin)) break; ungetc(ch1,stdin);}

  if (i&linemask) fprintf(stdout,"\n");

  fclose(fp); fclose(stdin); fclose(stdout);

  fprintf(stderr,"xmap: bytes processed: %d\n",(int) i);

  return 0;}

More information about the cryptography mailing list