/** * @brief Finds the Gibbs free energy for a stacking structure element. * * <PRE> * 5') [i] [i+1] ... * | | * 3') [j] [j-1] ... * </PRE> * * * @param arg_pair Pair containing nucleotides i and j indicating their positions in the sequence, where i < j. * * @todo 3 is hardcoded? << should be used from thermodynamics? */ float GibbsFreeEnergy::get_stacking_pair_element(Pair &arg_pair) { Nucleotide n1 = this->sequence[arg_pair.first]; Nucleotide n2 = this->sequence[arg_pair.second]; Pairing p = Pairing(n1, n2); float energy; if(((arg_pair.second - arg_pair.first - 1) < 3) || !p.is_canonical())///@todo figure out why 3 is not implemented as a constant ? shoudl be this->settings->min_hairpin_length? { energy = N_INFINITY; } else { Nucleotide n1p = this->sequence[arg_pair.first + 1]; Nucleotide n2p = this->sequence[arg_pair.second - 1]; Pairing p2 = Pairing(n1p, n2p); energy = this->get_stack(p, p2);///@todo figure out why in the original code this penalty was extended with eparam[0] which seemed to be a stack specific penalty of 0 } return energy; }
/** * @brief Energy function for Bulge Loop * * @section DESCRIPTION * This function returns the amount of energy for a bulge loop element. The * parameters must be: i<ip<jp<j where in particular: * * (ip-i == 1) || (j-jp == 1) * * There are two types of bulge loops: * * - Casus "5 prime bulge": * <PRE> * 5': ... i , ... , ip ... * 3': ... j , jp ... * </PRE> * * - Casus "3 prime bulge": * <PRE> * 5': ... i , ip ... * 3': ... j , ... , jp ... * </PRE> * * The corresponding energy is found in additional tables. * * * @param i Nucleotide position of the sequence, paired to j, where i < i' (ip) < j' (jp) < j * @param j Nucleotide position of the sequence, paired to i, where i < i' (ip) < j' (jp) < j * @param ip (i') Nucleotide position of the sequence, paired to j', where i < i' (ip) < j' (jp) < j * @param jp (j') Nucleotide position of the sequence, paired to i', where i < i' (ip) < j' (jp) < j * * @return Amount of corresponding Gibbs free energy if there is an bulge loop betweein (i,j) and (i',j'); infinity otherwise. * * @todo check: why check the size of only one size? -> does the algorithm ensure one side is always == 0? */ float GibbsFreeEnergy::get_bulge_loop_element(Region &r) { float energy; unsigned int n_unpaired_left = r.pair2.first - r.pair1.first; unsigned n_unpaired_right = r.pair1.second - r.pair2.second; unsigned int n_unpaired = std::max(n_unpaired_left, n_unpaired_right) - 1; if(r.pair2.second - r.pair2.first - 1 <= this->thermodynamics.minimal_hairpin_length) { energy = N_INFINITY; } #if DEBUG else if(n_unpaired < 1) { throw std::invalid_argument("GibbsFreeEnergy::get_bulge_loop_element({" + std::to_string(r.pair1.first) + "," + std::to_string(r.pair1.second) + "},{" + std::to_string(r.pair2.first) + "," + std::to_string(r.pair2.second) + "}): unnecessary invocation because of loop size"); energy = N_INFINITY; } #endif // DEBUG else { energy = this->get_loop_bulge(n_unpaired); Nucleotide n11 = this->sequence[r.pair1.first]; Nucleotide n12 = this->sequence[r.pair1.second]; Nucleotide n21 = this->sequence[r.pair2.first]; Nucleotide n22 = this->sequence[r.pair2.second]; Pairing pairing1 = Pairing(n11, n12);///@todo don't you get this penalty already when you calculate the hairpin? Pairing pairing2 = Pairing(n21, n22); if(n_unpaired == 1) { energy += this->get_stack(pairing1, pairing2);///@todo should the v matrix not be filled with the stack instead...? : return N_infinity? } else { energy += this->get_AU_penalty(pairing1);///@todo don't you get this penalty already when you calculate the hairpin? energy += this->get_AU_penalty(pairing2); ///http://unafold.math.rpi.edu/lectures/old_RNAfold/node2.html // "Because free energies are assigned to loops, and not to helices, there is no a priori way of knowing whether or not a stacked pair will be terminal or not. For this reason, the terminal AU penalty is built into the TSTACKH and TSTACKI tables. For bulge, multi-branch and exterior loops, the penalty is applied explicitly. In all of these cases, the penalty is formally assigned to the adjacent loop, although it really belongs to the helix" } } return energy; }
static EpidStatus DoPrecomputation(VerifierCtx* ctx) { EpidStatus result = kEpidErr; FfElement* e12 = NULL; FfElement* e22 = NULL; FfElement* e2w = NULL; FfElement* eg12 = NULL; Epid2Params_* params = NULL; GroupPubKey_* pub_key = NULL; PairingState* ps_ctx = NULL; if (!ctx) { return kEpidBadArgErr; } if (!ctx->epid2_params || !ctx->epid2_params->GT || !ctx->epid2_params->pairing_state || !ctx->pub_key || !ctx->e12 || !ctx->e22 || !ctx->e2w || !ctx->eg12) { return kEpidBadArgErr; } pub_key = ctx->pub_key; params = ctx->epid2_params; e12 = ctx->e12; e22 = ctx->e22; e2w = ctx->e2w; eg12 = ctx->eg12; ps_ctx = params->pairing_state; // do precomputation // 1. The verifier computes e12 = pairing(h1, g2). result = Pairing(ps_ctx, e12, pub_key->h1, params->g2); if (kEpidNoErr != result) { return result; } // 2. The verifier computes e22 = pairing(h2, g2). result = Pairing(ps_ctx, e22, pub_key->h2, params->g2); if (kEpidNoErr != result) { return result; } // 3. The verifier computes e2w = pairing(h2, w). result = Pairing(ps_ctx, e2w, pub_key->h2, pub_key->w); if (kEpidNoErr != result) { return result; } // 4. The verifier computes eg12 = pairing(g1, g2). result = Pairing(ps_ctx, eg12, params->g1, params->g2); if (kEpidNoErr != result) { return result; } return kEpidNoErr; }
/** * @brief Finds the Gibbs free energy for a hairpin loop structure element. * * @section DESCRIPTION * The hairpinloops Gibbs free energy levels are from a fixed table upto * a length of 30 unpaired nucleotides. Extrapoliation is applied for a * number of unpaired nucleotides which >= 30. * * <PRE> * 5') [i] [i+1] ... * 3') [j] [j-1] ... * </PRE> * * * @param arg_pair Pair containing nucleotides i and j indicating their positions in the sequence, where i < j. * * @return Amount of Gibbs free energy if (i,j) enclose a hairpin loop. */ float GibbsFreeEnergy::get_hairpin_loop_element(Pair &arg_pair) { unsigned int n_unpaired = arg_pair.second - arg_pair.first - 1; // The number of unpaired nucleotides between i and j: if i = j+1, unPaired = 0 float energy; if(n_unpaired < this->thermodynamics.minimal_hairpin_length) // Too small loop { energy = N_INFINITY;///@todo this should never happen and should be taken care of in the loops } else { // Loop size + Terminal mismatch(i',j') //energy = this->get_loop_hairpin(n_unpaired); Nucleotide i = this->sequence[arg_pair.first]; Nucleotide j = this->sequence[arg_pair.second]; Pairing pairing = Pairing(i, j); energy = this->get_loop_hairpin(n_unpaired) + this->get_tstackh(pairing.type, this->sequence[arg_pair.first + 1], this->sequence[arg_pair.second - 1]); // Loop-sequence specific penalty switch(n_unpaired) { case 3: { Sequence sub_sequence = this->sequence.subseq(arg_pair.first, arg_pair.second); ///@todo AU penalty? energy += this->get_triloop(sub_sequence); break; } case 4: { Sequence sub_sequence = this->sequence.subseq(arg_pair.first, arg_pair.second); energy += this->get_tloop(sub_sequence); break; } } energy += this->get_poly_C_loop_penalty(arg_pair, n_unpaired); energy += this->get_GGG_U_loop_penalty(arg_pair); } return energy; }
EpidStatus EpidSignBasic(MemberCtx const* ctx, void const* msg, size_t msg_len, void const* basename, size_t basename_len, BasicSignature* sig, BigNumStr* rnd_bsn) { EpidStatus sts = kEpidErr; EcPoint* B = NULL; EcPoint* t = NULL; // temp value in G1 EcPoint* k = NULL; EcPoint* e = NULL; FfElement* R2 = NULL; FfElement* p2y = NULL; FfElement* t1 = NULL; FfElement* t2 = NULL; FfElement* a = NULL; FfElement* b = NULL; FfElement* rx = NULL; FfElement* ra = NULL; FfElement* rb = NULL; struct p2x_t { uint32_t i; uint8_t bsn[1]; }* p2x = NULL; FfElement* t3 = NULL; // temporary for multiplication FfElement* c = NULL; uint8_t* digest = NULL; PreComputedSignature curr_presig = {0}; if (!ctx || !sig) { return kEpidBadArgErr; } if (!msg && (0 != msg_len)) { // if message is non-empty it must have both length and content return kEpidBadArgErr; } if (!basename && (0 != basename_len)) { // if basename is non-empty it must have both length and content return kEpidBadArgErr; } if (!ctx->epid2_params) { return kEpidBadArgErr; } do { FiniteField* Fp = ctx->epid2_params->Fp; SignCommitOutput commit_out = {0}; FpElemStr c_str = {0}; EcGroup* G1 = ctx->epid2_params->G1; FiniteField* GT = ctx->epid2_params->GT; FiniteField* Fq = ctx->epid2_params->Fq; PairingState* ps_ctx = ctx->epid2_params->pairing_state; const BigNumStr kOne = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; BigNumStr t1_str = {0}; BigNumStr t2_str = {0}; size_t digest_size = 0; uint16_t* rf_ctr = (uint16_t*)&ctx->rf_ctr; FfElement const* x = ctx->x; if (basename) { if (!IsBasenameAllowed(ctx->allowed_basenames, basename, basename_len)) { sts = kEpidBadArgErr; BREAK_ON_EPID_ERROR(sts); } } sts = NewEcPoint(G1, &B); BREAK_ON_EPID_ERROR(sts); sts = NewEcPoint(G1, &k); BREAK_ON_EPID_ERROR(sts); sts = NewEcPoint(G1, &t); BREAK_ON_EPID_ERROR(sts); sts = NewEcPoint(G1, &e); BREAK_ON_EPID_ERROR(sts); sts = NewFfElement(GT, &R2); BREAK_ON_EPID_ERROR(sts); sts = NewFfElement(Fq, &p2y); BREAK_ON_EPID_ERROR(sts); sts = NewFfElement(Fp, &t1); BREAK_ON_EPID_ERROR(sts); sts = NewFfElement(Fp, &t2); BREAK_ON_EPID_ERROR(sts); p2x = (struct p2x_t*)SAFE_ALLOC(sizeof(struct p2x_t) + basename_len - 1); if (!p2x) { sts = kEpidMemAllocErr; break; } sts = NewFfElement(Fp, &a); BREAK_ON_EPID_ERROR(sts); sts = NewFfElement(Fp, &b); BREAK_ON_EPID_ERROR(sts); sts = NewFfElement(Fp, &rx); BREAK_ON_EPID_ERROR(sts); sts = NewFfElement(Fp, &ra); BREAK_ON_EPID_ERROR(sts); sts = NewFfElement(Fp, &rb); BREAK_ON_EPID_ERROR(sts); sts = MemberGetPreSig((MemberCtx*)ctx, &curr_presig); BREAK_ON_EPID_ERROR(sts); // 3. If the pre-computed signature pre-sigma exists, the member // loads (B, K, T, a, b, rx, rf, ra, rb, R1, R2) from // pre-sigma. Refer to Section 4.4 for the computation of // these values. sts = ReadFfElement(Fp, &curr_presig.a, sizeof(curr_presig.a), a); BREAK_ON_EPID_ERROR(sts); sts = ReadFfElement(Fp, &curr_presig.b, sizeof(curr_presig.b), b); BREAK_ON_EPID_ERROR(sts); sts = ReadFfElement(Fp, &curr_presig.rx, sizeof(curr_presig.rx), rx); BREAK_ON_EPID_ERROR(sts); sts = ReadFfElement(Fp, &curr_presig.ra, sizeof(curr_presig.ra), ra); BREAK_ON_EPID_ERROR(sts); sts = ReadFfElement(Fp, &curr_presig.rb, sizeof(curr_presig.rb), rb); BREAK_ON_EPID_ERROR(sts); // If the basename is provided, use it, otherwise use presig B if (basename) { // 3.a. The member computes (B, i2, y2) = G1.tpmHash(bsn). sts = EcHash(G1, basename, basename_len, ctx->hash_alg, B, &p2x->i); BREAK_ON_EPID_ERROR(sts); p2x->i = htonl(p2x->i); sts = WriteEcPoint(G1, B, &commit_out.B, sizeof(commit_out.B)); BREAK_ON_EPID_ERROR(sts); sts = ReadFfElement(Fq, &commit_out.B.y, sizeof(commit_out.B.y), p2y); BREAK_ON_EPID_ERROR(sts); // b.i. (KTPM, LTPM, ETPM, counterTPM) = TPM2_Commit(P1=h1,(s2, y2) = (i2 // || bsn, y2)). // b.ii.K = KTPM. if (0 != memcpy_S((void*)p2x->bsn, basename_len, basename, basename_len)) { sts = kEpidBadArgErr; break; } sts = Tpm2Commit(ctx->tpm2_ctx, ctx->h1, p2x, sizeof(p2x->i) + basename_len, p2y, k, t, e, (uint16_t*)&ctx->rf_ctr); BREAK_ON_EPID_ERROR(sts); sts = WriteEcPoint(G1, k, &commit_out.K, sizeof(commit_out.K)); BREAK_ON_EPID_ERROR(sts); // c.i. The member computes R1 = LTPM. sts = WriteEcPoint(G1, t, &commit_out.R1, sizeof(commit_out.R1)); BREAK_ON_EPID_ERROR(sts); // c.ii. e12rf = pairing(ETPM, g2) sts = Pairing(ps_ctx, e, ctx->epid2_params->g2, R2); BREAK_ON_EPID_ERROR(sts); // c.iii. R2 = GT.sscmMultiExp(ea2, t1, e12rf, 1, e22, t2, e2w,ra). // 4.i. The member computes t1 = (- rx) mod p. sts = FfNeg(Fp, rx, t1); BREAK_ON_EPID_ERROR(sts); // 4.j. The member computes t2 = (rb - a * rx) mod p. sts = FfMul(Fp, a, rx, t2); BREAK_ON_EPID_ERROR(sts); sts = FfNeg(Fp, t2, t2); BREAK_ON_EPID_ERROR(sts); sts = FfAdd(Fp, rb, t2, t2); BREAK_ON_EPID_ERROR(sts); sts = WriteFfElement(Fp, t1, &t1_str, sizeof(t1_str)); BREAK_ON_EPID_ERROR(sts); sts = WriteFfElement(Fp, t2, &t2_str, sizeof(t2_str)); BREAK_ON_EPID_ERROR(sts); { FfElement const* points[4]; BigNumStr const* exponents[4]; points[0] = ctx->ea2; points[1] = R2; points[2] = ctx->e22; points[3] = ctx->e2w; exponents[0] = &t1_str; exponents[1] = &kOne; exponents[2] = &t2_str; exponents[3] = (BigNumStr*)&curr_presig.ra; sts = FfMultiExp(GT, points, exponents, COUNT_OF(points), R2); BREAK_ON_EPID_ERROR(sts); } sts = WriteFfElement(GT, R2, &commit_out.R2, sizeof(commit_out.R2)); BREAK_ON_EPID_ERROR(sts); // d. The member over-writes the counterTPM, B, K, R1 and R2 values. } else { if (!rnd_bsn) { sts = kEpidBadArgErr; break; } sts = ReadEcPoint(G1, &curr_presig.B, sizeof(curr_presig.B), B); BREAK_ON_EPID_ERROR(sts); commit_out.B = curr_presig.B; commit_out.K = curr_presig.K; commit_out.R1 = curr_presig.R1; ((MemberCtx*)ctx)->rf_ctr = curr_presig.rf_ctr; commit_out.R2 = curr_presig.R2; *rnd_bsn = curr_presig.rnd_bsn; } commit_out.T = curr_presig.T; sts = HashSignCommitment(Fp, ctx->hash_alg, &ctx->pub_key, &commit_out, msg, msg_len, &c_str); BREAK_ON_EPID_ERROR(sts); digest_size = EpidGetHashSize(ctx->hash_alg); digest = (uint8_t*)SAFE_ALLOC(digest_size); if (!digest) { sts = kEpidNoMemErr; break; } memcpy_S(digest + digest_size - sizeof(c_str), sizeof(c_str), &c_str, sizeof(c_str)); sts = NewFfElement(Fp, &t3); BREAK_ON_EPID_ERROR(sts); sts = NewFfElement(Fp, &c); BREAK_ON_EPID_ERROR(sts); sts = ReadFfElement(Fp, &c_str, sizeof(c_str), c); BREAK_ON_EPID_ERROR(sts); // 7. The member computes sx = (rx + c * x) mod p. sts = FfMul(Fp, c, x, t3); BREAK_ON_EPID_ERROR(sts); sts = FfAdd(Fp, rx, t3, t3); BREAK_ON_EPID_ERROR(sts); sts = WriteFfElement(Fp, t3, &sig->sx, sizeof(sig->sx)); BREAK_ON_EPID_ERROR(sts); // 8. The member computes sf = (rf + c * f) mod p. sts = Tpm2Sign(ctx->tpm2_ctx, digest, digest_size, *rf_ctr, NULL, t3); BREAK_ON_EPID_ERROR(sts); sts = WriteFfElement(Fp, t3, &sig->sf, sizeof(sig->sf)); BREAK_ON_EPID_ERROR(sts); // 9. The member computes sa = (ra + c * a) mod p. sts = FfMul(Fp, c, a, t3); BREAK_ON_EPID_ERROR(sts); sts = FfAdd(Fp, ra, t3, t3); BREAK_ON_EPID_ERROR(sts); sts = WriteFfElement(Fp, t3, &sig->sa, sizeof(sig->sa)); BREAK_ON_EPID_ERROR(sts); // 10. The member computes sb = (rb + c * b) mod p. sts = FfMul(Fp, c, b, t3); BREAK_ON_EPID_ERROR(sts); sts = FfAdd(Fp, rb, t3, t3); BREAK_ON_EPID_ERROR(sts); sts = WriteFfElement(Fp, t3, &sig->sb, sizeof(sig->sb)); BREAK_ON_EPID_ERROR(sts); sig->B = commit_out.B; sig->K = commit_out.K; sig->T = commit_out.T; sig->c = c_str; sts = kEpidNoErr; } while (0); if (sts != kEpidNoErr) { (void)Tpm2ReleaseCounter(ctx->tpm2_ctx, (uint16_t)ctx->rf_ctr); (void)Tpm2ReleaseCounter(ctx->tpm2_ctx, curr_presig.rf_ctr); } else if (basename) { (void)Tpm2ReleaseCounter(ctx->tpm2_ctx, curr_presig.rf_ctr); } EpidZeroMemory(&curr_presig, sizeof(curr_presig)); DeleteEcPoint(&B); DeleteEcPoint(&k); DeleteEcPoint(&t); DeleteEcPoint(&e); DeleteFfElement(&R2); DeleteFfElement(&p2y); DeleteFfElement(&t1); DeleteFfElement(&t2); DeleteFfElement(&a); DeleteFfElement(&b); DeleteFfElement(&rx); DeleteFfElement(&ra); DeleteFfElement(&rb); SAFE_FREE(p2x); DeleteFfElement(&t3); DeleteFfElement(&c); SAFE_FREE(digest); return sts; }
// implements section 3.2.2 "Validation of Private Key" from // Intel(R) EPID 2.0 Spec bool EpidIsPrivKeyInGroup(GroupPubKey const* pub_key, PrivKey const* priv_key) { bool result; // Intel(R) EPID Parameters Epid2Params_* params = NULL; PairingState* ps = NULL; // private key EcPoint* a_pt = NULL; // an element in G1 FfElement* x_el = NULL; // an integer between [1, p-1] FfElement* f_el = NULL; // an integer between [1, p-1] // public key EcPoint* h1_pt = NULL; // an element in G1 EcPoint* h2_pt = NULL; // an element in G1 EcPoint* w_pt = NULL; // an element in G2 // local variables EcPoint* t1_pt = NULL; // an element in G2 EcPoint* t2_pt = NULL; // an element in G1 FfElement* t3_el = NULL; // an element in GT FfElement* t4_el = NULL; // an element in GT if (!pub_key || !priv_key) { return false; } do { EpidStatus sts; EcGroup* G1 = NULL; EcGroup* G2 = NULL; FiniteField* GT = NULL; FiniteField* Fp = NULL; BigNumStr t_str = {0}; sts = CreateEpid2Params(¶ms); if (kEpidNoErr != sts) { result = false; break; } G1 = params->G1; G2 = params->G2; GT = params->GT; Fp = params->Fp; sts = WriteBigNum(params->t, sizeof(t_str), &t_str); if (kEpidNoErr != sts) { result = false; break; } sts = NewPairingState(G1, G2, GT, &t_str, params->neg, &ps); if (kEpidNoErr != sts) { result = false; break; } // Load private key sts = NewEcPoint(G1, &a_pt); if (kEpidNoErr != sts) { result = false; break; } sts = ReadEcPoint(G1, &priv_key->A, sizeof(priv_key->A), a_pt); if (kEpidNoErr != sts) { result = false; break; } sts = NewFfElement(Fp, &x_el); if (kEpidNoErr != sts) { result = false; break; } sts = ReadFfElement(Fp, &priv_key->x, sizeof(priv_key->x), x_el); if (kEpidNoErr != sts) { result = false; break; } sts = NewFfElement(Fp, &f_el); if (kEpidNoErr != sts) { result = false; break; } sts = ReadFfElement(Fp, &priv_key->f, sizeof(priv_key->f), f_el); if (kEpidNoErr != sts) { result = false; break; } // Load public key sts = NewEcPoint(G1, &h1_pt); if (kEpidNoErr != sts) { result = false; break; } sts = ReadEcPoint(G1, &pub_key->h1, sizeof(pub_key->h1), h1_pt); if (kEpidNoErr != sts) { result = false; break; } sts = NewEcPoint(G1, &h2_pt); if (kEpidNoErr != sts) { result = false; break; } sts = ReadEcPoint(G1, &pub_key->h2, sizeof(pub_key->h2), h2_pt); if (kEpidNoErr != sts) { result = false; break; } sts = NewEcPoint(G2, &w_pt); if (kEpidNoErr != sts) { result = false; break; } sts = ReadEcPoint(G2, &pub_key->w, sizeof(pub_key->w), w_pt); if (kEpidNoErr != sts) { result = false; break; } // local variables sts = NewEcPoint(G2, &t1_pt); if (kEpidNoErr != sts) { result = false; break; } sts = NewEcPoint(G1, &t2_pt); if (kEpidNoErr != sts) { result = false; break; } sts = NewFfElement(GT, &t3_el); if (kEpidNoErr != sts) { result = false; break; } sts = NewFfElement(GT, &t4_el); if (kEpidNoErr != sts) { result = false; break; } // Step 1. The member verifies that the gid in the public key matches the // gid in the private key. if (0 != memcmp(&pub_key->gid, &priv_key->gid, sizeof(priv_key->gid))) { result = false; break; } // Step 2. The member computes t1 = G2.sscmExp(g2, x). sts = EcSscmExp(G2, params->g2, (BigNumStr const*)&priv_key->x, t1_pt); if (kEpidNoErr != sts) { result = false; break; } // Step 3. The member computes t1 = G2.mul(t1, w). sts = EcMul(G2, t1_pt, w_pt, t1_pt); if (kEpidNoErr != sts) { result = false; break; } // Step 4. The member computes t3 = pairing(A, t1). sts = Pairing(ps, t3_el, a_pt, t1_pt); if (kEpidNoErr != sts) { result = false; break; } // Step 5. The member computes t2 = G1.sscmExp(h1, f). sts = EcSscmExp(G1, h1_pt, (BigNumStr const*)&priv_key->f, t2_pt); if (kEpidNoErr != sts) { result = false; break; } // Step 6. The member computes t2 = G1.mul(t2, g1). sts = EcMul(G1, t2_pt, params->g1, t2_pt); if (kEpidNoErr != sts) { result = false; break; } // Step 7. The member computes t4 = pairing(t2, g2). sts = WriteBigNum(params->t, sizeof(t_str), &t_str); if (kEpidNoErr != sts) { result = false; break; } sts = Pairing(ps, t4_el, t2_pt, params->g2); if (kEpidNoErr != sts) { result = false; break; } // Step 8. If GT.isEqual(t3, t4) = false, reports bad private key. sts = FfIsEqual(GT, t3_el, t4_el, &result); if (kEpidNoErr != sts) { result = false; break; } } while (0); // local variables DeleteFfElement(&t4_el); DeleteFfElement(&t3_el); DeleteEcPoint(&t2_pt); DeleteEcPoint(&t1_pt); // public key DeleteEcPoint(&w_pt); DeleteEcPoint(&h2_pt); DeleteEcPoint(&h1_pt); // private key DeleteFfElement(&f_el); DeleteFfElement(&x_el); DeleteEcPoint(&a_pt); // Intel(R) EPID Parameters DeletePairingState(&ps); DeleteEpid2Params(¶ms); return result; }
/** * @brief Energy function for Interior Loop * * @section DESCRIPTION * <PRE> * 5': i ... i' ... : 3' * 3': j ... j' ... : 5' * </PRE> * * @todo Check code for: * - loop contains end or beginning of sequence * - loop internal loop < min hairpin loop? * - use switches * * @param arg_region as region with Nucleotides i (pair1.first), j (pair1.second), i') and j' as positions of the sequence, where i paired to j, i' to j' and where i < i' < j' < j * * @return Amount of corresponding Gibbs free energy if there is an internal/interior loop betweein (i,j) and (i',j'); infinity otherwise. */ float GibbsFreeEnergy::get_interior_loop_element(Region &arg_region) { unsigned int n_unpaired; signed int n_asym; float energy = 0.0; unsigned int l1 = arg_region.pair2.first - arg_region.pair1.first; unsigned int l2 = arg_region.pair1.second - arg_region.pair2.second; //{i}{i'}.. -> l1 = 2 - 1 = 1 //{j}{j'}.. -> l2 = 8 - 9 = 1 //nup = 1 + 1 - 2 = 0 (correct) n_unpaired = l1 + l2 - 2;// saves one CPU operation ///@todo the following conversion is WEIRD but seems to solve the error ///Only the results should be converted, so max(l1,l2) , min(l1,l2) and make negative if l2 > l1 n_asym = ((signed int) l1 - (signed int) l2); // saves two CPU operations // 5') [i] ... [...] [i'] ... (3' // | | // 3') [j] ... [...] [j'] ... (5' if(arg_region.pair2.second - arg_region.pair2.first - 1 <= this->thermodynamics.minimal_hairpin_length)///@todo arg_region.pair2.size() + test { energy = N_INFINITY; } else if(n_unpaired > 4 || abs(n_asym) > 1) { Nucleotide ni = this->sequence[arg_region.pair1.first]; Nucleotide nj = this->sequence[arg_region.pair1.second]; Nucleotide nip = this->sequence[arg_region.pair2.first]; Nucleotide njp = this->sequence[arg_region.pair2.second]; Pairing pairing1 = Pairing(ni, nj); Pairing pairing2 = Pairing(njp, nip); // I and J are switched because 5' and 3' rotate after a hairpin //@todo this would mean that 2,2 loops get an equal penalty as 1,3 and 3,1 ? energy += this->get_loop_interior(n_unpaired); // tstki example: // // [x1]{R1}[y2] // 5') xxxG Axxxh // | | h // 3') xxxC Uxxxh // [x2]{R2}[y1] // // {h} and {x} are nucleotides that don't matter of which h represent the hairpin. // // G-C is the first pair (5' -> 3') // U-A is the second pair (5' -> 3') // // For this example you want to find the stacking panalties for forward: [G-C][x1][x2] // And the 'reverse' stack: [U-A][y1][y2] // // This is done in the following two lines: energy += this->get_tstacki(pairing1, this->sequence[arg_region.pair1.first + 1], this->sequence[arg_region.pair1.second - 1]); energy += this->get_tstacki(pairing2, this->sequence[arg_region.pair2.second + 1], this->sequence[arg_region.pair2.first - 1]); // watch out for 5' <-> 3' rotation: (jp + 1) and (ip - 1) // Asymetrical penalty energy += std::min( this->get_miscloop(MISCLOOP_ASYMETRIC_INTENRAL_LOOP), ( (float) abs(n_asym) * this->get_poppen( std::min( (unsigned int) this->thermodynamics.poppen_p.size(), std::min( l1, l2 ) ) - 1 ) ) ); } else { ///@todo SWITCH(n_unpaired) // 5') [i] [i+1] [i'] // | | // 3') [j] [j-1] [j'] if(n_unpaired == 2 && n_asym == 0) { Nucleotide ni = this->sequence[arg_region.pair1.first]; Nucleotide nj = this->sequence[arg_region.pair1.second]; Nucleotide nip = this->sequence[arg_region.pair2.first]; Nucleotide njp = this->sequence[arg_region.pair2.second]; Pairing pairing1 = Pairing(ni, nj); Pairing pairing2 = Pairing(nip, njp); ///@todo double check this order in the .dat file #if DEBUG if(pairing2.type == PairingType::None) { fprintf(stderr, "GibbsFreeEnergy::get_interior_loop_element - Requesting energy for interior loop enclosing with non canonical pairing [%i,%i].\n", arg_region.pair2.first, arg_region.pair2.second); energy += N_INFINITY; } else { energy += this->get_int11(pairing1.type, pairing2.type, this->sequence[arg_region.pair1.first + 1], this->sequence[arg_region.pair1.second - 1]); } #else energy += this->get_int11(pairing1.type, pairing2.type, this->sequence[arg_region.pair1.first + 1], this->sequence[arg_region.pair1.second - 1]); #endif //DEBUG } // 5') [i] [i+1] [i'] // | | // 3') [j] [j-1] [j-2] [j'] else if(n_unpaired == 3 && n_asym == -1) { Nucleotide ni = this->sequence[arg_region.pair1.first]; Nucleotide nj = this->sequence[arg_region.pair1.second]; Nucleotide nip = this->sequence[arg_region.pair2.first]; Nucleotide njp = this->sequence[arg_region.pair2.second]; Pairing pairing1 = Pairing(ni, nj); Pairing pairing2 = Pairing(nip, njp); energy += this->get_int21( pairing1.type, pairing2.type, this->sequence[arg_region.pair1.first + 1], this->sequence[arg_region.pair1.second - 1], this->sequence[arg_region.pair1.second - 2]); // checked : correct } // The situation we encounter is: // 5') [i] [i+1] [i+2] [i'] ... (3' // | | // 3') [j] [j-1] [j'] ... (5' // // If we rotate it 180 degrees, we get: // // 5') [j'] [j-1] [j] (3' // | | // 3') [i'] [i+2] [i+1] [i] (5' // // And we can make use of the same energy vector else if(n_unpaired == 3 && n_asym == 1) { Nucleotide ni = this->sequence[arg_region.pair1.first]; Nucleotide nj = this->sequence[arg_region.pair1.second]; Nucleotide nip = this->sequence[arg_region.pair2.first]; Nucleotide njp = this->sequence[arg_region.pair2.second]; Pairing pairing1 = Pairing(njp, nip); // Rotated Pairing pairing2 = Pairing(nj, ni); // Rotated energy += this->thermodynamics.int21 [pairing1.type] [pairing2.type] [this->sequence[arg_region.pair2.second + 1]] [this->sequence[arg_region.pair2.first - 1]] [this->sequence[arg_region.pair2.first - 2]]; } // 5') [i] [i+1] [i+2] [i'] (3' // | | // 3') [j] [j-1] [j-2] [j'] (5' else if(n_unpaired == 4 && n_asym == 0)//@todo figure out whether n_asym must be checked - if it would be 2, it would be a bulge loop and shouldn't reach this point. Also, the first if statement contains "|| abs(n_asym) > 1" which is always true if n_unpaired == 4 and n_asym != 0 { Nucleotide ni = this->sequence[arg_region.pair1.first]; Nucleotide nj = this->sequence[arg_region.pair1.second]; Nucleotide nip = this->sequence[arg_region.pair2.first]; Nucleotide njp = this->sequence[arg_region.pair2.second]; Pairing pairing1 = Pairing(ni, nj); Pairing pairing2 = Pairing(nip, njp); energy += this->thermodynamics.int22 [pairing1.type] [pairing2.type] [this->sequence[arg_region.pair1.first + 1]] [this->sequence[arg_region.pair1.second - 1]] [this->sequence[arg_region.pair1.first + 2]] [this->sequence[arg_region.pair1.second - 2]]; } else//@todo figure out when this should happen - probably never << probably when very small loops are requested { energy = N_INFINITY; } } return energy; }