## Elements

Elements belonging to an algebraic structure (groups, rings and fields) are accessible through the Element interface that represents a mutable value.

### Initializing Elements

Instances of the Element interface can be obtained from an algebraic structure as shown here.

This is a brief example that shows how to get a random value.

```Field G1 = pairing.getG1();
Element e = G1.newRandomElement();
```

### Assigning Elements

The following methods can be used to assign specific values to elements. When integers are assigned, they are mapped to algebraic structures canonically if it makes sense (e.g. rings and fields).

```/* Sets an element to zero. */

e.setToZero();
```
```/* Sets an element to one. */

e.setToOne();
```
```/* If the element lies in a finite algebraic structure,
assigns a uniformly random element to it. */

e.setToRandom();
```
```/* Sets an element to an int. */

e.set(5);
```
```/* Sets an element to a BigInteger. */

e.set(new BigInteger("126785438"));
```
```/* Returns a duplicate of e. Notice that
if e is immutable then the copy is mutable.*/

Element duplicate = e.duplicate();
```

### Element Arithmetic

The addition and the multiplication functions perform addition and multiplication operations in rings and fields. For groups, both addition and multiplication represent the group operation (and similarly both 0 and 1 represent the identity element).
```/* Performs the addition between e and a.*/

```
```/* Performs the substraction between e and a.

e.sub(a);
```
```/* Performs the multiplication between e and a. */

e.mul(a);
```
```/* Performs the multiplication between e and an int. */

e.mul(5);
```
```/* Performs the multiplication between e and a BigInteger. */

e.mul(new BigInteger("5"));
```
```/* Performs the multiplication between e and z
where z must be an element of a integer mod ring (i.e. Zr for some r). */

Element z = pairing.getZr().newRandomElement();
e.mulZn(z);
```
```/* Performs the division between e and a. */

e.div(a);
```
```/* Performs the doubling of e. */

e.twice();
```
```/* Performs the halving of e. */

e.halve();
```
```/* Performs the inversion of e. */

e.invert();
```
```/* Performs the squaring of e. */

e.square();
```
```/* Performs the negation of e. */

e.negate();
```
```/* Performs the square root of e. */

e.sqrt();
```

### Element Exponentiation

```/* Raises e to a BigInteger. */

e.pow(BigInteger.valueOf(5));
```
```/* Raises e to a z which must be an element of a integer mod ring (i.e. Zr for some r). */

Element z = pairing.getZr().newRandomElement();
e.powZn(z);
```

### Preprocessing

If it knows in advance that a particular value will be raised several times then time can be saved in the long run by first calling the preprocessing function. The ElementPowPreProcessing interface will do the job.

```/* Prepare e to be raised and store preprocessing information in ppp.
e will be not modified in any way.*/

ElementPowPreProcessing ppp = e.pow();

/* Now let's raise using ppp which returns a new element which contains the result of the operation. */

Element out1 = ppp.pow(BigInteger.valueOf(5));

Element out2 = ppp.pow(pairing.getZr().newRandomElement());
```
The preprocessing information can be stored to be used later. The following code convert ppp to a byte array:
```byte[] pppBytes = ppp.toBytes();
```
To get back an ElementPowPreProcessing object from a byte array do the following
```ElementPowPreProcessing ppp = e.getField().getElementPowPreProcessingFromBytes(pppBytes);
```

### Comparing Elements

```/* Returns true if e is 1. */

e.isOne();
```
```/* Returns true if e is 0. */

e.isZero();
```
```/* Returns 0 if a and b are the same, non-zero otherwise. */

a.compareTo(b);
```
```/* Returns true if a and b are the same, false otherwise. */

a.isEqual(b);
```
```/* Returns true if e is a perfect square (quadratic residue), false otherwise. */

e.isSqr();
```
```/* If e is zero, returns 0. For a non-zero value
the behaviour depends on the algebraic structure. */

e.sign();
```

### Import/Export Elements

```/* Converts e to bytes. The number of bytes can be determined
by calling e.getLengthInBytes(). */

byte[] bytes = e.toBytes();
```
```/* To get back an Element from a byte array. */

```
```/* To get back an Element from a byte array starting from a given offset.

```
```/* Sets e deterministically from a byte array.*/

e.setFromHash(bytes, 0, bytes.length);
```

### Make Immutable

For immutable elements the internal value cannot be modified after it is created. Then, any method designed to modify the internal value of an element will return a new element whose internal value represents the result of the computation carried on.

```/* Returns true if e is immutable, false otherwise. */

e.isImmutable();
```
```/* Returns an immutable copy of e. */

Element immutable = e.getImmutable();
```