void send_asymmetric_encrypted(struct network_status *net_stat, struct keypair *keypair) /*@ requires [?f0]world(?pub, ?key_clsfy) &*& keypair(keypair, ?attacker_id, ?id, ?info, pub) &*& proof_obligations(pub) &*& network_status(net_stat) &*& principal(attacker_id, ?count1) &*& true == bad(attacker_id); @*/ /*@ ensures [f0]world(pub, key_clsfy) &*& keypair(keypair, attacker_id, id, info, pub) &*& proof_obligations(pub) &*& network_status(net_stat) &*& principal(attacker_id, ?count2); @*/ { struct item *key = network_receive(net_stat); //@ assert item(key, ?k, pub); if (is_public_key(key)) { struct item *pay = network_receive(net_stat); //@ assert item(pay, ?p, pub); struct item *enc = asymmetric_encryption(key, pay); //@ assert item(enc, ?e, pub); //@ open proof_obligations(pub); /*@ if (col) { assert is_public_collision(?proof, pub); proof(e); } else { assert is_public_asymmetric_encrypted(?proof, pub); proof(e); } @*/ //@ close proof_obligations(pub); network_send(net_stat, enc); item_free(enc); item_free(pay); } item_free(key); }
struct item *asymmetric_authenticated_encryption(char recipient, struct item *public_key, struct item *private_key, struct item *payload) /*@ requires [?f]world(?pub) &*& generated_values(?principal1, ?count1) &*& item(public_key, ?pub_k, pub) &*& pub_k == public_key_item(?principal2, ?count2) &*& item(private_key, ?priv_k, pub) &*& priv_k == private_key_item(?principal3, ?count3) &*& item(payload, ?pay, pub); @*/ /*@ ensures [f]world(pub) &*& generated_values(principal1, count1 + 2) &*& item(public_key, pub_k, pub) &*& item(private_key, priv_k, pub) &*& item(payload, pay, pub) &*& item(result, ?msg, pub) &*& collision_in_run() ? true : msg == pair_item(?enc, ?sig) &*& enc == asymmetric_encrypted_item(principal2, count2, some(pay), _) &*& sig == asymmetric_signature_item(principal3, count3, some(?msg_id), _) &*& msg_id == pair_item(data_item(cons(recipient, nil)), hash_item(some(enc))); @*/ { struct item* encrypted = asymmetric_encryption(public_key, payload); struct item* hash = create_hash(encrypted); struct item* rcp = create_data_item_from_char(recipient); struct item* msg_id = create_pair(rcp, hash); struct item* signature = asymmetric_signature(private_key, msg_id); struct item* result = create_pair(encrypted, signature); item_free(encrypted); item_free(hash); item_free(rcp); item_free(msg_id); item_free(signature); return result; }