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

📄 garner.c

📁 应用密码学这本书的源代码
💻 C
字号:
/*

  Author:  Pate Williams (c) 1997



  14.71 Algorithm Garner's Algorithm for CRT

  See "Handbook of Applied Cryptography" by

  Alfred J. Menezes et al page 612.

*/



#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#include "lip.h"



#define CRT_SIZE 8192l



void Garner(long t, verylong *zm, verylong *zv, verylong *zx)

/* solution of the Chinese remaider theorem */

{

  long i, j;

  verylong za = 0, zb = 0, zu = 0, zC[CRT_SIZE];



  for (i = 0; i < CRT_SIZE; i++) zC[i] = 0;

  for (i = 1; i < t; i++) {

    zone(&zC[i]);

    for (j = 0; j <= i - 1; j++) {

      zinvmod(zm[j], zm[i], &zu);

      zmulmod(zu, zC[i], zm[i], &za);

      zcopy(za, &zC[i]);

    }

  }

  zcopy(zv[0], &zu);

  zcopy(zu, zx);

  for (i = 1; i < t; i++) {

    zsub(zv[i], *zx, &za);

    zmulmod(za, zC[i], zm[i], &zu);

    zone(&za);

    for (j = 0; j <= i - 1; j++) {

      zmul(za, zm[j], &zb);

      zcopy(zb, &za);

    }

    zmul(za, zu, &zb);

    zadd(*zx, zb, &za);

    zcopy(za, zx);

  }

  zfree(&za);

  zfree(&zb);

  zfree(&zu);

  for (i = 0; i < CRT_SIZE; i++) zfree(&zC[i]);

}



long OddRandom(long bit_length)

{

  long i, mask = 1, n;



  bit_length--;

  for (i = 1; i <= bit_length; i++)

    mask |= 1 << i;

  if (bit_length < 16)

    n = (1 << bit_length) | rand();

  else

    n = (1 << bit_length) | (rand() << 16) | rand();

  n &= mask;

  if ((n & 1) == 0) n++;

  return n;

}



void PROVABLE_PRIME(long k, verylong *zn)

{

  double c, r, s;

  int success;

  long B, m, n, p, sqrtn;

  verylong zI = 0, zR = 0, za = 0, zb = 0, zc = 0;

  verylong zd = 0, zk = 0, zl = 0, zq = 0, zu = 0;



  if (k <= 20) {

    do {

      n = OddRandom(k);

      sqrtn = sqrt(n);

      zpstart2();

      do p = zpnext(); while (n % p != 0 && p < sqrtn);

    } while (p < sqrtn);

    zintoz(n, zn);

  }

  else {

    c = 0.1;

    m = 20;

    B = c * k * k;

    if (k > 2 * m)

      do {

        s = rand() / (double) RAND_MAX;

        r = pow(2.0, s - 1.0);

      } while (k - r * k <= m);

    else

      r = 0.5;

    PROVABLE_PRIME(r * k + 1, &zq);

    zone(&za);

    zlshift(za, k - 1, &zk);

    zcopy(zq, &za);

    zlshift(za, 1l, &zl);

    zdiv(zk, zl, &zI, &za);

    zsadd(zI, 1l, &zl);

    zlshift(zI, 1l, &zu);

    success = 0;

    while (!success) {

      do zrandomb(zu, &zR); while (zcompare(zR, zl) < 0);

      zmul(zR, zq, &za);

      zlshift(za, 1l, &zb);

      zsadd(zb, 1l, zn);

      zcopy(zR, &za);

      zlshift(za, 1l, &zR);

      zpstart2();

      p = zpnext();

      while (zsmod(*zn, p) != 0 && p < B) p = zpnext();

      if (p >= B) {

        zcopy(*zn, &zc);

        zsadd(zc, - 2l, &zb);

        do

          zrandomb(*zn, &za);

        while (zscompare(za, 2l) < 0 || zcompare(za, zb) > 0);

        zsadd(*zn, - 1l, &zc);

        zexpmod(za, zc, *zn, &zb);

        if (zscompare(zb, 1l) == 0) {

          zexpmod(za, zR, *zn, &zb);

          zcopy(zb, &zd);

          zsadd(zd, - 1l, &zb);

          zgcd(zb, *zn, &zd);

          success = zscompare(zd, 1l) == 0;

        }

      }

    }

  }

  zfree(&zI);

  zfree(&zR);

  zfree(&za);

  zfree(&zb);

  zfree(&zc);

  zfree(&zd);

  zfree(&zk);

  zfree(&zl);

  zfree(&zq);

  zfree(&zu);

}



void RSA_gen_keys(long length, verylong *zd,

                  verylong *ze, verylong *zp,

                  verylong *zq)

{

  verylong zp1 = 0, zq1 = 0;

  verylong zphi = 0, zx = 0;



  srand(time(NULL));

  zrstarts(time(NULL));

  PROVABLE_PRIME(length, zp);

  PROVABLE_PRIME(length, zq);

  zsadd(*zp, - 1l, &zp1);

  zsadd(*zq, - 1l, &zq1);

  zmul(zp1, zq1, &zphi);

  do {

    do zrandomb(zphi, ze); while (zscompare(*ze, 1l) <= 0);

    zgcd(*ze, zphi, &zx);

  } while (zscompare(zx, 1l) != 0);

  zinvmod(*ze, zphi, zd);

  zfree(&zp1);

  zfree(&zq1);

  zfree(&zphi);

  zfree(&zx);

}



void RSA_exponentiation(verylong zx, verylong zd,

                        verylong zp, verylong zq,

                        verylong *zM)

{

  verylong zdp = 0, zdq = 0, zp1 = 0, zq1 = 0;

  verylong zm[2], zv[2];



  zsadd(zp, - 1l, &zp1);

  zsadd(zq, - 1l, &zq1);

  zmod(zd, zp1, &zdp);

  zmod(zd, zq1, &zdq);

  zm[0] = zm[1] = zv[0] = zv[1] = 0;

  zcopy(zp, &zm[0]);

  zcopy(zq, &zm[1]);

  zexpmod(zx, zdp, zp, &zv[0]);

  zexpmod(zx, zdq, zq, &zv[1]);

  Garner(2l, zm, zv, zM);

  zfree(&zdp);

  zfree(&zdq);

  zfree(&zp1);

  zfree(&zq1);

  zfree(&zm[0]);

  zfree(&zm[1]);

  zfree(&zv[0]);

  zfree(&zv[1]);

}



int main(void)

{

  verylong zM = 0, zN = 0, zd = 0, ze = 0, zn = 0;

  verylong zp = 0, zq = 0, zx = 0;



  RSA_gen_keys(128l, &zd, &ze, &zp, &zq);

  zintoz(65537l, &zx);

  RSA_exponentiation(zx, zd, zp, zq, &zM);

  zmul(zp, zq, &zn);

  zexpmod(zx, zd, zn, &zN);

  if (zcompare(zM, zN) == 0)

    printf("RSA_exponentiation confirmed\n");

  else

    printf("*error*\nin RSA_exponentiation\n");

  zfree(&zM);

  zfree(&zN);

  zfree(&zd);

  zfree(&ze);

  zfree(&zn);

  zfree(&zp);

  zfree(&zq);

  zfree(&zx);

  return 0;

}

⌨️ 快捷键说明

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