⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zz.c

📁 密码大家Shoup写的数论算法c语言实现
💻 C
📖 第 1 页 / 共 3 页
字号:
   long r = DivRem(qq, a, b);   if (r) return 0;   q = qq;   return 1;}long divide(const ZZ& a, long b){   if (!b) return IsZero(a);   if (b == 1) {      return 1;   }   long r = rem(a,  b);   return (r == 0);}   long RandomPrime_long(long l, long NumTrials){   if (l <= 1 || l >= NTL_BITS_PER_LONG)      Error("RandomPrime: length out of range");   long n;   do {      n = RandomLen_long(l);   } while (!ProbPrime(n, NumTrials));   return n;}PrimeSeq::PrimeSeq(){   movesieve = 0;   movesieve_mem = 0;   pshift = -1;   pindex = -1;   exhausted = 0;}PrimeSeq::~PrimeSeq(){   if (movesieve_mem)      free(movesieve_mem);}long PrimeSeq::next(){   if (exhausted) {      return 0;   }   if (pshift < 0) {      shift(0);      return 2;   }   for (;;) {      char *p = movesieve;      long i = pindex;      while ((++i) < NTL_PRIME_BND) {         if (p[i]) {            pindex = i;            return pshift + 2 * i + 3;         }      }      long newshift = pshift + 2*NTL_PRIME_BND;      if (newshift > 2 * NTL_PRIME_BND * (2 * NTL_PRIME_BND + 1)) {         /* end of the road */         exhausted = 1;         return 0;      }      shift(newshift);   }}static char *lowsieve = 0;void PrimeSeq::shift(long newshift){   long i;   long j;   long jstep;   long jstart;   long ibound;   char *p;   if (!lowsieve)      start();   pindex = -1;   exhausted = 0;   if (newshift < 0) {      pshift = -1;      return;   }   if (newshift == pshift) return;   pshift = newshift;   if (pshift == 0) {      movesieve = lowsieve;   }    else {      if (!movesieve_mem) {         movesieve_mem = (char *) malloc(NTL_PRIME_BND);         if (!movesieve_mem)             Error("out of memory in PrimeSeq");      }      p = movesieve = movesieve_mem;      for (i = 0; i < NTL_PRIME_BND; i++)         p[i] = 1;      jstep = 3;      ibound = pshift + 2 * NTL_PRIME_BND + 1;      for (i = 0; jstep * jstep <= ibound; i++) {         if (lowsieve[i]) {            if (!((jstart = (pshift + 2) / jstep + 1) & 1))               jstart++;            if (jstart <= jstep)               jstart = jstep;            jstart = (jstart * jstep - pshift - 3) / 2;            for (j = jstart; j < NTL_PRIME_BND; j += jstep)               p[j] = 0;         }         jstep += 2;      }   }}void PrimeSeq::start(){   long i;   long j;   long jstep;   long jstart;   long ibnd;   char *p;   p = lowsieve = (char *) malloc(NTL_PRIME_BND);   if (!p)      Error("out of memory in PrimeSeq");   for (i = 0; i < NTL_PRIME_BND; i++)      p[i] = 1;         jstep = 1;   jstart = -1;   ibnd = (SqrRoot(2 * NTL_PRIME_BND + 1) - 3) / 2;   for (i = 0; i <= ibnd; i++) {      jstart += 2 * ((jstep += 2) - 1);      if (p[i])         for (j = jstart; j < NTL_PRIME_BND; j += jstep)            p[j] = 0;   }}void PrimeSeq::reset(long b){   if (b > (2*NTL_PRIME_BND+1)*(2*NTL_PRIME_BND+1)) {      exhausted = 1;      return;   }   if (b <= 2) {      shift(-1);      return;   }   if ((b & 1) == 0) b++;   shift(((b-3) / (2*NTL_PRIME_BND))* (2*NTL_PRIME_BND));   pindex = (b - pshift - 3)/2 - 1;} long Jacobi(const ZZ& aa, const ZZ& nn){   ZZ a, n;   long t, k;   long d;   a = aa;   n = nn;   t = 1;   while (a != 0) {      k = MakeOdd(a);      d = trunc_long(n, 3);      if ((k & 1) && (d == 3 || d == 5)) t = -t;      if (trunc_long(a, 2) == 3 && (d & 3) == 3) t = -t;      swap(a, n);      rem(a, a, n);   }   if (n == 1)      return t;   else      return 0;}void SqrRootMod(ZZ& x, const ZZ& aa, const ZZ& nn){   if (aa == 0 || aa == 1) {      x = aa;      return;   }   // at this point, we msut have nn >= 5   long i, k;   ZZ ma, n, t, u, v, e;   ZZ t1, t2, t3;   n = nn;   NegateMod(ma, aa, n);   // find t such that t^2 - 4*a is not a square   MulMod(t1, ma, 4, n);   do {      RandomBnd(t, n);      SqrMod(t2, t, n);      AddMod(t2, t2, t1, n);   } while (Jacobi(t2, n) != -1);   // compute u*X + v = X^{(n+1)/2} mod f, where f = X^2 - t*X + a   add(e, n, 1);   RightShift(e, e, 1);   u = 0;   v = 1;   k = NumBits(e);   for (i = k - 1; i >= 0; i--) {      SqrMod(t1, u, n);      SqrMod(t2, v, n);      MulMod(t3, u, v, n);      MulMod(t3, t3, 2, n);      MulMod(u, t1, t, n);      AddMod(u, u, t3, n);      MulMod(v, t1, ma, n);      AddMod(v, v, t2, n);      if (bit(e, i)) {         MulMod(t1, u, t, n);         AddMod(t1, t1, v, n);         MulMod(v, u, ma, n);         u = t1;      }   }   x = v;}// Chinese Remaindering.//// This version in new to v3.7, and is significantly// simpler and faster than the previous version.//// This function takes as input g, a, G, p,// such that a > 0, 0 <= G < p, and gcd(a, p) = 1.// It computes a' = a*p and g' such that //   * g' = g (mod a);//   * g' = G (mod p);//   * -a'/2 < g' <= a'/2.// It then sets g := g' and a := a', and returns 1 iff g has changed.//// Under normal use, the input value g satisfies -a/2 < g <= a/2;// however, this was not documented or enforced in earlier versions,// so to maintain backward compatability, no restrictions are placed// on g.  This routine runs faster, though, if -a/2 < g <= a/2,// and the first thing the routine does is to make this condition// hold.//// Also, under normal use, both a and p are odd;  however, the routine// will still work even if this is not so.//// The routine is based on the following simple fact.//// Let -a/2 < g <= a/2, and let h satisfy//   * g + a h = G (mod p);//   * -p/2 < h <= p/2.// Further, if p = 2*h and g > 0, set//   g' := g - a h;// otherwise, set//   g' := g + a h.// Then g' so defined satisfies the above requirements.//// It is trivial to see that g's satisfies the congruence conditions.// The only thing is to check that the "balancing" condition// -a'/2 < g' <= a'/2 also holds.long CRT(ZZ& gg, ZZ& a, long G, long p){   if (p >= NTL_SP_BOUND) {      ZZ GG, pp;      conv(GG, G);      conv(pp, p);      return CRT(gg, a, GG, pp);   }   long modified = 0;   ZZ g;   if (!CRTInRange(gg, a)) {      modified = 1;      ZZ a1;      rem(g, gg, a);      RightShift(a1, a, 1);      if (g > a1) sub(g, g, a);   }   else      g = gg;   long p1;   p1 = p >> 1;   long a_inv;   a_inv = rem(a, p);   a_inv = InvMod(a_inv, p);   long h;   h = rem(g, p);   h = SubMod(G, h, p);   h = MulMod(h, a_inv, p);   if (h > p1)      h = h - p;   if (h != 0) {      modified = 1;      ZZ ah;      mul(ah, a, h);      if (!(p & 1) && g > 0 && (h == p1))         sub(g, g, ah);      else         add(g, g, ah);   }   mul(a, a, p);   gg = g;   return modified;}long CRT(ZZ& gg, ZZ& a, const ZZ& G, const ZZ& p){   long modified = 0;   ZZ g;   if (!CRTInRange(gg, a)) {      modified = 1;      ZZ a1;      rem(g, gg, a);      RightShift(a1, a, 1);      if (g > a1) sub(g, g, a);   }   else      g = gg;   ZZ p1;   RightShift(p1, p, 1);   ZZ a_inv;   rem(a_inv, a, p);   InvMod(a_inv, a_inv, p);   ZZ h;   rem(h, g, p);   SubMod(h, G, h, p);   MulMod(h, h, a_inv, p);   if (h > p1)      sub(h, h, p);   if (h != 0) {      modified = 1;      ZZ ah;      mul(ah, a, h);      if (!IsOdd(p) && g > 0 &&  (h == p1))         sub(g, g, ah);      else         add(g, g, ah);   }   mul(a, a, p);   gg = g;   return modified;}void sub(ZZ& x, const ZZ& a, long b){   static ZZ B;   conv(B, b);   sub(x, a, B);}void sub(ZZ& x, long a, const ZZ& b){   static ZZ A;   conv(A, a);   sub(x, A, b);}void power2(ZZ& x, long e){   if (e < 0) Error("power2: negative exponent");   set(x);   LeftShift(x, x, e);}   void conv(ZZ& x, const char *s){   long c;   long sign;   long ndigits;   long acc;   long i = 0;   static ZZ a;   if (!s) Error("bad ZZ input");   if (!iodigits) InitZZIO();   a = 0;   c = s[i];   while (c == ' ' || c == '\n' || c == '\t') {      i++;      c = s[i];   }   if (c == '-') {      sign = -1;      i++;      c = s[i];   }   else      sign = 1;   if (c < '0' || c > '9') Error("bad ZZ input");   ndigits = 0;   acc = 0;   while (c >= '0' && c <= '9') {      acc = acc*10 + c - '0';      ndigits++;      if (ndigits == iodigits) {         mul(a, a, ioradix);         add(a, a, acc);         ndigits = 0;         acc = 0;      }      i++;      c = s[i];   }   if (ndigits != 0) {      long mpy = 1;      while (ndigits > 0) {         mpy = mpy * 10;         ndigits--;      }      mul(a, a, mpy);      add(a, a, acc);   }   if (sign == -1)      negate(a, a);   x = a;}void bit_and(ZZ& x, const ZZ& a, long b){   static ZZ B;   conv(B, b);   bit_and(x, a, B);}void bit_or(ZZ& x, const ZZ& a, long b){   static ZZ B;   conv(B, b);   bit_or(x, a, B);}void bit_xor(ZZ& x, const ZZ& a, long b){   static ZZ B;   conv(B, b);   bit_xor(x, a, B);}long power_long(long a, long e){   if (e < 0) Error("power_long: negative exponent");   if (e == 0) return 1;   if (a == 1) return 1;   if (a == -1) {      if (e & 1)         return -1;      else         return 1;   }   long res = 1;   long i;   for (i = 0; i < e; i++)      res *= a;   return res;}//  RANDOM NUMBER GENERATION// Idea for this PRNG.  Iteratively hash seed using md5 // to get 256 bytes to initialize arc4.// Then use arc4 to get a pseudo-random byte stream.// I've taken care that the pseudo-random numbers generated by// the routines RandomBnd, RandomBits, and RandomLen // are completely platform independent.// I make use of the md5 compression function,// which I've modified to work on 64-bit machines/* *  BEGIN RSA's md5 stuff * *//* ********************************************************************** ** md5.c                                                            ** ** RSA Data Security, Inc. MD5 Message Digest Algorithm             ** ** Created: 2/17/90 RLR                                             ** ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version                  ** ********************************************************************** *//* ********************************************************************** ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** **                                                                  ** ** License to copy and use this software is granted provided that   ** ** it is identified as the "RSA Data Security, Inc. MD5 Message     ** ** Digest Algorithm" in all material mentioning or referencing this ** ** software or this function.                                       ** **                                                                  ** ** License is also granted to make and use derivative works         ** ** provided that such works are identified as "derived from the RSA ** ** Data Security, Inc. MD5 Message Digest Algorithm" in all         ** ** material mentioning or referencing the derived work.             ** **                                                                  ** ** RSA Data Security, Inc. makes no representations concerning      ** ** either the merchantability of this software or the suitability   ** ** of this software for any particular purpose.  It is provided "as ** ** is" without express or implied warranty of any kind.             ** **                                                                  ** ** These notices must be retained in any copies of any part of this ** ** documentation and/or software.                                   ** ********************************************************************** */#if (NTL_BITS_PER_LONG <= 32)#define TRUNC32(x) (x)#else#define TRUNC32(x) ((x) & ((1UL << 32)-1UL))#endif/* F, G and H are basic MD5 functions: selection, majority, parity */#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))#define H(x, y, z) ((x) ^ (y) ^ (z))#define I(x, y, z) (TRUNC32((y) ^ ((x) | (~z)))) /* ROTATE_LEFT rotates x left n bits */#define ROTATE_LEFT(x, n) (TRUNC32(((x) << (n)) | ((x) >> (32-(n)))))/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 *//* Rotation is separate from addition to prevent recomputation */#define FF(a, b, c, d, x, s, ac) \  {(a) = TRUNC32((a) + F((b), (c), (d)) + (x) + (ac)); \   (a) = ROTATE_LEFT((a), (s)); \   (a) = TRUNC32((a) + (b)); \  }#define GG(a, b, c, d, x, s, ac) \  {(a) = TRUNC32((a) + G((b), (c), (d)) + (x) + (ac)); \   (a) = ROTATE_LEFT((a), (s)); \   (a) = TRUNC32((a) + (b)); \  }#define HH(a, b, c, d, x, s, ac) \  {(a) = TRUNC32((a) + H((b), (c), (d)) + (x) + (ac)); \   (a) = ROTATE_LEFT((a), (s)); \   (a) = TRUNC32((a) + (b)); \  }#define II(a, b, c, d, x, s, ac) \  {(a) = TRUNC32((a) + I((b), (c), (d)) + (x) + (ac)); \   (a) = ROTATE_LEFT((a), (s)); \   (a) = TRUNC32((a) + (b)); \  }staticvoid MD5_default_IV(unsigned long *buf){   buf[0] = 0x67452301UL;   buf[1] = 0xefcdab89UL;   buf[2] = 0x98badcfeUL;   buf[3] = 0x10325476UL;}/* Basic MD5 step. Transform buf based on in. */staticvoid MD5_compress(unsigned long *buf, unsigned long *in){  unsigned long a = buf[0], b = buf[1], c = buf[2], d = buf[3];  /* Round 1 */#define S11 7#define S12 12#define S13 17#define S14 22  FF ( a, b, c, d, in[ 0], S11, 3614090360UL); /* 1 */  FF ( d, a, b, c, in[ 1], S12, 3905402710UL); /* 2 */  FF ( c, d, a, b, in[ 2], S13,  606105819UL); /* 3 */  FF ( b, c, d, a, in[ 3], S14, 3250441966UL); /* 4 */  FF ( a, b, c, d, in[ 4], S11, 4118548399UL); /* 5 */  FF ( d, a, b, c, in[ 5], S12, 1200080426UL); /* 6 */  FF ( c, d, a, b, in[ 6], S13, 2821735955UL); /* 7 */  FF ( b, c, d, a, in[ 7], S14, 4249261313UL); /* 8 */  FF ( a, b, c, d, in[ 8], S11, 1770035416UL); /* 9 */  FF ( d, a, b, c, in[ 9], S12, 2336552879UL); /* 10 */  FF ( c, d, a, b, in[10], S13, 4294925233UL); /* 11 */  FF ( b, c, d, a, in[11], S14, 2304563134UL); /* 12 */  FF ( a, b, c, d, in[12], S11, 1804603682UL); /* 13 */  FF ( d, a, b, c, in[13], S12, 4254626195UL); /* 14 */  FF ( c, d, a, b, in[14], S13, 2792965006UL); /* 15 */  FF ( b, c, d, a, in[15], S14, 1236535329UL); /* 16 */  /* Round 2 */#define S21 5#define S22 9#define S23 14#define S24 20  GG ( a, b, c, d, in[ 1], S21, 4129170786UL); /* 17 */  GG ( d, a, b, c, in[ 6], S22, 3225465664UL); /* 18 */  GG ( c, d, a, b, in[11], S23,  643717713UL); /* 19 */  GG ( b, c, d, a, in[ 0], S24, 3921069994UL); /* 20 */  GG ( a, b, c, d, in[ 5], S21, 3593408605UL); /* 21 */  GG ( d, a, b, c, in[10], S22,   38016083UL); /* 22 */  GG ( c, d, a, b, in[15], S23, 3634488961UL); /* 23 */  GG ( b, c, d, a, in[ 4], S24, 3889429448UL); /* 24 */  GG ( a, b, c, d, in[ 9], S21,  568446438UL); /* 25 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -