Element IntegerGroup::EncodeBytes(const QByteArray &in) const { // We can store p bytes minus 2 bytes for padding and one more to be safe const int can_read = BytesPerElement(); if(can_read < 1) qFatal("Illegal parameters"); if(in.count() > can_read) qFatal("Cannot encode: string is too long"); // Add initial 0xff byte and trailing 0x00 byte QByteArray padded; padded.append(0xff); padded.append(in.left(can_read)); padded.append((char)0x00); padded.append(0xff); // Change byte of padded string until the // integer represented by the byte arry is a quadratic // residue. We need to be sure that every plaintext // message is a quadratic residue modulo p const int last = padded.count()-2; for(unsigned char pad=0x00; pad < 0xff; pad++) { padded[last] = pad; Element element(new IntegerElementData(Integer(padded))); if(IsElement(element)) { return element; } } qFatal("Could not encode message as quadratic residue"); return Element(new IntegerElementData(Integer(1))); }
Element CppECGroup::EncodeBytes(const QByteArray &in) const { /* * See the article * "Encoding And Decoding of a Message in the * Implementation of Elliptic Curve Cryptography * using Koblitz’s Method" for details on how this works. * * k == MessageSerializationParameter defines the percentage * chance that we won't be able to encode a given message * in a given elliptic curve point. The failure probability * is 2^(-k). * * We can store b = log_2(p/k) bytes in every * elliptic curve point, where p is the security * parameter (prime size) of the elliptic curve. * * For p = 2^256, k = 256, b = 224 (minus 2 padding bytes) */ if(in.count() > BytesPerElement()) { qFatal("Failed to serialize over-sized string"); } // Holds the data to be encoded plus a leading and a trailing // 0xFF byte QByteArray data; data.append(0xff); data += in; data.append(0xff); // r is an encoding of the string in a big integer CryptoPP::Integer r(reinterpret_cast<const byte*>(data.constData()), data.count()); //qDebug() << "r" << FromCppInteger(r)).GetByteArray().toHex(); Q_ASSERT(r < _curve.FieldSize()); Element point; CryptoPP::Integer x, y; for(int i=0; i<_k; i++) { // x = rk + i mod p x = ((r*_k)+i); Q_ASSERT(x < _curve.FieldSize()); if(SolveForY(x, point)) { return point; } } qFatal("Failed to find point"); return Element(new CppECElementData(CryptoPP::ECPPoint())); }
Element ByteGroup::EncodeBytes(const QByteArray &in) const { const int can_read = BytesPerElement(); if(can_read < 1) qFatal("Illegal parameters"); if(in.count() > can_read) qFatal("Cannot encode: string is too long"); QByteArray out(_n_bytes, 0); Utils::Serialization::WriteInt(in.count(), out, 0); for(int i=0; i<can_read && i<in.count(); i++) { out[i+4] = in[i]; } return Element(new ByteElementData(out)); }
Element CompositeIntegerGroup::EncodeBytes(const QByteArray &in) const { // We can store p bytes minus 2 bytes for padding and one more to be safe const int can_read = BytesPerElement(); if(can_read < 1) qFatal("Illegal parameters"); if(in.count() > can_read) qFatal("Cannot encode: string is too long"); // Add initial 0xff byte and trailing 0x00 byte QByteArray padded; padded.append(0xff); padded.append(in.left(can_read)); padded.append(0xff); return Element(new IntegerElementData(Integer(padded))); }