# Welcome to bplib’s documentation!¶

The `bplib` is a library implementing support for computations on groups supporting bilinear pairings, as used in modern cryptography.

It is based on the OpenPairing library by Diego Aranha (https://github.com/dfaranha/OpenPairing), which is itself based on, and compatible with, OpenSSL math functions (`bn` and `ec`). The `bplib` is compatible with `petlib` types including `petlib.bn` and the group G1 is a `petlib.ec` EC group. Along with `petlib`, they provide easy to use support for maths and ciphers used in modern Privacy Enhancing Technologies.”

A set of bilinear EC groups is defined as:

```>>> G = bp.BpGroup()
```

Such a BpGroup describes 3 groups G1, G2 and GT such that pair(G1,G2)->GT. Generators for the groups G1 and G2 are denoted by:

```>>> g1, g2 = G.gen1(), G.gen2()
```

The special `pair` operation computes to pairing into GT:

```>>> gt = G.pair(g1, g2)
```

Operations are defined on all elements of G1, G2 or GT in a natural additive infix notation for G1 and G2, and a multiplicative notation for GT:

```>>> gt6 = gt**6
```

As expected the `pair` operations is additive:

```>>> G.pair(g1, 6*g2) == gt6
True
>>> G.pair(6*g1, g2) == gt6
True
>>> G.pair(2*g1, 3*g2) == gt6
True
```

# Reference¶

## Module bplib.bp.BpGroup¶

class `bplib.bp.``BpGroup`(nid=1, optimize_mult=True)

A class representing all groups involved in the bilinear pairing: G1, G2, and GT.

`gen1`()

Returns the generator for G1.

`gen2`()

Returns the generator for G2.

`hashG1`(sbin)

Hashes a byte string into a point of G1.

Example:
```>>> G = BpGroup()
>>> g1 = G.gen1()
>>> g1p = G.hashG1(b"Hello")
>>> x = g1 + g1p
```
`order`()

Returns the order of the group as a Big Number.

Example:
```>>> G = BpGroup()
>>> print(G.order())
16798108731015832284940804142231733909759579603404752749028378864165570215949
```
`pair`(g1, g2)

The pairing operation e(G1, G2) -> GT.

Example:
```>>> G = BpGroup()
>>> g1, g2 = G.gen1(), G.gen2()
>>> gt = G.pair(g1, g2)
>>> gt6 = G.pair(g1.mul(2), g2.mul(3))
>>> gt.exp(6).eq( gt6 )
True
>>> gt**6 == G.pair(2*g1, 3*g2)
True
```

## Module bplib.bp.GXElem¶

class `bplib.bp.``G1Elem`(group)
`add`(other)

Returns the sum of two points.

`double`()

Returns the double of the G1 point.

`eq`(other)

Returns True if points are equal.

Example:
```>>> G = BpGroup()
>>> g1 = G.gen1()
>>> g1.add(g1).eq(g1.double())
True
>>> g1.eq(g1.double())
False
>>> g1+g1 == 2*g1
True
>>> g1+g1 == Bn(2)*g1
True
```
`export`(form=0)

Export a point to a byte representation.

static `from_bytes`(sbin, group)

Import a G1 point from bytes.

Export:
```>>> G = BpGroup()
>>> g1 = G.gen1()
>>> buf = g1.export()
>>> g1p = G1Elem.from_bytes(buf, G)
>>> g1 == g1p
True
```
static `inf`(group)

Returns the element at infinity for G1

`isinf`()

Returns True if the element is infinity.

`mul`(scalar)

Multiplies the point with a scalar.

Example:
```>>> g1 = BpGroup().gen1()
>>> g1.mul(2).eq(g1.double())
True
```
`neg`()

Returns the inverse point.

Example:
```>>> G = BpGroup()
>>> g1 = G.gen1()
>>> g1.add(g1.neg()).isinf()
True
>>> g1 - g1 == G1Elem.inf(G)
True
```
class `bplib.bp.``G2Elem`(group)
`add`(other)

Returns the sum of two points.

`double`()

Returns the double of the G2 point.

`eq`(other)

Returns True if points are equal.

Example:
```>>> G = BpGroup()
>>> g2 = G.gen2()
>>> g2.add(g2).eq(g2.double())
True
>>> g2.add(g2) == g2.double()
True
>>> g2.eq(g2.double())
False
>>> g2 != g2.double()
True
```
`export`(form=1)

Export a point to a byte representation.

static `from_bytes`(sbin, group)

Import a G2 point from bytes.

Export:
```>>> G = BpGroup()
>>> g2 = G.gen2()
>>> buf = g2.export()
>>> g2p = G2Elem.from_bytes(buf, G)
>>> g2.eq(g2p)
True
```
static `inf`(group)

Returns the element at infinity for G2.

`isinf`()

Returns True if the element is infinity.

`mul`(scalar)

Multiplies the point with a scalar.

Example:
```>>> g2 = BpGroup().gen2()
>>> g2.mul(2).eq(g2.double())
True
```
`neg`()

Returns the inverse point.

Example:
```>>> g2 = BpGroup().gen2()
>>> g2.add(g2.neg()).isinf()
True
```
class `bplib.bp.``GTElem`(group)
`add`(other)

Returns the sum of two GT elements.

Example:
```>>> G = BpGroup()
>>> zero = GTElem.zero(G)
>>> x = zero.add(zero)
>>> x.iszero()
True
>>> zero + zero == zero
True
>>> one = GTElem.one(G)
>>> zero + one == one
True
```
`eq`(other)

Returns True if elements are equal.

`exp`(scalar)

Exponentiates the element with a scalar.

Example:
```>>> G = BpGroup()
>>> g = G.pair(G.gen1(), G.gen2())
>>> g**0 == g.one(G)
True
>>> g**3 * g**5 == g**8
True
>>> g**10 * g**(-13) == g**(-3)
True
>>> g**2 * g**(-2) == g.one(G)
True
```
`export`()

Export a GT element to a byte representation.

static `from_bytes`(sbin, group)

Import a GT element from bytes.

Export:
```>>> G = BpGroup()
>>> gt = G.pair(G.gen1(), G.gen2())
>>> buf = gt.export()
>>> gtp = GTElem.from_bytes(buf, G)
>>> gt.eq(gtp)
True
```
`inv`()

Returns the inverse element.

Example:
```>>> G = BpGroup()
>>> gt = G.pair(G.gen1(), G.gen2())
>>> gt2 = gt.mul(gt)
>>> gtp = gt.sqr()
>>> gtp.eq(gt2)
True
```
`isone`()

Return zero if the element is one.

`iszero`()

Return True if the element is zero.

`mul`(other)

Returns the product of two elements.

Example:
```>>> G = BpGroup()
>>> gt = G.pair(G.gen1(), G.gen2())
>>> gtinv = gt.inv()
>>> x = gt.mul(gtinv)
>>> x.isone()
True
>>> gt * gtinv == GTElem.one(G)
True
```
static `one`(group)

Returns the element at infinity for GT.

`sqr`()

Returns the square of an element.

`sub`(other)

Returns the difference of two GT elements.

Example:
```>>> G = BpGroup()
>>> zero = GTElem.zero(G)
>>> one = GTElem.one(G)
>>> x = one.sub(one)
>>> x.iszero()
True
>>> one - one == zero
True
```
static `zero`(group)

Returns the element at infinity for GT.

## Encoding and decoding bplib objects¶

The `petlib.pack` functions `encode` and `decode` may be used to get byte representations of `BpGroup`, `G1Elem`, `G2Elem`, and `GTElem`. Just ensure you import `bplib` before calling those functions.