# Part 3: Annotated Specification

## Helper Functions

### Math

`integer_squareroot`

```
def integer_squareroot(n: uint64) -> uint64:
"""
Return the largest integer ``x`` such that ``x**2 <= n``.
"""
x = n
y = (x + 1) // 2
while y < x:
x = y
y = (x + n // x) // 2
return x
```

Validator rewards scale with the reciprocal of the square root of the total active balance of all validators. This is calculated in `get_base_reward_per_increment()`

.

In principle `integer_squareroot`

is also used in `get_attestation_participation_flag_indices()`

, to specify the maximum delay for source votes to receive a reward. But this is just the constant, `integer_squareroot(SLOTS_PER_EPOCH)`

, which is `5`

.

Newton's method is used which has pretty good convergence properties, but implementations may use any method that gives identical results.

Used by | `get_base_reward_per_increment()` , `get_attestation_participation_flag_indices()` |

`xor`

```
def xor(bytes_1: Bytes32, bytes_2: Bytes32) -> Bytes32:
"""
Return the exclusive-or of two 32-byte strings.
"""
return Bytes32(a ^ b for a, b in zip(bytes_1, bytes_2))
```

The bitwise `xor`

of two 32-byte quantities is defined here in Python terms.

This is used only in `process_randao()`

when mixing in the new randao reveal.

Fun fact: if you `xor`

two `byte`

types in Java, the result is a 32 bit (signed) integer. This is one reason we need to define the "obvious" here. But mainly, because the spec is executable, we need to tell Python what it doesn't already know.

Used by | `process_randao()` |

`uint_to_bytes`

`def uint_to_bytes(n: uint) -> bytes`

is a function for serializing the`uint`

type object to bytes in`ENDIANNESS`

-endian. The expected length of the output is the byte-length of the`uint`

type.

For the most part, integers are integers and bytes are bytes, and they don't mix much. But there are a few places where we need to convert from integers to bytes:

- several times in the
`compute_shuffled_index()`

algorithm; - in
`compute_proposer_index()`

for selecting a proposer weighted by stake; - in
`get_seed()`

to mix the epoch number into the randao mix; - in
`get_beacon_proposer_index()`

to mix the slot number into the per-epoch randao seed; and - in
`get_next_sync_committee_indices()`

.

You'll note that in every case, the purpose of the conversion is for the integer to form part of a byte string that is hashed to create (pseudo-)randomness.

The result of this conversion is dependent on our arbitrary choice of endianness, that is, how we choose to represent integers as strings of bytes. For Eth2, we have chosen little-endian: see the discussion of `ENDIANNESS`

for more background.

The `uint_to_bytes()`

function is not given an explicit implementation in the specification, which is unusual. This to avoid exposing the innards of the Python SSZ implementation (of `uint`

) to the rest of the spec. When running the spec as an executable, it uses the definition in the SSZ utilities.

Used by | `compute_shuffled_index()` , `compute_proposer_index()` , `get_seed()` , `get_beacon_proposer_index()` , `get_next_sync_committee_indices()` |

See also | `ENDIANNESS` , SSZ utilities |

`bytes_to_uint64`

```
def bytes_to_uint64(data: bytes) -> uint64:
"""
Return the integer deserialization of ``data`` interpreted as ``ENDIANNESS``-endian.
"""
return uint64(int.from_bytes(data, ENDIANNESS))
```

`bytes_to_uint64()`

is the inverse of `uint_to_bytes()`

, and is used by the shuffling algorithm to create a random index from the output of a hash.

It is also used in the validator specification when selecting validators to aggregate attestations, and sync committee messages.

`int.from_bytes`

is a built-in Python 3 method. The `uint64`

cast is provided by the spec's SSZ implementation.

Used by | `compute_shuffled_index` |

See also | attestation aggregator selection, sync committee aggregator selection |