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

📄 mh.c

📁 应用密码学手册-英文版,学习密码学和网络安全的好资料。
💻 C
字号:
/*
  Author:  Pate Williams (c) 1997

  Merkle-Hellman knapsack encryption. See "Handbook
  of Applied Cryptography" by Alfred J. Menezes et
  al Section 8.6.1 pages 300 - 302.
*/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "lip.h"

#define DEBUG

void MH_gen_keys(long n, verylong zB, long *pi,
                 verylong *zM, verylong *zW,
                 verylong *za, verylong *zb)
/* Merkle Hellman knapsack key generation */
{
  int found;
  long i, j, p, s;
  verylong zc = 0, zd = 0, zs = 0;

  /* initialize the psuedo random number generators */
  srand(time(NULL));
  zrstarts(time(NULL));
  /* find a superincreasing sequence b[i] */
  zzero(zM);
  do zrandomb(zB, &zb[0]); while (zscompare(zb[0], 0l) == 0);
  for (i = 1; i < n; i++) {
    zzero(&zs);
    for (j = 0; j < i; j++) {
      zadd(zs, zb[j], &zc);
      zcopy(zc, &zs);
    }
    do s = rand(); while (s == 0);
    zsadd(zs, s, &zc);
    zcopy(zc, &zb[i]);
    zadd(*zM, zc, &zs);
    zcopy(zs, zM);
  }
  do s = rand(); while (s == 0);
  zsadd(*zM, s, &zc);
  zcopy(zc, zM);
  /* select a random integer 1 <= W <= M - 1 such
     that gcd(W, M) = 1 */
  do {
    do zrandomb(*zM, zW); while (zscompare(*zW, 0l) == 0);
    zgcd(*zW, *zM, &zd);
  } while (zscompare(zd, 1l) != 0);
  /* select a random permutation of 0, 1, ..., n - 1 */
  for (i = 0; i < n; i++) {
    do {
      found = 0;
      p = rand() % n;
      for (j = 0; j < i && !found; j++)
        found = p == pi[j];
    } while (found);
    pi[i] = p;
  }
  /* compute the public key */
  for (i = 0; i < n; i++)
    zmulmod(*zW, zb[pi[i]], *zM, &za[i]);
  zfree(&zc);
  zfree(&zd);
  zfree(&zs);
}

void MH_encryption(char *m, long n, verylong *za,
                   verylong *zc)
/* m consists of n message bits one per character */
{
  long i;
  verylong zb = 0, zd = 0;

  zzero(zc);
  for (i = 0; i < n; i++) {
    zsmul(za[i], m[i], &zb);
    zadd(*zc, zb, &zd);
    zcopy(zd, zc);
  }
  zfree(&zb);
  zfree(&zd);
}

void Solve(char *x, long n, verylong zs, verylong *zb)
/* solves a superincreasing subset sum problem */
{
  long i;
  verylong za = 0, zt = 0;

  zcopy(zs, &zt);
  i = n - 1;
  while (i >= 0) {
    if (zcompare(zt, zb[i]) >= 0) {
      x[i] = 1;
      zsub(zt, zb[i], &za);
      zcopy(za, &zt);
    }
    else x[i] = 0;
    i--;
  }
  zfree(&za);
  zfree(&zt);
}

void MH_decryption(char *m, char *r, long n, long *pi,
                   verylong zc, verylong zM,
                   verylong zW, verylong *zb)
{
  long i;
  verylong za = 0, zd = 0;

  zinvmod(zW, zM, &za);
  zmulmod(za, zc, zM, &zd);
  Solve(r, n, zd, zb);
  for (i = 0; i < n; i++) m[i] = r[pi[i]];
}

int main(void)
{
  char m[8] = {1, 0, 1, 0, 1, 0, 1, 0}, r[8];
  long i, n = 8, pi[8];
  verylong zB = 0, zM = 0, zW = 0, zc = 0;
  verylong za[8], zb[8];

  zintoz(1024l, &zB);
  for (i = 0; i < n; i++) {
    za[i] = zb[i] = 0;
    printf("%d", m[i]);
  }
  printf("\n");
  MH_gen_keys(n, zB, pi, &zM, &zW, za, zb);
  #ifdef DEBUG
  zwriteln(zM);
  zwriteln(zW);
  for (i = 0; i < n; i++) {
    zwrite(zb[i]); printf(" ");
  }
  printf("\n");
  #endif
  MH_encryption(m, n, za, &zc);
  MH_decryption(m, r, n, pi, zc, zM, zW, zb);
  for (i = 0; i < n; i++) {
    zfree(&za[i]);
    zfree(&zb[i]);
    printf("%d", m[i]);
  }
  printf("\n");
  zfree(&zB);
  zfree(&zM);
  zfree(&zW);
  zfree(&zc);
  return 0;
}

⌨️ 快捷键说明

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