C++ programlama dilini bilmediğimden yorumunuda yapamıyorum, bilen arkadaşlar varsa lütfen yorumlasınlar
Code:
#include "idea.h"
int nagra2_ecm(byte *ecm, byte *dw) {
byte key[0x10]={
0xF5,0x36,0x55,0x68,0xF5,0x46,0x63,0x32,0x52,0xEE, 0xD5,0x00,0x88,0x1E,0x5A,0x37
};
byte tempBUF[0x40];
int i,j,k;
word16 EK[IDEAKEYLEN];
nagra2RSA (ecm+0xa);
ecm[0x49] = ((ecm[9] & 0x80) | (ecm[0x49]));
ideaExpandKey(key, EK);
for (i=7; i>-1; i- {
ideaCipher(ecm+0xA+(i*8), ecm+0xA+(i*8), EK);
if (i>0) for (j=0; j<8; j++) ecm[(i*8)+j+0xA] ^= ecm[(i-1)*8+j+0xA];
}
nagra2RSA(ecm+0xA);
for(i=0; i<0x40; i++) tempBUF[i]=ecm[0x3F+0x0a-i];
memcpy (ecm+0xa, tempBUF, 0x40);
k = 0; // cw found
for (i=0; i<ecm[0x4]; i++) {
if(ecm[i] == 0x10 && ecm[i+1] == 0x09 && ecm[i+2] == 0) {
memcpy(dw+8, ecm+i+3, 8);
i+= 11;
k++;
}
if(ecm[i] == 0x11 && ecm[i+1] == 0x09 && ecm[i+2] == 0) {
memcpy(dw, ecm+i+3, 8);
i+= 11;
k++;
}
}
if(k) return true;
else {
#ifdef DEBUG
printf("system-nagra2: failed to get CW\n");
#endif
return false;
}
}
void nagra2RSA (byte *msg) { // RAM:C0108AA5
byte mod[0x40]={
0xD9,0x1F,0xB4,0x82,0xF5,0x4C,0x45,0x35,0x62,0x1D, 0x84,0x5F,0x7E,0xC4,0xAB,0x4D,
0xC9,0x30,0x9D,0xED,0x26,0xB5,0x40,0x30,0x84,0x8E, 0xB6,0x39,0x68,0x97,0x75,0x29,
0xFE,0x8F,0xF1,0x86,0x13,0x27,0x61,0x71,0xE5,0x7B, 0xDA,0x8A,0x47,0xAC,0x99,0x37,
0x03,0xCC,0xE2,0xA1,0xCB,0x07,0x19,0x98,0xEC,0xCB, 0x32,0x7E,0xF6,0x3C,0xCE,0xA7
};
byte exp[]={0x03};
NN_DIGIT E[0x22], N[0x22], MSG[0x22], M[0x22*4];
int nDigits, eDigits;
NN_DecodeLE(MSG, 0x22, msg, sizeof(mod));
NN_DecodeLE(E, 0x22, exp, sizeof(exp));
NN_DecodeLE(N, 0x22, mod, sizeof(mod));
nDigits = NN_Digits(MSG, 0x22);
eDigits = NN_Digits(E, 0x22);
R_memset((POINTER)M, 0, 0x22*4);
NN_ModExp(M, MSG, E, eDigits, N, nDigits);
NN_EncodeLE(msg, sizeof(MSG), M, 0x22);
return;
}
// idea.c - C source code for IDEA block cipher.
// Compute the multiplicative inverse of x, modulo 65537, using Euclid's
// algorithm. It is unrolled twice to avoid swapping the registers each
// iteration, and some subtracts of t have been changed to adds.
static uint16 mulInv(uint16 x) {
uint16 t0, t1, q, y;
if (x <= 1) return x; // 0 and 1 are self-inverse
t1 = 0x10001L / x; // Since x >= 2, this fits into 16 bits
y = 0x10001L % x;
if (y == 1) return low16(1-t1);
t0 = 1;
do {
q = x / y;
x = x % y;
t0 += q * t1;
if (x == 1) return t0;
q = y / x;
y = y % x;
t1 += q * t0;
} while (y != 1);
return low16(1-t1);
}
// Expand a 128-bit user key to a working encryption key EK
static void ideaExpandKey(byte const *userkey, word16 *EK) {
int i,j;
for (j=0; j<8; j++) {
EK[j] = (userkey[0]<<8) + userkey[1];
userkey += 2;
}
for (i=0; j < IDEAKEYLEN; j++) {
i++;
EK[i+7] = EK[i & 7] << 9 | EK[i+1 & 7] >> 7;
EK += i & 8;
i &= 7;
}
}
// MUL(x,y) computes x = x*y, modulo 0x10001. Requires two temps,
// t16 and t32. x is modified, and must me a side-effect-free lvalue.
// y may be anything, but unlike x, must be strictly 16 bits even if
// low16() is #defined.
// All of these are equivalent - see which is faster on your machine
#define MUL(x,y) ((t16=(y))?(x=low16(x))?t32=(word32)x*t16,x=low16( t32),t16=t32>>16,x=(x-t16)+(x<t16): (x=1-t16): (x=1-x))
// IDEA encryption/decryption algorithm
// Note that in and out can be the same buffer
static void ideaCipher(byte const (inbuf[8]), byte (outbuf[8]), word16 const *key) {
register uint16 x1, x2, x3, x4, s2, s3;
word16 *in, *out;
register uint16 t16; // Temporaries needed by MUL macro
register word32 t32;
int r = IDEAROUNDS;
in = (word16 *)inbuf;
x1 = *in++; x2 = *in++;
x3 = *in++; x4 = *in;
x1 = (x1 >>8) | (x1<<8);
x2 = (x2 >>8) | (x2<<8);
x3 = (x3 >>8) | (x3<<8);
x4 = (x4 >>8) | (x4<<8);
do {
MUL(x1,*key++);
x2 += *key++;
x3 += *key++;
MUL(x4, *key++);
s3 = x3;
x3 ^= x1;
MUL(x3, *key++);
s2 = x2;
x2 ^= x4;
x2 += x3;
MUL(x2, *key++);
x3 += x2;
x1 ^= x2; x4 ^= x3;
x2 ^= s3; x3 ^= s2;
} while (--r);
MUL(x1, *key++);
x3 += *key++;
x2 += *key++;
MUL(x4, *key);
out = (word16 *)outbuf;
*out++ = (x1 >>8) | (x1<<8);
*out++ = (x3 >>8) | (x3<<8);
*out++ = (x2 >>8) | (x2<<8);
*out = (x4 >>8) | (x4<<8);
}
================================================== ======================================
idea.h
Code:
#ifndef IDEA_H
#define IDEA_H
typedef unsigned short word16; /* values are 0-65535 */
typedef unsigned long word32; /* values are 0-4294967295 */
typedef word16 uint16;
#define low16(x) (x)
#define IDEAROUNDS 8
#define IDEAKEYLEN (6*IDEAROUNDS+4)
#endif
================================================== ======================================
#include "idea.h"
int nagra2_ecm(byte *ecm, byte *dw) {
byte key[0x10]={
0xF5,0x36,0x55,0x68,0xF5,0x46,0x63,0x32,0x52,0xEE, 0xD5,0x00,0x88,0x1E,0x5A,0x37
};
byte tempBUF[0x40];
int i,j,k;
word16 EK[IDEAKEYLEN];
nagra2RSA (ecm+0xa);
ecm[0x49] = ((ecm[9] & 0x80) | (ecm[0x49]));
ideaExpandKey(key, EK);
for (i=7; i>-1; i- {
ideaCipher(ecm+0xA+(i*8), ecm+0xA+(i*8), EK);
if (i>0) for (j=0; j<8; j++) ecm[(i*8)+j+0xA] ^= ecm[(i-1)*8+j+0xA];
}
nagra2RSA(ecm+0xA);
for(i=0; i<0x40; i++) tempBUF[i]=ecm[0x3F+0x0a-i];
memcpy (ecm+0xa, tempBUF, 0x40);
k = 0; // cw found
for (i=0; i<ecm[0x4]; i++) {
if(ecm[i] == 0x10 && ecm[i+1] == 0x09 && ecm[i+2] == 0) {
memcpy(dw+8, ecm+i+3, 8);
i+= 11;
k++;
}
if(ecm[i] == 0x11 && ecm[i+1] == 0x09 && ecm[i+2] == 0) {
memcpy(dw, ecm+i+3, 8);
i+= 11;
k++;
}
}
if(k) return true;
else {
#ifdef DEBUG
printf("system-nagra2: failed to get CW\n");
#endif
return false;
}
}
void nagra2RSA (byte *msg) { // RAM:C0108AA5
byte mod[0x40]={
0xD9,0x1F,0xB4,0x82,0xF5,0x4C,0x45,0x35,0x62,0x1D, 0x84,0x5F,0x7E,0xC4,0xAB,0x4D,
0xC9,0x30,0x9D,0xED,0x26,0xB5,0x40,0x30,0x84,0x8E, 0xB6,0x39,0x68,0x97,0x75,0x29,
0xFE,0x8F,0xF1,0x86,0x13,0x27,0x61,0x71,0xE5,0x7B, 0xDA,0x8A,0x47,0xAC,0x99,0x37,
0x03,0xCC,0xE2,0xA1,0xCB,0x07,0x19,0x98,0xEC,0xCB, 0x32,0x7E,0xF6,0x3C,0xCE,0xA7
};
byte exp[]={0x03};
NN_DIGIT E[0x22], N[0x22], MSG[0x22], M[0x22*4];
int nDigits, eDigits;
NN_DecodeLE(MSG, 0x22, msg, sizeof(mod));
NN_DecodeLE(E, 0x22, exp, sizeof(exp));
NN_DecodeLE(N, 0x22, mod, sizeof(mod));
nDigits = NN_Digits(MSG, 0x22);
eDigits = NN_Digits(E, 0x22);
R_memset((POINTER)M, 0, 0x22*4);
NN_ModExp(M, MSG, E, eDigits, N, nDigits);
NN_EncodeLE(msg, sizeof(MSG), M, 0x22);
return;
}
// idea.c - C source code for IDEA block cipher.
// Compute the multiplicative inverse of x, modulo 65537, using Euclid's
// algorithm. It is unrolled twice to avoid swapping the registers each
// iteration, and some subtracts of t have been changed to adds.
static uint16 mulInv(uint16 x) {
uint16 t0, t1, q, y;
if (x <= 1) return x; // 0 and 1 are self-inverse
t1 = 0x10001L / x; // Since x >= 2, this fits into 16 bits
y = 0x10001L % x;
if (y == 1) return low16(1-t1);
t0 = 1;
do {
q = x / y;
x = x % y;
t0 += q * t1;
if (x == 1) return t0;
q = y / x;
y = y % x;
t1 += q * t0;
} while (y != 1);
return low16(1-t1);
}
// Expand a 128-bit user key to a working encryption key EK
static void ideaExpandKey(byte const *userkey, word16 *EK) {
int i,j;
for (j=0; j<8; j++) {
EK[j] = (userkey[0]<<8) + userkey[1];
userkey += 2;
}
for (i=0; j < IDEAKEYLEN; j++) {
i++;
EK[i+7] = EK[i & 7] << 9 | EK[i+1 & 7] >> 7;
EK += i & 8;
i &= 7;
}
}
// MUL(x,y) computes x = x*y, modulo 0x10001. Requires two temps,
// t16 and t32. x is modified, and must me a side-effect-free lvalue.
// y may be anything, but unlike x, must be strictly 16 bits even if
// low16() is #defined.
// All of these are equivalent - see which is faster on your machine
#define MUL(x,y) ((t16=(y))?(x=low16(x))?t32=(word32)x*t16,x=low16( t32),t16=t32>>16,x=(x-t16)+(x<t16): (x=1-t16): (x=1-x))
// IDEA encryption/decryption algorithm
// Note that in and out can be the same buffer
static void ideaCipher(byte const (inbuf[8]), byte (outbuf[8]), word16 const *key) {
register uint16 x1, x2, x3, x4, s2, s3;
word16 *in, *out;
register uint16 t16; // Temporaries needed by MUL macro
register word32 t32;
int r = IDEAROUNDS;
in = (word16 *)inbuf;
x1 = *in++; x2 = *in++;
x3 = *in++; x4 = *in;
x1 = (x1 >>8) | (x1<<8);
x2 = (x2 >>8) | (x2<<8);
x3 = (x3 >>8) | (x3<<8);
x4 = (x4 >>8) | (x4<<8);
do {
MUL(x1,*key++);
x2 += *key++;
x3 += *key++;
MUL(x4, *key++);
s3 = x3;
x3 ^= x1;
MUL(x3, *key++);
s2 = x2;
x2 ^= x4;
x2 += x3;
MUL(x2, *key++);
x3 += x2;
x1 ^= x2; x4 ^= x3;
x2 ^= s3; x3 ^= s2;
} while (--r);
MUL(x1, *key++);
x3 += *key++;
x2 += *key++;
MUL(x4, *key);
out = (word16 *)outbuf;
*out++ = (x1 >>8) | (x1<<8);
*out++ = (x3 >>8) | (x3<<8);
*out++ = (x2 >>8) | (x2<<8);
*out = (x4 >>8) | (x4<<8);
}
================================================== ======================================
idea.h
Code:
#ifndef IDEA_H
#define IDEA_H
typedef unsigned short word16; /* values are 0-65535 */
typedef unsigned long word32; /* values are 0-4294967295 */
typedef word16 uint16;
#define low16(x) (x)
#define IDEAROUNDS 8
#define IDEAKEYLEN (6*IDEAROUNDS+4)
#endif
================================================== ======================================