├── README.md ├── 模重复平方 └── expmod.cpp ├── 中国剩余定理 └── ChineseRemainderTheorem.cpp ├── SPN增强 └── SPN_boost.cpp ├── PKCS7 └── My_PKCS7.cpp ├── RSA参数计算 └── RSA_CALC.cpp └── 彩虹表 └── my_rainbow.cpp /README.md: -------------------------------------------------------------------------------- 1 | # hust_crypto_design 2 | 华中科技大学 19级密码学课程设计 3 | -------------------------------------------------------------------------------- /模重复平方/expmod.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | void expmod(mpz_t e,mpz_t m,mpz_t p,mpz_t q){ 7 | char exp[8182+10]; 8 | mpz_get_str(exp,2,e); 9 | 10 | mpz_t pq,temp1,temp2,temp3; 11 | mpz_init(pq); 12 | mpz_init(temp1); 13 | mpz_init(temp2); 14 | mpz_init(temp3); 15 | mpz_mul(pq,p,q); 16 | mpz_set_ui(temp1,1);//temp1 放最终结果 17 | mpz_mod(temp2,m,pq); 18 | 19 | for(int i=strlen(exp)-1;i>=0;i--){ 20 | if(exp[i]=='1'){ 21 | mpz_mul(temp1,temp1,temp2); 22 | mpz_mod(temp1,temp1,pq); 23 | } 24 | mpz_mul(temp2,temp2,temp2); 25 | mpz_mod(temp2,temp2,pq); 26 | } 27 | 28 | gmp_printf("%Zd\n",temp1); 29 | } 30 | 31 | int main(){ 32 | int n; 33 | mpz_t e,m,p,q; 34 | mpz_init(e); 35 | mpz_init(m); 36 | mpz_init(p); 37 | mpz_init(q); 38 | 39 | scanf("%d",&n); 40 | for(int i=0;i 2 | #include 3 | 4 | #define window_size 5 5 | /* 6 | inline void expmod(mpz_t a, mpz_t paraE, mpz_t n) { 7 | // 平方乘算法 8 | int i = 0; 9 | char str[2000]; 10 | mpz_t aBack; 11 | mpz_init_set(aBack, a); 12 | mpz_get_str(str, 2, paraE); // 将其转化为二进制字符串,加速运算 13 | mpz_set_ui(a, 1); 14 | while (str[i] != '\0') { // 使用平方乘算法 15 | mpz_mul(a, a, a); 16 | mpz_mod(a, a, n); 17 | if (str[i] == '1') { 18 | mpz_mul(a, a, aBack); 19 | mpz_mod(a, a, n); 20 | } 21 | i++; 22 | } 23 | }*/ 24 | void expmod(mpz_t a, mpz_t paraE, mpz_t n){ 25 | mpz_t ret,tmp; 26 | mpz_init(ret); 27 | mpz_init(tmp); 28 | mpz_set_ui(ret,1); 29 | mpz_t pre[1<_mp_size*GMP_LIMB_BITS; 42 | long i=l-1; 43 | long s,ni; 44 | while (i>=0) 45 | { 46 | if(mpz_tstbit(paraE,i)==0){ 47 | mpz_mul(ret,ret,ret); 48 | mpz_mod(ret,ret,n); 49 | i--; 50 | }else{ 51 | s = (i + 1 - window_size) >= 0 ? (i + 1 - window_size) : 0; 52 | while (mpz_tstbit(paraE,s)==0) 53 | { 54 | s++; 55 | } 56 | for(int j=1;j<=i-s+1;j++){ 57 | mpz_mul(ret,ret,ret); 58 | mpz_mod(ret,ret,n); 59 | } 60 | //mpz_set_ui(tmp,s); 61 | mpz_div_2exp(tmp,paraE,s); 62 | unsigned long long temp = mpz_get_ui(tmp)&((1 << (i - s + 1)) - 1); 63 | mpz_mul(ret,ret,pre[temp]); 64 | mpz_mod(ret,ret,n); 65 | i=s-1; 66 | } 67 | } 68 | mpz_set(a,ret); 69 | } 70 | 71 | int main(){ 72 | int n; 73 | mpz_t e,p,q,d,c,p_inverse,q_inverse,N,phi_N,phi_q,phi_p,d1,d2,answer; 74 | mpz_init(e); 75 | mpz_init(p); 76 | mpz_init(q); 77 | mpz_init(d); 78 | mpz_init(c); 79 | mpz_init(p_inverse); 80 | mpz_init(q_inverse); 81 | mpz_init(N); 82 | mpz_init(phi_N); 83 | mpz_init(phi_q); 84 | mpz_init(phi_p); 85 | mpz_init(d1); 86 | mpz_init(d2); 87 | mpz_init(answer); 88 | 89 | //freopen("1.in","r",stdin); 90 | scanf("%d",&n); 91 | gmp_scanf("%Zd%Zd%Zd",p,q,e); 92 | //求各自的逆 93 | //inverse(p_inverse,p,q); 94 | //inverse(q_inverse,q,p); 95 | mpz_invert(p_inverse,p,q); 96 | mpz_invert(q_inverse,q,p); 97 | //N=p*q p-1 q-1 98 | mpz_mul(N,p,q); 99 | mpz_sub_ui(phi_q,q,1); 100 | mpz_sub_ui(phi_p,p,1); 101 | //inverse(d,e,phi_N); 102 | mpz_mul(phi_N,phi_q,phi_p); 103 | mpz_invert(d,e,phi_N); 104 | //求相对运算的模 105 | mpz_mod(d1,d,phi_p); 106 | mpz_mod(d2,d,phi_q); 107 | 108 | mpz_t b1,b2; 109 | mpz_init(b1); 110 | mpz_init(b2); 111 | 112 | for(int i=0;i 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define SPNBYTES (8) 8 | #define INPUTBYTES (1<<24) 9 | 10 | using namespace std; 11 | 12 | unsigned long long substitution[16] = { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 } ; 13 | unsigned long long permutationArr[64]; 14 | int permutationPos[64] = {0,16,32,48,1,17,33,49,2,18,34,50,3,19,35,51,4,20,36,52,5,21,37,53,6,22,38,54,7,23,39,55,8,24,40,56,9,25,41,57,10,26,42,58,11,27,43,59,12,28,44,60,13,29,45,61,14,30,46,62,15,31,47,63}; 15 | 16 | unsigned long long init_key[2]; 17 | unsigned long long round_key[5]; 18 | unsigned long long IV = 20001009; 19 | unsigned long long plain_text[1]; 20 | unsigned long long cipher_text[1]; 21 | 22 | void key_gen(){ 23 | round_key[0] = init_key[0]; 24 | round_key[1] = ((init_key[0]<<16)&0xffffffffffff0000)|((init_key[1]>>48)&0x000000000000ffff); 25 | round_key[2] = ((init_key[0]<<32)&0xffffffff00000000)|((init_key[1]>>32)&0x00000000ffffffff); 26 | round_key[3] = ((init_key[0]<<48)&0xffff000000000000)|((init_key[1]>>16)&0x0000ffffffffffff); 27 | round_key[4] = init_key[1]; 28 | } 29 | 30 | unsigned long long permutation(unsigned long long plaintext) { 31 | unsigned long long mask = 1; 32 | for (int i = 0; i < 64; i++) { 33 | permutationArr[i] = ((plaintext & mask) == 0? 0 : 1); 34 | mask <<= 1; 35 | } 36 | plaintext = 0; 37 | for (int i = 0; i < 64; i++) { 38 | plaintext ^= (permutationArr[permutationPos[i]]<> 4]) << 4) | 49 | ((substitution[(plaintext & 0xf00) >> 8]) << 8) | 50 | ((substitution[(plaintext & 0xf000) >> 12]) << 12) | 51 | ((substitution[(plaintext & 0xf0000) >> 16]) << 16) | 52 | ((substitution[(plaintext & 0xf00000) >> 20]) << 20) | 53 | ((substitution[(plaintext & 0xf000000) >> 24]) << 24) | 54 | ((substitution[(plaintext & 0xf0000000) >> 28]) << 28) | 55 | ((substitution[(plaintext & 0xf00000000) >> 32]) << 32) | 56 | ((substitution[(plaintext & 0xf000000000) >> 36]) << 36) | 57 | ((substitution[(plaintext & 0xf0000000000) >> 40]) << 40) | 58 | ((substitution[(plaintext & 0xf00000000000) >> 44]) << 44) | 59 | ((substitution[(plaintext & 0xf000000000000) >> 48]) << 48) | 60 | ((substitution[(plaintext & 0xf0000000000000) >> 52]) << 52) | 61 | ((substitution[(plaintext & 0xf00000000000000) >> 56]) << 56) | 62 | ((substitution[(plaintext & 0xf000000000000000) >> 60]) << 60); 63 | plaintext=permutation(plaintext); 64 | } 65 | plaintext ^=round_key[3]; 66 | plaintext = substitution[plaintext & 0xf] | 67 | ((substitution[(plaintext & 0xf0) >> 4]) << 4) | 68 | ((substitution[(plaintext & 0xf00) >> 8]) << 8) | 69 | ((substitution[(plaintext & 0xf000) >> 12]) << 12) | 70 | ((substitution[(plaintext & 0xf0000) >> 16]) << 16) | 71 | ((substitution[(plaintext & 0xf00000) >> 20]) << 20) | 72 | ((substitution[(plaintext & 0xf000000) >> 24]) << 24) | 73 | ((substitution[(plaintext & 0xf0000000) >> 28]) << 28) | 74 | ((substitution[(plaintext & 0xf00000000) >> 32]) << 32) | 75 | ((substitution[(plaintext & 0xf000000000) >> 36]) << 36) | 76 | ((substitution[(plaintext & 0xf0000000000) >> 40]) << 40) | 77 | ((substitution[(plaintext & 0xf00000000000) >> 44]) << 44) | 78 | ((substitution[(plaintext & 0xf000000000000) >> 48]) << 48) | 79 | ((substitution[(plaintext & 0xf0000000000000) >> 52]) << 52) | 80 | ((substitution[(plaintext & 0xf00000000000000) >> 56]) << 56) | 81 | ((substitution[(plaintext & 0xf000000000000000) >> 60]) << 60); 82 | //plaintext ^=round_key[4]; 83 | IV = plaintext; 84 | return plaintext; 85 | } 86 | 87 | int main(){ 88 | freopen("F:\\vs_workplace\\c++_code\\1.in", "rb", stdin); 89 | fread(init_key,SPNBYTES,1,stdin); 90 | fread(init_key+1,SPNBYTES,1,stdin); 91 | key_gen(); 92 | 93 | for(int i=0;i 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace std; 19 | 20 | const char cacert[] = "\ 21 | -----BEGIN CERTIFICATE----- \n\ 22 | MIIB/zCCAaagAwIBAgIJAKKa0PAt9M1FMAoGCCqBHM9VAYN1MFsxCzAJBgNVBAYT \n\ 23 | AkNOMQ4wDAYDVQQIDAVIdUJlaTEOMAwGA1UEBwwFV3VIYW4xDTALBgNVBAoMBEhV \n\ 24 | U1QxDDAKBgNVBAsMA0NTRTEPMA0GA1UEAwwGY2Fyb290MB4XDTIwMDkyMDIwNTkx \n\ 25 | OVoXDTMwMDkxODIwNTkxOVowWzELMAkGA1UEBhMCQ04xDjAMBgNVBAgMBUh1QmVp \n\ 26 | MQ4wDAYDVQQHDAVXdUhhbjENMAsGA1UECgwESFVTVDEMMAoGA1UECwwDQ1NFMQ8w \n\ 27 | DQYDVQQDDAZjYXJvb3QwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAASJ8mm28JJR \n\ 28 | bZKLr6DCo1+KWimpKEsiTfZM19Zi5ao7Au6YLosyN71256MWmjwkwXxJeLa0lCfm \n\ 29 | kF/YWCX6qGQ0o1MwUTAdBgNVHQ4EFgQUAL5hW3RUzqvsiTzIc1gUHeK5uzQwHwYD \n\ 30 | VR0jBBgwFoAUAL5hW3RUzqvsiTzIc1gUHeK5uzQwDwYDVR0TAQH/BAUwAwEB/zAK \n\ 31 | BggqgRzPVQGDdQNHADBEAiAaZMmvE5zzXHx/TBgdUhjtpRH3Jpd6OZ+SOAfMtKxD \n\ 32 | LAIgdKq/v2Jkmn37Y9U8FHYDfFqk5I0qlQOAmuvbVUi3yvM= \n\ 33 | -----END CERTIFICATE----- \n\ 34 | "; 35 | 36 | const char pkeyB[] = "\ 37 | -----BEGIN EC PARAMETERS----- \n\ 38 | BggqgRzPVQGCLQ== \n\ 39 | -----END EC PARAMETERS----- \n\ 40 | -----BEGIN EC PRIVATE KEY----- \n\ 41 | MHcCAQEEINQhCKslrI3tKt6cK4Kxkor/LBvM8PSv699Xea7kTXTToAoGCCqBHM9V \n\ 42 | AYItoUQDQgAEH7rLLiFASe3SWSsGbxFUtfPY//pXqLvgM6ROyiYhLkPxEulwrTe8 \n\ 43 | kv5R8/NA7kSSvcsGIQ9EPWhr6HnCULpklw== \n\ 44 | -----END EC PRIVATE KEY----- \n\ 45 | "; 46 | 47 | X509 *getX509(const char *cert) 48 | { 49 | BIO *bio; 50 | bio = BIO_new(BIO_s_mem()); 51 | BIO_puts(bio, cert); 52 | return PEM_read_bio_X509(bio, NULL, NULL, NULL); 53 | } 54 | EVP_PKEY *getpkey(const char *private_key) 55 | { 56 | BIO *bio_pkey = BIO_new_mem_buf((char *)private_key, strlen(private_key)); 57 | if (bio_pkey == NULL) 58 | return NULL; 59 | return PEM_read_bio_PrivateKey(bio_pkey, NULL, NULL, NULL); 60 | } 61 | PKCS7 *get_PKCS7(const char *pkcs7) 62 | { 63 | BIO *p7Bio = BIO_new_mem_buf((char *)pkcs7, strlen(pkcs7)); 64 | if (p7Bio==NULL) 65 | return NULL; 66 | return PEM_read_bio_PKCS7(p7Bio, NULL, NULL, NULL); 67 | } 68 | 69 | int verify_signature(PKCS7 *p7, BIO *p7Bio, X509 *tcacert) 70 | { 71 | STACK_OF(PKCS7_SIGNER_INFO) *sk = PKCS7_get_signer_info(p7); 72 | if (!sk) 73 | return false; 74 | X509_STORE *store = X509_STORE_new(); 75 | X509_STORE_CTX *ct = X509_STORE_CTX_new(); 76 | X509_STORE_add_cert(store, tcacert); 77 | int signNum = sk_PKCS7_SIGNER_INFO_num(sk); 78 | int flag = true; 79 | for (int i = 0; i < signNum; ++i) 80 | { 81 | PKCS7_SIGNER_INFO *signInfo = sk_PKCS7_SIGNER_INFO_value(sk, i); 82 | auto res = PKCS7_dataVerify(store, ct, p7Bio, p7, signInfo); 83 | PKCS7_SIGNER_INFO_free(signInfo); 84 | if (res <= 0) 85 | { 86 | flag = false; 87 | break; 88 | } 89 | } 90 | X509_STORE_free(store); 91 | X509_STORE_CTX_free(ct); 92 | sk_PKCS7_SIGNER_INFO_free(sk); 93 | return flag; 94 | } 95 | 96 | void pkcs7_decrypt(){ 97 | char buffer[4096]; 98 | char pkcs7[4096]; 99 | PKCS7 *p7; 100 | X509 *cert; 101 | BIO *p7bio; 102 | BIO *out = BIO_new_fd(fileno(stdout), BIO_NOCLOSE); 103 | 104 | //读数据 105 | fread(pkcs7,sizeof(pkcs7)-1,1,stdin); 106 | //将数据转换成信封格式 107 | p7 = get_PKCS7(pkcs7); 108 | if(!p7){ 109 | cout<<"ERROR"< 2 | #include 3 | using namespace std; 4 | 5 | #define min_e 65536 6 | #define flat 20 //表示p,q平滑程度 7 | 8 | bool is_prime(mpz_t paraN) 9 | { 10 | //拉宾米勒测试 11 | int count = 0; 12 | gmp_randstate_t state; 13 | gmp_randinit_mt(state); 14 | 15 | mpz_t b, t, temp, a, n; 16 | mpz_init(b); 17 | mpz_init(n); 18 | mpz_init(a); 19 | mpz_init(t); 20 | mpz_init(temp); 21 | 22 | mpz_init_set(n, paraN); 23 | mpz_set(t, n); 24 | mpz_sub_ui(t, t, 1); 25 | mpz_mod_ui(b, t, 2); 26 | while (mpz_cmp_ui(b, 0) == 0) 27 | { // 求解t 28 | mpz_div_ui(t, t, 2); 29 | mpz_mod_ui(b, t, 2); 30 | count++; 31 | } 32 | // 偶数直接排除 33 | mpz_sub_ui(t, n, 1); 34 | if (count == 0) 35 | { 36 | return false; 37 | } 38 | for (int i = 0; i < 300; i++) 39 | { 40 | mpz_urandomm(a, state, n); // 随机选择a 41 | if (mpz_cmp_ui(a, 0) != 0 && mpz_cmp_ui(a, 1) != 0) 42 | { 43 | mpz_powm(temp, a, t, n); 44 | if (mpz_cmp_ui(temp, 1) == 0) 45 | { // 是素数 46 | return true; 47 | } 48 | for (int j = 0; j < count; j++) 49 | { 50 | if (mpz_cmp(temp, t) == 0) 51 | { // 是素数 52 | return true; 53 | } 54 | mpz_powm_ui(temp, temp, 2, n); 55 | } 56 | } 57 | } 58 | return false; 59 | } 60 | 61 | bool gcd(mpz_t paraA, mpz_t paraB,int mode) 62 | { 63 | mpz_t temp, a, b; 64 | mpz_init(temp); 65 | mpz_init(a); 66 | mpz_init(b); 67 | mpz_init_set(a, paraA); 68 | mpz_init_set(b, paraB); 69 | mpz_mod(temp, a, b); 70 | while (mpz_cmp_ui(temp, 0) != 0) 71 | { 72 | mpz_init_set(a, b); 73 | mpz_init_set(b, temp); 74 | mpz_mod(temp, a, b); 75 | } 76 | if(mode==0){ 77 | if (mpz_cmp_ui(b, 1) == 0) 78 | { 79 | return true; 80 | } 81 | }else{ 82 | if (mpz_cmp_ui(b, flat) > 0) 83 | { 84 | return true; 85 | } 86 | } 87 | return false; 88 | } 89 | 90 | void calc(mpz_t e, mpz_t p, mpz_t q) 91 | { 92 | mpz_t st[5000]; 93 | int count = -1; 94 | for (int i = 0; i < 5000; i++) 95 | { 96 | mpz_init(st[i]); 97 | } 98 | mpz_t phi, temp, temp1, temp2; 99 | mpz_init(phi); 100 | mpz_init(temp); 101 | mpz_init(temp1); 102 | mpz_init(temp2); 103 | 104 | //e过小 105 | if (mpz_cmp_ui(e, min_e) < 0) 106 | { 107 | printf("ERROR\n"); 108 | return; 109 | } 110 | 111 | //p,q不是素数 112 | if (!(is_prime(p) && is_prime(q))) 113 | { 114 | printf("ERROR\n"); 115 | return; 116 | } 117 | 118 | // p,q差值过小 119 | mpz_sub(temp, p, q); 120 | mpz_div_ui(temp1, p, 10); 121 | mpz_abs(temp, temp); 122 | if (mpz_cmp(temp, temp1) < 0) 123 | { 124 | printf("ERROR\n"); 125 | return; 126 | } 127 | 128 | //太平滑(指p-1和q-1的最大公因数超过20) 129 | mpz_sub_ui(p, p, 1); 130 | mpz_sub_ui(q, q, 1); 131 | if (gcd(p, q,1)) 132 | { 133 | printf("ERROR\n"); 134 | return; 135 | } 136 | //e和phi不互素 137 | mpz_mul(phi, p, q); 138 | mpz_init_set_ui(temp, 0); 139 | mpz_sub(phi, temp, phi); 140 | if (!gcd(e, phi,0)) 141 | { 142 | printf("ERROR\n"); 143 | return; 144 | } 145 | 146 | // 求解d 147 | mpz_mod(temp, e, phi); 148 | mpz_sub(temp1, e, temp); 149 | mpz_div(temp1, temp1, phi); 150 | mpz_init_set(st[0], temp1); 151 | while (mpz_cmp_ui(temp, 0) != 0) 152 | { 153 | count++; 154 | mpz_init_set(st[count], temp1); 155 | mpz_init_set(e, phi); 156 | mpz_init_set(phi, temp); 157 | mpz_mod(temp, e, phi); 158 | mpz_sub(temp1, e, temp); 159 | mpz_div(temp1, temp1, phi); 160 | } 161 | mpz_init_set_ui(temp1, 0); 162 | mpz_init_set_ui(temp2, 1); 163 | mpz_sub(phi, temp1, phi); 164 | for (int i = count; i >= 0; i--) 165 | { 166 | mpz_init_set(temp, temp2); 167 | mpz_mul(temp2, temp2, st[i]); 168 | mpz_sub(temp2, temp1, temp2); 169 | mpz_init_set(temp1, temp); 170 | } 171 | gmp_printf("%Zd\n", temp1); 172 | } 173 | 174 | int main() 175 | { 176 | int n; 177 | mpz_t e, p, q; 178 | mpz_init(e); 179 | mpz_init(p); 180 | mpz_init(q); 181 | 182 | scanf("%d", &n); 183 | for (int i = 0; i < n; i++) 184 | { 185 | gmp_scanf("%Zd%Zd%Zd", e, p, q); 186 | calc(e, p, q); 187 | } 188 | return 0; 189 | } -------------------------------------------------------------------------------- /彩虹表/my_rainbow.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | unsigned int SHA1_tmp; 8 | 9 | #define SHA1_ROTL(a, b) (SHA1_tmp = (a), ((SHA1_tmp >> (32 - b)) & (0x7fffffff >> (31 - b))) | (SHA1_tmp << b)) 10 | #define SHA1_F(B, C, D, t) ((t < 40) ? ((t < 20) ? ((B & C) | ((~B) & D)) : (B ^ C ^ D)) : ((t < 60) ? ((B & C) | (B & D) | (C & D)) : (B ^ C ^ D))) 11 | 12 | static inline int UnitSHA1(const char *str, int length, unsigned sha1[5]) 13 | { 14 | unsigned char *pp, *ppend; 15 | unsigned int l, i, K[80], W[80], TEMP, A, B, C, D, E, H0, H1, H2, H3, H4; 16 | H0 = 0x67452301, H1 = 0xEFCDAB89, H2 = 0x98BADCFE, H3 = 0x10325476, 17 | H4 = 0xC3D2E1F0; 18 | for (i = 0; i < 20; K[i++] = 0x5A827999); 19 | for (i = 20; i < 40; K[i++] = 0x6ED9EBA1); 20 | for (i = 40; i < 60; K[i++] = 0x8F1BBCDC); 21 | for (i = 60; i < 80; K[i++] = 0xCA62C1D6); 22 | l = length + ((length % 64 > 56) ? (128 - length % 64) : (64 - length % 64)); 23 | if (!(pp = (unsigned char *)malloc((unsigned int)l))) 24 | return -1; 25 | for (i = 0; i < length; pp[i + 3 - 2 * (i % 4)] = str[i], i++); 26 | for (pp[i + 3 - 2 * (i % 4)] = 128, i++; i < l;pp[i + 3 - 2 * (i % 4)] = 0, i++); 27 | 28 | *((unsigned int *)(pp + l - 4)) = length << 3; 29 | *((unsigned int *)(pp + l - 8)) = length >> 29; 30 | 31 | for (ppend = pp + l; pp < ppend; pp += 64) 32 | { 33 | for (i = 0; i < 16; W[i] = ((unsigned int *)pp)[i], i++) 34 | ; 35 | 36 | for (i = 16; i < 80; 37 | W[i] = SHA1_ROTL((W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]), 1), 38 | i++) 39 | ; 40 | 41 | A = H0, B = H1, C = H2, D = H3, E = H4; 42 | for (i = 0; i < 80; i++) 43 | { 44 | TEMP = SHA1_ROTL(A, 5) + SHA1_F(B, C, D, i) + E + W[i] + K[i]; 45 | E = D, D = C, C = SHA1_ROTL(B, 30), B = A, A = TEMP; 46 | } 47 | H0 += A, H1 += B, H2 += C, H3 += D, H4 += E; 48 | } 49 | 50 | free(pp - l); 51 | sha1[0] = H0, sha1[1] = H1, sha1[2] = H2, sha1[3] = H3, sha1[4] = H4; 52 | return 0; 53 | } 54 | 55 | static inline void getstr(unsigned n, char str[8]) 56 | { 57 | str[0] = 'a';str[1] = '0';str[2] = '0';str[3] = '0';str[4] = '0';str[5] = '0';str[6] = '0';str[7] = '0'; 58 | int i = 2; 59 | while (n) 60 | { 61 | unsigned tmp = n % 36; 62 | if (tmp < 10) 63 | str[i++] = tmp + '0'; 64 | else 65 | { 66 | str[i++] = tmp - 10 + 'a'; 67 | } 68 | n = n / 36; 69 | } 70 | } 71 | 72 | static inline void R(unsigned sha1[5], char str[8], int i) 73 | { 74 | getstr((sha1[0] + sha1[1] * i) % 2176782336, str); 75 | } 76 | 77 | int is_equal(unsigned s1[5], unsigned s2[5]) 78 | { 79 | for (int i = 0; i < 5; i++) 80 | { 81 | if (s1[i] != s2[i]) 82 | return false; 83 | } 84 | return true; 85 | } 86 | 87 | int find_str(unsigned *sha1, char *str, const char *startstr) 88 | { 89 | unsigned tmpsha1[5]; 90 | char tmpstr[9]; 91 | strcpy(tmpstr, startstr); 92 | for (int j = 0; j < 10000; j++) 93 | { 94 | UnitSHA1(tmpstr, 8, tmpsha1); 95 | 96 | if (is_equal(sha1, tmpsha1)) 97 | { 98 | strcpy(str, tmpstr); 99 | return true; 100 | } 101 | R(tmpsha1, tmpstr, j % 100 + 1); 102 | } 103 | return false; 104 | } 105 | char head[9], tail[9]; 106 | unordered_map mapmap; 107 | int m; 108 | int find_sha1(unsigned *sha1, char *str) 109 | { 110 | int flag; 111 | char tmpstr[9]; 112 | unsigned tmpsha1[5]; 113 | for (int i = 0; i < 100; i++) 114 | { 115 | memcpy(tmpsha1, sha1, sizeof(tmpsha1)); 116 | for (int j = 0; j < 10000; j++) 117 | { 118 | R(tmpsha1, tmpstr, (i + j) % 100 + 1); 119 | if (((i + j) % 100 + 1) == 100) 120 | { 121 | auto find = mapmap.find(string(tmpstr)); 122 | if (find != mapmap.end()) 123 | flag = find_str(sha1, tmpstr, find->second.c_str()); 124 | if (flag) 125 | { 126 | strcpy(str, tmpstr); 127 | return flag; 128 | } 129 | } 130 | UnitSHA1(tmpstr, 8, tmpsha1); 131 | } 132 | } 133 | return false; 134 | } 135 | 136 | 137 | int main() 138 | { 139 | int flag; 140 | char str[9]; 141 | unsigned sha1[5]; 142 | scanf("%d", &m); 143 | for (int i = 0; i < m; i++) 144 | { 145 | scanf("%s%s", head, tail); 146 | mapmap[tail] = head; 147 | } 148 | scanf("%8x%8x%8x%8x%8x", &(sha1[0]), &(sha1[1]), &(sha1[2]), &(sha1[3]),&(sha1[4])); 149 | flag = find_sha1(sha1, str); 150 | if (flag) 151 | { 152 | printf("%s\n", str); 153 | }else 154 | { 155 | printf("None\n"); 156 | } 157 | return 0; 158 | } --------------------------------------------------------------------------------