Additive interface

The additive wrapper presents an additive interface for all three groups G1, G2, and GT. This is useful, for example, when integrating with zsks. You can use this interface by importing:

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

petrelic.additive.pairing

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

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 raise it to the power of 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) == (a*b) * G1.generator().pair(G2.generator())
True
class petrelic.additive.pairing.BilinearGroupPair[source]

A bilinear group pair.

Contains two origin groups G1, G2 and the image group GT.

groups()[source]

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

class petrelic.additive.pairing.G1[source]

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.additive.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)[source]

Pair element with another element in G2

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

Examples:
>>> g1, g2 = G1.generator(), G2.generator()
>>> a, b = 10, 50
>>> A, B = g1 * a, g2 * b
>>> A.pair(B) == g1.pair(g2) * (a * b)
True
>>> A.pair(g2) == g1.pair(g2 * a)
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.additive.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.additive.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
group

alias of G2

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.additive.pairing.GT[source]

GT group.

classmethod generator()[source]

Return generator of the group.

Example:
>>> generator = GT.generator()
>>> neutral = GT.neutral_element()
>>> generator + neutral == generator
True
classmethod infinity()[source]

The unity element

Alias for GT.neutral_element()

classmethod neutral_element()[source]

Return the neutral element of the group G1.

In this case, the point at infinity.

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

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

Example:
>>> generator = GT.generator()
>>> neutral = GT.neutral_element()
>>> order = GT.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 * GT.generator() for x in [10, 25, 13]]
>>> GT.sum(elems) ==  (10 + 25 + 13) * GT.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 * GT.generator() for x in [10, 25, 13]]
>>> GT.wsum(weights, elems) ==  (1 * 10 + 2 * 25 + 3 * 13) * GT.generator()
True
class petrelic.additive.pairing.GTElement[source]

GT element.

add(other)

Add two points together.

This method is aliased by a + b.

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

Return double of the current element

Example:
>>> generator = GT.generator()
>>> elem = generator.double()
>>> elem == 2 * generator
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

iadd(other)

Inplace add another point.

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

Inplace double the current element.

Example:
>>> generator = GT.generator()
>>> elem = GT.generator()
>>> _ = elem.idouble()
>>> elem == 2 * generator
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 point multiplication by a scalar

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

Return the inverse of the element.

Examples:
>>> a = 30
>>> elem = GT.generator() ** a
>>> elem.inverse() == GT.generator() ** (G1.order() - 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_valid()

Check if the element is in the group

Example:
>>> elem = GT.generator() ** 1337
>>> elem.is_valid()
True
isub(other)

Inplace substract another point.

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

Multiply point by a scalar

This method is aliased by n * pt.

Examples:
>>> g = GT.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 = GT.generator() ** a
>>> elem.inverse() == GT.generator() ** (G1.order() - a)
True
sub(other)

Substract two points

This method is aliased by a - b.

Examples:
>>> a = 50 * GT.generator()
>>> b = 13 * GT.generator()
>>> a - b == 37 * GT.generator()
True
>>> a.sub(b) == 37 * GT.generator()
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