 |
 |
View previous topic :: View next topic |
Author |
Message |
bulut_01
Joined: 24 Feb 2024 Posts: 317
|
|
Posted: Tue Jul 22, 2025 1:32 am |
|
|
temtronic wrote: | OK, please post your working results as I'm sure others would like to see them ! |
I will share information when this topic is completely finished. |
|
 |
bulut_01
Joined: 24 Feb 2024 Posts: 317
|
|
Posted: Sat Jul 26, 2025 3:38 pm |
|
|
The remote's encryption algorithm is DES (Data Encryption Standard). I found the DES algorithm and made some changes to it. Is this code a bit heavy for 16f1825 ? The revised code doesn't work as I'd like; it doesn't decode correctly. I'm also getting 6000 memory errors in the simulation. Does anyone have a better DES algorithm for CCS ?
Code: |
/////////////////////////////////////////////////////////////////////////////// DES
const unsigned char rom IP_TABLE[64] = {
57-1, 49-1, 41-1, 33-1, 25-1, 17-1, 9-1, 1-1,
59-1, 51-1, 43-1, 35-1, 27-1, 19-1, 11-1, 3-1,
61-1, 53-1, 45-1, 37-1, 29-1, 21-1, 13-1, 5-1,
63-1, 55-1, 47-1, 39-1, 31-1, 23-1, 15-1, 7-1,
56-1, 48-1, 40-1, 32-1, 24-1, 16-1, 8-1, 0-1,
58-1, 50-1, 42-1, 34-1, 26-1, 18-1, 10-1, 2-1,
60-1, 52-1, 44-1, 36-1, 28-1, 20-1, 12-1, 4-1,
62-1, 54-1, 46-1, 38-1, 30-1, 22-1, 14-1, 6-1
};
// Final Permutation (FP) Table (IP'nin tersi)
const unsigned char rom FP_TABLE[64] = {
40-1, 8-1, 48-1, 16-1, 56-1, 24-1, 64-1, 32-1,
39-1, 7-1, 47-1, 15-1, 55-1, 23-1, 63-1, 31-1,
38-1, 6-1, 46-1, 14-1, 54-1, 22-1, 62-1, 30-1,
37-1, 5-1, 45-1, 13-1, 53-1, 21-1, 61-1, 29-1,
36-1, 4-1, 44-1, 12-1, 52-1, 20-1, 60-1, 28-1,
35-1, 3-1, 43-1, 11-1, 51-1, 19-1, 59-1, 27-1,
34-1, 2-1, 42-1, 10-1, 50-1, 18-1, 58-1, 26-1,
33-1, 1-1, 41-1, 9-1, 49-1, 17-1, 57-1, 25-1
};
// Key Permutation Choice 1 (PC1) - 64 bit anahtardan 56 bit seçer
const unsigned char rom PC1_TABLE[56] = {
57-1, 49-1, 41-1, 33-1, 25-1, 17-1, 9-1,
1-1, 58-1, 50-1, 42-1, 34-1, 26-1, 18-1,
10-1, 2-1, 59-1, 51-1, 43-1, 35-1, 27-1,
19-1, 11-1, 3-1, 60-1, 52-1, 44-1, 36-1, // C0 (İlk 28 bit)
63-1, 55-1, 47-1, 39-1, 31-1, 23-1, 15-1,
7-1, 62-1, 54-1, 46-1, 38-1, 30-1, 22-1,
14-1, 6-1, 61-1, 53-1, 45-1, 37-1, 29-1,
21-1, 13-1, 5-1, 28-1, 20-1, 12-1, 4-1 // D0 (Son 28 bit)
};
// Key Permutation Choice 2 (PC2) - 56 bit anahtardan 48 bit seçer
const unsigned char rom PC2_TABLE[48] = {
14-1, 17-1, 11-1, 24-1, 1-1, 5-1,
3-1, 28-1, 15-1, 6-1, 21-1, 10-1,
23-1, 19-1, 12-1, 4-1, 26-1, 8-1,
16-1, 7-1, 27-1, 20-1, 13-1, 2-1,
41-1, 52-1, 31-1, 37-1, 47-1, 55-1,
30-1, 40-1, 51-1, 45-1, 33-1, 48-1,
44-1, 49-1, 39-1, 56-1, 34-1, 53-1,
46-1, 42-1, 50-1, 36-1, 29-1, 32-1
};
// Genişleme Permutasyonu (E) - 32 bitten 48 bite
const unsigned char rom E_TABLE[48] = {
32-1, 1-1, 2-1, 3-1, 4-1, 5-1,
4-1, 5-1, 6-1, 7-1, 8-1, 9-1,
8-1, 9-1, 10-1, 11-1, 12-1, 13-1,
12-1, 13-1, 14-1, 15-1, 16-1, 17-1,
16-1, 17-1, 18-1, 19-1, 20-1, 21-1,
20-1, 21-1, 22-1, 23-1, 24-1, 25-1,
24-1, 25-1, 26-1, 27-1, 28-1, 29-1,
28-1, 29-1, 30-1, 31-1, 32-1, 1-1
};
// P-Box (Straight Permutation) - 32 bit girişi 32 bit çıkışa permute eder
const unsigned char rom P_TABLE[32] = {
16-1, 7-1, 20-1, 21-1, 29-1, 12-1, 28-1, 17-1,
1-1, 15-1, 23-1, 26-1, 5-1, 18-1, 31-1, 10-1,
2-1, 8-1, 24-1, 14-1, 32-1, 27-1, 3-1, 9-1,
19-1, 13-1, 30-1, 6-1, 22-1, 11-1, 4-1, 25-1
};
// S-Kutuları (S-Boxes) - 8 adet 4x16'lık kutu
const unsigned char rom S_BOXES[8][4][16] = {
// S1
{
{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
{0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
{4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
{15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}
},
// S2
{
{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
{3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
{0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
{13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}
},
// S3
{
{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
{13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
{13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
{1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}
},
// S4
{
{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
{13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
{10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
{3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}
},
// S5
{
{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
{14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
{4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
{11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}
},
// S6
{
{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
{10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
{9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
{4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}
},
// S7
{
{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
{13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
{1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
{6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}
},
// S8
{
{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
{1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
{7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
{2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}
}
};
// Anahtar Oluşturma İçin Rotasyon Sayıları
const char KEY_ROTATIONS[16] = {
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
};
// --- Global Değişkenler ---
unsigned char subkeys[16][6]; //Tur anahtarları (subkeys) her biri 48 bit (6 bayt)
// --- Yardımcı Bit Fonksiyonları ---------------------------------------------
// Belirli bir bit'i oku
int get_bit_ccs(unsigned char *data, int bit_pos){
return (data[bit_pos / 8] >> (7 - (bit_pos % 8))) & 0x01;
}
// Belirli bir bit'i ayarla
void set_bit(unsigned char *data, int bit_pos, int value){
if (value) {
data[bit_pos / 8] |= (0x01 << (7 - (bit_pos % 8)));
} else {
data[bit_pos / 8] &= ~(0x01 << (7 - (bit_pos % 8)));
}
}
// Permutasyon uygular
void apply_permutation(unsigned char *input, unsigned char *output, rom unsigned char *table, int table_len, int output_byte_len){
memset(output, 0, output_byte_len); // Çıkışı sıfırla
for (int i = 0; i < table_len; i++) {
set_bit(output, i, get_bit_ccs(input, table[i]));
}
}
// Bitleri sola kaydır (DES anahtar oluşturma için)
void rotate_left1(unsigned char *data, int data_len_bits, int num_rotations){
unsigned char temp_data[8]; // Max 64 bit için yeterli
memcpy(temp_data, data, (data_len_bits + 7) / 8); // Mevcut veriyi kopyala
for (int r = 0; r < num_rotations; r++){
int first_bit = get_bit_ccs(temp_data, 0); // En soldaki bit'i al
for (int i = 0; i < data_len_bits - 1; i++){ // Tüm bitleri sola kaydır
set_bit(temp_data, i, get_bit_ccs(temp_data, i + 1));
}
set_bit(temp_data, data_len_bits - 1, first_bit); // İlk bit'i sona ekle
}
memcpy(data, temp_data, (data_len_bits + 7) / 8); // Sonucu geri kopyala
}
// --- DES Anahtar Çizelgesi Oluşturma ---
void DES_Key_Schedule(unsigned char *master_key){
unsigned char permuted_key_56[7]; // PC1 sonrası 56 bit (7 bayt)
unsigned char C_part[4]; // 28 bit C kısmı (4 baytın ilk 28 biti)
unsigned char D_part[4]; // 28 bit D kısmı (4 baytın ilk 28 biti)
// 1. PC1 uygulaması
apply_permutation(master_key, permuted_key_56, PC1_TABLE, 56, 7);
// C ve D parçalarını ayır
memset(C_part, 0, 4);
memset(D_part, 0, 4);
for (int i = 0; i < 28; i++){
set_bit(C_part, i, get_bit_ccs(permuted_key_56, i));
set_bit(D_part, i, get_bit_ccs(permuted_key_56, i + 28));
}
// 16 tur için tur anahtarlarını oluştur
for (int round = 0; round < 16; round++){
// C ve D'yi sola kaydır
rotate_left1(C_part, 28, KEY_ROTATIONS[round]);
rotate_left1(D_part, 28, KEY_ROTATIONS[round]);
// C ve D'yi birleştir (56 bit)
unsigned char combined_CD[7];
memset(combined_CD, 0, 7);
for (int i = 0; i < 28; i++){
set_bit(combined_CD, i, get_bit_ccs(C_part, i));
set_bit(combined_CD, i + 28, get_bit_ccs(D_part, i));
}
// PC2 uygulaması ile 48 bit tur anahtarını oluştur
apply_permutation(combined_CD, subkeys[round], PC2_TABLE, 48, 6);
}
}
// --- DES Feistel Fonksiyonu (F Fonksiyonu) ---
void DES_F_Function(unsigned char *R_in, unsigned int8 *K_round, unsigned char *F_out) {
unsigned char expanded_R[6]; // E-Box sonrası 48 bit (6 bayt)
unsigned char xored_ER_K[6]; // E_R XOR K sonrası 48 bit (6 bayt)
unsigned char sbox_output[4]; // S-Box sonrası 32 bit (4 bayt)
// 1. Genişleme (Expansion E-Box)
apply_permutation(R_in, expanded_R, E_TABLE, 48, 6);
// 2. Tur anahtarıyla XOR
for (int i = 0; i < 6; i++) {
xored_ER_K[i] = expanded_R[i] ^ K_round[i];
}
// 3. S-Box dönüşümü
memset(sbox_output, 0, 4); // Çıkışı sıfırla
for (int i = 0; i < 8; i++) { // Her bir S-Box için
// 6 bitlik girişi al (row ve col için)
unsigned char s_box_input_6_bits_val = 0; // Geçici 1 baytlık değişken
set_bit(&s_box_input_6_bits_val, 0, get_bit_ccs(xored_ER_K, i * 6));
set_bit(&s_box_input_6_bits_val, 1, get_bit_ccs(xored_ER_K, i * 6 + 1));
set_bit(&s_box_input_6_bits_val, 2, get_bit_ccs(xored_ER_K, i * 6 + 2));
set_bit(&s_box_input_6_bits_val, 3, get_bit_ccs(xored_ER_K, i * 6 + 3));
set_bit(&s_box_input_6_bits_val, 4, get_bit_ccs(xored_ER_K, i * 6 + 4));
set_bit(&s_box_input_6_bits_val, 5, get_bit_ccs(xored_ER_K, i * 6 + 5));
// Satır ve sütun hesapla
// Satır = (İlk bit << 1) | Son bit
unsigned char row = ((s_box_input_6_bits_val >> 5) & 0x01) << 1 | (s_box_input_6_bits_val & 0x01);
// Sütun = Ortadaki 4 bit
unsigned char col = (s_box_input_6_bits_val >> 1) & 0x0F;
unsigned char sbox_value = S_BOXES[i][row][col]; // S-Box'tan değeri al
// S-Box çıktısı 4 bit. Bunu sbox_output'a yerleştir.
set_bit(sbox_output, i * 4 + 0, (sbox_value >> 3) & 0x01);
set_bit(sbox_output, i * 4 + 1, (sbox_value >> 2) & 0x01);
set_bit(sbox_output, i * 4 + 2, (sbox_value >> 1) & 0x01);
set_bit(sbox_output, i * 4 + 3, sbox_value & 0x01);
}
// 4. P-Box (Permutation)
apply_permutation(sbox_output, F_out, P_TABLE, 32, 4);
}
// --- DES Blok Şifre Çözme ---
void DES_Decrypt_Block(unsigned char *ciphertext_block, unsigned char *plaintext_block) {
unsigned char permuted_input[8]; // IP sonrası 64 bit
unsigned char L_part[4], R_part[4]; // 32 bit Sol ve Sağ parçalar
unsigned char f_result[4]; // F fonksiyonu çıktısı (32 bit)
// 1. Initial Permutation (IP)
apply_permutation(ciphertext_block, permuted_input, IP_TABLE, 64, 8);
// 2. L0 ve R0'a böl (32 bit her biri)
memcpy(L_part, permuted_input, 4);
memcpy(R_part, permuted_input + 4, 4);
// 3. 16 tur Feistel ağı (deşifreleme için anahtarlar tersten kullanılır)
for (int round = 0; round < 16; round++) {
unsigned char temp_L[4];
memcpy(temp_L, L_part, 4); // L'nin kopyasını al (bir sonraki R için)
// Deşifreleme modunda tur anahtarları ters sırada kullanılır
int key_index = 15 - round; // Sadece deşifreleme için sabit
// F fonksiyonunu uygula: F(R, K)
DES_F_Function(R_part, subkeys[key_index], f_result);
// L(i+1) = R(i)
// R(i+1) = L(i) XOR F(R(i), K(i))
for (int i = 0; i < 4; i++) {
L_part[i] = R_part[i]; // L_part, bir önceki turdaki R_part olur
R_part[i] = temp_L[i] ^ f_result[i]; // R_part, bir önceki L_part XOR F(R, K) olur
}
}
// Son aşamada L ve R'yi takas et (Feistel yapısı gereği)
unsigned char combined_output[8];
memcpy(combined_output, R_part, 4); // Son R, sol tarafa gelir
memcpy(combined_output + 4, L_part, 4); // Son L, sağ tarafa gelir
// 4. Final Permutation (FP)
apply_permutation(combined_output, plaintext_block, FP_TABLE, 64, 8);
}
// --- Yardımcı Fonksiyon: HEX String -> Byte Dizisi ---
void hex_to_bytes(int8* hex_string, unsigned int8* byte_array, int len){
for (int i = 0; i < len; i++){
unsigned int val;
//HEX karakterlerini int'e dönüştürme (CCS C için manuel parsing güvenlidir)
if (hex_string[2*i] >= '0' && hex_string[2*i] <= '9') val = (hex_string[2*i] - '0') << 4;
else if (hex_string[2*i] >= 'A' && hex_string[2*i] <= 'F') val = (hex_string[2*i] - 'A' + 10) << 4;
else val = (hex_string[2*i] - 'a' + 10) << 4;
if (hex_string[2*i+1] >= '0' && hex_string[2*i+1] <= '9') val |= (hex_string[2*i+1] - '0');
else if (hex_string[2*i+1] >= 'A' && hex_string[2*i+1] <= 'F') val |= (hex_string[2*i+1] - 'A' + 10);
else val |= (hex_string[2*i+1] - 'a' + 10);
byte_array[i] = (unsigned char)val;
}
}
// --- Yardımcı Fonksiyon: Byte Dizisi -> HEX String (Gerektiğinde Seri Porta Basmak İçin) ---
void print_bytes_as_hex(unsigned int8* byte_array, int len){
for (int i = 0; i < len; i++) {
//printf("%02X ", byte_array[i]);
}
//printf("\r\n"); // Satır sonu ve satır başı
}
///////////////////////////////////////////////////////////////////////////////
void main()
{
unsigned char master_key[8] = {0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x00};
DES_Key_Schedule(master_key);
const char* encrypted_hex_data[] = {"C8B2465CC599B6C2"};
int num_blocks = 4;
//
for(int i = 0; i < num_blocks; i++){
unsigned char ciphertext_bytes[8];
unsigned char plaintext_bytes[8];
// HEX string'i byte dizisine çevir
hex_to_bytes(encrypted_hex_data[i], ciphertext_bytes, 8);
//printf("\r\n--- Sifreli Blok %d: %s ---\r\n", i + 1, encrypted_hex_data[i]);
// DES desifreleme işlemini çağır
DES_Decrypt_Block(ciphertext_bytes, plaintext_bytes);
//printf("Cozulen Ham Veri: ");
print_bytes_as_hex(plaintext_bytes, 8);
// Veriyi yapiya göre yorumla (Little-Endian)
unsigned long remote_id = (unsigned long)plaintext_bytes[3] << 24 |
(unsigned long)plaintext_bytes[2] << 16 |
(unsigned long)plaintext_bytes[1] << 8 |
(unsigned long)plaintext_bytes[0];
unsigned int counter = (unsigned int)plaintext_bytes[5] << 8 |
(unsigned int)plaintext_bytes[4];
unsigned char command = (plaintext_bytes[6] >> 4) & 0x0F;
unsigned char channel = plaintext_bytes[6] & 0x0F;
unsigned char checksum_expected = plaintext_bytes[7];
unsigned char checksum_calculated = 0;
for (int j = 0; j < 7; j++){
checksum_calculated ^= plaintext_bytes[j];
}}
|
|
|
 |
temtronic
Joined: 01 Jul 2010 Posts: 9568 Location: Greensville,Ontario
|
|
Posted: Sun Jul 27, 2025 5:26 am |
|
|
hmm, since it 'doesn't work'......
2 possibilties
1) you really don't have DES encryption.
2) your changes weren't correctly done.
DES has been 'carved in stone' for a very,very long time so lots written about 'how it works' and how to encode/decode. Just because it's '64 bit encryption' doesn't mean it's DES.
Not sure why you made changes,perhaps one of those has altered the decryption process ?
did you try this program with KNOWN data and CONFIRM it worked BEFORE making the changes? |
|
 |
bulut_01
Joined: 24 Feb 2024 Posts: 317
|
|
Posted: Sun Jul 27, 2025 3:13 pm |
|
|
temtronic wrote: | hmm, since it 'doesn't work'......
2 possibilties
1) you really don't have DES encryption.
2) your changes weren't correctly done.
DES has been 'carved in stone' for a very,very long time so lots written about 'how it works' and how to encode/decode. Just because it's '64 bit encryption' doesn't mean it's DES.
Not sure why you made changes,perhaps one of those has altered the decryption process ?
did you try this program with KNOWN data and CONFIRM it worked BEFORE making the changes? |
The AI found that this data was DES. I don't have that much experience with the algorithm the code was encrypted with. The AI found the key. When the AI decoded it, the remote control ID it found matched the values I read from the receiver's EEPROM.checksum values are correct In fact, the counter values in the remote control and the counter values of the decoded data match. I don't know which DES library the AI uses, but the code I shared above doesn't decode the DES data correctly. If there's a lighter DES algorithm written for CCS C, please share it.
I found this code with AI. It was written for C. I adapted it to CCS. It was giving a direct compilation error. I'm sharing the original.
orginal C des code (This code does not compile in CCS C.)
Code: |
const unsigned char IP_TABLE[64] = {
57-1, 49-1, 41-1, 33-1, 25-1, 17-1, 9-1, 1-1,
59-1, 51-1, 43-1, 35-1, 27-1, 19-1, 11-1, 3-1,
61-1, 53-1, 45-1, 37-1, 29-1, 21-1, 13-1, 5-1,
63-1, 55-1, 47-1, 39-1, 31-1, 23-1, 15-1, 7-1,
56-1, 48-1, 40-1, 32-1, 24-1, 16-1, 8-1, 0-1,
58-1, 50-1, 42-1, 34-1, 26-1, 18-1, 10-1, 2-1,
60-1, 52-1, 44-1, 36-1, 28-1, 20-1, 12-1, 4-1,
62-1, 54-1, 46-1, 38-1, 30-1, 22-1, 14-1, 6-1
};
// Final Permutation (FP) Table (IP'nin tersi)
const unsigned char FP_TABLE[64] = {
40-1, 8-1, 48-1, 16-1, 56-1, 24-1, 64-1, 32-1,
39-1, 7-1, 47-1, 15-1, 55-1, 23-1, 63-1, 31-1,
38-1, 6-1, 46-1, 14-1, 54-1, 22-1, 62-1, 30-1,
37-1, 5-1, 45-1, 13-1, 53-1, 21-1, 61-1, 29-1,
36-1, 4-1, 44-1, 12-1, 52-1, 20-1, 60-1, 28-1,
35-1, 3-1, 43-1, 11-1, 51-1, 19-1, 59-1, 27-1,
34-1, 2-1, 42-1, 10-1, 50-1, 18-1, 58-1, 26-1,
33-1, 1-1, 41-1, 9-1, 49-1, 17-1, 57-1, 25-1
};
// Key Permutation Choice 1 (PC1) - 64 bit anahtardan 56 bit seçer
const unsigned char PC1_TABLE[56] = {
57-1, 49-1, 41-1, 33-1, 25-1, 17-1, 9-1,
1-1, 58-1, 50-1, 42-1, 34-1, 26-1, 18-1,
10-1, 2-1, 59-1, 51-1, 43-1, 35-1, 27-1,
19-1, 11-1, 3-1, 60-1, 52-1, 44-1, 36-1, // C0 (İlk 28 bit)
63-1, 55-1, 47-1, 39-1, 31-1, 23-1, 15-1,
7-1, 62-1, 54-1, 46-1, 38-1, 30-1, 22-1,
14-1, 6-1, 61-1, 53-1, 45-1, 37-1, 29-1,
21-1, 13-1, 5-1, 28-1, 20-1, 12-1, 4-1 // D0 (Son 28 bit)
};
// Key Permutation Choice 2 (PC2) - 56 bit anahtardan 48 bit seçer
const unsigned char PC2_TABLE[48] = {
14-1, 17-1, 11-1, 24-1, 1-1, 5-1,
3-1, 28-1, 15-1, 6-1, 21-1, 10-1,
23-1, 19-1, 12-1, 4-1, 26-1, 8-1,
16-1, 7-1, 27-1, 20-1, 13-1, 2-1,
41-1, 52-1, 31-1, 37-1, 47-1, 55-1,
30-1, 40-1, 51-1, 45-1, 33-1, 48-1,
44-1, 49-1, 39-1, 56-1, 34-1, 53-1,
46-1, 42-1, 50-1, 36-1, 29-1, 32-1
};
// Genişleme Permutasyonu (E) - 32 bitten 48 bite
const unsigned char E_TABLE[48] = {
32-1, 1-1, 2-1, 3-1, 4-1, 5-1,
4-1, 5-1, 6-1, 7-1, 8-1, 9-1,
8-1, 9-1, 10-1, 11-1, 12-1, 13-1,
12-1, 13-1, 14-1, 15-1, 16-1, 17-1,
16-1, 17-1, 18-1, 19-1, 20-1, 21-1,
20-1, 21-1, 22-1, 23-1, 24-1, 25-1,
24-1, 25-1, 26-1, 27-1, 28-1, 29-1,
28-1, 29-1, 30-1, 31-1, 32-1, 1-1
};
// P-Box (Straight Permutation) - 32 bit girişi 32 bit çıkışa permute eder
const unsigned char P_TABLE[32] = {
16-1, 7-1, 20-1, 21-1, 29-1, 12-1, 28-1, 17-1,
1-1, 15-1, 23-1, 26-1, 5-1, 18-1, 31-1, 10-1,
2-1, 8-1, 24-1, 14-1, 32-1, 27-1, 3-1, 9-1,
19-1, 13-1, 30-1, 6-1, 22-1, 11-1, 4-1, 25-1
};
// S-Kutuları (S-Boxes) - 8 adet 4x16'lık kutu
const unsigned char S_BOXES[8][4][16] = {
// S1
{
{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
{0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
{4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
{15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}
},
// S2
{
{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
{3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
{0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
{13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}
},
// S3
{
{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
{13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
{13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
{1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}
},
// S4
{
{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
{13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
{10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
{3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}
},
// S5
{
{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
{14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
{4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
{11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}
},
// S6
{
{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
{10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
{9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
{4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}
},
// S7
{
{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
{13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
{1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
{6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}
},
// S8
{
{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
{1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
{7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
{2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}
}
};
// Anahtar Oluşturma İçin Rotasyon Sayıları
const unsigned char KEY_ROTATIONS[16] = {
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
};
// --- Global Değişkenler ---
unsigned char subkeys[16][6]; // Tur anahtarları (subkeys) her biri 48 bit (6 bayt)
// --- Yardımcı Bit Fonksiyonları ---
// Belirli bir bit'i oku
int get_bit(const unsigned char *data, int bit_pos) {
return (data[bit_pos / 8] >> (7 - (bit_pos % 8))) & 0x01;
}
// Belirli bir bit'i ayarla
void set_bit(unsigned char *data, int bit_pos, int value) {
if (value) {
data[bit_pos / 8] |= (0x01 << (7 - (bit_pos % 8)));
} else {
data[bit_pos / 8] &= ~(0x01 << (7 - (bit_pos % 8)));
}
}
// Permutasyon uygular
void apply_permutation(unsigned char *input, unsigned char *output, const unsigned char *table, int table_len, int output_byte_len) {
memset(output, 0, output_byte_len); // Çıkışı sıfırla
for (int i = 0; i < table_len; i++) {
set_bit(output, i, get_bit(input, table[i]));
}
}
// Bitleri sola kaydır (DES anahtar oluşturma için)
void rotate_left(unsigned char *data, int data_len_bits, int num_rotations) {
unsigned char temp_data[8]; // Max 64 bit için yeterli
memcpy(temp_data, data, (data_len_bits + 7) / 8); // Mevcut veriyi kopyala
for (int r = 0; r < num_rotations; r++) {
int first_bit = get_bit(temp_data, 0); // En soldaki bit'i al
for (int i = 0; i < data_len_bits - 1; i++) { // Tüm bitleri sola kaydır
set_bit(temp_data, i, get_bit(temp_data, i + 1));
}
set_bit(temp_data, data_len_bits - 1, first_bit); // İlk bit'i sona ekle
}
memcpy(data, temp_data, (data_len_bits + 7) / 8); // Sonucu geri kopyala
}
// --- DES Anahtar Çizelgesi Oluşturma ---
void DES_Key_Schedule(unsigned char *master_key) {
unsigned char permuted_key_56[7]; // PC1 sonrası 56 bit (7 bayt)
unsigned char C_part[4]; // 28 bit C kısmı (4 baytın ilk 28 biti)
unsigned char D_part[4]; // 28 bit D kısmı (4 baytın ilk 28 biti)
// 1. PC1 uygulaması
apply_permutation(master_key, permuted_key_56, PC1_TABLE, 56, 7);
// C ve D parçalarını ayır
memset(C_part, 0, 4);
memset(D_part, 0, 4);
for (int i = 0; i < 28; i++) {
set_bit(C_part, i, get_bit(permuted_key_56, i));
set_bit(D_part, i, get_bit(permuted_key_56, i + 28));
}
// 16 tur için tur anahtarlarını oluştur
for (int round = 0; round < 16; round++) {
// C ve D'yi sola kaydır
rotate_left(C_part, 28, KEY_ROTATIONS[round]);
rotate_left(D_part, 28, KEY_ROTATIONS[round]);
// C ve D'yi birleştir (56 bit)
unsigned char combined_CD[7];
memset(combined_CD, 0, 7);
for (int i = 0; i < 28; i++) {
set_bit(combined_CD, i, get_bit(C_part, i));
set_bit(combined_CD, i + 28, get_bit(D_part, i));
}
// PC2 uygulaması ile 48 bit tur anahtarını oluştur
apply_permutation(combined_CD, subkeys[round], PC2_TABLE, 48, 6);
}
}
// --- DES Feistel Fonksiyonu (F Fonksiyonu) ---
void DES_F_Function(unsigned char *R_in, const unsigned char *K_round, unsigned char *F_out) {
unsigned char expanded_R[6]; // E-Box sonrası 48 bit (6 bayt)
unsigned char xored_ER_K[6]; // E_R XOR K sonrası 48 bit (6 bayt)
unsigned char sbox_output[4]; // S-Box sonrası 32 bit (4 bayt)
// 1. Genişleme (Expansion E-Box)
apply_permutation(R_in, expanded_R, E_TABLE, 48, 6);
// 2. Tur anahtarıyla XOR
for (int i = 0; i < 6; i++) {
xored_ER_K[i] = expanded_R[i] ^ K_round[i];
}
// 3. S-Box dönüşümü
memset(sbox_output, 0, 4); // Çıkışı sıfırla
for (int i = 0; i < 8; i++) { // Her bir S-Box için
// 6 bitlik girişi al (row ve col için)
unsigned char s_box_input_6_bits_val = 0; // Geçici 1 baytlık değişken
set_bit(&s_box_input_6_bits_val, 0, get_bit(xored_ER_K, i * 6));
set_bit(&s_box_input_6_bits_val, 1, get_bit(xored_ER_K, i * 6 + 1));
set_bit(&s_box_input_6_bits_val, 2, get_bit(xored_ER_K, i * 6 + 2));
set_bit(&s_box_input_6_bits_val, 3, get_bit(xored_ER_K, i * 6 + 3));
set_bit(&s_box_input_6_bits_val, 4, get_bit(xored_ER_K, i * 6 + 4));
set_bit(&s_box_input_6_bits_val, 5, get_bit(xored_ER_K, i * 6 + 5));
// Satır ve sütun hesapla
// Satır = (İlk bit << 1) | Son bit
unsigned char row = ((s_box_input_6_bits_val >> 5) & 0x01) << 1 | (s_box_input_6_bits_val & 0x01);
// Sütun = Ortadaki 4 bit
unsigned char col = (s_box_input_6_bits_val >> 1) & 0x0F;
unsigned char sbox_value = S_BOXES[i][row][col]; // S-Box'tan değeri al
// S-Box çıktısı 4 bit. Bunu sbox_output'a yerleştir.
set_bit(sbox_output, i * 4 + 0, (sbox_value >> 3) & 0x01);
set_bit(sbox_output, i * 4 + 1, (sbox_value >> 2) & 0x01);
set_bit(sbox_output, i * 4 + 2, (sbox_value >> 1) & 0x01);
set_bit(sbox_output, i * 4 + 3, sbox_value & 0x01);
}
// 4. P-Box (Permutation)
apply_permutation(sbox_output, F_out, P_TABLE, 32, 4);
}
// --- DES Blok Şifre Çözme ---
void DES_Decrypt_Block(unsigned char *ciphertext_block, unsigned char *plaintext_block) {
unsigned char permuted_input[8]; // IP sonrası 64 bit
unsigned char L_part[4], R_part[4]; // 32 bit Sol ve Sağ parçalar
unsigned char f_result[4]; // F fonksiyonu çıktısı (32 bit)
// 1. Initial Permutation (IP)
apply_permutation(ciphertext_block, permuted_input, IP_TABLE, 64, 8);
// 2. L0 ve R0'a böl (32 bit her biri)
memcpy(L_part, permuted_input, 4);
memcpy(R_part, permuted_input + 4, 4);
// 3. 16 tur Feistel ağı (deşifreleme için anahtarlar tersten kullanılır)
for (int round = 0; round < 16; round++) {
unsigned char temp_L[4];
memcpy(temp_L, L_part, 4); // L'nin kopyasını al (bir sonraki R için)
// Deşifreleme modunda tur anahtarları ters sırada kullanılır
int key_index = 15 - round; // Sadece deşifreleme için sabit
// F fonksiyonunu uygula: F(R, K)
DES_F_Function(R_part, subkeys[key_index], f_result);
// L(i+1) = R(i)
// R(i+1) = L(i) XOR F(R(i), K(i))
for (int i = 0; i < 4; i++) {
L_part[i] = R_part[i]; // L_part, bir önceki turdaki R_part olur
R_part[i] = temp_L[i] ^ f_result[i]; // R_part, bir önceki L_part XOR F(R, K) olur
}
}
// Son aşamada L ve R'yi takas et (Feistel yapısı gereği)
unsigned char combined_output[8];
memcpy(combined_output, R_part, 4); // Son R, sol tarafa gelir
memcpy(combined_output + 4, L_part, 4); // Son L, sağ tarafa gelir
// 4. Final Permutation (FP)
apply_permutation(combined_output, plaintext_block, FP_TABLE, 64, 8);
}
// --- Yardımcı Fonksiyon: HEX String -> Byte Dizisi ---
void hex_to_bytes(const char* hex_string, unsigned char* byte_array, int len) {
for (int i = 0; i < len; i++) {
unsigned int val;
// HEX karakterlerini int'e dönüştürme (CCS C için manuel parsing güvenlidir)
if (hex_string[2*i] >= '0' && hex_string[2*i] <= '9') val = (hex_string[2*i] - '0') << 4;
else if (hex_string[2*i] >= 'A' && hex_string[2*i] <= 'F') val = (hex_string[2*i] - 'A' + 10) << 4;
else val = (hex_string[2*i] - 'a' + 10) << 4;
if (hex_string[2*i+1] >= '0' && hex_string[2*i+1] <= '9') val |= (hex_string[2*i+1] - '0');
else if (hex_string[2*i+1] >= 'A' && hex_string[2*i+1] <= 'F') val |= (hex_string[2*i+1] - 'A' + 10);
else val |= (hex_string[2*i+1] - 'a' + 10);
byte_array[i] = (unsigned char)val;
}
}
// --- Yardımcı Fonksiyon: Byte Dizisi -> HEX String (Gerektiğinde Seri Porta Basmak İçin) ---
void print_bytes_as_hex(const unsigned char* byte_array, int len) {
for (int i = 0; i < len; i++) {
printf("%02X ", byte_array[i]);
}
printf("\r\n"); // Satır sonu ve satır başı
}
////////////////////////////
void main{
unsigned char master_key[8] = {0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x00};
// Anahtar çizelgesini oluştur
printf("Anahtar cizelgesi olusturuluyor...\r\n");
DES_Key_Schedule(master_key);
printf("Anahtar cizelgesi olusturuldu.\r\n");
// Şifreli veri blokları
const char* encrypted_hex_data[] = {
"22266094FB0A28F5"
};
int num_blocks = 4; // Blok sayısı
for (int i = 0; i < num_blocks; i++) {
unsigned char ciphertext_bytes[8];
unsigned char plaintext_bytes[8];
// HEX string'i byte dizisine çevir
hex_to_bytes(encrypted_hex_data[i], ciphertext_bytes, 8);
printf("\r\n--- Sifreli Blok %d: %s ---\r\n", i + 1, encrypted_hex_data[i]);
// DES desifreleme işlemini çağır
DES_Decrypt_Block(ciphertext_bytes, plaintext_bytes);
printf("Cozulen Ham Veri: ");
print_bytes_as_hex(plaintext_bytes, 8);
// Veriyi yapiya göre yorumla (Little-Endian)
unsigned long remote_id = (unsigned long)plaintext_bytes[3] << 24 |
(unsigned long)plaintext_bytes[2] << 16 |
(unsigned long)plaintext_bytes[1] << 8 |
(unsigned long)plaintext_bytes[0];
unsigned int counter = (unsigned int)plaintext_bytes[5] << 8 |
(unsigned int)plaintext_bytes[4];
unsigned char command = (plaintext_bytes[6] >> 4) & 0x0F;
unsigned char channel = plaintext_bytes[6] & 0x0F;
unsigned char checksum_expected = plaintext_bytes[7];
unsigned char checksum_calculated = 0;
for (int j = 0; j < 7; j++) {
checksum_calculated ^= plaintext_bytes[j];
}
printf("Remote ID : %lu (0x%08lX)\r\n", remote_id, remote_id);
printf("Sayac : %u\r\n", counter);
printf("Komut : %u\r\n", command);
printf("Kanal : %u\r\n", channel);
printf("Checksum : 0x%02X (Hesaplanan: 0x%02X) - %s\r\n",
checksum_expected, checksum_calculated,
(checksum_expected == checksum_calculated) ? "Gecerli" : "Gecersiz");
}
|
|
|
 |
temtronic
Joined: 01 Jul 2010 Posts: 9568 Location: Greensville,Ontario
|
|
Posted: Sun Jul 27, 2025 3:19 pm |
|
|
I don't think 'unsigned char' is valid in CCS C.
Usually 'char' is 8 bit unsigned integer
At least for older compilers' and 16/18 PICs. |
|
 |
bulut_01
Joined: 24 Feb 2024 Posts: 317
|
|
Posted: Sun Jul 27, 2025 3:36 pm |
|
|
temtronic wrote: | I don't think 'unsigned char' is valid in CCS C.
Usually 'char' is 8 bit unsigned integer
At least for older compilers' and 16/18 PICs. |
I should use unsigned int8 instead of unsigned char, right?
Also, do you know if there is a DES decryption code written for CCS C? |
|
 |
temtronic
Joined: 01 Jul 2010 Posts: 9568 Location: Greensville,Ontario
|
|
Posted: Sun Jul 27, 2025 4:14 pm |
|
|
hmm, just saw this in the first table...
0-1,
that won't compute as 'unsigned' .
maybe someone can tell this dinosaur WHY the tables are filled with xx-1s and not the real numbers ?
IE: 56 instead of 57-1 |
|
 |
bulut_01
Joined: 24 Feb 2024 Posts: 317
|
|
Posted: Sun Jul 27, 2025 4:52 pm |
|
|
temtronic wrote: | hmm, just saw this in the first table...
0-1,
that won't compute as 'unsigned' .
maybe someone can tell this dinosaur WHY the tables are filled with xx-1s and not the real numbers ?
IE: 56 instead of 57-1 |
I didn't understand anything you said. You should speak more clearly.
You write something but you don't say the solution. |
|
 |
temtronic
Joined: 01 Jul 2010 Posts: 9568 Location: Greensville,Ontario
|
|
Posted: Sun Jul 27, 2025 6:02 pm |
|
|
The IP_TABLE[40] value is 0-1
that reduces to -1
-1 is NOT a valid unsigned value |
|
 |
bulut_01
Joined: 24 Feb 2024 Posts: 317
|
|
Posted: Sun Jul 27, 2025 6:12 pm |
|
|
temtronic wrote: | The IP_TABLE[40] value is 0-1
that reduces to -1
-1 is NOT a valid unsigned value |
What is the solution? |
|
 |
temtronic
Joined: 01 Jul 2010 Posts: 9568 Location: Greensville,Ontario
|
|
Posted: Mon Jul 28, 2025 8:26 am |
|
|
you'd have to contact the person who wrote the code, find out what processor he used, which compiler and why the code was written that way.
looking quickly though the code there's a function called get_bit(x,y), I've never seen that in CCS C,though it'd be easy to translate.
lack of comments in the code doesn't help either. |
|
 |
bulut_01
Joined: 24 Feb 2024 Posts: 317
|
|
Posted: Mon Jul 28, 2025 11:45 am |
|
|
temtronic wrote: | you'd have to contact the person who wrote the code, find out what processor he used, which compiler and why the code was written that way.
looking quickly though the code there's a function called get_bit(x,y), I've never seen that in CCS C,though it'd be easy to translate.
lack of comments in the code doesn't help either. |
The code was written by an artificial intelligence. There are explanations, but they're in Turkish. This code was written for C, so I had to adapt it to CCS C. Do you know of any stable des decode algorithms? |
|
 |
temtronic
Joined: 01 Jul 2010 Posts: 9568 Location: Greensville,Ontario
|
|
Posted: Mon Jul 28, 2025 3:08 pm |
|
|
Well that shows why I have ZERO faith in 'AI' !
There are several 64 bit DES examples, GITHUB has a few, easy enough to convert into CCS C. Might take a few hours to narrow down the results but some keywords needed would be 'DES 64 bits C code'.
might check ardunio websites, AVR, etc. |
|
 |
Ttelmah
Joined: 11 Mar 2010 Posts: 19928
|
|
Posted: Tue Jul 29, 2025 7:57 am |
|
|
Yes.
My comment at the moment is "Artificial Intelligence == Real Stupidity"....
There are some things that AI does brilliantly. Looking for particular
patterns in data etc.. However if you ask them to write a program, I have
yet to see anything much beyond a basic 'Hello World', that it not full
of total idiocies.
The way the numbers are being generated into the array is an almost
'classic' example of this.
Trained monkeys are still better at the moment.
Set your compiler to ANSI mode, and this version should be very easy to
translate:
[url]
https://github.com/bressan3/DES/blob/master/main.c
[/url]
If you don't want to work in ANSI mode, then change the variable
sizes to signed int16 for int etc..
You need to do this, since the rotations used in several parts are
dependant on the variables having longer size. You can use int8 for
the arrays, but must cast them to int16, before the left rotations
using these. |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|