Rabin FUNCTIONS(3BM)

NAME
genRabinKeySet, getRabinPublicKey, getRabinPrivateKey, RabinEncrypt, RabinDecrypt, RabinSign, RabinVerify, freeRabinKeys, freeRabinSig randBytesNeededForRabinSet, randBytesNeededForRabinEncrypt, randBytesNeededForRabinSign

SYNOPSIS
#include <libcrypt.h>

int randBytesNeededForRabinSet(int modbits)

int randBytesNeededForRabinEncrypt(int modbits)

int randBytesNeededForRabinSign(int modbits)

RabinKeySet *genRabinKeySet(int modulusdBits, BitInt randomStart)

BigInt RabinEncrypt(message, RabinPubKey, randomStart)
BigInt message;
RabinPublicKey *RabinPubKey;
BigInt randomStart;

BigInt RabinDecrypt(message, RabinPrivKey)
BigInt message;
RabinPrivateKey *RabinPrivKey;

BigInt quantized_RabinDecrypt(message, RabinPrivKey)
BigInt message;
RabinPrivateKey *RabinPrivKey;

RabinSignature *RabinSign(message, RabinPrivKey, randomStart)
BigInt message;
RabinPRivateKey *RabinPrivKey;
BigInt randomStart;

RabinSignature *quantized_RabinSign(message, RabinPrivKey, randomStart)
BigInt message;
RabinPRivateKey *RabinPrivKey;
BigInt randomStart;

Boolean RabinVerify(message, signature, RabinPubKey)
BigInt message;
RabinSignature *signature;
RabinPublicKey *RabinPubKey;

freeRabinKeys(RabinKeySet)
RabinKeySet *RabinKeySet;

freeRabinSig(RabinSig)
RabinSignature *RabinSig;

DESCRIPTION

For all of these functions $BigInt$ arguments are assumed to be initialized $BigInts$. $bigInit(0)$ should be used for initialization of empty $BigInts$. If more space is needed than is provided the functions themselves take care of the space allocation.

In all of the function which have an argument, $randomStart$, if this argument is chosen NULL, the default, DES-based pseudo-RNG seeded with truerand() will be used to generate necessary random material. If $randomStart$ is not NULL, the accompanying functions, randBytesNeededForEG... are used to find out how many random bytes are expected.

Rabin's scheme is essentially RSA with 2 as the public exponent. Care has been taken to avoid the small exponent attack (See Simmons' Contemporary Cryptology). Encryption, Decryption, Signature and Verification work exactly as with RSA. However, since squaring is the encryption process, to decrypt the square root is taken. This yields 4 square roots. Thus some way to detect which if these is correct is needed. The message to be encrypted is thus given "structure". From most-sig-byte to least, the format is: [random pad | message | msg_len (4 bytes) | digest (pad | msg | msg_len) ] The digest functions supported are SHS, MD{2, 4, 5}. The functions below take as arguments the digest type and digest length in bytes.

In order to sign messages the square root must be calculated. Thus the message to be signed must be put into a form which is a quadratic residue modulo N. It is for this reason that Rabin's signature is usually less efficient than doing RSASign.

The quantized version use STD_QUANTUM milliseconds as the quantum for execution to defend against Kocher-style timing attacks. STD_QUANTUM is defined in libcrypt.h and should be tuned to your environment.

$freeRabinKeySet$ frees the key set structure and all of its associated BigInts.

$freeRabinSig$ frees the Rabin signature (actually just a BigInt).

SEE ALSO
bigInit(3BM), bigTest(3BM), bigBits(3BM), bigToBuf(3BM), bufToBig(3BM), fBigPrint(3BM), atobig(3BM), bigPow(3BM), fputRabinPrivateKey(3BM) start_quantize(3BM) end_quantize(3BM)