/** Divide a set at an item. * @param i is an item in some set * @param s is the canonical element of the set containing i * @return the pair of sets [s1,s2] obtained by dividing s into three parts, * s1,i and s2, where the keys of the items in s1 are smaller than the key * of i and keys of items in s2 are larger than the key of i */ setPair DualKeyBsts::split(item i, sset s) { setPair pair = SelfAdjBsts::split(i,s); if (pair.s1 != 0) dmin(pair.s1) += dmin(i); if (pair.s2 != 0) dmin(pair.s2) += dmin(i); dmin(i) += dkey(i); dkey(i) = 0; return pair; }
/** Join two sets at an item. * @param s1 is the canonical element of some set * @param s2 is the canonical element of some set * @param i is a singleton item with key larger than that of any item in s1, * and smaller than that of any item in s2 * @return the new set formed by combining s1, i and s2 */ sset DualKeyBsts::join(sset s1, item i, sset s2) { SelfAdjBsts::join(s1,i,s2); keytyp key2i = dmin(i) + dkey(i); if (s1 != 0) dmin(i) = min(dmin(i),dmin(s1)); if (s2 != 0) dmin(i) = min(dmin(i),dmin(s2)); dkey(i) = key2i - dmin(i); if (s1 != 0) dmin(s1) -= dmin(i); if (s2 != 0) dmin(s2) -= dmin(i); return i; }
static void spec_sync_keybundle_test(void) { const char *orig_username = "******"; /* this example is badly misleading as the shar256 base32 username must be used in reality */ const uint8_t orig_synckey[] = { 0xc7,0x1a,0xa7,0xcb,0xd8,0xb8,0x2a,0x8f, 0xf6,0xed,0xa5,0x5c,0x39,0x47,0x9f,0xd2 }; const uint8_t orig_hmac[] = { 0xbf,0x9e,0x48,0xac,0x50,0xa2,0xfc,0xc4,0x00,0xae,0x4d,0x30,0xa5,0x8d,0xc6,0xa8,0x3a,0x77,0x20,0xc3,0x2f,0x58,0xc6,0x0f,0xd9,0xd0,0x2d,0xb1,0x6e,0x40,0x62,0x16 }; const uint8_t orig_encryption[] = { 0x8d,0x07,0x65,0x43,0x0e,0xa0,0xd9,0xdb,0xd5,0x3c,0x53,0x6c,0x6c,0x5c,0x4c,0xb6,0x39,0xc0,0x93,0x07,0x5e,0xf2,0xbd,0x77,0xcd,0x30,0xcf,0x48,0x51,0x38,0xb9,0x05 }; struct nssync_crypto_keybundle *sync_keybundle; uint8_t *encryption; uint8_t *hmac; size_t length; printf("Sync keybundle creation:"); if (nssync_crypto_keybundle_new_synckey(orig_synckey, orig_username, &sync_keybundle) == NSSYNC_ERROR_OK) { printf("passed\nEncryption value:"); nssync_crypto_keybundle_get_encryption(sync_keybundle, &encryption, &length); if (memcmp(orig_encryption, encryption, length) != 0) { printf("incorrect\n"); dkey(encryption); dkey(orig_encryption); } else { printf("correct\n"); } printf("hmac value:"); nssync_crypto_keybundle_get_hmac(sync_keybundle, &hmac, &length); if (memcmp(orig_hmac, hmac, length) != 0) { printf("incorrect\n"); dkey(hmac); dkey(orig_hmac); } else { printf("correct\n"); } free(sync_keybundle); } else { printf("failed\n"); } }
/** Insert an item into a set. * @param i is a singleton item * @param s is the canonical element of some set * @return the new set that results from adding i to s */ item DualKeyBsts::insert(item i, sset s) { assert (1 <= i && i <= n && 1 <= s && s <= n && i != s); assert (left(0) == 0 && right(0) == 0 && p(0) == 0); sset x = s; keytyp key2i = dmin(i); // save key2 value of i and correct dmin, dkey values // of i after splay brings it to the root while (true) { if (kee1(i) < kee1(x) && left(x) != 0) x = left(x); else if (kee1(i) > kee1(x) && right(x) != 0) x = right(x); else break; } if (kee1(i) < kee1(x)) left(x) = i; else if (kee1(i) > kee1(x)) right(x) = i; else fatal("DualKeyBsts::insert: inserting item with duplicate key"); p(i) = x; splay(i); // note: apparent key value of i is >= that of any node on // path back to root; this ensures correct dmin, dkey values // assigned to other nodes during rotations item l = left(i); item r = right(i); keytyp dmi = key2i; if (l != 0 && dmin(l) + dmin(i) < dmi) dmi = dmin(l) + dmin(i); if (r != 0 && dmin(r) + dmin(i) < dmi) dmi = dmin(r) + dmin(i); if (l != 0) dmin(l) += (dmin(i) - dmi); if (r != 0) dmin(r) += (dmin(i) - dmi); dmin(i) = dmi; dkey(i) = key2i - dmi; return i; }
const string& ptree::get(const string& key) const { if (!m_root) { return k_empty; } digest dkey(key); return m_root->get(dkey); }
/** Copy another object to this one. * @param source is object to be copied to this one */ void Ssets2k::copyFrom(const Ssets2k& source) { if (&source == this) return; if (source.n() > n()) resize(source.n()); else clear(); Ssets_rbt::copyFrom(source); for (index x = 1; x <= n(); x++) { dmin(x) = source.dmin[x]; dkey(x) = source.dkey[x]; } }
/** Construct a string representation of a single item. * @param i is an item in some set * @param s is a string in which the result is returned * @return a reference to s */ string& DualKeyBsts::item2string(item i, string& s) const { string s1; s = ""; if (i == 0) return s; s += Util::node2string(i,n,s1) + ":"; s += Util::num2string(kee1(i),s1) + ":"; s += Util::num2string(dmin(i),s1) + ":"; s += Util::num2string(dkey(i),s1); return s; }
/** Copy another object to this one. * @param source is object to be copied to this one */ void DkBstSet::copyFrom(const DkBstSet& source) { if (&source == this) return; if (source.n() > n()) resize(source.n()); else clear(); BalBstSet::copyFrom(source); for (index x = 1; x <= n(); x++) { dmin(x) = source.dmin[x]; dkey(x) = source.dkey[x]; } }
// moving x up to take its parent's place. void DualKeyBsts::rotate(item x) { item y = p(x); if (y == 0) return; item a, b, c; if (x == left(y)) { a = left(x); b = right(x); c = right(y); } else { a = right(x); b = left(x); c = left(y); } SelfAdjBsts::rotate(x); dmin(a) += dmin(x); dmin(b) += dmin(x); dkey(x) = dkey(x) + dmin(x); keytyp dmx = dmin(x); dmin(x) = dmin(y); dmin(y) = dkey(y); if (b != 0) dmin(y) = min(dmin(y),dmin(b)+dmx); if (c != 0) dmin(y) = min(dmin(y),dmin(c)); dkey(y) = dkey(y) - dmin(y); dmin(b) -= dmin(y); dmin(c) -= dmin(y); }
void ptree::set(const string& key, const string& value) { assert(key.size() > 0); digest dkey(key); if (!m_root) { if (value != k_empty) { m_root = make_shared<ptree_leaf>(key, dkey, value); } return; } m_root = m_root->set(key, dkey, value); }
/** Remove an item from a set. * @param i is an item in some set * @param s is the canonical element of the set containing i * @return the canonical element of the new set that results from removing * i from s */ item DualKeyBsts::remove(item i, sset s) { assert(1 <= i && i <= n && 1 <= s && s <= n); assert (left(0) == 0 && right(0) == 0 && p(0) == 0); // search for i in the tree to determine its key2 value item x = s; keytyp key2i = 0; while (x != i) { assert(x != 0); key2i += dmin(x); if (kee1(i) < kee1(x)) x = left(x); else x = right(x); } key2i += (dmin(i) + dkey(i)); item j; if (left(i) == 0 || right(i) == 0) { // move the non-null child (if any) into i's position j = (left(i) == 0 ? right(i) : left(i)); if (j != 0) { dmin(j) += dmin(i); p(j) = p(i); } if (p(i) != 0) { if (i == left(p(i))) left(p(i)) = j; else if (i == right(p(i))) right(p(i)) = j; } } else { // find first node to the left of i for (j = left(i); right(j) != 0; j = right(j)) {} // move j up into i's position in tree int pi = p(i); while (p(j) != i && p(j) != pi) splaystep(j); if (p(j) == i) rotate(j); // now i is the right child of j and has no left child right(j) = right(i); p(right(j)) = j; dmin(right(j)) += dmin(i); } p(i) = left(i) = right(i) = 0; dmin(i) = key2i; dkey(i) = 0; return splay(j); }
QVariant LRSAuthenticate::PrepareForChallenge() { Library *lib = CryptoFactory::GetInstance().GetLibrary(); QSharedPointer<AsymmetricKey> skey(lib->CreatePrivateKey()); QSharedPointer<AsymmetricKey> dkey(lib->CreatePrivateKey()); QSharedPointer<DiffieHellman> dh(lib->CreateDiffieHellman()); _ident = PrivateIdentity(_ori_ident.GetLocalId(), skey, dkey, dh, _ori_ident.GetSuperPeer()); _pub_ident = GetPublicIdentity(_ident); QByteArray bident; QDataStream stream(&bident, QIODevice::WriteOnly); stream << _pub_ident; QVariantList list; list.append(bident); list.append(_lrs->Sign(bident)); return list; }
int main(int argc, char **argv) { spec_synckey_coding_test(); spec_sync_keybundle_test(); local_sync_key_record_decode(); printf("PASS\n"); #if 0 char *synckey_enc; uint8_t *synckey; struct nssync_crypto_keybundle *sync_keybundle; // const char *synckey_accountname = "*****@*****.**"; const char *synckey_username = "******"; const char *synckey_encoded = "i-xsxyz-wd3yj-5ytjx-9i7mj-wiwyy"; const char *ciphertext_b64 = "Hpdf65sSxNzB6sbQzeAcp6CKRhN/mMi2WdM9c39rS2bDStkutQvMoW4l/hHOxAoRVgNWYKPYeY0LeYJX231xXvUqgw6o8/loO8tHxEMC8VQGR5hRuf0ya2ZgCqzarUGaCJljCBy981o8vIAEi26l0SX1XnqV6OAVVu9lKx+1TP+tZzYs0sDDHoKfG3tM8Cho/WRKemQWoGvW/mYs10jiKw=="; const char *iv_b64="VmXHMMKy8mqVPpEfAlQ4vg=="; const char *hmac_hex = "10462b667bba107d1334424117c2a5ce4f465a01c0a91c4f3e5827fd3bfb87d4"; uint8_t *iv; uint8_t *record_hmac; const char *ex_ciphertext_b64 = "wcgqzENt5iXt9/7KPJ3rTA=="; uint8_t ex_hmac_key[32] = { 0x2c,0x5d,0x98,0x09,0x2d,0x50,0x0a,0x04,0x8d,0x09,0xfd,0x01,0x09,0x0b,0xd0,0xd3,0xa4,0x86,0x1f,0xc8,0xea,0x24,0x38,0xbd,0x74,0xa8,0xf4,0x3b,0xe6,0xf4,0x7f,0x02 }; uint8_t *ciphertext; size_t output_length; unsigned int local_hmac_key_len = SHA256_DIGEST_LENGTH; uint8_t local_hmac[SHA256_DIGEST_LENGTH]; /* HMAC verification key */ printf("\ntest encipher\n"); ciphertext = base64_decode((uint8_t *)ex_ciphertext_b64, strlen(ex_ciphertext_b64), &output_length); dskey(ciphertext); dkey(ex_hmac_key); HMAC(EVP_sha256(), ex_hmac_key, SHA256_DIGEST_LENGTH, (uint8_t *)ex_ciphertext_b64, strlen(ex_ciphertext_b64), local_hmac, &local_hmac_key_len); dkey(local_hmac); free(ciphertext); printf("\nusername: %s\n", synckey_username); nssync_crypto_synckey_decode(synckey_encoded, &synckey); dskey(synckey); nssync_crypto_new_sync_keybundle(synckey, synckey_username, &sync_keybundle); dkey(sync_keybundle->encryption); dkey(sync_keybundle->hmac); record_hmac = hex16_decode((uint8_t *)hmac_hex, strlen(hmac_hex), &output_length); printf("hmac length %d\n", output_length); HMAC(EVP_sha256(), sync_keybundle->hmac, SHA256_DIGEST_LENGTH, (uint8_t *)ciphertext_b64, strlen(ciphertext_b64), local_hmac, &local_hmac_key_len); if (memcmp(record_hmac, local_hmac, SHA256_DIGEST_LENGTH) != 0) { printf("record hmac does not match computed.sync key bad? %d\n", local_hmac_key_len); dkey(record_hmac); dkey(local_hmac); } else { int ciphertext_length; char *outbuf; AES_KEY aeskey; iv = base64_decode((uint8_t *)iv_b64, strlen(iv_b64), &output_length); printf("iv length %d\n", output_length); dskey(iv); ciphertext = base64_decode((uint8_t *)ciphertext_b64, strlen(ciphertext_b64), &ciphertext_length); outbuf = calloc(1, ciphertext_length); AES_set_decrypt_key(sync_keybundle->encryption, 256, &aeskey); AES_cbc_encrypt(ciphertext, outbuf, ciphertext_length, &aeskey, iv, AES_DECRYPT); int plaintext_len; plaintext_len = strlen(outbuf); printf("%s\n%02x %02x\n", outbuf, outbuf[plaintext_len-2], outbuf[plaintext_len-1]); free(ciphertext); } free(sync_keybundle); free(synckey); #endif return 0; }
/** Get the value of the second key of a node. * @param i is a node in a search tree * @return the value of the second key at i */ keytyp Ssets2k::key2(index i) { assert(valid(i)); return dmin(i) + dkey(i); }
/** Get the value of the second key of a node. * @param i is a node in a search tree * @return the value of the second key at i */ keytyp DkBstSet::key2(index i) { assert(valid(i)); return dmin(i) + dkey(i); }
/** Initialize data for the DkBstSet subclass. */ void DkBstSet::init() { for (int i = 0; i <= n(); i++) dmin(i) = dkey(i) = 0; }
/** Get the value of the second key of an item. * @param i is an item in a search tree * @return the value of the second key at i */ keytyp DualKeyBsts::key2(item i) { assert(1 <= i && i <= n); splay(i); return dmin(i) + dkey(i); }
/** Initialize data for the Ssets2k subclass. */ void Ssets2k::init() { for (int i = 0; i <= n(); i++) dmin(i) = dkey(i) = 0; }
/** Constructor for DualKeyBsts class. * @param N is the number of vertices in the constructed object */ DualKeyBsts::DualKeyBsts(int N) : SelfAdjBsts(N) { dmin = new keytyp[N+1]; dkey = new keytyp[N+1]; for (int i = 0; i <= N; i++) dmin(i) = dkey(i) = 0; }