int elgv3sign(const mpbarrett* p, const mpbarrett* n, const mpnumber* g, randomGeneratorContext* rgc, const mpnumber* hm, const mpnumber* x, mpnumber* r, mpnumber* s) { register size_t size = p->size; register mpw* temp = (mpw*) malloc((6*size+2)*sizeof(mpw)); if (temp) { /* get a random k */ mpbrnd_w(p, rgc, temp, temp+2*size); /* compute r = g^k mod p */ mpnfree(r); mpnsize(r, size); mpbpowmod_w(p, g->size, g->data, size, temp, r->data, temp+2*size); /* compute u1 = x*r mod n */ mpbmulmod_w(n, x->size, x->data, size, r->data, temp+size, temp+2*size); /* compute u2 = k*h(m) mod n */ mpbmulmod_w(n, size, temp, hm->size, hm->data, temp, temp+2*size); /* compute s = u1+u2 mod n */ mpnfree(s); mpnsize(s, n->size); mpbaddmod_w(n, size, temp, size, temp+size, s->data, temp+2*size); free(temp); return 0; } return -1; }
int dldp_pgoqGenerator_w(dldp_p* dp, randomGeneratorContext* rgc, mpw* wksp) { /* * Randomly determine a generator over the subgroup with order q */ register size_t size = dp->p.size; mpnfree(&dp->g); mpnsize(&dp->g, size); while (1) { /* get a random value h (stored into g) */ mpbrnd_w(&dp->p, rgc, dp->g.data, wksp); /* first compute h^r mod p (stored in g) */ mpbpowmod_w(&dp->p, size, dp->g.data, dp->r.size, dp->r.data, dp->g.data, wksp); if (mpisone(size, dp->g.data)) continue; return 0; } return -1; }
void mpbnrnd(const mpbarrett* b, randomGeneratorContext* rc, mpnumber* result) { register size_t size = b->size; register mpw* temp = (mpw*) malloc(size * sizeof(mpw)); mpnfree(result); mpnsize(result, size); mpbrnd_w(b, rc, result->data, temp); free(temp); }
void mpbnpowmodsld(const mpbarrett* b, const mpw* slide, const mpnumber* pow, mpnumber* y) { register size_t size = b->size; register mpw* temp = (mpw*) malloc((4*size+2) * sizeof(mpw)); mpnfree(y); mpnsize(y, size); mpbpowmodsld_w(b, slide, pow->size, pow->data, y->data, temp); free(temp); }
int elgv1sign(const mpbarrett* p, const mpbarrett* n, const mpnumber* g, randomGeneratorContext* rgc, const mpnumber* hm, const mpnumber* x, mpnumber* r, mpnumber* s) { register size_t size = p->size; register mpw* temp = (mpw*) malloc((8*size+6)*sizeof(mpw)); if (temp) { /* get a random k, invertible modulo (p-1) */ mpbrndinv_w(n, rgc, temp, temp+size, temp+2*size); /* compute r = g^k mod p */ mpnfree(r); mpnsize(r, size); mpbpowmod_w(p, g->size, g->data, size, temp, r->data, temp+2*size); /* compute x*r mod n */ mpbmulmod_w(n, x->size, x->data, r->size, r->data, temp, temp+2*size); /* compute -(x*r) mod n */ mpneg(size, temp); mpadd(size, temp, n->modl); /* compute h(m) - x*r mod n */ mpbaddmod_w(n, hm->size, hm->data, size, temp, temp, temp+2*size); /* compute s = inv(k)*(h(m) - x*r) mod n */ mpnfree(s); mpnsize(s, size); mpbmulmod_w(n, size, temp, size, temp+size, s->data, temp+2*size); free(temp); return 0; } return -1; }
void mpbnsqrmod(const mpbarrett* b, const mpnumber* x, mpnumber* result) { register size_t size = b->size; register mpw* temp = (mpw*) malloc(size * sizeof(mpw)); /* xsize must be <= b->size */ register size_t fill = 2*(size-x->size); register mpw* opnd = temp + size*2+2; if (fill) mpzero(fill, opnd); mpsqr(opnd+fill, x->size, x->data); mpnsize(result, size); mpbmod_w(b, opnd, result->data, temp); free(temp); }
void mpbnmulmod(const mpbarrett* b, const mpnumber* x, const mpnumber* y, mpnumber* result) { register size_t size = b->size; register mpw* temp = (mpw*) malloc((4*size+2) * sizeof(mpw)); /* xsize and ysize must be <= b->size */ register size_t fill = 2*size-x->size-y->size; register mpw* opnd = temp+size*2+2; mpnfree(result); mpnsize(result, size); if (fill) mpzero(fill, opnd); mpmul(opnd+fill, x->size, x->data, y->size, y->data); mpbmod_w(b, opnd, result->data, temp); free(temp); }
int main( int argc, char **argv ) { FILE *secblock; unsigned char packetType; unsigned short packetLen; unsigned char buffer[4096]; unsigned char hexrep[8192]; // for CRT computation mpbarrett psubone, qsubone; // for testing mpnumber m, cipher, decipher, holder; rsakp keypair; size_t bits = 2048; size_t pbits = (bits+1) >> 1; size_t qbits = (bits - pbits); size_t psize = MP_BITS_TO_WORDS(pbits+MP_WBITS-1); size_t qsize = MP_BITS_TO_WORDS(qbits+MP_WBITS-1); size_t pqsize = psize+qsize; mpw* temp = (mpw*) malloc((16*pqsize+6)*sizeof(mpw)); if( argc < 2 ) { printf( "usage: %s <secblock>\n", argv[0] ); exit( 1 ); } mpbzero(&psubone); mpbzero(&qsubone); secblock = fopen(argv[1], "rb"); if( secblock == NULL ) { printf( "Can't open %s\n", argv[1] ); exit(0); } packetType = fgetc(secblock); packetLen = 0; //big endianness... big16read(&packetLen, secblock); printf( "Packet type: 0x%02X\n", packetType ); printf( "Packet length: %04d\n", (int) packetLen ); // skip ahead six bytes, this includes key generation time and other attributes fread( buffer, 6, 1, secblock); rsakpInit(&keypair); big16read(&packetLen, secblock); printf( "n Packet length: %02d bits, %02d bytes\n", (int) packetLen, (int) bytesFromMpn(packetLen) ); printf( "offset: %x\n", ftell( secblock ) ); fread( buffer, bytesFromMpn(packetLen), 1, secblock ); mpbsetbin(&keypair.n, buffer, bytesFromMpn(packetLen)); mpprintln(packetLen/32, keypair.n.modl); big16read(&packetLen, secblock); printf( "e Packet length: %02d bits, %02d bytes\n", (int) packetLen, (int) bytesFromMpn(packetLen) ); printf( "offset: %x\n", ftell( secblock ) ); fread( buffer, bytesFromMpn(packetLen), 1, secblock ); mpnsetbin(&keypair.e, buffer, bytesFromMpn(packetLen)); mpprintln(keypair.e.size, keypair.e.data); packetType = fgetc(secblock); if( packetType == 0 ) { printf( "secret data is plaintext\n" ); } else { printf( "secret data is encrypted\n" ); } big16read(&packetLen, secblock); printf( "d Packet length: %02d bits, %02d bytes\n", (int) packetLen, (int) bytesFromMpn(packetLen) ); printf( "offset: %x\n", ftell( secblock ) ); fread( buffer, bytesFromMpn(packetLen), 1, secblock ); mpnsetbin(&keypair.d, buffer, bytesFromMpn(packetLen)); mpprintln(keypair.d.size, keypair.d.data); big16read(&packetLen, secblock); printf( "p Packet length: %02d bits, %02d bytes\n", (int) packetLen, (int) bytesFromMpn(packetLen) ); printf( "offset: %x\n", ftell( secblock ) ); fread( buffer, bytesFromMpn(packetLen), 1, secblock ); mpbsetbin(&keypair.p, buffer, bytesFromMpn(packetLen)); mpprintln(packetLen/32, keypair.p.modl); big16read(&packetLen, secblock); printf( "q Packet length: %02d bits, %02d bytes\n", (int) packetLen, (int) bytesFromMpn(packetLen) ); printf( "offset: %x\n", ftell( secblock ) ); fread( buffer, bytesFromMpn(packetLen), 1, secblock ); mpbsetbin(&keypair.q, buffer, bytesFromMpn(packetLen)); mpprintln(packetLen/32, keypair.q.modl); big16read(&packetLen, secblock); printf( "mystery packet length: %02d bits, %02d bytes\n", (int) packetLen, (int) bytesFromMpn(packetLen) ); printf( "offset: %x\n", ftell( secblock ) ); fread( buffer, bytesFromMpn(packetLen), 1, secblock ); mpnzero(&holder); mpnsetbin(&holder, buffer, bytesFromMpn(packetLen)); mpprintln(holder.size, holder.data); fread( buffer, 4, 1, secblock ); // advance by two bytes printf( "offset: %x\n", ftell( secblock ) ); fread( buffer, bytesFromMpn(packetLen), 1, secblock ); printf( "%s\n", buffer ); #ifdef USE_CRT // compute CRT elements /* compute p-1 */ mpbsubone(&keypair.p, temp); mpbset(&psubone, psize, temp); /* compute q-1 */ mpbsubone(&keypair.q, temp); mpbset(&qsubone, qsize, temp); /* compute dp = d mod (p-1) */ mpnsize(&keypair.dp, psize); mpbmod_w(&psubone, keypair.d.data, keypair.dp.data, temp); /* compute dq = d mod (q-1) */ mpnsize(&keypair.dq, qsize); mpbmod_w(&qsubone, keypair.d.data, keypair.dq.data, temp); /* compute qi = inv(q) mod p */ mpninv(&keypair.qi, (mpnumber*) &keypair.q, (mpnumber*) &keypair.p); #endif // now test mpnzero(&m); mpnzero(&cipher); mpnzero(&decipher); mpnsethex(&m, "d436e99569fd32a7c8a05bbc90d32c49"); printf( "Original: " ); mpprintln(m.size, m.data); rsapub(&keypair.n, &keypair.e, &m, &cipher); printf( "Encrypted: " ); mpprintln(cipher.size, cipher.data); #ifdef USE_CRT rsapricrt(&keypair.n, &keypair.p, &keypair.q, &keypair.dp, &keypair.dq, &keypair.qi, &cipher, &decipher); #else rsapri(&keypair.n, &keypair.d, &cipher, &decipher); #endif printf( "Recovered: " ); mpprintln(decipher.size, decipher.data); if (mpnex(m.size, m.data, decipher.size, decipher.data)) printf ( "results don't match\n" ); else printf ( "before and after encyrption sizes match\n" ); printf( "special test routine for STM32 validation\n" ); mpnzero(&cipher); mpnzero(&decipher); mpnsethex(&cipher, "6fa1bf55e15b47f4662f86e8fc7fadf0dc02c603c20c1090096fdbeafbd56897794ee106d0fcd8a58392ee7e14fd4e15b49c4adb02f0eebeb9587e9823e9e11048c1754c5e6ba273a08c35dd68f72bf4758b8c31dee196f683298cdbd259c28976c1459058c37be29b52589f3919dcb41cf57fd0c64796a056702be8c1f7574a005cad8b0aedb8f833d1fcfe5383b6d6695d766cc1a9a3413f7609fa18b0a1214486f8fec17febd3f4cbc177dd6f26568b715249853280c570e2ef8519f51fe78fb1978061a48fcc6730fb24e365120b54e6f4e2c3815997176167456b2a2b8f1a13b66967765fc42d4aeec2b4f8211e54ba9cbbbbfdd8ac7b2f20af8d44cd68" ); printf( "Decrypting: " ); mpprintln(cipher.size, cipher.data); rsapub(&keypair.n, &keypair.e, &cipher, &decipher); printf( "Recovered: " ); mpprintln(decipher.size, decipher.data); free(temp); return 0; }
int dsasign(const mpbarrett* p, const mpbarrett* q, const mpnumber* g, randomGeneratorContext* rgc, const mpnumber* hm, const mpnumber* x, mpnumber* r, mpnumber* s) { register size_t psize = p->size; register size_t qsize = q->size; register mpw* ptemp; register mpw* qtemp; register mpw* pwksp; register mpw* qwksp; register int rc = -1; ptemp = (mpw*) malloc((5*psize+2)*sizeof(mpw)); if (ptemp == (mpw*) 0) return rc; qtemp = (mpw*) malloc((9*qsize+6)*sizeof(mpw)); if (qtemp == (mpw*) 0) { free(ptemp); return rc; } pwksp = ptemp+psize; qwksp = qtemp+3*qsize; /* allocate r */ mpnfree(r); mpnsize(r, qsize); /* get a random k, invertible modulo q; store k @ qtemp, inv(k) @ qtemp+qsize */ mpbrndinv_w(q, rgc, qtemp, qtemp+qsize, qwksp); /* g^k mod p */ mpbpowmod_w(p, g->size, g->data, qsize, qtemp, ptemp, pwksp); /* (g^k mod p) mod q - simple modulo */ mpmod(qtemp+2*qsize, psize, ptemp, qsize, q->modl, pwksp); mpcopy(qsize, r->data, qtemp+psize+qsize); /* allocate s */ mpnfree(s); mpnsize(s, qsize); /* x*r mod q */ mpbmulmod_w(q, x->size, x->data, r->size, r->data, qtemp, qwksp); /* add h(m) mod q */ mpbaddmod_w(q, qsize, qtemp, hm->size, hm->data, qtemp+2*qsize, qwksp); /* multiply inv(k) mod q */ mpbmulmod_w(q, qsize, qtemp+qsize, qsize, qtemp+2*qsize, s->data, qwksp); rc = 0; free(qtemp); free(ptemp); return rc; }
int dldp_pgonGenerator_w(dldp_p* dp, randomGeneratorContext* rgc, mpw* wksp) { register size_t size = dp->p.size; mpnfree(&dp->g); mpnsize(&dp->g, size); while (1) { mpbrnd_w(&dp->p, rgc, dp->g.data, wksp); if (mpistwo(dp->r.size, dp->r.data)) { /* * A little math here: the only element in the group which has order 2 is (p-1); * the two group elements raised to power two which result in 1 (mod p) are thus (p-1) and 1 * * mpbrnd_w doesn't return 1 or (p-1), so the test where g^2 mod p = 1 can be safely skipped */ /* check g^q mod p*/ mpbpowmod_w(&dp->p, size, dp->g.data, dp->q.size, dp->q.modl, wksp, wksp+size); if (mpisone(size, wksp)) continue; } else { /* we can either compute g^r, g^2q and g^(qr/2) or * we first compute s = r/2, and then compute g^2s, g^2q and g^qs * * hence we first compute t = g^s * then compute t^2 mod p, and test if one * then compute t^q mod p, and test if one * then compute (g^q mod p)^2 mod p, and test if one */ /* compute s = r/2 */ mpsetx(size, wksp, dp->r.size, dp->r.data); mpdivtwo(size, wksp); /* compute t = g^s mod p */ mpbpowmod_w(&dp->p, size, dp->g.data, size, wksp, wksp+size, wksp+2*size); /* compute t^2 mod p = g^2s mod p = g^r mod p*/ mpbsqrmod_w(&dp->p, size, wksp+size, wksp+size, wksp+2*size); if (mpisone(size, wksp+size)) continue; /* compute t^q mod p = g^qs mod p */ mpbpowmod_w(&dp->p, size, wksp, dp->q.size, dp->q.modl, wksp+size, wksp+2*size); if (mpisone(size, wksp+size)) continue; /* compute g^2q mod p */ mpbpowmod_w(&dp->p, size, dp->g.data, dp->q.size, dp->q.modl, wksp, wksp+size); mpbsqrmod_w(&dp->p, size, wksp, wksp+size, wksp+2*size); if (mpisone(size, wksp+size)) continue; } return 0; } return -1; }