Example #1
0
int main()
{   
  int i,bytes,res;
  unsigned long ran;
  char m[RFS],ml[RFS],c[RFS],e[RFS],raw[100];
  rsa_public_key pub;
  rsa_private_key priv;
  csprng RNG;  
  octet M={0,sizeof(m),m};
  octet ML={0,sizeof(ml),ml};
  octet C={0,sizeof(c),c};
  octet E={0,sizeof(e),e};
  octet RAW={0,sizeof(raw),raw};

  time((time_t *)&ran);

  RAW.len=100;				/* fake random seed source */
  RAW.val[0]=ran;
  RAW.val[1]=ran>>8;
  RAW.val[2]=ran>>16;
  RAW.val[3]=ran>>24;
  for (i=4;i<100;i++) RAW.val[i]=i;

  CREATE_CSPRNG(&RNG,&RAW);   /* initialise strong RNG */

  printf("Generating public/private key pair\n");
  RSA_KEY_PAIR(&RNG,65537,&priv,&pub);

  printf("Encrypting test string\n");
  OCT_jstring(&M,(char *)"Hello World\n");
  OAEP_ENCODE(&M,&RNG,NULL,&E); /* OAEP encode message m to e  */

  RSA_ENCRYPT(&pub,&E,&C);     /* encrypt encoded message */
  printf("Ciphertext= "); OCT_output(&C); 

  printf("Decrypting test string\n");
  RSA_DECRYPT(&priv,&C,&ML);   /* ... and then decrypt it */

  OAEP_DECODE(NULL,&ML);    /* decode it */
  OCT_output_string(&ML);

  if (!OCT_comp(&M,&ML))
    {
      printf("FAILURE RSA Encryption failed");
      return 1;
    }
 
  OCT_clear(&M); OCT_clear(&ML);   /* clean up afterwards */
  OCT_clear(&C); OCT_clear(&RAW); OCT_clear(&E); 

  KILL_CSPRNG(&RNG);

  RSA_PRIVATE_KEY_KILL(&priv);

  printf("SUCCESS\n");
  return 0;
}
Example #2
0
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; 
}
Example #3
0
int main()
{
    int res,len,sha;
    int c,ic;
    rsa_public_key_2048 PK;
    pktype st,ca,pt;

    printf("First check signature on self-signed cert and extract CA public key\n");
    OCT_frombase64(&IO,ca_b64);
    printf("CA Self-Signed Cert= \n");
    OCT_output(&IO);
    printf("\n");

    st=X509_extract_cert_sig(&IO,&SIG); // returns signature type

    if (st.type==0)
    {
        printf("Unable to extract cert signature\n");
        return 0;
    }

    if (st.type==ECC)
    {
        OCT_chop(&SIG,&S,SIG.len/2);
        OCT_copy(&R,&SIG);
        printf("ECC SIG= \n");
        OCT_output(&R);
        OCT_output(&S);
        printf("\n");
    }

    if (st.type==RSA)
    {
        printf("RSA SIG= \n");
        OCT_output(&SIG);
        printf("\n");
    }

    if (st.hash==H256) printf("Hashed with SHA256\n");
    if (st.hash==H384) printf("Hashed with SHA384\n");
    if (st.hash==H512) printf("Hashed with SHA512\n");

// Extract Cert from signed Cert

    c=X509_extract_cert(&IO,&H);

    printf("\nCert= \n");
    OCT_output(&H);
    printf("\n");

// show some details
    printf("Issuer Details\n");
    ic=X509_find_issuer(&H);
    c=X509_find_entity_property(&H,&ON,ic,&len);
    print_out("owner=",&H,c,len);
    c=X509_find_entity_property(&H,&CN,ic,&len);
    print_out("country=",&H,c,len);
    c=X509_find_entity_property(&H,&EN,ic,&len);
    print_out("email=",&H,c,len);
    printf("\n");

    ca=X509_extract_public_key(&H,&CAKEY);

    if (ca.type==0)
    {
        printf("Not supported by library\n");
        return 0;
    }
    if (ca.type!=st.type)
    {
        printf("Not self-signed\n");
    }

    if (ca.type==ECC)
    {
        printf("EXTRACTED ECC PUBLIC KEY= \n");
        OCT_output(&CAKEY);
    }
    if (ca.type==RSA)
    {
        printf("EXTRACTED RSA PUBLIC KEY= \n");
        OCT_output(&CAKEY);
    }
    printf("\n");

// Cert is self-signed - so check signature

    printf("Checking Self-Signed Signature\n");
    if (ca.type==ECC)
    {
        if (ca.curve!=CHOICE)
        {
            printf("Curve is not supported\n");
            return 0;
        }
        res=ECP_NIST256_PUBLIC_KEY_VALIDATE(1,&CAKEY);
        if (res!=0)
        {
            printf("ECP Public Key is invalid!\n");
            return 0;
        }
        else printf("ECP Public Key is Valid\n");

        sha=0;

        if (st.hash==H256) sha=SHA256;
        if (st.hash==H384) sha=SHA384;
        if (st.hash==H512) sha=SHA512;
        if (st.hash==0)
        {
            printf("Hash Function not supported\n");
            return 0;
        }

        if (ECP_NIST256_VP_DSA(sha,&CAKEY,&H,&R,&S)!=0)
        {
            printf("***ECDSA Verification Failed\n");
            return 0;
        }
        else
            printf("ECDSA Signature/Verification succeeded \n");
    }

    if (ca.type==RSA)
    {
        if (ca.curve!=2048)
        {
            printf("RSA bit size is not supported\n");
            return 0;
        }
        PK.e=65537; // assuming this!
        RSA_2048_fromOctet(PK.n,&CAKEY);

        sha=0;

        if (st.hash==H256) sha=SHA256;
        if (st.hash==H384) sha=SHA384;
        if (st.hash==H512) sha=SHA512;
        if (st.hash==0)
        {
            printf("Hash Function not supported\n");
            return 0;
        }
        PKCS15(sha,&H,&HP);

        RSA_2048_ENCRYPT(&PK,&SIG,&HH);

        if (OCT_comp(&HP,&HH))
            printf("RSA Signature/Verification succeeded \n");
        else
        {
            printf("***RSA Verification Failed\n");
            return 0;
        }
    }

    printf("\nNext check CA signature on cert, and extract public key\n");

    OCT_frombase64(&IO,cert_b64);
    printf("Example Cert= \n");
    OCT_output(&IO);
    printf("\n");

    st=X509_extract_cert_sig(&IO,&SIG);

    if (st.type==0)
    {
        printf("Unable to check cert signature\n");
        return 0;
    }

    if (st.type==ECC)
    {
        OCT_chop(&SIG,&S,SIG.len/2);
        OCT_copy(&R,&SIG);
        printf("SIG= \n");
        OCT_output(&R);

        OCT_output(&S);

        printf("\n");
    }

    if (st.type==RSA)
    {
        printf("SIG= \n");
        OCT_output(&SIG);
        printf("\n");
    }

    c=X509_extract_cert(&IO,&H);

    printf("Cert= \n");
    OCT_output(&H);
    printf("\n");

    printf("Subject Details\n");
    ic=X509_find_subject(&H);
    c=X509_find_entity_property(&H,&ON,ic,&len);
    print_out("owner=",&H,c,len);
    c=X509_find_entity_property(&H,&CN,ic,&len);
    print_out("country=",&H,c,len);
    c=X509_find_entity_property(&H,&EN,ic,&len);
    print_out("email=",&H,c,len);
    printf("\n");

    ic=X509_find_validity(&H);
    c=X509_find_start_date(&H,ic);
    print_date("start date= ",&H,c);
    c=X509_find_expiry_date(&H,ic);
    print_date("expiry date=",&H,c);
    printf("\n");

    pt=X509_extract_public_key(&H,&CERTKEY);

    if (pt.type==0)
    {
        printf("Not supported by library\n");
        return 0;
    }

    if (pt.type==ECC)
    {
        printf("EXTRACTED ECC PUBLIC KEY= \n");
        OCT_output(&CERTKEY);
    }
    if (pt.type==RSA)
    {
        printf("EXTRACTED RSA PUBLIC KEY= \n");
        OCT_output(&CERTKEY);
    }

    printf("\n");

    /* Check CA signature */

    if (ca.type==ECC)
    {
        printf("Checking CA's ECC Signature on Cert\n");
        res=ECP_NIST256_PUBLIC_KEY_VALIDATE(1,&CAKEY);
        if (res!=0)
            printf("ECP Public Key is invalid!\n");
        else printf("ECP Public Key is Valid\n");

        sha=0;

        if (st.hash==H256) sha=SHA256;
        if (st.hash==H384) sha=SHA384;
        if (st.hash==H512) sha=SHA512;
        if (st.hash==0)
        {
            printf("Hash Function not supported\n");
            return 0;
        }

        if (ECP_NIST256_VP_DSA(sha,&CAKEY,&H,&R,&S)!=0)
            printf("***ECDSA Verification Failed\n");
        else
            printf("ECDSA Signature/Verification succeeded \n");
    }

    if (ca.type==RSA)
    {
        printf("Checking CA's RSA Signature on Cert\n");
        PK.e=65537; // assuming this!
        RSA_2048_fromOctet(PK.n,&CAKEY);

        sha=0;

        if (st.hash==H256) sha=SHA256;
        if (st.hash==H384) sha=SHA384;
        if (st.hash==H512) sha=SHA512;
        if (st.hash==0)
        {
            printf("Hash Function not supported\n");
            return 0;
        }
        PKCS15(sha,&H,&HP);

        RSA_2048_ENCRYPT(&PK,&SIG,&HH);

        if (OCT_comp(&HP,&HH))
            printf("RSA Signature/Verification succeeded \n");
        else
            printf("***RSA Verification Failed\n");

    }

    return 0;
}
Example #4
0
int main()
{   
  int i,j=0,res;
  int result;
  unsigned long ran;
  char *pp="M0ng00se";
  /* These octets are automatically protected against buffer overflow attacks */
  /* Note salt must be big enough to include an appended word */
  /* Note ECIES ciphertext C must be big enough to include at least 1 appended block */
  /* Recall EFS is field size in bytes. So EFS=32 for 256-bit curve */
  char s0[EGS],s1[EGS],w0[2*EFS+1],w1[2*EFS+1],z0[EFS],z1[EFS],raw[100],key[EAS],salt[32],pw[20],p1[30],p2[30],v[2*EFS+1],m[32],c[64],t[32],cs[EGS],ds[EGS];
  octet S0={0,sizeof(s0),s0};
  octet S1={0,sizeof(s1),s1};
  octet W0={0,sizeof(w0),w0};
  octet W1={0,sizeof(w1),w1};
  octet Z0={0,sizeof(z0),z0};
  octet Z1={0,sizeof(z1),z1};
  octet RAW={0,sizeof(raw),raw};
  octet KEY={0,sizeof(key),key};
  octet SALT={0,sizeof(salt),salt};
  octet PW={0,sizeof(pw),pw};
  octet P1={0,sizeof(p1),p1};
  octet P2={0,sizeof(p2),p2};
  octet V={0,sizeof(v),v};
  octet M={0,sizeof(m),m};
  octet C={0,sizeof(c),c};
  octet T={0,sizeof(t),t};
  octet CS={0,sizeof(cs),cs};
  octet DS={0,sizeof(ds),ds};

  /* Crypto Strong RNG */
  csprng RNG;                  				  
  time((time_t *)&ran);
  /* fake random seed source */
  RAW.len=100;		
  RAW.val[0]=ran;
  RAW.val[1]=ran>>8;
  RAW.val[2]=ran>>16;
  RAW.val[3]=ran>>24;
  for (i=0;i<100;i++) RAW.val[i]=i;
  /* initialise strong RNG */
  CREATE_CSPRNG(&RNG,&RAW);   

  SALT.len=8;
  for (i=0;i<8;i++) SALT.val[i]=i+1;  // set Salt

  printf("Alice's Passphrase= %s\n",pp);

  OCT_empty(&PW);
  OCT_jstring(&PW,pp);   // set Password from string

  /* private key S0 of size EGS bytes derived from Password and Salt */
  PBKDF2(&PW,&SALT,1000,EGS,&S0);
  printf("Alices private key= 0x"); OCT_output(&S0);

  /* Generate Key pair S/W */
  ECP_KEY_PAIR_GENERATE(NULL,&S0,&W0); 

  res=ECP_PUBLIC_KEY_VALIDATE(1,&W0);
  if (res!=0)
  {
    printf("ECP Public Key is invalid!\n");
    return 1;
  }

  printf("Alice's public key= 0x");  OCT_output(&W0);

  /* Random private key for other party */
  ECP_KEY_PAIR_GENERATE(&RNG,&S1,&W1);
  res=ECP_PUBLIC_KEY_VALIDATE(1,&W1);
  if (res!=0)
  {
    printf("ECP Public Key is invalid!\n");
    return 1;
  }
  printf("Servers private key= 0x");  OCT_output(&S1);
  printf("Servers public key= 0x");   OCT_output(&W1);

  /* Calculate common key using DH - IEEE 1363 method */
  ECPSVDP_DH(&S0,&W1,&Z0);
  ECPSVDP_DH(&S1,&W0,&Z1);
  
  if (!OCT_comp(&Z0,&Z1))
  {
    printf("*** ECPSVDP-DH Failed\n");
    return 0;
  }

  KDF2(&Z0,NULL,EAS,&KEY);

  printf("Alice's DH Key=  0x"); OCT_output(&KEY);
  printf("Servers DH Key=  0x"); OCT_output(&KEY);

  printf("Testing ECIES\n");

  P1.len=3; P1.val[0]=0x0; P1.val[1]=0x1; P1.val[2]=0x2; 
  P2.len=4; P2.val[0]=0x0; P2.val[1]=0x1; P2.val[2]=0x2; P2.val[3]=0x3; 

  M.len=17;
  for (i=0;i<=16;i++) M.val[i]=i; 

  ECP_ECIES_ENCRYPT(&P1,&P2,&RNG,&W1,&M,12,&V,&C,&T);

  printf("Ciphertext= \n"); 
  printf("V= 0x"); OCT_output(&V);
  printf("C= 0x"); OCT_output(&C);
  printf("T= 0x"); OCT_output(&T);

  if (!ECP_ECIES_DECRYPT(&P1,&P2,&V,&C,&T,&S1,&M))
  {
    printf("*** ECIES Decryption Failed\n");
    return 1;
  }
  else printf("Decryption succeeded\n");

  printf("Message is 0x"); OCT_output(&M);

  printf("Testing ECDSA\n");

  if (ECPSP_DSA(&RNG,&S0,&M,&CS,&DS)!=0)
  {
    printf("***ECDSA Signature Failed\n");
    return 1;
  }

  printf("Signature C = 0x"); OCT_output(&CS);
  printf("Signature D = 0x"); OCT_output(&DS);

  if (ECPVP_DSA(&W0,&M,&CS,&DS)!=0)
  {
    printf("***ECDSA Verification Failed\n");
    return 1;
  }
  else printf("ECDSA Signature/Verification succeeded %d\n",j);

  KILL_CSPRNG(&RNG);

  printf("SUCCESS\n");
  return 0;
}
Example #5
0
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;
}
Example #6
0
int test_ecdsa_keypair(int argc, char** argv)
{
    if (argc != 2)
    {
        printf("usage: ./test_ecdsa_sign [path to test vector file]\n");
        exit(EXIT_FAILURE);
    }
    int rc;
    FILE * fp = NULL;
    char line[LINE_LEN];
    char * linePtr = NULL;
    int l1=0;
    int l2=0;
    char * d = NULL;
    const char* dStr = "d = ";
    octet dOct;
    char Qx[EGS];
    const char* QxStr = "Qx = ";
    octet QxOct = {EGS,EGS,Qx};
    char Qy[EGS];
    const char* QyStr = "Qy = ";
    octet QyOct = {EGS,EGS,Qy};

    char q2[2*EFS+1];
    octet Q2Oct= {0,sizeof(q2),q2};

    fp = fopen(argv[1], "r");
    if (fp == NULL)
    {
        printf("ERROR opening test vector file\n");
        exit(EXIT_FAILURE);
    }

    bool readLine = false;
    int i=0;
    while (fgets(line, LINE_LEN, fp) != NULL)
    {
        i++;
        readLine = true;
        if (!strncmp(line, dStr, strlen(dStr)))
        {
#ifdef DEBUG
            printf("line %d %s\n", i,line);
#endif
            // Find hex value in string
            linePtr = line + strlen(dStr);

            // Allocate memory
            l1 = strlen(linePtr)-1;
            l2 = l1/2;
            d = (char*) malloc (l2);
            if (d==NULL)
                exit(EXIT_FAILURE);

            // d binary value
            amcl_hex2bin(linePtr, d, l1);

            dOct.len=l2;
            dOct.max=l2;
            dOct.val=d;
        }

        if (!strncmp(line, QxStr, strlen(QxStr)))
        {
#ifdef DEBUG
            printf("line %d %s\n", i,line);
#endif
            // Find hex value in string
            linePtr = line + strlen(QxStr);

            // Allocate data
            l1 = strlen(linePtr)-1;

            // Qx binary value
            amcl_hex2bin(linePtr, Qx, l1);
        }

        if (!strncmp(line, QyStr, strlen(QyStr)))
        {
#ifdef DEBUG
            printf("line %d %s\n", i,line);
#endif
            // Find hex value in string
            linePtr = line + strlen(QyStr);

            // Allocate data
            l1 = strlen(linePtr)-1;

            // Qy binary value
            amcl_hex2bin(linePtr, Qy, l1);

            // Assign Public Key
            BIG qx, qy;
            char q[2*EFS+1];
            BIG_fromBytes(qx,QxOct.val);
            BIG_fromBytes(qy,QyOct.val);
            octet QOct= {sizeof(q),sizeof(q),q};
            QOct.val[0]=4;
            BIG_toBytes(&(QOct.val[1]),qx);
            BIG_toBytes(&(QOct.val[EFS+1]),qy);

            // Generate Key pair
            ECP_KEY_PAIR_GENERATE(NULL,&dOct,&Q2Oct);

#ifdef DEBUG
            printf("QOct: ");
            OCT_output(&QOct);
            printf("\r\n");
            printf("Q2Oct: ");
            OCT_output(&Q2Oct);
            printf("\r\n");
#endif
            rc = OCT_comp(&QOct,&Q2Oct);
            if (!rc)
            {
                printf("TEST ECDSA KEYPAIR FAILED LINE %d\n",i);
                exit(EXIT_FAILURE);
            }
            free(d);
            d = NULL;
        }
    }
    fclose(fp);
    if (!readLine)
    {
        printf("ERROR Empty test vector file\n");
        exit(EXIT_FAILURE);
    }
    printf("SUCCESS TEST ECDSA KEYPAIR PASSED\n");
    exit(EXIT_SUCCESS);
}
Example #7
0
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; 
}
Example #8
0
int main()
{
    char* KT="feffe9928665731c6d6a8f9467308308";
    char* MT="d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39";
    char* HT="feedfacedeadbeeffeedfacedeadbeefabaddad2";
    char* NT="9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b";
    // Tag should be 619cc5aefffe0bfa462af43c1699d050

    int lenM=strlen(MT)/2;
    int lenH=strlen(HT)/2;
    int lenK=strlen(KT)/2;
    int lenIV=strlen(NT)/2;

    char t1[16];  // Tag
    char t2[16];  // Tag
    char k[16];   // AES Key
    char h[64];   // Header - to be included in Authentication, but not encrypted
    char iv[100]; // IV - Initialisation vector
    char m[100];  // Plaintext to be encrypted/authenticated
    char c[100];  // Ciphertext
    char p[100];  // Recovered Plaintext
    octet T1= {sizeof(t1),sizeof(t1),t1};
    octet T2= {sizeof(t2),sizeof(t2),t2};
    octet K= {0,sizeof(k),k};
    octet H= {0,sizeof(h),h};
    octet IV= {0,sizeof(iv),iv};
    octet M= {0,sizeof(m),m};
    octet C= {0,sizeof(c),c};
    octet P= {0,sizeof(p),p};
    M.len=lenM;
    K.len=lenK;
    H.len=lenH;
    IV.len=lenIV;

    hex2bytes(MT, m);
    hex2bytes(HT, h);
    hex2bytes(NT, iv);
    hex2bytes(KT, k);

    printf("Plaintext: ");
    OCT_output(&M);
    printf("\n");

    AES_GCM_ENCRYPT(&K, &IV, &H, &M, &C, &T1);

    printf("Ciphertext: ");
    OCT_output(&C);
    printf("\n");

    printf("Encryption Tag: ");
    OCT_output(&T1);
    printf("\n");

    AES_GCM_DECRYPT(&K, &IV, &H, &C, &P, &T2);

    printf("Plaintext: ");
    OCT_output(&P);
    printf("\n");

    printf("Decryption Tag: ");
    OCT_output(&T2);
    printf("\n");

    if (!OCT_comp(&M,&P))
    {
        printf("FAILURE Decryption\n");
        return 1;
    }

    if (!OCT_comp(&T1,&T2))
    {
        printf("FAILURE TAG mismatch\n");
        return 1;
    }

    printf("SUCCESS\n");
    return 0;
}
Example #9
0
int main()
{
  int i,j=0,res;
  int result;
  unsigned long ran;
  char *pp="M0ng00se";
  /* These octets are automatically protected against buffer overflow attacks */
  /* Note salt must be big enough to include an appended word */
  /* Note ECIES ciphertext C must be big enough to include at least 1 appended block */
  /* Recall EFS is field size in bytes. So EFS=32 for 256-bit curve */
  char s0[EGS],s1[EGS],w0[2*EFS+1],w1[2*EFS+1],z0[EFS],z1[EFS],raw[100],key[EAS],salt[32],pw[20];
  octet S0={0,sizeof(s0),s0};
  octet S1={0,sizeof(s1),s1};
  octet W0={0,sizeof(w0),w0};
  octet W1={0,sizeof(w1),w1};
  octet Z0={0,sizeof(z0),z0};
  octet Z1={0,sizeof(z1),z1};
  octet RAW={0,sizeof(raw),raw};
  octet KEY={0,sizeof(key),key};
  octet SALT={0,sizeof(salt),salt};
  octet PW={0,sizeof(pw),pw};

  /* Crypto Strong RNG */
  csprng RNG;
  time((time_t *)&ran);
  /* fake random seed source */
  RAW.len=100;
  RAW.val[0]=ran;
  RAW.val[1]=ran>>8;
  RAW.val[2]=ran>>16;
  RAW.val[3]=ran>>24;
  for (i=4;i<100;i++) RAW.val[i]=i;

  CREATE_CSPRNG(&RNG,&RAW);   /* initialise strong RNG */

  SALT.len=8;
  for (i=0;i<8;i++) SALT.val[i]=i+1;  // set Salt

  printf("Alice's Passphrase= %s\n",pp);

  OCT_clear(&PW);
  OCT_jstring(&PW,pp);   // set Password from string

  /* private key S0 of size EGS bytes derived from Password and Salt */
  PBKDF2(&PW,&SALT,1000,EGS,&S0);
  printf("Alices private key= 0x"); OCT_output(&S0);

  /* Generate Key pair S/W */
  ECP_KEY_PAIR_GENERATE(NULL,&S0,&W0);

  res=ECP_PUBLIC_KEY_VALIDATE(1,&W0);
  if (res!=0)
  {
    printf("Alice's ECP Public Key is invalid!\n");
    return 1;
  }

  printf("Alice's public key= 0x");  OCT_output(&W0);

  /* Random private key for other party */
  ECP_KEY_PAIR_GENERATE(&RNG,&S1,&W1);
  printf("Servers private key= 0x");  OCT_output(&S1);
  printf("Servers public key= 0x");   OCT_output(&W1);

  res=ECP_PUBLIC_KEY_VALIDATE(1,&W1);
  if (res!=0)
  {
    printf("Server's ECP Public Key is invalid!\n");
    return 1;
  }

  /* Calculate common key using DH - IEEE 1363 method */

  ECPSVDP_DH(&S0,&W1,&Z0);
  ECPSVDP_DH(&S1,&W0,&Z1);

  if (!OCT_comp(&Z0,&Z1))
  {
    printf("*** ECPSVDP-DH Failed\n");
    return 1;
  }

  KDF2(&Z0,NULL,EAS,&KEY);

  printf("Alice's DH Key=  0x"); OCT_output(&KEY);
  printf("Servers DH Key=  0x"); OCT_output(&KEY);

  printf("SUCCESS\n");
  return 0;
}
Example #10
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;
}