?? pegwit.c
字號:
/*
pegwit by George Barwood <george.barwood@dial.pipex.com>
100% Public Domain
clearsigning code by Mr. Tines <tines@windsong.demon.co.uk>
also the filter mode support.
*/
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include "ec_crypt.h"
#include "sha1.h"
#include "square.h"
#include "sqcts.h"
#include "binasc.h"
#if defined(__BORLANDC__) && defined(__MSDOS__)
#include <dos.h>
unsigned _stklen = 32768u;
#endif
const char manual /*:)*/ [] =
"Pegwit v8.7\n"
"Usage (init/encrypt/decrypt/sign/verify) :\n"
"-i <secret-key >public-key\n"
"-e public-key plain cipher <random-junk\n"
"-d cipher plain <secret-key\n"
"-s plain <secret-key >signature\n"
"-v public-key plain <signature\n"
"-E plain cipher <key\n"
"-D cipher plain <key\n"
"-S text <secret-key >clearsigned-text\n"
"-V public-key clearsigned-text >text\n"
"-f[operation] [type pegwit -f for details]\n";
const char filterManual [] =
"Pegwit [filter sub-mode]\n"
"Usage (encrypt/decrypt/sign/verify) :\n"
"-fe public-key random-junk <plain >ascii-cipher\n"
"-fd secret-key <ascii-cipher >plain\n"
"-fE key <plain >ascii-cipher\n"
"-fD key <ascii-cipher >plain\n"
"-fS secret-key <text >clearsigned-text\n"
"-fV public-key <clearsigned-text >text\n";
const char pubkey_magic [] = "pegwit v8 public key =";
const char err_output [] = "Pegwit, error writing output, disk full?";
const char err_open_failed [] = "Pegwit, error : failed to open ";
const char err_bad_public_key [] = "Pegwit, error : public key must start with \"";
const char err_signature [] = "signature did not verify\a\a\a\n";
const char err_decrypt [] = "decryption failed\a\a\a\n";
const char begin_clearsign [] = "###\n";
const char end_clearsign [] = "### end pegwit v8 signed text\n";
const char end_ckarmour [] = "### end pegwit v8.7 -fE encrypted text\n";
const char end_pkarmour [] = "### end pegwit v8.7 -fe encrypted text\n";
const char escape [] = "## ";
const char warn_long_line [] =
"Very long line - > 8k bytes. Binary file?\n"
"Clearsignature dubious\a\a\a\n";
const char warn_control_chars [] =
"Large number of control characters. Binary file?\n"
"Clearsignature dubious\a\a\a\n";
const char err_clearsig_header_not_found [] =
"Clearsignature header \"###\" not found\a\a\a\n";
#define BPB (SQUARE_BLOCKSIZE) /* 16 */
#define NB ((GF_M+1+7)/8)
void hash_process_file( hash_context * c, FILE * f_inp, unsigned barrel )
{
unsigned n;
unsigned char buffer[0x4000];
while (1)
{
n = fread( buffer, 1, 0x4000, f_inp ); /* note: no error check */
if (n==0) break;
{
unsigned j;
for ( j=0; j<barrel; j+=1 )
{
hash_process( c+j, buffer, n );
}
}
if (n < 0x4000) break;
}
memset( buffer, sizeof(buffer), 0 );
fseek( f_inp, 0, SEEK_SET );
}
int downcase(char c)
{
if(isascii(c)) if(isupper(c)) return tolower(c);
return c;
}
int case_blind_compare(const char *a, const char *b)
{
while(*a && *b)
{
if(downcase(*a) < downcase(*b)) return -1;
if(downcase(*a) > downcase(*b)) return 1;
a += 1;
b += 1;
}
if(*a) return 1;
if(*b) return -1;
return 0;
}
void hash_process_ascii( hash_context * c, FILE * f_inp,
FILE * f_out, unsigned barrel, int write)
{
unsigned n;
unsigned char buffer[0x4000], *begin;
unsigned long bytes=0, control=0;
while (1)
{
unsigned i;
fgets((char*)buffer, 0x4000, f_inp); /* EOL -> \n */
if(feof(f_inp)) break;
n = strlen((char*)buffer);
begin = buffer;
if(n > 0x2000)
{
fputs( warn_long_line, f_out );
}
bytes += n;
for(i=0; i<n; ++i)
{
if(buffer[i] >= 0x7F) ++control;
if(buffer[i] < ' ' && buffer[i] != '\n' && buffer[i] != '\r'
&& buffer[i] != '\t') ++control;
}
if(write)
{
if (!strncmp( (char*)buffer, escape, 2 ) ||
!case_blind_compare((char*)buffer, "from") )
{
fputs( escape, f_out );
}
fputs( (char*)buffer, f_out);
}
else
{
if(!strncmp((char*)buffer, escape, 3)) {n-=3, begin+=3;}
else if(!strncmp((char*)buffer, end_clearsign, 3)) break; /* must be end of packet */
fputs((char*)begin, f_out);
}
for ( i=0; i<barrel; ++i )
{
hash_process( c+i, begin, n );
}
}
if(control*6 > bytes)
{
fputs( warn_control_chars, stderr );
}
memset( buffer, sizeof(buffer), 0 );
}
typedef struct /* Whole structure will be hashed */
{
unsigned count; /* Count of words */
word32 seed[2+HW*3]; /* Used to crank prng */
} prng;
void prng_init( prng * p )
{
memset( p, 0, sizeof(*p) );
}
void prng_set_secret( prng * p, FILE * f_key )
{
hash_context c[1];
hash_initial( c );
hash_process_file( c, f_key, 1 );
hash_final( c, p->seed+1 );
p->count = 1+HW;
}
void prng_init_mac(hash_context c[2])
{
/* Use 2 barrels to be conservative */
unsigned char b;
for ( b=0; b<2; ++b )
{
hash_initial( c+b );
hash_process( c+1, &b, 1 ); /* uninitialised on first pass */
}
}
void prng_set_mac( prng * p, FILE * f_inp, int barrel )
{
/* barrel should be 1 or 2 */
unsigned char b;
hash_context c[2];
for ( b=0; b<barrel; b+=1 )
{
hash_initial( c+b );
if ( b==1 ) hash_process( c+1, &b, 1 );
}
hash_process_file( c, f_inp, barrel );
for ( b=0; b<barrel; b+=1 )
{
hash_final( c, p->seed+1+HW*(b+1) );
}
p->count = 1 + (barrel+1)*HW;
}
void clearsign( prng * p, FILE * f_inp, FILE * f_out )
{
hash_context c[2];
prng_init_mac(c);
fputs(begin_clearsign,f_out);
hash_process_ascii( c, f_inp, f_out, 2, 1 );
fputs(end_clearsign,f_out);
hash_final( c, p->seed+1+HW );
hash_final( c, p->seed+1+2*HW );
p->count = 1 + 3*HW;
}
int position(FILE * f_inp) /* scan ascii file for ### introducer */
{
while(!feof(f_inp))
{
char buffer[1024];
fgets(buffer, 1024, f_inp);
if(!strncmp(buffer, begin_clearsign, 3)) break;
}
if(feof(f_inp))
{
fputs( err_clearsig_header_not_found, stderr );
return 0;
}
return 1;
}
int readsign( prng * p, FILE * f_inp, FILE * f_out )
{
hash_context c[2];
prng_init_mac(c);
if(!position(f_inp)) return 1;
hash_process_ascii( c, f_inp, f_out, 2, 0 );
hash_final( c, p->seed+1+HW );
hash_final( c, p->seed+1+2*HW );
p->count = 1 + 3*HW;
return 0;
}
void prng_set_time( prng * p )
{
p->seed[1+3*HW] = (word32) time(0);
p->count = 2 + 3*HW;
}
word32 prng_next( prng * p )
{
word32 tmp[HW];
byte buffer[ ( 3*HW + 2 ) * 4 ];
unsigned i,j;
hash_context c;
p->seed[0] += 1;
for ( i = 0; i < p->count; i+=1 )
{
for ( j = 0; j < 4; j += 1 )
{
buffer[ i*4 + j ] = (byte) ( p->seed[i] >> (j*8) );
}
}
hash_initial( &c );
hash_process( &c, buffer, p->count*4 );
hash_final( &c, tmp );
memset( buffer, 0, sizeof(buffer) );
return tmp[0];
}
void prng_to_vlong( prng * p, vlPoint V )
{
unsigned i;
V[0] = 15; /* 240 bits */
for (i=1;i<16;i+=1)
V[i] = (unsigned short) prng_next( p );
}
void hash_to_vlong( word32 * mac, vlPoint V )
{
unsigned i;
V[0] = 15; /* 240 bits */
for (i=0;i<8;i+=1)
{
word32 x = mac[i];
V[i*2+1] = (word16) x;
V[i*2+2] = (word16) (x>>16);
}
}
void get_vlong( FILE *f, vlPoint v )
{
unsigned u;
vlPoint w;
vlClear (v);
w[0] = 1;
while (1)
{
u = fgetc( f );
if ( u >= '0' && u <= '9' )
u -= '0';
else if ( u >= 'a' && u <= 'z' )
u -= 'a' - 10;
else if ( u >= 'A' && u <= 'Z' )
u -= 'A' - 10;
else if ( u <= ' ' )
continue;
else
break;
vlShortLshift (v, 4);
w[1] = (word16) u;
vlAdd (v, w);
}
}
void get_vlong_a( FILE *f, vlPoint v )
{
unsigned i=0;
char buffer[256], u;
vlPoint w;
vlClear (v);
w[0] = 1;
buffer[0]=0;
fgets(buffer, 256, f);
while ((u = buffer[i++]) != 0)
{
if ( u >= '0' && u <= '9' )
u -= '0';
else if ( u >= 'a' && u <= 'z' )
u -= 'a' - 10;
else if ( u >= 'A' && u <= 'Z' )
u -= 'A' - 10;
else if ( u <= ' ' )
continue;
else
break;
vlShortLshift (v, 4);
w[1] = (word16) u;
vlAdd (v, w);
}
}
const char hex[16] = "0123456789abcdef";
void put_vlong( vlPoint v )
{
unsigned i,j;
for (i = v[0]; i > 0; i--)
{
unsigned x = v[i];
for (j=0;j<4;j+=1)
putchar( hex[ (x >> (12-4*j)) % 16 ] );
}
}
void put_binary_vlong (FILE *f, vlPoint v)
{
unsigned n = NB;
while (n--)
{
if (v[0] == 0) v[1] = 0;
fputcPlus (v[1] & 0xff, f);
vlShortRshift (v, 8);
}
}
void get_binary_vlong(FILE *f, vlPoint v)
{
byte u[NB];
vlPoint w;
unsigned n = NB;
freadPlus(u, 1, NB, f);
vlClear (v); w[0] = 1;
while (n--)
{
vlShortLshift (v, 8);
w[1] = u[n];
vlAdd (v, w);
}
}
#define BIG_BLOCK_SIZE 0x1000
typedef word32 big_buf[1+BIG_BLOCK_SIZE/4]; /* Use word32 to force alignment */
/* 1 extra word to cope with expansion */
void vlong_to_square_block( const vlPoint V, squareBlock key )
{
vlPoint v;
unsigned j;
vlCopy (v, V);
for (j = 0; j < BPB; j++)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -