NTL cryptographic algorithm open source library -- large integer ZZ class

Keywords: Algorithm cryptology


Overview of this chapter

   The large integer ZZ class mainly realizes the representation of large integers of arbitrary length, the greatest common factor, Jacobi symbol and prime test. The author will show readers how NTL realizes the above functions step by step by analyzing the form of functions in ZZ.cpp source code one by one.

Calculate the maximum common factor (gcd)

(1) Fundamentals of Mathematics: (generalized) Euclidean Division

Knowledge reserve (theorem, public, formula)

·If b|a, then (a,b) = b;

·If a and B are two integers, then (a,b) = (b,a)

·If p is a prime, a is an integer, and p (  a. Then a and p are coprime

   It is proved that if (a,p) = D, there is d|p and d|a. Because P is prime, d = 1 or d = p

        For d = p, and p (  A is contradictory, so d = 1, that is, (a, p) = 1. The conclusion is true

·Let B be any positive integer, (0, b) = B

·Let a,b,c ≠ 0 and be an integer. If c|a,c|b, then c|(sa+tb). (if c|a,c|b, then C divides any linear combination of a and b)

   Proof: s*a+t*b   = s* θ*c+t*β*c = c*(s* θ+t* β)

·Let a,b and C be three integers that are not all zero. If a = q*b+c, where q is an integer, then (a,b) = (b,c)

   Proof: d = (a,b), = > d|a, d|b  => d|(a+(-q)b)   => d|c   , d|b    => D is the common factor of b,c = > D ≤ d1

        d1 = (b,c), similarly: D1 ≤ D. = > d1=d  => (a,b) = (b,c)

Generalized Euclidean Division:

Euclidean algorithm Rolling phase division , which is used to calculate two Nonnegative integer a. b greatest common divisor . The application fields are mathematics And computer. Calculation formula gcd(a,b) = gcd(b,a mod b). Euclidean algorithm is used to find the maximum common divisor of two positive integers. Euclid, an ancient Greek mathematician, first described this algorithm in his book The Elements, so it was named Euclid algorithm. The extended Euclidean algorithm can be used to RSA Encryption and other fields.

If it is necessary to find the maximum common divisor of two positive integers, 1997 and 615, the Euclidean algorithm is carried out as follows:

1997 / 615 = 3 (remaining 152)

615 / 152 = 4 (remaining 7)

152 / 7 = 21 (remaining 5)

7 / 5 = 1 (remaining 2)

5 / 2 = 2 (remaining 1)

2 / 1 = 2 (remaining 0)

So far, the maximum common divisor is 1

Divide repeatedly with divisor and remainder. When the remainder is 0, take the divisor of the current formula as the maximum common divisor, so the maximum common divisor 1 of 1997 and 615 is obtained.

(2) Code analysis:

Finding the greatest common factor by generalized Euclidean Division

long GCD(long a, long b)


   long u, v, t, x;

   if (a < 0) {

      if (a < -NTL_MAX_LONG) ResourceError("GCD: integer overflow");

      a = -a;                    //Judge whether the input long integer overflows


   if (b < 0) {

      if (b < -NTL_MAX_LONG) ResourceError("GCD: integer overflow");

      b = -b;                   //Judge whether the input long integer overflows


   if (b==0)

      x = a;

   else {

      u = a;

      v = b;

      do {

         t = u % v;       //a = qb+r Euclidean core algorithm (see above knowledge reserve - generalized Euclidean division for details)

         u = v;

         v = t;

      } while (v != 0);

      x = u;


   return x;


Bezu formula (inverse method of generalized Euclidean)

Using the algorithm step by step backtracking of generalized Euclidean, we can find such a group of (x,y) (see the code for details) @Yuanjie ~ shanghuai)

·Bezu formula:

A simple way to find s and t is to use the generalized Euclidean division method to obtain (a,b), that is, the maximum common factor of a and B, and then replace it to obtain the integer s and t.

2.2.4 about modular operation

Fundamentals of Mathematics: multiplication inverse element solution

Examples are as follows:

Multiplicative inverse: if A and N are known to be coprime, there is an integer B such that A*B=1(mod N)

Use the generalized Euclidean division (rolling Division) to divide the remainder N, and then arrange the quotient in reverse order (as shown in the black words in the first line of the above figure), and then use the deformation of bezu formula to calculate the relevant data in the third line of the above figure (the first number in the third line is always 1, and the second number is the same as the first number in the first line) For example: 5 = 1 + 1 * 4; 9 = 4 + 5 * 1; 14 = 5 + 9 * 1; 23 = 9 + 14 * 1; 37 = 14 + 23 * 1

Finally, 550 is the multiplicative inverse of 550 with respect to module 1769, that is, (550 * 550) mod 1769 = 1.

long InvModStatus(long& x, long a, long n)  //Find the multiplicative inverse of a with respect to n and assign it to X. at the same time, return whether a and ns are mutually prime.


   long d, s, t;

   XGCD(d, s, t, a, n);

   if (d != 1) {

      x = d;

      return 1;


   else {

      if (s < 0)

         x = s + n;                      //Specifies that if the inverse of multiplication is positive, if it is not a positive number, double n shall be added to turn it into a positive number output


         x = s;

      return 0;



long InvMod(long a, long n)


   long d, s, t;

   XGCD(d, s, t, a, n);

   if (d != 1) {

      InvModError("InvMod: inverse undefined");


   if (s < 0)

      return s + n;


      return s;


long PowerMod(long a, long ee, long n)


   long x, y;

   unsigned long e;

   if (ee < 0)

      e = - ((unsigned long) ee);


      e = ee;

   x = 1;

   y = a;

   while (e) {

      if (e & 1) x = MulMod(x, y, n);   //The algorithm is accelerated. The product is calculated twice in one cycle. Through the right shift instruction and bitwise fetch and instruction, the fast cycle iteration is achieved, the number of cycles is reduced and the operation speed is accelerated.

                                       //Using the formula: ((a{x} mod n)*(a{y} mod n))mod n = a{x+y} mod n   --- See you later

      y = MulMod(y, y, n);

      e = e >> 1;


   if (ee < 0) x = InvMod(x, n);

   return x;


Proof: ((a{x} mod n)*(a{y} mod n))mod n = a{x+y} mod n

Left side of the original formula = ((a{x}-k1*n)*(a{y}-k2*n))mod n

         = (a{x+y}-n(k2* a{x}+k1* a{y})+n{2}*k1*k2)mod n

        = (a{x+y}) mod n

Posted by burfo on Tue, 05 Oct 2021 12:52:38 -0700