I am currently trying to get the schifra library running for making some tests to implement it later in my code.
I am currently looking at the schifra_reed_solomon_example02.cpp and try to understand how I have to set the values to suite my needs.
/* Finite Field Parameters */
const std::size_t field_descriptor = 8; // GF(2^8) ok
const std::size_t generator_polynommial_index = 120; // what is this?
const std::size_t generator_polynommial_root_count = 32; // polynomial up to x^32
/* Reed Solomon Code Parameters */
const std::size_t code_length = 255; // amount of symbols in codeword
const std::size_t fec_length = 32; // minimal distance d ?
const std::size_t data_length = code_length - fec_length; // amount of symbols my message has
So what I try to have is an RS-Code for n, k , d = (128, 16, 113)
And I would proceed the following:
/* Finite Field Parameters */
const std::size_t field_descriptor = 8; // I want GF(2^8)
const std::size_t generator_polynommial_index = 120; // still not knowing
const std::size_t generator_polynommial_root_count = 16; // because polynomial up to 16
/* Reed Solomon Code Parameters */
const std::size_t code_length = 128; // 128 byte codewords
const std::size_t fec_length = 113; // minimal distance, 113 because d = n - k +1
const std::size_t data_length = 16;
I then receive at encoding a mesage an error.
schifra::galois::field_polynomial generator_polynomial(field);
schifra::sequential_root_generator_polynomial_creator(field,
generator_polynommial_index,
generator_polynommial_root_count,
generator_polynomial);
/* Instantiate Encoder and Decoder (Codec) */
schifra::reed_solomon::encoder<code_length,fec_length> encoder(field,generator_polynomial);
schifra::reed_solomon::decoder<code_length,fec_length> decoder(field,generator_polynommial_index);
std::string message = "A professional i"; // its 16 bytes
std::cout << "Original Message: [" << message << "]" << std::endl;
message = message + std::string(data_length - message.length(),static_cast<unsigned char>(0x00)); // this one is also done in example
std::cout << "Original Message: [" << message << "]" << std::endl;
std::cout << "Message length: " << message.length() << std::endl; // still 16 bytes
/* Instantiate RS Block For Codec */
schifra::reed_solomon::block<code_length,fec_length> block;
/* Transform message into Reed-Solomon encoded codeword */
if (!encoder.encode(message,block))
{
std::cout << "Error - Critical encoding failure!" << std::endl;
return 1;
}
The Error - Critical encoding failure! is then given.
I think what I do wrong is setting up the polynommial correct - maybe someone can help me?
Reed-Solomon encoding is not meant to work with
your parameters, independent of the program code.
You can choose following things:
B, that is how many bit one data unit has (eg. B=8 for normal byte data).Twith0 <= T < (2^b)/3: Larger Ts mean better error correction, but less encoding speed.You can NOT choose:
2^B, nothing else.(2^B - 2*T - 1)data units (here bytes), nothing else.2*Tdata units checksum data.2^B -1data units.This means, with bytes as data units, such a block has exactly 255 byte, nothing else.
Twrong data units can be corrected(the errors may be in plaintext and/or checksum part, doesn't matter)
2*Twrong data units can be recognized, but necessarily corrected.2*Terrors, all bets are off.In the example code (partially):
So for each 233 plaintext byte, RS calculates 32 checksum byte
(=255 total byte), to be able to correct up to 16 wrong byte later.
In your code, you choose GF(2^8) and byte data, so B=8, thus code_length 128 is wrong. It has to be 255. The checksum part length 113 is too much and not even, and the plaintext length isn't the difference of the previous values.
...
Other than that, of 6 RS codes I know in the internet, Shifra is by far the worst (very slow despite being praised as "highly optimzed", quirky code, problematic license, ...). Choose anything, but not Schifra.
I'll check if I can share something I wrote ... Including learning about the inner workings of the algorithm, writing everything (encoder+decoder) took not even a day, and it was 3 times faster than Schifra on the test machine back then (no asm, just C++). The downside is that is can only work with byte-based data, ie.
B=8, without being able to choose other bases. But probably you don't need that anyways.