http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version3/c/rsa_support.c ---------------------------------------------------------------------- diff --git a/version3/c/rsa_support.c b/version3/c/rsa_support.c new file mode 100644 index 0000000..a4cfdca --- /dev/null +++ b/version3/c/rsa_support.c @@ -0,0 +1,237 @@ +#include "rsa_support.h" + +#define ROUNDUP(a,b) ((a)-1)/(b)+1 + +/* general purpose hash function w=hash(p|n|x|y) */ +int hashit(int sha,octet *p,int n,octet *w) +{ + int i,c[4],hlen; + hash256 sha256; + hash512 sha512; + char hh[64]; + + switch (sha) + { + case SHA256: + HASH256_init(&sha256); + break; + case SHA384: + HASH384_init(&sha512); + break; + case SHA512: + HASH512_init(&sha512); + break; + } + + hlen=sha; + + if (p!=NULL) for (i=0; i<p->len; i++) + { + switch(sha) + { + case SHA256: + HASH256_process(&sha256,p->val[i]); + break; + case SHA384: + HASH384_process(&sha512,p->val[i]); + break; + case SHA512: + HASH512_process(&sha512,p->val[i]); + break; + } + } + if (n>=0) + { + c[0]=(n>>24)&0xff; + c[1]=(n>>16)&0xff; + c[2]=(n>>8)&0xff; + c[3]=(n)&0xff; + for (i=0; i<4; i++) + { + switch(sha) + { + case SHA256: + HASH256_process(&sha256,c[i]); + break; + case SHA384: + HASH384_process(&sha512,c[i]); + break; + case SHA512: + HASH512_process(&sha512,c[i]); + break; + } + } + } + + switch (sha) + { + case SHA256: + HASH256_hash(&sha256,hh); + break; + case SHA384: + HASH384_hash(&sha512,hh); + break; + case SHA512: + HASH512_hash(&sha512,hh); + break; + } + + OCT_empty(w); + OCT_jbytes(w,hh,hlen); + for (i=0; i<hlen; i++) hh[i]=0; + + return hlen; +} + +/* Mask Generation Function */ + +static void MGF1(int sha,octet *z,int olen,octet *mask) +{ + char h[64]; + octet H= {0,sizeof(h),h}; + int hlen=sha; + int counter,cthreshold; + + OCT_empty(mask); + + cthreshold=ROUNDUP(olen,hlen); + for (counter=0; counter<cthreshold; counter++) + { + hashit(sha,z,counter,&H); + if (mask->len+hlen>olen) OCT_jbytes(mask,H.val,olen%hlen); + else OCT_joctet(mask,&H); + } + OCT_clear(&H); +} + +/* SHAXXX identifier strings */ +const unsigned char SHA256ID[]= {0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20}; +const unsigned char SHA384ID[]= {0x30,0x41,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30}; +const unsigned char SHA512ID[]= {0x30,0x51,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0x04,0x40}; + +/* PKCS 1.5 padding of a message to be signed */ + +int PKCS15(int sha,octet *m,octet *w) +{ + int olen=w->max; + int hlen=sha; + int idlen=19; + char h[64]; + octet H= {0,sizeof(h),h}; + + if (olen<idlen+hlen+10) return 1; + hashit(sha,m,-1,&H); + + OCT_empty(w); + OCT_jbyte(w,0x00,1); + OCT_jbyte(w,0x01,1); + OCT_jbyte(w,0xff,olen-idlen-hlen-3); + OCT_jbyte(w,0x00,1); + + if (hlen==32) OCT_jbytes(w,(char *)SHA256ID,idlen); + if (hlen==48) OCT_jbytes(w,(char *)SHA384ID,idlen); + if (hlen==64) OCT_jbytes(w,(char *)SHA512ID,idlen); + + OCT_joctet(w,&H); + + return 0; +} + +/* OAEP Message Encoding for Encryption */ + +int OAEP_ENCODE(int sha,octet *m,csprng *RNG,octet *p,octet *f) +{ + int slen,olen=f->max-1; + int mlen=m->len; + int hlen,seedlen; + char dbmask[MAX_RSA_BYTES],seed[64]; + octet DBMASK= {0,sizeof(dbmask),dbmask}; + octet SEED= {0,sizeof(seed),seed}; + + hlen=seedlen=sha; + if (mlen>olen-hlen-seedlen-1) return 1; + if (m==f) return 1; /* must be distinct octets */ + + hashit(sha,p,-1,f); + + slen=olen-mlen-hlen-seedlen-1; + + OCT_jbyte(f,0,slen); + OCT_jbyte(f,0x1,1); + OCT_joctet(f,m); + + OCT_rand(&SEED,RNG,seedlen); + + MGF1(sha,&SEED,olen-seedlen,&DBMASK); + + OCT_xor(&DBMASK,f); + MGF1(sha,&DBMASK,seedlen,f); + + OCT_xor(f,&SEED); + + OCT_joctet(f,&DBMASK); + + OCT_pad(f,f->max); + OCT_clear(&SEED); + OCT_clear(&DBMASK); + + return 0; +} + +/* OAEP Message Decoding for Decryption */ + +int OAEP_DECODE(int sha,octet *p,octet *f) +{ + int comp,x,t; + int i,k,olen=f->max-1; + int hlen,seedlen; + char dbmask[MAX_RSA_BYTES],seed[64],chash[64]; + octet DBMASK= {0,sizeof(dbmask),dbmask}; + octet SEED= {0,sizeof(seed),seed}; + octet CHASH= {0,sizeof(chash),chash}; + + seedlen=hlen=sha; + if (olen<seedlen+hlen+1) return 1; + if (!OCT_pad(f,olen+1)) return 1; + hashit(sha,p,-1,&CHASH); + + x=f->val[0]; + for (i=seedlen; i<olen; i++) + DBMASK.val[i-seedlen]=f->val[i+1]; + DBMASK.len=olen-seedlen; + + MGF1(sha,&DBMASK,seedlen,&SEED); + for (i=0; i<seedlen; i++) SEED.val[i]^=f->val[i+1]; + MGF1(sha,&SEED,olen-seedlen,f); + OCT_xor(&DBMASK,f); + + comp=OCT_ncomp(&CHASH,&DBMASK,hlen); + + OCT_shl(&DBMASK,hlen); + + OCT_clear(&SEED); + OCT_clear(&CHASH); + + for (k=0;; k++) + { + if (k>=DBMASK.len) + { + OCT_clear(&DBMASK); + return 1; + } + if (DBMASK.val[k]!=0) break; + } + + t=DBMASK.val[k]; + if (!comp || x!=0 || t!=0x01) + { + OCT_clear(&DBMASK); + return 1; + } + + OCT_shl(&DBMASK,k+1); + OCT_copy(f,&DBMASK); + OCT_clear(&DBMASK); + + return 0; +}
http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version3/c/rsa_support.h ---------------------------------------------------------------------- diff --git a/version3/c/rsa_support.h b/version3/c/rsa_support.h new file mode 100644 index 0000000..3bd495f --- /dev/null +++ b/version3/c/rsa_support.h @@ -0,0 +1,62 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +/** + * @file rsa_support.h + * @author Mike Scott + * @brief RSA Support Header File + * + */ + +#ifndef RSA_SUPPORT_H +#define RSA_SUPPORT_H + +#include "amcl.h" + +#define MAX_RSA_BYTES 512 /**< Maximum of 4096 */ + +/** @brief PKCS V1.5 padding of a message prior to RSA signature + * + @param h is the hash type + @param M is the input message + @param W is the output encoding, ready for RSA signature + @return 1 if OK, else 0 + */ +extern int PKCS15(int h,octet *M,octet *W); +/** @brief OAEP padding of a message prior to RSA encryption + * + @param h is the hash type + @param M is the input message + @param R is a pointer to a cryptographically secure random number generator + @param P are input encoding parameter string (could be NULL) + @param F is the output encoding, ready for RSA encryption + @return 1 if OK, else 0 + */ +extern int OAEP_ENCODE(int h,octet *M,csprng *R,octet *P,octet *F); +/** @brief OAEP unpadding of a message after RSA decryption + * + Unpadding is done in-place + @param h is the hash type + @param P are input encoding parameter string (could be NULL) + @param F is input padded message, unpadded on output + @return 1 if OK, else 0 + */ +extern int OAEP_DECODE(int h,octet *P,octet *F); + +#endif http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version3/c/testall.c ---------------------------------------------------------------------- diff --git a/version3/c/testall.c b/version3/c/testall.c new file mode 100644 index 0000000..da8e034 --- /dev/null +++ b/version3/c/testall.c @@ -0,0 +1,1627 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include "ecdh_ED25519.h" +#include "mpin_BN254.h" +#include "rsa_2048.h" +#include "randapi.h" + +#if CHUNK==32 || CHUNK==64 +#include "ecdh_NIST256.h" +#include "ecdh_GOLDILOCKS.h" +#include "mpin_BLS383.h" +#include "mpin192_BLS24.h" +#include "mpin256_BLS48.h" +#endif + +int ecdh_ED25519(csprng *RNG) +{ + int i,res; + 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_ED25519 is field size in bytes. So EFS_ED25519=32 for 256-bit curve + char s0[2*EGS_ED25519],s1[EGS_ED25519],w0[2*EFS_ED25519+1],w1[2*EFS_ED25519+1],z0[EFS_ED25519],z1[EFS_ED25519],key[AESKEY_ED25519],salt[40],pw[40]; + 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 KEY= {0,sizeof(key),key}; + octet SALT= {0,sizeof(salt),salt}; + octet PW= {0,sizeof(pw),pw}; + + 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_ED25519 bytes derived from Password and Salt + + PBKDF2(HASH_TYPE_ED25519,&PW,&SALT,1000,EGS_ED25519,&S0); + + printf("Alices private key= 0x"); + OCT_output(&S0); + + // Generate Key pair S/W + + ECP_ED25519_KEY_PAIR_GENERATE(NULL,&S0,&W0); + printf("Alices public key= 0x"); + OCT_output(&W0); + + res=ECP_ED25519_PUBLIC_KEY_VALIDATE(&W0); + if (res!=0) + { + printf("ECP Public Key is invalid!\n"); + return 0; + } + + // Random private key for other party + ECP_ED25519_KEY_PAIR_GENERATE(RNG,&S1,&W1); + res=ECP_ED25519_PUBLIC_KEY_VALIDATE(&W1); + if (res!=0) + { + printf("ECP Public Key is invalid!\n"); + return 0; + } + printf("Servers private key= 0x"); + OCT_output(&S1); + printf("Servers public key= 0x"); + OCT_output(&W1); + + // Calculate common key using DH - IEEE 1363 method + + ECP_ED25519_SVDP_DH(&S0,&W1,&Z0); + ECP_ED25519_SVDP_DH(&S1,&W0,&Z1); + + if (!OCT_comp(&Z0,&Z1)) + { + printf("*** ECPSVDP-DH Failed\n"); + return 0; + } + + KDF2(HASH_TYPE_ED25519,&Z0,NULL,AESKEY_ED25519,&KEY); + + printf("Alice's DH Key= 0x"); + OCT_output(&KEY); + printf("Servers DH Key= 0x"); + OCT_output(&KEY); + +#if CURVETYPE_ED25519 != MONTGOMERY + + char ds[EGS_ED25519],p1[30],p2[30],v[2*EFS_ED25519+1],m[32],c[64],t[32],cs[EGS_ED25519]; + octet DS= {0,sizeof(ds),ds}; + octet CS= {0,sizeof(cs),cs}; + 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}; + + 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_ED25519_ECIES_ENCRYPT(HASH_TYPE_ED25519,&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_ED25519_ECIES_DECRYPT(HASH_TYPE_ED25519,&P1,&P2,&V,&C,&T,&S1,&M)) + { + printf("*** ECIES Decryption Failed\n"); + return 0; + } + else printf("Decryption succeeded\n"); + + printf("Message is 0x"); + OCT_output(&M); + + + printf("Testing ECDSA\n"); + + if (ECP_ED25519_SP_DSA(HASH_TYPE_ED25519,RNG,NULL,&S0,&M,&CS,&DS)!=0) + { + printf("***ECDSA Signature Failed\n"); + return 0; + } + + printf("Signature C = 0x"); + OCT_output(&CS); + printf("Signature D = 0x"); + OCT_output(&DS); + + if (ECP_ED25519_VP_DSA(HASH_TYPE_ED25519,&W0,&M,&CS,&DS)!=0) + { + printf("***ECDSA Verification Failed\n"); + return 0; + } + else + { + printf("ECDSA Signature/Verification succeeded\n"); + } + +#endif + + return 0; +} + +#if CHUNK==32 || CHUNK==64 +int ecdh_NIST256(csprng *RNG) +{ + int i,res; + 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_NIST256 is field size in bytes. So EFS_NIST256=32 for 256-bit curve + char s0[2*EGS_NIST256],s1[EGS_NIST256],w0[2*EFS_NIST256+1],w1[2*EFS_NIST256+1],z0[EFS_NIST256],z1[EFS_NIST256],key[AESKEY_NIST256],salt[40],pw[40]; + 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 KEY= {0,sizeof(key),key}; + octet SALT= {0,sizeof(salt),salt}; + octet PW= {0,sizeof(pw),pw}; + + 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_NIST256 bytes derived from Password and Salt + + PBKDF2(HASH_TYPE_NIST256,&PW,&SALT,1000,EGS_NIST256,&S0); + + printf("Alices private key= 0x"); + OCT_output(&S0); + + // Generate Key pair S/W + + ECP_NIST256_KEY_PAIR_GENERATE(NULL,&S0,&W0); + printf("Alices public key= 0x"); + OCT_output(&W0); + + res=ECP_NIST256_PUBLIC_KEY_VALIDATE(&W0); + if (res!=0) + { + printf("ECP Public Key is invalid!\n"); + return 0; + } + + // Random private key for other party + ECP_NIST256_KEY_PAIR_GENERATE(RNG,&S1,&W1); + res=ECP_NIST256_PUBLIC_KEY_VALIDATE(&W1); + if (res!=0) + { + printf("ECP Public Key is invalid!\n"); + return 0; + } + printf("Servers private key= 0x"); + OCT_output(&S1); + printf("Servers public key= 0x"); + OCT_output(&W1); + + // Calculate common key using DH - IEEE 1363 method + + ECP_NIST256_SVDP_DH(&S0,&W1,&Z0); + ECP_NIST256_SVDP_DH(&S1,&W0,&Z1); + + if (!OCT_comp(&Z0,&Z1)) + { + printf("*** ECPSVDP-DH Failed\n"); + return 0; + } + + KDF2(HASH_TYPE_NIST256,&Z0,NULL,AESKEY_NIST256,&KEY); + + printf("Alice's DH Key= 0x"); + OCT_output(&KEY); + printf("Servers DH Key= 0x"); + OCT_output(&KEY); + +#if CURVETYPE_NIST256 != MONTGOMERY + + char ds[EGS_NIST256],p1[30],p2[30],v[2*EFS_NIST256+1],m[32],c[64],t[32],cs[EGS_NIST256]; + octet DS= {0,sizeof(ds),ds}; + octet CS= {0,sizeof(cs),cs}; + 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}; + + 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_NIST256_ECIES_ENCRYPT(HASH_TYPE_NIST256,&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_NIST256_ECIES_DECRYPT(HASH_TYPE_NIST256,&P1,&P2,&V,&C,&T,&S1,&M)) + { + printf("*** ECIES Decryption Failed\n"); + return 0; + } + else printf("Decryption succeeded\n"); + + printf("Message is 0x"); + OCT_output(&M); + + + printf("Testing ECDSA\n"); + + if (ECP_NIST256_SP_DSA(HASH_TYPE_NIST256,RNG,NULL,&S0,&M,&CS,&DS)!=0) + { + printf("***ECDSA Signature Failed\n"); + return 0; + } + + printf("Signature C = 0x"); + OCT_output(&CS); + printf("Signature D = 0x"); + OCT_output(&DS); + + if (ECP_NIST256_VP_DSA(HASH_TYPE_NIST256,&W0,&M,&CS,&DS)!=0) + { + printf("***ECDSA Verification Failed\n"); + return 0; + } + else + { + printf("ECDSA Signature/Verification succeeded\n"); + } + +#endif + + return 0; +} + +int ecdh_GOLDILOCKS(csprng *RNG) +{ + int i,res; + 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_GOLDILOCKS is field size in bytes. So EFS_GOLDILOCKS=32 for 256-bit curve + char s0[2*EGS_GOLDILOCKS],s1[EGS_GOLDILOCKS],w0[2*EFS_GOLDILOCKS+1],w1[2*EFS_GOLDILOCKS+1],z0[EFS_GOLDILOCKS],z1[EFS_GOLDILOCKS],key[AESKEY_GOLDILOCKS],salt[40],pw[40]; + 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 KEY= {0,sizeof(key),key}; + octet SALT= {0,sizeof(salt),salt}; + octet PW= {0,sizeof(pw),pw}; + + 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_GOLDILOCKS bytes derived from Password and Salt + + PBKDF2(HASH_TYPE_GOLDILOCKS,&PW,&SALT,1000,EGS_GOLDILOCKS,&S0); + + printf("Alices private key= 0x"); + OCT_output(&S0); + + // Generate Key pair S/W + + ECP_GOLDILOCKS_KEY_PAIR_GENERATE(NULL,&S0,&W0); + printf("Alices public key= 0x"); + OCT_output(&W0); + + res=ECP_GOLDILOCKS_PUBLIC_KEY_VALIDATE(&W0); + if (res!=0) + { + printf("ECP Public Key is invalid!\n"); + return 0; + } + + // Random private key for other party + ECP_GOLDILOCKS_KEY_PAIR_GENERATE(RNG,&S1,&W1); + res=ECP_GOLDILOCKS_PUBLIC_KEY_VALIDATE(&W1); + if (res!=0) + { + printf("ECP Public Key is invalid!\n"); + return 0; + } + printf("Servers private key= 0x"); + OCT_output(&S1); + printf("Servers public key= 0x"); + OCT_output(&W1); + + // Calculate common key using DH - IEEE 1363 method + + ECP_GOLDILOCKS_SVDP_DH(&S0,&W1,&Z0); + ECP_GOLDILOCKS_SVDP_DH(&S1,&W0,&Z1); + + if (!OCT_comp(&Z0,&Z1)) + { + printf("*** ECPSVDP-DH Failed\n"); + return 0; + } + + KDF2(HASH_TYPE_GOLDILOCKS,&Z0,NULL,AESKEY_GOLDILOCKS,&KEY); + + printf("Alice's DH Key= 0x"); + OCT_output(&KEY); + printf("Servers DH Key= 0x"); + OCT_output(&KEY); + +#if CURVETYPE_GOLDILOCKS != MONTGOMERY + + char ds[EGS_GOLDILOCKS],p1[30],p2[30],v[2*EFS_GOLDILOCKS+1],m[32],c[64],t[32],cs[EGS_GOLDILOCKS]; + octet DS= {0,sizeof(ds),ds}; + octet CS= {0,sizeof(cs),cs}; + 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}; + + 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_GOLDILOCKS_ECIES_ENCRYPT(HASH_TYPE_GOLDILOCKS,&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_GOLDILOCKS_ECIES_DECRYPT(HASH_TYPE_GOLDILOCKS,&P1,&P2,&V,&C,&T,&S1,&M)) + { + printf("*** ECIES Decryption Failed\n"); + return 0; + } + else printf("Decryption succeeded\n"); + + printf("Message is 0x"); + OCT_output(&M); + + + printf("Testing ECDSA\n"); + + if (ECP_GOLDILOCKS_SP_DSA(HASH_TYPE_GOLDILOCKS,RNG,NULL,&S0,&M,&CS,&DS)!=0) + { + printf("***ECDSA Signature Failed\n"); + return 0; + } + + printf("Signature C = 0x"); + OCT_output(&CS); + printf("Signature D = 0x"); + OCT_output(&DS); + + if (ECP_GOLDILOCKS_VP_DSA(HASH_TYPE_GOLDILOCKS,&W0,&M,&CS,&DS)!=0) + { + printf("***ECDSA Verification Failed\n"); + return 0; + } + else + { + printf("ECDSA Signature/Verification succeeded\n"); + } + +#endif + + return 0; +} +#endif + +#define PERMITS // for time permits ON or OFF +#define PINERROR // For PIN ERROR detection ON or OFF +#define FULL // for M-Pin Full or M-Pin regular + +int mpin_BN254(csprng *RNG) +{ + int i,pin,rtn,err; +#ifdef PERMITS + int date=today(); +#else + int date=0; +#endif + unsigned long ran; + char x[PGS_BN254],s[PGS_BN254],y[PGS_BN254],client_id[100],sst[4*PFS_BN254],token[2*PFS_BN254+1],sec[2*PFS_BN254+1],permit[2*PFS_BN254+1],xcid[2*PFS_BN254+1],xid[2*PFS_BN254+1],e[12*PFS_BN254],f[12*PFS_BN254]; + char hcid[PFS_BN254],hsid[PFS_BN254],hid[2*PFS_BN254+1],htid[2*PFS_BN254+1],h[PGS_BN254]; +#ifdef FULL + char r[PGS_BN254],z[2*PFS_BN254+1],w[PGS_BN254],t[2*PFS_BN254+1]; + char g1[12*PFS_BN254],g2[12*PFS_BN254]; + char ck[AESKEY_BN254],sk[AESKEY_BN254]; +#endif + octet S= {0,sizeof(s),s}; + octet X= {0,sizeof(x),x}; + octet Y= {0,sizeof(y),y}; + octet H= {0,sizeof(h),h}; + octet CLIENT_ID= {0,sizeof(client_id),client_id}; + octet SST= {0,sizeof(sst),sst}; + octet TOKEN= {0,sizeof(token),token}; + octet SEC= {0,sizeof(sec),sec}; + octet PERMIT= {0,sizeof(permit),permit}; + octet xCID= {0,sizeof(xcid),xcid}; + octet xID= {0,sizeof(xid),xid}; + octet HCID= {0,sizeof(hcid),hcid}; + octet HSID= {0,sizeof(hsid),hsid}; + octet HID= {0,sizeof(hid),hid}; + octet HTID= {0,sizeof(htid),htid}; + octet E= {0,sizeof(e),e}; + octet F= {0,sizeof(f),f}; +#ifdef FULL + octet R= {0,sizeof(r),r}; + octet Z= {0,sizeof(z),z}; + octet W= {0,sizeof(w),w}; + octet T= {0,sizeof(t),t}; + octet G1= {0,sizeof(g1),g1}; + octet G2= {0,sizeof(g2),g2}; + octet SK= {0,sizeof(sk),sk}; + octet CK= {0,sizeof(ck),ck}; +#endif + octet *pxID,*pxCID,*pHID,*pHTID,*pE,*pF,*pPERMIT,*prHID; + char idhex[100]; + + // Trusted Authority set-up + MPIN_BN254_RANDOM_GENERATE(RNG,&S); + printf("Master Secret= "); + OCT_output(&S); + + // Create Client Identity + OCT_jstring(&CLIENT_ID,"[email protected]"); + HASH_ID(HASH_TYPE_BN254,&CLIENT_ID,&HCID); // Either Client or TA calculates Hash(ID) - you decide! + + printf("Client ID Hash= "); + OCT_output(&HCID); + printf("\n"); + + OCT_toHex(&CLIENT_ID,idhex); + printf("Client ID= %s\n",idhex);// OCT_toHex(&CLIENT_ID); printf("\n"); + + MPIN_BN254_GET_CLIENT_SECRET(&S,&HCID,&TOKEN); + printf("Client Secret= "); + OCT_output(&TOKEN); + +// Client and Server are issued secrets by DTA + MPIN_BN254_GET_SERVER_SECRET(&S,&SST); + printf("Server Secret= "); + OCT_output(&SST); + + + + // Client extracts PIN from secret to create Token + pin=1234; + printf("Client extracts PIN= %d\n",pin); + MPIN_BN254_EXTRACT_PIN(HASH_TYPE_BN254,&CLIENT_ID,pin,&TOKEN); + printf("Client Token= "); + OCT_output(&TOKEN); + +#ifdef FULL + MPIN_BN254_PRECOMPUTE(&TOKEN,&HCID,NULL,&G1,&G2); +#endif + +#ifdef PERMITS + // Client gets "Time Permit" from DTA + printf("Client gets Time Permit\n"); + + MPIN_BN254_GET_CLIENT_PERMIT(HASH_TYPE_BN254,date,&S,&HCID,&PERMIT); + printf("Time Permit= "); + OCT_output(&PERMIT); + + // This encoding makes Time permit look random + if (MPIN_BN254_ENCODING(RNG,&PERMIT)!=0) printf("Encoding error\n"); + // printf("Encoded Time Permit= "); OCT_output(&PERMIT); + if (MPIN_BN254_DECODING(&PERMIT)!=0) printf("Decoding error\n"); + // printf("Decoded Time Permit= "); OCT_output(&PERMIT); +#endif + + // MPin Protocol + + // Client enters PIN + printf("\nPIN= "); + if(scanf("%d",&pin)) {}; + // to avoid silly compile error + getchar(); + + // Set date=0 and PERMIT=NULL if time permits not in use + + // Client First pass: Inputs CLIENT_ID, optional RNG, pin, TOKEN and PERMIT. Output xID = x.H(CLIENT_ID) and re-combined secret SEC + // If PERMITS are is use, then date!=0 and PERMIT is added to secret and xCID = x.(H(CLIENT_ID)+H(date|H(CLIENT_ID))) + // Random value x is supplied externally if RNG=NULL, otherwise generated and passed out by RNG + + // HSID - hashed client ID as calculated by the server + // HCID - hashed client ID as calculated by the client + + // IMPORTANT: To save space and time.. + // If Time Permits OFF set xCID = NULL, HTID=NULL and use xID and HID only + // If Time permits are ON, AND pin error detection is required then all of xID, xCID, HID and HTID are required + // If Time permits are ON, AND pin error detection is NOT required, set xID=NULL, HID=NULL and use xCID and HTID only. + + + + pxID=&xID; + pxCID=&xCID; + pHID=&HID; + pHTID=&HTID; + pE=&E; + pF=&F; + pPERMIT=&PERMIT; + +#ifdef PERMITS + prHID=pHTID; +#ifndef PINERROR + pxID=NULL; +// pHID=NULL; //new +#endif +#else + prHID=pHID; + pPERMIT=NULL; + pxCID=NULL; + pHTID=NULL; +#endif +#ifndef PINERROR + pE=NULL; + pF=NULL; +#endif + + // When set only send hashed IDs to server + octet *pID; +#ifdef USE_ANONYMOUS + pID = &HCID; +#else + pID = &CLIENT_ID; +#endif + +#ifdef SINGLE_PASS + int timeValue; + printf("MPIN Single Pass\n"); + timeValue = MPIN_BN254_GET_TIME(); + + rtn=MPIN_BN254_CLIENT(HASH_TYPE_BN254,date,&CLIENT_ID,RNG,&X,pin,&TOKEN,&SEC,pxID,pxCID,pPERMIT,NULL,timeValue,&Y); + + if (rtn != 0) + { + printf("MPIN_BN254_CLIENT ERROR %d\n", rtn); + return 1; + } + +#ifdef FULL + MPIN_BN254_GET_G1_MULTIPLE(RNG,1,&R,&HCID,&Z); // Also Send Z=r.ID to Server, remember random r +#endif + + + rtn=MPIN_BN254_SERVER(HASH_TYPE_BN254,date,pHID,pHTID,&Y,&SST,pxID,pxCID,&SEC,pE,pF,pID,NULL,timeValue,NULL); + +#ifdef FULL + HASH_ID(HASH_TYPE_BN254,&CLIENT_ID,&HSID); // new + MPIN_BN254_GET_G1_MULTIPLE(RNG,0,&W,prHID,&T); // Also send T=w.ID to client, remember random w +#endif + +#else // SINGLE_PASS + printf("MPIN Multi Pass\n"); + if (MPIN_BN254_CLIENT_1(HASH_TYPE_BN254,date,&CLIENT_ID,RNG,&X,pin,&TOKEN,&SEC,pxID,pxCID,pPERMIT)!=0) + { + printf("Error from Client side - First Pass\n"); + return 0; + } + + // Send U=x.ID to server, and recreate secret from token and pin + +#ifdef FULL + HASH_ID(HASH_TYPE_BN254,&CLIENT_ID,&HCID); + MPIN_BN254_GET_G1_MULTIPLE(RNG,1,&R,&HCID,&Z); // Also Send Z=r.ID to Server, remember random r, DH component +#endif + + // Server calculates H(ID) and H(ID)+H(T|H(ID)) (if time permits enabled), and maps them to points on the curve HID and HTID resp. + MPIN_BN254_SERVER_1(HASH_TYPE_BN254,date,pID,pHID,pHTID); + + // Server generates Random number Y and sends it to Client + MPIN_BN254_RANDOM_GENERATE(RNG,&Y); + +#ifdef FULL + HASH_ID(HASH_TYPE_BN254,&CLIENT_ID,&HSID); //new + MPIN_BN254_GET_G1_MULTIPLE(RNG,0,&W,prHID,&T); // Also send T=w.ID to client, remember random w, DH component +#endif + + // Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC + if (MPIN_BN254_CLIENT_2(&X,&Y,&SEC)!=0) + { + printf("Error from Client side - Second Pass\n"); + return 1; + } + + // Server Second phase. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. + // If PIN error not required, set E and F = NULL + rtn=MPIN_BN254_SERVER_2(date,pHID,pHTID,&Y,&SST,pxID,pxCID,&SEC,pE,pF,NULL); +#endif // SINGLE_PASS + + if (rtn!=0) + { + printf("Server says - Bad Pin.\n"); +#ifdef PINERROR + + err=MPIN_BN254_KANGAROO(&E,&F); + if (err) printf("(Client PIN is out by %d)\n",err); + +#endif + return 1; + } + else + { + printf("Server says - PIN is good! You really are "); + OCT_output_string(&CLIENT_ID); + printf(".\n"); + } + +#ifdef FULL + + HASH_ALL(HASH_TYPE_BN254,&HCID,pxID,pxCID,&SEC,&Y,&Z,&T,&H); // new + MPIN_BN254_CLIENT_KEY(HASH_TYPE_BN254,&G1,&G2,pin,&R,&X,&H,&T,&CK); // new H + printf("Client Key = "); + OCT_output(&CK); + + HASH_ALL(HASH_TYPE_BN254,&HSID,pxID,pxCID,&SEC,&Y,&Z,&T,&H); + MPIN_BN254_SERVER_KEY(HASH_TYPE_BN254,&Z,&SST,&W,&H,pHID,pxID,pxCID,&SK); // new H,pHID + printf("Server Key = "); + OCT_output(&SK); +#endif + return 0; +} + +#if CHUNK==32 || CHUNK==64 + +int mpin_BLS383(csprng *RNG) +{ + int i,pin,rtn,err; +#ifdef PERMITS + int date=today(); +#else + int date=0; +#endif + unsigned long ran; + char x[PGS_BLS383],s[PGS_BLS383],y[PGS_BLS383],client_id[100],sst[4*PFS_BLS383],token[2*PFS_BLS383+1],sec[2*PFS_BLS383+1],permit[2*PFS_BLS383+1],xcid[2*PFS_BLS383+1],xid[2*PFS_BLS383+1],e[12*PFS_BLS383],f[12*PFS_BLS383]; + char hcid[PFS_BLS383],hsid[PFS_BLS383],hid[2*PFS_BLS383+1],htid[2*PFS_BLS383+1],h[PGS_BLS383]; +#ifdef FULL + char r[PGS_BLS383],z[2*PFS_BLS383+1],w[PGS_BLS383],t[2*PFS_BLS383+1]; + char g1[12*PFS_BLS383],g2[12*PFS_BLS383]; + char ck[AESKEY_BLS383],sk[AESKEY_BLS383]; +#endif + octet S= {0,sizeof(s),s}; + octet X= {0,sizeof(x),x}; + octet Y= {0,sizeof(y),y}; + octet H= {0,sizeof(h),h}; + octet CLIENT_ID= {0,sizeof(client_id),client_id}; + octet SST= {0,sizeof(sst),sst}; + octet TOKEN= {0,sizeof(token),token}; + octet SEC= {0,sizeof(sec),sec}; + octet PERMIT= {0,sizeof(permit),permit}; + octet xCID= {0,sizeof(xcid),xcid}; + octet xID= {0,sizeof(xid),xid}; + octet HCID= {0,sizeof(hcid),hcid}; + octet HSID= {0,sizeof(hsid),hsid}; + octet HID= {0,sizeof(hid),hid}; + octet HTID= {0,sizeof(htid),htid}; + octet E= {0,sizeof(e),e}; + octet F= {0,sizeof(f),f}; +#ifdef FULL + octet R= {0,sizeof(r),r}; + octet Z= {0,sizeof(z),z}; + octet W= {0,sizeof(w),w}; + octet T= {0,sizeof(t),t}; + octet G1= {0,sizeof(g1),g1}; + octet G2= {0,sizeof(g2),g2}; + octet SK= {0,sizeof(sk),sk}; + octet CK= {0,sizeof(ck),ck}; +#endif + octet *pxID,*pxCID,*pHID,*pHTID,*pE,*pF,*pPERMIT,*prHID; + char idhex[100]; + + // Trusted Authority set-up + MPIN_BLS383_RANDOM_GENERATE(RNG,&S); + printf("Master Secret= "); + OCT_output(&S); + + // Create Client Identity + OCT_jstring(&CLIENT_ID,"[email protected]"); + HASH_ID(HASH_TYPE_BLS383,&CLIENT_ID,&HCID); // Either Client or TA calculates Hash(ID) - you decide! + + printf("Client ID Hash= "); + OCT_output(&HCID); + printf("\n"); + + OCT_toHex(&CLIENT_ID,idhex); + printf("Client ID= %s\n",idhex);// OCT_toHex(&CLIENT_ID); printf("\n"); + + MPIN_BLS383_GET_CLIENT_SECRET(&S,&HCID,&TOKEN); + printf("Client Secret= "); + OCT_output(&TOKEN); + +// Client and Server are issued secrets by DTA + MPIN_BLS383_GET_SERVER_SECRET(&S,&SST); + printf("Server Secret= "); + OCT_output(&SST); + + + + // Client extracts PIN from secret to create Token + pin=1234; + printf("Client extracts PIN= %d\n",pin); + MPIN_BLS383_EXTRACT_PIN(HASH_TYPE_BLS383,&CLIENT_ID,pin,&TOKEN); + printf("Client Token= "); + OCT_output(&TOKEN); + +#ifdef FULL + MPIN_BLS383_PRECOMPUTE(&TOKEN,&HCID,NULL,&G1,&G2); +#endif + +#ifdef PERMITS + // Client gets "Time Permit" from DTA + printf("Client gets Time Permit\n"); + + MPIN_BLS383_GET_CLIENT_PERMIT(HASH_TYPE_BLS383,date,&S,&HCID,&PERMIT); + printf("Time Permit= "); + OCT_output(&PERMIT); + + // This encoding makes Time permit look random + if (MPIN_BLS383_ENCODING(RNG,&PERMIT)!=0) printf("Encoding error\n"); + // printf("Encoded Time Permit= "); OCT_output(&PERMIT); + if (MPIN_BLS383_DECODING(&PERMIT)!=0) printf("Decoding error\n"); + // printf("Decoded Time Permit= "); OCT_output(&PERMIT); +#endif + + // MPin Protocol + + // Client enters PIN + printf("\nPIN= "); + if(scanf("%d",&pin)) {}; + // to avoid silly compile error + getchar(); + + // Set date=0 and PERMIT=NULL if time permits not in use + + // Client First pass: Inputs CLIENT_ID, optional RNG, pin, TOKEN and PERMIT. Output xID = x.H(CLIENT_ID) and re-combined secret SEC + // If PERMITS are is use, then date!=0 and PERMIT is added to secret and xCID = x.(H(CLIENT_ID)+H(date|H(CLIENT_ID))) + // Random value x is supplied externally if RNG=NULL, otherwise generated and passed out by RNG + + // HSID - hashed client ID as calculated by the server + // HCID - hashed client ID as calculated by the client + + // IMPORTANT: To save space and time.. + // If Time Permits OFF set xCID = NULL, HTID=NULL and use xID and HID only + // If Time permits are ON, AND pin error detection is required then all of xID, xCID, HID and HTID are required + // If Time permits are ON, AND pin error detection is NOT required, set xID=NULL, HID=NULL and use xCID and HTID only. + + + + pxID=&xID; + pxCID=&xCID; + pHID=&HID; + pHTID=&HTID; + pE=&E; + pF=&F; + pPERMIT=&PERMIT; + +#ifdef PERMITS + prHID=pHTID; +#ifndef PINERROR + pxID=NULL; +// pHID=NULL; //new +#endif +#else + prHID=pHID; + pPERMIT=NULL; + pxCID=NULL; + pHTID=NULL; +#endif +#ifndef PINERROR + pE=NULL; + pF=NULL; +#endif + + // When set only send hashed IDs to server + octet *pID; +#ifdef USE_ANONYMOUS + pID = &HCID; +#else + pID = &CLIENT_ID; +#endif + +#ifdef SINGLE_PASS + int timeValue; + printf("MPIN Single Pass\n"); + timeValue = MPIN_BLS383_GET_TIME(); + + rtn=MPIN_BLS383_CLIENT(HASH_TYPE_BLS383,date,&CLIENT_ID,RNG,&X,pin,&TOKEN,&SEC,pxID,pxCID,pPERMIT,NULL,timeValue,&Y); + + if (rtn != 0) + { + printf("MPIN_BLS383_CLIENT ERROR %d\n", rtn); + return 1; + } + +#ifdef FULL + MPIN_BLS383_GET_G1_MULTIPLE(RNG,1,&R,&HCID,&Z); // Also Send Z=r.ID to Server, remember random r +#endif + + + rtn=MPIN_BLS383_SERVER(HASH_TYPE_BLS383,date,pHID,pHTID,&Y,&SST,pxID,pxCID,&SEC,pE,pF,pID,NULL,timeValue,NULL); + +#ifdef FULL + HASH_ID(HASH_TYPE_BLS383,&CLIENT_ID,&HSID); // new + MPIN_BLS383_GET_G1_MULTIPLE(RNG,0,&W,prHID,&T); // Also send T=w.ID to client, remember random w +#endif + +#else // SINGLE_PASS + printf("MPIN Multi Pass\n"); + if (MPIN_BLS383_CLIENT_1(HASH_TYPE_BLS383,date,&CLIENT_ID,RNG,&X,pin,&TOKEN,&SEC,pxID,pxCID,pPERMIT)!=0) + { + printf("Error from Client side - First Pass\n"); + return 0; + } + + // Send U=x.ID to server, and recreate secret from token and pin + +#ifdef FULL + HASH_ID(HASH_TYPE_BLS383,&CLIENT_ID,&HCID); + MPIN_BLS383_GET_G1_MULTIPLE(RNG,1,&R,&HCID,&Z); // Also Send Z=r.ID to Server, remember random r, DH component +#endif + + // Server calculates H(ID) and H(ID)+H(T|H(ID)) (if time permits enabled), and maps them to points on the curve HID and HTID resp. + MPIN_BLS383_SERVER_1(HASH_TYPE_BLS383,date,pID,pHID,pHTID); + + // Server generates Random number Y and sends it to Client + MPIN_BLS383_RANDOM_GENERATE(RNG,&Y); + +#ifdef FULL + HASH_ID(HASH_TYPE_BLS383,&CLIENT_ID,&HSID); //new + MPIN_BLS383_GET_G1_MULTIPLE(RNG,0,&W,prHID,&T); // Also send T=w.ID to client, remember random w, DH component +#endif + + // Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC + if (MPIN_BLS383_CLIENT_2(&X,&Y,&SEC)!=0) + { + printf("Error from Client side - Second Pass\n"); + return 1; + } + + // Server Second phase. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. + // If PIN error not required, set E and F = NULL + rtn=MPIN_BLS383_SERVER_2(date,pHID,pHTID,&Y,&SST,pxID,pxCID,&SEC,pE,pF,NULL); +#endif // SINGLE_PASS + + if (rtn!=0) + { + printf("Server says - Bad Pin.\n"); +#ifdef PINERROR + + err=MPIN_BLS383_KANGAROO(&E,&F); + if (err) printf("(Client PIN is out by %d)\n",err); + +#endif + return 1; + } + else + { + printf("Server says - PIN is good! You really are "); + OCT_output_string(&CLIENT_ID); + printf(".\n"); + } + +#ifdef FULL + + HASH_ALL(HASH_TYPE_BLS383,&HCID,pxID,pxCID,&SEC,&Y,&Z,&T,&H); // new + MPIN_BLS383_CLIENT_KEY(HASH_TYPE_BLS383,&G1,&G2,pin,&R,&X,&H,&T,&CK); // new H + printf("Client Key = "); + OCT_output(&CK); + + HASH_ALL(HASH_TYPE_BLS383,&HSID,pxID,pxCID,&SEC,&Y,&Z,&T,&H); + MPIN_BLS383_SERVER_KEY(HASH_TYPE_BLS383,&Z,&SST,&W,&H,pHID,pxID,pxCID,&SK); // new H,pHID + printf("Server Key = "); + OCT_output(&SK); +#endif + return 0; +} + + +int mpin192_BLS24(csprng *RNG) +{ + int i,pin,rtn,err; +#ifdef PERMITS + int date=today(); +#else + int date=0; +#endif + unsigned long ran; + char x[PGS_BLS24],s[PGS_BLS24],y[PGS_BLS24],client_id[100],sst[8*PFS_BLS24],token[2*PFS_BLS24+1],sec[2*PFS_BLS24+1],permit[2*PFS_BLS24+1],xcid[2*PFS_BLS24+1],xid[2*PFS_BLS24+1],e[24*PFS_BLS24],f[24*PFS_BLS24]; + char hcid[PFS_BLS24],hsid[PFS_BLS24],hid[2*PFS_BLS24+1],htid[2*PFS_BLS24+1],h[PGS_BLS24]; +#ifdef FULL + char r[PGS_BLS24],z[2*PFS_BLS24+1],w[PGS_BLS24],t[2*PFS_BLS24+1]; + char g1[24*PFS_BLS24],g2[24*PFS_BLS24]; + char ck[AESKEY_BLS24],sk[AESKEY_BLS24]; +#endif + octet S= {0,sizeof(s),s}; + octet X= {0,sizeof(x),x}; + octet Y= {0,sizeof(y),y}; + octet H= {0,sizeof(h),h}; + octet CLIENT_ID= {0,sizeof(client_id),client_id}; + octet SST= {0,sizeof(sst),sst}; + octet TOKEN= {0,sizeof(token),token}; + octet SEC= {0,sizeof(sec),sec}; + octet PERMIT= {0,sizeof(permit),permit}; + octet xCID= {0,sizeof(xcid),xcid}; + octet xID= {0,sizeof(xid),xid}; + octet HCID= {0,sizeof(hcid),hcid}; + octet HSID= {0,sizeof(hsid),hsid}; + octet HID= {0,sizeof(hid),hid}; + octet HTID= {0,sizeof(htid),htid}; + octet E= {0,sizeof(e),e}; + octet F= {0,sizeof(f),f}; +#ifdef FULL + octet R= {0,sizeof(r),r}; + octet Z= {0,sizeof(z),z}; + octet W= {0,sizeof(w),w}; + octet T= {0,sizeof(t),t}; + octet G1= {0,sizeof(g1),g1}; + octet G2= {0,sizeof(g2),g2}; + octet SK= {0,sizeof(sk),sk}; + octet CK= {0,sizeof(ck),ck}; +#endif + octet *pxID,*pxCID,*pHID,*pHTID,*pE,*pF,*pPERMIT,*prHID; + char idhex[100]; + + // Trusted Authority set-up + MPIN_BLS24_RANDOM_GENERATE(RNG,&S); + printf("Master Secret= "); + OCT_output(&S); + + // Create Client Identity + OCT_jstring(&CLIENT_ID,"[email protected]"); + HASH_ID(HASH_TYPE_BLS24,&CLIENT_ID,&HCID); // Either Client or TA calculates Hash(ID) - you decide! + + printf("Client ID Hash= "); + OCT_output(&HCID); + printf("\n"); + + OCT_toHex(&CLIENT_ID,idhex); + printf("Client ID= %s\n",idhex);// OCT_toHex(&CLIENT_ID); printf("\n"); + + MPIN_BLS24_GET_CLIENT_SECRET(&S,&HCID,&TOKEN); + printf("Client Secret= "); + OCT_output(&TOKEN); + +// Client and Server are issued secrets by DTA + MPIN_BLS24_GET_SERVER_SECRET(&S,&SST); + printf("Server Secret= "); + OCT_output(&SST); + + + + // Client extracts PIN from secret to create Token + pin=1234; + printf("Client extracts PIN= %d\n",pin); + MPIN_BLS24_EXTRACT_PIN(HASH_TYPE_BLS24,&CLIENT_ID,pin,&TOKEN); + printf("Client Token= "); + OCT_output(&TOKEN); + +#ifdef FULL + MPIN_BLS24_PRECOMPUTE(&TOKEN,&HCID,NULL,&G1,&G2); +#endif + +#ifdef PERMITS + // Client gets "Time Permit" from DTA + printf("Client gets Time Permit\n"); + + MPIN_BLS24_GET_CLIENT_PERMIT(HASH_TYPE_BLS24,date,&S,&HCID,&PERMIT); + printf("Time Permit= "); + OCT_output(&PERMIT); + + // This encoding makes Time permit look random + if (MPIN_BLS24_ENCODING(RNG,&PERMIT)!=0) printf("Encoding error\n"); + // printf("Encoded Time Permit= "); OCT_output(&PERMIT); + if (MPIN_BLS24_DECODING(&PERMIT)!=0) printf("Decoding error\n"); + // printf("Decoded Time Permit= "); OCT_output(&PERMIT); +#endif + + // MPin Protocol + + // Client enters PIN + printf("\nPIN= "); + if(scanf("%d",&pin)) {}; + // to avoid silly compile error + getchar(); + + // Set date=0 and PERMIT=NULL if time permits not in use + + // Client First pass: Inputs CLIENT_ID, optional RNG, pin, TOKEN and PERMIT. Output xID = x.H(CLIENT_ID) and re-combined secret SEC + // If PERMITS are is use, then date!=0 and PERMIT is added to secret and xCID = x.(H(CLIENT_ID)+H(date|H(CLIENT_ID))) + // Random value x is supplied externally if RNG=NULL, otherwise generated and passed out by RNG + + // HSID - hashed client ID as calculated by the server + // HCID - hashed client ID as calculated by the client + + // IMPORTANT: To save space and time.. + // If Time Permits OFF set xCID = NULL, HTID=NULL and use xID and HID only + // If Time permits are ON, AND pin error detection is required then all of xID, xCID, HID and HTID are required + // If Time permits are ON, AND pin error detection is NOT required, set xID=NULL, HID=NULL and use xCID and HTID only. + + + + pxID=&xID; + pxCID=&xCID; + pHID=&HID; + pHTID=&HTID; + pE=&E; + pF=&F; + pPERMIT=&PERMIT; + +#ifdef PERMITS + prHID=pHTID; +#ifndef PINERROR + pxID=NULL; +// pHID=NULL; //new +#endif +#else + prHID=pHID; + pPERMIT=NULL; + pxCID=NULL; + pHTID=NULL; +#endif +#ifndef PINERROR + pE=NULL; + pF=NULL; +#endif + + // When set only send hashed IDs to server + octet *pID; +#ifdef USE_ANONYMOUS + pID = &HCID; +#else + pID = &CLIENT_ID; +#endif + +#ifdef SINGLE_PASS + int timeValue; + printf("MPIN Single Pass\n"); + timeValue = MPIN_BLS24_GET_TIME(); + + rtn=MPIN_BLS24_CLIENT(HASH_TYPE_BLS24,date,&CLIENT_ID,RNG,&X,pin,&TOKEN,&SEC,pxID,pxCID,pPERMIT,NULL,timeValue,&Y); + + if (rtn != 0) + { + printf("MPIN_BLS24_CLIENT ERROR %d\n", rtn); + return 1; + } + +#ifdef FULL + MPIN_BLS24_GET_G1_MULTIPLE(RNG,1,&R,&HCID,&Z); // Also Send Z=r.ID to Server, remember random r +#endif + + + rtn=MPIN_BLS24_SERVER(HASH_TYPE_BLS24,date,pHID,pHTID,&Y,&SST,pxID,pxCID,&SEC,pE,pF,pID,NULL,timeValue,NULL); + +#ifdef FULL + HASH_ID(HASH_TYPE_BLS24,&CLIENT_ID,&HSID); // new + MPIN_BLS24_GET_G1_MULTIPLE(RNG,0,&W,prHID,&T); // Also send T=w.ID to client, remember random w +#endif + +#else // SINGLE_PASS + printf("MPIN Multi Pass\n"); + if (MPIN_BLS24_CLIENT_1(HASH_TYPE_BLS24,date,&CLIENT_ID,RNG,&X,pin,&TOKEN,&SEC,pxID,pxCID,pPERMIT)!=0) + { + printf("Error from Client side - First Pass\n"); + return 0; + } + + // Send U=x.ID to server, and recreate secret from token and pin + +#ifdef FULL + HASH_ID(HASH_TYPE_BLS24,&CLIENT_ID,&HCID); + MPIN_BLS24_GET_G1_MULTIPLE(RNG,1,&R,&HCID,&Z); // Also Send Z=r.ID to Server, remember random r, DH component +#endif + + // Server calculates H(ID) and H(ID)+H(T|H(ID)) (if time permits enabled), and maps them to points on the curve HID and HTID resp. + MPIN_BLS24_SERVER_1(HASH_TYPE_BLS24,date,pID,pHID,pHTID); + + // Server generates Random number Y and sends it to Client + MPIN_BLS24_RANDOM_GENERATE(RNG,&Y); + +#ifdef FULL + HASH_ID(HASH_TYPE_BLS24,&CLIENT_ID,&HSID); //new + MPIN_BLS24_GET_G1_MULTIPLE(RNG,0,&W,prHID,&T); // Also send T=w.ID to client, remember random w, DH component +#endif + + // Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC + if (MPIN_BLS24_CLIENT_2(&X,&Y,&SEC)!=0) + { + printf("Error from Client side - Second Pass\n"); + return 1; + } + + // Server Second phase. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. + // If PIN error not required, set E and F = NULL + rtn=MPIN_BLS24_SERVER_2(date,pHID,pHTID,&Y,&SST,pxID,pxCID,&SEC,pE,pF,NULL); +#endif // SINGLE_PASS + + if (rtn!=0) + { + printf("Server says - Bad Pin.\n"); +#ifdef PINERROR + + err=MPIN_BLS24_KANGAROO(&E,&F); + if (err) printf("(Client PIN is out by %d)\n",err); + +#endif + return 1; + } + else + { + printf("Server says - PIN is good! You really are "); + OCT_output_string(&CLIENT_ID); + printf(".\n"); + } + +#ifdef FULL + + HASH_ALL(HASH_TYPE_BLS24,&HCID,pxID,pxCID,&SEC,&Y,&Z,&T,&H); // new + MPIN_BLS24_CLIENT_KEY(HASH_TYPE_BLS24,&G1,&G2,pin,&R,&X,&H,&T,&CK); // new H + printf("Client Key = "); + OCT_output(&CK); + + HASH_ALL(HASH_TYPE_BLS24,&HSID,pxID,pxCID,&SEC,&Y,&Z,&T,&H); + MPIN_BLS24_SERVER_KEY(HASH_TYPE_BLS24,&Z,&SST,&W,&H,pHID,pxID,pxCID,&SK); // new H,pHID + printf("Server Key = "); + OCT_output(&SK); +#endif + return 0; +} + + +int mpin256_BLS48(csprng *RNG) +{ + int i,pin,rtn,err; +#ifdef PERMITS + int date=today(); +#else + int date=0; +#endif + unsigned long ran; + char x[PGS_BLS48],s[PGS_BLS48],y[PGS_BLS48],client_id[100],sst[16*PFS_BLS48],token[2*PFS_BLS48+1],sec[2*PFS_BLS48+1],permit[2*PFS_BLS48+1],xcid[2*PFS_BLS48+1],xid[2*PFS_BLS48+1],e[48*PFS_BLS48],f[48*PFS_BLS48]; + char hcid[PFS_BLS48],hsid[PFS_BLS48],hid[2*PFS_BLS48+1],htid[2*PFS_BLS48+1],h[PGS_BLS48]; +#ifdef FULL + char r[PGS_BLS48],z[2*PFS_BLS48+1],w[PGS_BLS48],t[2*PFS_BLS48+1]; + char g1[48*PFS_BLS48],g2[48*PFS_BLS48]; + char ck[AESKEY_BLS48],sk[AESKEY_BLS48]; +#endif + octet S= {0,sizeof(s),s}; + octet X= {0,sizeof(x),x}; + octet Y= {0,sizeof(y),y}; + octet H= {0,sizeof(h),h}; + octet CLIENT_ID= {0,sizeof(client_id),client_id}; + octet SST= {0,sizeof(sst),sst}; + octet TOKEN= {0,sizeof(token),token}; + octet SEC= {0,sizeof(sec),sec}; + octet PERMIT= {0,sizeof(permit),permit}; + octet xCID= {0,sizeof(xcid),xcid}; + octet xID= {0,sizeof(xid),xid}; + octet HCID= {0,sizeof(hcid),hcid}; + octet HSID= {0,sizeof(hsid),hsid}; + octet HID= {0,sizeof(hid),hid}; + octet HTID= {0,sizeof(htid),htid}; + octet E= {0,sizeof(e),e}; + octet F= {0,sizeof(f),f}; +#ifdef FULL + octet R= {0,sizeof(r),r}; + octet Z= {0,sizeof(z),z}; + octet W= {0,sizeof(w),w}; + octet T= {0,sizeof(t),t}; + octet G1= {0,sizeof(g1),g1}; + octet G2= {0,sizeof(g2),g2}; + octet SK= {0,sizeof(sk),sk}; + octet CK= {0,sizeof(ck),ck}; +#endif + octet *pxID,*pxCID,*pHID,*pHTID,*pE,*pF,*pPERMIT,*prHID; + char idhex[100]; + + // Trusted Authority set-up + MPIN_BLS48_RANDOM_GENERATE(RNG,&S); + printf("Master Secret= "); + OCT_output(&S); + + // Create Client Identity + OCT_jstring(&CLIENT_ID,"[email protected]"); + HASH_ID(HASH_TYPE_BLS48,&CLIENT_ID,&HCID); // Either Client or TA calculates Hash(ID) - you decide! + + printf("Client ID Hash= "); + OCT_output(&HCID); + printf("\n"); + + OCT_toHex(&CLIENT_ID,idhex); + printf("Client ID= %s\n",idhex);// OCT_toHex(&CLIENT_ID); printf("\n"); + + MPIN_BLS48_GET_CLIENT_SECRET(&S,&HCID,&TOKEN); + printf("Client Secret= "); + OCT_output(&TOKEN); + +// Client and Server are issued secrets by DTA + MPIN_BLS48_GET_SERVER_SECRET(&S,&SST); + printf("Server Secret= "); + OCT_output(&SST); + + + + // Client extracts PIN from secret to create Token + pin=1234; + printf("Client extracts PIN= %d\n",pin); + MPIN_BLS48_EXTRACT_PIN(HASH_TYPE_BLS48,&CLIENT_ID,pin,&TOKEN); + printf("Client Token= "); + OCT_output(&TOKEN); + +#ifdef FULL + MPIN_BLS48_PRECOMPUTE(&TOKEN,&HCID,NULL,&G1,&G2); +#endif + +#ifdef PERMITS + // Client gets "Time Permit" from DTA + printf("Client gets Time Permit\n"); + + MPIN_BLS48_GET_CLIENT_PERMIT(HASH_TYPE_BLS48,date,&S,&HCID,&PERMIT); + printf("Time Permit= "); + OCT_output(&PERMIT); + + // This encoding makes Time permit look random + if (MPIN_BLS48_ENCODING(RNG,&PERMIT)!=0) printf("Encoding error\n"); + // printf("Encoded Time Permit= "); OCT_output(&PERMIT); + if (MPIN_BLS48_DECODING(&PERMIT)!=0) printf("Decoding error\n"); + // printf("Decoded Time Permit= "); OCT_output(&PERMIT); +#endif + + // MPin Protocol + + // Client enters PIN + printf("\nPIN= "); + if(scanf("%d",&pin)) {}; + // to avoid silly compile error + getchar(); + + // Set date=0 and PERMIT=NULL if time permits not in use + + // Client First pass: Inputs CLIENT_ID, optional RNG, pin, TOKEN and PERMIT. Output xID = x.H(CLIENT_ID) and re-combined secret SEC + // If PERMITS are is use, then date!=0 and PERMIT is added to secret and xCID = x.(H(CLIENT_ID)+H(date|H(CLIENT_ID))) + // Random value x is supplied externally if RNG=NULL, otherwise generated and passed out by RNG + + // HSID - hashed client ID as calculated by the server + // HCID - hashed client ID as calculated by the client + + // IMPORTANT: To save space and time.. + // If Time Permits OFF set xCID = NULL, HTID=NULL and use xID and HID only + // If Time permits are ON, AND pin error detection is required then all of xID, xCID, HID and HTID are required + // If Time permits are ON, AND pin error detection is NOT required, set xID=NULL, HID=NULL and use xCID and HTID only. + + + + pxID=&xID; + pxCID=&xCID; + pHID=&HID; + pHTID=&HTID; + pE=&E; + pF=&F; + pPERMIT=&PERMIT; + +#ifdef PERMITS + prHID=pHTID; +#ifndef PINERROR + pxID=NULL; +// pHID=NULL; //new +#endif +#else + prHID=pHID; + pPERMIT=NULL; + pxCID=NULL; + pHTID=NULL; +#endif +#ifndef PINERROR + pE=NULL; + pF=NULL; +#endif + + // When set only send hashed IDs to server + octet *pID; +#ifdef USE_ANONYMOUS + pID = &HCID; +#else + pID = &CLIENT_ID; +#endif + +#ifdef SINGLE_PASS + int timeValue; + printf("MPIN Single Pass\n"); + timeValue = MPIN_BLS48_GET_TIME(); + + rtn=MPIN_BLS48_CLIENT(HASH_TYPE_BLS48,date,&CLIENT_ID,RNG,&X,pin,&TOKEN,&SEC,pxID,pxCID,pPERMIT,NULL,timeValue,&Y); + + if (rtn != 0) + { + printf("MPIN_BLS48_CLIENT ERROR %d\n", rtn); + return 1; + } + +#ifdef FULL + MPIN_BLS48_GET_G1_MULTIPLE(RNG,1,&R,&HCID,&Z); // Also Send Z=r.ID to Server, remember random r +#endif + + + rtn=MPIN_BLS48_SERVER(HASH_TYPE_BLS48,date,pHID,pHTID,&Y,&SST,pxID,pxCID,&SEC,pE,pF,pID,NULL,timeValue,NULL); + +#ifdef FULL + HASH_ID(HASH_TYPE_BLS48,&CLIENT_ID,&HSID); // new + MPIN_BLS48_GET_G1_MULTIPLE(RNG,0,&W,prHID,&T); // Also send T=w.ID to client, remember random w +#endif + +#else // SINGLE_PASS + printf("MPIN Multi Pass\n"); + if (MPIN_BLS48_CLIENT_1(HASH_TYPE_BLS48,date,&CLIENT_ID,RNG,&X,pin,&TOKEN,&SEC,pxID,pxCID,pPERMIT)!=0) + { + printf("Error from Client side - First Pass\n"); + return 0; + } + + // Send U=x.ID to server, and recreate secret from token and pin + +#ifdef FULL + HASH_ID(HASH_TYPE_BLS48,&CLIENT_ID,&HCID); + MPIN_BLS48_GET_G1_MULTIPLE(RNG,1,&R,&HCID,&Z); // Also Send Z=r.ID to Server, remember random r, DH component +#endif + + // Server calculates H(ID) and H(ID)+H(T|H(ID)) (if time permits enabled), and maps them to points on the curve HID and HTID resp. + MPIN_BLS48_SERVER_1(HASH_TYPE_BLS48,date,pID,pHID,pHTID); + + // Server generates Random number Y and sends it to Client + MPIN_BLS48_RANDOM_GENERATE(RNG,&Y); + +#ifdef FULL + HASH_ID(HASH_TYPE_BLS48,&CLIENT_ID,&HSID); //new + MPIN_BLS48_GET_G1_MULTIPLE(RNG,0,&W,prHID,&T); // Also send T=w.ID to client, remember random w, DH component +#endif + + // Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC + if (MPIN_BLS48_CLIENT_2(&X,&Y,&SEC)!=0) + { + printf("Error from Client side - Second Pass\n"); + return 1; + } + + // Server Second phase. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. + // If PIN error not required, set E and F = NULL + rtn=MPIN_BLS48_SERVER_2(date,pHID,pHTID,&Y,&SST,pxID,pxCID,&SEC,pE,pF,NULL); +#endif // SINGLE_PASS + + if (rtn!=0) + { + printf("Server says - Bad Pin.\n"); +#ifdef PINERROR + + err=MPIN_BLS48_KANGAROO(&E,&F); + if (err) printf("(Client PIN is out by %d)\n",err); + +#endif + return 1; + } + else + { + printf("Server says - PIN is good! You really are "); + OCT_output_string(&CLIENT_ID); + printf(".\n"); + } + +#ifdef FULL + + HASH_ALL(HASH_TYPE_BLS48,&HCID,pxID,pxCID,&SEC,&Y,&Z,&T,&H); // new + MPIN_BLS48_CLIENT_KEY(HASH_TYPE_BLS48,&G1,&G2,pin,&R,&X,&H,&T,&CK); // new H + printf("Client Key = "); + OCT_output(&CK); + + HASH_ALL(HASH_TYPE_BLS48,&HSID,pxID,pxCID,&SEC,&Y,&Z,&T,&H); + MPIN_BLS48_SERVER_KEY(HASH_TYPE_BLS48,&Z,&SST,&W,&H,pHID,pxID,pxCID,&SK); // new H,pHID + printf("Server Key = "); + OCT_output(&SK); +#endif + return 0; +} + + +#endif + +int rsa_2048(csprng *RNG) +{ + int i; + unsigned long ran; + char m[RFS_2048],ml[RFS_2048],c[RFS_2048],e[RFS_2048],s[RFS_2048]; + rsa_public_key_2048 pub; + rsa_private_key_2048 priv; + + 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 S= {0,sizeof(s),s}; + + printf("Generating public/private key pair\n"); + RSA_2048_KEY_PAIR(RNG,65537,&priv,&pub,NULL,NULL); + + printf("Encrypting test string\n"); + OCT_jstring(&M,(char *)"Hello World\n"); + + OAEP_ENCODE(HASH_TYPE_RSA_2048,&M,RNG,NULL,&E); // OAEP encode message m to e + + RSA_2048_ENCRYPT(&pub,&E,&C); // encrypt encoded message + printf("Ciphertext= "); + OCT_output(&C); + + printf("Decrypting test string\n"); + RSA_2048_DECRYPT(&priv,&C,&ML); // ... and then decrypt it + + OAEP_DECODE(HASH_TYPE_RSA_2048,NULL,&ML); // decode it + OCT_output_string(&ML); + + printf("Signing message\n"); + PKCS15(HASH_TYPE_RSA_2048,&M,&C); + + RSA_2048_DECRYPT(&priv,&C,&S); // create signature in S + + printf("Signature= "); + OCT_output(&S); + + RSA_2048_ENCRYPT(&pub,&S,&ML); + + if (OCT_comp(&C,&ML)) printf("Signature is valid\n"); + else printf("Signature is INVALID\n"); + + RSA_2048_PRIVATE_KEY_KILL(&priv); + + OCT_clear(&M); + OCT_clear(&ML); // clean up afterwards + OCT_clear(&C); + OCT_clear(&E); + + return 0; +} + + +int main() +{ + int i,res; + unsigned long ran; + + char raw[100]; + octet RAW= {0,sizeof(raw),raw}; + csprng RNG; // Crypto Strong RNG + + 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("\nTesting MPIN protocols for curve BN254\n"); + mpin_BN254(&RNG); + +#if CHUNK!=16 + printf("\nTesting MPIN protocols for curve BLS383\n"); + mpin_BLS383(&RNG); + printf("\nTesting MPIN protocols for curve BLS24\n"); + mpin192_BLS24(&RNG); + printf("\nTesting MPIN protocols for curve BLS48\n"); + mpin256_BLS48(&RNG); +#endif + + + printf("\nTesting ECDH protocols for curve ED25519\n"); + ecdh_ED25519(&RNG); +#if CHUNK!=16 + printf("\nTesting ECDH protocols for curve NIST256\n"); + ecdh_NIST256(&RNG); + printf("\nTesting ECDH protocols for curve GOLDILOCKS\n"); + ecdh_GOLDILOCKS(&RNG); +#endif + printf("\nTesting RSA protocols for 2048-bit RSA\n"); + rsa_2048(&RNG); + + KILL_CSPRNG(&RNG); +} + http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version3/c/testbls.c ---------------------------------------------------------------------- diff --git a/version3/c/testbls.c b/version3/c/testbls.c new file mode 100644 index 0000000..ae71a25 --- /dev/null +++ b/version3/c/testbls.c @@ -0,0 +1,189 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +/* test driver and function exerciser for BLS Signature API Functions */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include "bls_BN254.h" + +#if CHUNK==32 || CHUNK==64 +#include "bls_BLS383.h" +#include "bls192_BLS24.h" +#include "bls256_BLS48.h" +#endif + +#include "randapi.h" + +static char message[]="This is a test message"; + +int bls_BN254(csprng *RNG) +{ + int res; + char s[BGS_BN254],w[4*BFS_BN254],sig[BFS_BN254+1]; + octet S= {0,sizeof(s),s}; + octet W= {0,sizeof(w),w}; + octet SIG= {0,sizeof(sig),sig}; + + BLS_BN254_KEY_PAIR_GENERATE(RNG,&S,&W); + + printf("Private key= 0x"); + OCT_output(&S); + printf("Public key= 0x"); + OCT_output(&W); + + BLS_BN254_SIGN(&SIG,message,&S); + printf("Signature= 0x"); + OCT_output(&SIG); + + //message[7]='f'; // change the message + + res=BLS_BN254_VERIFY(&SIG,message,&W); + if (res==BLS_OK) printf("Signature is OK\n"); + else printf("Signature is *NOT* OK\n"); + return res; +} + +#if CHUNK==32 || CHUNK==64 + +int bls_BLS383(csprng *RNG) +{ + int res; + char s[BGS_BLS383],w[4*BFS_BLS383],sig[BFS_BLS383+1]; + octet S= {0,sizeof(s),s}; + octet W= {0,sizeof(w),w}; + octet SIG= {0,sizeof(sig),sig}; + + BLS_BLS383_KEY_PAIR_GENERATE(RNG,&S,&W); + + printf("Private key= 0x"); + OCT_output(&S); + printf("Public key= 0x"); + OCT_output(&W); + + BLS_BLS383_SIGN(&SIG,message,&S); + printf("Signature= 0x"); + OCT_output(&SIG); + + //message[7]='f'; // change the message + + res=BLS_BLS383_VERIFY(&SIG,message,&W); + if (res==BLS_OK) printf("Signature is OK\n"); + else printf("Signature is *NOT* OK\n"); + return res; +} + +int bls_BLS24(csprng *RNG) +{ + int res; + char s[BGS_BLS24],w[8*BFS_BLS24],sig[BFS_BLS24+1]; + octet S= {0,sizeof(s),s}; + octet W= {0,sizeof(w),w}; + octet SIG= {0,sizeof(sig),sig}; + + BLS_BLS24_KEY_PAIR_GENERATE(RNG,&S,&W); + + printf("Private key= 0x"); + OCT_output(&S); + printf("Public key= 0x"); + OCT_output(&W); + + BLS_BLS24_SIGN(&SIG,message,&S); + printf("Signature= 0x"); + OCT_output(&SIG); + + //message[7]='f'; // change the message + + res=BLS_BLS24_VERIFY(&SIG,message,&W); + if (res==BLS_OK) printf("Signature is OK\n"); + else printf("Signature is *NOT* OK\n"); + return res; +} + +int bls_BLS48(csprng *RNG) +{ + int res; + char s[BGS_BLS48],w[16*BFS_BLS48],sig[BFS_BLS48+1]; + octet S= {0,sizeof(s),s}; + octet W= {0,sizeof(w),w}; + octet SIG= {0,sizeof(sig),sig}; + + BLS_BLS48_KEY_PAIR_GENERATE(RNG,&S,&W); + + printf("Private key= 0x"); + OCT_output(&S); + printf("Public key= 0x"); + OCT_output(&W); + + BLS_BLS48_SIGN(&SIG,message,&S); + printf("Signature= 0x"); + OCT_output(&SIG); + + //message[7]='f'; // change the message + + res=BLS_BLS48_VERIFY(&SIG,message,&W); + if (res==BLS_OK) printf("Signature is OK\n"); + else printf("Signature is *NOT* OK\n"); + return res; +} + +#endif + +int main() +{ + int i,res; + unsigned long ran; + + char raw[100]; + octet RAW= {0,sizeof(raw),raw}; + csprng RNG; // Crypto Strong RNG + + 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("%d bit build\n",CHUNK); + + printf("Testing BLS signature for curve BN254\n"); + bls_BN254(&RNG); + +#if CHUNK!=16 + printf("\nTesting BLS signature for curve BLS383\n"); + bls_BLS383(&RNG); + + printf("\nTesting BLS signature for curve BLS24\n"); + bls_BLS24(&RNG); + + printf("\nTesting BLS signature for curve BLS48\n"); + bls_BLS48(&RNG); +#endif + + KILL_CSPRNG(&RNG); +} + + http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version3/c/testnhs.c ---------------------------------------------------------------------- diff --git a/version3/c/testnhs.c b/version3/c/testnhs.c new file mode 100644 index 0000000..dca7925 --- /dev/null +++ b/version3/c/testnhs.c @@ -0,0 +1,71 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +/* test driver and function exerciser for NewHope Functions */ + +// See https://eprint.iacr.org/2016/1157 (Alkim, Ducas, Popplemann and Schwabe) + +/* gcc -O2 testnhs.c amcl.a -o testnhs.exe */ + +#include <stdio.h> +#include <time.h> +#include "newhope.h" + +int main() +{ + int i,ii,j,err; + unsigned long ran; + char raw[100]; + csprng SRNG,CRNG; + RAND_clean(&SRNG); RAND_clean(&CRNG); + char s[1792],sb[1824],uc[2176],keyA[32],keyB[32]; + + octet S= {0,sizeof(s),s}; + octet SB= {0,sizeof(sb),sb}; + octet UC= {0,sizeof(uc),uc}; + octet KEYA={0,sizeof(keyA),keyA}; + octet KEYB={0,sizeof(keyB),keyB}; + +// initialise random number generators + time((time_t *)&ran); + + raw[0]=ran; + raw[1]=ran>>8; + raw[2]=ran>>16; + raw[3]=ran>>24; + + for (i=4;i<100;i++) raw[i]=i+1; + RAND_seed(&SRNG,100,raw); + for (i=4;i<100;i++) raw[i]=i+2; + RAND_seed(&CRNG,100,raw); +// NewHope Simple key exchange + + NHS_SERVER_1(&SRNG,&SB,&S); + NHS_CLIENT(&CRNG,&SB,&UC,&KEYB); + NHS_SERVER_2(&S,&UC,&KEYA); + + printf("Alice key= 0x"); + OCT_output(&KEYA); + printf("Bob's key= 0x"); + OCT_output(&KEYB); + + return 0; +} + +
