📄 secret.cpp.svn-base
字号:
{
if ( value->share ) value->share -=1; else delete value;
value = x.value;
value->share += 1;
negative = x.negative;
return *this;
}
vlong vlong::from_str( const char * s, int len )
{
vlong x(0);
int n = 0;
while (n<len)
{
x = x * vlong(256) + vlong((unsigned char)*s);
s += 1;
n += 1;
}
return x;
}
vlong vlong::from_sysstr( const char * s, int len )
{
char szSystem20[SE_LEN_SYSTEMSTR+1] = SE_SYSTEM20_CHAR;
vlong x(0);
int n = 0;
while (n<len)
{
int k;
for( k=0; k<SE_LEN_SYSTEMSTR; k++ )
{
if( szSystem20[k] == *s )
break;
}
if( k == SE_LEN_SYSTEMSTR )
{
TRACE( "vlong::from_sysstr( ... ), s is not sysstr.\n" );
// ASSERT( FALSE );
break;
}
x = x * vlong(SE_LEN_SYSTEMSTR) + vlong(k);
s += 1;
n += 1;
}
return x;
}
int vlong::to_str( char * s, int len )
{
char * pbuf = new char[len+1];
if( 0 == pbuf )
return -1;
memset( s, 0, len );
vlong vllocal( *this );
int n = 0;
while( vllocal != vlong(0) && n < len-1 )
{
*(pbuf+n) = vllocal % vlong(256);
vllocal = vllocal/vlong(256);
n ++;
}
for( int i=n-1; i>=0; i-- )
*(s+n-1-i) = *(pbuf+i);
delete [] pbuf;
if( vllocal != vlong(0) )
return -1;
return n;
}
int vlong::to_sysstr( char * s, int len )
{
char szSystem20[SE_LEN_SYSTEMSTR+1] = SE_SYSTEM20_CHAR;
char * pbuf = new char[len+1];
if( 0 == pbuf )
return -1;
memset( s, 0, len );
vlong vllocal( *this );
int n = 0;
while( vllocal != vlong(0) && n < len-1 )
{
*(pbuf+n) = szSystem20[ unsigned(vllocal % vlong(SE_LEN_SYSTEMSTR)) ];
vllocal = vllocal/vlong(SE_LEN_SYSTEMSTR);
n ++;
}
for( int i=n-1; i>=0; i-- )
*(s+n-1-i) = *(pbuf+i);
delete [] pbuf;
if( vllocal != vlong(0) )
return -1;
return n;
}
vlong::~vlong()
{
if ( value->share ) value->share -=1; else delete value;
}
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; // not sure about this?
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;
}
}
vlong modinv( const vlong &a, const vlong &m ) // modular inverse
// returns i in range 1..m-1 such that i*a = 1 mod m
// a must be in range 1..m-1
{
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;
}
class monty // class for montgomery modular exponentiation
{
vlong R,R1,m,n1;
vlong T,k; // work registers
unsigned N; // bits for R
void mul( vlong &x, const vlong &y );
public:
vlong exp( const vlong &x, const vlong &e );
monty( const vlong &M );
};
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;
}
vlong monty::exp( const vlong &x, const vlong &e )
{
vlong result = R-m, 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;
}
vlong modexp( const vlong & x, const vlong & e, const vlong & m )
{
monty me(m);
return me.exp( x,e );
}
///////////////////////////////////////////////////////////////////////
// class prime_factory
class prime_factory
{
unsigned np;
unsigned *pl;
public:
prime_factory();
~prime_factory();
vlong find_prime( vlong & start );
};
// prime factory implementation
static int is_probable_prime( const vlong &p )
{
// Test based on Fermats theorem a**(p-1) = 1 mod p for prime p
// For 1000 bit numbers this can take quite a while
const int rep = 4;
const unsigned any[rep] = { 2,3,5,7 };
for ( unsigned i=0; i<rep; i+=1 )
if ( modexp( any[i], p-1, p ) != vlong(1) )
return 0;
return 1;
}
prime_factory::prime_factory()
{
np = 0;
unsigned NP = 200;
pl = new unsigned[NP];
// Initialise pl
unsigned SS = 8*NP; // Rough estimate to fill pl
char * b = new char[SS+1]; // one extra to stop search
for (unsigned i=0;i<=SS;i+=1) b[i] = 1;
unsigned p = 2;
while (1)
{
// skip composites
while ( b[p] == 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;
}
vlong prime_factory::find_prime( vlong & start )
{
unsigned SS = 1000; // should be enough unless we are unlucky
char * b = new char[SS]; // bitset of candidate primes
unsigned tested = 0;
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); // not as fast as it should be - could do with special routine
if (r) r = p - r;
// cross off multiples of p
while ( r < SS )
{
b[r] = 0;
r += p;
}
}
// now test candidates
for (i=0;i<SS;i+=1)
{
if ( b[i] )
{
tested += 1;
if ( is_probable_prime(start) )
return start;
}
start += 1;
}
}
delete [] b;
}
///////////////////////////////////////////////////////////////////////
// class private_key and public key
void private_key::create( const char * r1, const char * r2 )
{
// Choose primes
{
prime_factory pf;
p = pf.find_prime( vlong::from_str(r1,strlen(r1)) );
q = pf.find_prime( vlong::from_str(r2,strlen(r2)) );
if ( p > q ) { vlong tmp = p; p = q; q = tmp; }
}
// Calculate public key
{
m = p*q;
e = 50001; // must be odd since p-1 and q-1 are even
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));
// Apply chinese remainder theorem
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 );
}
/////////////////////////////////////////////////////////////////////////////
// Disk Serial
#define PRINTING_TO_CONSOLE_ALLOWED
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
// Required to ensure correct PhysicalDrive IOCTL structure setup
#pragma pack(1)
// Max number of drives assuming primary/secondary, master/slave topology
#define MAX_IDE_DRIVES 4
#define IDENTIFY_BUFFER_SIZE 512
// IOCTL commands
#define DFP_GET_VERSION 0x00074080
#define DFP_SEND_DRIVE_COMMAND 0x0007c084
#define DFP_RECEIVE_DRIVE_DATA 0x0007c088
#define FILE_DEVICE_SCSI 0x0000001b
#define IOCTL_SCSI_MINIPORT_IDENTIFY ((FILE_DEVICE_SCSI << 16) + 0x0501)
#define IOCTL_SCSI_MINIPORT 0x0004D008 // see NTDDSCSI.H for definition
// GETVERSIONOUTPARAMS contains the data returned from the
// Get Driver Version function.
typedef struct _GETVERSIONOUTPARAMS
{
BYTE bVersion; // Binary driver version.
BYTE bRevision; // Binary driver revision.
BYTE bReserved; // Not used.
BYTE bIDEDeviceMap; // Bit map of IDE devices.
DWORD fCapabilities; // Bit mask of driver capabilities.
DWORD dwReserved[4]; // For future use.
} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;
// Bits returned in the fCapabilities member of GETVERSIONOUTPARAMS
#define CAP_IDE_ID_FUNCTION 1 // ATA ID command supported
#define CAP_IDE_ATAPI_ID 2 // ATAPI ID command supported
#define CAP_IDE_EXECUTE_SMART_FUNCTION 4 // SMART commannds supported
// IDE registers
#if(_WIN32_WINNT < 0x0400)
typedef struct _IDEREGS
{
BYTE bFeaturesReg; // Used for specifying SMART "commands".
BYTE bSectorCountReg; // IDE sector count register
BYTE bSectorNumberReg; // IDE sector number register
BYTE bCylLowReg; // IDE low order cylinder value
BYTE bCylHighReg; // IDE high order cylinder value
BYTE bDriveHeadReg; // IDE drive/head register
BYTE bCommandReg; // Actual IDE command.
BYTE bReserved; // reserved for future use. Must be zero.
} IDEREGS, *PIDEREGS, *LPIDEREGS;
#endif // (_WIN32_WINNT < 0x0400)
// SENDCMDINPARAMS contains the input parameters for the
// Send Command to Drive function.
#if(_WIN32_WINNT < 0x0400)
typedef struct _SENDCMDINPARAMS
{
DWORD cBufferSize; // Buffer size in bytes
IDEREGS irDriveRegs; // Structure with drive register values.
BYTE bDriveNumber; // Physical drive number to send
// command to (0,1,2,3).
BYTE bReserved[3]; // Reserved for future expansion.
DWORD dwReserved[4]; // For future use.
BYTE bBuffer[1]; // Input buffer.
} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;
#endif // (_WIN32_WINNT < 0x0400)
#define IDE_ATAPI_IDENTIFY 0xA1 // Returns ID sector for ATAPI.
#define IDE_ATA_IDENTIFY 0xEC // Returns ID sector for ATA.
// Status returned from driver
#if(_WIN32_WINNT < 0x0400)
typedef struct _DRIVERSTATUS
{
BYTE bDriverError; // Error code from driver, or 0 if no error.
BYTE bIDEStatus; // Contents of IDE Error register.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -