void CLyapWolfMethod::orthonormalize() { if (mNumExp < 1) return; //TODO generalize C_FLOAT64 *dbl, *dblEnd; dbl = mVariables.array() + mSystemSize; dblEnd = dbl + mSystemSize; mNorms[0] = norm(dbl, dblEnd); scalarmult(dbl, dblEnd, 1 / mNorms[0]); size_t i, j; for (i = 1; i < mNumExp; ++i) { dbl += mSystemSize; dblEnd = dbl + mSystemSize; //orthogonalisation for (j = 0; j < i; ++j) { add(dbl, dblEnd, -product(dbl, dblEnd, mVariables.array() + (j + 1)*mSystemSize), mVariables.array() + (j + 1)*mSystemSize); } //normalisation mNorms[i] = norm(dbl, dblEnd); scalarmult(dbl, dblEnd, 1 / mNorms[i]); } }
//connect of originator, send X' short ike_run_originator(unsigned char* data) { unsigned char* p=data+4; //in/out ptr cc->cnt_in=3; //start IKE as originator //destination public key is preset in CC->B ike_rand(cc->x, 32); //originator's private x in cc->x ike_rand(cc->U, 32); //originator's private u in cc->U scalarmult(cc->T,cc->x, cc->B); //their tag Tb = B*x in cc->T sh_ini(); sh_upd(cc->T, 32); //Tb sh_xof(); sh_out(cc->C, 32); //H(Tb) r2p(cc->S, cc->C); //speke base P = E(Tb) scalarmult(cc->C, cc->U, cc->S); //our speke key U=u*P: our U in cc->C scalarmultbase(p, cc->x); //our X=G*x sh_ini(); sh_upd(cc->C, 32); //hash our U sh_xof(); sh_crp(p, 32); //mask our X (for commitment reason): X'=X^H(U) //output X' data[0]=TR_Q; return IKE_LEN; }
//originator rcvd V, send A short ike_5(unsigned char* data) { unsigned char cp; short i; unsigned char* p=data+4; //in/out ptr cc->cnt_in+=2; //receive V //check speke keys not same cp=ike_cmp(cc->C, p); //compare our and their SPEKE public keys ike_rand(cc->T, 32); //get random for(i=0;i<32;i++) cc->U[i]^=(cc->T[i]&cp); //mask our SPEKE secret if their key invalid scalarmult(cc->C,cc->U, p); //compute speke secret x1*y1*E(X*b) scalarmult(cc->U,cc->x, cc->B); //compute their tag Tb=B*x //mask A memcpy(p, cc->A, 32); //our A sh_ini(); sh_upd(cc->C, 32); //speke secret sh_xof(); sh_out(cc->C, 32); //replace SPEKE secret by it's hash sh_crp(p, 32); //encrypt A to A' //send A' data[0]=TR_Q; return IKE_LEN; }
//acceptor rcvd A', send DH fingerprint C short ike_8(unsigned char* data) { unsigned char* p=data+4; //in/out ptr cc->cnt_in+=2; //receive A' //unmask A sh_ini(); sh_upd(cc->C, 32); //use speke secret sh_xof(); sh_out(cc->C, 32); //replace SPEKE secret by it's hash sh_crp(p, 32); //decrypt A memcpy(cc->B, p, 32); //A scalarmult(cc->U,cc->x, cc->B); //Ta=A*y (their tag) //compute fingerprint of DH secret sh_ini(); sh_upd(cc->S, 32); //DH secret sh_upd((char*)"$DH:SALT", 8); //salt sh_xof(); sh_out(p, 32); //C //send C data[0]=TR_Q; return IKE_LEN; }
void stemu(unsigned char* data) { unsigned char* p=data+4; //their efemeral Y unsigned char tag[32]; scalarmult(tag, cc->a, p); //compute tag Ta=Y*a memcpy(p, tag, 32); //output tag }
//acceptor rcvd U, unmask X and send to ST short ike_4(unsigned char* data) { unsigned char* p=data+4; //in/out ptr cc->cnt_in+=2; //receive U scalarmult(cc->C, cc->U, p); //compute SPEKE secret S=U^v to cc->C //unmask their X (was masked for commitment reason) sh_ini(); sh_upd(p, 32); //hash their speke key U sh_xof(); sh_crp(cc->Y, 32); //unmask X: X=X'^H(U) store their efemeral X in cc->Y scalarmult(cc->S, cc->x, cc->Y); //compute DH secret = X*y to cc->S //output X to ST memcpy(p, cc->Y, 32); //output their efemeral X to ST for safely compute tag Tb=X*b data[0]=ST_SEC; return IKE_LEN; }
//originator rcvd Y, send U short ike_3(unsigned char* data) { unsigned char* p=data+4; //in/out ptr cc->cnt_in+=2; //receive Y memcpy(cc->Y, p, 32); //store their efemeral Y in cc->Y scalarmult(cc->S, cc->x, cc->Y); //compute DH secret = Y*x to cc->S memcpy(p, cc->C, 32); //output our speke key U from cc->C //output U data[0]=TR_Q; return IKE_LEN; }
//compute obfuscation shared secret and set to TR on pre-IKE stage short ike_obf(unsigned char* data) { unsigned char* p=data+4; //in/out ptr if(cc->cnt_in) return 0; //only in iddle state! cc->cnt_in=1; //set state! r2p(cc->Y, p); //compute point form their representation scalarmult(p, cc->U, cc->Y); //compute shared secret sh_ini(); sh_upd(p, 32); //hash secret sh_xof(); sh_out(p, 32); //output material sh_clr(); data[0]=TR_OBF; //output to TR return IKE_LEN; }
//acceptor rcvd tag X*b from ST, send V short ike_6(unsigned char* data) { unsigned char* p=data+4; //in/out ptr cc->cnt_in+=2; //receive tag from ST //if ST fail input is random generated by ST memcpy(cc->T, p, 32); //save our tag X*b //compute speke base point using Tb sh_ini(); sh_upd(cc->T, 32); //Tb=X*b sh_xof(); sh_out(p, 32); //H(Tb) r2p(cc->Y, p); //P=E(Tb) //SPEKE point scalarmult(p,cc->U, cc->Y); //V=v*P //output V data[0]=TR_Q; return IKE_LEN; }
//self-test of assemler cryptographic procedures (x25519_mult, x25519_elligator2, keccak-800 sponge) //returns 1 is OK, 0 is failure unsigned char ike_test(void) { #define TST_VECTOR 0xAF91E972 unsigned int i,j; unsigned char pub[32]; unsigned char key[32]; unsigned char sec[32]; unsigned char c=0; //elligator2 test for(i=0;i<16;i++) { sh_ini(); sh_upd(&i, 4); //absorb counter sh_xof(); //permute sh_out(sec, 32); //output secret key p2r(key, sec); //correct sec and output representation r2p(pub, key); //convert representation to point scalarmultbase(key, sec); //compute point in usual was: must be the same for(j=0;j<32;j++) c|=key[j]^pub[j]; } if(c) return 0; //old test memset(pub, 0x55, 32); //set initial value for(i=0;i<16;i++) //provide sequence of computing { //secret=H1(value); value^=H2(value); their_key=elligator2(value); value = their_key^secret; sh_ini(); //init shake sh_upd(&i, 4); //absorb counter sh_upd(pub, 32); //absorb value sh_xof(); //permute sh_crp(pub, 32); //update initial value sh_out(sec, 32); //output secret key r2p(key, pub); //compute curve point into their_key scalarmult(pub, sec, key); //compute public key } //compare crc32 of resulting value with precomputed vector if(TST_VECTOR ^ cr_crc32(pub, 32)) return 0; //result fail else return 1; //result ok }
int MeshEdgeElementTable::calcLineIntersections(int elem_index, short elem_dir, Point3& lstart, Point3& ldir, Point3* isec_points) { meshElementCode elem_code = getElementCode(elem_index); if (elem_code < MEC_202 || elem_code >= 303) return 0; const int* nodeIds = getNodeIds(elem_index, elem_dir); Point3& p0 = meshNodes[nodeIds[0]]; Point3& p1 = meshNodes[nodeIds[1]]; Point3& normal = normals[elem_index]; if (elem_dir == -1) scalarmult(-1, normal, normal); // Check end-point cases if ( samepoint(p0, lstart) ){ copy3(p0, *isec_points); return 1; } if ( samepoint(p1, lstart) ){ copy3(p1, *isec_points); return 1; } Point3 edge_dir, l_delta0, tmp; // Edge direction vector (normalized) edge_dir[0] = normal[1]; edge_dir[1] = -1 * normal[0]; edge_dir[2] = 0.0; // Edge length diff3(p1, p0, tmp); double edge_len = dot3(edge_dir, tmp); // Vector l_delta0 = lstart - p0 diff3(lstart, p0, l_delta0); // Check that intersection is "within" the edge // project the intersection point to the edge double t = dot3(edge_dir, l_delta0); if ( isLess(t, 0.0) || isGreater(t, edge_len) ) return 0; // Check that intersection distance from the edge is ok // project intersection point to the edge normal double d = dot3(normal, l_delta0); if (d < 0) d *= -1; if ( isGreater(d, MeshEdgeElementTable::pickingTolerance) ) return 0; // Intersection point is: p0 + t * (p1 - p0) scalarmult(t, edge_dir, tmp); add3(p0, tmp, *isec_points); return 1; }
// NOTE: This should work for all triangle elments (303 - 306), but only // if mid-edge and middle nodes are after "corner" nodes in the node list! // Return nof intersections // int MeshFaceElementTable::calcTriangleLineIntersections(int elem_index, short direction, Point3& lstart, Point3& ldir, Point3* isec_points) { // Ccw ordered nodes (if elem_dir is -1, it is from the parent2 // and nodes are cw oriented and must me reordered Point3& p0 = meshNodes[nodeIds[elem_index][0]]; Point3& p1 = meshNodes[nodeIds[elem_index][1]]; Point3& p2 = meshNodes[nodeIds[elem_index][2]]; Point3& normal = normals[elem_index]; static Point3* points[3]; points[0] = (direction >= 0)? &p0 : &p1; points[1] = (direction >= 0)? &p1 : &p0; points[2] = &p2; #if 0 // If element is looking into wrong direction // // NOTE: This makes picking much faster, so wew have to use it (unless some better // method is found), although it means that elements cannot be selected from 'inside', // which would be quite convenient in some cases! // if ( direction == 1 ) { if ( !isLess(dot3(normal, ldir), 0) ) { return 0; } } else if ( direction == -1 ) { if ( !isGreater(dot3(normal, ldir), 0) ) { return 0; } } #endif // Plane equation for the normal and a point in the plane is; // (r) dot (normal) = (r0) dot (normal) = d // So for the form Ax + By + Cz + D = 0, we have // A = normal[0], B = normal[1], C = normal[2], D = -d double D = -1 * dot3(p0, normal); double numer = dot3(normal, lstart) + D; double denom = dot3(normal, ldir); double t; // Intersection if (denom != 0) { t = - numer / denom; // Line is on the plane } else if (numer == 0) { t = 0.0; // Line is parallel,but not in the plane } else { return 0; } //-Calc intersection point from the line equation Point3 tmp; scalarmult(t, ldir, tmp); Point3 isec_point; add3(lstart, tmp, isec_point); // Finally check if intersection point // is inside the element (triangle) if ( pointInsideTriangle(isec_point, points, centers[elem_index], rSquares[elem_index]) ) { copy3(isec_point, *isec_points); return 1; } else { return 0; } }