1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
#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 <openssl/sha.h>
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)));
}
|