void PrimaBinTreeVSSS::solve() { int INF = 2000000000; //вершина u предок для i вершины, т.ч. (i,u) - мин. ребро vector<int> key(size, INF), p(size, -1); vector<int> gg1(gg.size(), 0); set<pair<int, int> > T;//множесто ребер мин. остового дерева //положить в нужном порядке вершины //Приоритетная очередь вершин графа, список не задействованных вершин. set<pair<int, int> > Q; key[0] = 0;// расстояние от "корня" дерева до построенного дерева Q.insert(make_pair(0, 0)); while(!Q.empty()) { size_t v = Q.begin()->second; Q.erase(Q.begin()); if (p[v] != -1) T.insert(make_pair(v, p[v])); for (size_t u = ig[v]; u < ig[v + 1]; u++) { int k = jg[u]; if (gg[u] != 0) { if (gg[u] < key[k] && k != v) { Q.erase(make_pair(key[k], k)); p[k] = v; key[k] = gg[u]; Q.insert(make_pair(key[k], k)); } } } } for(auto& t : T) { size_t i = t.first; size_t j = t.second; for(int k = ig[i]; k < ig[i + 1]; k++) { if(jg[k] == j) gg1[k] = gg[k]; } for(int k = ig[j]; k < ig[j + 1]; k++) { if(jg[k] == i) gg1[k] = gg[k]; } } gg = gg1; }
void sm3::transform(const uint8_t* mp, uint64_t num_blks) { for (uint64_t blk = 0; blk < num_blks; blk++) { uint32_t M[16]; for (uint32_t i = 0; i < 64 / 4; i++) { M[i] = swap_uint32((reinterpret_cast<const uint32_t*>(mp)[blk * 16 + i])); } #ifdef CPPCRYPTO_DEBUG printf("M1 - M8: %08X %08X %08X %08X %08X %08X %08X %08X %08X %08X %08X %08X %08X %08X %08X %08X\n", M[0], M[1], M[2], M[3], M[4], M[5], M[6], M[7], M[8], M[9], M[10], M[11], M[12], M[13], M[14], M[15]); #endif uint32_t W[68]; uint32_t W2[64]; for (int t = 0; t <= 15; t++) W[t] = M[t]; for (int t = 16; t <= 67; t++) W[t] = p1(W[t - 16] ^ W[t - 9] ^ rotatel32(W[t - 3], 15)) ^ rotatel32(W[t - 13], 7) ^ W[t - 6]; for (int t = 0; t <= 63; t++) W2[t] = W[t] ^ W[t + 4]; uint32_t a = H[0]; uint32_t b = H[1]; uint32_t c = H[2]; uint32_t d = H[3]; uint32_t e = H[4]; uint32_t f = H[5]; uint32_t g = H[6]; uint32_t h = H[7]; #ifdef CPPCRYPTO_DEBUG printf("===============================================\n"); printf("i = %d: %08X %08X %08X %08X %08X %08X %08X %08X\n", -1, a, b, c, d, e, f, g, h); for (int i = 0; i <= 67; i++) printf("W[%d] = %08X\n", i, W[i]); for (int i = 0; i <= 63; i++) printf("W2[%d] = %08X\n", i, W2[i]); #endif for (int t = 0; t <= 15; t++) { uint32_t ss1 = rotatel32((rotatel32(a, 12) + e + rotatel32(0x79cc4519, t)), 7); uint32_t ss2 = ss1 ^ rotatel32(a, 12); uint32_t tt1 = xorf(a, b, c) + d + ss2 + W2[t]; uint32_t tt2 = xorf(e, f, g) + h + ss1 + W[t]; d = c; c = rotatel32(b, 9); b = a; a = tt1; h = g; g = rotatel32(f, 19); f = e; e = p0(tt2); #ifdef CPPCRYPTO_DEBUG printf("t = %d: %08X %08X %08X %08X %08X %08X %08X %08X (ss1=%08X ss2=%08X tt1=%08X tt2=%08X)\n", t, a, b, c, d, e, f, g, h, ss1, ss2, tt1, tt2); #endif } for (int t = 16; t <= 63; t++) { uint32_t ss1 = rotatel32((rotatel32(a, 12) + e + rotatel32(0x7a879d8a, t)), 7); uint32_t ss2 = ss1 ^ rotatel32(a, 12); uint32_t tt1 = ff1(a, b, c) + d + ss2 + W2[t]; uint32_t tt2 = gg1(e, f, g) + h + ss1 + W[t]; d = c; c = rotatel32(b, 9); b = a; a = tt1; h = g; g = rotatel32(f, 19); f = e; e = p0(tt2); #ifdef CPPCRYPTO_DEBUG printf("t = %d: %08X %08X %08X %08X %08X %08X %08X %08X (ss1=%08X ss2=%08X tt1=%08X tt2=%08X)\n", t, a, b, c, d, e, f, g, h, ss1, ss2, tt1, tt2); #endif } H[0] ^= a; H[1] ^= b; H[2] ^= c; H[3] ^= d; H[4] ^= e; H[5] ^= f; H[6] ^= g; H[7] ^= h; #ifdef CPPCRYPTO_DEBUG printf("H[0] - H[7]: %08X %08X %08X %08X %08X %08X %08X %08X\n", H[0], H[1], H[2], H[3], H[4], H[5], H[6], H[7]); #endif } }