Native interface

The native wrapper follows RELIC’s convention of writing operations in G1 and G2 additively, and those in GT multiplicatively. You can use this interface by importing

from petrelic.native.pairing import G1, G2, GT

petrelic.native.pairing

This module provides a Python wrapper around RELIC’s pairings using a native interface: operations in petrelic.native.pairings.G1 and petrelic.native.pairings.G2 are written additively, whereas operations in petrelic.native.pairings.GT are written multiplicatively.

Let’s see how we can use this interface to implement the Boney-Lynn-Shacham signature scheme for type III pairings. First we generate a private key:

>>> sk = G1.order().random()

which is a random integer modulo the group order. Note that for this setting, all three groups have the same order. Next, we generate the corresponding public key:

>>> pk = (sk * G1.generator(), sk * G2.generator())

(For security in the type III setting, the first component is a necessary part of the public key. It is not actually used in the scheme.) To sign a message m we first hash it to the curve G1 using G1.hash_to_point() and then multiply it with the signing key sk to obtain a signature:

>>> m = b"Some message"
>>> signature = sk * G1.hash_to_point(m)

Finally, we can use the pairing operator to verify the signature:

>>> signature.pair(G2.generator()) == G1.hash_to_point(m).pair(pk[1])
True

Indeed, the pairing operator is bilinear. For example:

>>> a, b = 13, 29
>>> A = a * G1.generator()
>>> B = b * G2.generator()
>>> A.pair(B) == G1.generator().pair(G2.generator()) ** (a * b)
True
class petrelic.native.pairing.BilinearGroupPair[source]

A bilinear group pair used to wrap the three groups G1, G2, GT.

groups()[source]

Returns the three groups in the following order : G1, G2, GT.

class petrelic.native.pairing.G1[source]

The G1 group.

classmethod generator()

Return generator of the group.

Example:
>>> generator = G1.generator()
>>> neutral = G1.neutral_element()
>>> generator + neutral == generator
True
classmethod hash_to_point(hinput)

Return group element obtained by hashing the input

Example:
>>> elem = G1.hash_to_point(b"foo")
>>> elem.is_valid()
True
classmethod infinity()[source]

The point at infinity.

Alias for G1.neutral_element()

classmethod neutral_element()

Return the neutral element of the group G1.

In this case, the point at infinity.

Example:
>>> generator = G1.generator()
>>> neutral = G1.neutral_element()
>>> generator + neutral == generator
True
classmethod order()

Return the order of the group as a Bn large integer.

Example:
>>> generator = G1.generator()
>>> neutral = G1.neutral_element()
>>> order = G1.order()
>>> order * generator == neutral
True
classmethod sum(elems)[source]

Efficient sum of a number of elements

In the current implementation this function is not optimized.

Example:
>>> elems = [ x * G1.generator() for x in [10, 25, 13]]
>>> G1.sum(elems) ==  (10 + 25 + 13) * G1.generator()
True
classmethod wsum(weights, elems)[source]

Efficient weighted product of a number of elements

In the current implementation this function is not optimized.

Example:
>>> weights = [1, 2, 3]
>>> elems = [ x * G1.generator() for x in [10, 25, 13]]
>>> G1.wsum(weights, elems) ==  (1 * 10 + 2 * 25 + 3 * 13) * G1.generator()
True
class petrelic.native.pairing.G1Element[source]

Element of the G1 group.

add(other)

Add two points together.

This method is aliased by a + b.

Examples:
>>> a = 10 * G1.generator()
>>> b = 40 * G1.generator()
>>> a + b == 50 * G1.generator()
True
>>> a.add(b) == 50 * G1.generator()
True
double()[source]

Return double of the current element

Example:
>>> generator = G1.generator()
>>> elem = generator.double()
>>> elem == 2 * generator
True
eq(other)

Check point equality.

classmethod from_binary(sbin)

Deserialize a binary representation of the element of G1.

Example:
>>> generator = G1.generator()
>>> bin_repr = generator.to_binary()
>>> elem = G1Element.from_binary(bin_repr)
>>> generator == elem
True
get_affine_coordinates()

Return the affine coordinates (x,y) of this EC Point.

Example:
>>> generator = G1.generator()
>>> x, y = generator.get_affine_coordinates()
>>> x
Bn(3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507)
>>> y
Bn(1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569)
group

alias of G1

iadd(other)

Inplace add another point.

Examples:
>>> a = 10 * G1.generator()
>>> b = 10 * G1.generator()
>>> a += 3 * G1.generator()
>>> _ = b.iadd(3 * G1.generator())
>>> a == b
True
>>> a == 13 * G1.generator()
True
idouble()[source]

Inplace double the current element.

Example:
>>> generator = G1.generator()
>>> elem = G1.generator()
>>> _ = elem.idouble()
>>> elem == 2 * generator
True
iinverse()

Inplace inverse of the current element

Examples:
>>> a = 30
>>> elem1 = a * G1.generator()
>>> elem2 = a * G1.generator()
>>> _ = elem1.iinverse()
>>> elem1 == elem2.inverse()
True
imul(other)

Inplace point multiplication by a scalar

Examples:
>>> a = G1.generator()
>>> b = G1.generator()
>>> a *= 10
>>> _ = b.imul(10)
>>> a == b
True
>>> a == 10 * G1.generator()
True
inverse()

Return the inverse of the element.

Examples:
>>> a = 30
>>> elem = a * G1.generator()
>>> -elem == elem.inverse()
True
>>> elem.inverse() == (G1.order() - a) * G1.generator()
True
is_infinity()

Check if the object is the neutral element of G1.

Example:
>>> generator = G1.generator()
>>> order = G1.order()
>>> elem = order * generator
>>> elem.is_neutral_element()
True
is_neutral_element()

Check if the object is the neutral element of G1.

Example:
>>> generator = G1.generator()
>>> order = G1.order()
>>> elem = order * generator
>>> elem.is_neutral_element()
True
is_valid()

Check if the element is a valid element on the curve. This method excludes the unity element. For that use is_infinity.

Example:
>>> elem = G1.hash_to_point(b"foo")
>>> elem.is_valid()
True
>>> elem = G1.infinity()
>>> elem.is_valid()
False
isub(other)

Inplace substract another point.

Examples:
>>> a = 10 * G1.generator()
>>> b = 10 * G1.generator()
>>> a -= 3 * G1.generator()
>>> _ = b.isub(3 * G1.generator())
>>> a == b
True
>>> a == 7 * G1.generator()
True
mul(other)

Multiply point by a scalar

This method is aliased by n * pt.

Examples:
>>> g = G1.generator()
>>> g + g == 2 * g
True
ne(other)

Check that the points are different.

neg()

Return the inverse of the element.

Examples:
>>> a = 30
>>> elem = a * G1.generator()
>>> -elem == elem.inverse()
True
>>> elem.inverse() == (G1.order() - a) * G1.generator()
True
pair(other)

Pair element with another element in G2

Computes the bilinear pairing between self and another element in petrelic.native.pairing.G2.

Examples:
>>> g1, g2 = G1.generator(), G2.generator()
>>> a, b = 10, 50
>>> A, B = a * g1, b * g2
>>> A.pair(B) == g1.pair(g2) ** (a * b)
True
>>> A.pair(g2) == g1.pair(a * g2)
True
>>> A.pair(g2) == g1.pair(g2) ** a
True
sub(other)

Substract two points

This method is aliased by a - b.

Examples:
>>> a = 50 * G1.generator()
>>> b = 13 * G1.generator()
>>> a - b == 37 * G1.generator()
True
>>> a.sub(b) == 37 * G1.generator()
True
to_binary(compressed=True)

Serialize the element of G1 into a binary representation.

Example:
>>> generator = G1.generator()
>>> bin_repr = generator.to_binary()
>>> elem = G1Element.from_binary(bin_repr)
>>> generator == elem
True
class petrelic.native.pairing.G2[source]

G2 group.

classmethod generator()

Return generator of the group.

Example:
>>> generator = G2.generator()
>>> neutral = G2.neutral_element()
>>> generator + neutral == generator
True
classmethod hash_to_point(hinput)

Return group element obtained by hashing the input

Example:
>>> elem = G2.hash_to_point(b"foo")
>>> elem.is_valid()
True
classmethod infinity()[source]

The point at infinity.

Alias for G1.neutral_element()

classmethod neutral_element()

Return the neutral element of the group G2.

In this case, the point at infinity.

Example:
>>> generator = G2.generator()
>>> neutral = G2.neutral_element()
>>> generator + neutral == generator
True
classmethod order()

Return the order of the EC group as a Bn large integer.

Example:
>>> generator = G2.generator()
>>> neutral = G2.neutral_element()
>>> order = G2.order()
>>> order * generator == neutral
True
classmethod sum(elems)[source]

Efficient sum of a number of elements

In the current implementation this function is not optimized.

Example:
>>> elems = [ x * G2.generator() for x in [10, 25, 13]]
>>> G2.sum(elems) ==  (10 + 25 + 13) * G2.generator()
True
classmethod wsum(weights, elems)[source]

Efficient weighted product of a number of elements

In the current implementation this function is not optimized.

Example:
>>> weights = [1, 2, 3]
>>> elems = [ x * G2.generator() for x in [10, 25, 13]]
>>> G2.wsum(weights, elems) ==  (1 * 10 + 2 * 25 + 3 * 13) * G2.generator()
True
class petrelic.native.pairing.G2Element[source]

Element of the G2 group.

add(other)

Add two points together.

This method is aliased by a + b.

Examples:
>>> a = 10 * G2.generator()
>>> b = 40 * G2.generator()
>>> a + b == 50 * G2.generator()
True
>>> a.add(b) == 50 * G2.generator()
True
double()[source]

Return double of the current element

Example:
>>> generator = G2.generator()
>>> elem = generator.double()
>>> elem == 2 * generator
True
eq(other)

Check that the points on the EC are equal.

classmethod from_binary(sbin)

Deserialize a binary representation of the element of G2.

Example:
>>> generator = G2.generator()
>>> bin_repr = generator.to_binary()
>>> elem = G2Element.from_binary(bin_repr)
>>> generator == elem
True
iadd(other)

Add two points together.

This method is aliased by a + b.

Examples:
>>> a = 10 * G2.generator()
>>> b = 40 * G2.generator()
>>> a + b == 50 * G2.generator()
True
>>> a.add(b) == 50 * G2.generator()
True
idouble()[source]

Inplace double the current element.

Example:
>>> generator = G2.generator()
>>> elem = G2.generator()
>>> _ = elem.idouble()
>>> elem == 2 * generator
True
iinverse()

Inplace inverse of the current element

Examples:
>>> a = 30
>>> elem1 = a * G2.generator()
>>> elem2 = a * G2.generator()
>>> _ = elem1.iinverse()
>>> elem1 == elem2.inverse()
True
imul(other)

Inplace point multiplication by a scalar

Examples:
>>> a = G2.generator()
>>> b = G2.generator()
>>> a *= 10
>>> _ = b.imul(10)
>>> a == b
True
>>> a == 10 * G2.generator()
True
inverse()

Return the inverse of the element.

Examples:
>>> a = 30
>>> elem = a * G2.generator()
>>> -elem == elem.inverse()
True
>>> elem.inverse() == (G2.order() - a) * G2.generator()
True
is_infinity()

Check if the object is the neutral element of G2.

Example:
>>> generator = G2.generator()
>>> order = G2.order()
>>> elem = order * generator
>>> elem.is_neutral_element()
True
is_neutral_element()

Check if the object is the neutral element of G2.

Example:
>>> generator = G2.generator()
>>> order = G2.order()
>>> elem = order * generator
>>> elem.is_neutral_element()
True
is_valid()

Check if the element is a valid element on the curve. This method excludes the unity element. For that use is_infinity.

Example:
>>> elem = G2.hash_to_point(b"foo")
>>> elem.is_valid()
True
>>> elem = G2.infinity()
>>> elem.is_valid()
False
isub(other)

Inplace substract another point.

Examples:
>>> a = 10 * G2.generator()
>>> b = 10 * G2.generator()
>>> a -= 3 * G2.generator()
>>> _ = b.isub(3 * G2.generator())
>>> a == b
True
>>> a == 7 * G2.generator()
True
mul(other)

Multiply point by a scalar

This method is aliased by n * pt.

Examples:
>>> g = G2.generator()
>>> g + g == 2 * g
True
ne(other)

Check that the points on the EC are not equal.

neg()

Return the inverse of the element.

Examples:
>>> a = 30
>>> elem = a * G2.generator()
>>> -elem == elem.inverse()
True
>>> elem.inverse() == (G2.order() - a) * G2.generator()
True
sub(other)

Substract two points

This method is aliased by a - b.

Examples:
>>> a = 50 * G2.generator()
>>> b = 13 * G2.generator()
>>> a - b == 37 * G2.generator()
True
>>> a.sub(b) == 37 * G2.generator()
True
to_binary(compressed=True)

Serialize the element of G2 into a binary representation.

Example:
>>> generator = G2.generator()
>>> bin_repr = generator.to_binary()
>>> elem = G2Element.from_binary(bin_repr)
>>> generator == elem
True
class petrelic.native.pairing.GT[source]

GT group.

classmethod generator()

Return generator of the EC group.

Example:
>>> generator = GT.generator()
>>> neutral = GT.neutral_element()
>>> generator * neutral == generator
True
classmethod neutral_element()

Return the neutral element of the group GT. In this case, the unity point.

Example:
>>> generator = GT.generator()
>>> neutral = GT.neutral_element()
>>> generator * neutral == generator
True
classmethod order()

Return the order of the EC group as a Bn large integer.

Example:
>>> generator = GT.generator()
>>> neutral = GT.neutral_element()
>>> order = GT.order()
>>> generator ** order == neutral
True
classmethod prod(elems)[source]

Efficient product of a number of elements

In the current implementation this function is not optimized.

Example:
>>> elems = [ GT.generator() ** x for x in [10, 25, 13]]
>>> GT.prod(elems) ==  GT.generator() ** (10 + 25 + 13)
True
classmethod unity()[source]

The unity elements

Alias for GT.neutral_element()

classmethod wprod(weights, elems)[source]

Efficient weighted product of a number of elements

In the current implementation this function is not optimized.

Example:
>>> weights = [1, 2, 3]
>>> elems = [ GT.generator() ** x for x in [10, 25, 13]]
>>> GT.wprod(weights, elems) ==  GT.generator() ** (1 * 10 + 2 * 25 + 3 * 13)
True
class petrelic.native.pairing.GTElement[source]

GT element.

div(other)

Divide two points

This method is aliased by a / b and a // b.

Examples:
>>> a = GT.generator() ** 50
>>> b = GT.generator() ** 13
>>> a / b == GT.generator() ** 37
True
>>> a // b == GT.generator() ** 37
True
>>> a.div(b) == GT.generator() ** 37
True
eq(other)

Check that the points are equal.

classmethod from_binary(sbin)

Deserialize a binary representation of the element of GT.

Example:
>>> generator = GT.generator()
>>> bin_repr = generator.to_binary()
>>> elem = GTElement.from_binary(bin_repr)
>>> generator == elem
True
group

alias of GT

idiv(other)

Inplace division by another point

Examples:
>>> a = GT.generator() ** 10
>>> b = GT.generator() ** 10
>>> a /= GT.generator() ** 3
>>> _ = b.idiv(GT.generator() ** 3)
>>> a == b
True
>>> a == GT.generator() ** 7
True
iinverse()

Inplace inverse of the current element

Examples:
>>> a = 30
>>> elem1 = GT.generator() ** a
>>> elem2 = GT.generator() ** a
>>> _ = elem1.iinverse()
>>> elem1 == elem2.inverse()
True
imul(other)

Inplace multiplication by another element

Examples:
>>> a = GT.generator() ** 10
>>> b = GT.generator() ** 10
>>> a *= GT.generator() ** 3
>>> _ = b.imul(GT.generator() ** 3)
>>> a == b
True
>>> a == GT.generator() ** 13
True
inverse()

Return the inverse of the element.

Examples:
>>> a = 30
>>> elem = GT.generator() ** a
>>> elem.inverse() == GT.generator() ** (G1.order() - a)
True
ipow(other)

Inplace raise element to the power of a scalar

Examples:
>>> g = GT.generator()
>>> a = GT.generator()
>>> _ = a.ipow(3)
>>> g * g * g == a
True
is_neutral_element()

Check if the object is the neutral element of GT.

Example:
>>> generator = GT.generator()
>>> order = GT.order()
>>> elem = generator ** order
>>> elem.is_neutral_element()
True
is_unity()

Check if the object is the neutral element of GT.

Example:
>>> generator = GT.generator()
>>> order = GT.order()
>>> elem = generator ** order
>>> elem.is_neutral_element()
True
is_valid()

Check if the element is in the group

Example:
>>> elem = GT.generator() ** 1337
>>> elem.is_valid()
True
isquare()[source]

Inplace square of the current element.

Example:
>>> elem = GT.generator()
>>> _ = elem.isquare()
>>> elem == GT.generator() ** 2
True
mul(other)

Multiply two elements

This method is aliased by a * b.

Examples:
>>> a = GT.generator() ** 10
>>> b = GT.generator() ** 40
>>> a * b == GT.generator() ** 50
True
>>> a.mul(b) == GT.generator() ** 50
True
ne(other)

Check that the points on the EC are not equal.

pow(other)

Raise element to the power of a scalar

This method is aliased by el ** n.

Examples:
>>> g = GT.generator()
>>> g * g == g ** 2
True
>>> g * g == g.pow(2)
True
square()[source]

Return the square of the current element

Example:
>>> generator = GT.generator()
>>> elem = generator.square()
>>> elem == generator ** 2
True
to_binary(compressed=True)

Serialize the element of GT into a binary representation.

Example:
>>> generator = GT.generator()
>>> bin_repr = generator.to_binary()
>>> elem = GTElement.from_binary(bin_repr)
>>> generator == elem
True
exception petrelic.native.pairing.NoAffineCoordinateForECPoint[source]

Exception raised when an EC point can not be represented as affine coordinates.

args
msg = 'No affine coordinates exists for the given EC point.'
with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.