コード例 #1
0
ファイル: test_mpin_tp.c プロジェクト: gitter-badger/MiotCL
int main()
{
  int i,PIN1,PIN2,rtn,err,iter;

  char client_id[256];
  octet CLIENT_ID = {0,sizeof(client_id),client_id};

  char x[PGS],y[PGS];
  octet X={sizeof(x), sizeof(x),x};
  octet Y={sizeof(y),sizeof(y),y};

  /* Master secret shares */
  char ms1[PGS], ms2[PGS];
  octet MS1={sizeof(ms1),sizeof(ms1),ms1};
  octet MS2={sizeof(ms2),sizeof(ms2),ms2};

  /* Hash values of CLIENT_ID */
  char hcid[32];
  octet HCID={sizeof(hcid),sizeof(hcid), hcid};

  /* Client secret and shares */
  char cs1[2*PFS+1], cs2[2*PFS+1], sec[2*PFS+1];
  octet SEC={sizeof(sec),sizeof(sec),sec};
  octet CS1={sizeof(cs1),sizeof(cs1), cs1};
  octet CS2={sizeof(cs2),sizeof(cs2), cs2};

  /* Server secret and shares */
  char ss1[4*PFS], ss2[4*PFS], serverSecret[4*PFS];
  octet ServerSecret={sizeof(serverSecret),sizeof(serverSecret),serverSecret};
  octet SS1={sizeof(ss1),sizeof(ss1),ss1};
  octet SS2={sizeof(ss2),sizeof(ss2),ss2};

  /* Time Permit and shares */
  char tp1[2*PFS+1], tp2[2*PFS+1], tp[2*PFS+1];
  octet TP={sizeof(tp),sizeof(tp),tp};
  octet TP1={sizeof(tp1),sizeof(tp1),tp1};
  octet TP2={sizeof(tp2),sizeof(tp2),tp2};

  /* Token stored on computer */
  char token[2*PFS+1];
  octet TOKEN={sizeof(token),sizeof(token),token};

  char ut[2*PFS+1],u[2*PFS+1];
  octet UT={sizeof(ut),sizeof(ut),ut};
  octet U={sizeof(u),sizeof(u),u};

  char hid[2*PFS+1],htid[2*PFS+1];
  octet HID={0,sizeof(hid),hid};
  octet HTID={0,sizeof(htid),htid};

  char e[12*PFS], f[12*PFS];
  octet E={sizeof(e),sizeof(e),e};
  octet F={sizeof(f),sizeof(f),f};

  PIN1 = 1234;
  PIN2 = 1234;

  /* Assign the End-User an ID */
  char* user = "******";
  OCT_jstring(&CLIENT_ID,user);
  printf("CLIENT: ID %s\n", user);

  int date = 0;
  char seed[100] = {0};
  octet SEED = {0,sizeof(seed),seed};
  csprng RNG;               

  /* unrandom seed value! */
  SEED.len=100;
  for (i=0;i<100;i++) SEED.val[i]=i+1;

  /* initialise random number generator */ 
  CREATE_CSPRNG(&RNG,&SEED);   

  /* Hash CLIENT_ID */
  MPIN_HASH_ID(&CLIENT_ID,&HCID); 
  OCT_output(&HCID);

  /* Generate Client master secret for Certivox and Customer */
  rtn = MPIN_RANDOM_GENERATE(&RNG,&MS1); 
  if (rtn != 0)
    {
      printf("MPIN_RANDOM_GENERATE(&RNG,&MS1) Error %d\n", rtn);
      return 1;
    }
  rtn = MPIN_RANDOM_GENERATE(&RNG,&MS2); 
  if (rtn != 0)
    {
      printf("MPIN_RANDOM_GENERATE(&RNG,&MS2) Error %d\n", rtn);
      return 1;
    }
  printf("MASTER SECRET CERTIVOX:= 0x"); 
  OCT_output(&MS1);
  printf("MASTER SECRET CUSTOMER:= 0x"); 
  OCT_output(&MS2);

  /* Generate server secret shares */
  rtn = MPIN_GET_SERVER_SECRET(&MS1,&SS1);
  if (rtn != 0)
    {
      printf("MPIN_GET_SERVER_SECRET(&MS1,&SS1) Error %d\n", rtn);
      return 1;
    }
  rtn = MPIN_GET_SERVER_SECRET(&MS2,&SS2);
  if (rtn != 0)
    {
      printf("MPIN_GET_SERVER_SECRET(&MS2,&SS2) Error %d\n", rtn);
      return 1;
    }
  printf("SS1 = 0x"); 
  OCT_output(&SS1);
  printf("SS2 = 0x"); 
  OCT_output(&SS2);

  /* Combine server secret share */
  rtn = MPIN_RECOMBINE_G2(&SS1, &SS2, &ServerSecret);
  if (rtn != 0)
    {
      printf("MPIN_RECOMBINE_G2(&SS1, &SS2, &ServerSecret) Error %d\n", rtn);
      return 1;
    }
  printf("ServerSecret = 0x"); 
  OCT_output(&ServerSecret);

  /* Generate client secret shares */
  rtn = MPIN_GET_CLIENT_SECRET(&MS1,&HCID,&CS1);
  if (rtn != 0)
    {
      printf("MPIN_GET_CLIENT_SECRET(&MS1,&HCID,&CS1) Error %d\n", rtn);
      return 1;
    }
  rtn = MPIN_GET_CLIENT_SECRET(&MS2,&HCID,&CS2);
  if (rtn != 0)
    {
      printf("MPIN_GET_CLIENT_SECRET(&MS2,&HCID,&CS2) Error %d\n", rtn);
      return 1;
    }
  printf("CS1 = 0x"); 
  OCT_output(&CS1);
  printf("CS2 = 0x"); 
  OCT_output(&CS2);

  /* Combine client secret shares : TOKEN is the full client secret */
  rtn = MPIN_RECOMBINE_G1(&CS1, &CS2, &TOKEN);
  if (rtn != 0)
    {
      printf("MPIN_RECOMBINE_G1(&CS1, &CS2, &TOKEN) Error %d\n", rtn);
      return 1;
    }
  printf("Client Secret = 0x"); 
  OCT_output(&TOKEN);

  /* Client extracts PIN1 from secret to create Token */
  rtn = MPIN_EXTRACT_PIN(&CLIENT_ID, PIN1, &TOKEN);
  if (rtn != 0)
    {
      printf("MPIN_EXTRACT_PIN( &CLIENT_ID, PIN, &TOKEN) Error %d\n", rtn);
      return 1;
    }
  printf("Token = 0x"); 
  OCT_output(&TOKEN);

  /* Generate Time Permit shares */
  date = today();
  for(iter=1; iter<nTimePermitTests+1; iter++)
    {
      printf("Date %d \n", date);
      rtn = MPIN_GET_CLIENT_PERMIT(date,&MS1,&HCID,&TP1);
      if (rtn != 0)
        {
          printf("MPIN_GET_CLIENT_PERMIT(date,&MS1,&HCID,&TP1) Error %d\n", rtn);
          return 1;
        }
      rtn = MPIN_GET_CLIENT_PERMIT(date,&MS2,&HCID,&TP2);
      if (rtn != 0)
        {
          printf("MPIN_GET_CLIENT_PERMIT(date,&MS2,&HCID,&TP2) Error %d\n", rtn);
          return 1;
        }
      printf("TP1 = 0x"); 
      OCT_output(&TP1);
      printf("TP2 = 0x"); 
      OCT_output(&TP2);
    
      /* Combine Time Permit shares */
      rtn = MPIN_RECOMBINE_G1(&TP1, &TP2, &TP);
      if (rtn != 0)
        {
          printf("MPIN_RECOMBINE_G1(&TP1, &TP2, &TP) Error %d\n", rtn);
          return 1;
        }
      printf("Time Permit = 0x"); 
      OCT_output(&TP);
    
      /* This encoding makes Time permit look random */
      if (MPIN_ENCODING(&RNG,&TP)!=0) printf("Encoding error\n");
      printf("Encoded Time Permit= "); OCT_output(&TP);
      if (MPIN_DECODING(&TP)!=0) printf("Decoding error\n");
      printf("Decoded Time Permit= "); OCT_output(&TP);
    
      /* Client first pass */
      rtn = MPIN_CLIENT_1(date,&CLIENT_ID,&RNG,&X,PIN2,&TOKEN,&SEC,&U,&UT,&TP);
      if (rtn != 0)
        {
          printf("MPIN_CLIENT_1 ERROR %d\n", rtn);
          return 1;
        }
    
      /* Server calculates H(ID) and H(T|H(ID)) (if time permits enabled), and maps them to points on the curve HID and HTID resp. */
      MPIN_SERVER_1(date,&CLIENT_ID,&HID,&HTID);
    
      /* Server generates Random number Y and sends it to Client */
      rtn = MPIN_RANDOM_GENERATE(&RNG,&Y); 
      if (rtn != 0)
        {
          printf("MPIN_RANDOM_GENERATE(&RNG,&Y) Error %d\n", rtn);
          return 1;
        }
      printf("Y = 0x"); 
      OCT_output(&Y);
    
      /* Client second pass */
      rtn = MPIN_CLIENT_2(&X,&Y,&SEC);
      if (rtn != 0)
        printf("MPIN_CLIENT_2(&X,&Y,&SEC) Error %d\n", rtn);
      printf("V = 0x"); 
      OCT_output(&SEC);
    
      /* Server second pass */
      rtn = MPIN_SERVER_2(date,&HID,&HTID,&Y,&ServerSecret,&U,&UT,&SEC,&E,&F);
      if (rtn != 0)
        {
          err=MPIN_KANGAROO(&E,&F);
          if (err==0)
            {
              printf("Iteration %d FAILURE Invalid Token Error Code %d\n", iter, rtn);
              break;
	    }
          else 
            {
              printf("Iteration %d FAILURE PIN Error %d, Error Code %d\n", iter, err, rtn);
              break;
	    }
        }
      else
        {
          printf("Iteration %d SUCCESS Error Code %d\n", iter, rtn); 
        } 
      date++;
    }
  return 0; 
}
コード例 #2
0
ファイル: test_mpin.c プロジェクト: gitter-badger/MiotCL
int main()
{
  int i,PIN1,PIN2,rtn,err;

  char client_id[256];
  octet CLIENT_ID = {0,sizeof(client_id),client_id};

  char x[PGS],y1[PGS],y2[PGS];
  octet X={sizeof(x), sizeof(x),x};
  octet Y1={sizeof(y1),sizeof(y1),y1};
  octet Y2={sizeof(y2),sizeof(y2),y2};

  /* Master secret shares */
  char ms1[PGS], ms2[PGS];
  octet MS1={sizeof(ms1),sizeof(ms1),ms1};
  octet MS2={sizeof(ms2),sizeof(ms2),ms2};

  /* Hash values of Client ID */
  char hcid[32];
  octet HCID={sizeof(hcid),sizeof(hcid), hcid};

  /* Client secret and shares */
  char cs1[2*PFS+1], cs2[2*PFS+1], sec[2*PFS+1];
  octet SEC={sizeof(sec),sizeof(sec),sec};
  octet CS1={sizeof(cs1),sizeof(cs1), cs1};
  octet CS2={sizeof(cs2),sizeof(cs2), cs2};

  /* Server secret and shares */
  char ss1[4*PFS], ss2[4*PFS], serverSecret[4*PFS];
  octet ServerSecret={sizeof(serverSecret),sizeof(serverSecret),serverSecret};
  octet SS1={sizeof(ss1),sizeof(ss1),ss1};
  octet SS2={sizeof(ss2),sizeof(ss2),ss2};

  /* Time Permit and shares */
  char tp1[2*PFS+1], tp2[2*PFS+1], tp[2*PFS+1];
  octet TP={sizeof(tp),sizeof(tp),tp};
  octet TP1={sizeof(tp1),sizeof(tp1),tp1};
  octet TP2={sizeof(tp2),sizeof(tp2),tp2};

  /* Token stored on computer */
  char token[2*PFS+1];
  octet TOKEN={sizeof(token),sizeof(token),token};

  char ut[2*PFS+1],u[2*PFS+1];
  octet UT={sizeof(ut),sizeof(ut),ut};
  octet U={sizeof(u),sizeof(u),u};

  char hid[2*PFS+1],htid[2*PFS+1];
  octet HID={0,sizeof(hid),hid};
  octet HTID={0,sizeof(htid),htid};

  char e[12*PFS], f[12*PFS];
  octet E={sizeof(e),sizeof(e),e};
  octet F={sizeof(f),sizeof(f),f};

  int TimeValue = 0;

  PIN1 = 1234;
  PIN2 = 1234;

  /* Assign the End-User an ID */
  char* user = "******";
  OCT_jstring(&CLIENT_ID,user);
  printf("CLIENT: ID %s\n", user);

  int date = 0;
  char seed[100] = {0};
  octet SEED = {0,sizeof(seed),seed};
  csprng RNG;               

  /* unrandom seed value! */
  SEED.len=100;
  for (i=0;i<100;i++) SEED.val[i]=i+1;

  /* initialise random number generator */ 
  CREATE_CSPRNG(&RNG,&SEED);   

  /* Hash CLIENT_ID */
  MPIN_HASH_ID(&CLIENT_ID,&HCID); 
  OCT_output(&HCID);

  /* Generate Client master secret for Certivox and Customer */
  rtn = MPIN_RANDOM_GENERATE(&RNG,&MS1); 
  if (rtn != 0)
    {
      printf("MPIN_RANDOM_GENERATE(&RNG,&MS1) Error %d\n", rtn);
      return 1;
    }
  rtn = MPIN_RANDOM_GENERATE(&RNG,&MS2); 
  if (rtn != 0)
    {
      printf("MPIN_RANDOM_GENERATE(&RNG,&MS2) Error %d\n", rtn);
      return 1;
    }
  printf("MASTER SECRET CERTIVOX:= 0x"); 
  OCT_output(&MS1);
  printf("MASTER SECRET CUSTOMER:= 0x"); 
  OCT_output(&MS2);

  /* Generate server secret shares */
  rtn = MPIN_GET_SERVER_SECRET(&MS1,&SS1);
  if (rtn != 0)
    {
      printf("MPIN_GET_SERVER_SECRET(&MS1,&SS1) Error %d\n", rtn);
      return 1;
    }
  rtn = MPIN_GET_SERVER_SECRET(&MS2,&SS2);
  if (rtn != 0)
    {
      printf("MPIN_GET_SERVER_SECRET(&MS2,&SS2) Error %d\n", rtn);
      return 1;
    }
  printf("SS1 = 0x"); 
  OCT_output(&SS1);
  printf("SS2 = 0x"); 
  OCT_output(&SS2);

  /* Combine server secret share */
  rtn = MPIN_RECOMBINE_G2(&SS1, &SS2, &ServerSecret);
  if (rtn != 0)
    {
      printf("MPIN_RECOMBINE_G2(&SS1, &SS2, &ServerSecret) Error %d\n", rtn);
      return 1;
    }
  printf("ServerSecret = 0x"); 
  OCT_output(&ServerSecret);

  /* Generate client secret shares */
  rtn = MPIN_GET_CLIENT_SECRET(&MS1,&HCID,&CS1);
  if (rtn != 0)
    {
      printf("MPIN_GET_CLIENT_SECRET(&MS1,&HCID,&CS1) Error %d\n", rtn);
      return 1;
    }
  rtn = MPIN_GET_CLIENT_SECRET(&MS2,&HCID,&CS2);
  if (rtn != 0)
    {
      printf("MPIN_GET_CLIENT_SECRET(&MS2,&HCID,&CS2) Error %d\n", rtn);
      return 1;
    }
  printf("CS1 = 0x"); 
  OCT_output(&CS1);
  printf("CS2 = 0x"); 
  OCT_output(&CS2);

  /* Combine client secret shares : TOKEN is the full client secret */
  rtn = MPIN_RECOMBINE_G1(&CS1, &CS2, &TOKEN);
  if (rtn != 0)
    {
      printf("MPIN_RECOMBINE_G1(&CS1, &CS2, &TOKEN) Error %d\n", rtn);
      return 1;
    }
  printf("Client Secret = 0x"); 
  OCT_output(&TOKEN);

  /* Generate Time Permit shares */
  date = today();
  printf("Date %d \n", date);
  rtn = MPIN_GET_CLIENT_PERMIT(date,&MS1,&HCID,&TP1);
  if (rtn != 0)
    {
      printf("MPIN_GET_CLIENT_PERMIT(date,&MS1,&HCID,&TP1) Error %d\n", rtn);
      return 1;
    }
  rtn = MPIN_GET_CLIENT_PERMIT(date,&MS2,&HCID,&TP2);
  if (rtn != 0)
    {
      printf("MPIN_GET_CLIENT_PERMIT(date,&MS2,&HCID,&TP2) Error %d\n", rtn);
      return 1;
    }
  printf("TP1 = 0x"); 
  OCT_output(&TP1);
  printf("TP2 = 0x"); 
  OCT_output(&TP2);

  /* Combine Time Permit shares */
  rtn = MPIN_RECOMBINE_G1(&TP1, &TP2, &TP);
  if (rtn != 0)
    {
      printf("MPIN_RECOMBINE_G1(&TP1, &TP2, &TP) Error %d\n", rtn);
      return 1;
    }
  printf("Time Permit = 0x"); 
  OCT_output(&TP);

  /* This encoding makes Time permit look random */
  if (MPIN_ENCODING(&RNG,&TP)!=0) printf("Encoding error\n");
  printf("Encoded Time Permit= "); OCT_output(&TP);
  if (MPIN_DECODING(&TP)!=0) printf("Decoding error\n");
  printf("Decoded Time Permit= "); OCT_output(&TP);

  /* Client extracts PIN1 from secret to create Token */
  rtn = MPIN_EXTRACT_PIN(&CLIENT_ID, PIN1, &TOKEN);
  if (rtn != 0)
    {
      printf("MPIN_EXTRACT_PIN( &CLIENT_ID, PIN, &TOKEN) Error %d\n", rtn);
      return 1;
    }
  printf("Token = 0x"); 
  OCT_output(&TOKEN);

  /* One pass MPIN protocol */
  /* Client  */
  TimeValue = MPIN_GET_TIME();
  printf("TimeValue %d \n", TimeValue);
  rtn = MPIN_CLIENT(date,&CLIENT_ID,&RNG,&X,PIN2,&TOKEN,&SEC,NULL,&UT,&TP,TimeValue,&Y1);
  if (rtn != 0)
    {
      printf("MPIN_CLIENT ERROR %d\n", rtn);
      return 1;
    }
  printf("Y1 = 0x"); 
  OCT_output(&Y1);
  printf("V = 0x"); 
  OCT_output(&SEC);

  /* Server  */
  rtn = MPIN_SERVER(date,NULL,&HTID,&Y2,&ServerSecret,NULL,&UT,&SEC,&E,&F,&CLIENT_ID,TimeValue);
  printf("Y2 = 0x"); 
  OCT_output(&Y2);
  if (rtn != 0)
    {
      printf("FAILURE Invalid Token Error Code %d\n", rtn);
    }
  else
    {
      printf("SUCCESS Error Code %d\n", rtn);
    } 
  return 0; 
}
コード例 #3
0
ファイル: TA_cs.c プロジェクト: apache/incubator-milagro-tls
int main(){
    
    int rtn, i, PIN;

    const char* user;
    
    /* Master secret shares */
    char ms1[PGS];
    octet MS1={sizeof(ms1),sizeof(ms1),ms1};
    
    /* Client Identity and its hash */
    char client_id[100], hash_id[HASH_BYTES];
    octet CLIENT_ID={0,sizeof(client_id),client_id};
    octet HASH_ID={0,sizeof(hash_id),hash_id};
    
    /* Server secret and shares */
    char serverSecret[4*PFS];
    octet ServerSecret={sizeof(serverSecret),sizeof(serverSecret),serverSecret};

#if defined(MBEDTLS_TLS_MILAGRO_CS_TIME_PERMITS)
    /* Time Permit and shares */
    char tp[2*PFS+1];
    octet TP={sizeof(tp),sizeof(tp),tp};
    int date = MPIN_today();
#endif
    
    /* Token stored on computer */
    char token[2*PFS+1];
    octet TOKEN={sizeof(token),sizeof(token),token};
    
    
    /* Random generator */
    char seed[32] = {0};
    octet SEED = {0,sizeof(seed),seed};
    csprng RNG;
    
    /* unrandom seed value! */
    SEED.len=32;
    for (i=0;i<32;i++) SEED.val[i]=i+1;
#ifdef DEBUG
    printf("SEED: ");
    OCT_output(&SEED);
    printf("\n");
#endif

    MPIN_CREATE_CSPRNG(&RNG,&SEED);
    
    /* Assign the End-User an ID */
    user = "******";
    OCT_jstring(&CLIENT_ID, (char*)user);
    
    /* Hash CLIENT_ID */
    MPIN_HASH_ID(&CLIENT_ID,&HASH_ID);
    
    /* master secret */
    rtn = MPIN_RANDOM_GENERATE(&RNG,&MS1);
    if (rtn != 0)
    {
        printf("MILAGRO_CS_RANDOM_GENERATE(&RNG,&MS1) Error %d\n", rtn);
        return 1;
    }

    /* server secret */
    rtn = MPIN_GET_SERVER_SECRET(&MS1,&ServerSecret);
    if (rtn != 0)
    {
        printf("MILAGRO_CS_GET_SERVER_SECRET(&MS1,&SS1) Error %d\n", rtn);
        return 1;
    }
    printf("Server Secret = 0x");
    OCT_output(&ServerSecret);
    
    /* client secret */
    rtn = MPIN_GET_CLIENT_SECRET(&MS1,&HASH_ID,&TOKEN);
    if (rtn != 0)
    {
        printf("MILAGRO_CS_GET_CLIENT_SECRET(&MS1,&HASH_ID,&CS1) Error %d\n", rtn);
        return 1;
    }
    printf("Client Secret = 0x");
    OCT_output(&TOKEN);

#if defined(MBEDTLS_TLS_MILAGRO_CS_TIME_PERMITS)
    /* Generate Time Permits */
    rtn = MPIN_GET_CLIENT_PERMIT(date,&MS1,&HASH_ID,&TP);
    if (rtn != 0)
    {
        printf("MILAGRO_CS_GET_CLIENT_PERMIT(date,&MS1,&HASH_ID,&TP1) Error %d\n", rtn);
        return 1;
    }
    printf("\nTime Permit = 0x");
    OCT_output(&TP);
#endif
#if defined(MBEDTLS_TLS_MILAGRO_CS_ENABLE_PIN)
    /* Client extracts PIN from secret to create Token */
    PIN = 1234;
#else
    PIN = 0;
#endif
    rtn = MPIN_EXTRACT_PIN(&HASH_ID, PIN, &TOKEN);
    if (rtn != 0)
    {
        printf("MILAGRO_CS_EXTRACT_PIN( &HASH_ID, PIN, &TOKEN) Error %d\n", rtn);
        return 1;
    }
    printf("\nToken = 0x");
    OCT_output(&TOKEN);
    
#if defined(MBEDTLS_TLS_MILAGRO_CS_TIME_PERMITS)
    write_to_file("CSTimePermit", TP);
#endif
    write_to_file("CSServerKey", ServerSecret);
    
    write_to_file("CSClientKey", TOKEN);
    
    return 0;
}
コード例 #4
0
int main()
{
  int i,PIN1,PIN2,rtn,err,iter;

  char x[PGS],y[PGS];
  octet X={sizeof(x), sizeof(x),x};
  octet Y={sizeof(y),sizeof(y),y};

  /* Master secret shares */
  char ms1[PGS], ms2[PGS];
  octet MS1={sizeof(ms1),sizeof(ms1),ms1};
  octet MS2={sizeof(ms2),sizeof(ms2),ms2};

  /* Hash values of CLIENT_ID */
  char hcid[32];
  octet HCID={sizeof(hcid),sizeof(hcid), hcid};

  /* Client secret and shares */
  char cs1[2*PFS+1], cs2[2*PFS+1], sec[2*PFS+1];
  octet SEC={sizeof(sec),sizeof(sec),sec};
  octet CS1={sizeof(cs1),sizeof(cs1), cs1};
  octet CS2={sizeof(cs2),sizeof(cs2), cs2};

  /* Server secret and shares */
  char ss1[4*PFS], ss2[4*PFS], serverSecret[4*PFS];
  octet ServerSecret={sizeof(serverSecret),sizeof(serverSecret),serverSecret};
  octet SS1={sizeof(ss1),sizeof(ss1),ss1};
  octet SS2={sizeof(ss2),sizeof(ss2),ss2};

  /* Time Permit and shares */
  char tp1[2*PFS+1], tp2[2*PFS+1], tp[2*PFS+1];
  octet TP={sizeof(tp),sizeof(tp),tp};
  octet TP1={sizeof(tp1),sizeof(tp1),tp1};
  octet TP2={sizeof(tp2),sizeof(tp2),tp2};

  /* Token stored on computer */
  char token[2*PFS+1];
  octet TOKEN={sizeof(token),sizeof(token),token};

  char ut[2*PFS+1],u[2*PFS+1];
  octet UT={sizeof(ut),sizeof(ut),ut};
  octet U={sizeof(u),sizeof(u),u};

  char hid[2*PFS+1],htid[2*PFS+1];
  octet HID={0,sizeof(hid),hid};
  octet HTID={0,sizeof(htid),htid};

  char e[12*PFS], f[12*PFS];
  octet E={sizeof(e),sizeof(e),e};
  octet F={sizeof(f),sizeof(f),f};

  int date = 0;

  unsigned long ran;
  int byte_count = 32;
  FILE *fp;
  char seed[32] = {0};
  octet SEED = {sizeof(seed),sizeof(seed),seed};
  csprng RNG;

#ifdef __linux__
  size_t readSize;
  fp = fopen("/dev/urandom", "r");
  readSize = fread(&seed, 1, byte_count, fp);
  fclose(fp);
#else
  /* non random seed value! */
  time((time_t *)&ran);
  SEED.val[0]=ran;
  SEED.val[1]=ran>>8;
  SEED.val[2]=ran>>16;
  SEED.val[3]=ran>>24;
  for (i=4;i<byte_count;i++) SEED.val[i]=i+1;
#endif
  printf("SEED 0x");
  OCT_output(&SEED);

  /* initialise random number generator */
  CREATE_CSPRNG(&RNG,&SEED);

  for(iter=1; iter<nRandomTests+1; iter++)
    {
      /* Generate Client master secret for MIRACL and Customer */
      rtn = MPIN_RANDOM_GENERATE(&RNG,&MS1);
      if (rtn != 0)
        {
          printf("MPIN_RANDOM_GENERATE(&RNG,&MS1) Error %d\n", rtn);
          return 1;
        }
      rtn = MPIN_RANDOM_GENERATE(&RNG,&MS2);
      if (rtn != 0)
        {
          printf("MPIN_RANDOM_GENERATE(&RNG,&MS2) Error %d\n", rtn);
          return 1;
        }
      printf("MASTER SECRET MIRACL:= 0x");
      OCT_output(&MS1);
      printf("MASTER SECRET CUSTOMER:= 0x");
      OCT_output(&MS2);

      /* Generate server secret shares */
      rtn = MPIN_GET_SERVER_SECRET(&MS1,&SS1);
      if (rtn != 0)
        {
          printf("MPIN_GET_SERVER_SECRET(&MS1,&SS1) Error %d\n", rtn);
          return 1;
        }
      rtn = MPIN_GET_SERVER_SECRET(&MS2,&SS2);
      if (rtn != 0)
        {
          printf("MPIN_GET_SERVER_SECRET(&MS2,&SS2) Error %d\n", rtn);
          return 1;
        }
      printf("SS1 = 0x");
      OCT_output(&SS1);
      printf("SS2 = 0x");
      OCT_output(&SS2);

      /* Combine server secret share */
      rtn = MPIN_RECOMBINE_G2(&SS1, &SS2, &ServerSecret);
      if (rtn != 0)
        {
          printf("MPIN_RECOMBINE_G2(&SS1, &SS2, &ServerSecret) Error %d\n", rtn);
          return 1;
        }
      printf("ServerSecret = 0x");
      OCT_output(&ServerSecret);

      /* Assign the End-User an ID */
      char client_id[256];
      octet CLIENT_ID = {0,sizeof(client_id),client_id};
      rand_str(client_id,256);
      OCT_jstring(&CLIENT_ID,client_id);
      printf("CLIENT: ID %s\n", client_id);

      /* Hash CLIENT_ID */
      MPIN_HASH_ID(&CLIENT_ID,&HCID);
      OCT_output(&HCID);

      srand ( time (NULL) );
      PIN1 = rand()%MAX_RANGE; // Get random between 0 and MAX_RANGE
      PIN2 = PIN1;
      printf("PIN1 %d PIN2 %d\n", PIN1, PIN2);

      /* Generate client secret shares */
      rtn = MPIN_GET_CLIENT_SECRET(&MS1,&HCID,&CS1);
      if (rtn != 0)
        {
          printf("MPIN_GET_CLIENT_SECRET(&MS1,&HCID,&CS1) Error %d\n", rtn);
          return 1;
        }
      rtn = MPIN_GET_CLIENT_SECRET(&MS2,&HCID,&CS2);
      if (rtn != 0)
        {
          printf("MPIN_GET_CLIENT_SECRET(&MS2,&HCID,&CS2) Error %d\n", rtn);
          return 1;
        }
      printf("CS1 = 0x");
      OCT_output(&CS1);
      printf("CS2 = 0x");
      OCT_output(&CS2);

      /* Combine client secret shares : TOKEN is the full client secret */
      rtn = MPIN_RECOMBINE_G1(&CS1, &CS2, &TOKEN);
      if (rtn != 0)
        {
          printf("MPIN_RECOMBINE_G1(&CS1, &CS2, &TOKEN) Error %d\n", rtn);
          return 1;
        }
      printf("Client Secret = 0x");
      OCT_output(&TOKEN);

      /* Client extracts PIN1 from secret to create Token */
      rtn = MPIN_EXTRACT_PIN(&CLIENT_ID, PIN1, &TOKEN);
      if (rtn != 0)
        {
          printf("MPIN_EXTRACT_PIN( &CLIENT_ID, PIN, &TOKEN) Error %d\n", rtn);
          return 1;
        }
      printf("Token = 0x");
      OCT_output(&TOKEN);

      /* Generate Time Permit shares */
      date = today();

      printf("Date %d \n", date);
      rtn = MPIN_GET_CLIENT_PERMIT(date,&MS1,&HCID,&TP1);
      if (rtn != 0)
        {
          printf("MPIN_GET_CLIENT_PERMIT(date,&MS1,&HCID,&TP1) Error %d\n", rtn);
          return 1;
        }
      rtn = MPIN_GET_CLIENT_PERMIT(date,&MS2,&HCID,&TP2);
      if (rtn != 0)
        {
          printf("MPIN_GET_CLIENT_PERMIT(date,&MS2,&HCID,&TP2) Error %d\n", rtn);
          return 1;
        }
      printf("TP1 = 0x");
      OCT_output(&TP1);
      printf("TP2 = 0x");
      OCT_output(&TP2);

      /* Combine Time Permit shares */
      rtn = MPIN_RECOMBINE_G1(&TP1, &TP2, &TP);
      if (rtn != 0)
        {
          printf("MPIN_RECOMBINE_G1(&TP1, &TP2, &TP) Error %d\n", rtn);
          return 1;
        }
      printf("Time Permit = 0x");
      OCT_output(&TP);

      /* This encoding makes Time permit look random */
      if (MPIN_ENCODING(&RNG,&TP)!=0) printf("Encoding error\n");
      printf("Encoded Time Permit= "); OCT_output(&TP);
      if (MPIN_DECODING(&TP)!=0) printf("Decoding error\n");
      printf("Decoded Time Permit= "); OCT_output(&TP);


      /* Client first pass */
      rtn = MPIN_CLIENT_1(date,&CLIENT_ID,&RNG,&X,PIN2,&TOKEN,&SEC,&U,&UT,&TP);
      if (rtn != 0)
        {
          printf("MPIN_CLIENT_1 ERROR %d\n", rtn);
          return 1;
        }

      /* Server calculates H(ID) and H(T|H(ID)) (if time permits enabled), and maps them to points on the curve HID and HTID resp. */
      MPIN_SERVER_1(date,&CLIENT_ID,&HID,&HTID);

      /* Server generates Random number Y and sends it to Client */
      rtn = MPIN_RANDOM_GENERATE(&RNG,&Y);
      if (rtn != 0)
        {
          printf("MPIN_RANDOM_GENERATE(&RNG,&Y) Error %d\n", rtn);
          return 1;
        }
      printf("Y = 0x");
      OCT_output(&Y);

      /* Client second pass */
      rtn = MPIN_CLIENT_2(&X,&Y,&SEC);
      if (rtn != 0)
        printf("MPIN_CLIENT_2(&X,&Y,&SEC) Error %d\n", rtn);
      printf("V = 0x");
      OCT_output(&SEC);

      /* Server second pass */
      rtn = MPIN_SERVER_2(date,&HID,&HTID,&Y,&ServerSecret,&U,&UT,&SEC,&E,&F);
      if (rtn != 0)
        {
          err=MPIN_KANGAROO(&E,&F);
          if (err==0)
            {
              printf("Iteration %d FAILURE Invalid Token Error Code %d\n", iter, rtn);
              return 1;
	    }
          else
            {
              printf("Iteration %d FAILURE PIN Error %d, Error Code %d\n", iter, err, rtn);
              return 1;
	    }
        }
      else
        {
          printf("Iteration %d SUCCESS Error Code %d\n\n", iter, rtn);
        }
    }
  return 0;
}