#include "../lib/lib.h" #include "../lib/lib2.h" #include "../lib/lib3.h" #include "../lib/lib4.h" #include "../lib/lib5.h" #include "../lib/lib6.h" #include int main() { int i; struct dsa_public_params dsa_pub; struct dsa_per_user_param dsa_user; SHA_CTX sha1; BIGNUM *mess1_hash_bn = BN_new(); BIGNUM *mess2_hash_bn = BN_new(); BIGNUM *s1_bn = BN_new(); BIGNUM *s2_bn = BN_new(); dsa_user.public = BN_new(); dsa_user.private = BN_new(); dsa_user.r = BN_new(); dsa_user.s = BN_new(); char *y = "2d026f4bf30195ede3a088da85e398ef869611d0f68f07" "13d51c9c1a3a26c95105d915e2d8cdf26d056b86b8a7b8" "5519b1c23cc3ecdc6062650462e3063bd179c2a6581519" "f674a61f1d89a1fff27171ebc1b93d4dc57bceb7ae2430" "f98a6a4d83d8279ee65d71c1203d2c96d65ebbf7cce9d3" "2971c3de5084cce04a2e147821"; out = BIO_new(BIO_s_file()); BIO_set_fp(out, stdout, BIO_NOCLOSE); ctx = BN_CTX_new(); init_dsa_pub_param(&dsa_pub); // from the 44.txt the first message and the third last have // the same r, which means the same k was used char *r = "1105520928110492191417703162650245113664610474875"; char *s1 = "1267396447369736888040262262183731677867615804316"; char *s2 = "1021643638653719618255840562522049391608552714967"; char *mess1 = "Listen for me, you better listen for me now. "; char *mess2 = "Pure black people mon is all I mon know. "; char hash[20]; char hex[41]; // save the public key BN_hex2bn(&dsa_user.public, y); BN_dec2bn(&s1_bn, s1); BN_dec2bn(&s2_bn, s2); BN_dec2bn(&dsa_user.s, s1); BN_dec2bn(&dsa_user.r, r); // computing SHA1 hashes for both messages SHA1_Init(&sha1); SHA1_Update(&sha1, mess1, strlen(mess1)); SHA1_Final(hash, &sha1); BN_bin2bn(hash, 20, mess1_hash_bn); hex_binary_to_string(hash, hex, 20); printf("sha1 from mess1 is: %s\n", hex); SHA1_Init(&sha1); SHA1_Update(&sha1, mess2, strlen(mess2)); SHA1_Final(hash, &sha1); BN_bin2bn(hash, 20, mess2_hash_bn); BIGNUM *k = BN_new(); dsa_recover_k_from_repeated_nonce(mess1_hash_bn, mess2_hash_bn, s1_bn, s2_bn, &dsa_pub, &dsa_user, k); dsa_recover_x_from_known_k(&dsa_pub, k, &dsa_user, mess1_hash_bn); printf("\nreceovered x is:\n"); BN_print(out, dsa_user.private); printf("\n"); // so dsa_user now contains the recovered private and public key, // we can use to sign every new message // compare hash of compute private key with given one char *priv_key_bin = malloc(BN_num_bytes(dsa_user.private)); char *priv_key_hex = malloc(BN_num_bytes(dsa_user.private)*2+1); BN_bn2bin(dsa_user.private, priv_key_bin); hex_binary_to_string(priv_key_bin, priv_key_hex, BN_num_bytes(dsa_user.private)); SHA1_Init(&sha1); SHA1_Update(&sha1, priv_key_hex, BN_num_bytes(dsa_user.private)*2); SHA1_Final(hash, &sha1); hex_binary_to_string(hash, hex, 20); char *given_hash = "ca8f6f7c66fa362d40760d135b763eb8527d3d52"; printf("hash of recovered private key is: %s\n", hex); printf("given hash is: %s\n", given_hash); printf("equal ? : %i\n", memcmp(hex, given_hash, strlen(given_hash))); }