int expmod(int a, int e, int n) { if (a > n) return expmod((a % n), e, n); else if (e == 1) return (a % n); else if (e == 0) return 1; else if (a == 0) return 0; else if (e % 2 == 0) return expmod(a * a, e / 2, n); else return (expmod(a, e - 1, n) * a) % n; }
ll expmod(ll b, ll e, ll m) { //O(log b) if (!e) return 1; ll q = expmod(b, e / 2, m); q = mulmod(q, q, m); return e % 2 ? mulmod(b, q, m) : q; }
int RSA::is_prime_san(int p[MAX]) { int i, a[MAX], t[MAX], s[MAX], o[MAX]; for (i = 0; i<MAX; i++) s[i] = o[i] = a[i] = t[i] = 0; t[0] = 1; t[MAX - 1] = 1; a[0] = 2;// { 2,3,5,7 } a[MAX - 1] = 1; sub(p, t, s); expmod(a, s, p, o); if (cmp(o, t) != 0) { return 0; } a[0] = 3; for (i = 0; i<MAX; i++) o[i] = 0; expmod(a, s, p, o); if (cmp(o, t) != 0) { return 0; } a[0] = 5; for (i = 0; i<MAX; i++) o[i] = 0; expmod(a, s, p, o); if (cmp(o, t) != 0) { return 0; } a[0] = 7; for (i = 0; i<MAX; i++) o[i] = 0; expmod(a, s, p, o); if (cmp(o, t) != 0) { return 0; } return 1; }
bool es_primo_prob(ll n, int a) { if (n == a) return true; ll s = 0, d = n - 1; while (d % 2 == 0) s++, d /= 2; ll x = expmod(a, d, n); if ((x == 1) || (x + 1 == n)) return true; for (int i = 0; i < s-1; ++i) { x = mulmod(x, x, n); if (x == 1) return false; if (x + 1 == n) return true; } return false; }
/*! * @param[in] d,n为私钥,由函数RSAKey()产生 * @param[in] text为密文,对应加密函数,密文的格式为string * @return[string] 解密之后的明文采用string进行存储 * @pre \e 进行解密的过程中进行了数据类型的转换 * @see e,d,n & text */ string RSA::tdecrypto(int d[MAX], int n[MAX], string text) { struct slink *h, *p1, *p2; char ch; int i, j, k, c, count, temp; i = 0; j = 3; count = 0; h = p1 = p2 = (struct slink *)malloc(LEN); int kk; for (kk = 0; kk < text.length(); kk++) { ch = text.at(kk); c = ch; if (j == 3) { p1->bignum[MAX - 2] = c; j--; } else if (j == 2) { temp = c - 48; j--; } else if (j == 1) { p1->bignum[MAX - 1] = temp * 10 + c - 48; j--; } else if (j == 0) { p1->bignum[i] = c - 48; i++; if (i == p1->bignum[MAX - 1]) { i = 0; j = 3; count++; if (count == 1) h = p1; else p2->next = p1; p2 = p1; p1 = (struct slink *)malloc(LEN); } } } p2->next = NULL; p2 = (struct slink *)malloc(LEN); p1 = h; k = 0; string res; if (h != NULL)/*/temp为暂存ASIIC码的int值*/ do { for (i = 0; i<MAX; i++) p2->bignum[i] = 0; expmod(p1->bignum, d, n, p2->bignum); temp = p2->bignum[0] + p2->bignum[1] * 10 + p2->bignum[2] * 100; if ((p2->bignum[MAX - 2]) == '0') { temp = 0 - temp; }/*/转化为正确的ASIIC码,如-78-96形成汉字 */ ch = temp;/* str[k]--->ch */ res += ch; k++; p1 = p1->next; p2 = (struct slink *)malloc(LEN); } while (p1 != NULL); return res; }
/*! * @param[in] e,n为随机产生的公钥,利用公钥进行加密 * @param[in] text为明文,明文以char*的格式存储 * @return[string] 返回值为加密成功之后的密文,采用string类型进行存储 * @pre \e 进行加密的过程中进行了数据类型的转换 * @see e,d,n & text */ string RSA::tencrypto(int e[MAX], int n[MAX], char* text)/*//对有需要的文件进行加密*/ { int i, k, count, temp, c; char ch; struct slink *p, *p1, *p2; struct slink *h; h = p = p1 = p2 = (struct slink *)malloc(LEN); h = NULL; if (text == NULL) { return NULL; } count = 0; int j; for (j = 0; j < strlen(text); j++) { ch = text[j]; c = ch; k = 0; if (c<0) { c = abs(c);/*/把负数取正并且做一个标记*/ p1->bignum[MAX - 2] = '0'; } else { p1->bignum[MAX - 2] = '1'; } while (c / 10 != 0) { temp = c % 10; c = c / 10; p1->bignum[k] = temp; k++; } p1->bignum[k] = c; p1->bignum[MAX - 1] = k + 1; count = count + 1; if (count == 1) h = p1; else p2->next = p1; p2 = p1; p1 = (struct slink *)malloc(LEN); } p2->next = NULL; string res; p = p1 = (struct slink *)malloc(LEN); p = h; if (h != NULL) do { expmod(p->bignum, e, n, p1->bignum); ch = p1->bignum[MAX - 2]; res += ch; if ((p1->bignum[MAX - 1] / 10) == 0)/*/判断p1->bignum[99]的是否大于十;*/ { ch = 0 + 48; res += ch; ch = p1->bignum[MAX - 1] + 48; res += ch; } else { ch = p1->bignum[MAX - 1] / 10 + 48; res += ch; ch = p1->bignum[MAX - 1] % 10 + 48; res += ch; } for (i = 0; i<p1->bignum[MAX - 1]; i++) { ch = p1->bignum[i] + 48; res += ch; } p = p->next; p1 = (struct slink *)malloc(LEN); } while (p != NULL); return res; }
int main() { uint32_t b, p, m; while (std::cin >> b >> p >> m) { std::cout << expmod(b, p, m) << std::endl; } }