Bonjour,

J'aimerai que quelqu'un m'explique comment fonctionne ce code.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
 
// Software optimized 48-bit Philips/NXP Mifare "Classic" CRYPTO-1 stream cipher algorithm by I.C. Wiener 2007-2008.
// For educational purposes only.
// No warranties or guarantees of any kind.
// This code is released into the public domain by its author.
 
#include <stdio.h>
 
// Basic macros:
 
#define u8				unsigned char
#define u32				unsigned long
#define u64				unsigned long long
#define rev8(x)			((((x)>>7)&1)^((((x)>>6)&1)<<1)^((((x)>>5)&1)<<2)^((((x)>>4)&1)<<3)^((((x)>>3)&1)<<4)^((((x)>>2)&1)<<5)^((((x)>>1)&1)<<6)^(((x)&1)<<7))
#define rev16(x)		(rev8 (x)^(rev8 (x>> 8)<< 8))
#define rev32(x)		(rev16(x)^(rev16(x>>16)<<16))
#define bit(x,n)		(((x)>>(n))&1)
 
// Single bit CRYPTO-1 functions:
 
// PRNG
 
static u32 crypto1_next (u32 x, const u32 n)
{
	u32		i;
 
	x = rev32(x);
	for (i = 0; i < n; i++) x=(x<<1)+(((x>>15)^(x>>13)^(x>>12)^(x>>10))&1);
	return rev32(x);
}
 
#define i4(x,a,b,c,d)	((u32)((((x)>>(a))&1)+(((x)>>(b))&1)*2+(((x)>>(c))&1)*4+(((x)>>(d))&1)*8))
 
static const u32 mf1_f4a = 0x9E98;
static const u32 mf1_f4b = 0xB48E;
static const u32 mf1_f5c = 0xEC57E80A;
 
// Nonlinear output/feedback function
 
static u32 nf20 (const u64 x)
{
	u32		i5;
 
	i5 = ((mf1_f4b >> i4 (x, 9,11,13,15)) & 1)* 1
	   + ((mf1_f4a >> i4 (x,17,19,21,23)) & 1)* 2
	   + ((mf1_f4a >> i4 (x,25,27,29,31)) & 1)* 4
	   + ((mf1_f4b >> i4 (x,33,35,37,39)) & 1)* 8
	   + ((mf1_f4a >> i4 (x,41,43,45,47)) & 1)*16;
 
	return (mf1_f5c >> i5) & 1;
}
 
// Linear output/feedback function
 
static u32 lf18 (const u64 x)
{
	return  (((x >>  0) ^ (x >>  5) ^ (x >>  9) ^ (x >> 10) ^ (x >> 12) ^ (x >> 14)
			^ (x >> 15) ^ (x >> 17) ^ (x >> 19) ^ (x >> 24) ^ (x >> 25) ^ (x >> 27)
			^ (x >> 29) ^ (x >> 35) ^ (x >> 39) ^ (x >> 41) ^ (x >> 42) ^ (x >> 43)) & 1);
}
 
// Single CRYPTO-1 round
 
// 0 - no feedback
// 1 - linear feedback
// 2 - nonlinear feedback
// 3 - both
 
static u32 crypto1_round (u64 *state, const u64 in_bit, const u32 fb)
{
	u64		x = *state;
	u32		lf, nf;
 
	lf = lf18(x);
	nf = nf20 (x);
	x = (x>>1) ^ ((in_bit ^ (fb&1?lf:0) ^ (fb&2?nf:0)) << 47);
	*state = x;
	return nf;
}
 
// 32 CRYPTO-1 rounds
 
static u32 crypto1_word (u64 * x, const u32 in_word, const u32 fb)
{
	u32		i, o;
 
	for (i = 0, o = 0; i < 32; i++) o += (u32) crypto1_round (x, bit(in_word,i^24), fb) << (i^24);
	return o;
}
 
#define tests	8
 
int main (void)
{
	u32		i, k;
	u64		s[tests];
	u64		key[tests] = {-1ULL>>16,  -1ULL>>16,  -1ULL>>16,  -1ULL>>16,  -1ULL>>16,  -1ULL>>16,  -1ULL>>16,  -1ULL>>16};
	u32		ID[tests] = {0x7BED1AFD, 0x7BED1AFD, 0x7BED1AFD, 0x7BED1AFD, 0x7BED1AFD, 0x7BED1AFD, 0x7BED1AFD, 0x7BED1AFD};
	u32		TC[tests] = {0x01020304, 0x02030405, 0x03040506, 0x04050607, 0x05060708, 0x06070809, 0x0708090A, 0x08090A0B};
	u32		RC[tests] = {0x12345678, 0x23456789, 0x3456789A, 0x456789AB, 0x56789ABC, 0x6789ABCD, 0x789ABCDE, 0x89ABCDEF};
	u32		RR[tests] = {0x8D3A9A9C, 0x525BF719, 0xB3B6BCF5, 0x8D58D582, 0x1A4389AD, 0x8E791939, 0x6D3566AF, 0x870B0215};
	u32		TR[tests] = {0x7208E6C6, 0xBBEF66AE, 0xC622FC7F, 0x21741A05, 0xE350ACD9, 0xD0240BF8, 0xF0B5A5C5, 0x8AD097B3};
	u32		KS[tests][5] =
	{
		{0xF0293188, 0x96188BA7, 0x8743C386, 0x4BAFEEF2, 0x9F5B3C53},
		{0x6C5976CF, 0x4B2F94B8, 0x77B92595, 0xDDB19335, 0xB811C5A5},
		{0x7E55F18D, 0xE0AB17F7, 0xFFCF6559, 0x131E7093, 0x7145E26B},
		{0xBFDC7361, 0x9403B607, 0x26E4D8F2, 0xFEBAB9F0, 0x81AEB1C9},
		{0xD556A1EC, 0x8759D54D, 0xC5B10ACE, 0xB6A9C3CD, 0x94F5A51C},
		{0x0916465B, 0x0A9AE66B, 0x31EF4F79, 0x044D4505, 0xEE4125C4},
		{0x99C49847, 0x525B1DE4, 0xB7F78842, 0xF3A36608, 0x72E92768},
		{0xFEA22F39, 0x3B809753, 0x9893345F, 0x82371E6D, 0xBB9DEFAF}
	};
 
	for (k = 0; k < tests; k++)
	{
	//	s[k] = key[k];
	//	crypto1_word (s+k, ID[k] ^ TC[k], 1);
	//	crypto1_word (s+k, RC[k]        , 3);
	//	RR[k] = crypto1_next (TC[k], 64) ^ crypto1_word (s+k, 0, 1);
	//	TR[k] = crypto1_next (TC[k], 96) ^ crypto1_word (s+k, 0, 1);
	//	KS[k][0] = 0x3002108B ^ crypto1_word (s+k, 0, 1);
	//	for (i = 1; i < 5; i++) KS[k][i] = crypto1_word (s+k, 0, 1);
		s[k] = key[k];
		crypto1_word (s+k, ID[k] ^ TC[k], 1); printf ("%08X ", TC[k]);
		crypto1_word (s+k, RC[k]        , 3); printf ("%08X ", RC[k]);
		printf ("UID: %08X\nTag Challenge: %08X\nReader Challenge: %08X\nReader Response: %08X\nTag Response:%08X\nTag Command:%08X\nTag Data: %08X %08X %08X %08X\n\n",
			ID[k], TC[k], RC[k], RR[k], TR[k], KS[k][0], KS[k][1], KS[k][2], KS[k][3], KS[k][4]);
		printf ("%s ", (crypto1_next (TC[k], 64) ^ crypto1_word (s+k, 0, 1)) == RR[k] ? "OK" : "??");
		printf ("%s ", (crypto1_next (TC[k], 96) ^ crypto1_word (s+k, 0, 1)) == TR[k] ? "OK" : "??");
		for (i = 0; i < 5; i++) printf ("%08X ", KS[k][i] ^ crypto1_word (s+k, 0, 1));
		printf ("\n\n");
	}
	return 0;
}
Je vous remercie.