#!/usr/bin/env python3

import re

keypair = r'''#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "mceliece.h" /* -lmceliece */
#include "limits.inc"

static unsigned char pk[PRIMITIVE_PUBLICKEYBYTES];
static unsigned char sk[PRIMITIVE_SECRETKEYBYTES];

static void die_temp(const char *why,const char *why2)
{
  if (why2)
    fprintf(stderr,"PRIMITIVE-keypair: fatal: %s: %s\n",why,why2);
  else
    fprintf(stderr,"PRIMITIVE-keypair: fatal: %s\n",why);
  exit(111);
}

int main()
{
  FILE *pkfile;
  FILE *skfile;

  limits();

  pkfile = fdopen(5,"w");
  if (!pkfile) {
    fprintf(stderr,"PRIMITIVE-keypair: usage: PRIMITIVE-keypair: 5>publickey 9>secretkey\n");
    die_temp("fdopen 5 failed",strerror(errno));
  }

  skfile = fdopen(9,"w");
  if (!skfile) {
    fprintf(stderr,"PRIMITIVE-keypair: usage: PRIMITIVE-keypair: 5>publickey 9>secretkey\n");
    die_temp("fdopen 9 failed",strerror(errno));
  }

  PRIMITIVE_keypair(pk,sk);

  if (fwrite(pk,1,sizeof pk,pkfile) < sizeof pk)
    die_temp("write publickey failed",strerror(errno));
  if (fflush(pkfile))
    die_temp("write publickey failed",strerror(errno));
  fclose(pkfile);

  if (fwrite(sk,1,sizeof sk,skfile) < sizeof sk)
    die_temp("write secretkey failed",strerror(errno));
  if (fflush(skfile))
    die_temp("write secretkey failed",strerror(errno));
  fclose(skfile);

  return 0;
}
'''

enc = r'''#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "mceliece.h" /* -lmceliece */
#include "limits.inc"

static unsigned char pk[PRIMITIVE_PUBLICKEYBYTES];
static unsigned char c[PRIMITIVE_CIPHERTEXTBYTES];
static unsigned char k[PRIMITIVE_BYTES];

static void die_temp(const char *why,const char *why2)
{
  if (why2)
    fprintf(stderr,"PRIMITIVE-enc: fatal: %s: %s\n",why,why2);
  else
    fprintf(stderr,"PRIMITIVE-enc: fatal: %s\n",why);
  exit(111);
}

int main()
{
  FILE *pkfile;
  FILE *kfile;

  limits();

  pkfile = fdopen(4,"r");
  if (!pkfile) {
    fprintf(stderr,"PRIMITIVE-enc: usage: PRIMITIVE-enc >ciphertext 7>sessionkey 4<publickey\n");
    die_temp("fdopen 4 failed",strerror(errno));
  }

  kfile = fdopen(7,"w");
  if (!kfile) {
    fprintf(stderr,"PRIMITIVE-enc: usage: PRIMITIVE-enc >ciphertext 7>sessionkey 4<publickey\n");
    die_temp("fdopen 7 failed",strerror(errno));
  }

  if (fread(pk,1,sizeof pk,pkfile) < sizeof pk) {
    if (ferror(pkfile))
      die_temp("read publickey failed",strerror(errno));
    die_temp("read publickey failed","end of file");
  }
  fclose(pkfile);

  if (PRIMITIVE_enc(c,k,pk)) die_temp("encapsulation failed",0);

  if (fwrite(c,1,sizeof c,stdout) < sizeof c)
    die_temp("write ciphertext failed",strerror(errno));
  if (fflush(stdout))
    die_temp("write ciphertext failed",strerror(errno));
  fclose(stdout);

  if (fwrite(k,1,sizeof k,kfile) < sizeof k)
    die_temp("write sessionkey failed",strerror(errno));
  if (fflush(kfile))
    die_temp("write sessionkey failed",strerror(errno));
  fclose(kfile);

  return 0;
}
'''

dec = r'''#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "mceliece.h" /* -lmceliece */
#include "limits.inc"

static unsigned char sk[PRIMITIVE_SECRETKEYBYTES];
static unsigned char c[PRIMITIVE_CIPHERTEXTBYTES];
static unsigned char k[PRIMITIVE_BYTES];

static void die_temp(const char *why,const char *why2)
{
  if (why2)
    fprintf(stderr,"PRIMITIVE-dec: fatal: %s: %s\n",why,why2);
  else
    fprintf(stderr,"PRIMITIVE-dec: fatal: %s\n",why);
  exit(111);
}

int main()
{
  FILE *skfile;
  FILE *kfile;

  limits();

  skfile = fdopen(8,"r");
  if (!skfile) {
    fprintf(stderr,"PRIMITIVE-dec: usage: PRIMITIVE-dec 7>sessionkey <ciphertext 8<secretkey\n");
    die_temp("fdopen 8 failed",strerror(errno));
  }

  kfile = fdopen(7,"w");
  if (!kfile) {
    fprintf(stderr,"PRIMITIVE-dec: usage: PRIMITIVE-dec 7>sessionkey <ciphertext 8<secretkey\n");
    die_temp("fdopen 7 failed",strerror(errno));
  }

  if (fread(sk,1,sizeof sk,skfile) < sizeof sk) {
    if (ferror(skfile))
      die_temp("read secretkey failed",strerror(errno));
    die_temp("read secretkey failed","end of file");
  }
  fclose(skfile);

  if (fread(c,1,sizeof c,stdin) < sizeof c) {
    if (ferror(stdin))
      die_temp("read ciphertext failed",strerror(errno));
    die_temp("read ciphertext failed","end of file");
  }
  fclose(stdin);

  if (PRIMITIVE_dec(k,c,sk)) die_temp("decapsulation failed",0);

  if (fwrite(k,1,sizeof k,kfile) < sizeof k)
    die_temp("write sessionkey failed",strerror(errno));
  if (fflush(kfile))
    die_temp("write sessionkey failed",strerror(errno));
  fclose(kfile);

  return 0;
}
'''

for size in '6960119','6688128','8192128','460896','348864':
  for primitive in 'mceliece'+size,'mceliece'+size+'pc':
    with open('command/%s-keypair.c'%primitive,'w') as f:
      f.write(re.sub('PRIMITIVE',primitive,keypair))
    with open('command/%s-enc.c'%primitive,'w') as f:
      f.write(re.sub('PRIMITIVE',primitive,enc))
    with open('command/%s-dec.c'%primitive,'w') as f:
      f.write(re.sub('PRIMITIVE',primitive,dec))
    with open('command/%sf-keypair.c'%primitive,'w') as f:
      f.write(re.sub('PRIMITIVE',primitive+'f',keypair))
