# Big integers

This section explains the key concepts of big integer library.

### Purpose of big integer

Some types of cryptography require the handling of finite arbitrary length integers. This big integer library attempts to provide support for that requirement.

It is capable of representing both negative and positive integers with an absolute value of less than 2^(237).

### Using the big integer library

There are four categories of exposed APIs:

1. Creation of new integers given some other representation (descriptor, TUint, etc). `RInteger::NewL()`

2. Creation of new integers given some criteria (range, bitcount, prime). `RInteger::NewRandomL()`, `RInteger::NewPrimeL()`

3. Exporting of previously created integers to descriptors. `TInteger::BufferLC()`

4. Querying attributes about the size of a previously created integer. `TInteger::BitCount()`, `TInteger::ByteCount()`, `TInteger::WordCount()`.

The following code demonstrates how to create an `RInteger` from a bit string representation of a big integer.

```//This creates an RInteger from the following binary hexadecimal (base 16)
//descriptor.  Note that the number is written overall in big endian (most
//significant digit is first, least significant digit (ones digit) is last).
//P.S. The hexadecimal binary descriptor below is the base 16 representation
//of the base 10 number 123456789012345678901234567890.
RInteger integer = RInteger::NewL(_L8("18EE90FF6C373E0EE4E3F0AD2"));
CleanupStack::PushL(integer);

//This next line converts the number stored by an RInteger into a binary, big
//endian, hexadecimal descriptor.
HBufC8* descriptor = integer.BufferLC();
CleanupStack::Pop(descriptor);
CleanupStack::PopAndDestroy(integer);
//descriptor is the same as the original _L8 input value now.
```

For more information on integers, including important memory management information and additional creation overloads, see `RInteger` in the Cryptography API Reference material.

### Base classes and their derived classes

The following diagram shows the main classes used in bigint and which are implemented in `cryptography.dll`. The color of the boxes indicates the type of Symbian class, that is, `M`, `C`, `R` or `T` class. Figure: The inheritance diagram for `TInteger` and `RInteger` classes.

RInteger class

`RInteger` is a `TInteger` derived class allowing the construction of variable length big integers.

This class follows standard `R` class rules. As a quick refresher, the following rules apply to `RInteger` s:

• You can construct an empty `RInteger`.

```RInteger integer;
```

This is a constructed, but uninitialized integer. It does not own memory and no operations can be performed on it. It is useful, mostly, to assign the result of another integer operation to. `Push` ing and then `PopAndDestroy` ing an empty `RInteger` works, although it's not needed.

• `RInteger` s can be bitwised copied (the default assignment operator and copy constructor are valid), but you need to be careful you don't lose your original memory in the process. You should only use the assignment operator on a newly declared integer. To set an `RInteger` to another value without losing memory see `TInteger::Set()`.

```RInteger a = anotherInteger; // OK -- you now have two integers that point to the same memory
RInteger b = RInteger::NewL(aDesc); // OK
b = a; // NOT OK, b's original memory has been lost
```
• You own any `RInteger` returned by value from a `TInteger` function.

```RInteger integer = a.MinusL(b); // We now own integer
CleanupStack::PushL(integer);
```
• You must call `Close()` on all `RInteger` s that own memory before they go out of scope. (The cleanup stack can do this for you as well, see further bullet points below).

```void foo(void)
{
RInteger integer = a.TimesL(TInteger::Two);
//< all sorts of non-leaving code here >
integer.Close();
}
```
• `RInteger` has a operator `TCleanupItem()` cast function that allows you to call `CleanupStack::PushL(RInteger&)`. Use this in preference to `CleanupClosePushL(RInteger&)`, which although it does the same thing, generates more code.

```RInteger integer = a.ModularExponentiateL(b, p);
CleanupStack::PushL(integer);
//< all sorts of leaving code here >
CleanupStack::PopAndDestroy(&integer);
```
• Be careful calling `TInteger::Set()`. After calling this, two `RInteger` s have a pointer to the same heap-based integer. Calling `Close()` on one, either explicitly or through the cleanup stack, leaves a dangling pointer to the other. You probably want to use code similar to the following:

```RInteger first = RInteger::NewL(298728);
CleanupStack::PushL(first);
//< all sorts of leaving code here >
RInteger second.Set(first);
CleanupStack::Pop(first);
CleanupStack::PushL(second);
```