首页
社区
课程
招聘
请问在哪可以找到RSA或DES的C语言源代码?
发表于: 2005-4-25 11:45 7035

请问在哪可以找到RSA或DES的C语言源代码?

2005-4-25 11:45
7035
收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 3686
活跃值: (1036)
能力值: (RANK:760 )
在线值:
发帖
回帖
粉丝
2
像这样找算法源代码的问题最好的解决办法就是用搜索引擎,
如google,或者http://www.koders.com/也不错.
2005-4-25 12:46
0
雪    币: 208
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
//rsa算法
/*------------------------------------------------vlong.h----------------------------------------------------*/

//长整数类,可随意定义其长度
class vlong                        
{
public:

  // 重载常用算术运算符
  friend vlong operator +( const vlong& x, const vlong& y );
  friend vlong operator -( const vlong& x, const vlong& y );
  friend vlong operator *( const vlong& x, const vlong& y );
  friend vlong operator /( const vlong& x, const vlong& y );
  friend vlong operator %( const vlong& x, const vlong& y );
  vlong& operator +=( const vlong& x );
  vlong& operator -=( const vlong& x );

  // 重载常用比较运算符
  friend inline int operator !=( const vlong& x, const vlong& y ){ return x.cf( y ) != 0; }
  friend inline int operator ==( const vlong& x, const vlong& y ){ return x.cf( y ) == 0; }
  friend inline int operator >=( const vlong& x, const vlong& y ){ return x.cf( y ) >= 0; }
  friend inline int operator <=( const vlong& x, const vlong& y ){ return x.cf( y ) <= 0; }
  friend inline int operator > ( const vlong& x, const vlong& y ){ return x.cf( y ) > 0; }
  friend inline int operator < ( const vlong& x, const vlong& y ){ return x.cf( y ) < 0; }

  // 构造函数
  vlong ( unsigned x=0 );
  vlong ( const vlong& x );

  // 析构函数
  ~vlong();

// 转换操作符
  operator unsigned ();
  vlong& operator =(const vlong& x);

private:
  class vlong_value * value;
  int negative;
  int cf( const vlong x ) const;
  void docopy();
  friend class monty;
};

vlong modexp( const vlong & x, const vlong & e, const vlong & m ); // m必须为质数
vlong gcd( const vlong &X, const vlong &Y ); // 求最大因子
vlong modinv( const vlong &a, const vlong &m ); //Euclid算法

/*-----------------------------------------------RSA.h--------------------------------------------------*/
#include "vlong.h"

class public_key
{
  public:
  vlong m,e;
  vlong encrypt( const vlong& plain ); // Requires 0 <= plain < m
};

class private_key : public public_key
{
  public:
  vlong p,q;
  vlong decrypt( const vlong& cipher );

  void create( const char * r1, const char * r2 );
  // r1 和 r2 为以null结尾的字符串,长度约为35个字符(以保证n约为500位模块)
};

//将以0结尾的字符串转化为长整数
static vlong from_str( const char * s )
{
  vlong x = 0;
  while (*s)
  {
    x = x * vlong(256) + (vlong)(unsigned char)*s;
    s += 1;
  }
  return x;
}

/*---------------------------------------------vlong.cpp*---------------------------------------------------------*/
#include "vlong.h"

class vlong_value;

/*-------------------------------以下为flex_unit类定义与实现----------------------------*/

//flex_unit类:提供存储分配与索引检查的类
class flex_unit                                       
{
  unsigned * a;                                        //内存unsigned int单元数组
  unsigned z;                                        //分配单元数
public:
  unsigned n;                                        //已使用的单元数(只读属性)
  flex_unit();
  ~flex_unit();
  void clear();                                         //已使用单元数n清0
  unsigned get( unsigned i ) const;                //获取第i个单元值
  void set( unsigned i, unsigned x );           //设置第i个单元值
  void reserve( unsigned x );          //扩展存储区

  //有时间要求的乘法
  void fast_mul( flex_unit &x, flex_unit &y, unsigned n );
};

//按索引获取单元值
unsigned flex_unit::get( unsigned i ) const
{
  if ( i >= n ) return 0;
  return a[i];
}

//清空
void flex_unit::clear()
{
   n = 0;
}

//构造函数
flex_unit::flex_unit()
{
  z = 0;
  a = 0;
  n = 0;
}

//析构函数
flex_unit::~flex_unit()
{
  unsigned i=z;
  while (i)
  {
          i-=1;
           a[i] = 0;
  }
  delete [] a;
}

//改变大数尺寸
void flex_unit::reserve( unsigned x )
{
  if (x > z)
  {
    unsigned * na = new unsigned[x];
    for (unsigned i=0;i<n;i+=1) na[i] = a[i];
    delete [] a;
    a = na;
    z = x;
  }
}

//根据索引设置元素值
void flex_unit::set( unsigned i, unsigned x )
{
  if ( i < n )
  {
    a[i] = x;
    if (x==0)
    while (n && a[n-1]==0)                        //去除高位0
                n-=1;                
  }
  else if ( x )
  {
    reserve(i+1);
    for (unsigned j=n;j<i;j+=1) a[j] = 0;
    a[i] = x;
    n = i+1;
  }
}

#define BPU ( 8*sizeof(unsigned) )                //unsigned int类型bit数
#define lo(x) ( (x) & ((1<<(BPU/2))-1) )         //unsigned int低半部分
#define hi(x) ( (x) >> (BPU/2) )                        //unsigned int高半部分
#define lh(x) ( (x) << (BPU/2) )                 //使低半部分左移至高半部分

//快速乘法
void flex_unit::fast_mul( flex_unit &x, flex_unit &y, unsigned keep )
{
  // *this = (x*y) % (2**keep)
  unsigned i,limit = (keep+BPU-1)/BPU;        //运算结果单元数
  reserve(limit);
  for (i=0; i<limit; i+=1)
     a[i] = 0;
  unsigned min = x.n;
  if (min>limit)
     min = limit;
  for (i=0; i<min; i+=1)
  {
    unsigned m = x.a[i];
    unsigned c = 0;
    unsigned min = i+y.n;
    if (min>limit) min = limit;
    for ( unsigned j=i; j<min; j+=1 )
    {
      //此处代码为运算关键,可使用机器或汇编代码以加快速度
      // c:a[j] = a[j] + c + m*y.a[j-i];
      unsigned w, v = a[j], p = y.a[j-i];
      v += c; c = ( v < c );
      w = lo(p)*lo(m); v += w; c += ( v < w );
      w = lo(p)*hi(m); c += hi(w); w = lh(w); v += w; c += ( v < w );
      w = hi(p)*lo(m); c += hi(w); w = lh(w); v += w; c += ( v < w );
      c += hi(p) * hi(m);
      a[j] = v;
    }
    while ( c && j<limit )
    {
      a[j] += c;
      c = a[j] < c;
      j += 1;
    }
  }

  //去除不必要的bit
  keep %= BPU;
  if (keep)
    a[limit-1] &= (1<<keep)-1;

   //计算使用单元数
  while (limit && a[limit-1]==0)
     limit-=1;
  n = limit;
};

/*---------------------------------以上为flex_unit类定义与实现----------------------------*/

/*-------------------------------以下为vlong_value类定义与实现----------------------------*/

class vlong_value : public flex_unit        //继承自flex_unit,负责vlong类内存管理
{
  public:
  unsigned share;                               
  int is_zero() const;
  int test( unsigned i ) const;
  unsigned bits() const;
  int cf( vlong_value& x ) const;
  void shl();
  void shr();
  void shr( unsigned n );
  void add( vlong_value& x );
  void subtract( vlong_value& x );
  void init( unsigned x );
  void copy( vlong_value& x );
  operator unsigned();                         //转换至unsigned int类型,不安全
  vlong_value();
  void mul( vlong_value& x, vlong_value& y );
  void divide( vlong_value& x, vlong_value& y, vlong_value& rem );
};

// 将大数转换为无符号整数
vlong_value::operator unsigned()
{
  return get(0);
}

// 测试大数是否为0
int vlong_value::is_zero() const
{
  return n==0;
}

//测试第i位(bit)值是否为0
int vlong_value::test( unsigned i ) const
{
   return ( get(i/BPU) & (1<<(i%BPU)) ) != 0;
}

//获取大数位(bit)数
unsigned vlong_value::bits() const
{
  unsigned x = n*BPU;
  while (x && test(x-1)==0) x -= 1;
  return x;
}

//比较两个大数值大小
int vlong_value::cf( vlong_value& x ) const
{
  if ( n > x.n ) return +1;
  if ( n < x.n ) return -1;
  unsigned i = n;
  while (i)
  {
    i -= 1;
    if ( get(i) > x.get(i) ) return +1;
    if ( get(i) < x.get(i) ) return -1;
  }
  return 0;
}

//按位左移
void vlong_value::shl()
{
  unsigned carry = 0;
  unsigned N = n;
  for (unsigned i=0;i<=N;i+=1)
  {
    unsigned u = get(i);
    set(i,(u<<1)+carry);
    carry = u>>(BPU-1);
  }
}

//按位右移
void vlong_value::shr()
{
  unsigned carry = 0;
  unsigned i=n;
  while (i)
  {
    i -= 1;
    unsigned u = get(i);
    set(i,(u>>1)+carry);
    carry = u<<(BPU-1);
  }
}

//左移x位
void vlong_value::shr( unsigned x )
{
  unsigned delta = x/BPU;
x %= BPU;
  for (unsigned i=0;i<n;i+=1)
  {
    unsigned u = get(i+delta);
    if (x)
    {
      u >>= x;
      u += get(i+delta+1) << (BPU-x);
    }
    set(i,u);
  }
}

//大数加法
void vlong_value::add( vlong_value & x )
{
  unsigned carry = 0;
  unsigned max = n; if (max<x.n) max = x.n;
  reserve(max);
  for (unsigned i=0;i<max+1;i+=1)
  {
    unsigned u = get(i);
    u = u + carry; carry = ( u < carry );
    unsigned ux = x.get(i);
    u = u + ux; carry += ( u < ux );
    set(i,u);
  }
}

//大数减法
void vlong_value::subtract( vlong_value & x )
{
  unsigned carry = 0;
  unsigned N = n;
  for (unsigned i=0;i<N;i+=1)
  {
    unsigned ux = x.get(i);
    ux += carry;
    if ( ux >= carry )
    {
      unsigned u = get(i);
      unsigned nu = u - ux;
      carry = nu > u;
      set(i,nu);
    }
  }
}

//使用无符号整数x初始化大数
void vlong_value::init( unsigned x )
{
  clear();
  set(0,x);
}

//将参数x(大数类型)值赋给本实例
void vlong_value::copy( vlong_value& x )
{
  clear();
  unsigned i=x.n;
  while (i) { i -= 1; set( i, x.get(i) ); }
}
       
vlong_value::vlong_value()
{
  share = 0;
}

//大数乘法
void vlong_value::mul( vlong_value& x, vlong_value& y )
{
  fast_mul( x, y, x.bits()+y.bits() );
}

//大数除法
void vlong_value::divide( vlong_value& x, vlong_value& y, vlong_value& rem )
{
  init(0);
  rem.copy(x);
  vlong_value m,s;
  m.copy(y);
  s.init(1);
  while ( rem.cf(m) > 0 )
  {
    m.shl();
    s.shl();
  }
  while ( rem.cf(y) >= 0 )
  {
    while ( rem.cf(m) < 0 )
    {
      m.shr();
      s.shr();
    }
    rem.subtract( m );
    add( s );
  }
}

/*---------------------以上为vlong_value类定义与实现---------------------------*/

/*-----------------------------------以下为vlong类实现-------------------------------*/

void vlong::docopy()
{
  if ( value->share )
  {
    value->share -= 1;
    vlong_value * nv = new vlong_value;
    nv->copy(*value);
    value = nv;
  }
}

//大数比较
int vlong::cf( const vlong x ) const
{
  int neg = negative && !value->is_zero();
  if ( neg == (x.negative && !x.value->is_zero()) )
    return value->cf( *x.value );
  else if ( neg ) return -1;
  else return +1;
}

//构造函数
vlong::vlong (unsigned x)
{
  value = new vlong_value;
  negative = 0;
  value->init(x);
}

//复制构造函数
vlong::vlong ( const vlong& x )
{
  negative = x.negative;
  value = x.value;
  value->share += 1;
}

//赋值函数
vlong& vlong::operator =(const vlong& x)
{
  if ( value->share ) value->share -=1; else delete value;
  value = x.value;
  value->share += 1;
  negative = x.negative;
  return *this;
}

//析构函数
vlong::~vlong()
{
  if ( value->share ) value->share -=1; else delete value;
}

//unsigned转换符,将大数转换为无符号整数
vlong::operator unsigned () // conversion to unsigned
{
  return *value;
}

//重载+=运算符
vlong& vlong::operator +=(const vlong& x)
{
  if ( negative == x.negative )
  {
    docopy();
    value->add( *x.value );
  }
  else if ( value->cf( *x.value ) >= 0 )
  {
    docopy();
    value->subtract( *x.value );
  }
  else
  {
    vlong tmp = *this;
    *this = x;
    *this += tmp;
  }
  return *this;
}

//重载-=运算符
vlong& vlong::operator -=(const vlong& x)
{
  if ( negative != x.negative )
  {
    docopy();
    value->add( *x.value );
  }
  else if ( value->cf( *x.value ) >= 0 )
  {
    docopy();
    value->subtract( *x.value );
  }
  else
  {
    vlong tmp = *this;
    *this = x;
    *this -= tmp;
    negative = 1 - negative;
  }
  return *this;
}

//重载 + 运算符,大数加法
vlong operator +( const vlong& x, const vlong& y )
{
  vlong result = x;
  result += y;
  return result;
}

//重载 - 运算符,大数减法
vlong operator -( const vlong& x, const vlong& y )
{
  vlong result = x;
  result -= y;
  return result;
}

//重载 * 运算符,大数乘法
vlong operator *( const vlong& x, const vlong& y )
{
  vlong result;
  result.value->mul( *x.value, *y.value );
  result.negative = x.negative ^ y.negative;
  return result;
}

//重载 / 运算符,大数除法
vlong operator /( const vlong& x, const vlong& y )
{
  vlong result;
  vlong_value rem;
  result.value->divide( *x.value, *y.value, rem );
  result.negative = x.negative ^ y.negative;
  return result;
}

//重载 % 运算符,大数求模
vlong operator %( const vlong& x, const vlong& y )
{
  vlong result;
  vlong_value divide;
  divide.divide( *x.value, *y.value, *result.value );
  result.negative = x.negative;
  return result;
}

//辗转相除求最大因子
vlong gcd( const vlong &X, const vlong &Y )
{
  vlong x=X, y=Y;
  while (1)
  {
    if ( y == (vlong)0 ) return x;
    x = x % y;
    if ( x == (vlong)0 ) return y;
    y = y % x;
  }
}

//密钥产生流程最后一步,Euclid 算法
// 返回在1到m-1之间的长整数i,使i*a = 1 mod m
// a必须为在1到m-1之间的长整数
vlong modinv( const vlong &a, const vlong &m )
{
  vlong j=1,i=0,b=m,c=a,x,y;
  while ( c != (vlong)0 )
  {
    x = b / c;
    y = b - x*c;
    b = c;
    c = y;
    y = j;
    j = i - j*x;
    i = y;
  }
  if ( i < (vlong)0 )
    i += m;
  return i;
}

/*-----------------------------------以下为vlong类实现-------------------------------*/

/*--------------------------以下为monty类定义与实现-------------------------------*/

//monty:求模与幂的相关类,主要用于分块加密与解密
//加密: = ^e ( mod n )
//解密: = ^d ( mod n )       
class monty        
{
  vlong R,R1,m,n1;
  vlong T,k;                 //工作寄存器
  unsigned N;                //R的位(bit)数
  void mul( vlong &x, const vlong &y );
public:
  vlong exp( const vlong &x, const vlong &e );
  monty( const vlong &M );
};

//赋M为默认除数,即加/解密式中的n
monty::monty( const vlong &M )
{
  m = M;
  N = 0;
  R = 1;
  while ( R < M )
  {
     R += R;
     N += 1;
  }
  R1 = modinv( R-m, m );
  n1 = R - modinv( m, R );
}

void monty::mul( vlong &x, const vlong &y )
{
  // T = x*y;
  T.value->fast_mul( *x.value, *y.value, N*2 );

  // k = ( T * n1 ) % R;
  k.value->fast_mul( *T.value, *n1.value, N );

  // x = ( T + k*m ) / R;
  x.value->fast_mul( *k.value, *m.value, N*2 );
  x += T;
  x.value->shr( N );

  if (x>=m) x -= m;
}

//返回值= (x^e)%(this->m)
vlong monty::exp( const vlong &x, const vlong &e )
{
  vlong result = R-m;
vlong t = ( x * R ) % m;
  unsigned bits = e.value->bits();
  unsigned i = 0;
  while (1)
  {
    if ( e.value->test(i) )
      mul( result, t);
    i += 1;
    if ( i == bits ) break;
    mul( t, t );
  }
  return ( result * R1 ) % m;
}

//返回值= (x^e)%m
vlong modexp( const vlong & x, const vlong & e, const vlong & m )
{
  monty me(m);
  return me.exp( x,e );
}

/*-----------------------------------------------RSA.cpp-----------------------------------------------*/
#include "rsa.h"

/*---------------------以下为prime_factory类定义与实现-------------------*/

//prime_factory:用于产生质数
class prime_factory
{
  unsigned np;
  unsigned *pl;
  public:
  prime_factory();
  ~prime_factory();
  vlong find_prime( vlong & start );
};

//判定是否有很大概率为质数
static int is_probable_prime( const vlong &p )
{
  //基于费马小定理:若p是任一质数, a 是任一整数, 则 a^p = 1 mod p 。换句话说,
  //如果 a 和 p 互质, 则 a^(p-1) == 1 mod p。将{2,3,5,7}值分别代入a,若上式均成立,
  //则p为质数的概率极大
  const rep = 4;
  const unsigned any[rep] = { 2,3,5,7 };
  for ( unsigned i=0; i<rep; i+=1 )
    if ( modexp( any[i], p-(vlong)1, p ) != (vlong)1 )
      return 0;
  return 1;
}

//构造小质数表
prime_factory::prime_factory()
{
  np = 0;
  unsigned NP = 200;
  pl = new unsigned[NP];

  //初始化质数表
  unsigned SS = 8*NP;                 //粗略估计质数表上限
  char * b = new char[SS+1];
  for (unsigned i=0;i<=SS;i+=1)
        b[i] = 1;
  unsigned p = 2;
  while (1)
  {
    // skip composites
    while ( b

== 0 ) p += 1;
    if ( p == SS ) break;
    pl[np] = p;
    np += 1;
    if ( np == NP ) break;
    // cross off multiples
    unsigned c = p*2;
    while ( c < SS )
    {
      b[c] = 0;
      c += p;
    }
    p += 1;
  }
  delete [] b;
}

//析构函数
prime_factory::~prime_factory()
{
  delete [] pl;
}

//寻找第一个>=start的质数
vlong prime_factory::find_prime( vlong & start )
{
  unsigned SS = 1000;                        //1000通常已足够
  char * b = new char[SS];                 //后备质数检验位,若SS[i]=0,则不需要用
                                                //费马小定理(is_probable_prime)检验start+i,因为它
                                                //必非质数
  unsigned tested = 0;                        //使用is_probable_prime函数检验过的后备质数次数
  while (1)
  {
    unsigned i;
    for (i=0;i<SS;i+=1)
      b[i] = 1;
    for (i=0;i<np;i+=1)
    {
      unsigned p = pl[i];
      unsigned r = start % (vlong)p;        //取模运算较慢,此处可专门设计函数做取模计算
      if (r)
                r = p - r;
      // 去除所有能被p除尽的后备质数
      while ( r < SS )
      {
        b[r] = 0;
        r += p;
      }
    }
    // 检验后备质数
    for (i=0;i<SS;i+=1)
    {
      if ( b[i] )
      {
        tested += 1;
        if ( is_probable_prime(start) )
          return start;
      }
      start += 1;
    }
  }
  delete [] b;
}

//由字符串r1和r2创建p、q和公钥
void private_key::create( const char * r1, const char * r2 )
{
  // 由r1和r2产生质数p、q
  {
    prime_factory pf;
    p = pf.find_prime( from_str(r1) );
    q = pf.find_prime( from_str(r2) );
    if ( p > q )
    {
       vlong tmp = p;
       p = q;
       q = tmp;
    }
  }
  // 计算公钥
  //从[0,(p-1)(q-1)-1]中随机选取加密密钥e,使得e和(p-1)(q-1)互质。此处
  //为使e较大,直接从一较大数开始选取(50001)
  {
    m = p*q;
    e = 50001;                         //必须为奇数,因p-1,q-1均为偶数
    while ( gcd(p-(vlong)1,e) != (vlong)1 || gcd(q-(vlong)1,e) != (vlong)1 )
                e += 2;
  }
}

//加密明文
vlong public_key::encrypt( const vlong& plain )
{
  return modexp( plain, e, m );
}

//解密秘文
vlong private_key::decrypt( const vlong& cipher )
{
  // Calculate values for performing decryption
  // These could be cached, but the calculation is quite fast
  vlong d = modinv( e, (p-(vlong)1)*(q-(vlong)1) );
  vlong u = modinv( p, q );
  vlong dp = d % (p-(vlong)1);
  vlong dq = d % (q-(vlong)1);

  // 应用同余定理
  vlong a = modexp( cipher % p, dp, p );
  vlong b = modexp( cipher % q, dq, q );
  if ( b < a ) b += q;
  return a + p * ( ((b-a)*u) % q );
}

//rsa类简单使用实例

#include "rsa.h"
#include <iostream>
using namespace std;

main()
{
        private_key pkey;
        pkey.create("abcdefgaaaaaaaaaaaaaaaaaa","deeeeeeeeeeeeeeeefffffffff");
        vlong m;
        m=from_str("abbbbccc");
        pkey.encrypt(m);
       
        cout<<"ok";
        pkey.decrypt(m);
       
}

2005-4-25 14:19
0
雪    币: 208
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
//DES算法
/*-----------des.h-----------------------------------*/
#ifndef __DES_H
#define __DES_H
class DES
{
public:
           //使用key中56位密钥加/解密data中的数据。data默认为为64位数据块
        //返回值为1表示成功加/解密,否则失败
        int encrypt (unsigned char key[8],unsigned char* data, int blocks = 1 );
        int decrypt (unsigned char key[8],unsigned char* data, int blocks = 1 );

        //使用key中56位密钥加/解密data中任意长度数据。在调用加/解密函数前,可以将
           //待处理数据复制到新的缓冲区,缓冲区大小可由extend函数计算
        int yencrypt (unsigned char key[8],unsigned char* data, int size );
        int ydecrypt (unsigned char key[8],unsigned char* in, int blocks, int* size = 0 );

        int extend ( int size ) { return (size/8+1)*8; };

private:
        void des(unsigned char* in, unsigned char* out, int blocks);
        void des_block(unsigned char* in, unsigned char* out);

private:
        unsigned long KnL[32];
        enum Mode { ENCRYPT, DECRYPT };
        void deskey(unsigned char key[8], Mode md);
        void usekey(unsigned long *);
        void cookey(unsigned long *);

private:
        void scrunch(unsigned char *, unsigned long *);
        void unscrun(unsigned long *, unsigned char *);
        void desfunc(unsigned long *, unsigned long *);

private:
        static unsigned char Df_Key[24];
        static unsigned short bytebit[8];
        static unsigned long bigbyte[24];
        static unsigned char pc1[56];
        static unsigned char totrot[16];
        static unsigned char pc2[48];
        static unsigned long SP1[64];
        static unsigned long SP2[64];
        static unsigned long SP3[64];
        static unsigned long SP4[64];
        static unsigned long SP5[64];
        static unsigned long SP6[64];
        static unsigned long SP7[64];
        static unsigned long SP8[64];

};

#endif

/*-------------------------------------------------------------des.cpp------------------------------------------------------*/
#include <memory.h>
#include "des.h"

//encrypt
//        使用key中56位有效密钥加密data中的数据,data默认为64位数据块
//        返回值为1表示成功加密,否则失败
int DES::encrypt (unsigned char key[8], unsigned char* data, int blocks )
{
   if ((!data)||(blocks<1))
      return 0;
   deskey ( key, ENCRYPT );
   des ( data, data, blocks);
   return 1;
}

// ------------------------------------------------------------------------
//decrypt
//        使用key中56位有效密钥解密data中的数据,data默认为64位数据块
//        返回值为1表示成功解密,否则失败
int DES::decrypt (unsigned char key[8], unsigned char* data, int blocks )
{
   if ((!data)||(blocks<1))
      return 0;
   deskey ( key, DECRYPT );
   des ( data, data, blocks);
   return 1;
}

// ------------------------------------------------------------------------
//yencrypt
//        使用key中56位密钥加密data中任意长度数据。在调用加/解密函数前,可以将
//        待处理数据复制到新的缓冲区,缓冲区大小可由extend函数计算。size参数指明
//        data长度
int DES::yencrypt (unsigned char key[8], unsigned char* data, int size )
{
   if ((!data)||(size<1))
      return 0;

   char lastChar = *(data+size-1);
   int blocks = size/8+1;
   memset (data+size, ~lastChar, blocks*8-size);
   deskey ( key, ENCRYPT );
   return encrypt ( data, data, blocks);
}

// ------------------------------------------------------------------------
//ydecrypt
//        使用key中56位有效密钥解密data中任意长度数据。在调用解密函数前,可以将
//        待处理数据复制到新的缓冲区,缓冲区大小可由extend函数计算。Block参数指出
//        data中56位数据快数量;size为返回参数,指明解密后数据长度

int DES::ydecrypt (unsigned char key[8],unsigned char* data, int blocks, int* size )
{
   if ( (!data) || (blocks<1) )
      return 0;

   deskey ( key, DECRYPT );
   if ( !decrypt ( data, data, blocks) )
      return 0;
   if ( size != 0 )
   {
      int pos = blocks*8-1;
      char endChar = data[pos];
      while ((pos>0)&&(data[pos]==endChar))
            pos--;
      if ( data[pos] != ~endChar )
         return 0;
      *size = pos+1;
   }
   return 1;
}

// ------------------------------------------------------------------------
//des
//        使用当前内部密钥寄存器中装载的密钥加/解密以8字节为单位的数据块,
//        源数据在存储in中,加/解密后数据存储在out中,blocks表示数据块大小
//        (以8字节为单位)

void DES::des ( unsigned char* in, unsigned char* out, int blocks )
{
  for (int i = 0; i < blocks; i++,in+=8,out+=8)
      des_block(in,out);
};

// -----------------------------------------------------------------------
//des_block
//        使用当前内部密钥寄存器中装载的密钥加/解密8字节数据块,
//        源数据在存储in中,加/解密后数据存储在out中

void DES::des_block(unsigned char *in, unsigned char *out)
{
  unsigned long work[2];

  scrunch(in, work);
  desfunc(work, KnL);
  unscrun(work, out);
}

// ----------------------------------------------------------------------
// deskey
//        根据64位key参数设置内部密钥寄存器(使用DES密钥生成流程)
//        md参数为加/解密标志

void DES::deskey(unsigned char key[8], Mode md)  /* Thanks to James Gillogly & Phil Karn! */
{
  register int i, j, l, m, n;
  unsigned char pc1m[56], pcr[56];
  unsigned long kn[32];

  for (j = 0; j < 56; j++) {
    l = pc1[j];
    m = l & 07;
    pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1:0;
  }
  for (i = 0; i < 16; i++) {
    if (md == DECRYPT) m = (15 - i) << 1;
      else m = i << 1;
      n = m + 1;
      kn[m] = kn[n] = 0L;
      for (j = 0; j < 28; j++) {
        l = j + totrot[i];
        if (l < 28) pcr[j] = pc1m[l];
          else pcr[j] = pc1m[l - 28];
      }
      for (j = 28; j < 56; j++) {
        l = j + totrot[i];
        if (l < 56) pcr[j] = pc1m[l];
          else pcr[j] = pc1m[l - 28];
      }
      for (j = 0; j < 24; j++) {
        if (pcr[ pc2[j] ]) kn[m] |= bigbyte[j];
        if (pcr[ pc2[j+24] ]) kn[n] |= bigbyte[j];
      }
  }
  cookey(kn);
  return;
}

// ----------------------------------------------------------------------
// cookey
//        只由deskey调用

void DES::cookey(register unsigned long *raw1)
{
  register unsigned long *cook, *raw0;
  unsigned long dough[32];
  register int i;

  cook = dough;
  for (i = 0; i < 16; i++, raw1++) {
    raw0 = raw1++;
    *cook = (*raw0 & 0x00fc0000L) << 6;
    *cook |= (*raw0 & 0x00000fc0L) << 10;
    *cook |= (*raw1 & 0x00fc0000L) >> 10;
    *cook++ |= (*raw1 & 0x00000fc0L) >> 6;
    *cook = (*raw0 & 0x0003f000L) << 12;
    *cook |= (*raw0 & 0x0000003fL) << 16;
    *cook |= (*raw1 & 0x0003f000L) >> 4;
    *cook++ |= (*raw1 & 0x0000003fL);
  }
  usekey(dough);
  return;
}

// ----------------------------------------------------------------------
// usekey
//        只由cookey调用
//        用cookedkey中的数据装载内部密钥寄存器

void DES::usekey(register unsigned long *from)
{
  register unsigned long *to, *endp;

  to = KnL, endp = &KnL[32];
  while (to < endp) *to++ = *from++;
  return;
}

// scrunch
//        将outof参数指向的8字节字符串转换为返回型参数into
//        指向的长整数数组(长度为2)

void DES::scrunch(register unsigned char *outof, register unsigned long *into )
{
  *into = (*outof++ & 0xffL) << 24;
  *into |= (*outof++ & 0xffL) << 16;
  *into |= (*outof++ & 0xffL) << 8;
  *into++ |= (*outof++ & 0xffL);
  *into = (*outof++ & 0xffL) << 24;
  *into |= (*outof++ & 0xffL) << 16;
  *into |= (*outof++ & 0xffL) << 8;
  *into |= (*outof & 0xffL);
  return;
}

//unscrun
//        将outof参数指向的长整数数组(长度为2)转换为返回型参数
//        outof指向的字符串

void DES::unscrun(register unsigned long *outof, register unsigned char *into)
{
  *into++ = (*outof >> 24) & 0xffL;
  *into++ = (*outof >> 16) & 0xffL;
  *into++ = (*outof >> 8) & 0xffL;
  *into++ = *outof++ & 0xffL;
  *into++ = (*outof >> 24) & 0xffL;
  *into++ = (*outof >> 16) & 0xffL;
  *into++ = (*outof >> 8) & 0xffL;
  *into = *outof & 0xffL;
  return;
}

// desfunc
//        将block参数指向的长整数数组(由八字节数据块转换而成)
//        用des算法加密,算法密钥填充于返回型参数keys中
void DES::desfunc(register unsigned long *block,register unsigned long *keys)
{
  register unsigned long fval, work, right, leftt;
  register int round;

  leftt = block[0];
  right = block[1];
  work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
  right ^= work;
  leftt ^= (work << 4);
  work = ((leftt >> 16) ^ right) & 0x0000ffffL;
  right ^= work;
  leftt ^= (work << 16);
  work = ((right >> 2) ^ leftt) & 0x33333333L;
  leftt ^= work;
  right ^= (work << 2);
  work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
  leftt ^= work;
  right ^= (work << 8);
  right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
  work = (leftt ^ right) & 0xaaaaaaaaL;
  leftt ^= work;
  right ^= work;
  leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL;

  for (round = 0; round < 8; round++)
  {
    work = (right << 28) | (right >> 4);
    work ^= *keys++;
    fval  = SP7[work         & 0x3fL];
    fval |= SP5[(work >>  8) & 0x3fL];
    fval |= SP3[(work >> 16) & 0x3fL];
    fval |= SP1[(work >> 24) & 0x3fL];
    work = right ^ *keys++;
    fval |= SP8[work         & 0x3fL];
    fval |= SP6[(work >>  8) & 0x3fL];
    fval |= SP4[(work >> 16) & 0x3fL];
    fval |= SP2[(work >> 24) & 0x3fL];
    leftt ^= fval;
    work = (leftt << 28) | (leftt >> 4);
    work ^= *keys++;
    fval  = SP7[work         & 0x3fL];
    fval |= SP5[(work >>  8) & 0x3fL];
    fval |= SP3[(work >> 16) & 0x3fL];
    fval |= SP1[(work >> 24) & 0x3fL];
    work = leftt ^ *keys++;
    fval |= SP8[work         & 0x3fL];
    fval |= SP6[(work >>  8) & 0x3fL];
    fval |= SP4[(work >> 16) & 0x3fL];
    fval |= SP2[(work >> 24) & 0x3fL];
    right ^= fval;
  }
  right = (right << 31) | (right >> 1);
  work = (leftt ^ right) & 0xaaaaaaaaL;
  leftt ^= work;
  right ^= work;
  leftt = (leftt << 31) | ( leftt >> 1);
  work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
  right ^= work;
  leftt ^= (work << 8);
  work = ((leftt >> 2) ^ right) & 0x33333333L;
  right ^= work;
  leftt ^= (work << 2);
  work = ((right >> 16) ^ leftt) & 0x0000ffffL;
  leftt ^= work;
  right ^= (work << 16);
  work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
  leftt ^= work;
  right ^= (work << 4);
  *block++ = right;
  *block = leftt;
  return;
}
// ------------------------------
// DES算法所需静态初始数据,不能被改动。被类的所有实例使用

unsigned char DES::Df_Key[24] =
{
       0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
       0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
       0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67
};

unsigned short DES::bytebit[8] =
{
       0200, 0100, 040, 020, 010, 04, 02, 01
};

unsigned long DES::bigbyte[24] =
{
       0x800000L, 0x400000L, 0x200000L, 0x100000L,
       0x80000L,  0x40000L,  0x20000L,  0x10000L,
       0x8000L,   0x4000L,   0x2000L,   0x1000L,
       0x800L,    0x400L,    0x200L,    0x100L,
       0x80L,     0x40L,     0x20L,     0x10L,
       0x8L,      0x4L,      0x2L,      0x1L        
};

unsigned char DES::pc1[56] =
{
       56, 48, 40, 32, 24, 16,  8,  0, 57, 49, 41, 33, 25, 17,
        9,  1, 58, 50, 42, 34, 26, 18, 10,  2, 59, 51, 43, 35,
       62, 54, 46, 38, 30, 22, 14,  6, 61, 53, 45, 37, 29, 21,
       13,  5, 60, 52, 44, 36, 28, 20, 12,  4, 27, 19, 11, 3   
};

unsigned char DES::totrot[16] =
{
       1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
};

unsigned char DES::pc2[48] =
{
       13, 16, 10, 23,  0,  4,      2, 27, 14,  5, 20,  9,
       22, 18, 11,  3, 25,  7,     15,  6, 26, 19, 12,  1,
       40, 51, 30, 36, 46, 54,     29, 39, 50, 44, 32, 47,
       43, 48, 38, 55, 33, 52,     45, 41, 49, 35, 28, 31   
};

unsigned long DES::SP1[64] =
{
       0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
       0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
       0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
       0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
       0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
       0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
       0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
       0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
       0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
       0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
       0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
       0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
       0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
       0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
       0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
       0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L  
};

unsigned long DES::SP2[64] =
{
       0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
       0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
       0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
       0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
       0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
       0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
       0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
       0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
       0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
       0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
       0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
       0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
       0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
       0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
       0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
       0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L  
};

unsigned long DES::SP3[64] =
{
       0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
       0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
       0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
       0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
       0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
       0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
       0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
       0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
       0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
       0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
       0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
       0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
       0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
       0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
       0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
       0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L  
};

unsigned long DES::SP4[64] =
{
       0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
       0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
       0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
       0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
       0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
       0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
       0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
       0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
       0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
       0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
       0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
       0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
       0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
       0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
       0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
       0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L  
};

unsigned long DES::SP5[64] =
{
       0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
       0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
       0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
       0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
       0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
       0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
       0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
       0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
       0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
       0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
       0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
       0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
       0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
       0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
       0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
       0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L  
};

unsigned long DES::SP6[64] =
{
       0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
       0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
       0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
       0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
       0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
       0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
       0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
       0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
       0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
       0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
       0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
       0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
       0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
       0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
       0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
       0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L  
};

unsigned long DES::SP7[64] =
{
       0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
       0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
       0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
       0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
       0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
       0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
       0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
       0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
       0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
       0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
       0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
       0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
       0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
       0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
       0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
       0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L  
};

unsigned long DES::SP8[64] =
{
       0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
       0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
       0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
       0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
       0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
       0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
       0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
       0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
       0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
       0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
       0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
       0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
       0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
       0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
       0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
       0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L  
};

//应用举例
#include <memory.h>
#include "des.h"

main()
{
        unsigned char key[8];
        unsigned char* data=new unsigned char[8];
        key[0]=0x01;
        key[1]=0x23;
        key[2]=0x45;
        key[3]=0x67;
        key[4]=0x89;
        key[5]=0xab;
        key[6]=0xcd;
        key[7]=0xef;
        memcpy(data,key,8);
        data[7]=0xe7;
        DES des;
        des.encrypt(key,data);
       
}
2005-4-25 14:24
0
雪    币: 237
活跃值: (145)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
5
非常感谢!!
2005-4-25 16:32
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
你要的东西在卢开澄编的密码学原理一书中有
2005-5-23 10:56
0
雪    币: 442
活跃值: (1216)
能力值: ( LV12,RANK:1130 )
在线值:
发帖
回帖
粉丝
7
最初由 wx2005 发布
你要的东西在卢开澄编的密码学原理一书中有


书上有照着打一遍要死人的,万一打错一点和编辑出书的时候搞错了,那会死的很难看的。
2005-5-25 11:07
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
呵呵,那就无法了,上网搜搜吧
不过我是要搞硬件的,VHDL编程
2005-5-26 19:05
0
雪    币: 3246
活跃值: (374)
能力值: (RANK:20 )
在线值:
发帖
回帖
粉丝
9
vlong的那个类我记得以前看时看到有处内存泄漏
2005-5-27 17:23
0
游客
登录 | 注册 方可回帖
返回
//