char in C++ is equivalent to byte or sbyte in C#.
When bit shifting etc in C#, the result is an int so a cast back to byte is required.
Assuming the seed values are assigned to elsewhere and the C++ code isn't relying on some default overflow behavior not present in .net then the code below is a straight conversion (you may also want to decide what the default case in the switch should be):
public static byte s0, s1, s2, s3, s4, s5;
public static byte byteConv(byte byt, int byteNum)
{
byte b, shift, c;
switch (byteNum)
{
default:
case 0:
c = (byte)(byt ^ s0);
break;
case 1:
c = (byte)(byt ^ s1);
break;
case 2:
c = (byte)(byt ^ s2);
break;
case 3:
c = (byte)(byt ^ s3);
break;
case 4:
c = (byte)(byt ^ s4);
break;
case 5:
c = (byte)(byt ^ s5);
break;
}
shift = 0;
for (byte i = 0; i < 8; i++)
shift += (byte)((c >> i) & 0x01);
shift = (byte)((shift + s0 + s1 + s2 + s3 + s4 + s5) & 0x07);
b = (byte)((c >> shift) | (c << (8 - shift)));
return b;
}
public static void responseCode(
byte challenge0,
byte challenge1,
byte challenge2,
byte challenge3,
byte challenge4,
byte challenge5,
out byte response0,
out byte response1,
out byte response2,
out byte response3,
out byte response4,
out byte response5)
{
byte b0, b1, b2, b3, b4, b5;
b0 = byteConv(challenge0, 0);
b1 = byteConv(challenge1, 1);
b2 = byteConv(challenge2, 2);
b3 = byteConv(challenge3, 3);
b4 = byteConv(challenge4, 4);
b5 = byteConv(challenge5, 5);
response0 = (byte)((b1 + b2 - b3 + b4 - b5) ^ b0);
response1 = (byte)((b2 + b3 - b4 + b5 - b0) ^ b1);
response2 = (byte)((b3 + b4 - b5 + b0 - b1) ^ b2);
response3 = (byte)((b4 + b5 - b0 + b1 - b2) ^ b3);
response4 = (byte)((b5 + b0 - b1 + b2 - b3) ^ b4);
response5 = (byte)((b0 + b1 - b2 + b3 - b4) ^ b5);
}